我不知道pbf库(如果可以请检查OSMDroid)。
无论如何,我成功地在运行时自己缓存了来自openstreetmap的png。这意味着我只缓存了一个区域内显示的瓦片,而不是所有瓦片(我进行了暴力下载,但不建议这样做)。
下面是“缓存”实时瓦片的代码。如果您想要提供应用程序一起使用的png,然后读取它们,您可以尝试将png放置在文件夹结构中,该结构的第一级为缩放级别(Z),然后放置两个其他级别用于行/纬度(y)和列/经度(x),并在此处放置文件,最好的情况是文件具有三个值:Z_Y_X.png
您必须编辑“getTile”方法以检查上述创建的文件夹结构中的PNG文件。
以下是我的“实时缓存”代码:
import com.jakewharton.disklrucache.DiskLruCache;
public class CachedTileProvider implements TileProvider {
private static final String TAG = CachedTileProvider.class.getSimpleName();
private static final String KEY_FORMAT = "%3$d_%2$d_%1$d_%4$s";
private static final int INDEX_DATA = 0;
private static final int INDEX_HEIGHT = 1;
private static final int INDEX_WIDTH = 2;
private static final double[] TILES_ORIGIN = {-20037508.34789244, 20037508.34789244};
private static final double MAP_SIZE = 20037508.34789244 * 2;
private static final double ORIGIN_SHIFT = Math.PI * 6378137d;
private final String mKeyTag;
private final TileProvider mTileProvider;
private DiskLruCache mCache;
private Set<String> cachedStringsWMS = null;
Context cont = null;
public CachedTileProvider(String keyTag, TileProvider tileProvider, DiskLruCache cache, Context context) {
mKeyTag = keyTag;
mTileProvider = tileProvider;
mCache = cache;
cont = context;
}
public void setNewDiskCache(DiskLruCache cache) {
mCache = cache;
}
@Override
public Tile getTile(int x, int y, int zoom) {
final String key = CachedTileProvider.generateKey(x, y, zoom, mKeyTag);
Tile tile = getCachedTile(key);
if (tile == null) {
tile = mTileProvider.getTile(x, y, zoom);
if (null != tile && cacheTile(key, tile)) {
if (BuildConfig.DEBUG) Log.d(TAG, "Added tile to cache " + key);
}
}
return tile;
}
private Tile getCachedTile(String key) {
try {
DiskLruCache.Snapshot snapshot = mCache.get(key);
if (snapshot == null) {
return null;
}
final byte[] data = readStreamAsByteArray(snapshot.getInputStream(INDEX_DATA));
final int height = readStreamAsInt(snapshot.getInputStream(INDEX_HEIGHT));
final int width = readStreamAsInt(snapshot.getInputStream(INDEX_WIDTH));
if (data != null) {
if (BuildConfig.DEBUG)Log.d(TAG, "Cache hit for tile " + key);
return new Tile(width, height, data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException ise) {
Log.e(TAG, "IllegalStateException thrown, maybe cache is closed: " + ise.getMessage(), ise);
}
return null;
}
private boolean cacheTile(String key, Tile tile) {
try {
DiskLruCache.Editor editor = mCache.edit(key);
if (editor == null) {
return false;
}
writeByteArrayToStream(tile.data, editor.newOutputStream(INDEX_DATA));
writeIntToStream(tile.height, editor.newOutputStream(INDEX_HEIGHT));
writeIntToStream(tile.width, editor.newOutputStream(INDEX_WIDTH));
editor.commit();
return true;
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException ise) {
Log.e(TAG, "IllegalStateException thrown, maybe cache is closed: " + ise.getMessage(), ise);
}
return false;
}
private static String generateKey(int x, int y, int zoom, String tag) {
return String.format(KEY_FORMAT, x, y, zoom, tag);
}
private static void writeByteArrayToStream(byte[] data, OutputStream stream) throws IOException {
try {
stream.write(data);
} finally {
stream.close();
}
}
private static void writeIntToStream(int data, OutputStream stream) throws IOException {
DataOutputStream dos = new DataOutputStream(stream);
try {
dos.writeInt(data);
} finally {
try {
dos.close();
} finally {
stream.close();
}
}
}
private static byte[] readStreamAsByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int read = 0;
byte[] data = new byte[1024];
try {
while ((read = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, read);
}
} finally {
inputStream.close();
}
return buffer.toByteArray();
}
private static int readStreamAsInt(InputStream inputStream) throws IOException {
DataInputStream buffer = new DataInputStream(inputStream);
try {
return buffer.readInt();
} finally {
inputStream.close();
}
}
}
然后,您可以通过将Tile提供程序封装起来创建该实例:
CachedTileProvider cachedTileProvider = new CachedTileProvider("osm", TileProviderFactory.getOSMBackGroundTileProvider(layerInfo.get(i)), mContext);
在哪里
public static TileProvider getOSMBackGroundTileProvider() {
TileProvider mOSMTileProvider = new UrlTileProvider(256, 256) {
@Override
public URL getTileUrl(int x, int y, int z) {
try {
String f = "http://a.tile.openstreetmap.org/%d/%d/%d.png";
return new URL(String.format(f, z, x, y));
} catch (MalformedURLException e) {
return null;
}
}
};
return mOSMTileProvider;
}
现在您需要探索和检查jakewharton的DiskLruCache库,但是有很多文档可供参考,如果需要的话最好开一个新问题。