refactoring

This commit is contained in:
simon 2020-09-07 17:30:27 +03:00
parent 485ee88a13
commit 150e769709
8 changed files with 3388 additions and 122 deletions

File diff suppressed because it is too large Load diff

View file

@ -10,18 +10,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>OsmAnd - Offline Mobile Maps and Navigation</title> <title>OsmAnd - Offline Mobile Maps and Navigation</title>
<link rel="stylesheet" type="text/css" href="/css/site.css?v=4"/> <link rel="stylesheet" type="text/css" href="/css/site.css?v=4"/>
<!-- <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" /> -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.1.0/dist/leaflet.css"/> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.1.0/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.1.0/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet@1.1.0/dist/leaflet.js"></script>
<script type="text/javascript" src="/scripts/jquery-3.1.0.min.js"></script> <script type="text/javascript" src="/scripts/jquery-3.1.0.min.js"></script>
<!--
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
-->
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/1.5.2/css/ionicons.min.css">
<link rel="stylesheet" href="css/leaflet.awesome-markers.css">
<script src="/scripts/leaflet.awesome-markers.js"></script> <script src="/scripts/leaflet.awesome-markers.js"></script>
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/1.5.2/css/ionicons.min.css">
<script type="text/javascript" src="/scripts/js.cookie.js"></script>
<script type="text/javascript" src="/scripts/go.js?v=5"></script> <script type="text/javascript" src="/scripts/go.js?v=5"></script>
<script> <script>
@ -70,9 +64,9 @@
}); });
} }
$(document).ready(function () { // $(document).ready(function () {
setupMarkers(); // //setupMarkers();
}); // });
</script> </script>
</head> </head>
@ -80,22 +74,8 @@
<div class="gocontainer" id="gocontainer"> <div class="gocontainer" id="gocontainer">
<div class="goheader"> <div class="goheader">
<a href="/"><img src="/images/logo-grey.png" class="logo"/></a> <a href="/"><img src="/images/logo-grey.png" class="logo"/></a>
<div class="coordinatescontainer">
<div><span class="title">LAT</span><span class="coordinate latitude"></span></div>
<div><span class="title">LON</span><span class="coordinate longitude"></span></div>
</div>
<div class="clear:both;"></div>
</div> </div>
<div id="map"></div> <div id="map"></div>
<div class="overlay" style="display:none;"></div>
<div class="popup" style="display:none;">
<div class="logo"></div>
<h1>Did you know</h1>
<p>OsmAnd has an iOS application</p>
<a class="button yes" href="javascript:void(0);">Yep, I've already got it</a>
<a class="button no" href="javascript:void(0);">Nope, but I'd love to try it</a>
<a class="button cancel" href="javascript:void(0);">Leave me alone</a>
</div>
</div> </div>
</body> </body>
</html> </html>

View file

@ -1,10 +0,0 @@
package net.osmand.plus.server;
import fi.iki.elonen.NanoHTTPD;
import net.osmand.plus.activities.MapActivity;
public interface ApiEndpoint {
NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session);
void setMapActivity(MapActivity mapActivity);
}

View file

@ -1,8 +0,0 @@
package net.osmand.plus.server;
import android.graphics.Bitmap;
import net.osmand.data.RotatedTileBox;
public interface IMapOnImageDrawn {
void onDraw(RotatedTileBox viewport, Bitmap bmp);
}

View file

