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 GetTileUriAsync(int level, int row, int column, CancellationToken cancellationToken)
        {
            //Console.WriteLine(level.ToString() + "," + row.ToString() + "," + column.ToString());//打印输出
            Task myTask = new Task(() => 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 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 lodDefault = new List()//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然后即可显示底图。