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();
        }
    }

}
View Code

另外還有三個類,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);



}
View Code

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();
        }
    }

}
View Code

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;
    }

}
View Code

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));
    }

}
View Code

 

調用的地圖服務相關信息
效果圖:
效果圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM