简体   繁体   English

osmdroid map 磁贴仅在缩小后加载

[英]osmdroid map tiles only load after zooming out

After each fresh install tiles in my MapView only load after zooming out quite a bit.在我的MapView中每次全新安装磁贴后,仅在缩小相当多后才会加载。 After that it works fine, but I can't figure out what causes this.之后它工作正常,但我无法弄清楚是什么原因造成的。 The debug logs are as follows:调试日志如下:

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
...

I have initialized my MapView in onViewCreated like this:我已经在onViewCreated中初始化了我的 MapView,如下所示:

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

And once I obtained a location fix, the following is executed:一旦我获得了位置修复,就会执行以下操作:

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

I have followed the osmdroid tutorial, set the user agent, added the necessary permissions to the manifest and so on.我已经按照 osmdroid 教程,设置了用户代理,向清单添加了必要的权限等等。 Please let me know, if you need further information.如果您需要更多信息,请告诉我。

Edit: I'm using version 6.1.11编辑:我使用的是 6.1.11 版

Updated:更新:

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

This would be the url the tilesource is trying to pull the image from.这将是 tilesource 试图从中提取图像的 url。 And as you can see the tile is there.正如你所看到的那样,瓷砖就在那里。

have you tried invalidating the map to force a redraw?您是否尝试过使 map 无效以强制重绘?

map.invalidate()

I had this exact problem.我有这个确切的问题。 It seems that if you initially set any zoom level > 19, tiles are not rendered correctly.似乎如果您最初设置的任何缩放级别 > 19,瓷砖都不会正确渲染。

As a workaround I set zoom level to 19 instead of 20. Then the user is able to set it as he likes作为一种解决方法,我将缩放级别设置为 19 而不是 20。然后用户可以根据自己的喜好进行设置

Every time you zoom in/out, OsmDroid checks to see if there is a copy of the tile for every tile index within the map view's current boundary.每次放大/缩小时,OsmDroid 都会检查 map 视图当前边界内的每个图块索引是否存在图块副本。 If a copy exists, it will be copied from the tile cache and drawn on the map.如果存在副本,将从切片缓存中复制并绘制在 map 上。 If not, the tile will be downloaded from the online map tile database and drawn on the map.如果没有,将从在线 map 瓷砖数据库下载瓷砖并在 map 上绘制。 The downloaded tile will be saved in the tile cache for quick retrieval the next time those tile indices are in the view's boundary.下载的切片将保存在切片缓存中,以便下次这些切片索引位于视图边界中时快速检索。

It does, however, involve a significant number of tile module provider objects that handle each event.但是,它确实涉及处理每个事件的大量 tile 模块提供程序对象。 They are saved in the MapTileModuleProviderBase tile module provider array that is set in MapView.setTileProvider() call.它们保存在MapView.setTileProvider()调用中设置的MapTileModuleProviderBase切片模块提供程序数组中。 If the map tile download module provider is not included, it will not download any tiles from the Internet/network;如果不包括 map 瓦片下载模块提供程序,则不会从 Internet/网络下载任何瓦片; instead, it will retrieve a copy from any attached tile module providers: cache tile module provider, assets tile module provider, file archive module provider, and so on.相反,它将从任何附加的 tile 模块提供程序中检索副本:缓存 tile 模块提供程序、资产 tile 模块提供程序、文件存档模块提供程序等。 If any of those tile providers are missing from the tile module provider array, the tile for that tile index will not be drawn properly and you will see an empty grey "tile" square.如果切片模块提供程序数组中缺少任何这些切片提供程序,则该切片索引的切片将无法正确绘制,您将看到一个空的灰色“切片”方块。

These tile module providers may refer to the OsmDroid default configuration instance, the DefaultConfigurationProvider , for properties that control tile expiration rate, cache size, and so on.这些 tile 模块提供程序可以参考 OsmDroid 默认配置实例DefaultConfigurationProvider ,用于控制 tile 过期率、缓存大小等的属性。 These properties affect the tile draw performance.这些属性会影响瓷砖绘制性能。

If you use OsmDroid-specific tile module provider API (MapsForge, GeoPackage, WMS, etc.) to load online/offline map databases which may change the current tile module provider array structure, follow these steps to properly reset to the MAPNIK database:如果您使用 OsmDroid 特定的 tile 模块提供程序 API(MapsForge、GeoPackage、WMS 等)来加载在线/离线 map 数据库,这可能会更改当前的 tile 模块提供程序数组结构,请按照以下步骤正确重置到 MAPNK 数据库:


//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);

Normally, we don't need to explicitly call MapView.invalidate() (if called from a UI thread) or MapView.postInvalidate() (if called from a non-UI thread) since this is handled by MapView for tile resources.通常,我们不需要显式调用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();
}

If you change any of MapView's properties in a thread again, you must call the appropriate map view invalidation to force the redraw.如果您再次在线程中更改任何 MapView 的属性,则必须调用相应的 map 视图失效以强制重绘。 Calling invalidation too frequently will have a negative impact on the app's performance.过于频繁地调用失效会对应用程序的性能产生负面影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM