osmdroid地图分块仅在缩小后加载



在我的MapView中每次新安装瓷砖后,只在缩小一点后加载。在那之后,它工作得很好,但我不知道是什么原因造成的。调试日志如下:

D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/1/0/0
D/OsmDroid: Archives - Tile doesn't exist: /1/0/0
D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/3/1/3
D/OsmDroid: Archives - Tile doesn't exist: /3/1/3
D/OsmDroid: SqlCache - Tile doesn't exist: Mapnik/5/5/12
...

我已经在onViewCreated中初始化了我的MapView,如下所示:

map = requireView().findViewById(R.id.map);
map.setTileSource(TileSourceFactory.MAPNIK);
map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
map.setMultiTouchControls(true);

一旦我获得了位置修复,就会执行以下操作:

IMapController mapController = map.getController();
mapController.setZoom(10.0);
GeoPoint startingPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
mapController.setCenter(startingPoint);

我已经学习了osmdroid教程,设置了用户代理,向清单添加了必要的权限等等。如果你需要更多信息,请告诉我。

编辑:我使用的是6.1.11版

我遇到了这个问题。似乎如果您最初设置任何缩放级别>19,瓷砖未正确渲染。

作为一种变通方法,我将缩放级别设置为19,而不是20。然后用户可以根据自己的喜好设置

每次放大/缩小时,OsmDroid都会检查地图视图当前边界内的每个平铺索引是否都有平铺的副本。如果存在副本,则会将其从平铺缓存中复制并绘制在地图上。如果没有,将从在线地图分幅数据库下载分幅,并在地图上绘制。下载的磁贴将保存在磁贴缓存中,以便下次这些磁贴索引位于视图边界时快速检索。

然而,它确实涉及大量处理每个事件的tile模块提供程序对象。它们保存在MapView.setTileProvider()调用中设置的MapTileModuleProviderBase瓦片模块提供程序数组中。如果不包括地图瓦片下载模块提供商,则其将不会从互联网/网络下载任何瓦片;相反,它将从任何附加的磁贴模块提供程序中检索副本:缓存磁贴模块提供方、资产磁贴模块提供者、文件存档模块提供者等等;瓦片";广场

这些磁贴模块提供程序可能会参考OsmDroid默认配置实例DefaultConfigurationProvider,以获取控制磁贴过期率、缓存大小等的属性。这些属性会影响磁贴绘制性能。

如果您使用OsmDroid-specific磁贴模块提供程序API(MapsForge、GeoPackage、WMS等(加载在线/离线地图数据库,这可能会更改当前磁贴模块提供方阵列结构,请按照以下步骤正确重置到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()(如果从UI线程调用(或MapView.postInvalidate()(如果从非UI线程调用的话(,因为这是由MapView为tile资源处理的。

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();
}

如果在线程中再次更改MapView的任何属性,则必须调用相应的地图视图无效来强制重绘。过于频繁地调用无效将对应用程序的性能产生负面影响。

更新:

https://tile.openstreetmap.org/1/0/0.png

这将是tilesource试图从中提取图像的url。正如你所看到的,瓷砖就在那里。

你有没有试过让地图失效以强制重画?

map.invalidate()

最新更新