refactoring

This commit is contained in:
simon 2020-09-04 18:22:24 +03:00
parent 9823461435
commit fef6f93621

View file

@ -1,7 +1,6 @@
package net.osmand.plus.server.endpoints; package net.osmand.plus.server.endpoints;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.util.Pair;
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;
@ -18,13 +17,12 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.*;
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
public class TileEndpoint implements ApiEndpoint { public class TileEndpoint implements ApiEndpoint {
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); private static final int RENDER_WAIT_THRESHOLD = 5000;
ExecutorService executor = Executors.newFixedThreadPool(3); private static final Object lock = new Object();
Map<RotatedTileBox, Bitmap> hashMap = new HashMap<>(); Map<RotatedTileBox, Bitmap> hashMap = new HashMap<>();
Map<RotatedTileBox, Bitmap> map = Collections.synchronizedMap(hashMap); Map<RotatedTileBox, Bitmap> map = Collections.synchronizedMap(hashMap);
OsmandApplication application; OsmandApplication application;
@ -35,27 +33,29 @@ public class TileEndpoint implements ApiEndpoint {
@Override @Override
public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) {
int zoom; synchronized (lock) {
double lat; int zoom;
double lon; double lat;
String fullUri = session.getUri().replace("/tile/", ""); double lon;
Scanner s = new Scanner(fullUri).useDelimiter("/"); String fullUri = session.getUri().replace("/tile/", "");
zoom = s.nextInt(); Scanner s = new Scanner(fullUri).useDelimiter("/");
lat = s.nextDouble(); zoom = s.nextInt();
lon = s.nextDouble(); lat = s.nextDouble();
Bitmap bitmap = requestTile(lat, lon, zoom); lon = s.nextDouble();
if (bitmap == null) { Bitmap bitmap = requestTile(lat, lon, zoom);
return OsmAndHttpServer.ErrorResponses.response500; if (bitmap == null) {
return OsmAndHttpServer.ErrorResponses.response500;
}
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());
} }
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());
} }
@Override @Override
@ -63,40 +63,31 @@ public class TileEndpoint implements ApiEndpoint {
this.application = application; this.application = application;
} }
private synchronized Bitmap requestTile(double lat, double lon, int zoom) { private Bitmap requestTile(double lat, double lon, int zoom) {
Future<Pair<RotatedTileBox, Bitmap>> future;
final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder() final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder()
.setLocation(lat, lon) .setLocation(lat, lon)
.setZoom(zoom) .setZoom(zoom)
.setPixelDimensions(512, 512, 0.5f, 0.5f).build(); .setPixelDimensions(512, 512, 0.5f, 0.5f).build();
final MapRenderRepositories renderer = application.getResourceManager().getRenderer(); final MapRenderRepositories renderer = application.getResourceManager().getRenderer();
future = executor.submit(new Callable<Pair<RotatedTileBox, Bitmap>>() {
@Override
public Pair<RotatedTileBox, Bitmap> call() throws Exception {
Bitmap bmp;
int sleepTime = 500;
while ((bmp = map.get(rotatedTileBox)) == null) {
Thread.sleep(sleepTime);
sleepTime += 500;
}
return Pair.create(rotatedTileBox, bmp);
}
});
application.getResourceManager().updateRendererMap(rotatedTileBox, new AsyncLoadingThread.OnMapLoadedListener() { application.getResourceManager().updateRendererMap(rotatedTileBox, new AsyncLoadingThread.OnMapLoadedListener() {
@Override @Override
public void onMapLoaded(boolean interrupted) { public void onMapLoaded(boolean interrupted) {
map.put(rotatedTileBox, renderer.getBitmap()); map.put(rotatedTileBox, renderer.getBitmap());
} }
}); });
try { Bitmap bmp;
Pair<RotatedTileBox, Bitmap> pair = future.get(); int sleepTime = 500;
Bitmap bitmap = pair.second; while ((bmp = map.get(rotatedTileBox)) == null) {
return bitmap; try {
} catch (ExecutionException e) { Thread.sleep(sleepTime);
LOG.error("Execution exception", e); } catch (InterruptedException e) {
} catch (InterruptedException e) { e.printStackTrace();
LOG.error("Interrupted exception", e); }
sleepTime += 500;
if (sleepTime > RENDER_WAIT_THRESHOLD) {
break;
}
} }
return null; return bmp;
} }
} }