|
@@ -25,7 +25,11 @@ import com.vividsolutions.jts.geom.MultiLineString;
|
|
|
import com.vividsolutions.jts.geom.Point;
|
|
|
import com.vividsolutions.jts.geom.Polygon;
|
|
|
import org.apache.lucene.geo.GeoTestUtil;
|
|
|
+import org.elasticsearch.ElasticsearchException;
|
|
|
import org.elasticsearch.ElasticsearchParseException;
|
|
|
+import org.elasticsearch.Version;
|
|
|
+import org.elasticsearch.cluster.metadata.IndexMetaData;
|
|
|
+import org.elasticsearch.common.UUIDs;
|
|
|
import org.elasticsearch.common.geo.builders.CoordinatesBuilder;
|
|
|
import org.elasticsearch.common.geo.builders.EnvelopeBuilder;
|
|
|
import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder;
|
|
@@ -37,9 +41,14 @@ import org.elasticsearch.common.geo.builders.PointBuilder;
|
|
|
import org.elasticsearch.common.geo.builders.PolygonBuilder;
|
|
|
import org.elasticsearch.common.geo.builders.ShapeBuilder;
|
|
|
import org.elasticsearch.common.geo.parsers.GeoWKTParser;
|
|
|
+import org.elasticsearch.common.geo.parsers.ShapeParser;
|
|
|
+import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
|
|
import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
+import org.elasticsearch.index.mapper.ContentPath;
|
|
|
+import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
|
|
|
+import org.elasticsearch.index.mapper.Mapper;
|
|
|
import org.elasticsearch.test.geo.RandomShapeGenerator;
|
|
|
import org.locationtech.spatial4j.exception.InvalidShapeException;
|
|
|
import org.locationtech.spatial4j.shape.Rectangle;
|
|
@@ -80,7 +89,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
assertGeometryEquals(expected, xContentBuilder);
|
|
|
}
|
|
|
|
|
|
- private void assertMalformed(Shape expected, ShapeBuilder builder) throws IOException {
|
|
|
+ private void assertMalformed(ShapeBuilder builder) throws IOException {
|
|
|
XContentBuilder xContentBuilder = toWKTContent(builder, true);
|
|
|
assertValidException(xContentBuilder, ElasticsearchParseException.class);
|
|
|
}
|
|
@@ -91,7 +100,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
Coordinate c = new Coordinate(p.lon(), p.lat());
|
|
|
Point expected = GEOMETRY_FACTORY.createPoint(c);
|
|
|
assertExpected(new JtsPoint(expected, SPATIAL_CONTEXT), new PointBuilder().coordinate(c));
|
|
|
- assertMalformed(new JtsPoint(expected, SPATIAL_CONTEXT), new PointBuilder().coordinate(c));
|
|
|
+ assertMalformed(new PointBuilder().coordinate(c));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -107,7 +116,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
}
|
|
|
ShapeCollection expected = shapeCollection(shapes);
|
|
|
assertExpected(expected, new MultiPointBuilder(coordinates));
|
|
|
- assertMalformed(expected, new MultiPointBuilder(coordinates));
|
|
|
+ assertMalformed(new MultiPointBuilder(coordinates));
|
|
|
}
|
|
|
|
|
|
private List<Coordinate> randomLineStringCoords() {
|
|
@@ -142,7 +151,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
MultiLineString expected = GEOMETRY_FACTORY.createMultiLineString(
|
|
|
lineStrings.toArray(new LineString[lineStrings.size()]));
|
|
|
assertExpected(jtsGeom(expected), builder);
|
|
|
- assertMalformed(jtsGeom(expected), builder);
|
|
|
+ assertMalformed(builder);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -153,7 +162,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
LinearRing shell = GEOMETRY_FACTORY.createLinearRing(coords);
|
|
|
Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, null);
|
|
|
assertExpected(jtsGeom(expected), builder);
|
|
|
- assertMalformed(jtsGeom(expected), builder);
|
|
|
+ assertMalformed(builder);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -173,16 +182,16 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
}
|
|
|
Shape expected = shapeCollection(shapes);
|
|
|
assertExpected(expected, builder);
|
|
|
- assertMalformed(expected, builder);
|
|
|
+ assertMalformed(builder);
|
|
|
}
|
|
|
|
|
|
public void testParsePolygonWithHole() throws IOException {
|
|
|
// add 3d point to test ISSUE #10501
|
|
|
List<Coordinate> shellCoordinates = new ArrayList<>();
|
|
|
- shellCoordinates.add(new Coordinate(100, 0, 15.0));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0));
|
|
|
shellCoordinates.add(new Coordinate(101, 0));
|
|
|
shellCoordinates.add(new Coordinate(101, 1));
|
|
|
- shellCoordinates.add(new Coordinate(100, 1, 10.0));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 1));
|
|
|
shellCoordinates.add(new Coordinate(100, 0));
|
|
|
|
|
|
List<Coordinate> holeCoordinates = new ArrayList<>();
|
|
@@ -203,7 +212,110 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, holes);
|
|
|
|
|
|
assertExpected(jtsGeom(expected), polygonWithHole);
|
|
|
- assertMalformed(jtsGeom(expected), polygonWithHole);
|
|
|
+ assertMalformed(polygonWithHole);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParseMixedDimensionPolyWithHole() throws IOException {
|
|
|
+ List<Coordinate> shellCoordinates = new ArrayList<>();
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 1));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 1));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0));
|
|
|
+
|
|
|
+ // add 3d point to test ISSUE #10501
|
|
|
+ List<Coordinate> holeCoordinates = new ArrayList<>();
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.2, 15.0));
|
|
|
+ holeCoordinates.add(new Coordinate(100.8, 0.2));
|
|
|
+ holeCoordinates.add(new Coordinate(100.8, 0.8));
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.8, 10.0));
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.2));
|
|
|
+
|
|
|
+ PolygonBuilder builder = new PolygonBuilder(new CoordinatesBuilder().coordinates(shellCoordinates));
|
|
|
+ builder.hole(new LineStringBuilder(holeCoordinates));
|
|
|
+
|
|
|
+ XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().value(builder.toWKT());
|
|
|
+ XContentParser parser = createParser(xContentBuilder);
|
|
|
+ parser.nextToken();
|
|
|
+
|
|
|
+ Settings indexSettings = Settings.builder()
|
|
|
+ .put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
|
|
+ .put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()).build();
|
|
|
+
|
|
|
+ Mapper.BuilderContext mockBuilderContext = new Mapper.BuilderContext(indexSettings, new ContentPath());
|
|
|
+ final GeoShapeFieldMapper mapperBuilder = new GeoShapeFieldMapper.Builder("test").ignoreZValue(false).build(mockBuilderContext);
|
|
|
+
|
|
|
+ // test store z disabled
|
|
|
+ ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class,
|
|
|
+ () -> ShapeParser.parse(parser, mapperBuilder));
|
|
|
+ assertThat(e, hasToString(containsString("but [ignore_z_value] parameter is [false]")));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParseMixedDimensionPolyWithHoleStoredZ() throws IOException {
|
|
|
+ List<Coordinate> shellCoordinates = new ArrayList<>();
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 1));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 1));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0));
|
|
|
+
|
|
|
+ // add 3d point to test ISSUE #10501
|
|
|
+ List<Coordinate> holeCoordinates = new ArrayList<>();
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.2, 15.0));
|
|
|
+ holeCoordinates.add(new Coordinate(100.8, 0.2));
|
|
|
+ holeCoordinates.add(new Coordinate(100.8, 0.8));
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.8, 10.0));
|
|
|
+ holeCoordinates.add(new Coordinate(100.2, 0.2));
|
|
|
+
|
|
|
+ PolygonBuilder builder = new PolygonBuilder(new CoordinatesBuilder().coordinates(shellCoordinates));
|
|
|
+ builder.hole(new LineStringBuilder(holeCoordinates));
|
|
|
+
|
|
|
+ XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().value(builder.toWKT());
|
|
|
+ XContentParser parser = createParser(xContentBuilder);
|
|
|
+ parser.nextToken();
|
|
|
+
|
|
|
+ Settings indexSettings = Settings.builder()
|
|
|
+ .put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
|
|
+ .put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()).build();
|
|
|
+
|
|
|
+ Mapper.BuilderContext mockBuilderContext = new Mapper.BuilderContext(indexSettings, new ContentPath());
|
|
|
+ final GeoShapeFieldMapper mapperBuilder = new GeoShapeFieldMapper.Builder("test").ignoreZValue(true).build(mockBuilderContext);
|
|
|
+
|
|
|
+ // test store z disabled
|
|
|
+ ElasticsearchException e = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> ShapeParser.parse(parser, mapperBuilder));
|
|
|
+ assertThat(e, hasToString(containsString("unable to add coordinate to CoordinateBuilder: coordinate dimensions do not match")));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParsePolyWithStoredZ() throws IOException {
|
|
|
+ List<Coordinate> shellCoordinates = new ArrayList<>();
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 0, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(101, 1, 0));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 1, 5));
|
|
|
+ shellCoordinates.add(new Coordinate(100, 0, 5));
|
|
|
+
|
|
|
+ PolygonBuilder builder = new PolygonBuilder(new CoordinatesBuilder().coordinates(shellCoordinates));
|
|
|
+
|
|
|
+ XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().value(builder.toWKT());
|
|
|
+ XContentParser parser = createParser(xContentBuilder);
|
|
|
+ parser.nextToken();
|
|
|
+
|
|
|
+ Settings indexSettings = Settings.builder()
|
|
|
+ .put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
|
|
+ .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
|
|
+ .put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()).build();
|
|
|
+
|
|
|
+ Mapper.BuilderContext mockBuilderContext = new Mapper.BuilderContext(indexSettings, new ContentPath());
|
|
|
+ final GeoShapeFieldMapper mapperBuilder = new GeoShapeFieldMapper.Builder("test").ignoreZValue(true).build(mockBuilderContext);
|
|
|
+
|
|
|
+ ShapeBuilder shapeBuilder = ShapeParser.parse(parser, mapperBuilder);
|
|
|
+ assertEquals(shapeBuilder.numDimensions(), 3);
|
|
|
}
|
|
|
|
|
|
public void testParseSelfCrossingPolygon() throws IOException {
|
|
@@ -235,7 +347,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|
|
EnvelopeBuilder builder = new EnvelopeBuilder(new Coordinate(r.minLon, r.maxLat), new Coordinate(r.maxLon, r.minLat));
|
|
|
Rectangle expected = SPATIAL_CONTEXT.makeRectangle(r.minLon, r.maxLon, r.minLat, r.maxLat);
|
|
|
assertExpected(expected, builder);
|
|
|
- assertMalformed(expected, builder);
|
|
|
+ assertMalformed(builder);
|
|
|
}
|
|
|
|
|
|
public void testInvalidGeometryType() throws IOException {
|