ArcGIS读取天地图出现错位的情况
来源:互联网 发布:晚吃姜如砒霜 知乎 编辑:程序博客网 时间:2024/05/22 01:30
天地图2.0(http://www.chinaonmap.com)于2013年3月份上线,基本情况如下:
1) 基于OGC的WMTS 1.0.0版本;
2) 提供矢量地图、影像地图和地形图;
3) 提供两种坐标系:国家2000大地坐标系和Web Mercator投影坐标系;
4) 地图和标注数据分开,矢量地图和影像地图提供中英文标注,地形图仅提供中文标注。
ArcGIS接口可以灵活扩展支持天地图。本文是以ArcGIS Runtime SDK for Android为例说明如何扩展来加载天地图的。其它产品,比如Web APIs、Native SDKs、Portal for ArcGIS、桌面都可以通过扩展实现对天地图的支持。要获取扩展源码及示例,包括使用说明文档,请点击此处下载
1. ArcGIS WMTS接口访问天地图
ArcGIS产品,包括桌面产品、Web APIs、Native SDKs都提供了对WMTS的支持。如此,可以通过这些接口来访问天地图的WMTS服务。但是实际情况要复杂一些,经过测试发现,使用ArcGIS的WMTS接口访问天地图,会出现偏差,如下图所示。
经过研究发现,产生偏差的根本原因在于:ArcGIS WMTS接口中使用的DPI与天地图使用的DPI不一致。
OGCWMTS标准中规定,通过getcapatilities请求可以获得WMTS的元数据。上图是天地图2.0 WMTS元数据的部分截图(XML格式)。元数据中包含各个级别的比例尺数据(如图中红框内容)。在访问WMTS时,需要通过这些元数据计算出分辨率,公式如下所示。
OGC WMTS规范中DPI采用90.71(即采用0.028mm作为一个像素的物理宽度),而天地图使用的DPI采用国家标准规定的96(见《电子地图规范》)。由于ArcGIS WMTS接口实现均遵循OGC WMTS标准,使用90.71作为DPI来计算分辨率,导致ArcGIS通过WMTS接口访问天地图时,图片物理尺寸变大,使得地图看上去向右下方偏移。
2. 扩展ArcGIS接口访问天地图(以ArcGIS Runtime SDK forAndroid为例)
在第2小结,分析了用ArcGIS WMTS接口访问天地图产生偏移的原因,那么就可以有针对性的对ArcGIS接口进行扩展,来实现对天地图的访问。
ArcGIS接口可以扩展。以ArcGIS Runtime SDK for Android为例,提供了TiledServiceLayer类。这是访问切片服务的基础类,通过扩展这个类,就可以访问天地图的WMTS服务了。扩展之前,需要了解一下天地图服务的一些参数,包括:(1)比例尺
// 两种坐标系下的分辨率一致
private static final double[] SCALES = { 2.958293554545656E8,
1.479146777272828E8, 7.39573388636414E7, 3.69786694318207E7,
1.848933471591035E7, 9244667.357955175, 4622333.678977588,
2311166.839488794, 1155583.419744397, 577791.7098721985,
288895.85493609926, 144447.92746804963, 72223.96373402482,
36111.98186701241, 18055.990933506204, 9027.995466753102,
4513.997733376551, 2256.998866688275 };
(2)分辨率
// 墨卡托坐标系下的分辨率
private static final double[] RESOLUTIONS_MERCATOR = { 78271.51696402048,
39135.75848201024, 19567.87924100512, 9783.93962050256,
4891.96981025128, 2445.98490512564, 1222.99245256282,
611.49622628141, 305.748113140705, 152.8740565703525,
76.43702828517625, 38.21851414258813, 19.109257071294063,
9.554628535647032, 4.777314267823516, 2.388657133911758,
1.194328566955879, 0.5971642834779395 };
// 国家2000坐标系下的分辨率
private static final double[] RESOLUTIONS_2000 = { 0.7031249999891485,
0.35156249999999994, 0.17578124999999997, 0.08789062500000014,
0.04394531250000007, 0.021972656250000007, 0.01098632812500002,
0.00549316406250001, 0.0027465820312500017, 0.0013732910156250009,
0.000686645507812499, 0.0003433227539062495,
0.00017166137695312503, 0.00008583068847656251,
0.000042915344238281406, 0.000021457672119140645,
0.000010728836059570307, 0.000005364418029785169};
(3)起始点
// 国家2000坐标系下的起始点
private static final Point ORIGIN_2000 =new Point(-180, 90);
// 墨卡托坐标系下的起始点
private static final Point ORIGIN_MERCATOR =new Point(-20037508.3427892,
20037508.3427892);
(4)地图范围
// 国家2000坐标系下的地图范围
private static final double X_MIN_2000 = -180;
private static final double Y_MIN_2000 = -90;
private static final double X_MAX_2000 = 180;
private static final double Y_MAX_2000 = 90;
// 墨卡托坐标系下的地图范围
private static final double X_MIN_MERCATOR = -20037508.3427892;
private static final double Y_MIN_MERCATOR = -20037508.3427892;
private static final double X_MAX_MERCATOR = 20037508.3427892;
private static final double Y_MAX_MERCATOR = 20037508.3427892;
有了以上信息,通过扩展TiledServiceLayer,就可以访问天地图了,核心代码如下所示:
TianDiTuLayer.javapublic class TianDiTuLayer extends TiledServiceLayer {
private TianDiTuLayerInfolayerInfo;
public TianDiTuLayer(int layerType) {
super(true);
this.layerInfo = LayerInfoFactory.getLayerInfo(layerType);
this.init();
}
private void init() {
try {
getServiceExecutor().submit(new Runnable() {
publicvoid run() {
TianDiTuLayer.this.initLayer();
}
});
} catch (RejectedExecutionException rejectedexecutionexception) {
Log.e("ArcGIS","initialization of the layer failed.",
rejectedexecutionexception);
}
}
protected byte[] getTile(int level,int col, int row)throws Exception {
if (level >layerInfo.getMaxZoomLevel()
|| level < layerInfo.getMinZoomLevel())
return new byte[0];
String url = layerInfo.getUrl()
+ "?service=wmts&request=gettile&version=1.0.0&layer="
+ layerInfo.getLayerName() +"&format=tiles&tilematrixset="
+ layerInfo.getTileMatrixSet() +"&tilecol=" + col
+ "&tilerow=" + row +"&tilematrix=" + (level+1);
Map<String, String> map = null;
return com.esri.core.internal.io.handler.a.a(url, map);
}
protected void initLayer() {
if (getID() == 0L) {
nativeHandle = create();
changeStatus(com.esri.android.map.event.OnStatusChangedListener.STATUS
.fromInt(-1000));
} else {
this.setDefaultSpatialReference(SpatialReference.create(layerInfo
.getSrid()));
this.setFullExtent(new Envelope(layerInfo.getxMin(),layerInfo
.getyMin(), layerInfo.getxMax(),layerInfo.getyMax()));
this.setTileInfo(new TileInfo(layerInfo.getOrigin(),layerInfo
.getScales(), layerInfo.getResolutions(),layerInfo
.getScales().length,layerInfo.getDpi(), layerInfo
.getTileWidth(), layerInfo.getTileHeight()));
super.initLayer();
}
}
}
以下代码说明如何使用扩展后的TianDiTuLayer来显示天地图服务。
mapMercator = (MapView) this.findViewById(R.id.mapMercator);
Layer mapLayer = new TianDiTuLayer(TianDiTuLayerTypes.TIANDITU_VECTOR_MERCATOR);
this.mapMercator.addLayer(mapLayer);
Layer annotationLayer = new TianDiTuLayer(
TianDiTuLayerTypes.TIANDITU_VECTOR_ANNOTATION_CHINESE_MERCATOR);
this.mapMercator.addLayer(annotationLayer);
使用扩展后的TianDiTuLayer加载天地图,与业务数据叠加效果图如下所示:3. 总结
ArcGIS接口可以灵活扩展。以上是以ArcGIS Runtime SDK for Android为例说明如何扩展来加载天地图。其它接口,比如Web APIs、Native SDKs、Portal for ArcGIS、桌面都可以通过类似的方式实现扩展。想扩展源码及示例,包括使用说明文档, 请点击此处下载
- ArcGIS读取天地图出现错位的情况
- ArcGIS读取天地图2.0
- 找到的一串arcgis里面使用天地图的代码
- 重写ArcGIS的TiledMapServiceLayer调用天地图瓦片
- 在ie浏览器中 arcgis js api 生成的 infowindow 会产生错位的情况
- 入门Android开发--ArcGis读取天地图,并实现一些简单功能。
- arcgis api for javascript 调用天地图,并加载数据arcgis server 发布的数据
- ArcGIS Flex API调用天地图
- ArcGIS Silverlight API访问天地图服务
- arcgis api for android 叠加天地图
- ArcGIS Silverlight API访问天地图服务
- ArcGIS Silverlight API访问天地图服务
- ArcGIS Web API 接入天地图瓦片
- arcgis调用国家天地图wfs服务
- ArcGIS切片和天地图瓦片匹配
- Arcgis for js加载天地图
- arcgis for javascript 加载天地图影像
- ArcGIS API for JavaScript加载天地图
- XSLT 参数与变量
- 教你如何科学的在Xcode8上使用插件
- echarts柱状折线图数据量大,柱状图不显示问题解决办法.
- C# 格式化输出
- PAT A 1117. Eddington Number
- ArcGIS读取天地图出现错位的情况
- java使用poi操作excel
- R语言实用案例分析-1
- checkbox全选、反选功能
- BeanUtils.copyProperties() 用法
- React Native iOS原生模块开发实战|教程|心得|如何创建React Native iOS原生模块
- jquery插件EasyUI中form表单提交实例分享
- Tex中的引号(UVa 272)
- TypeScript入门-7.函数特性-不定参数