Skip to content

Commit

Permalink
fixing zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
DiaZork committed Jan 24, 2025
1 parent 9fb666e commit 58bc3bc
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 18 deletions.
15 changes: 10 additions & 5 deletions src/main/java/eu/ec/doris/kohesio/controller/MapController.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,22 @@ private ResponseEntity<JSONObject> handleBoundingBox(
}
} else if (granularityRegion != null && !granularityRegion.equals("https://linkedopendata.eu/entity/Q1")) {
Geometry geometry = geoJSONReader.read(facetController.nutsRegion.get(granularityRegion).geoJson.replace("'", "\""));
logger.info("\n{}\n{}\n", geometry, boundingBox);
// logger.info("\n{}\n{}\n", geometry, boundingBox);
if (!geometry.convexHull().contains(boundingBox.toGeometry())) {
bboxToUse = new BoundingBox(geometry.getEnvelopeInternal());
}
}

if (zoom == -1) {
zoom = bboxToUse.getZoomLevel();
zoom = bboxToUse.getZoomLevel4();
logger.info(
"zoom1 : {}, zoom2 : {}, zoom3 : {}, zoom4 : {}, bounds: {}",
bboxToUse.getZoomLevel(),
bboxToUse.getZoomLevel2(),
bboxToUse.getZoomLevel3(),
bboxToUse.getZoomLevel4(),
bboxToUse.getBounds()
);
}

logger.info("zoom = {}", zoom);
Expand Down Expand Up @@ -996,9 +1004,6 @@ else if (zoom == 7) {
String geo = querySolution.getBinding("geo").getValue().stringValue();
if (uriCount.containsKey(lid)) {
Zone zone = new Zone(uri, lid, geo, type, uriCount.get(lid));
if (!result.containsKey(lid)) {
result.put(lid, zone);
}
result.put(lid, zone);
}
}
Expand Down
133 changes: 120 additions & 13 deletions src/main/java/eu/ec/doris/kohesio/payload/BoundingBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,6 @@ public Geometry toGeometry() {
return new GeometryFactory().createPolygon(coordinates);
}

// public String getCenterBBox(BoundingBox bbox) throws ParseException {
// Point point = wktReader.read(this.geo).getCentroid();
// Geometry bboxGeom = wktReader.read(bbox.toWkt());
// Point center = bboxGeom.getCentroid();
// Geometry line = wktReader.read("LINESTRING(" + point.getX() + " " + point.getY() + "," + center.getX() + " " + center.getY() + ")");
// // find the intersection between the center of the bbox and the point
// Geometry intersection = line.intersection(bboxGeom);
// logger.info("Intersection: {}", intersection.toText());
//
// Coordinate coordinate = intersection.getCentroid().getCoordinate();
// // lat,lng
// return coordinate.x + "," + coordinate.y;
// }
public int getZoomLevel() {
double latDiff = this.getNorth() - this.getSouth();
double lngDiff = this.getEast() - this.getWest();
Expand All @@ -154,4 +141,124 @@ public int getZoomLevel() {
return Math.max((int) (-1 * ((Math.log(maxDiff) / Math.log(2)) - (Math.log(360) / Math.log(2)))), 1) + 3;
}
}

