runtime 100.1 中加载天地图/百度/高德/腾讯等底图(二)

3
分享 2017-08-10
       在上一篇runtime 100.1 中加载天地图/百度/高德/腾讯等底图(一)中介绍了加载天地图和高德地图作为底图,这一篇中将介绍如何编写自定义的切片图层。
       编写自定义的切片图层,将使用到ImageTiledLayer类,这里我使用的是可以传回url的类ServiceImageTiledLayer,ImageTiledLayer是根据缩放级别,动态传回ImageTileData数据渲染,加载到地图上,ServiceImageTiledLayer继承自ImageTiledLayer,扩展了一个方法:
Task<Uri> GetTileUriAsync(int level, int row, int column, CancellationToken cancellationToken)
这个方法会根据当前的缩放级别,动态的去指定的url请求图片数据,和WebTiledLayer不同的是,可以继承ServiceImageTiledLayer重写GetTileUriAsync方法,实现不标准url模板的数据请求,比如百度/腾讯等地图数据,下面直接贴代码
    #region 百度地图
public class BaiduMapLayer : Esri.ArcGISRuntime.Mapping.ServiceImageTiledLayer
{
string baidulayerType;
public BaiduMapLayer(string type = "road")
: base(CreateTileInfo(), new Envelope(-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator))
{
baidulayerType = type;
}

private static Esri.ArcGISRuntime.ArcGISServices.TileInfo CreateTileInfo()
{
var levels = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail[19];
double resolution = 20037508.3427892 * 2 / 256;
double scale = resolution * 96 * 39.37;
for (int i = 0; i < levels.Length; i++)
{
levels[i] = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail(i, resolution, scale);
resolution /= 2;
scale /= 2;
}
return new Esri.ArcGISRuntime.ArcGISServices.TileInfo(96, TileImageFormat.Png, levels, new MapPoint(-20037508.3427892, 20037508.3427892, new SpatialReference(102100)),
SpatialReferences.WebMercator, 256, 256);
}

private static string subdomains = { "a", "b", "c" };

protected override Task<Uri> GetTileUriAsync(int level, int row, int col, CancellationToken cancellationToken)
{

var zoom = level - 1;
var offsetX = (int)Math.Pow(2, zoom);
var offsetY = offsetX - 1;
var numX = col - offsetX;
var numY = (-row) + offsetY;
var num = (col + row) % 8 + 1;
var url = "";
switch (this.baidulayerType)
{
case "road":
url = "http://online" + num + ".map.bdimg.com/tile/?qt=tile&x=" + numX + "&y=" + numY + "&z=" + level + "&styles=pl&udt=20170706";
break;
case "st":
url = "http://shangetu3.map.bdimg.com/it/u=x=" + numX + ";y=" + numY + ";z=" + level + ";v=009;type=sate&fm=46&app=webearth2&v=009&udt=20170704";
break;
default:
url = "http://online" + num + ".map.bdimg.com/tile/?qt=tile&x=" + numX + "&y=" + numY + "&z=" + level + "&styles=pl&udt=20170706";
break;
}
return Task.FromResult(new Uri(url, UriKind.Absolute));
}
}
#endregion[/i]
[i]#region 腾讯地图
public class TencentMapLayer : Esri.ArcGISRuntime.Mapping.ServiceImageTiledLayer
{
string tencentlayerType;
public TencentMapLayer(string layerType = "road")
: base(CreateTileInfo(), new Envelope(-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator))
{
tencentlayerType = layerType;
}

private static Esri.ArcGISRuntime.ArcGISServices.TileInfo CreateTileInfo()
{
var levels = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail[19];
double resolution = 20037508.3427892 * 2 / 256;
double scale = resolution * 96 * 39.37;
for (int i = 0; i < levels.Length; i++)
{
levels[i] = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail(i, resolution, scale);
resolution /= 2;
scale /= 2;
}
return new Esri.ArcGISRuntime.ArcGISServices.TileInfo(96, TileImageFormat.Png, levels, new MapPoint(-20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator),
SpatialReferences.WebMercator, 256, 256);
}



protected override Task<Uri> GetTileUriAsync(int level, int row, int column, CancellationToken cancellationToken)
{

row = (int)Math.Pow(2, level) - 1 - row;
var url = "";
switch (this.tencentlayerType)
{
case "road":
url = $"http://rt0.map.gtimg.com/realtimerender?z={level}&x={column}&y={row}&type=vector&style=0";
break;
case "st":
url = $"http://p0.map.gtimg.com/sateTiles/{level}/{Math.Floor((Decimal)column / 16)}/{Math.Floor((Decimal)row / 16)}/{column}_{row}.jpg?version=228";
break;
case "a":
url = $"http://rt2.map.gtimg.com/tile?z={level}&x={column}&y={row}&styleid=2&version=232";
break;
default:
break;
}
return Task.FromResult(new Uri(url, UriKind.Absolute));
}
}
#endregion[/i][/i]
[i][i]    #region openstreet
public class OpenStreetMapLayer : Esri.ArcGISRuntime.Mapping.ServiceImageTiledLayer
{
public OpenStreetMapLayer()
: base(CreateTileInfo(), new Envelope(-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator))
{
}

private static Esri.ArcGISRuntime.ArcGISServices.TileInfo CreateTileInfo()
{
var levels = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail[19];
double resolution = 20037508.3427892 * 2 / 256;
double scale = resolution * 96 * 39.37;
for (int i = 0; i < levels.Length; i++)
{
levels[i] = new Esri.ArcGISRuntime.ArcGISServices.LevelOfDetail(i, resolution, scale);
resolution /= 2;
scale /= 2;
}
return new Esri.ArcGISRuntime.ArcGISServices.TileInfo(96, TileImageFormat.Png, levels, new MapPoint(-20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator),
SpatialReferences.WebMercator, 256, 256);
}

private static string subdomains = { "a", "b", "c" };

protected override Task<Uri> GetTileUriAsync(int level, int row, int column, CancellationToken cancellationToken)
{
return Task.FromResult(new Uri($"http://{ subdomains[(level + column + row) % subdomains.Length]}.tile.openstreetmap.org/{level}/{column}/{row}.png", UriKind.Absolute));
}
}
#endregion[/i][/i][/i]

[i][i] 如何使用这些类:[/i][/i]
[i][i]var _layer = new BaiduMapLayer();[/i][/i]

[i][i]MyMapView.Map.Basemap.BaseLayers.Add(_layer)[/i][/i]
runtime 100.1 中加载天地图/百度/高德/腾讯等底图(一):http://zhihu.esrichina.com.cn/article/3246 
runtime 100.1 中加载天地图/百度/高德/腾讯等底图(二):http://zhihu.esrichina.com.cn/publish/article/3248

1 个评论

谢谢,非常有帮助。 请问有100.2 FOR ANDROID 的代码吗?

要回复文章请先登录注册