@ -15,29 +15,17 @@ import java.util.Map;
public class OsmAndHttpServer extends NanoHTTPD { public class OsmAndHttpServer extends NanoHTTPD {
private static final String FOLDER_NAME = "server"; private static final String FOLDER_NAME = "server";
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class); private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class);
public static final int PORT = 24990;
public static String HOSTNAME = "0.0.0.0";
private final Map<String, ApiEndpoint> endpoints = new HashMap<>(); private final Map<String, ApiEndpoint> endpoints = new HashMap<>();
private OsmandApplication application;
private MapActivity mapActivity; private MapActivity mapActivity;
public OsmAndHttpServer(MapActivity mapActivity) throws IOException { public OsmAndHttpServer(String hostname, int port) {
super(HOSTNAME, PORT); super(hostname, port);
setMapActivity(mapActivity);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
registerEndpoints();
} }
public OsmandApplication getApplication() { public void start(MapActivity mapActivity) throws IOException {
return application;
}
public void setMapActivity(MapActivity mapActivity) {
this.application = mapActivity.getMyApplication();
this.mapActivity = mapActivity; this.mapActivity = mapActivity;
for (String s : endpoints.keySet()) { registerEndpoints();
endpoints.get(s).setMapActivity(mapActivity); start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
}
} }
@Override @Override
@ -78,16 +66,16 @@ public class OsmAndHttpServer extends NanoHTTPD {
} }
private void register(String path, ApiEndpoint endpoint) { private void register(String path, ApiEndpoint endpoint) {
endpoint.setMapActivity(mapActivity);
endpoints.put(path, endpoint); endpoints.put(path, endpoint);
} }
private NanoHTTPD.Response getStatic(String uri) { private NanoHTTPD.Response getStatic(String uri) {
InputStream is; InputStream is;
String mimeType = parseMimeType(uri); String mimeType = parseMimeType(uri);
if (application != null) { OsmandApplication app = mapActivity.getMyApplication();
if (app != null) {
try { try {
is = application.getAssets().open(FOLDER_NAME + uri); is = app.getAssets().open(FOLDER_NAME + uri);
if (is.available() == 0) { if (is.available() == 0) {
return ErrorResponses.response404; return ErrorResponses.response404;
} }
@ -114,6 +102,14 @@ public class OsmAndHttpServer extends NanoHTTPD {
return type; return type;
} }
public String getUrl() {
return "http://" + getHostname() + ":" + getListeningPort();
}
public interface ApiEndpoint {
NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session);
}
public static class ErrorResponses { public static class ErrorResponses {
public static NanoHTTPD.Response response404 = public static NanoHTTPD.Response response404 =
newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND, newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND,

View file

@ -12,8 +12,8 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import fi.iki.elonen.NanoHTTPD;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
@ -25,6 +25,7 @@ import static android.content.Context.WIFI_SERVICE;
public class ServerFragment extends BaseOsmAndFragment { public class ServerFragment extends BaseOsmAndFragment {
private final static Log LOG = PlatformUtil.getLog(ServerFragment.class); private final static Log LOG = PlatformUtil.getLog(ServerFragment.class);
private final int port = 24990;
private boolean initialized = false; private boolean initialized = false;
private OsmAndHttpServer server; private OsmAndHttpServer server;
private View view; private View view;
@ -85,11 +86,12 @@ public class ServerFragment extends BaseOsmAndFragment {
private void initServer() { private void initServer() {
final int THREAD_ID = 10000; final int THREAD_ID = 10000;
TrafficStats.setThreadStatsTag(THREAD_ID); TrafficStats.setThreadStatsTag(THREAD_ID);
OsmAndHttpServer.HOSTNAME = getDeviceAddress(); String hostname = getDeviceAddress();
try { try {
server = new OsmAndHttpServer((MapActivity) getActivity()); server = new OsmAndHttpServer(hostname, port);
server.start((MapActivity) getActivity());
initialized = true; initialized = true;
updateTextView("Server started at: http://" + getDeviceAddress() + ":" + OsmAndHttpServer.PORT); updateTextView("Server started at: " + server.getUrl());
} catch (IOException e) { } catch (IOException e) {
Toast.makeText(requireContext(), Toast.makeText(requireContext(),
e.getLocalizedMessage(), e.getLocalizedMessage(),

View file

@ -4,96 +4,78 @@ import android.graphics.Bitmap;
import fi.iki.elonen.NanoHTTPD; import fi.iki.elonen.NanoHTTPD;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.plus.server.ApiEndpoint;
import net.osmand.plus.server.IMapOnImageDrawn;
import net.osmand.plus.server.OsmAndHttpServer; import net.osmand.plus.server.OsmAndHttpServer;
import net.osmand.plus.views.OsmandMapTileView;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import static fi.iki.elonen.NanoHTTPD.SOCKET_READ_TIMEOUT;
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
public class TileEndpoint implements ApiEndpoint, IMapOnImageDrawn { public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint, OsmandMapTileView.IMapOnImageDrawn {
private static final Object lock = new Object();
private static final int TILE_SIZE_PX = 512; private static final int TILE_SIZE_PX = 512;
private static final int TIMEOUT_STEP = 500;
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class);
Map<RotatedTileBox, Bitmap> hashMap = new HashMap<>(); private RotatedTileBox resultBmpViewport;
Map<RotatedTileBox, Bitmap> map = Collections.synchronizedMap(hashMap);
OsmandApplication application;
private RotatedTileBox viewPort;
private Bitmap resultBitmap; private Bitmap resultBitmap;
private MapActivity mapActivity; private MapActivity mapActivity;
public TileEndpoint(MapActivity mapActivity) { public TileEndpoint(MapActivity mapActivity) {
setMapActivity(mapActivity);
}
@Override
public void setMapActivity(MapActivity mapActivity) {
this.mapActivity = mapActivity; this.mapActivity = mapActivity;
this.application = mapActivity.getMyApplication();
} }
@Override @Override
public void onDraw(RotatedTileBox viewport, Bitmap bmp) { public void onDraw(RotatedTileBox viewport, Bitmap bmp) {
map.put(viewport, bmp); this.resultBmpViewport = viewport;
this.viewPort = viewport;
this.resultBitmap = bmp; this.resultBitmap = bmp;
} }
@Override @Override
public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) {
synchronized (lock) { this.mapActivity.getMapView().setOnImageDrawnListener(this);
this.mapActivity.getMapView().setOnImageDrawnListener(this); RotatedTileBox tileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
RotatedTileBox tileBoxCopy = mapActivity.getMapView().getCurrentRotatedTileBox().copy(); Scanner s = new Scanner(session.getUri()).useDelimiter("/");
int zoom; //reading path
double lat; s.next();
double lon; int zoom = s.nextInt();
String fullUri = session.getUri().replace("/tile/", ""); double lat = s.nextDouble();
Scanner s = new Scanner(fullUri).useDelimiter("/"); double lon = s.nextDouble();
zoom = s.nextInt(); Bitmap bitmap = requestTile(lat, lon, zoom);
lat = s.nextDouble(); if (bitmap == null) {
lon = s.nextDouble(); return OsmAndHttpServer.ErrorResponses.response500;
Bitmap bitmap = requestTile(lat, lon, zoom);
if (bitmap == null) {
return OsmAndHttpServer.ErrorResponses.response500;
}
//stream also needs to be synchronized
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
ByteArrayInputStream str = new ByteArrayInputStream(byteArray);
mapActivity.getMapView().setCurrentViewport(tileBoxCopy);
return newFixedLengthResponse(
NanoHTTPD.Response.Status.OK,
"image/png",
str,
str.available());
} }
//stream also needs to be synchronized
ByteArrayOutputStream stream = new ByteArrayOutputStream();
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());
} }
private Bitmap requestTile(double lat, double lon, int zoom) { private synchronized Bitmap requestTile(double lat, double lon, int zoom) {
final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder() final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder()
.setLocation(lat, lon) .setLocation(lat, lon)
.setZoom(zoom) .setZoom(zoom)
.setPixelDimensions(TILE_SIZE_PX, TILE_SIZE_PX, 0.5f, 0.5f).build(); .setPixelDimensions(TILE_SIZE_PX, TILE_SIZE_PX, 0.5f, 0.5f).build();
final MapRenderRepositories renderer = application.getResourceManager().getRenderer();
mapActivity.getMapView().setCurrentViewport(rotatedTileBox); mapActivity.getMapView().setCurrentViewport(rotatedTileBox);
Bitmap bmp = null; Bitmap bmp = null;
int timeout = 0; int timeout = 0;
try { try {
while ((viewPort == null && !rotatedTileBox.equals(viewPort)) || timeout < 5000) { while (!rotatedTileBox.equals(resultBmpViewport) && timeout < SOCKET_READ_TIMEOUT) {
Thread.sleep(100); Thread.sleep(TIMEOUT_STEP);
timeout += 100; timeout += TIMEOUT_STEP;
} }
resultBmpViewport = null;
return resultBitmap; return resultBitmap;
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.error(e); LOG.error(e);

View file

@ -46,8 +46,6 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.TwoFingerTapDetector; import net.osmand.plus.helpers.TwoFingerTapDetector;
import net.osmand.plus.server.IMapOnImageDrawn;
import net.osmand.plus.server.endpoints.TileEndpoint;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener; import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
@ -89,7 +87,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
private class FPSMeasurement { private class FPSMeasurement {
int fpsMeasureCount = 0; int fpsMeasureCount = 0;
int fpsMeasureMs = 0; int fpsMeasureMs = 0;
long fpsFirstMeasurement = 0 ; long fpsFirstMeasurement = 0;
float fps; float fps;
void calculateFPS(long start, long end) { void calculateFPS(long start, long end) {
@ -108,6 +106,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
protected static final int emptyTileDivisor = 16; protected static final int emptyTileDivisor = 16;
public interface IMapOnImageDrawn {
void onDraw(RotatedTileBox viewport, Bitmap bmp);
}
public interface OnTrackBallListener { public interface OnTrackBallListener {
public boolean onTrackBallEvent(MotionEvent e); public boolean onTrackBallEvent(MotionEvent e);
} }
@ -582,7 +584,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
RectF rct = new RectF(x1, y1, x2, y2); RectF rct = new RectF(x1, y1, x2, y2);
canvas.drawBitmap(bufferBitmap, null, rct, paintImg); canvas.drawBitmap(bufferBitmap, null, rct, paintImg);
if (mapOnImageDrawnListener != null){ if (mapOnImageDrawnListener != null){
mapOnImageDrawnListener.onDraw(currentViewport,bufferBitmap); mapOnImageDrawnListener.onDraw(bufferImgLoc,bufferBitmap);
} }
} }
canvas.rotate(-rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY()); canvas.rotate(-rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY());