1. 程式人生 > >Android的關於高德地圖載入谷歌瓦片,並快取本地的功能.

Android的關於高德地圖載入谷歌瓦片,並快取本地的功能.

最近開發的Android的App需要使用到衛星圖,不過發現國內現有的百度,高德的衛星圖對郊區圖層支援的不好,只能使用谷歌的衛星圖.

在嘗試使用谷歌的Google Map API for Android後又發現去要手機安裝谷歌服務,並且有可能用到科學上網.所以就想有沒有一個既能載入谷歌衛星圖的,又不需要安裝谷歌服務.

最後找到了osmdroid,經過一段時間的研究,發現使用osmdroid的還是少數,教程不多.

最後偶爾的一個機會看到了虎虎之王的部落格

就打算從這下手了.再次感謝虎虎之王.

中途還有一些博主的文章被參閱,可惜沒有記下具體連結,望海涵.

在原作者的基礎上,我修改了圖源,用於載入谷歌的衛星圖,並且在第一次載入的時候,自動快取本地,既能在二次載入減少載入時間,又能節省流量,畢竟是手機使用.流量能省則省

上主要程式碼:

/**
     * 載入線上瓦片資料
     */
    private void useOMCMap() {
        final String url =  "http://www.google.cn/maps/vt?lyrs=y&gl=cn&x=%d&s=&y=%d&z=%d";
        //final String url =  "http://mt1.google.cn/vt/lyrs=y&hl=zh-CN&gl=cn&x=%d&s=&y=%d&z=%d";

        TileOverlayOptions tileOverlayOptions =
                new TileOverlayOptions().tileProvider(new UrlTileProvider(256, 256) {
                    @Override
                    public URL getTileUrl(int x, int y, int zoom) {
                        try {
                            //return new URL(String.format(url, zoom + 1, TileXYToQuadKey(x, y, zoom)));
                            //return new URL(String.format(url, x, y, zoom));
                            String mFileDirName;
                            String mFileName;
                            mFileDirName = String.format("L%02d/", zoom + 1);
                            mFileName = String.format("%s", TileXYToQuadKey(x, y, zoom));//為了不在手機的圖片中顯示,下載的圖片取消jpg字尾,檔名自己定義,寫入和讀取一致即可,由於有自己的bingmap圖源服務,所以此處我用的bingmap的檔名
                            String LJ = ALBUM_PATH +mFileDirName+ mFileName;
                            if (MapImageCache.getInstance().isBitmapExit( mFileDirName + mFileName)) {//判斷本地是否有圖片檔案,如果有返回本地url,如果沒有,快取到本地並返回googleurl
                                return new URL("file://" + LJ);
                            } else {
                                String filePath = String.format(url, x, y, zoom);
                                Bitmap mBitmap;
                                //mBitmap = BitmapFactory.decodeStream(getImageStream(filePath));//不知什麼原因導致有大量的圖片存在壞圖,所以重寫InputStream寫到byte陣列方法
                                mBitmap = getImageBitmap(getImageStream(filePath));
                                try {
                                    saveFile(mBitmap, mFileName, mFileDirName);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                return new URL(filePath);
                            }
                        }catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                });
        tileOverlayOptions.diskCacheEnabled(false)   //由於高德自帶的瓦片快取在關閉程式後會自動清空,所以無意義,關閉本地快取
                .diskCacheDir("/storage/emulated/0/amap/OMCcache")
                .diskCacheSize(1024000)
                .memoryCacheEnabled(true)
                .memCacheSize(102400)
                .zIndex(-9999);
        mtileOverlay = aMap.addTileOverlay(tileOverlayOptions);
    }

瓦片資料下載途中發現會有圖片出現黑塊,格式損壞的問題,參考了下面的文章進行解決.

    public Bitmap getImageBitmap(InputStream imputStream){
        // 將所有InputStream寫到byte陣列當中
        byte[] targetData = null;
        byte[] bytePart = new byte[4096];
        while (true) {
            try {
                int readLength = imputStream.read(bytePart);
                if (readLength == -1) {
                    break;
                } else {
                    byte[] temp = new byte[readLength + (targetData == null ? 0 : targetData.length)];
                    if (targetData != null) {
                        System.arraycopy(targetData, 0, temp, 0, targetData.length);
                        System.arraycopy(bytePart, 0, temp, targetData.length, readLength);
                    } else {
                        System.arraycopy(bytePart, 0, temp, 0, readLength);
                    }
                    targetData = temp;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 指使Bitmap通過byte陣列獲取資料
        Bitmap bitmap = BitmapFactory.decodeByteArray(targetData, 0, targetData.length);
        return bitmap;
    }

最終儲存圖片的程式碼!

    /**
     * 儲存檔案
     */
    public void saveFile(final Bitmap bm, final String fileName,final String fileDirName)  throws IOException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if(bm != null) {
                        File dirFile = new File(ALBUM_PATH + fileDirName);
                        if(!dirFile.exists()){
                            dirFile.mkdir();
                        }
                        File myCaptureFile = new File(ALBUM_PATH + fileDirName + fileName);
                        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
                        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
                        bos.flush();
                        bos.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

demo下載地址:

https://download.csdn.net/download/zfcomfort/10447822