Cha*_*ake 5 android caching mapbox google-maps-android-api-2
我想实现一个具有此功能的 TileProvider:
Map要求一个TileTile可以离线使用TileTileProvider都会在线检查新磁贴并将其下载到Cache外部存储中。TileProvider为地图提供新的图块,然后地图更新它。这是我当前的UrlTileProvider实现:
public class MapBoxOnlineTileProvider extends UrlTileProvider {
private static final String[] FORMATS;
static {
final String[] servers = new String[] { "a", "b", "c", "d" };
final String[] formats = new String[servers.length];
for (int i = 0; i < servers.length; i++) {
formats[i] = String.format(
"%%s://%s.tiles.mapbox.com/v3/%%s/%%d/%%d/%%d.png",
servers[i]);
}
FORMATS = formats;
}
// ------------------------------------------------------------------------
// Instance Variables
// ------------------------------------------------------------------------
private String mMapIdentifier;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
public MapBoxOnlineTileProvider(final String mapIdentifier) {
super(256, 256);
this.mMapIdentifier = mapIdentifier;
}
// ------------------------------------------------------------------------
// Public Methods
// ------------------------------------------------------------------------
public String getMapIdentifier() {
return this.mMapIdentifier;
}
public void setMapIdentifier(final String anIdentifier) {
this.mMapIdentifier = anIdentifier;
}
@Override
public URL getTileUrl(final int x, final int y, final int z) {
final String f = FORMATS[new Random().nextInt(FORMATS.length)];
final String p = "http";
try {
return new URL(String.format(f, p, this.mMapIdentifier, z, x, y));
} catch (final MalformedURLException e) {
e.printStackTrace();
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这只会将其缓存在内存中,因此如果用户关闭我的应用程序,它不会缓存它们,并且默认的 Google 地图地图将在Tiles下载之前出现。
UrlTileProvider实现getTile为final,所以我无法覆盖它。TileProvider没有getTileURL方法,并且UrlTileProvider没有源代码可供我重写我的解决方案。
我应该如何处理这个问题?有什么办法可以做我想做的事吗?为什么是getTile最终的?我错过了什么吗?
用包装第一类的第二类解决了这个问题。
尽管我不喜欢包装器,但这是我能想到的最好的方法,而且我必须说它效果非常好。
public class MapBoxMixedTileProvider implements TileProvider {
private final MapBoxOnlineTileProvider provider;
private final Context context;
public MapBoxMixedTileProvider(final Context context, final String mapId) {
provider = new MapBoxOnlineTileProvider(mapId);
this.context = context;
}
@Override
public Tile getTile(final int arg0, final int arg1, final int arg2) {
final URL url = provider.getTileUrl(arg0, arg1, arg2);
// Remove the "http://a." from the url, then replace all the '/' and '.'
// with
// '_', then replace the final "_png" with ".png", so openFileInput
// doesn't cry a lot.
final String finalUrl = (url.toString().substring(9)).replace('/', '_')
.replace('.', '_').replace("_png", ".png");
System.out.println(finalUrl);
boolean contained = false;
for (final String file : context.fileList()) {
if (file.contains(finalUrl)) {
contained = true;
break;
}
}
try {
if (contained) {
final FileInputStream fis = context.openFileInput(finalUrl);
return new Tile(256, 256, byteArrayFromInputStream(fis));
} else {
final FileOutputStream fos = context.openFileOutput(finalUrl,
Context.MODE_PRIVATE);
final Tile t = provider.getTile(arg0, arg1, arg2);
fos.write(t.data);
fos.flush();
fos.close();
return t;
}
} catch (final IOException ex) {
ex.printStackTrace();
return null;
}
}
private byte[] byteArrayFromInputStream(final FileInputStream is)
throws IOException {
final BufferedInputStream bis = new BufferedInputStream(is);
final ArrayList<Integer> bytes = new ArrayList<Integer>();
int current = 0;
while ((current = bis.read()) != -1) {
bytes.add(Integer.valueOf(current));
}
final byte[] bs = new byte[bytes.size()];
for (int i = 0; i < bytes.size(); i++) {
bs[i] = bytes.get(i).byteValue();
}
bis.close();
is.close();
return bs;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,为了让它TileProvider工作,我只需要这样做:
final MapBoxMixedTileProvider provider = new MapBoxMixedTileProvider(
this, MAPBOX_MAP_IDENTIFIER);
//zIndex is set to -4 so Polyines and Polygons get shown OVER and not under the Overlay
final TileOverlayOptions overlay = new TileOverlayOptions().tileProvider(provider).zIndex(-4);
tileOverlay = mMap.addTileOverlay(overlay);
Run Code Online (Sandbox Code Playgroud)
我知道我的 byteArrayFromInputStream 效率极低。欢迎对我的代码进行任何升级。
| 归档时间: |
|
| 查看次数: |
3609 次 |
| 最近记录: |