server refactoring
This commit is contained in:
parent
6a95630076
commit
e47493a229
3 changed files with 160 additions and 80 deletions
|
@ -2,6 +2,8 @@ package net.osmand.data;
|
|||
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class RotatedTileBox {
|
||||
|
||||
/// primary fields
|
||||
|
@ -69,6 +71,47 @@ public class RotatedTileBox {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RotatedTileBox tileBox = (RotatedTileBox) o;
|
||||
return Double.compare(tileBox.lat, lat) == 0 &&
|
||||
Double.compare(tileBox.lon, lon) == 0 &&
|
||||
Float.compare(tileBox.rotate, rotate) == 0 &&
|
||||
Float.compare(tileBox.density, density) == 0 &&
|
||||
zoom == tileBox.zoom &&
|
||||
Double.compare(tileBox.mapDensity, mapDensity) == 0 &&
|
||||
Double.compare(tileBox.zoomAnimation, zoomAnimation) == 0 &&
|
||||
Double.compare(tileBox.zoomFloatPart, zoomFloatPart) == 0 &&
|
||||
cx == tileBox.cx &&
|
||||
cy == tileBox.cy &&
|
||||
pixWidth == tileBox.pixWidth &&
|
||||
pixHeight == tileBox.pixHeight &&
|
||||
Double.compare(tileBox.zoomFactor, zoomFactor) == 0 &&
|
||||
Double.compare(tileBox.rotateCos, rotateCos) == 0 &&
|
||||
Double.compare(tileBox.rotateSin, rotateSin) == 0 &&
|
||||
Double.compare(tileBox.oxTile, oxTile) == 0 &&
|
||||
Double.compare(tileBox.oyTile, oyTile) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1 + (int)lat +
|
||||
3* (int)lon +
|
||||
5* (int)rotate +
|
||||
7* (int)density +
|
||||
11* (int)zoom +
|
||||
13* (int)mapDensity +
|
||||
17* (int)zoomAnimation +
|
||||
19* (int)zoomFloatPart +
|
||||
23* (int)cx +
|
||||
29* (int)cy +
|
||||
31* (int)pixWidth +
|
||||
37* (int)pixHeight;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void calculateDerivedFields() {
|
||||
zoomFactor = Math.pow(2, zoomAnimation + zoomFloatPart) * 256 * mapDensity;
|
||||
double rad = Math.toRadians(this.rotate);
|
||||
|
|
|
@ -1,37 +1,28 @@
|
|||
package net.osmand.plus.server;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import androidx.core.util.Pair;
|
||||
import com.google.gson.Gson;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
import net.osmand.data.*;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.resources.ResourceManager;
|
||||
import net.osmand.plus.server.map.LayersDraw;
|
||||
import net.osmand.plus.server.map.MapTileMiniLayer;
|
||||
import net.osmand.plus.server.map.OsmandMapMiniLayer;
|
||||
import net.osmand.plus.server.map.OsmandMapTileMiniView;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
|
||||
|
||||
public class ApiRouter {
|
||||
public class ApiRouter implements OsmandMapTileView.IMapImageDrawListener {
|
||||
private OsmandApplication androidContext;
|
||||
|
||||
public OsmandApplication getAndroidContext() {
|
||||
return androidContext;
|
||||
}
|
||||
|
@ -42,80 +33,92 @@ public class ApiRouter {
|
|||
//change to weakreference
|
||||
public static MapActivity mapActivity;
|
||||
|
||||
public ApiRouter(){
|
||||
public ApiRouter() {
|
||||
initRoutes();
|
||||
}
|
||||
|
||||
private void initRoutes() {
|
||||
ApiEndpoint favorites = new ApiEndpoint();
|
||||
favorites.uri = "/favorites";
|
||||
favorites.apiCall = new ApiEndpoint.ApiCall(){
|
||||
favorites.apiCall = new ApiEndpoint.ApiCall() {
|
||||
@Override
|
||||
public NanoHTTPD.Response call(NanoHTTPD.IHTTPSession session) {
|
||||
return newFixedLengthResponse(getFavoritesJson());
|
||||
}
|
||||
};
|
||||
endpoints.put(favorites.uri,favorites);
|
||||
endpoints.put(favorites.uri, favorites);
|
||||
|
||||
final ApiEndpoint tile = new ApiEndpoint();
|
||||
tile.uri = "/tile";
|
||||
tile.apiCall = new ApiEndpoint.ApiCall(){
|
||||
tile.apiCall = new ApiEndpoint.ApiCall() {
|
||||
@Override
|
||||
public NanoHTTPD.Response call(NanoHTTPD.IHTTPSession session) {
|
||||
try{
|
||||
int zoom = 0;
|
||||
double lat = 0;//50.901430;
|
||||
double lon = 0;//34.801775;
|
||||
try{
|
||||
String fullUri = session.getUri().replace("/tile/","");
|
||||
Scanner s = new Scanner(fullUri).useDelimiter("/");
|
||||
zoom = s.nextInt();
|
||||
lat = s.nextDouble();//50.901430;
|
||||
lon = s.nextDouble();//34.801775;
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
Log.d("TILE","HAVING VALUES" + zoom + " " + lat + " " + lon);
|
||||
RotatedTileBox rotatedTileBox = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
|
||||
rotatedTileBox.setZoom(zoom);
|
||||
rotatedTileBox.setLatLonCenter(lat,lon);
|
||||
rotatedTileBox.setPixelDimensions(512,512);
|
||||
mapActivity.getMapView().setIntZoom(zoom);
|
||||
mapActivity.getMapView().setLatLon(lat,lon);
|
||||
OsmandMapLayer.DrawSettings param =
|
||||
new OsmandMapLayer.DrawSettings(androidContext.getDaynightHelper().isNightMode(),
|
||||
false);
|
||||
mapActivity.getMapView().refreshMap();
|
||||
mapActivity.getMapView().refreshMapInternal(param);
|
||||
mapActivity.getMapView().refreshBaseMapInternal(rotatedTileBox, param);
|
||||
Bitmap bitmap = mapActivity.getMapView().currentCanvas;
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
OsmandMapLayer.DrawSettings drawSettings = new OsmandMapLayer.DrawSettings(
|
||||
androidContext.getDaynightHelper().isNightMode(),
|
||||
true);
|
||||
// mapActivity.getMapView().drawOverMap(canvas,
|
||||
// rotatedTileBox,
|
||||
// drawSettings);
|
||||
//Bitmap bitmap = Bitmap.createBitmap(512,512,Bitmap.Config.ARGB_8888);
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
ByteArrayInputStream str = new ByteArrayInputStream(byteArray);
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
"image/png",
|
||||
str,
|
||||
str.available());
|
||||
}
|
||||
catch (Exception e){
|
||||
try {
|
||||
return tileApiCall(session);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
};
|
||||
endpoints.put(tile.uri,tile);
|
||||
endpoints.put(tile.uri, tile);
|
||||
}
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(3);
|
||||
|
||||
Map<RotatedTileBox,Bitmap> hashMap = new HashMap<>();
|
||||
Map<RotatedTileBox,Bitmap> map = Collections.synchronizedMap(hashMap);
|
||||
|
||||
private NanoHTTPD.Response tileApiCall(NanoHTTPD.IHTTPSession session) {
|
||||
int zoom = 0;
|
||||
double lat = 0;//50.901430;
|
||||
double lon = 0;//34.801775;
|
||||
try {
|
||||
String fullUri = session.getUri().replace("/tile/", "");
|
||||
Scanner s = new Scanner(fullUri).useDelimiter("/");
|
||||
zoom = s.nextInt();
|
||||
lat = s.nextDouble();
|
||||
lon = s.nextDouble();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
mapActivity.getMapView().setMapImageDrawListener(this);
|
||||
Future<Pair<RotatedTileBox,Bitmap>> future;
|
||||
final RotatedTileBox rotatedTileBox = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
|
||||
rotatedTileBox.setZoom(zoom);
|
||||
rotatedTileBox.setLatLonCenter(lat, lon);
|
||||
rotatedTileBox.setPixelDimensions(512, 512);
|
||||
future = executor.submit(new Callable<Pair<RotatedTileBox, Bitmap>>() {
|
||||
@Override
|
||||
public Pair<RotatedTileBox, Bitmap> call() throws Exception {
|
||||
Bitmap bmp;
|
||||
while((bmp = map.get(rotatedTileBox)) == null) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
return Pair.create(rotatedTileBox,bmp);
|
||||
}
|
||||
});
|
||||
mapActivity.getMapView().setCurrentRotatedTileBox(rotatedTileBox);
|
||||
try {
|
||||
Pair<RotatedTileBox, Bitmap> pair = future.get();
|
||||
Bitmap bitmap = pair.second;// mapActivity.getMapView().currentCanvas;
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
ByteArrayInputStream str = new ByteArrayInputStream(byteArray);
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
"image/png",
|
||||
str,
|
||||
str.available());
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return ErrorResponses.response500;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAndroidContext(OsmandApplication androidContext) {
|
||||
|
@ -132,10 +135,9 @@ public class ApiRouter {
|
|||
uri.contains("/fonts/") ||
|
||||
uri.contains("/favicon.ico")
|
||||
) return getStatic(uri);
|
||||
if (isApiUrl(uri)){
|
||||
if (isApiUrl(uri)) {
|
||||
return routeApi(session);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return routeContent(session);
|
||||
}
|
||||
}
|
||||
|
@ -143,18 +145,18 @@ public class ApiRouter {
|
|||
private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) {
|
||||
String uri = session.getUri();
|
||||
//TODO rewrite
|
||||
if (uri.contains("tile")){
|
||||
if (uri.contains("tile")) {
|
||||
return endpoints.get("/tile").apiCall.call(session);
|
||||
}
|
||||
ApiEndpoint endpoint = endpoints.get(uri);
|
||||
if (endpoint != null){
|
||||
if (endpoint != null) {
|
||||
return endpoint.apiCall.call(session);
|
||||
}
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
|
||||
private boolean isApiUrl(String uri) {
|
||||
for (String endpoint : endpoints.keySet()){
|
||||
for (String endpoint : endpoints.keySet()) {
|
||||
//TODO rewrite contains
|
||||
if (endpoint.equals(uri) || uri.contains("tile")) return true;
|
||||
}
|
||||
|
@ -240,13 +242,18 @@ public class ApiRouter {
|
|||
text.append(json);
|
||||
text.append(",");
|
||||
}
|
||||
return "[" + text.substring(0,text.length()-1) + "]";
|
||||
return "[" + text.substring(0, text.length() - 1) + "]";
|
||||
}
|
||||
|
||||
private String jsonFromFavorite(FavouritePoint favouritePoint) {
|
||||
return gson.toJson(favouritePoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(RotatedTileBox viewport, Bitmap bmp) {
|
||||
this.map.put(viewport,bmp);
|
||||
}
|
||||
|
||||
static class ErrorResponses {
|
||||
static NanoHTTPD.Response response404 =
|
||||
newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND,
|
||||
|
|
|
@ -105,7 +105,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
|
||||
protected static final int emptyTileDivisor = 16;
|
||||
|
||||
|
||||
public interface OnTrackBallListener {
|
||||
public boolean onTrackBallEvent(MotionEvent e);
|
||||
}
|
||||
|
@ -122,6 +121,10 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
public void onDrawOverMap();
|
||||
}
|
||||
|
||||
public interface IMapImageDrawListener {
|
||||
public void onDraw(RotatedTileBox viewport,Bitmap bmp);
|
||||
}
|
||||
|
||||
protected static final Log LOG = PlatformUtil.getLog(OsmandMapTileView.class);
|
||||
|
||||
|
||||
|
@ -145,6 +148,8 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
|
||||
private OnTrackBallListener trackBallDelegate;
|
||||
|
||||
private IMapImageDrawListener iMapImageDrawListener;
|
||||
|
||||
private AccessibilityActionsProvider accessibilityActions;
|
||||
|
||||
private List<OsmandMapLayer> layers = new ArrayList<>();
|
||||
|
@ -367,6 +372,14 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
return wasZoomInMultiTouch;
|
||||
}
|
||||
|
||||
public IMapImageDrawListener getMapImageDrawListener() {
|
||||
return iMapImageDrawListener;
|
||||
}
|
||||
|
||||
public void setMapImageDrawListener(IMapImageDrawListener iMapImageDrawListener) {
|
||||
this.iMapImageDrawListener = iMapImageDrawListener;
|
||||
}
|
||||
|
||||
public boolean mapGestureAllowed(OsmandMapLayer.MapGestureType type) {
|
||||
for (OsmandMapLayer layer : layers) {
|
||||
if (!layer.isMapGestureAllowed(type)) {
|
||||
|
@ -518,8 +531,8 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
|
||||
public void restoreMapRatio() {
|
||||
RotatedTileBox box = currentViewport.copy();
|
||||
float rx = (float)box.getCenterPixelX() / box.getPixWidth();
|
||||
float ry = (float)box.getCenterPixelY() / box.getPixHeight();
|
||||
float rx = (float) box.getCenterPixelX() / box.getPixWidth();
|
||||
float ry = (float) box.getCenterPixelY() / box.getPixHeight();
|
||||
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
|
||||
ry -= 0.35;
|
||||
}
|
||||
|
@ -616,6 +629,9 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
}
|
||||
long end = SystemClock.elapsedRealtime();
|
||||
additional.calculateFPS(start, end);
|
||||
if (iMapImageDrawListener != null){
|
||||
iMapImageDrawListener.onDraw(tileBox,bufferBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshMapInternal(DrawSettings drawSettings) {
|
||||
|
@ -871,6 +887,20 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
|
|||
return currentViewport;
|
||||
}
|
||||
|
||||
public void setCurrentRotatedTileBox(net.osmand.data.RotatedTileBox tileBox) {
|
||||
float rx = (float) tileBox.getCenterPixelX() / tileBox.getPixWidth();
|
||||
float ry = (float) tileBox.getCenterPixelY() / tileBox.getPixHeight();
|
||||
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
|
||||
ry -= 0.35;
|
||||
}
|
||||
tileBox.setCenterLocation(rx, ry);
|
||||
LatLon screenCenter = tileBox.getLatLonFromPixel(tileBox.getPixWidth() / 2f, tileBox.getPixHeight() / 2f);
|
||||
mapRatioX = 0;
|
||||
mapRatioY = 0;
|
||||
setLatLon(screenCenter.getLatitude(), screenCenter.getLongitude());
|
||||
currentViewport = tileBox;
|
||||
}
|
||||
|
||||
public float getDensity() {
|
||||
return currentViewport.getDensity();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue