Android GIS开发系列-- 入门季(12) 显示载天地图
在项目中可以经常需要动态加载一些图层,像投影地图服务、投影地图服务器。其实网上有大量这样的服务,比如天地图官网,
。
随便点开一个服务,里面有相关的信息。那如何加载这样图层服务呢。
一、首先感谢这篇博文ArcGIS读取天地图出现错位的情况,这篇文章的下载链接也有许多有用的资料。加载天地图用到一个关键的自定义类TianDiTuLayer
package com.huang.tianditu.layer; import java.util.Map; import java.util.concurrent.RejectedExecutionException; import android.util.Log; import com.esri.android.map.TiledServiceLayer; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.SpatialReference; public class TianDiTuLayer extends TiledServiceLayer { private TianDiTuLayerInfo layerInfo; public TianDiTuLayer(int layerType) { super(true); this.layerInfo = LayerInfoFactory.getLayerInfo(layerType); this.init(); } private void init() { try { getServiceExecutor().submit(new Runnable() { public void run() { TianDiTuLayer.this.initLayer(); } }); } catch (RejectedExecutionException rejectedexecutionexception) { Log.e("ArcGIS", "initialization of the layer failed.", rejectedexecutionexception); } } public byte[] getTile(int level, int col, int row) throws Exception { 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())); Log.e("huang", layerInfo.toString()+""); 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(); } } }
另外还有三个类,TianDiTuLayerInfo、LayerInfoFactory、TianDiTuLayerTypes这里就不贴代码了。资料下载。
二、我们修改一下代码
1.常量类TDTConstant:
package com.huang.tianditu; import com.esri.android.map.TiledServiceLayer.TileInfo; import com.esri.core.geometry.Envelope; import com.esri.core.geometry.Point; public class TDTConstant { public static final String LAYER_NAME_VECTOR = "vec"; public static final String LAYER_NAME_VECTOR_ANNOTATION_CHINESE = "cva"; public static final String LAYER_NAME_VECTOR_ANNOTATION_ENGLISH = "eva"; public static final String LAYER_NAME_IMAGE = "img"; public static final String LAYER_NAME_IMAGE_ANNOTATION_CHINESE = "cia"; public static final String LAYER_NAME_IMAGE_ANNOTATION_ENGLISH = "eia"; public static final String LAYER_NAME_TERRAIN = "ter"; public static final String LAYER_NAME_TERRAIN_ANNOTATION_CHINESE = "cta"; public static final String TILE_MATRIX_SET_MERCATOR = "w"; public static final String TILE_MATRIX_SET_2000 = "c"; public static final Point ORIGIN_2000 = new Point(-180, 90); public static final Point ORIGIN_MERCATOR = new Point(-20037508.3427892, 20037508.3427892); public static final int SRID_2000 = 4490; public static final int SRID_MERCATOR = 102100; public static final double X_MIN_2000 = -180; public static final double Y_MIN_2000 = -90; public static final double X_MAX_2000 = 180; public static final double Y_MAX_2000 = 90; public static final double X_MIN_MERCATOR = -20037508.3427892; private static final double Y_MIN_MERCATOR = -20037508.3427892; public static final double X_MAX_MERCATOR = 20037508.3427892; public static final double Y_MAX_MERCATOR = 20037508.3427892; public static final int tileWidth = 256; public static final int tileHeight = 256; public static final int dpi = 96; public 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 }; public 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 }; public 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 }; public static final Envelope Envelope_2000 = new Envelope(TDTConstant.X_MIN_2000, TDTConstant.Y_MIN_2000, TDTConstant.X_MAX_2000, TDTConstant.Y_MAX_2000); public static final Envelope Envelope_MERCATOR = new Envelope(TDTConstant.X_MIN_MERCATOR, TDTConstant.Y_MIN_MERCATOR, TDTConstant.X_MAX_MERCATOR, TDTConstant.Y_MAX_MERCATOR); public static final TileInfo TileInfo_2000 = new TileInfo(TDTConstant.ORIGIN_2000, TDTConstant.SCALES, TDTConstant.RESOLUTIONS_2000, TDTConstant.SCALES.length, TDTConstant.dpi, TDTConstant.tileWidth, TDTConstant.tileHeight); public static final TileInfo TileInfo_MERCATOR = new TileInfo(TDTConstant.ORIGIN_MERCATOR, TDTConstant.SCALES, TDTConstant.RESOLUTIONS_MERCATOR, TDTConstant.SCALES.length, TDTConstant.dpi, TDTConstant.tileWidth, TDTConstant.tileHeight); }
2.TianDiTuLayer,代码如下 :
package com.huang.tianditu; import java.util.Map; import java.util.concurrent.RejectedExecutionException; import android.util.Log; import com.esri.android.map.TiledServiceLayer; import com.esri.core.geometry.SpatialReference; public class TianDiTuLayer extends TiledServiceLayer { private TianDiTuInfo tianDiTuInfo; public TianDiTuLayer(TianDiTuInfo tianDiTuInfo) { super(true); this.tianDiTuInfo = tianDiTuInfo; this.init(); } private void init() { try { getServiceExecutor().submit(new Runnable() { public void run() { TianDiTuLayer.this.initLayer(); } }); } catch (RejectedExecutionException rejectedexecutionexception) { Log.e("ArcGIS", "initialization of the layer failed.", rejectedexecutionexception); } } public byte[] getTile(int level, int col, int row) throws Exception { String url = tianDiTuInfo.getUrl() + "?service=wmts&request=gettile&version=1.0.0&layer=" + tianDiTuInfo.getLayerName() + "&format=tiles&tilematrixset=" + tianDiTuInfo.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(tianDiTuInfo.getSrid())); this.setFullExtent(tianDiTuInfo.getEnvelope()); this.setTileInfo(tianDiTuInfo.getTileInfo()); super.initLayer(); } } }
3.TianDiTuInfo实体类:
package com.huang.tianditu; import com.esri.android.map.TiledServiceLayer.TileInfo; import com.esri.core.geometry.Envelope; public class TianDiTuInfo { private String url; private String layerName; private int minZoomLevel = 0; private int maxZoomLevel = 17; private int srid; private String tileMatrixSet; private Envelope envelope; private TileInfo tileInfo; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getLayerName() { return layerName; } public void setLayerName(String layerName) { this.layerName = layerName; } public int getMinZoomLevel() { return minZoomLevel; } public void setMinZoomLevel(int minZoomLevel) { this.minZoomLevel = minZoomLevel; } public int getMaxZoomLevel() { return maxZoomLevel; } public void setMaxZoomLevel(int maxZoomLevel) { this.maxZoomLevel = maxZoomLevel; } public int getSrid() { return srid; } public void setSrid(int srid) { this.srid = srid; } public String getTileMatrixSet() { return tileMatrixSet; } public void setTileMatrixSet(String tileMatrixSet) { this.tileMatrixSet = tileMatrixSet; } public Envelope getEnvelope() { return envelope; } public void setEnvelope(Envelope envelope) { this.envelope = envelope; } public TileInfo getTileInfo() { return tileInfo; } public void setTileInfo(TileInfo tileInfo) { this.tileInfo = tileInfo; } }
4.Activity代码:
package com.huang.tianditu; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import com.esri.android.map.MapView; public class TianDiTuLayerActivity extends Activity { private MapView mMapView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mMapView = (MapView) findViewById(R.id.mapView); TianDiTuInfo tianDiTuInfo = new TianDiTuInfo(); tianDiTuInfo.setUrl("http://t0.tianditu.com/vec_c/wmts"); tianDiTuInfo.setLayerName(TDTConstant.LAYER_NAME_VECTOR); tianDiTuInfo.setTileMatrixSet(TDTConstant.TILE_MATRIX_SET_2000); tianDiTuInfo.setSrid(TDTConstant.SRID_2000); tianDiTuInfo.setEnvelope(TDTConstant.Envelope_2000); tianDiTuInfo.setTileInfo(TDTConstant.TileInfo_2000); mMapView.addLayer(new TianDiTuLayer(tianDiTuInfo)); } }
调用的地图服务相关信息
效果图:
你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。