GaodeMapsTiledServiceLayer.java 8.24 KB
package com.pashanhoo.landsurvey.layers.gaode;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.util.Log;

import com.esri.android.map.TiledServiceLayer;
import com.esri.android.map.event.OnStatusChangedListener;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.internal.io.handler.ResponseListener;
import com.esri.core.internal.io.handler.a;
import com.esri.core.io.UserCredentials;
import com.pashanhoo.landsurvey.layers.google.GoogleMapLayerTypes;
import com.pashanhoo.landsurvey.utils.AppInfo;
import com.pashanhoo.landsurvey.utils.GADBHelper;

import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.RejectedExecutionException;

/**
 * Created by jiangbotao on 2018/3/28.
 */

public class GaodeMapsTiledServiceLayer extends TiledServiceLayer {
    private static final double xmin = -22041257.773878;
    private static final double ymin = -32673939.6727517;
    private static final double xmax = 22041257.773878;
    private static final double ymax = 20851350.0432886;

    private static final double[] res = {
            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 final double[] scale = {
            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.98186701241,
            18055.954822,
            9027.9774109999998,
            4513.9887049999998,
            2256.994353,
            1128.4971760000001};

    private static String URL = "http://maps.iwxlh.com";
    private ResponseListener responseListener;
    private static Point origin = new Point(-20037508.342787, 20037508.342787);

    private GaodeMapLayerTypes gaodeMapLayerTypes;

    public GaodeMapsTiledServiceLayer(GaodeMapLayerTypes layerType) {
        this(true);
        this.gaodeMapLayerTypes = layerType;
        // 新建数据表,主要在Activity中必须有AppInfo.Settings()初始数据库
        GADBHelper.createTable(AppInfo.mapcachedb, this.gaodeMapLayerTypes.getName());
    }

    public GaodeMapsTiledServiceLayer(boolean initLayer) {
        super(URL);
        this.isBingMap = true;

        if (!(initLayer))
            return;
        try {
            getServiceExecutor().submit(new Runnable() {
                public void run() {
                    GaodeMapsTiledServiceLayer.this.initLayer();
                }
            });
        } catch (RejectedExecutionException localRejectedExecutionException) {
            Log.e("ArcGIS", "initialization of the layer failed.", localRejectedExecutionException);
        }
    }

    public static double getRes(int level) {
        return res[level];
    }

    protected void initLayer() {
        if (getID() == 0L) {
            this.nativeHandle = create();
        }
        if (getID() == 0L) {
            this.changeStatus(OnStatusChangedListener.STATUS.fromInt(-1000));
        } else {
            try {
                this.setDefaultSpatialReference(SpatialReference.create(102100));
                this.setFullExtent(new Envelope(xmin, ymin, xmax, ymax));
                this.setTileInfo(new TileInfo(origin, scale, res, scale.length, 96, 256, 256));
                super.initLayer();
            } catch (Exception localException) {
                this.changeStatus(OnStatusChangedListener.STATUS.fromInt(-1005));
                Log.e("ArcGIS", "Bing map url =" + getUrl(), localException);
            }
        }
    }

    @SuppressLint("DefaultLocale")
    protected byte[] getTile(int level, int col, int row) throws Exception {
        byte[] result = null;

        String url = "";
        String s = "Galil";
        switch (gaodeMapLayerTypes) {
            case AMAP_VECTOR:
                url = "http://webrd01.is.autonavi.com/appmaptile?&x=" + col + "&y=" + row + "&z=" + level +
                        "&lang=zh_cn&size=1&scale=1&style=7";
                break;
            case AMAP_IMAGE:
                url = "http://webst02.is.autonavi.com/appmaptile?style=6&x=" + col + "&y=" + row + "&z=" + level;
                break;
            case AMAP_ROAD:
                url = "http://webst02.is.autonavi.com/appmaptile?style=8&x=" + col + "&y=" + row + "&z=" + level;
                break;
            case AMAP_TRAFFIC:
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
                int day = calendar.get(Calendar.DAY_OF_WEEK);
                int hh = calendar.get(Calendar.HOUR_OF_DAY);
                int mm = calendar.get(Calendar.MINUTE);
                url = "http://history.traffic.amap.com/traffic?type=2" + "&day=" + day + "&hh=" + hh + "&mm=" + mm
                        + "&x=" + col + "&y=" + row + "&z=" + level;
                break;
        }

        try {
            // 首先从离线数据库中读取
            result = getOfflineCacheDB(level, col, row);
            // 如果没有就直接从web上读取
            if (result == null) {
                result = a.a(url, null, null, this.responseListener);
                // 将读取的数据存入mbtiles中
                AddOfflineCacheDB(level, col, row, result);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return result;
    }

    public void refresh() {
        try {
            getServiceExecutor().submit(new Runnable() {
                public void run() {
                    if (!(GaodeMapsTiledServiceLayer.this.isInitialized()))
                        return;
                    try {
                        GaodeMapsTiledServiceLayer.this.clearTiles();
                    } catch (Exception localException) {
                        Log.e("ArcGIS", "Re-initialization of the layer failed.", localException);
                    }
                }
            });
        } catch (RejectedExecutionException localRejectedExecutionException) {
            return;
        }
    }

    public void reinitializeLayer(UserCredentials usercredentials) {
    }

    public void reinitializeLayer(String appID) {
        super.reinitializeLayer(null);
    }

    private byte[] getOfflineCacheDB(int level, int col, int row) throws Exception {

        byte[] result = null;
        String sql = "select * from " + this.gaodeMapLayerTypes.getName() + " where TILELEVEL = " +
                level + " and TILECOL = " + col + " and TILEROW = " + row;
        Cursor mCursor = AppInfo.mapcachedb.rawQuery(sql, null);
        boolean hasData = false;

        while (mCursor.moveToNext()) {//判断是否存在数据
            hasData = true;
        }
        if (hasData) {//数据库中有数据
            try {
                if (mCursor.moveToFirst()) {
                    result = mCursor.getBlob(mCursor.getColumnIndex("TILEDATA"));
                }
                mCursor.close();
            } catch (Exception e) {
                e.printStackTrace();
                result = null;
            }
        }
        return result;
    }

    private void AddOfflineCacheDB(int level, int col, int row, byte[] bytes) {
        ContentValues values = new ContentValues();
        values.put("TILELEVEL", level);
        values.put("TILECOL", col);
        values.put("TILEROW", row);
        values.put("TILEDATA", bytes);

        AppInfo.mapcachedb.insert(this.gaodeMapLayerTypes.getName(), null, values);
    }
}