Android解析TMS地图切片规则,实现离线地图下载

版权声明: https://blog.csdn.net/GISuuser/article/details/83588147

       TMS(Tiled Map Service)切片地图服务,ArcGIS、百度和高德等都给出开发者离线地图下载的接口,但是这些接口仅仅真对他们自己的地图,博主这里自己研究了一下TMS地图切片的规则,在Android上实现了Google地图TMS服务的离线下载,下载到本地后,以后可以根据需要在Android直接加载本地的离线TMS地图。想要在PC运行的话需要自己改成为Java或其他的语言。以后大家用这个程序就可以随意下载在线的TMS地图资源了。

       Google的TMS切片地图是EPSG:3857坐标系,是将地图投影为一个正方形。TMS地图服务的0级即为这个正方形,1级为将这个正方形平分为4个正方形。n级就有4的n次方个正方形。Google的TMS编号规则与标准TMS编号规则不同,不过这并不影响下载,可能影响以后的调用方法。每一级左上角的正方形坐标为(0,0),右下角为(2的n次方-1,2的n次方-1),从左向右为X轴正方希,从上到下有Y轴正方向。http://www.google.cn/maps/vt?lyrs=r@189&gl=cn&x={x}&y={y}&z={z}是一个TMS服务的地址,其实每一个瓦片的地址就是将url中的{x}{y} {z}替换成对应的瓦片坐标即可,z是地图的缩放等级,从0开始。

核心代码如下所示:

  /**
     * 开始下载
     *
     * @param view
     */
    public void downLoad(View view) {
        EditText editText = findViewById(R.id.url);
        url = String.valueOf(editText.getText());
        EditText editText1 = findViewById(R.id.minLevel);
        minLevel = Integer.parseInt(String.valueOf(editText1.getText()));
        EditText editText2 = findViewById(R.id.maxLevel);
        maxLevel = Integer.parseInt(String.valueOf(editText2.getText()));

        for (int z = minLevel; z <= maxLevel; z++) {
            createFolder(storageUrl + "/" + z);
            int maxValue = (int) Math.pow(2, z) - 1;
            Log.e(TAG, "下载第" + z + "级");
            for (int x = 0; x <= maxValue; x++) {
                createFolder(storageUrl + "/" + z + "/" + x);
                for (int y = 0; y <= maxValue; y++) {
                    downImage(getCurrentUrl(x, y, z), storageUrl + "/" + z + "/" + x + "/" + y + ".png");
                }
            }
        }


    }

    /**
     * 通过替换xyz参数生成每一个图片的下载url
     * @param x
     * @param y
     * @param z
     * @return
     */
    String getCurrentUrl(int x, int y, int z) {
        String temp = url.replace("{x}", String.valueOf(x));
        temp = temp.replace("{y}", String.valueOf(y));
        return temp.replace("{z}", String.valueOf(z));
    }

    /**
     * 创建文件夹
     *
     * @param url
     */
    void createFolder(String url) {
        File dir = new File(url);
        // 如果目录不中存在,创建这个目录
        if (!dir.exists())
            if (dir.mkdirs()) {
                Log.e(TAG, url + "创建成功");
            } else {
                Log.e(TAG, url + "创建失败");
            }

    }

    /**
     * 通过OkHttp下载图片
     *
     * @param url
     */
    void downImage(String url, final String filePath) {
        Request request = new Request.Builder().get().url(url).build();
        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "下载失败");
                Log.e(TAG, String.valueOf(e));
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    byte[] picture_bt = response.body().bytes();
                    Bitmap bitmap = BitmapFactory.decodeByteArray(picture_bt, 0, picture_bt.length);
                    Log.e(TAG, String.valueOf(bitmap.getWidth()));
                    Log.e(TAG, String.valueOf(bitmap.getHeight()));
                    File file = new File(filePath);
                    bitMapToPNG(bitmap, file);
                }
            }
        });
    }

    /**
     * Bitmap写入本地文件
     *
     * @param file 图片路径文件
     */
    static void bitMapToPNG(Bitmap bitmap, File file) {
        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            //100为不压缩
            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                out.flush();
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行的效果如下图所示:

下载选项页面

下载结果

需要全部代码运行的可以看码云https://gitee.com/GISuser/DownloadMap

猜你喜欢

转载自blog.csdn.net/GISuuser/article/details/83588147