Skip to content

Commit 833b646

Browse files
committed
add shape-type metadata to geo_shape's doc-value
This commit serializes the ShapeType of the indexed geometry. The ShapeType can be useful for other future features. For one thing: elastic#49887 depends on the ability to determine what the highest dimensional shape is for centroid calculations. GeometryCollection is reduced to the sub-shape of the higest dimension relates elastic#37206.
1 parent bd1d0c2 commit 833b646

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

libs/geo/src/main/java/org/elasticsearch/geometry/ShapeType.java

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public enum ShapeType {
3636
ENVELOPE, // not part of the actual WKB spec
3737
CIRCLE; // not part of the actual WKB spec
3838

39+
private static ShapeType[] values = values();
40+
41+
public static ShapeType forOrdinal(int ordinal) {
42+
return values[ordinal];
43+
}
3944
public static ShapeType forName(String shapeName) {
4045
return ShapeType.valueOf(shapeName.toUpperCase(Locale.ROOT));
4146
}

server/src/main/java/org/elasticsearch/common/geo/TriangleTreeReader.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.lucene.util.BytesRef;
2222
import org.elasticsearch.common.io.stream.ByteBufferStreamInput;
23+
import org.elasticsearch.geometry.ShapeType;
2324

2425
import java.io.IOException;
2526
import java.nio.ByteBuffer;
@@ -34,8 +35,8 @@
3435
* relations against the serialized triangle tree.
3536
*/
3637
public class TriangleTreeReader {
38+
private static final int SKIP_CENTROID = 8;
3739

38-
private final int extentOffset = 8;
3940
private ByteBufferStreamInput input;
4041
private final CoordinateEncoder coordinateEncoder;
4142
private final Rectangle2D rectangle2D;
@@ -58,7 +59,9 @@ public void reset(BytesRef bytesRef) throws IOException {
5859
*/
5960
public Extent getExtent() throws IOException {
6061
if (treeOffset == 0) {
61-
input.position(extentOffset);
62+
input.position(SKIP_CENTROID);
63+
input.readVInt(); // skip ShapeType
64+
6265
int top = input.readInt();
6366
int bottom = Math.toIntExact(top - input.readVLong());
6467
int posRight = input.readInt();
@@ -89,6 +92,11 @@ public double getCentroidY() throws IOException {
8992
return coordinateEncoder.decodeY(input.readInt());
9093
}
9194

95+
public ShapeType getShapeType() throws IOException {
96+
input.position(SKIP_CENTROID);
97+
return ShapeType.forOrdinal(input.readVInt());
98+
}
99+
92100
/**
93101
* Compute the relation with the provided bounding box. If the result is CELL_INSIDE_QUERY
94102
* then the bounding box is within the shape.

server/src/main/java/org/elasticsearch/common/geo/TriangleTreeWriter.java

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public TriangleTreeWriter(Geometry geometry, CoordinateEncoder coordinateEncoder
7171
public void writeTo(StreamOutput out) throws IOException {
7272
out.writeInt(coordinateEncoder.encodeX(centroidCalculator.getX()));
7373
out.writeInt(coordinateEncoder.encodeY(centroidCalculator.getY()));
74+
out.writeEnum(type);
7475
out.writeInt(extent.top);
7576
out.writeVLong((long) extent.top - extent.bottom);
7677
out.writeInt(extent.posRight);

server/src/main/java/org/elasticsearch/index/fielddata/MultiGeoValues.java

+16
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.common.io.stream.BytesStreamOutput;
3030
import org.elasticsearch.geometry.Geometry;
3131
import org.elasticsearch.geometry.Rectangle;
32+
import org.elasticsearch.geometry.ShapeType;
3233
import org.elasticsearch.geometry.utils.GeographyValidator;
3334
import org.elasticsearch.geometry.utils.WellKnownText;
3435
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
@@ -107,6 +108,11 @@ public GeoRelation relate(Rectangle rectangle) {
107108
return GeoRelation.QUERY_DISJOINT;
108109
}
109110

111+
@Override
112+
public ShapeType shapeType() {
113+
return ShapeType.POINT;
114+
}
115+
110116
@Override
111117
public double lat() {
112118
return geoPoint.lat();
@@ -157,6 +163,15 @@ public GeoRelation relate(Rectangle rectangle) {
157163
}
158164
}
159165

166+
@Override
167+
public ShapeType shapeType() {
168+
try {
169+
return reader.getShapeType();
170+
} catch (IOException e) {
171+
throw new IllegalStateException("unable to reach ShapeType", e);
172+
}
173+
}
174+
160175
@Override
161176
public double lat() {
162177
try {
@@ -202,6 +217,7 @@ public interface GeoValue {
202217
double lon();
203218
BoundingBox boundingBox();
204219
GeoRelation relate(Rectangle rectangle);
220+
ShapeType shapeType();
205221
}
206222

207223
public static class BoundingBox {

server/src/test/java/org/elasticsearch/common/geo/TriangleTreeTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.elasticsearch.common.geo;
2020

21+
import org.elasticsearch.common.io.stream.BytesStreamOutput;
2122
import org.elasticsearch.geo.GeometryTestUtils;
2223
import org.elasticsearch.geometry.Geometry;
2324
import org.elasticsearch.geometry.GeometryCollection;
@@ -46,6 +47,21 @@
4647

4748
public class TriangleTreeTests extends ESTestCase {
4849

50+
public void testShapeType() throws IOException {
51+
Geometry geometry = randomGeometryTreeGeometry();
52+
TriangleTreeWriter writer = new TriangleTreeWriter(geometry, GeoShapeCoordinateEncoder.INSTANCE);
53+
assertThat(writer.getShapeType(), equalTo(geometry.type()));
54+
55+
BytesStreamOutput output = new BytesStreamOutput();
56+
writer.writeTo(output);
57+
output.close();
58+
59+
TriangleTreeReader reader = new TriangleTreeReader(GeoShapeCoordinateEncoder.INSTANCE);
60+
reader.reset(output.bytes().toBytesRef());
61+
62+
assertThat(reader.getShapeType(), equalTo(geometry.type()));
63+
}
64+
4965
public void testRectangleShape() throws IOException {
5066
for (int i = 0; i < 1000; i++) {
5167
int minX = randomIntBetween(-80, 70);

0 commit comments

Comments
 (0)