ArcGIS for Android Runtime100 高级功能(一)-互联网地图加载引用及缓存

arcgis for android最后一版是10.2.9。据说之后不再更新维护该版本,直接跳跃到100系列,而100系列与之前的版本还是有较大差别。但也新增了更多功能,性能也优化很多。具体的差别此处不再赘述,多用用100版本就能感觉出来。

本节主要是讲讲新版本中互联网地图的引用,主要指常用的天地图、谷歌地图。其实加载百度、高德地图是一样的原理,但由于他们的地图坐标数据都是火星坐标,针对专业GIS开发时,就用不上了。

1、重载ImageTiledLayer。主要实现两个方法,

一个是构造函数:protected ImageTiledLayer(TileInfo tileInfo, Envelope fullExtent)

一个是瓦片下载函数:protected abstract byte[] getTile(TileKey var1)

2、根据我们之前的经验,构造函数主要是TileInfo参数构建,把之前的参数搬过来就可以了。

直接上代码

BaseMapLayer 类

public class BaseMapLayer extends ImageTiledLayer {

    //天地、谷歌矢量图和影像图常量
    public static final int MAPLAYER_TIANDI_VECTOR = 1;
    public static final int MAPLAYER_TIANDI_IMAGE = 2;
    public static final int MAPLAYER_GOOGLE_VECTOR = 3;
    public static final int MAPLAYER_GOOGLE_IMAGE = 4;
    //影像地图标注常量
    public static final int MAPLAYER_TIANDI_IMAGE_LABEL = 5;
    public static final int MAPLAYER_TIANDI_VECTOR_LABEL = 6;



    private static double[] scales = new double[]{591657527.591555,
            295828763.79577702, 147914381.89788899, 73957190.948944002,
            36978595.474472001, 18489297.737236001, 9244648.8686180003,
            4622324.4343090001, 2311162.217155, 1155581.108577, 577790.554289,
            288895.277144, 144447.638572, 72223.819286, 36111.909643,
            18055.954822, 9027.9774109999998, 4513.9887049999998, 2256.994353,
            1128.4971760000001};
    private static double[] resolutions = new double[]{156543.03392800014,
            78271.516963999937, 39135.758482000092, 19567.879240999919,
            9783.9396204999593, 4891.9698102499797, 2445.9849051249898,
            1222.9924525624949, 611.49622628138, 305.748113140558,
            152.874056570411, 76.4370282850732, 38.2185141425366,
            19.1092570712683, 9.55462853563415, 4.7773142679493699,
            2.3886571339746849, 1.1943285668550503, 0.59716428355981721,
            0.29858214164761665};
    private static Point origin = new Point(-20037508.342787, 20037508.342787, SpatialReference.create(3857));

    int type = 0;

    protected BaseMapLayer(TileInfo tileInfo, Envelope fullExtent) {
        super(tileInfo, fullExtent);
    }

    protected BaseMapLayer(CoreImageTiledLayer coreTiledLayer, boolean addToCache) {
        super(coreTiledLayer, addToCache);
    }

