每次放大/缩小时,OsmDroid 都会检查地图视图当前边界内的每个图块索引是否存在图块副本。如果存在副本,将从切片缓存中复制并绘制在地图上。如果没有,将从在线地图切片数据库下载切片并在地图上绘制。下载的切片将保存在切片缓存中,以便下次这些切片索引位于视图边界中时快速检索。
但是,它确实涉及处理每个事件的大量 tile 模块提供程序对象。它们保存在MapView.setTileProvider() 调用中设置的MapTileModuleProviderBase tile 模块提供程序数组中。如果不包含地图瓦片下载模块提供程序,则不会从 Internet/网络下载任何瓦片;相反,它将从任何附加的 tile 模块提供程序中检索副本:缓存 tile 模块提供程序、资产 tile 模块提供程序、文件存档模块提供程序等。如果切片模块提供程序数组中缺少任何这些切片提供程序,则该切片索引的切片将无法正确绘制,您将看到一个空的灰色“切片”方块。
这些 tile 模块提供程序可以参考 OsmDroid 默认配置实例 DefaultConfigurationProvider,以获取控制 tile 过期率、缓存大小等的属性。这些属性会影响瓷砖绘制性能。
如果您使用 OsmDroid 特定的 tile 模块提供程序 API(MapsForge、GeoPackage、WMS 等)加载可能会更改当前 tile 模块提供程序数组结构的在线/离线地图数据库,请按照以下步骤正确重置为 MAPNIK 数据库:
//load MAPNIK basemap updateable from Internet and cacheable
IFilesystemCache tileWriter = null;
INetworkAvailablityCheck networkAvailabilityCheck = new NetworkAvailabliltyCheck(getContext());
List<MapTileModuleProviderBase> defaultProviders = new ArrayList<>();
SimpleRegisterReceiver simpleRegisterReceiver = new SimpleRegisterReceiver(getContext());
if (Build.VERSION.SDK_INT < 10) {
tileWriter = new TileWriter();
} else {
tileWriter = new SqlTileWriter();
}
defaultProviders.add(new MapTileAssetsProvider(simpleRegisterReceiver, getContext().getAssets()));
final MapTileAssetsProvider assetsProvider = new MapTileAssetsProvider(
simpleRegisterReceiver, getContext().getAssets(), TileSourceFactory.MAPNIK);
defaultProviders.add(assetsProvider);
final MapTileFileStorageProviderBase cacheProvider =
MapTileProviderBasic.getMapTileFileStorageProviderBase(simpleRegisterReceiver, TileSourceFactory.MAPNIK, tileWriter);
defaultProviders.add(cacheProvider);
final MapTileFileArchiveProvider archiveProvider = new MapTileFileArchiveProvider(
simpleRegisterReceiver, TileSourceFactory.MAPNIK);
defaultProviders.add(archiveProvider);
final MapTileApproximater approximationProvider = new MapTileApproximater();
defaultProviders.add(approximationProvider);
approximationProvider.addProvider(assetsProvider);
approximationProvider.addProvider(cacheProvider);
approximationProvider.addProvider(archiveProvider);
final MapTileDownloader downloaderProvider = new MapTileDownloader(TileSourceFactory.MAPNIK, tileWriter, networkAvailabilityCheck);
defaultProviders.add(downloaderProvider);
MapTileModuleProviderBase[] providerArray = new MapTileModuleProviderBase[defaultProviders.size()];
for (int i = 0; i < defaultProviders.size(); i++) {
providerArray[i] = defaultProviders.get(i);
}
Log.i(IMapView.LOGTAG, String.format("reset MAPNIK: current tile module providers(%d) = %s",
providerArray.length,
Arrays.toString(providerArray)));
MapTileProviderArray obj = new MapTileProviderArray(TileSourceFactory.DEFAULT_TILE_SOURCE, simpleRegisterReceiver, providerArray);
mapView.setTileProvider(obj);
mapView.setTileSource(TileSourceFactory.MAPNIK);
通常,我们不需要显式调用MapView.invalidate() 或MapView.postInvalidate(),因为这是由 MapView 处理的瓦片资源。
public void setTileProvider(final MapTileProviderBase base) {
this.mTileProvider.detach();
mTileProvider.clearTileCache();
this.mTileProvider = base;
mTileProvider.getTileRequestCompleteHandlers().add(mTileRequestCompleteHandler);
updateTileSizeForDensity(mTileProvider.getTileSource());
this.mMapOverlay = new TilesOverlay(mTileProvider, this.getContext(), horizontalMapRepetitionEnabled, verticalMapRepetitionEnabled);
mOverlayManager.setTilesOverlay(mMapOverlay);
invalidate();
}