缩放 in/out 某些图块未呈现 - Osmdroid 离线地图
Zooming in/out some tiles not rendering - Osmdroid offline maps
我正在从资产中加载图块,这些是我的代码,用于初始化地图:
mapView = (MapView)findViewById(R.id.offline_map_view);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(false);
mapView.setMaxZoomLevel(macroZoomLevel);
mapView.setMinZoomLevel(macroZoomLevel);
mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
mapView.setTileSource(new XYTileSource("MapQuest", 0, 18, 256, ".png",new String[] {"file:///android_asset/try/"} ));
mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
giveMarkersForActualLevel();
一切正常,直到我尝试放大,有部分地图无法正确渲染。然后我缩小,开始时正确渲染的区域现在有一些灰色瓷砖。
首先我用的是osmdroid 4.3,是这样添加的:
compile 'org.osmdroid:osmdroid-android:4.3'
然后我尝试使用最新版本的 osmdroid,通过 website compile 'org.osmdroid:osmdroid-android:5.1@aar'
中描述的方法导入它
然后我阅读了 here tu build from sources 所以我下载了最新的源代码,通过 gradle 构建它并添加了 aar
文件 osmdroid-android-release.aar
。
这也不能解决我的问题。
放大和缩小后,我正在删除标记并添加另一个标记,所以我尝试以这种方式刷新地图。
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();
Marker startMarker = new Marker(mapView);
startMarker.setPosition(new GeoPoint(54.337385, 18.662132));
setPropertiesForTopMarker(startMarker);
mapView.getOverlays().add(startMarker);
Marker startMarker1 = new Marker(mapView);
startMarker1.setPosition(new GeoPoint(54.332781, 18.587932));
setPropertiesForTopMarker(startMarker1);
mapView.getOverlays().add(startMarker1);
mapView.invalidate();
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();
但它也不起作用。
你有什么想法,如何解决这个问题?
已编辑:
我试图从源代码构建 osmdroid 以更改@spy 提到的这个值。来自我的 logcat 的调试看起来没问题。 Here 是日志。这里贴不下去了,因为行太多了。
我尝试以这种方式添加磁贴提供程序:
final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());
final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
registerReceiver, tileSource);
final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
tileSource, registerReceiver, new MapTileModuleProviderBase[] {
fileSystemProvider});
mapView = new MapView(this, new DefaultResourceProxyImpl(this), tileProviderArray);
或者这样
final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());
final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
registerReceiver, tileSource);
final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
tileSource, registerReceiver, new MapTileModuleProviderBase[] {
fileSystemProvider});
TilesOverlay tilesOverlay =
new TilesOverlay(tileProviderArray, getApplicationContext());
mapView.getOverlays().add(tilesOverlay);
但这两种方法都没有给我显示任何地图。 Source 此代码。
值得一试的东西...
如果您只想加载资产,请使用仅包含断言加载器的自定义图块提供程序数组。在上面的配置中,它仍然是在线机制(okhttp 或设备上的任何东西)尝试从 file:/// 下载文件,这可能与文件 url 的行为很奇怪。
也可以尝试通过 OpenStreetMapTileProviderConstants.DEBUGMODE 和 DEBUG_TILE_PROVIDERS 打开磁贴调试。它可能会揭示根本原因
好的,最后我使用 Providers
解决了我的问题。
我对取自 this 答案的代码做了一些修改,所以现在它看起来像这样。
mapView.setClickable(true);
mapView.setBuiltInZoomControls(false);
mapView.setMaxZoomLevel(macroZoomLevel);
mapView.setMinZoomLevel(macroZoomLevel);
mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
// save zip to sd
AssetManager assetManager = this.getAssets();
InputStream is;
String fileName = "map.zip"; // the zip file lies in assets root
String path = this.getExternalFilesDir(null) + File.separator + fileName; // the path I save SD to
File tileFile = new File(path);
if(!tileFile.exists()) {
try {
is = assetManager.open(fileName);
FileOutputStream fo = new FileOutputStream(path);
byte[] b = new byte[1024];
int length;
while((length = is.read(b)) != -1) {
fo.write(b, 0, length);
}
fo.flush();
fo.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
IArchiveFile[] archives = new IArchiveFile[1];
archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);
// Simple implementation that extends BitmapTileSourceBase and nothing else
CustomTileSource customTiles = new CustomTileSource("MapQuest", null, 10, 14, 256, ".png"); // Maverik is the name of the folder inside the zip (so zip is map.zip and inside it is a folder called Maverik)
MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[1];
providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(this.getApplicationContext()), customTiles, archives); // this one is for local tiles (zip etc.)
MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles,
new SimpleRegisterReceiver(this.getApplicationContext()), providers);
tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext());
tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT); // this makes sure that the invisble tiles of local tiles are transparent so we can see tiles from web, transparent have a minor performance decline.
mapView.getOverlays().add(tilesOverlay);
CustomTileSource
看起来像这样:
public class CustomTileSource extends BitmapTileSourceBase {
public CustomTileSource(String aName, ResourceProxy.string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding) {
super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
}
}
所以这只是 BitmapTileSourceBase
的子类,没有任何附加方法。
我有一个 assets zip 类型的文件,名称是 map.zip,这个目录的结构如下所示:
map.zip/MapQuest/[lvlOfZoom]/[x]/[y.png]
现在它工作正常,我只在我点击我的标记时缩放,手势用户不能这样做。
如果您在实施我描述的方法时遇到一些问题或者您不清楚的地方,我会尽力在评论中帮助您。
我正在从资产中加载图块,这些是我的代码,用于初始化地图:
mapView = (MapView)findViewById(R.id.offline_map_view);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(false);
mapView.setMaxZoomLevel(macroZoomLevel);
mapView.setMinZoomLevel(macroZoomLevel);
mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
mapView.setTileSource(new XYTileSource("MapQuest", 0, 18, 256, ".png",new String[] {"file:///android_asset/try/"} ));
mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
giveMarkersForActualLevel();
一切正常,直到我尝试放大,有部分地图无法正确渲染。然后我缩小,开始时正确渲染的区域现在有一些灰色瓷砖。
首先我用的是osmdroid 4.3,是这样添加的:
compile 'org.osmdroid:osmdroid-android:4.3'
然后我尝试使用最新版本的 osmdroid,通过 website compile 'org.osmdroid:osmdroid-android:5.1@aar'
然后我阅读了 here tu build from sources 所以我下载了最新的源代码,通过 gradle 构建它并添加了 aar
文件 osmdroid-android-release.aar
。
这也不能解决我的问题。
放大和缩小后,我正在删除标记并添加另一个标记,所以我尝试以这种方式刷新地图。
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();
Marker startMarker = new Marker(mapView);
startMarker.setPosition(new GeoPoint(54.337385, 18.662132));
setPropertiesForTopMarker(startMarker);
mapView.getOverlays().add(startMarker);
Marker startMarker1 = new Marker(mapView);
startMarker1.setPosition(new GeoPoint(54.332781, 18.587932));
setPropertiesForTopMarker(startMarker1);
mapView.getOverlays().add(startMarker1);
mapView.invalidate();
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();
但它也不起作用。
你有什么想法,如何解决这个问题?
已编辑:
我试图从源代码构建 osmdroid 以更改@spy 提到的这个值。来自我的 logcat 的调试看起来没问题。 Here 是日志。这里贴不下去了,因为行太多了。
我尝试以这种方式添加磁贴提供程序:
final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());
final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
registerReceiver, tileSource);
final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
tileSource, registerReceiver, new MapTileModuleProviderBase[] {
fileSystemProvider});
mapView = new MapView(this, new DefaultResourceProxyImpl(this), tileProviderArray);
或者这样
final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());
final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
registerReceiver, tileSource);
final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
tileSource, registerReceiver, new MapTileModuleProviderBase[] {
fileSystemProvider});
TilesOverlay tilesOverlay =
new TilesOverlay(tileProviderArray, getApplicationContext());
mapView.getOverlays().add(tilesOverlay);
但这两种方法都没有给我显示任何地图。 Source 此代码。
值得一试的东西...
如果您只想加载资产,请使用仅包含断言加载器的自定义图块提供程序数组。在上面的配置中,它仍然是在线机制(okhttp 或设备上的任何东西)尝试从 file:/// 下载文件,这可能与文件 url 的行为很奇怪。
也可以尝试通过 OpenStreetMapTileProviderConstants.DEBUGMODE 和 DEBUG_TILE_PROVIDERS 打开磁贴调试。它可能会揭示根本原因
好的,最后我使用 Providers
解决了我的问题。
我对取自 this 答案的代码做了一些修改,所以现在它看起来像这样。
mapView.setClickable(true);
mapView.setBuiltInZoomControls(false);
mapView.setMaxZoomLevel(macroZoomLevel);
mapView.setMinZoomLevel(macroZoomLevel);
mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
// save zip to sd
AssetManager assetManager = this.getAssets();
InputStream is;
String fileName = "map.zip"; // the zip file lies in assets root
String path = this.getExternalFilesDir(null) + File.separator + fileName; // the path I save SD to
File tileFile = new File(path);
if(!tileFile.exists()) {
try {
is = assetManager.open(fileName);
FileOutputStream fo = new FileOutputStream(path);
byte[] b = new byte[1024];
int length;
while((length = is.read(b)) != -1) {
fo.write(b, 0, length);
}
fo.flush();
fo.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
IArchiveFile[] archives = new IArchiveFile[1];
archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);
// Simple implementation that extends BitmapTileSourceBase and nothing else
CustomTileSource customTiles = new CustomTileSource("MapQuest", null, 10, 14, 256, ".png"); // Maverik is the name of the folder inside the zip (so zip is map.zip and inside it is a folder called Maverik)
MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[1];
providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(this.getApplicationContext()), customTiles, archives); // this one is for local tiles (zip etc.)
MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles,
new SimpleRegisterReceiver(this.getApplicationContext()), providers);
tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext());
tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT); // this makes sure that the invisble tiles of local tiles are transparent so we can see tiles from web, transparent have a minor performance decline.
mapView.getOverlays().add(tilesOverlay);
CustomTileSource
看起来像这样:
public class CustomTileSource extends BitmapTileSourceBase {
public CustomTileSource(String aName, ResourceProxy.string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding) {
super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
}
}
所以这只是 BitmapTileSourceBase
的子类,没有任何附加方法。
我有一个 assets zip 类型的文件,名称是 map.zip,这个目录的结构如下所示:
map.zip/MapQuest/[lvlOfZoom]/[x]/[y.png]
现在它工作正常,我只在我点击我的标记时缩放,手势用户不能这样做。
如果您在实施我描述的方法时遇到一些问题或者您不清楚的地方,我会尽力在评论中帮助您。