    public static BaseMapLayer CreateBaseMapLayer(int type) {

        List<LevelOfDetail> levelOfDetails = MapTilesTool.getLevelOfDetails();

        try {
            TileInfo tileInfo = new TileInfo(96, TileInfo.ImageFormat.MIXED, levelOfDetails
                    , origin
                    , SpatialReference.create(3857)
                    , 256, 256);

            Envelope fullExtent = new Envelope(-22041257.773878,
                    -32673939.6727517, 22041257.773878, 20851350.0432886, SpatialReference.create(3857));
            BaseMapLayer layer = new BaseMapLayer(tileInfo, fullExtent);
            layer.type = type;
            return layer;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    public static String getUrl(int type) {
        String[] subDomains = null;
        String urlPart = "";
        String flag = "";

        switch (type) {
            case MAPLAYER_TIANDI_VECTOR://天地图矢量地图
                subDomains = new String[]{"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"};
                urlPart = ".tianditu.com/DataServer?T=vec_w";
                flag = "l";

                break;
            case MAPLAYER_TIANDI_IMAGE://天地图影像地图
                subDomains = new String[]{"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"};
                urlPart = ".tianditu.com/DataServer?T=img_w";
                flag = "l";

                break;
            case MAPLAYER_GOOGLE_VECTOR://Google 矢量地图
                subDomains = new String[]{"mt0", "mt1", "mt2", "mt3"};
                urlPart = ".google.cn/vt/hl=zh-CN";
                flag = "z";

                break;
            case MAPLAYER_GOOGLE_IMAGE://Google 影像地图
                subDomains = new String[]{"mt0", "mt1", "mt2", "mt3"};
                urlPart = ".google.cn/vt/lyrs=s@105&hl=zh-CN";
                flag = "z";

                break;
            case MAPLAYER_TIANDI_IMAGE_LABEL://天地图影像地图标注
                subDomains = new String[]{"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"};
                urlPart = ".tianditu.com/DataServer?T=cia_w";
                flag = "l";

                break;
            case MAPLAYER_TIANDI_VECTOR_LABEL://天地图矢量地图标注
                subDomains = new String[]{"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"};
                urlPart = ".tianditu.com/DataServer?T=cva_w";
                flag = "l";
                break;
        }
        if (subDomains != null) {
            String subDomain = subDomains[new Random().nextInt(100) % subDomains.length];

            String url = "http://" + subDomain + urlPart + "&x=%d&" + "y=%d&" + flag + "=%d";
            return url;
        }
        return null;
    }

    public static double getResolution(int level) {
        if (level < resolutions.length)
            return resolutions[level];
        else
            return 1;
    }

    @Override
    protected byte[] getTile(TileKey tileKey) {
        byte[] iResult = null;
        String mapCache = CacheUtil.getMapCache() + "//";
        mapCache += type + "//";
        mapCache += tileKey.getLevel();
        File f0 = new File(mapCache);
        if (!f0.exists()) {
            f0.mkdirs();
        }
        String fileName = String.format("%d_%d.dat", tileKey.getColumn(), tileKey.getRow());
        File f = new File(mapCache + "//" + fileName);
        if (f.exists()) {
            iResult = CacheUtil.ReadFile(f.getPath());
        }
        if (iResult == null || iResult.length == 0) {
            try {
                boolean hasNetwork = MapTilesTool.isNetworkConnected();
                if (!hasNetwork) return null;
                String baseUrl = getUrl(type);
                if (baseUrl == null) return new byte[0];
                String url = String.format(baseUrl, tileKey.getColumn(), tileKey.getRow(), tileKey.getLevel());
                iResult = downTile(url);
                if (iResult != null)
                    CacheUtil.WriteFile(f.getPath(), iResult);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return iResult;
    }

    private byte[] downTile(String iPath) {
        try {
            //对资源链接
            URL url = new URL(iPath);

            InputStream inputStream = url.openStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 开始读取数据
            byte[] buffer = new byte[1024];
            int len = 0;// 每次读取到的数据的长度
            while ((len = inputStream.read(buffer)) != -1) {// len值为-1时,表示没有数据了
                // append方法往sb对象里面添加数据
                outputStream.write(buffer, 0, len);
            }
            inputStream.close();
            // 输出字符串
            return outputStream.toByteArray();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }
}

 

MapTilesTool 类

public class MapTilesTool {

    private static double[] scales = new double[]{591657527.591555,
            295828763.79577702, 147914381.89788899, 73957190.948944002,
            36978595.474472001, 18489297.737236001, 9244648.8686180003,
            4622324.4343090001, 2311162.217155, 1155581.108577, 577790.554289,
            288895.277144, 144447.638572, 72223.819286, 36111.909643,
            18055.954822, 9027.9774109999998, 4513.9887049999998, 2256.994353,
            1128.4971760000001};

    private static double[] resolutions = new double[]{156543.03392800014,
            78271.516963999937, 39135.758482000092, 19567.879240999919,
            9783.9396204999593, 4891.9698102499797, 2445.9849051249898,
            1222.9924525624949, 611.49622628138, 305.748113140558,
            152.874056570411, 76.4370282850732, 38.2185141425366,
            19.1092570712683, 9.55462853563415, 4.7773142679493699,
            2.3886571339746849, 1.1943285668550503, 0.59716428355981721,
            0.29858214164761665};

    public static MapServerTileInfo PJson2MapServerInfo(MapServerPJson pJson) {

        if (pJson == null || pJson.getTileInfo() == null) {
            return null;
        }
        MapServerTileInfo tileInfo = new MapServerTileInfo();
        tileInfo.dpi = pJson.getTileInfo().getDpi();
        tileInfo.tileHeight = pJson.getTileInfo().getCols();
        tileInfo.tileWidth = pJson.getTileInfo().getRows();
        int wkid = pJson.getTileInfo().getSpatialReference().getWkid();
        tileInfo.spatialReference = SpatialReference.create(wkid);
        tileInfo.origin = new Point(pJson.getTileInfo().getOrigin().getX()
                , pJson.getTileInfo().getOrigin().getY()
                , SpatialReference.create(wkid));

        MapServerPJson.FullExtentBean fullExtentBean = pJson.getFullExtent();
        tileInfo.fullExtent = new Envelope(fullExtentBean.getXmin(), fullExtentBean.getYmin(), fullExtentBean.getXmax(),
                fullExtentBean.getYmax(), SpatialReference.create(wkid));
        int i = 0;
        List<LevelOfDetail> levelOfDetails = new ArrayList<>();
        for (MapServerPJson.TileInfoBean.LodsBean lodsBean : pJson.getTileInfo().getLods()) {
            LevelOfDetail detail = new LevelOfDetail(i, lodsBean.getResolution(), lodsBean.getScale());
            levelOfDetails.add(detail);
            i++;
        }
        tileInfo.levelOfDetails = levelOfDetails;
        tileInfo.minScale = pJson.getMinScale();
        tileInfo.maxScale = pJson.getMaxScale();
        return tileInfo;
    }

    public static List<LevelOfDetail> getLevelOfDetails() {

        List<LevelOfDetail> levelOfDetails = new ArrayList<>();
        int level = 0;
        for (; level < scales.length; level++) {
            LevelOfDetail detail = new LevelOfDetail(level, resolutions[level], scales[level]);
            levelOfDetails.add(detail);
        }
        return levelOfDetails;
    }

    public static int getLevel(double scale) {
        int level = scales.length - 1;
        double minStep = Double.MAX_VALUE;
        for (int i = 0; i < scales.length; i++) {
            double sca = scales[i];
            if (Math.abs(scale - sca) < minStep) {
                minStep = Math.abs(scale - sca);
                level = i;
            }
        }
        return level;
    }

    public static double getResolution(int level) {
        if (level < resolutions.length)
            return resolutions[level];
        else
            return 1;
    }
    //是否有网络
    public static boolean isNetworkConnected() {

        ConnectivityManager mConnectivityManager = (ConnectivityManager) NSCApplication.mContext
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        if (mNetworkInfo != null) {
            return mNetworkInfo.isAvailable();
        }
        return false;

    }

}

加载到地图

  final BaseMapLayer webTiledLayer = BaseMapLayer.CreateBaseMapLayer(OtherMapLayer.MAPLAYER_TIANDI_VECTOR);
        webTiledLayer.loadAsync();
        webTiledLayer.addDoneLoadingListener(new Runnable() {
            @Override
            public void run() {
                if (webTiledLayer.getLoadStatus() == LoadStatus.LOADED) {
                    ArcGISMap map = new ArcGISMap(new Basemap(webTiledLayer));
                    mMapView.setMap(map);
                    mMapView.getGraphicsOverlays().add(overlay);
                }
            }
        });

 

BaseMapLayer 中的 getTile中已经实现了缓存瓦片的下载、加载和管理。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值