public int getZoomLevel2() {
double east = this.getEast();
double west = this.getWest();
double north = this.getNorth();
double south = this.getSouth();

// Calculate longitude difference, adjusting for antimeridian crossing
double lngDiff = east - west;
if (lngDiff < 0) {
lngDiff += 360;
}

// Handle edge case where the bounding box spans the entire globe
if (lngDiff >= 360 || (north - south) >= 180) {
return 1; // Minimum zoom
}

// Calculate zoom based on longitude
double zoomX = Math.log(360.0 / lngDiff) / Math.log(2);

// Calculate Mercator-projected latitude difference
double yNorth = latToMercator(north);
double ySouth = latToMercator(south);
double mercatorLatDiff = Math.abs(yNorth - ySouth);

// Avoid division by zero in zoom calculation
if (mercatorLatDiff <= 1e-10) {
mercatorLatDiff = 1e-10;
}

// Calculate zoom based on latitude
double zoomY = Math.log((2 * Math.PI) / mercatorLatDiff) / Math.log(2);

// Use the limiting zoom (smaller of the two)
double zoom = Math.min(zoomX, zoomY);

// Apply adjustments similar to original code (+3) and clamp values
int finalZoom = (int) Math.floor(zoom);
finalZoom = Math.max(finalZoom, 1) + 3; // Ensure minimum zoom of 1+3=4
finalZoom = Math.min(finalZoom, 18); // Maximum zoom level

return finalZoom;
}

public int getZoomLevel3() {
double east = this.getEast();
double west = this.getWest();
double north = this.getNorth();
double south = this.getSouth();

// Calculate longitude difference, handling antimeridian
double lngDiff = east - west;
if (lngDiff < 0) lngDiff += 360;

// Global coverage edge case
if (lngDiff >= 360 || (north - south) >= 180) return 1;

// Viewport adjustment for 2048px width/height (3 = log2(2048/256))
final double VIEWPORT_ADJUSTMENT = 3;

// Calculate longitude-based zoom with adjustment
double zoomX = (Math.log(360.0 / lngDiff) / Math.log(2)) + VIEWPORT_ADJUSTMENT;

// Calculate latitude-based zoom with Mercator projection
double yNorth = latToMercator(north);
double ySouth = latToMercator(south);
double mercatorLatDiff = Math.abs(yNorth - ySouth);
if (mercatorLatDiff < 1e-10) mercatorLatDiff = 1e-10;
double zoomY = (Math.log(2 * Math.PI / mercatorLatDiff) / Math.log(2)) + VIEWPORT_ADJUSTMENT;

// Use the more constrained zoom (min of X/Y zooms)
double zoom = Math.min(zoomX, zoomY);

// Finalize zoom level with clamping
int finalZoom = (int) Math.floor(zoom);
finalZoom = Math.max(finalZoom, 1); // Minimum zoom 1
finalZoom = Math.min(finalZoom, 18); // Maximum zoom 18

return finalZoom;
}

public int getZoomLevel4() {
double east = this.getEast();
double west = this.getWest();
double north = this.getNorth();
double south = this.getSouth();

// Handle longitude wrapping and global bounds
double lngDiff = east - west;
if (lngDiff < 0) lngDiff += 360;
if (lngDiff >= 360 || (north - south) >= 180) return 1;

// Convert to radians for Mercator calculations
double northRad = Math.toRadians(north);
double southRad = Math.toRadians(south);

// Leaflet's Mercator Y coordinate calculation
double y1 = 0.5 - (Math.log(Math.tan(northRad) + 1/Math.cos(northRad)) / (2 * Math.PI));
double y2 = 0.5 - (Math.log(Math.tan(southRad) + 1/Math.cos(southRad)) / (2 * Math.PI));
double latFraction = Math.abs(y1 - y2);

// Calculate zoom for longitude and latitude separately
double zoomX = Math.log(360.0 / lngDiff) / Math.log(2);
double zoomY = Math.log(1.0 / latFraction) / Math.log(2);

// Use the more constrained zoom (matching Leaflet's fitBounds behavior)
double zoom = Math.min(zoomX, zoomY);

// Apply Leaflet's zoom snapping and clamp to valid range
int finalZoom = (int) Math.floor(zoom + 0.5); // Round to nearest integer
finalZoom = Math.max(0, Math.min(finalZoom, 18)); // Standard Leaflet zoom range

return finalZoom;
}

private double latToMercator(double latDegrees) {
double lat = Math.toRadians(latDegrees);
return Math.log(Math.tan(lat / 2 + Math.PI / 4));
}
}

0 comments on commit 58bc3bc

Please sign in to comment.