1. 程式人生 > >ArcGIS Runtime 新增谷歌地圖、OpenStreetMap作為底圖

ArcGIS Runtime 新增谷歌地圖、OpenStreetMap作為底圖

ArcGIS 自從釋出Runtime以來一直以Web+C/S的模式,慢慢挑戰著AE/AO的江湖地位。其可以新增Web底圖的方法更是其殺手鐗。

現在就分享ArcGIS Runtime中新增Google底圖的方法。

開門見山,直接寫出其最關鍵的類,自定義的一個類GoogleTileLayer

public class GoogleTileLayer : ServiceImageTiledLayer
    {
        private string LayerType = "s";//圖層型別

        public GoogleTileLayer(TileInfo tileInfo, Envelope fullExtent, String inputLayerType)
            : base(tileInfo, fullExtent)
        {
            LayerType = inputLayerType;
        }

        //重寫Uri函式
        protected override Task<Uri> GetTileUriAsync(int level, int row, int column, CancellationToken cancellationToken)
        {
            //Console.WriteLine(level.ToString() + "," + row.ToString() + "," + column.ToString());//列印輸出
            Task<Uri> myTask = new Task<Uri>(() => GetTileUri(level, row, column, cancellationToken));
            myTask.Start();
            return myTask;
        }

        private Uri GetTileUri(int level, int row, int column, CancellationToken cancellationToken)
        {
           MapViewControl.VisableInt = level;
            string baseUrlString = "http://mt0.google.cn/vt/lyrs=" + LayerType;
            string urlString = baseUrlString + "&x=" + column.ToString() + "&y=" + row.ToString() + "&z=" + level.ToString() + "&s=";
            Uri myUri = new Uri(urlString);
            return myUri;
        }
    }

該類中的最核心函式為

GetTileUri

這個函式重寫了獲取谷歌瓦片地圖的伺服器地址,不僅僅是mt0伺服器mt1-4伺服器也是可以訪問的。

(注意:不同伺服器的地圖更新程度可能不一樣,就比如正射影像,半年的更新頻率,在不同伺服器中具體情況不同。)

接下來就是例項化這個函式的時候的這個構造函數了

 public GoogleTileLayer(TileInfo tileInfo, Envelope fullExtent, String inputLayerType): base(tileInfo, fullExtent)
其中Tileinfo的細節如下
public TileInfo(int dpi, TileImageFormat format, IEnumerable<LevelOfDetail> levelsOfDetail, MapPoint origin, SpatialReference spatialReference, int tileHeight, int tileWidth);

查詢對應的引數以後做出以下對應的定義:

private SpatialReference referenceDefault = new SpatialReference(3875);//定義墨卡託投影
MapPoint mapPointDefault = new MapPoint(-20037508.342787, 20037508.342787, referenceDefault);//預設初始點
int GoogleMapTileHeight = 256;//每塊切片的高度和寬度
int GoogleMapTileWidth = 256;
int dpiDefault = 96;//谷歌地圖DPI
TileImageFormat tileImageFormat = TileImageFormat.Png;//瓦片地圖型別
其中比較關鍵的LevelOfDetail如下
 List<LevelOfDetail> lodDefault = new List<LevelOfDetail>()//LevelOfDetailList
            {
                new LevelOfDetail (0,156543.033928023,591657527.591555),
                new LevelOfDetail (1,78271.5169640117,295828763.795778),
                new LevelOfDetail (2,39135.7584820059,147914381.897889),
                new LevelOfDetail (3,19567.8792410029,73957190.9489444),
                new LevelOfDetail (4,9783.93962050147,36978595.4744722),
                new LevelOfDetail (5,4891.96981025073,18489297.7372361),
                new LevelOfDetail (6,2445.98490512537,9244648.86861805),
                new LevelOfDetail (7,1222.99245256268,4622324.43430902),
                new LevelOfDetail (8,611.496226281342,2311162.21715451),
                new LevelOfDetail (9,305.748113140671,1155581.10857726),
                new LevelOfDetail (10,152.874056570335,577790.554288628),
                new LevelOfDetail (11,76.4370282851677,288895.277144314),
                new LevelOfDetail (12,38.2185141425838,144447.638572157),
                new LevelOfDetail (13,19.1092570712919,72223.8192860785),
                new LevelOfDetail (14,9.55462853564596,36111.9096430392),
                new LevelOfDetail (15,4.77731426782298,18055.9548215196),
                new LevelOfDetail (16,2.38865713391149,9027.97741075981),
                new LevelOfDetail (17,1.19432856695575,4513.98870537991),
                new LevelOfDetail (18,0.597164283477873,2256.99435268995),
                new LevelOfDetail (19,0.298582141738936,1128.49717634498),
                new LevelOfDetail(20,0.1492910708694683,564.24858817249),
                new LevelOfDetail(21,0.07464553543473415,282.124294086245),
                new LevelOfDetail(22,0.037322767717367075,141.0621470431225),
            };
然後將例項化以後的GoogleTileLayer 傳給MapView作為其Map.BaseMap然後即可顯示底圖。