用多少眼泪才能让你相信 发表于 2025-3-1 17:54:38

高德地图自定义服务器瓦片

项目之前用的天地图,现要求替换成自己服务器的地图瓦片!

1.添加瓦片API
官网和网上很多使用瓦片的教程
private void useOMCMap() {

final String url = "http://tile.opencyclemap.org/cycle/%d/%d/%d.png";

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, x, y));

    } catch (Exception e) {

      e.printStackTrace();

    }

    return null;

    }

});

tileOverlayOptions.diskCacheEnabled(true)

.diskCacheDir("/storage/emulated/0/amap/OMCcache")

.diskCacheSize(100000)

.memoryCacheEnabled(true)

.memCacheSize(100000)

.zIndex(-9999);

mtileOverlay = aMap.addTileOverlay(tileOverlayOptions);

}} 此中URL为在线瓦片所在,具体所在可以查看 天地图API
但我们的需求是使用自己后台提供的URL 大概涉及用户授权获取其他
2.获取服务器自定义瓦片数据
通过网络请求获取瓦片数据 这里使用okhttp
    public synchronized void getImageStream(String url, Callback callback) throws Exception {
      HttpRequestManager.Header[] headers = getHeaders();
      OkHttpClient okhttpclient = HttpRequestManager.manager().getOkClient();
      FormBody formBody = new FormBody.Builder().build();
      Headers head = HttpRequestManager.manager().getDefaultHeaders(null, headers);
      Request request1 = new Request.Builder()
                .url(url)
                .post(formBody)
                .headers(head)
                .build();
      Call call = okhttpclient.newCall(request1);
      call.enqueue(callback);
    } 3.将瓦片数据保存到本地
                getImageStream(real_url, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                              Log.e("AnbUrlTileProvider", "获取瓦片fail");
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                              Log.e("AnbUrlTileProvider", "获取瓦片成功 ==== " + response.toString());
                              if (response.code() == 200 && response.body() != null) {
                                    InputStream in = response.body().byteStream();
                                    try {
                                        //保存瓦片图片数据到本地
                                        saveFile(getImageBitmap(in), mFileName, mFileDirName);
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                              }
                            }

                        }
                ); 4.返回本地瓦片所在 
完整代码如下:
public class AnbUrlTileProvider extends UrlTileProvider {    private final String url = Constants.URL_MAP_TITLE_PROVIDER;//agrcontent/dmz/map/getMap/{z}/{x}/{y}    private final String ALBUM_PATH;    public AnbUrlTileProvider(Context context) {      super(256, 256);      ALBUM_PATH = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath() + "/Cache/";    }    @Override    public URL getTileUrl(int x, int y, int zoom) {      String mFileDirName = String.format("L%02d/", zoom + 1) + "title/";      String mFileName = String.format("%s", TileXYToQuadKey(x, y, zoom));//为了不在手机的图片中显示,取消jpg后缀,文件名自己定义,写入和读取同等即可,由于有自己的bingmap图源服务,所以此处我用的bingmap的文件名      String LJ = ALBUM_PATH + mFileDirName + mFileName;      Log.e("名称是否存在: ", mFileName + "getTileUrl: " + (MapImageCache.getInstance().isBitmapExit(mFileName, ALBUM_PATH + mFileDirName)) + "");      if (MapImageCache.getInstance().isBitmapExit(mFileName, ALBUM_PATH + mFileDirName)) {//判断本地是否有图片文件,如果有返回本地url,如果没有,缓存到本地并返回googleurl            try {                return new URL("file://" + LJ);            } catch (MalformedURLException e) {                throw new RuntimeException(e);            }      } else {            String real_url = String.format(url, zoom, x, y);            try {                //获取服务器 图片二进制数据流                getImageStream(real_url, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                              Log.e("AnbUrlTileProvider", "获取瓦片fail");
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                              Log.e("AnbUrlTileProvider", "获取瓦片成功 ==== " + response.toString());
                              if (response.code() == 200 && response.body() != null) {
                                    InputStream in = response.body().byteStream();
                                    try {
                                        //保存瓦片图片数据到本地
                                        saveFile(getImageBitmap(in), mFileName, mFileDirName);
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                              }
                            }

                        }
                );                return new URL("file://" + LJ);//返回本地瓦片图片路径            } catch (Exception e) {                throw new RuntimeException(e);            }      }    }    /**   * 瓦片数据坐标转换   */    private String TileXYToQuadKey(int tileX, int tileY, int levelOfDetail) {      StringBuilder quadKey = new StringBuilder();      for (int i = levelOfDetail; i > 0; i--) {            char digit = '0';            int mask = 1 << (i - 1);            if ((tileX & mask) != 0) {                digit++;            }            if ((tileY & mask) != 0) {                digit++;                digit++;            }            quadKey.append(digit);      }      return quadKey.toString();    }    /**   * 保存文件   */    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.mkdirs();                            Log.e("创建文件夹", (dirFile.exists()) + "");                        }                        File myCaptureFile = new File(ALBUM_PATH + fileDirName + fileName);                        Log.e("保存路径", myCaptureFile.getPath());                        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));                        bm.compress(Bitmap.CompressFormat.PNG, 80, bos);                        try {                            bos.flush();                        } catch (IOException e) {                            throw new RuntimeException(e);                        }                        bos.close();                  }                } catch (IOException e) {                  e.printStackTrace();                }            }      }).start();    }    public Bitmap getImageBitmap(InputStream imputStream) {      // 将所有InputStream写到byte数组当中      byte[] targetData = null;      if (imputStream != null) {            byte[] bytePart = new byte;            while (true) {                try {                  int readLength = imputStream.read(bytePart);                  if (readLength == -1) {                        break;                  } else {                        byte[] temp = new byte;                        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数组获取数据      return BitmapFactory.decodeByteArray(targetData, 0, targetData.length);    }    public synchronized void getImageStream(String url, Callback callback) throws Exception {
      HttpRequestManager.Header[] headers = getHeaders();
      OkHttpClient okhttpclient = HttpRequestManager.manager().getOkClient();
      FormBody formBody = new FormBody.Builder().build();
      Headers head = HttpRequestManager.manager().getDefaultHeaders(null, headers);
      Request request1 = new Request.Builder()
                .url(url)
                .post(formBody)
                .headers(head)
                .build();
      Call call = okhttpclient.newCall(request1);
      call.enqueue(callback);
    }    private HttpRequestManager.Header[] getHeaders() {      return new HttpRequestManager.Header[]{new HttpRequestManager.Header() {            public String getName() {                return "Content-Type";            }            public String getValue() {                return "image/webp";            }      }, new HttpRequestManager.Header() {            public String getName() {                return HttpRequestManager.SPARTA_ID;            }            public String getValue() {                return DeviceInfoUtil.getDeviceNo(MainApplication.getInstance());            }      }};    }}  使用瓦片后,会涉及地图坐标转换问题 参考Android中GPS坐标转换为高德地图坐标详解_Android_脚本之家 
定位小蓝点坐标会出现漂移
可以通过marker自定义定位图标   在定位后刷新

参考文章:Android 高德地图 添加 天地图 卫星瓦片图片 离线缓存_天地图 离线缓存-CSDN博客 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 高德地图自定义服务器瓦片