cache added
This commit is contained in:
parent
576e70a606
commit
2cd4e23463
3 changed files with 101 additions and 20 deletions
|
@ -0,0 +1,77 @@
|
|||
package net.osmand.plus.server;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.server.endpoints.TileEndpoint;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class MetaTileFileSystemCache {
|
||||
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class);
|
||||
private static final Object TILES_FOLDER = "tiles";
|
||||
private static final int MAX_IN_MEMORY_CACHE_SIZE = 4;
|
||||
private static final int MAX_CACHE_SIZE = 4;
|
||||
private final ConcurrentLinkedQueue<TileEndpoint.MetaTileCache> inMemoryCache = new ConcurrentLinkedQueue<>();
|
||||
private final File externalCacheDir;
|
||||
public boolean inMemoryCacheEnabled = false;
|
||||
|
||||
public MetaTileFileSystemCache(OsmandApplication application) {
|
||||
externalCacheDir = new File(
|
||||
application.getExternalCacheDir().getAbsoluteFile() + File.separator + TILES_FOLDER);
|
||||
if (!externalCacheDir.exists()) {
|
||||
externalCacheDir.mkdir();
|
||||
}
|
||||
}
|
||||
|
||||
public void put(TileEndpoint.MetaTileCache tile) {
|
||||
while (inMemoryCache.size() > MAX_IN_MEMORY_CACHE_SIZE) {
|
||||
inMemoryCache.poll();
|
||||
}
|
||||
while (externalCacheDir.listFiles().length > MAX_CACHE_SIZE) {
|
||||
//remove outdated files
|
||||
for (int i = 0; i < externalCacheDir.listFiles().length - MAX_CACHE_SIZE; i++) {
|
||||
externalCacheDir.listFiles()[i].delete();
|
||||
}
|
||||
}
|
||||
String fileName = tile.getTileId();
|
||||
File file = new File(externalCacheDir, fileName);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
tile.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
if (inMemoryCacheEnabled) {
|
||||
inMemoryCache.add(tile);
|
||||
}
|
||||
}
|
||||
|
||||
public TileEndpoint.MetaTileCache get(int zoom, int METATILE_SIZE, int x, int y) {
|
||||
for (int tx = x - METATILE_SIZE + 1; tx < METATILE_SIZE + x - 1; tx++) {
|
||||
for (int ty = y - METATILE_SIZE + 1; ty < METATILE_SIZE + y - 1; ty++) {
|
||||
File file = new File(externalCacheDir, zoom + "_" + METATILE_SIZE + "_" + tx + "_" + ty);
|
||||
if (file.exists()) {
|
||||
TileEndpoint.MetaTileCache tile = new TileEndpoint.MetaTileCache(
|
||||
BitmapFactory.decodeFile(file.getAbsolutePath()),
|
||||
tx, ty, tx + METATILE_SIZE, ty + METATILE_SIZE, zoom
|
||||
);
|
||||
if (inMemoryCacheEnabled) {
|
||||
inMemoryCache.add(tile);
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ public class OsmAndHttpServer extends NanoHTTPD {
|
|||
return e.getValue().process(session, uri);
|
||||
} catch (Exception exception) {
|
||||
LOG.error("SERVER ERROR: " + exception.getMessage());
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ import net.osmand.PlatformUtil;
|
|||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.resources.AsyncLoadingThread;
|
||||
import net.osmand.plus.server.MetaTileFileSystemCache;
|
||||
import net.osmand.plus.server.OsmAndHttpServer;
|
||||
import net.osmand.util.MapUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
|
||||
|
||||
|
@ -22,14 +22,12 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
|
|||
private static final int TIMEOUT_STEP = 500;
|
||||
private static final int TIMEOUT = 5000;
|
||||
private static final int METATILE_SIZE = 2;
|
||||
private static final int MAX_CACHE_SIZE = 4;
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class);
|
||||
private final MapActivity mapActivity;
|
||||
// TODO store on file system
|
||||
private final ConcurrentLinkedQueue<MetaTileCache> cache = new ConcurrentLinkedQueue<>();
|
||||
private final MetaTileFileSystemCache cache;
|
||||
|
||||
private static class MetaTileCache {
|
||||
public static class MetaTileCache {
|
||||
Bitmap bmp;
|
||||
int sx;
|
||||
int sy;
|
||||
|
@ -37,11 +35,28 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
|
|||
int ey;
|
||||
int zoom;
|
||||
|
||||
public MetaTileCache() {
|
||||
|
||||
}
|
||||
|
||||
public MetaTileCache(Bitmap bmp, int sx, int sy, int ex, int ey, int zoom) {
|
||||
this.bmp = bmp;
|
||||
this.sx = sx;
|
||||
this.sy = sy;
|
||||
this.ex = ex;
|
||||
this.ey = ey;
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
// to be used in file name
|
||||
public String getTileId() {
|
||||
return zoom + "_" + METATILE_SIZE + "_" + sx + "_" + sy;
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public Bitmap getSubtile(int x, int y) {
|
||||
return Bitmap.createBitmap(bmp,
|
||||
(x - sx) * TILE_SIZE_PX * TILE_DENSITY,
|
||||
|
@ -52,13 +67,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
|
|||
|
||||
public TileEndpoint(MapActivity mapActivity) {
|
||||
this.mapActivity = mapActivity;
|
||||
}
|
||||
|
||||
private void addToMemoryCache(MetaTileCache res) {
|
||||
while (cache.size() > MAX_CACHE_SIZE) {
|
||||
cache.poll();
|
||||
}
|
||||
cache.add(res);
|
||||
this.cache = new MetaTileFileSystemCache(mapActivity.getMyApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,13 +87,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
|
|||
int zoom = Integer.parseInt(prms[1]);
|
||||
int x = Integer.parseInt(prms[2]);
|
||||
int y = Integer.parseInt(prms[3]);
|
||||
|
||||
MetaTileCache res = null;
|
||||
for (MetaTileCache r : cache) {
|
||||
if (r.zoom == zoom && r.ex >= x && r.ey >= y && r.sx <= x && r.sy <= y) {
|
||||
res = r;
|
||||
}
|
||||
}
|
||||
MetaTileCache res = cache.get(zoom, METATILE_SIZE, x, y);
|
||||
if (res == null) {
|
||||
res = requestMetatile(x, y, zoom);
|
||||
if (res == null) {
|
||||
|
@ -137,7 +140,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
|
|||
res.zoom = zoom;
|
||||
Bitmap tempBmp = mapActivity.getMapView().getBufferBitmap();
|
||||
res.bmp = tempBmp.copy(tempBmp.getConfig(), true);
|
||||
addToMemoryCache(res);
|
||||
cache.put(res);
|
||||
}
|
||||
return res;
|
||||
} catch (InterruptedException e) {
|
||||
|
|
Loading…
Reference in a new issue