高德地图更换瓦片指南 小坑
前段时间接了一个高德地图,用到了瓦片数据替换的api,过程中有一些小坑,在官网找具体的说明执照到了切换地图图层,但是那只是切换地图白天黑夜的一个显示而已,根本无法实现。然后就找不到对应的api介绍了,后来下载官方demo,只看到了在线加载的,后台数据也是官方的文件数据,有这么一段代码,
/** * 加载在线瓦片数据 */
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);
}}
但是却没有提到本地加载是怎么加载的,后来在一篇博文上看到:
/** * 加载离线瓦片数据 */
private void useOfflineTile() {
final String url = "file:///storage/emulated/0/tiles/tiles/%d/%d/%d.jpg";
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/tilecache")
.diskCacheSize(100000)
.memoryCacheEnabled(true)
.memCacheSize(100000)
.zIndex(-9999);
mtileOverlay = aMap.addTileOverlay(tileOverlayOptions);
}
可以看到离线和在线的加载方式基本上一样,只不过路径地址变换了一下,需要加上几个占位符,结果运行后发现并不起什么作用,又翻了很多资料,发现高德
已经换了方式去加载离线的,采用了:
class LocalTileProvider implements TileProvider{
private static final int TILE_WIDTH = 256;
private static final int TILE_HEIGHT = 256;
public static final int BUFFER_SIZE = 16 * 1024;
private String tilePath;
public LocalTileProvider(String path) {
tilePath=path;
}
@Override
public Tile getTile(int x, int y, int zoom) {
byte[] image = readTileImage(x, y, zoom);
return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT, image);
}
private byte[] readTileImage(int x, int y, int zoom) {
InputStream in = null;
ByteArrayOutputStream buffer = null;
File f = new File(getTileFilename(x, y, zoom));
if(f.exists()){
try {
buffer = new ByteArrayOutputStream();
in = new FileInputStream(f);
int nRead;
byte[] data = new byte[BUFFER_SIZE];
while ((nRead = in.read(data, 0, BUFFER_SIZE)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
} finally {
if (in != null) try { in.close(); } catch (Exception ignored) {}
if (buffer != null) try { buffer.close(); } catch (Exception ignored) {}
}
}else{
return null;
}
}
private String getTileFilename(int x, int y, int zoom) {
return tilePath + zoom + "/tile" + x + "_" + y + ".png";
}
@Override
public int getTileWidth() {
return TILE_HEIGHT;
}
@Override
public int getTileHeight() {
return TILE_WIDTH;
}
}
然后去通过下面这段代码来引入的:
final String sdCardPath = Environment.getExternalStorageDirectory().getPath();
TileProvider tileProvider = new LocalTileProvider(sdCardPath + File.separator + "tiles/");
Log.e("","地址"+sdCardPath + File.separator + "tiles/%d/");
map.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
可以看到上面标红的代码,路径问题曾一度为难我,按照图片的命名规则:
tilePath
+ zoom + "/tile" + x + "_" + y + ".png"
根目录/tiles/缩放比zoom/拼接的文件名
也就是如下图的路径:
设置好后,在onresume里加载即可,还有就是这个图是通过工具切出来的,输入经纬度,就会根据一系列算法,将这个图片
自动给切出来,生成这些文件。
最后测试的时候定位到那个经纬度地点,定位到zoom层级下,就可看到替换了的瓦片数据,如下图:
提供一些我查阅的资料和工具:
切图的下载地址:http://www.1hwj.net/down/tiler32_64.zip
大牛的博客:http://blog.****.net/bq_cui/article/details/47372005
:http://blog.****.net/xiaolaohuqwer/article/details/71583651