Skip to content
Merged
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 @@ -35,6 +35,7 @@
import com.here.xyz.jobs.datasets.filters.Filters;
import com.here.xyz.jobs.datasets.streams.Notifications;
import com.here.xyz.models.hub.Ref;
import com.here.xyz.util.geo.GeometryValidator;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = Id.NAME, property = "type")
Expand Down Expand Up @@ -90,6 +91,11 @@ public Filters getFilters() {
@Override
public void setFilters(Filters filters) {
this.filters = filters;
if(filters != null && filters.getSpatialFilter() != null && filters.getSpatialFilter().getGeometry() != null
&& GeometryValidator.isWorldBoundingBox(filters.getSpatialFilter().getGeometry())){
//Remove spatialFilter if it is a world bounding box
this.filters = null;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,20 @@

import static com.here.xyz.models.hub.Ref.HEAD;

import com.here.xyz.XyzSerializable;
import com.here.xyz.events.PropertiesQuery;
import com.here.xyz.jobs.datasets.filters.SpatialFilter;
import com.here.xyz.jobs.steps.impl.transport.ExportSpaceToFiles;
import com.here.xyz.models.geojson.coordinates.PointCoordinates;
import com.here.xyz.models.geojson.implementation.Point;
import com.here.xyz.models.hub.Ref;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import com.here.xyz.util.geo.GeometryValidator;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand All @@ -46,7 +53,6 @@ public class ExportStepTest extends ExportTestBase {
*
*/


@BeforeEach
public void setUp() throws Exception {
putFeatureCollectionToSpace(SPACE_ID, readTestFeatureCollection("/testFeatureCollections/fcWithMixedGeometryTypes.geojson"));
Expand Down Expand Up @@ -94,4 +100,45 @@ public void exportWithSpatialAndPropertyFilter() throws Exception {
executeExportStepAndCheckResults(SPACE_ID, null, spatialFilter,
PropertiesQuery.fromString(propertiesQuery), new Ref(HEAD), hubQuery);
}

@Test
public void testWorldWideBBOX() throws IOException {
ExportSpaceToFiles step = XyzSerializable.deserialize("""
{
"type": "ExportSpaceToFiles",
"spatialFilter": {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-180.0,
-90.0
],
[
180,
-90.0
],
[
180.000,
90
],
[
-180,
90
],
[
-180,
-90
]
]
]
},
"clipped": true
}
}
""", ExportSpaceToFiles.class);

Assertions.assertTrue(GeometryValidator.isWorldBoundingBox(step.getSpatialFilter().getGeometry()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,21 @@ public BBox calculateBBox() {
}
return null;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Position other))
return false;

if (this.size() != other.size())
return false;

for (int i = 0; i < this.size(); i++) {
if (!this.get(i).equals(other.get(i))) {
return false;
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,23 @@

package com.here.xyz.util.geo;

import com.here.xyz.models.geojson.coordinates.LinearRingCoordinates;
import com.here.xyz.models.geojson.coordinates.PolygonCoordinates;
import com.here.xyz.models.geojson.coordinates.Position;
import com.here.xyz.models.geojson.implementation.Geometry;
import com.here.xyz.models.geojson.implementation.Point;
import com.here.xyz.models.geojson.implementation.Polygon;

import java.util.List;

public class GeometryValidator {
public static int MAX_NUMBER_OF_COORDNIATES = 12_000;
public static final int MAX_NUMBER_OF_COORDNIATES = 12_000;
private static final List<Position> canonical = List.of(
new Position(-180.0, -90.0),
new Position(180.0, -90.0),
new Position(180.0, 90.0),
new Position(-180.0, 90.0)
); // Define the canonical world bbox positions (counter-clockwise)

public static void validateGeometry(Geometry geometry, int radius) throws GeometryException {
if (geometry == null)
Expand All @@ -46,6 +58,45 @@ public static void validateGeometry(Geometry geometry, int radius) throws Geomet
}
}

public static boolean isWorldBoundingBox(Geometry geometry) {
if (!(geometry instanceof Polygon inputPolygon)) {
return false;
}

PolygonCoordinates inputCoords = inputPolygon.getCoordinates();

if (inputCoords == null || inputCoords.isEmpty()) {
return false;
}

LinearRingCoordinates inputLrc = inputCoords.get(0);
if (inputLrc.size() != 5) {
return false;
}

// Try all 4 valid cyclic permutations
for (int offset = 0; offset < 4; offset++) {
boolean match = true;
for (int i = 0; i <= 4; i++) {
Position expected = canonical.get((i + offset) % 4);
// Last point should always match the first to close the ring
if (i == 4) {
expected = canonical.get(offset % 4);
}
Position actual = inputLrc.get(i);
if (!expected.equals(actual)) {
match = false;
break;
}
}
if (match) {
return true;
}
}

return false;
}

public static class GeometryException extends Exception {
public GeometryException(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.here.xyz.test.util.geo;

import com.here.xyz.models.geojson.coordinates.LineStringCoordinates;
import com.here.xyz.models.geojson.coordinates.LinearRingCoordinates;
import com.here.xyz.models.geojson.coordinates.PointCoordinates;
import com.here.xyz.models.geojson.coordinates.PolygonCoordinates;
import com.here.xyz.models.geojson.coordinates.Position;
import com.here.xyz.models.geojson.exceptions.InvalidGeometryException;
import com.here.xyz.models.geojson.implementation.LineString;
import com.here.xyz.models.geojson.implementation.Point;
import com.here.xyz.models.geojson.implementation.Polygon;
import com.here.xyz.util.geo.GeometryValidator;
import com.here.xyz.util.geo.GeometryValidator.GeometryException;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -45,4 +48,56 @@ public void testInvalidGeometry() throws InvalidGeometryException {
Assertions.assertThrows(GeometryException.class, () -> GeometryValidator.validateGeometry(point, 0));
}

@Test
public void testIsWorldBoundingBox_withValidBBoxes() {
PolygonCoordinates expectedCoordinates = new PolygonCoordinates();

// Expected coordinates of a world bounding box
LinearRingCoordinates lrc = new LinearRingCoordinates();
lrc.add(new Position(-180.0, -90.0));
lrc.add(new Position(180.0, -90.0));
lrc.add(new Position(180.0, 90.0));
lrc.add(new Position(-180.0, 90.0));
lrc.add(new Position(-180.0, -90.0));

expectedCoordinates.add(lrc);
Polygon polygon = new Polygon().withCoordinates(expectedCoordinates);
Assertions.assertTrue(GeometryValidator.isWorldBoundingBox(polygon), "Should detect valid world bbox");

Comment thread
roegi marked this conversation as resolved.
//other valid permutation
lrc = new LinearRingCoordinates();
lrc.add(new Position(-180.0, 90.0));
lrc.add(new Position(-180.0, -90.0));
lrc.add(new Position(180.0, -90.0));
lrc.add(new Position(180.0, 90.0));
lrc.add(new Position(-180.0, 90.0));
expectedCoordinates.add(0, lrc);

Assertions.assertTrue(GeometryValidator.isWorldBoundingBox(polygon), "Should detect valid world bbox");
}

@Test
public void testIsWorldBoundingBox_withInvalidBBoxes() {
PolygonCoordinates expectedCoordinates = new PolygonCoordinates();
LinearRingCoordinates lrc = new LinearRingCoordinates();
//invalid WWBOX
lrc.add(new Position(-180.0, -90.0));
lrc.add(new Position(180.0, -90.0));
lrc.add(new Position(180.0, 90.0));
lrc.add(new Position(-180.0, 90.0));
lrc.add(new Position(-180.0, 90.0));
expectedCoordinates.add(lrc);
Polygon polygon = new Polygon().withCoordinates(expectedCoordinates);

Comment thread
roegi marked this conversation as resolved.
lrc = new LinearRingCoordinates();
//no WWBOX
lrc.add(new Position(8.228788827111089, 50.14263202814135));
lrc.add(new Position(8.228788827111089, 49.76343646294657));
lrc.add(new Position(8.728858987763317, 49.76343646294657));
lrc.add(new Position(8.728858987763317, 50.14263202814135));
lrc.add(new Position(8.228788827111089, 50.14263202814135));
expectedCoordinates.add(0, lrc);

Assertions.assertFalse(GeometryValidator.isWorldBoundingBox(polygon), "Should detect invalid world bbox");
}
}