项目之前用的天地图,现要求替换成自己服务器的地图瓦片!
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[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数组获取数据 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企服之家,中国第一个企服评测及商务社交产业平台。 |