Skip to content

Commit 2271a3a

Browse files
committed
Implement serialization for LinearRing.
Signed-off-by: dblock <dblock@amazon.com>
1 parent d08003d commit 2271a3a

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

server/src/main/java/org/opensearch/action/search/SearchTask.java

+1-5
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,7 @@ public SearchTask(
8080

8181
@Override
8282
public final String getDescription() {
83-
try {
84-
return descriptionSupplier.get();
85-
} catch(UnsupportedOperationException e) {
86-
return e.getMessage();
87-
}
83+
return descriptionSupplier.get();
8884
}
8985

9086
@Override

server/src/main/java/org/opensearch/common/geo/GeoJson.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,13 @@ public XContentBuilder visit(Line line) throws IOException {
125125
}
126126

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

132137
@Override
@@ -254,7 +259,18 @@ public Void visit(Line line) {
254259

255260
@Override
256261
public Void visit(LinearRing ring) {
257-
throw new UnsupportedOperationException("linearRing cannot be serialized using GeoJson");
262+
List<Object> points = new ArrayList<>(ring.length());
263+
for (int i = 0; i < ring.length(); i++) {
264+
List<Object> point = new ArrayList<>();
265+
point.add(ring.getX(i));
266+
point.add(ring.getY(i));
267+
if (ring.hasZ()) {
268+
point.add(ring.getZ(i));
269+
}
270+
points.add(point);
271+
}
272+
root.put(ShapeParser.FIELD_COORDINATES.getPreferredName(), points);
273+
return null;
258274
}
259275

260276
@Override
@@ -428,6 +444,9 @@ private static Geometry createGeometry(
428444
case LINESTRING:
429445
verifyNulls(type, geometries, orientation, radius);
430446
return coordinates.asLineString(coerce);
447+
case LINEARRING:
448+
verifyNulls(type, geometries, orientation, radius);
449+
return coordinates.asLinearRing(orientation != null ? orientation : defaultOrientation, coerce);
431450
case MULTILINESTRING:
432451
verifyNulls(type, geometries, orientation, radius);
433452
return coordinates.asMultiLineString(coerce);
@@ -558,7 +577,7 @@ public String visit(Line line) {
558577

559578
@Override
560579
public String visit(LinearRing ring) {
561-
throw new UnsupportedOperationException("line ring cannot be serialized using GeoJson");
580+
return "LinearRing";
562581
}
563582

564583
@Override

server/src/test/java/org/opensearch/common/geo/GeoJsonSerializationTests.java

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import static org.opensearch.geo.GeometryTestUtils.randomCircle;
5757
import static org.opensearch.geo.GeometryTestUtils.randomGeometryCollection;
5858
import static org.opensearch.geo.GeometryTestUtils.randomLine;
59+
import static org.opensearch.geo.GeometryTestUtils.randomLinearRing;
5960
import static org.opensearch.geo.GeometryTestUtils.randomMultiLine;
6061
import static org.opensearch.geo.GeometryTestUtils.randomMultiPoint;
6162
import static org.opensearch.geo.GeometryTestUtils.randomMultiPolygon;
@@ -121,6 +122,10 @@ public void testLineString() throws IOException {
121122
xContentTest(() -> randomLine(randomBoolean()));
122123
}
123124

125+
public void testLinearRing() throws IOException {
126+
xContentTest(() -> randomLinearRing(randomBoolean()));
127+
}
128+
124129
public void testMultiLineString() throws IOException {
125130
xContentTest(() -> randomMultiLine(randomBoolean()));
126131
}

test/framework/src/main/java/org/opensearch/geo/GeometryTestUtils.java

+24
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,30 @@ public static Line randomLine(boolean hasAlts) {
102102
return new Line(lons, lats);
103103
}
104104

105+
public static LinearRing randomLinearRing(boolean hasAlts) {
106+
// we use nextPolygon because it guarantees no duplicate points
107+
org.apache.lucene.geo.Polygon lucenePolygon = GeoTestUtil.nextPolygon();
108+
int size = lucenePolygon.numPoints() - 1;
109+
double[] lats = new double[size + 1];
110+
double[] lons = new double[size + 1];
111+
double[] alts = hasAlts ? new double[size + 1] : null;
112+
for (int i = 0; i < size; i++) {
113+
lats[i] = lucenePolygon.getPolyLat(i);
114+
lons[i] = lucenePolygon.getPolyLon(i);
115+
if (hasAlts) {
116+
alts[i] = randomAlt();
117+
}
118+
}
119+
// first and last points of the linear ring must be the same
120+
lats[size] = lats[0];
121+
lons[size] = lons[0];
122+
if (hasAlts) {
123+
alts[size] = alts[0];
124+
return new LinearRing(lons, lats, alts);
125+
}
126+
return new LinearRing(lons, lats);
127+
}
128+
105129
public static Point randomPoint() {
106130
return randomPoint(OpenSearchTestCase.randomBoolean());
107131
}

0 commit comments

Comments
 (0)