Skip to content

Commit

Permalink
Implement serialization for LinearRing.
Browse files Browse the repository at this point in the history
Signed-off-by: dblock <[email protected]>
  • Loading branch information
dblock committed Mar 21, 2024
1 parent d08003d commit 2271a3a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,7 @@ public SearchTask(

@Override
public final String getDescription() {
try {
return descriptionSupplier.get();
} catch(UnsupportedOperationException e) {
return e.getMessage();
}
return descriptionSupplier.get();
}

@Override
Expand Down
27 changes: 23 additions & 4 deletions server/src/main/java/org/opensearch/common/geo/GeoJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,13 @@ public XContentBuilder visit(Line line) throws IOException {
}

@Override
public XContentBuilder visit(LinearRing ring) {
throw new UnsupportedOperationException("linearRing cannot be serialized using GeoJson");
public XContentBuilder visit(LinearRing ring) throws IOException {
builder.field(ShapeParser.FIELD_COORDINATES.getPreferredName());
builder.startArray();
for (int i = 0; i < ring.length(); i++) {
coordinatesToXContent(ring.getLat(i), ring.getLon(i), ring.getAlt(i));
}
return builder.endArray();
}

@Override
Expand Down Expand Up @@ -254,7 +259,18 @@ public Void visit(Line line) {

@Override
public Void visit(LinearRing ring) {
throw new UnsupportedOperationException("linearRing cannot be serialized using GeoJson");
List<Object> points = new ArrayList<>(ring.length());
for (int i = 0; i < ring.length(); i++) {
List<Object> point = new ArrayList<>();
point.add(ring.getX(i));
point.add(ring.getY(i));
if (ring.hasZ()) {
point.add(ring.getZ(i));
}
points.add(point);
}
root.put(ShapeParser.FIELD_COORDINATES.getPreferredName(), points);
return null;
}

@Override
Expand Down Expand Up @@ -428,6 +444,9 @@ private static Geometry createGeometry(
case LINESTRING:
verifyNulls(type, geometries, orientation, radius);
return coordinates.asLineString(coerce);
case LINEARRING:
verifyNulls(type, geometries, orientation, radius);
return coordinates.asLinearRing(orientation != null ? orientation : defaultOrientation, coerce);
case MULTILINESTRING:
verifyNulls(type, geometries, orientation, radius);
return coordinates.asMultiLineString(coerce);
Expand Down Expand Up @@ -558,7 +577,7 @@ public String visit(Line line) {

@Override
public String visit(LinearRing ring) {
throw new UnsupportedOperationException("line ring cannot be serialized using GeoJson");
return "LinearRing";
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import static org.opensearch.geo.GeometryTestUtils.randomCircle;
import static org.opensearch.geo.GeometryTestUtils.randomGeometryCollection;
import static org.opensearch.geo.GeometryTestUtils.randomLine;
import static org.opensearch.geo.GeometryTestUtils.randomLinearRing;
import static org.opensearch.geo.GeometryTestUtils.randomMultiLine;
import static org.opensearch.geo.GeometryTestUtils.randomMultiPoint;
import static org.opensearch.geo.GeometryTestUtils.randomMultiPolygon;
Expand Down Expand Up @@ -121,6 +122,10 @@ public void testLineString() throws IOException {
xContentTest(() -> randomLine(randomBoolean()));
}

public void testLinearRing() throws IOException {
xContentTest(() -> randomLinearRing(randomBoolean()));
}

public void testMultiLineString() throws IOException {
xContentTest(() -> randomMultiLine(randomBoolean()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,30 @@ public static Line randomLine(boolean hasAlts) {
return new Line(lons, lats);
}

public static LinearRing randomLinearRing(boolean hasAlts) {
// we use nextPolygon because it guarantees no duplicate points
org.apache.lucene.geo.Polygon lucenePolygon = GeoTestUtil.nextPolygon();
int size = lucenePolygon.numPoints() - 1;
double[] lats = new double[size + 1];
double[] lons = new double[size + 1];
double[] alts = hasAlts ? new double[size + 1] : null;
for (int i = 0; i < size; i++) {
lats[i] = lucenePolygon.getPolyLat(i);
lons[i] = lucenePolygon.getPolyLon(i);
if (hasAlts) {
alts[i] = randomAlt();
}
}
// first and last points of the linear ring must be the same
lats[size] = lats[0];
lons[size] = lons[0];
if (hasAlts) {
alts[size] = alts[0];
return new LinearRing(lons, lats, alts);
}
return new LinearRing(lons, lats);
}

public static Point randomPoint() {
return randomPoint(OpenSearchTestCase.randomBoolean());
}
Expand Down

0 comments on commit 2271a3a

Please sign in to comment.