diff --git a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java index a8f2021142..aa67eeeae2 100644 --- a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java +++ b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java @@ -19,16 +19,14 @@ public class OsmAndHttpServer extends NanoHTTPD { private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class); private final Map endpoints = new HashMap<>(); private MapActivity mapActivity; + private RotatedTileBox mapTileBoxCopy; + private boolean mapLinkedToLocation; + private OsmandApplication app; public OsmAndHttpServer(String hostname, int port) { super(hostname, port); } - @Override - public void stop() { - mapActivity.getMapView().setScreenViewDetached(false); - super.stop(); - } @Override public Response serve(IHTTPSession session) { @@ -44,9 +42,32 @@ public class OsmAndHttpServer extends NanoHTTPD { public void start(MapActivity mapActivity) throws IOException { this.mapActivity = mapActivity; + // don't leak map activity with applciation + this.app = mapActivity.getMyApplication(); registerEndpoints(); start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); mapActivity.getMapView().setScreenViewDetached(true); + this.mapTileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); + mapLinkedToLocation = mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); + mapActivity.getMapViewTrackingUtilities().setMapLinkedToLocation(false); + } + + + @Override + public void stop() { + mapActivity.getMapView().setScreenViewDetached(false); + mapActivity.getMapView().setCurrentViewport(mapTileBoxCopy); + mapActivity.getMapViewTrackingUtilities().setMapLinkedToLocation(mapLinkedToLocation); + mapActivity = null; + super.stop(); + } + + public MapActivity getMapActivity() { + return mapActivity; + } + + public OsmandApplication getMyApplication() { + return app; } public String getUrl() { diff --git a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java index 28be86089f..574e983f6e 100644 --- a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java @@ -8,6 +8,7 @@ import net.osmand.data.RotatedTileBox; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.resources.AsyncLoadingThread; import net.osmand.plus.server.OsmAndHttpServer; +import net.osmand.plus.views.OsmandMapTileView; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -20,25 +21,24 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint { private static final int TIMEOUT_STEP = 150; private static final int TIMEOUT = 15000; private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); - @GuardedBy("this") - private static int lastZoom = -999; - //TODO restore mapState on Exit - private final RotatedTileBox mapTileBoxCopy; - private final MapActivity mapActivity; - private final MetaTileFileSystemCache cache; - public TileEndpoint(MapActivity mapActivity) { - this.mapActivity = mapActivity; - this.cache = new MetaTileFileSystemCache(mapActivity.getMyApplication()); - this.mapTileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); - //for debug + private final RotatedTileBox mapTileBoxCopy; + private final OsmAndHttpServer server; + private final MetaTileFileSystemCache cache; + private int lastRequestedZoom; + + public TileEndpoint(OsmAndHttpServer server) { + this.server = server; + this.cache = new MetaTileFileSystemCache(server.getMyApplication()); + this.mapTileBoxCopy = server.getMapActivity().getMapView().getCurrentRotatedTileBox().copy(); this.cache.clearCache(); } + + @Override public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session, String url) { // https://tile.osmand.net/hd/6/55/25.png - LOG.debug("SERVER: STARTED REQUEST"); int extInd = url.indexOf('.'); if (extInd >= 0) { url = url.substring(0, extInd); @@ -53,16 +53,11 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint { int zoom = Integer.parseInt(prms[1]); int x = Integer.parseInt(prms[2]); int y = Integer.parseInt(prms[3]); - synchronized (this){ - if (zoom > lastZoom+1 || zoom < lastZoom-1){ - lastZoom = zoom; - } - } MetaTileFileSystemCache.MetaTileCache res = cache.get(zoom, x, y); if (res == null) { + lastRequestedZoom = zoom; res = requestMetatile(x, y, zoom); if (res == null) { - LOG.error("SERVER: Cannot request metatile"); return OsmAndHttpServer.ErrorResponses.response500; } } @@ -81,38 +76,44 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint { str, str.available()); } + private synchronized MetaTileFileSystemCache.MetaTileCache requestMetatile(int x, int y, int zoom) { - long time2 = System.currentTimeMillis(); + long tm = System.currentTimeMillis(); + MapActivity mapActivity = server.getMapActivity(); + if (mapActivity == null) { + return null; + } MetaTileFileSystemCache.MetaTileCache cacheTile = this.cache.get(zoom, x, y); if (cacheTile != null) { return cacheTile; } - if (zoom != lastZoom){ - return null; - } MetaTileFileSystemCache.MetaTileCache res = cache.createMetaTile(zoom, x, y); mapActivity.getMapView().setCurrentViewport(res.bbox); int timeout = 0; try { AsyncLoadingThread athread = mapActivity.getMyApplication().getResourceManager().getAsyncLoadingThread(); - Thread.sleep(TIMEOUT_STEP); // TODO line should be removed in future + Thread.sleep(TIMEOUT_STEP); // to do line should be removed in future while (athread.areResourcesLoading() && timeout < TIMEOUT) { + if(lastRequestedZoom != zoom) { + return null; + } Thread.sleep(TIMEOUT_STEP); timeout += TIMEOUT_STEP; } - Bitmap tempBmp = mapActivity.getMapView().getBufferBitmap(); + Bitmap rbmp = mapActivity.getMapView().getBufferBitmap(); if (timeout >= TIMEOUT) { - Canvas canvas = new Canvas(tempBmp); - Paint paint = new Paint(); - paint.setColor(Color.RED); - paint.setTextSize(12); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); - canvas.drawText("TIMEOUT", tempBmp.getWidth() / 2, tempBmp.getHeight() / 2, paint); + return null; +// Canvas canvas = new Canvas(tempBmp); +// Paint paint = new Paint(); +// paint.setColor(Color.RED); +// paint.setTextSize(12); +// paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); +// canvas.drawText("TIMEOUT", tempBmp.getWidth() / 2, tempBmp.getHeight() / 2, paint); // here we could return stub } - res.bmp = tempBmp.copy(tempBmp.getConfig(), true); + res.bmp = rbmp.copy(rbmp.getConfig(), true); this.cache.put(res); - LOG.debug("SERVER: TIME TO REQUEST TILE: " + (System.currentTimeMillis() - time2)); + LOG.debug("Render metatile: " + (System.currentTimeMillis() - tm)/1000.0f); return res; } catch (InterruptedException e) { LOG.error(e);