首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >osmdroid映射块只在缩放后加载。

osmdroid映射块只在缩放后加载。
EN

Stack Overflow用户
提问于 2022-03-13 20:53:12
回答 3查看 174关注 0票数 2

每次新安装后,我的MapView中的瓷砖只会在放大相当多之后加载。之后效果很好,但我不知道是什么原因造成的。调试日志如下:

代码语言:javascript
运行
复制
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,如下所示:

代码语言:javascript
运行
复制
map = requireView().findViewById(R.id.map);
map.setTileSource(TileSourceFactory.MAPNIK);
map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
map.setMultiTouchControls(true);

获得位置修复后,将执行以下操作:

代码语言:javascript
运行
复制
IMapController mapController = map.getController();
mapController.setZoom(10.0);
GeoPoint startingPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
mapController.setCenter(startingPoint);

我遵循了osmdroid教程,设置了用户代理,向清单添加了必要的权限,等等。如果您需要进一步的信息,请告诉我。

编辑:我使用的是6.1.11版本

EN

回答 3

Stack Overflow用户

发布于 2022-04-14 07:21:39

更新:

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

这将是发条源试图从其上提取图像的网址。如你所见,瓷砖就在那里。

你试过让地图无效来强制重绘吗?

代码语言:javascript
运行
复制
map.invalidate()
票数 1
EN

Stack Overflow用户

发布于 2022-08-11 18:26:35

我确实有这个问题。看起来,如果您最初设置的缩放级别> 19,则不会正确呈现瓷砖。

作为解决办法,我将缩放级别设置为19,而不是20。然后用户可以随意设置它。

票数 1
EN

Stack Overflow用户

发布于 2022-08-23 10:31:09

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

但是,它涉及大量处理每个事件的块模块提供程序对象。它们保存在在MapTileModuleProviderBase调用中设置的MapView.setTileProvider()块模块提供程序数组中。如果地图瓷砖下载模块提供程序不包括在内,它将不会从Internet/网络下载任何瓷砖;相反,它将从任何附加的瓷砖模块提供程序(缓存瓷砖模块提供程序、资产瓦片模块提供程序、文件存档模块提供程序等)检索副本。如果瓷砖模块提供程序数组中缺少任何这些瓷砖提供程序,则该平铺索引的平铺将无法正确绘制,您将看到一个空的灰色“瓷砖”方格。

这些平铺模块提供程序可以引用OsmDroid默认配置实例DefaultConfigurationProvider,以获得控制瓷砖过期率、缓存大小等的属性。这些属性会影响瓷砖的拉伸性能。

如果使用特定于OsmDroid的模块提供程序API (MapsForge、GeoPackage、WMS等)若要加载可能更改当前块模块提供程序数组结构的联机/脱机地图数据库,请按照以下步骤正确重置到MAPNIK数据库:

代码语言:javascript
运行
复制
//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处理的。

代码语言:javascript
运行
复制
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视图无效来强制重绘。太频繁地调用失效会对应用程序的性能产生负面影响。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71460758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档