使用 Android Studio 和array1.find(x => callback(x))
库进行编程。
我使用osmdroid
方法下载了地图的一部分。此方法将地图片段存储在我选择的cacheManager.downloadAreaAsync()
目录中的sqlite文件中。
现在,我想使用此地图将其离线加载到移动应用程序中。
我尝试通过各种类(data/data/<package>/osmdroid/tiles
)来做到这一点,但我无法显示地图。
我应该怎么做?
答案 0 :(得分:0)
要下载部分地图,请执行以下操作:
map.setTileSource(TileSourceFactory.OpenTopo);
outputPath = "/data/data/<package>/files" + File.separator + "osmdroid" + File.separator + "tiles" + File.separator;
outputName = outputPath + boxE6.name + ".db";
try {
writer=new SqliteArchiveTileWriter(outputName);
} catch (Exception ex) {
ex.printStackTrace();
}
CacheManager cacheManager = new CacheManager(map,writer);
cacheManager.downloadAreaAsync(this, boxE6, 7, 13, new CacheManager.CacheManagerCallback() {
@Override
public void onTaskComplete() {
Toast.makeText(ctx, "Download complete!", Toast.LENGTH_LONG).show();
if (writer!=null)
writer.onDetach();
} ...
要检索存储的地图(在这种情况下,它在usa.db文件中),我尝试执行以下操作:
map.setUseDataConnection(false);
map.setTileSource(TileSourceFactory.OpenTopo);
File cache = new File(outputName);
Configuration.getInstance().setOsmdroidTileCache(cache);
mapController.setCenter(new GeoPoint((n+s)/2,(e+w)/2));
答案 1 :(得分:0)
我将展示我如何存储和加载多个 sqlite Tiles,而不仅仅是一个。
José Espejo Roig 的上述回答仅对我有用。它几乎可以很好地缓存图块,但不能用于读取它们。不过,写下缓存文件也不完整。我使用以下示例创建了自己的代码:Make a tile archive from OSMDroid Github。
因此,为了在特定目录中存储可能超过 1 个图块,我使用如下代码。它按顺序创建 my_mapX.sqlite,其中 X 只是步进的连续整数。所以我得到了 my_map1.sqlite、my_map2.sqlite 等等。
private final String MAP_FILE_NAME = "my_map";
private final String MAP_FILE_EXTENSION = ".sqlite";
// ...
Context ctx = getActivity();
mMapView = new MapView(ctx);
((ConstraintLayout) view.findViewById(R.id.osm_fragment)).addView(mMapView);
mMapView.setTileSource(TileSourceFactory.OpenTopo);
ContextWrapper contextWrapper = new ContextWrapper(ctx);
File root_directory = contextWrapper.getDir(ctx.getFilesDir().getName(), Context.MODE_PRIVATE);
File directory_osm = new File(root_directory, "osmdroid");
directory_osm.mkdir();
File directory = new File(directory_osm, "tiles");
directory.mkdir();
File[] nrFiles = directory.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(MAP_FILE_EXTENSION))
return true;
return false;
}
});
String osmdroidTile = directory.getAbsolutePath() + File.separator + MAP_FILE_NAME + (nrFiles.length + 1) + MAP_FILE_EXTENSION;
BoundingBox boxE6 = mMapView.getBoundingBox();
SqliteArchiveTileWriter writer = null;
try {
writer = new SqliteArchiveTileWriter(osmdroidTile);
} catch (Exception ex) {
ex.printStackTrace();
}
CacheManager cacheManager = new CacheManager(mMapView, writer);
SqliteArchiveTileWriter finalWriter = writer;
int currZoom = (int)mMapView.getZoomLevelDouble();
cacheManager.downloadAreaAsync(ctx, boxE6, currZoom, currZoom + 1, new CacheManager.CacheManagerCallback() {
@Override
public void onTaskComplete() {
Toast.makeText(ctx, "Download complete!", Toast.LENGTH_LONG).show();
if (finalWriter != null)
finalWriter.onDetach();
}
@Override
public void updateProgress(int progress, int currentZoomLevel, int zoomMin, int zoomMax) {
}
@Override
public void downloadStarted() {
}
@Override
public void setPossibleTilesInArea(int total) {
}
@Override
public void onTaskFailed(int errors) {
Toast.makeText(getActivity(), "Download complete with " + errors + " errors", Toast.LENGTH_LONG).show();
if (finalWriter != null)
finalWriter.onDetach();
}
});
}
});
这样我就可以创建任意数量的磁贴文件。重要的是它们有“.sqlite”扩展名。 “.db”扩展名对我不起作用。
现在为了阅读这些图块,我再次使用了 OSMDroid Github 中的示例:Sample SQLITE example。在 OSMDroid Github 示例中,TileSource 由 IArchiveFile 确定。我跳过了那个,因为我假设我知道我使用的是什么 TileSource(在我的例子中它是 OpenTopo,如你所见)。然后从同一个 TileSource 读取多个离线图块(基于 OSMDroid 的示例),我的代码如下所示:
//first we'll look at the default location for tiles that we support
Context ctx = getActivity();
mMapView = new MapView(ctx);
((ConstraintLayout) view.findViewById(R.id.osm_fragment)).addView(mMapView);
mMapView.setUseDataConnection(false);
ContextWrapper contextWrapper = new ContextWrapper(ctx);
File root_directory = contextWrapper.getDir(ctx.getFilesDir().getName(), Context.MODE_PRIVATE);
String osmDir = root_directory.getAbsolutePath() + File.separator + "osmdroid" + File.separator + "tiles";
File f = new File(osmDir);
if (f.exists()) {
File[] list = f.listFiles();
ArrayList<File> sqliteArray = new ArrayList<>();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
continue;
}
String name = list[i].getName().toLowerCase();
if (!name.contains(".")) {
continue; //skip files without an extension
}
name = name.substring(name.lastIndexOf(".") + 1);
if (name.length() == 0) {
continue;
}
//narrow it down to only sqlite tiles
if (ArchiveFileFactory.isFileExtensionRegistered(name) && name.equals("sqlite")) {
sqliteArray.add(list[i]);
}
}
}
OfflineTileProvider tileProvider;
if (sqliteArray.size() > 0) {
try {
tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(getActivity()), sqliteArray.toArray(new File[0]));
mMapView.setTileProvider(tileProvider);
mMapView.setTileSource(TileSourceFactory.OpenTopo);
mMapView.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
Toast.makeText(getActivity(), f.getAbsolutePath() + " dir not found!", Toast.LENGTH_SHORT).show();
}