diff --git a/OsmAnd/src/net/osmand/plus/resources/AsyncLoadingThread.java b/OsmAnd/src/net/osmand/plus/resources/AsyncLoadingThread.java index 59f62e30b5..565e0c048b 100644 --- a/OsmAnd/src/net/osmand/plus/resources/AsyncLoadingThread.java +++ b/OsmAnd/src/net/osmand/plus/resources/AsyncLoadingThread.java @@ -69,6 +69,11 @@ public class AsyncLoadingThread extends Thread { } } + public boolean areResourcesLoading() { + return !requests.isEmpty(); + + } + public void requestToLoadTile(TileLoadDownloadRequest req) { requests.push(req); } diff --git a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java index ae123b2c8b..8b276c889a 100644 --- a/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/resources/ResourceManager.java @@ -1176,7 +1176,12 @@ public class ResourceManager { tc.tilesOnFS.clear(); } } - + + + public AsyncLoadingThread getAsyncLoadingThread() { + return asyncLoadingThread; + } + /// On low memory method /// public void onLowMemory() { log.info("On low memory"); diff --git a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java index 44f8cbab71..15db8a651b 100644 --- a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java +++ b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java @@ -10,10 +10,11 @@ import net.osmand.plus.server.endpoints.TileEndpoint; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; public class OsmAndHttpServer extends NanoHTTPD { - private static final String FOLDER_NAME = "server"; + private static final String ASSETS_FOLDER_NAME = "server"; private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class); private final Map endpoints = new HashMap<>(); private MapActivity mapActivity; @@ -46,9 +47,11 @@ public class OsmAndHttpServer extends NanoHTTPD { private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) { String uri = session.getUri(); - for (String path : endpoints.keySet()) { - if (uri.startsWith(path)) { - return endpoints.get(path).process(session); + Iterator> it = endpoints.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry e = it.next(); + if (uri.startsWith(e.getKey())) { + return e.getValue().process(session, uri); } } return ErrorResponses.response404; @@ -79,7 +82,7 @@ public class OsmAndHttpServer extends NanoHTTPD { OsmandApplication app = mapActivity.getMyApplication(); if (app != null) { try { - is = app.getAssets().open(FOLDER_NAME + uri); + is = app.getAssets().open(ASSETS_FOLDER_NAME + uri); if (is.available() == 0) { return ErrorResponses.response404; } @@ -107,7 +110,7 @@ public class OsmAndHttpServer extends NanoHTTPD { } public interface ApiEndpoint { - NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session); + NanoHTTPD.Response process(IHTTPSession session, String url); } public static class ErrorResponses { diff --git a/OsmAnd/src/net/osmand/plus/server/ServerFragment.java b/OsmAnd/src/net/osmand/plus/server/ServerFragment.java index 5917a11562..1b83e614a2 100644 --- a/OsmAnd/src/net/osmand/plus/server/ServerFragment.java +++ b/OsmAnd/src/net/osmand/plus/server/ServerFragment.java @@ -26,6 +26,7 @@ import static android.content.Context.WIFI_SERVICE; public class ServerFragment extends BaseOsmAndFragment { private final static Log LOG = PlatformUtil.getLog(ServerFragment.class); private final int port = 24990; + final int THREAD_ID = 14231; // random number private boolean initialized = false; private OsmAndHttpServer server; private View view; @@ -84,7 +85,7 @@ public class ServerFragment extends BaseOsmAndFragment { } private void initServer() { - final int THREAD_ID = 10000; + TrafficStats.setThreadStatsTag(THREAD_ID); String hostname = getDeviceAddress(); try { @@ -115,7 +116,8 @@ public class ServerFragment extends BaseOsmAndFragment { if (getActivity() != null) { try { getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); - } catch (Exception e) { + } catch (RuntimeException e) { + LOG.error(e.getMessage(), e); } } } diff --git a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java index a21c15de2a..31d940be08 100644 --- a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java @@ -1,50 +1,53 @@ package net.osmand.plus.server.endpoints; import android.graphics.Bitmap; + import fi.iki.elonen.NanoHTTPD; + 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.OsmAndHttpServer; import net.osmand.plus.views.OsmandMapTileView; +import net.osmand.util.MapUtils; + import org.apache.commons.logging.Log; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.net.URL; import java.util.Scanner; -import static fi.iki.elonen.NanoHTTPD.SOCKET_READ_TIMEOUT; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; -public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint, OsmandMapTileView.IMapOnImageDrawn { +public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint { private static final int TILE_SIZE_PX = 512; private static final int TIMEOUT_STEP = 500; + private static final int TIMEOUT = 5000; + private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); private final MapActivity mapActivity; - private RotatedTileBox resultBmpViewport; - private Bitmap resultBitmap; public TileEndpoint(MapActivity mapActivity) { this.mapActivity = mapActivity; } @Override - public void onDraw(RotatedTileBox viewport, Bitmap bmp) { - this.resultBmpViewport = viewport; - this.resultBitmap = bmp; - } - - @Override - public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { - this.mapActivity.getMapView().setOnImageDrawnListener(this); - RotatedTileBox tileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); - Scanner s = new Scanner(session.getUri()).useDelimiter("/"); - //reading path - s.next(); - int zoom = s.nextInt(); - double lat = s.nextDouble(); - double lon = s.nextDouble(); - Bitmap bitmap = requestTile(lat, lon, zoom); + public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session, String url) { + // https://tile.osmand.net/hd/6/55/25.png + int extInd = url.indexOf('.'); + if(extInd >= 0) { + url = url.substring(0, extInd); + } + String[] prms = url.split("/"); + if(prms.length < 4) { + return OsmAndHttpServer.ErrorResponses.response500; + } + int zoom = Integer.parseInt(prms[1]); + int x = Integer.parseInt(prms[2]); + int y = Integer.parseInt(prms[3]); + Bitmap bitmap = requestTile(x, y, zoom); if (bitmap == null) { return OsmAndHttpServer.ErrorResponses.response500; } @@ -52,16 +55,14 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint, OsmandMapTile bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); ByteArrayInputStream str = new ByteArrayInputStream(byteArray); - mapActivity.getMapView().setCurrentViewport(tileBoxCopy); - this.mapActivity.getMapView().setOnImageDrawnListener(null); return newFixedLengthResponse( - NanoHTTPD.Response.Status.OK, - "image/png", - str, - str.available()); + NanoHTTPD.Response.Status.OK, "image/png", + str, str.available()); } - private synchronized Bitmap requestTile(double lat, double lon, int zoom) { + private synchronized Bitmap requestTile(int x, int y, int zoom) { + double lat = MapUtils.getLatitudeFromTile(zoom, y); + double lon = MapUtils.getLongitudeFromTile(zoom, x); final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder() .setLocation(lat, lon) .setZoom(zoom) @@ -69,12 +70,18 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint, OsmandMapTile mapActivity.getMapView().setCurrentViewport(rotatedTileBox); int timeout = 0; try { - while (timeout < SOCKET_READ_TIMEOUT) { + AsyncLoadingThread athread = mapActivity.getMyApplication().getResourceManager().getAsyncLoadingThread(); + + Bitmap res = null; + while (athread.areResourcesLoading() && timeout < TIMEOUT) { Thread.sleep(TIMEOUT_STEP); timeout += TIMEOUT_STEP; } - resultBmpViewport = null; - return resultBitmap; + if(!athread.areResourcesLoading()) { + res = mapActivity.getMapView().getBufferBitmap(); + LOG.debug(mapActivity.getMapView().getBufferImgLoc()); + } + return res; } catch (InterruptedException e) { LOG.error(e); } diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index 0df9bcb74f..35e652094b 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -77,7 +77,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback { protected OsmandSettings settings = null; private CanvasColors canvasColors = null; private Boolean nightMode = null; - private IMapOnImageDrawn mapOnImageDrawnListener; private class CanvasColors { int colorDay = MAP_DEFAULT_COLOR; @@ -106,10 +105,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback { protected static final int emptyTileDivisor = 16; - public interface IMapOnImageDrawn { - void onDraw(RotatedTileBox viewport, Bitmap bmp); - } - public interface OnTrackBallListener { public boolean onTrackBallEvent(MotionEvent e); } @@ -346,10 +341,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback { return application; } - public void setOnImageDrawnListener(IMapOnImageDrawn iMapOnImageDrawn) { - this.mapOnImageDrawnListener = iMapOnImageDrawn; - } - // ///////////////////////// NON UI PART (could be extracted in common) ///////////////////////////// public LatLon getFirstTouchPointLatLon() { return firstTouchPointLatLon; @@ -583,9 +574,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback { if (!bufferBitmap.isRecycled()) { RectF rct = new RectF(x1, y1, x2, y2); canvas.drawBitmap(bufferBitmap, null, rct, paintImg); - if (mapOnImageDrawnListener != null){ - mapOnImageDrawnListener.onDraw(bufferImgLoc,bufferBitmap); - } } canvas.rotate(-rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY()); } @@ -886,6 +874,14 @@ public class OsmandMapTileView implements IMapDownloaderCallback { refreshMap(); } + public Bitmap getBufferBitmap() { + return bufferBitmap; + } + + public RotatedTileBox getBufferImgLoc() { + return bufferImgLoc; + } + public float getDensity() { return currentViewport.getDensity(); } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..f6b961fd5a Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