Stuff
This commit is contained in:
parent
ac04dbf352
commit
1d7000d592
3 changed files with 61 additions and 6 deletions
|
|
@ -150,6 +150,9 @@ public class ActivityImageService {
|
||||||
int trackWidth = (int) (width * 0.6);
|
int trackWidth = (int) (width * 0.6);
|
||||||
int trackHeight = height;
|
int trackHeight = height;
|
||||||
|
|
||||||
|
// Get letterbox transformation from OSM renderer
|
||||||
|
OsmTileRenderer.LetterboxTransform letterbox = osmTileRenderer.getLastLetterboxTransform();
|
||||||
|
|
||||||
// Convert bounds to Web Mercator normalized coordinates (0-1)
|
// Convert bounds to Web Mercator normalized coordinates (0-1)
|
||||||
// This matches the projection used by OSM tiles
|
// This matches the projection used by OSM tiles
|
||||||
double minX = longitudeToWebMercatorX(bounds.minLon);
|
double minX = longitudeToWebMercatorX(bounds.minLon);
|
||||||
|
|
@ -158,8 +161,15 @@ public class ActivityImageService {
|
||||||
double maxY = latitudeToWebMercatorY(bounds.minLat); // Note: minLat -> maxY (inverted)
|
double maxY = latitudeToWebMercatorY(bounds.minLat); // Note: minLat -> maxY (inverted)
|
||||||
|
|
||||||
// Calculate scale to map Web Mercator coordinates to pixels
|
// Calculate scale to map Web Mercator coordinates to pixels
|
||||||
double scaleX = trackWidth / (maxX - minX);
|
// Apply letterbox scaling if available
|
||||||
double scaleY = trackHeight / (maxY - minY);
|
double baseScaleX = trackWidth / (maxX - minX);
|
||||||
|
double baseScaleY = trackHeight / (maxY - minY);
|
||||||
|
|
||||||
|
double scaleX = letterbox != null ? baseScaleX * letterbox.scaleFactorX : baseScaleX;
|
||||||
|
double scaleY = letterbox != null ? baseScaleY * letterbox.scaleFactorY : baseScaleY;
|
||||||
|
|
||||||
|
int offsetX = letterbox != null ? letterbox.offsetX : 0;
|
||||||
|
int offsetY = letterbox != null ? letterbox.offsetY : 0;
|
||||||
|
|
||||||
// Draw track segments with privacy fade
|
// Draw track segments with privacy fade
|
||||||
g2d.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
g2d.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
||||||
|
|
@ -184,10 +194,11 @@ public class ActivityImageService {
|
||||||
double mercatorY2 = latitudeToWebMercatorY(lat2);
|
double mercatorY2 = latitudeToWebMercatorY(lat2);
|
||||||
|
|
||||||
// Map Web Mercator coordinates to pixel coordinates
|
// Map Web Mercator coordinates to pixel coordinates
|
||||||
double x1 = (mercatorX1 - minX) * scaleX;
|
// Apply letterbox offset
|
||||||
double y1 = (mercatorY1 - minY) * scaleY;
|
double x1 = (mercatorX1 - minX) * scaleX + offsetX;
|
||||||
double x2 = (mercatorX2 - minX) * scaleX;
|
double y1 = (mercatorY1 - minY) * scaleY + offsetY;
|
||||||
double y2 = (mercatorY2 - minY) * scaleY;
|
double x2 = (mercatorX2 - minX) * scaleX + offsetX;
|
||||||
|
double y2 = (mercatorY2 - minY) * scaleY + offsetY;
|
||||||
|
|
||||||
// Calculate opacity based on distance from start/end
|
// Calculate opacity based on distance from start/end
|
||||||
double distanceFromStart = cumulativeDistances[i];
|
double distanceFromStart = cumulativeDistances[i];
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,37 @@ public class OsmTileRenderer {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder for letterboxing transformation parameters.
|
||||||
|
*/
|
||||||
|
public static class LetterboxTransform {
|
||||||
|
public final int offsetX;
|
||||||
|
public final int offsetY;
|
||||||
|
public final int scaledWidth;
|
||||||
|
public final int scaledHeight;
|
||||||
|
public final double scaleFactorX;
|
||||||
|
public final double scaleFactorY;
|
||||||
|
|
||||||
|
public LetterboxTransform(int offsetX, int offsetY, int scaledWidth, int scaledHeight,
|
||||||
|
int originalWidth, int originalHeight) {
|
||||||
|
this.offsetX = offsetX;
|
||||||
|
this.offsetY = offsetY;
|
||||||
|
this.scaledWidth = scaledWidth;
|
||||||
|
this.scaledHeight = scaledHeight;
|
||||||
|
this.scaleFactorX = (double) scaledWidth / originalWidth;
|
||||||
|
this.scaleFactorY = (double) scaledHeight / originalHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LetterboxTransform lastLetterboxTransform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the letterbox transformation from the last render operation.
|
||||||
|
*/
|
||||||
|
public LetterboxTransform getLastLetterboxTransform() {
|
||||||
|
return lastLetterboxTransform;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a map image with OSM tiles covering the specified geographic bounds.
|
* Render a map image with OSM tiles covering the specified geographic bounds.
|
||||||
*
|
*
|
||||||
|
|
@ -168,6 +199,12 @@ public class OsmTileRenderer {
|
||||||
g.drawImage(croppedMap, drawX, drawY, drawWidth, drawHeight, null);
|
g.drawImage(croppedMap, drawX, drawY, drawWidth, drawHeight, null);
|
||||||
g.dispose();
|
g.dispose();
|
||||||
|
|
||||||
|
// Store letterbox transform for track rendering
|
||||||
|
lastLetterboxTransform = new LetterboxTransform(
|
||||||
|
drawX, drawY, drawWidth, drawHeight,
|
||||||
|
croppedMap.getWidth(), croppedMap.getHeight()
|
||||||
|
);
|
||||||
|
|
||||||
return scaledMap;
|
return scaledMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,13 @@ public class WeatherService {
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode firstPoint = trackPoints.get(0);
|
JsonNode firstPoint = trackPoints.get(0);
|
||||||
|
|
||||||
|
// Check if lat/lon fields exist
|
||||||
|
if (!firstPoint.has("lat") || !firstPoint.has("lon")) {
|
||||||
|
log.debug("First track point missing lat/lon for activity {}", activity.getId());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
double lat = firstPoint.get("lat").asDouble();
|
double lat = firstPoint.get("lat").asDouble();
|
||||||
double lon = firstPoint.get("lon").asDouble();
|
double lon = firstPoint.get("lon").asDouble();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue