Android Google Maps API本地TileOverlay不显示,如何生成Asset有效URL?
解决Android Google Maps TileOverlay加载本地Assets瓦片的问题
这个问题我之前也碰到过!UrlTileProvider确实没法直接识别file:///android_asset的URL,因为这个URL scheme是Android WebView特有的解析规则,Google Maps的TileProvider并不支持。咱们换个思路,直接从Assets里读取瓦片文件的字节流来创建Tile就行,具体步骤如下:
1. 自定义AssetTileProvider类
不用继承UrlTileProvider,直接实现TileProvider接口,通过AssetManager读取assets目录下的瓦片文件:
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import com.google.android.gms.maps.model.Tile; import com.google.android.gms.maps.model.TileProvider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class AssetTileProvider implements TileProvider { private static final int TILE_SIZE = 256; private final Context mContext; public AssetTileProvider(Context context) { mContext = context; } @Override public Tile getTile(int x, int y, int zoom) { // 注意:如果你的瓦片是标准TMS坐标系生成的,需要翻转y轴 // y = (1 << zoom) - 1 - y; String tilePath = "tiles/" + x + "-" + y + "-" + zoom + ".png"; InputStream inputStream = null; try { inputStream = mContext.getAssets().open(tilePath); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); if (bitmap != null) { byte[] tileData = bitmapToByteArray(bitmap); return new Tile(TILE_SIZE, TILE_SIZE, tileData); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // 文件不存在或读取失败时返回空瓦片 return NO_TILE; } private byte[] bitmapToByteArray(Bitmap bitmap) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); bitmap.recycle(); return byteArray; } }
2. 在onMapReady中使用自定义TileProvider
替换原来的UrlTileProvider,换成我们的AssetTileProvider:
@Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; TileProvider tileProvider = new AssetTileProvider(this); TileOverlay tileOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider)); }
关键注意点
- 坐标系适配:如果你的瓦片是用标准TMS工具生成的,Google Maps的y轴坐标系是翻转的,需要在
getTile方法里添加y = (1 << zoom) - 1 - y的转换,否则瓦片位置会出错。 - 瓦片尺寸:确保你的PNG瓦片是256x256像素,和代码里的
TILE_SIZE保持一致。 - 异常处理:代码里已经处理了文件不存在的情况,返回
NO_TILE会让Google Maps跳过该瓦片,避免应用崩溃。
这样修改后,就能直接从Assets目录加载本地瓦片,完全不需要联网也能正常显示TileOverlay了!
内容的提问来源于stack exchange,提问作者remjln
相关产品推荐
相关产品推荐

