Android TileProvider加载assets内PNG地图时重复显示多次如何解决
问题原因与解决方案
你的地图重复显示是代码里的几个核心错误导致的,对应修复逻辑如下:
String.format("map.png", zoom, x, y)写法错误:字符串模板没有%d占位符,不管瓦片请求的坐标、缩放等级是什么,永远读取同一张map.png,所有网格位置的瓦片都返回同一张图,自然会重复铺满整个地图。new Tile(256, 356, file)参数错误:谷歌地图标准瓦片尺寸为256*256,错误的高度会导致瓦片渲染错位、拉伸重复。- 没有做有效范围校验:超出你自定义地图覆盖范围的瓦片请求也会返回你的PNG图,移动、缩放地图时就会出现多份重复的地图。
修复后的代码示例
如果你的需求是单张PNG作为固定区域的地图覆盖层,先确认这张图对应的缩放等级、瓦片坐标范围,只有请求落在有效范围内时才返回你的图片,否则返回空瓦片即可:
// 按照你的实际地图参数调整以下有效值 private static final int TARGET_ZOOM = 10; // 你的PNG对应的缩放等级 private static final int VALID_X = 123; // 你的PNG对应的瓦片X坐标 private static final int VALID_Y = 456; // 你的PNG对应的瓦片Y坐标 TileProvider tileProvider = new TileProvider() { @Override public Tile getTile(int x, int y, int zoom) { // 不在有效范围内的请求返回空瓦片,不会渲染你的图片 if (zoom != TARGET_ZOOM || x != VALID_X || y != VALID_Y) { return TileProvider.NO_TILE; } try { InputStream inputStream = getAssets().open("map.png"); byte[] buffer = new byte[8192]; int bytesRead; ByteArrayOutputStream output = new ByteArrayOutputStream(); while ((bytesRead = inputStream.read(buffer)) != -1) { output.write(buffer, 0, bytesRead); } byte file[] = output.toByteArray(); // 修正瓦片尺寸为256*256,如果你提前裁剪为其他尺寸请对应修改 Tile result = new Tile(256, 256, file); return result; } catch (Exception e) { e.printStackTrace(); } return TileProvider.NO_TILE; } }; TileOverlay tileOverlay = mMap.addTileOverlay(new TileOverlayOptions() .tileProvider(tileProvider) .zIndex(3000));
额外优化建议
- 如果你是多瓦片拼接的自定义地图,把所有瓦片按
缩放等级/X坐标/Y坐标.png的规则放到assets对应目录,读取时把文件路径改为String.format("%d/%d/%d.png", zoom, x, y)即可正常加载对应位置的瓦片,不会重复。 - 本地瓦片加载建议增加内存缓存,避免每次请求都重复读取assets文件,提升渲染流畅度。
内容的提问来源于stack exchange,提问作者Mohammed khalefa
相关产品推荐
相关产品推荐

