每次新安装后,我的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
...
我在MapView中初始化了onViewCreated
,如下所示:
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版本
发布于 2022-04-14 07:21:39
更新:
https://tile.openstreetmap.org/1/0/0.png
这将是发条源试图从其上提取图像的网址。如你所见,瓷砖就在那里。
你试过让地图无效来强制重绘吗?
map.invalidate()
发布于 2022-08-11 18:26:35
我确实有这个问题。看起来,如果您最初设置的缩放级别> 19,则不会正确呈现瓷砖。
作为解决办法,我将缩放级别设置为19,而不是20。然后用户可以随意设置它。
发布于 2022-08-23 10:31:09
每次放大/缩小时,OsmDroid都会检查地图视图当前边界内的每个平铺索引是否有平铺的副本。如果副本存在,它将从平铺缓存中复制并在地图上绘制。如果没有,则将从在线地图平铺数据库下载该瓷砖并在地图上绘制。下载的平铺将保存在瓷砖缓存中,以便下次这些平铺索引在视图的边界上快速检索。
但是,它涉及大量处理每个事件的块模块提供程序对象。它们保存在在MapTileModuleProviderBase
调用中设置的MapView.setTileProvider()
块模块提供程序数组中。如果地图瓷砖下载模块提供程序不包括在内,它将不会从Internet/网络下载任何瓷砖;相反,它将从任何附加的瓷砖模块提供程序(缓存瓷砖模块提供程序、资产瓦片模块提供程序、文件存档模块提供程序等)检索副本。如果瓷砖模块提供程序数组中缺少任何这些瓷砖提供程序,则该平铺索引的平铺将无法正确绘制,您将看到一个空的灰色“瓷砖”方格。
这些平铺模块提供程序可以引用OsmDroid默认配置实例DefaultConfigurationProvider
,以获得控制瓷砖过期率、缓存大小等的属性。这些属性会影响瓷砖的拉伸性能。
如果使用特定于OsmDroid的模块提供程序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处理的。
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的任何属性,则必须调用适当的map视图无效来强制重绘。太频繁地调用失效会对应用程序的性能产生负面影响。
https://stackoverflow.com/questions/71460758
复制相似问题