Skip to content

Commit

Permalink
src/huskymaps: Update API for Javalin 4 path params
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinlin1 committed Oct 17, 2022
1 parent f058760 commit 18e88db
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 62 deletions.
96 changes: 37 additions & 59 deletions src/huskymaps/MapServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import graphs.AStarSolver;
import io.javalin.Javalin;
import io.javalin.core.validation.JavalinValidation;
import io.javalin.core.validation.Validator;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.shape.Point;

Expand All @@ -13,6 +15,7 @@
import java.net.URL;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -55,13 +58,13 @@ public static void main(String[] args) throws Exception {
config.addSinglePageRoot("/", "huskymaps/index.html");
}).start(port());
ConcurrentHashMap<String, BufferedImage> cache = new ConcurrentHashMap<>();
app.get("/map/{coordinates}/{dimensions}", ctx -> {
String[] coordinates = ctx.pathParam("coordinates").split(",");
Point center = pointLonLat(context, coordinates);
int zoom = Integer.parseInt(coordinates[2]);
String[] dimensions = ctx.pathParam("dimensions").split("x");
int width = Integer.parseInt(dimensions[0]);
int height = Integer.parseInt(dimensions[1]);
app.get("/map/{lon},{lat},{zoom}/{width}x{height}", ctx -> {
double lon = ctx.pathParamAsClass("lon", Double.class).get();
double lat = ctx.pathParamAsClass("lat", Double.class).get();
int zoom = ctx.pathParamAsClass("zoom", Integer.class).get();
int width = ctx.pathParamAsClass("width", Integer.class).get();
int height = ctx.pathParamAsClass("height", Integer.class).get();
Point center = context.getShapeFactory().pointLatLon(lat, lon);
BufferedImage image = cache.get(ctx.path());
List<Point> locations = map.getLocations(ctx.queryParam("term"), center);
if (image == null || !locations.isEmpty()) {
Expand All @@ -71,17 +74,18 @@ public static void main(String[] args) throws Exception {
cache.putIfAbsent(ctx.path(), image);
}
}
String start = ctx.queryParam("start");
String goal = ctx.queryParam("goal");
if (start != null && goal != null) {
Validator<Double> startLon = ctx.queryParamAsClass("startLon", Double.class);
Validator<Double> startLat = ctx.queryParamAsClass("startLat", Double.class);
Validator<Double> goalLon = ctx.queryParamAsClass("goalLon", Double.class);
Validator<Double> goalLat = ctx.queryParamAsClass("goalLat", Double.class);
if (JavalinValidation.collectErrors(startLon, startLat, goalLon, goalLat).isEmpty()) {
// Overlay route if the route start and goal are defined.
Point start = context.getShapeFactory().pointLatLon(startLat.get(), startLon.get());
Point goal = context.getShapeFactory().pointLatLon(goalLat.get(), goalLon.get());
List<Point> route = new AStarSolver<>(map, map.closest(start), map.closest(goal)).solution();
// Convert route to xPoints and yPoints for Graphics2D.drawPolyline
double lonDPP = SEATTLE_ROOT_LONDPP / Math.pow(2, zoom);
double latDPP = SEATTLE_ROOT_LATDPP / Math.pow(2, zoom);
List<Point> route = new AStarSolver<>(
map,
map.closest(pointLonLat(context, start.split(","))),
map.closest(pointLonLat(context, goal.split(",")))
).solution();
int[] xPoints = new int[route.size()];
int[] yPoints = new int[route.size()];
int i = 0;
Expand All @@ -90,7 +94,24 @@ public static void main(String[] args) throws Exception {
yPoints[i] = (int) ((center.getLat() - location.getLat()) * (1 / latDPP)) + (height / 2);
i += 1;
}
image = withPolyline(image, xPoints, yPoints);
// Create a copy of the image to avoid modifying cached image
image = new BufferedImage(
image.getColorModel(),
image.copyData(null),
image.isAlphaPremultiplied(),
null
);
Graphics2D g2d = image.createGraphics();
// Draw route outline
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 255));
g2d.setStroke(new BasicStroke(10.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawPolyline(xPoints, yPoints, xPoints.length);
// Draw route on top of outline
g2d.setColor(new Color(108, 181, 230));
g2d.setStroke(new BasicStroke(5.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawPolyline(xPoints, yPoints, xPoints.length);
g2d.dispose();
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
Expand Down Expand Up @@ -119,22 +140,6 @@ private static int port() {
return PORT;
}

/**
* Returns a new {@link Point} from parsing the given longitude and latitude strings.
*
* @param context the spatial context.
* @param lonLat the strings representing the longitude and latitude.
* @return a new {@link Point} from parsing the given longitude and latitude strings.
*/
private static Point pointLonLat(SpatialContext context, String... lonLat) {
if (lonLat == null || lonLat.length < 2) {
return null;
}
double lon = Double.parseDouble(lonLat[0]);
double lat = Double.parseDouble(lonLat[1]);
return context.getShapeFactory().pointLatLon(lat, lon);
}

/**
* Return the API URL for retrieving the map image.
*
Expand Down Expand Up @@ -170,31 +175,4 @@ private static URL url(Point center, int zoom, int width, int height, List<Point
System.getenv("TOKEN")
));
}

/**
* Returns a new image identical to the given image except for an additional polyline defined by the points.
*
* @param image the input image.
* @param xPoints the x-coordinates for the points on the polyline.
* @param yPoints the y-coordinates for the points on the polyline.
* @return a new image identical to the given image except for an additional polyline defined by the points.
*/
private static BufferedImage withPolyline(BufferedImage image, int[] xPoints, int[] yPoints) {
BufferedImage clone = new BufferedImage(
image.getColorModel(),
image.copyData(null),
image.isAlphaPremultiplied(),
null
);
Graphics2D g2d = clone.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 255));
g2d.setStroke(new BasicStroke(10.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawPolyline(xPoints, yPoints, xPoints.length);
g2d.setColor(new Color(108, 181, 230));
g2d.setStroke(new BasicStroke(5.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawPolyline(xPoints, yPoints, xPoints.length);
g2d.dispose();
return clone;
}
}
8 changes: 5 additions & 3 deletions src/huskymaps/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,13 @@
document.addEventListener('dblclick', event => {
const clickLon = lon + (event.pageX - window.innerWidth / 2) * lonDPP();
const clickLat = lat - (event.pageY - window.innerHeight / 2) * latDPP();
if (params.start) {
params.goal = `${clickLon},${clickLat}`;
if (params.startLon && params.startLat) {
params.goalLon = clickLon;
params.goalLat = clickLat;
update();
} else {
params.start = `${clickLon},${clickLat}`;
params.startLon = clickLon;
params.startLat = clickLat;
}
});

Expand Down

0 comments on commit 18e88db

Please sign in to comment.