Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,30 @@ public class BboxUtils {
* @return - Geometry which is bounded [-180, 180]
*/
public static MultiPolygon normalizeBbox(double minx, double maxx, double miny, double maxy) {
// Bounding check, if greater than 360 already cover whole world, so adjust the maxx to something
// meaningful, noted that minx and maxx is not normalized yet so can be anything even beyond 180
if((maxx - minx) >= 360) {
// Value does not matter, it covered whole world which is equal to
// A span of 360 or more covers the whole world. Incoming longitudes may sit outside [-180, 180].
if ((maxx - minx) >= 360) {
minx = -180;
maxx = 180;
} else {
// Shift into one 360-degree window with minx in [-180, 180). A viewport that
// continues past the date line (for example 112 to 188.9) then has maxx > 180,
// and the wrapped east edge is maxx - 360 (188.9 -> -171.1), not -(maxx - 180).
while (minx < -180) {
minx += 360;
maxx += 360;
}
while (minx >= 180) {
minx -= 360;
maxx -= 360;
}
}
minx = (minx < -180) ? 180 - Math.abs(180 + minx) : minx;
maxx = (maxx > 180) ? -(maxx - 180) : maxx;
// Normalized the box, so it is within [-180, 180]

List<Polygon> polygons = new ArrayList<>();
if(maxx >= 0 && maxx <= 180) {
// Normal case
polygons.add((Polygon)createBoxPolygon(minx, maxx, miny, maxy));
}
else {
polygons.add((Polygon)createBoxPolygon(minx, 180, miny, maxy));
polygons.add((Polygon)createBoxPolygon(-180, maxx, miny, maxy));
if (maxx <= 180) {
polygons.add((Polygon) createBoxPolygon(minx, maxx, miny, maxy));
} else {
polygons.add((Polygon) createBoxPolygon(minx, 180, miny, maxy));
polygons.add((Polygon) createBoxPolygon(-180, maxx - 360, miny, maxy));
}
return GeometryUtils.getFactory().createMultiPolygon(polygons.toArray(new Polygon[0]));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -855,10 +855,10 @@ public void verifyCentroidCalIsCorrect() throws IOException {
cacheNoLandGeometry.evictAllNoLandGeometry();

String expected = """
{"links":[],"collections":[{"properties":{"centroid":[[129.19579,-33.09197]]},"id":"097a5435-91f4-4730-90aa-ddae94afcbda","links":[],"itemType":"Collection"}],"total":1,"search_after":["0.0","str:097a5435-91f4-4730-90aa-ddae94afcbda"]}""";
{"links":[],"collections":[{"properties":{"centroid":[[166.75446,-27.62500]]},"id":"097a5435-91f4-4730-90aa-ddae94afcbda","links":[],"itemType":"Collection"}],"total":1,"search_after":["0.0","str:097a5435-91f4-4730-90aa-ddae94afcbda"]}""";

ResponseEntity<String> collections = testRestTemplate.exchange(
getBasePath() + "/collections?properties=id,centroid&q=097a5435-91f4-4730-90aa-ddae94afcbda&filter=page_size=800 AND BBOX(geometry,117.21720908167362,-34.63803401514584,149.78279091832303,-16.36196598484962)&sortby=id",
getBasePath() + "/collections?properties=id,centroid&q=097a5435-91f4-4730-90aa-ddae94afcbda&filter=page_size=800 AND BBOX(geometry,112.03097102449121,-50.499567507281824,188.89962377189153,-4.6416246696196195)&sortby=id",
HttpMethod.GET,
null,
new ParameterizedTypeReference<>() {});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package au.org.aodn.ogcapi.server.core.util;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Polygon;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static au.org.aodn.ogcapi.server.BaseTestClass.readResourceFile;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class BboxUtilsTest {
/**
* This test have bbox start from -4.6 -> 0 -> 180 -> -180 -> -76.5
* East edge 314.173 wraps to 314.173 - 360 = -45.827, so the box runs
* -4.6 -> 180 and -180 -> -45.827.
*/
@Test
public void verifyNormalizeBbox1() {
Expand All @@ -18,11 +26,11 @@ public void verifyNormalizeBbox1() {
Polygon expect1 = (Polygon)BboxUtils.createBoxPolygon(-4.614697916267209, 180, -76.58044236400484, 60.83962132913365);
assertEquals(expect1, n.getGeometryN(0), "First polygon");

Polygon expect3 = (Polygon)BboxUtils.createBoxPolygon(-180, -134.17320304524225, -76.58044236400484, 60.83962132913365);
Polygon expect3 = (Polygon)BboxUtils.createBoxPolygon(-180, -45.826796954757754, -76.58044236400484, 60.83962132913365);
assertEquals(expect3, n.getGeometryN(1), "Second polygon");
}
/**
* This test have bbox start from 10 -> 180 -> -180 -> -76.5
* East edge 314.173 wraps to -45.827, so the box runs 10 -> 180 and -180 -> -45.827.
*/
@Test
public void verifyNormalizeBbox2() {
Expand All @@ -32,7 +40,7 @@ public void verifyNormalizeBbox2() {
Polygon expect1 = (Polygon)BboxUtils.createBoxPolygon(10, 180, -76.58044236400484, 60.83962132913365);
assertEquals(expect1, n.getGeometryN(0), "First polygon");

Polygon expect2 = (Polygon)BboxUtils.createBoxPolygon(-180, -134.17320304524225, -76.58044236400484, 60.83962132913365);
Polygon expect2 = (Polygon)BboxUtils.createBoxPolygon(-180, -45.826796954757754, -76.58044236400484, 60.83962132913365);
assertEquals(expect2, n.getGeometryN(1), "Second polygon");
}
/**
Expand Down Expand Up @@ -102,4 +110,57 @@ public void verifyNormalizeBboxVerySmallMinX() {
Polygon expect1 = (Polygon)BboxUtils.createBoxPolygon(-180, 180, -76.58044236400484, 60.83962132913365);
assertEquals(expect1, n.getGeometryN(0), "First polygon min 10");
}

/**
* A map viewport of 112.03 to 188.90 continues only ~9 degrees past the date line.
*/
@Test
public void verifyNormalizeBboxViewportPastDateline() {
double minx = 112.03097102449121;
double maxx = 188.89962377189153;
double miny = -50.499567507281824;
double maxy = -4.6416246696196195;
Geometry n = BboxUtils.normalizeBbox(minx, maxx, miny, maxy);
assertEquals(2, n.getNumGeometries(), "Size correct");

Polygon eastOfAustralia = (Polygon) BboxUtils.createBoxPolygon(minx, 180, miny, maxy);
assertEquals(eastOfAustralia, n.getGeometryN(0), "First polygon");

Polygon pastDateline = (Polygon) BboxUtils.createBoxPolygon(-180, -171.10037622810847, miny, maxy);
assertEquals(pastDateline, n.getGeometryN(1), "Second polygon");
}

@Test
public void verifyNormalizeBboxWestOfGreenwichStaysOnePolygon() {
Geometry n = BboxUtils.normalizeBbox(-20, -10, -5, 5);
assertEquals(1, n.getNumGeometries(), "Size correct");
Polygon expect = (Polygon) BboxUtils.createBoxPolygon(-20, -10, -5, 5);
assertEquals(expect, n.getGeometryN(0), "West box");
}

/**
* OBIS no-land geometry crosses the date line. The centroid of the visible clip must sit in the viewport.
*/
@Test
public void verifyObisCentroidInsideViewport() throws Exception {
String json = readResourceFile("classpath:databag/097a5435-91f4-4730-90aa-ddae94afcbda.json");
@SuppressWarnings("unchecked")
Map<String, Object> record = GeometryUtils.getMapper().readValue(json, Map.class);
@SuppressWarnings("unchecked")
Map<String, Object> summaries = (Map<String, Object>) record.get("summaries");
Geometry noLand = GeometryUtils.readGeometry(summaries.get("proj:geometry_noland")).orElseThrow();

double minx = 112.03097102449121;
double maxx = 188.89962377189153;
double miny = -50.499567507281824;
double maxy = -4.6416246696196195;
Geometry visible = noLand.intersection(BboxUtils.normalizeBbox(minx, maxx, miny, maxy));
List<List<BigDecimal>> centroid = GeometryUtils.createCentroid(visible);
Assertions.assertNotNull(centroid);
assertEquals(1, centroid.size(), "One centroid");
double x = centroid.get(0).get(0).doubleValue();
double y = centroid.get(0).get(1).doubleValue();
boolean inView = y >= miny && y <= maxy && ((x >= minx && x <= 180) || (x >= -180 && x <= maxx - 360));
assertTrue(inView, "centroid " + centroid + " outside viewport");
}
}
11,168 changes: 10,796 additions & 372 deletions server/src/test/resources/databag/097a5435-91f4-4730-90aa-ddae94afcbda.json

Large diffs are not rendered by default.

Loading