diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeIndexer.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeIndexer.java index 2df89bee955ba..7346a94c5f180 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeIndexer.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeIndexer.java @@ -6,8 +6,6 @@ package org.elasticsearch.xpack.spatial.index.mapper; import org.apache.lucene.document.XYShape; -import org.apache.lucene.geo.XYLine; -import org.apache.lucene.geo.XYPolygon; import org.apache.lucene.index.IndexableField; import org.elasticsearch.geometry.Circle; import org.elasticsearch.geometry.Geometry; @@ -75,8 +73,7 @@ public Void visit(GeometryCollection collection) { @Override public Void visit(Line line) { - float[][] vertices = lineToFloatArray(line.getX(), line.getY()); - addFields(XYShape.createIndexableFields(name, new XYLine(vertices[0], vertices[1]))); + addFields(XYShape.createIndexableFields(name, ShapeUtils.toLuceneXYLine(line))); return null; } @@ -111,22 +108,19 @@ public Void visit(MultiPolygon multiPolygon) { @Override public Void visit(Point point) { - addFields(XYShape.createIndexableFields(name, (float)point.getX(), (float)point.getY())); + addFields(XYShape.createIndexableFields(name, (float) point.getX(), (float) point.getY())); return null; } @Override public Void visit(Polygon polygon) { - addFields(XYShape.createIndexableFields(name, toLucenePolygon(polygon))); + addFields(XYShape.createIndexableFields(name, ShapeUtils.toLuceneXYPolygon(polygon))); return null; } @Override public Void visit(Rectangle r) { - XYPolygon p = new XYPolygon( - new float[]{(float)r.getMinX(), (float)r.getMaxX(), (float)r.getMaxX(), (float)r.getMinX(), (float)r.getMinX()}, - new float[]{(float)r.getMinY(), (float)r.getMinY(), (float)r.getMaxY(), (float)r.getMaxY(), (float)r.getMinY()}); - addFields(XYShape.createIndexableFields(name, p)); + addFields(XYShape.createIndexableFields(name, ShapeUtils.toLuceneXYPolygon(r))); return null; } @@ -134,27 +128,4 @@ private void addFields(IndexableField[] fields) { this.fields.addAll(Arrays.asList(fields)); } } - - public static XYPolygon toLucenePolygon(Polygon polygon) { - XYPolygon[] holes = new XYPolygon[polygon.getNumberOfHoles()]; - LinearRing ring; - float[][] vertices; - for(int i = 0; i { - QueryShardContext context; - String fieldName; - ShapeRelation relation; + private Query getVectorQueryFromShape(Geometry queryShape, String fieldName, ShapeRelation relation, QueryShardContext context) { + final LuceneGeometryCollector visitor = new LuceneGeometryCollector(fieldName, context); + queryShape.visit(visitor); + final List geometries = visitor.geometries(); + if (geometries.size() == 0) { + return new MatchNoDocsQuery(); + } + return XYShape.newGeometryQuery(fieldName, relation.getLuceneRelation(), + geometries.toArray(new XYGeometry[geometries.size()])); + } + + private static class LuceneGeometryCollector implements GeometryVisitor { + private final List geometries = new ArrayList<>(); + private final String name; + private final QueryShardContext context; - ShapeVisitor(QueryShardContext context, String fieldName, ShapeRelation relation) { + private LuceneGeometryCollector(String name, QueryShardContext context) { + this.name = name; this.context = context; - this.fieldName = fieldName; - this.relation = relation; } - @Override - public Query visit(Circle circle) { - throw new QueryShardException(context, "Field [" + fieldName + "] found and unknown shape Circle"); + List geometries() { + return geometries; } @Override - public Query visit(GeometryCollection collection) { - BooleanQuery.Builder bqb = new BooleanQuery.Builder(); - visit(bqb, collection); - return bqb.build(); - } - - private void visit(BooleanQuery.Builder bqb, GeometryCollection collection) { - BooleanClause.Occur occur; - if (relation == ShapeRelation.CONTAINS || relation == ShapeRelation.DISJOINT) { - // all shapes must be disjoint / must be contained in relation to the indexed shape. - occur = BooleanClause.Occur.MUST; - } else { - // at least one shape must intersect / contain the indexed shape. - occur = BooleanClause.Occur.SHOULD; + public Void visit(Circle circle) { + if (circle.isEmpty() == false) { + geometries.add(ShapeUtils.toLuceneXYCircle(circle)); } + return null; + } + + @Override + public Void visit(GeometryCollection collection) { for (Geometry shape : collection) { - bqb.add(shape.visit(this), occur); + shape.visit(this); } + return null; } @Override - public Query visit(Line line) { - return XYShape.newLineQuery(fieldName, relation.getLuceneRelation(), - new XYLine(doubleArrayToFloatArray(line.getX()), doubleArrayToFloatArray(line.getY()))); + public Void visit(Line line) { + if (line.isEmpty() == false) { + geometries.add(ShapeUtils.toLuceneXYLine(line)); + } + return null; } @Override - public Query visit(LinearRing ring) { - throw new QueryShardException(context, "Field [" + fieldName + "] found and unsupported shape LinearRing"); + public Void visit(LinearRing ring) { + throw new QueryShardException(context, "Field [" + name + "] found and unsupported shape LinearRing"); } @Override - public Query visit(MultiLine multiLine) { - XYLine[] lines = new XYLine[multiLine.size()]; - for (int i=0; i