Search in sources :

Example 1 with InvalidShapeException

use of org.locationtech.spatial4j.exception.InvalidShapeException in project elasticsearch by elastic.

the class RandomShapeGenerator method createShape.

private static ShapeBuilder createShape(Random r, Point nearPoint, Rectangle within, ShapeType st) throws InvalidShapeException {
    ShapeBuilder shape;
    short i = 0;
    do {
        shape = createShape(r, nearPoint, within, st, ST_VALIDATE);
        if (shape != null) {
            return shape;
        }
    } while (++i != 100);
    throw new InvalidShapeException("Unable to create a valid random shape with provided seed");
}
Also used : ShapeBuilder(org.elasticsearch.common.geo.builders.ShapeBuilder) InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException)

Example 2 with InvalidShapeException

use of org.locationtech.spatial4j.exception.InvalidShapeException in project lucene-solr by apache.

the class SpatialUtils method parseRectangle.

/**
   * Parses {@code str} in the format of '[minPoint TO maxPoint]' where {@code minPoint} is the lower left corner
   * and maxPoint is the upper-right corner of the bounding box.  Both corners may optionally be wrapped with a quote
   * and then it's parsed via {@link #parsePoint(String, org.locationtech.spatial4j.context.SpatialContext)}.
   * @param str Non-null; may *not* have leading or trailing spaces
   * @param ctx Non-null
   * @return the Rectangle
   * @throws InvalidShapeException If for any reason there was a problem parsing the string or creating the rectangle.
   */
public static Rectangle parseRectangle(String str, SpatialContext ctx) throws InvalidShapeException {
    //note we don't do generic whitespace, just a literal space char detection
    try {
        int toIdx = str.indexOf(" TO ");
        if (toIdx == -1 || str.charAt(0) != '[' || str.charAt(str.length() - 1) != ']') {
            throw new InvalidShapeException("expecting '[bottomLeft TO topRight]'");
        }
        String leftPart = unwrapQuotes(str.substring(1, toIdx).trim());
        String rightPart = unwrapQuotes(str.substring(toIdx + " TO ".length(), str.length() - 1).trim());
        return ctx.makeRectangle(parsePoint(leftPart, ctx), parsePoint(rightPart, ctx));
    } catch (InvalidShapeException e) {
        throw e;
    } catch (Exception e) {
        throw new InvalidShapeException(e.toString(), e);
    }
}
Also used : InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException) Point(org.locationtech.spatial4j.shape.Point) SolrException(org.apache.solr.common.SolrException) InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException) ParseException(java.text.ParseException)

Example 3 with InvalidShapeException

use of org.locationtech.spatial4j.exception.InvalidShapeException in project elasticsearch by elastic.

the class PolygonBuilder method concat.

/**
     * Concatenate a set of points to a polygon
     *
     * @param component
     *            component id of the polygon
     * @param direction
     *            direction of the ring
     * @param points
     *            list of points to concatenate
     * @param pointOffset
     *            index of the first point
     * @param edges
     *            Array of edges to write the result to
     * @param edgeOffset
     *            index of the first edge in the result
     * @param length
     *            number of points to use
     * @return the edges creates
     */
private static Edge[] concat(int component, boolean direction, Coordinate[] points, final int pointOffset, Edge[] edges, final int edgeOffset, int length) {
    assert edges.length >= length + edgeOffset;
    assert points.length >= length + pointOffset;
    edges[edgeOffset] = new Edge(points[pointOffset], null);
    for (int i = 1; i < length; i++) {
        if (direction) {
            edges[edgeOffset + i] = new Edge(points[pointOffset + i], edges[edgeOffset + i - 1]);
            edges[edgeOffset + i].component = component;
        } else if (!edges[edgeOffset + i - 1].coordinate.equals(points[pointOffset + i])) {
            edges[edgeOffset + i - 1].next = edges[edgeOffset + i] = new Edge(points[pointOffset + i], null);
            edges[edgeOffset + i - 1].component = component;
        } else {
            throw new InvalidShapeException("Provided shape has duplicate consecutive coordinates at: " + points[pointOffset + i]);
        }
    }
    if (direction) {
        edges[edgeOffset].setNext(edges[edgeOffset + length - 1]);
        edges[edgeOffset].component = component;
    } else {
        edges[edgeOffset + length - 1].setNext(edges[edgeOffset]);
        edges[edgeOffset + length - 1].component = component;
    }
    return edges;
}
Also used : InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException)

Example 4 with InvalidShapeException

use of org.locationtech.spatial4j.exception.InvalidShapeException in project elasticsearch by elastic.

the class GeoFilterIT method testShapeBuilders.

public void testShapeBuilders() {
    try {
        // self intersection polygon
        ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(-10, -10).coordinate(10, 10).coordinate(-10, 10).coordinate(10, -10).close()).build();
        fail("Self intersection not detected");
    } catch (InvalidShapeException e) {
    }
    // polygon with hole
    ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()).hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())).build();
    try {
        // polygon with overlapping hole
        ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()).hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 11).coordinate(5, 11).coordinate(5, -5).close())).build();
        fail("Self intersection not detected");
    } catch (InvalidShapeException e) {
    }
    try {
        // polygon with intersection holes
        ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()).hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())).hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -6).coordinate(5, -6).coordinate(5, -4).coordinate(-5, -4).close())).build();
        fail("Intersection of holes not detected");
    } catch (InvalidShapeException e) {
    }
    try {
        // Common line in polygon
        ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(-5, 10).coordinate(-5, -5).coordinate(-5, 20).coordinate(10, 20).coordinate(10, -10).close()).build();
        fail("Self intersection not detected");
    } catch (InvalidShapeException e) {
    }
    // Multipolygon: polygon with hole and polygon within the whole
    ShapeBuilders.newMultiPolygon().polygon(new PolygonBuilder(new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()).hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close()))).polygon(new PolygonBuilder(new CoordinatesBuilder().coordinate(-4, -4).coordinate(-4, 4).coordinate(4, 4).coordinate(4, -4).close())).build();
}
Also used : CoordinatesBuilder(org.elasticsearch.common.geo.builders.CoordinatesBuilder) InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException) LineStringBuilder(org.elasticsearch.common.geo.builders.LineStringBuilder) MultiPolygonBuilder(org.elasticsearch.common.geo.builders.MultiPolygonBuilder) PolygonBuilder(org.elasticsearch.common.geo.builders.PolygonBuilder)

Example 5 with InvalidShapeException

use of org.locationtech.spatial4j.exception.InvalidShapeException in project elasticsearch by elastic.

the class RandomShapeGenerator method createShape.

/**
     * Creates a random shape useful for randomized testing, NOTE: exercise caution when using this to build random GeometryCollections
     * as creating a large random number of random shapes can result in massive resource consumption
     * see: {@link GeoShapeQueryTests#testShapeFilterWithRandomGeoCollection}
     *
     * The following options are included
     * @param nearPoint Create a shape near a provided point
     * @param within Create a shape within the provided rectangle (note: if not null this will override the provided point)
     * @param st Create a random shape of the provided type
     * @return the ShapeBuilder for a random shape
     */
private static ShapeBuilder createShape(Random r, Point nearPoint, Rectangle within, ShapeType st, boolean validate) throws InvalidShapeException {
    if (st == null) {
        st = ShapeType.randomType(r);
    }
    if (within == null) {
        within = xRandomRectangle(r, nearPoint);
    }
    // inside non overlapping bounding rectangles
    switch(st) {
        case POINT:
            Point p = xRandomPointIn(r, within);
            PointBuilder pb = new PointBuilder().coordinate(new Coordinate(p.getX(), p.getY(), Double.NaN));
            return pb;
        case MULTIPOINT:
        case LINESTRING:
            // for random testing having a maximum number of 10 points for a line string is more than sufficient
            // if this number gets out of hand, the number of self intersections for a linestring can become
            // (n^2-n)/2 and computing the relation intersection matrix will become NP-Hard
            int numPoints = RandomNumbers.randomIntBetween(r, 3, 10);
            CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder();
            for (int i = 0; i < numPoints; ++i) {
                p = xRandomPointIn(r, within);
                coordinatesBuilder.coordinate(p.getX(), p.getY());
            }
            CoordinateCollection pcb = (st == ShapeType.MULTIPOINT) ? new MultiPointBuilder(coordinatesBuilder.build()) : new LineStringBuilder(coordinatesBuilder);
            return pcb;
        case MULTILINESTRING:
            MultiLineStringBuilder mlsb = new MultiLineStringBuilder();
            for (int i = 0; i < RandomNumbers.randomIntBetween(r, 1, 10); ++i) {
                mlsb.linestring((LineStringBuilder) createShape(r, nearPoint, within, ShapeType.LINESTRING, false));
            }
            return mlsb;
        case POLYGON:
            numPoints = RandomNumbers.randomIntBetween(r, 5, 25);
            Coordinate[] coordinates = new Coordinate[numPoints];
            for (int i = 0; i < numPoints; ++i) {
                p = (Point) createShape(r, nearPoint, within, ShapeType.POINT, false).build();
                coordinates[i] = new Coordinate(p.getX(), p.getY());
            }
            // random point order or random linestrings can lead to invalid self-crossing polygons,
            // compute the convex hull for a set of points to ensure polygon does not self cross
            Geometry shell = new ConvexHull(coordinates, ctx.getGeometryFactory()).getConvexHull();
            Coordinate[] shellCoords = shell.getCoordinates();
            // when all else fails, use the bounding box as the polygon
            if (shellCoords.length < 3) {
                shellCoords = new Coordinate[4];
                shellCoords[0] = new Coordinate(within.getMinX(), within.getMinY());
                shellCoords[1] = new Coordinate(within.getMinX(), within.getMaxY());
                shellCoords[2] = new Coordinate(within.getMaxX(), within.getMaxY());
                shellCoords[3] = new Coordinate(within.getMaxX(), within.getMinY());
            }
            PolygonBuilder pgb = new PolygonBuilder(new CoordinatesBuilder().coordinates(shellCoords).close());
            if (validate) {
                // The validate flag will check for these possibilities and bail if an incorrect geometry is created
                try {
                    pgb.build();
                } catch (AssertionError | InvalidShapeException e) {
                    // or InvalidShapeException
                    return null;
                }
            }
            return pgb;
        default:
            throw new ElasticsearchException("Unable to create shape of type [" + st + "]");
    }
}
Also used : InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException) ConvexHull(com.vividsolutions.jts.algorithm.ConvexHull) Point(org.locationtech.spatial4j.shape.Point) ElasticsearchException(org.elasticsearch.ElasticsearchException) MultiPointBuilder(org.elasticsearch.common.geo.builders.MultiPointBuilder) Point(org.locationtech.spatial4j.shape.Point) LineStringBuilder(org.elasticsearch.common.geo.builders.LineStringBuilder) MultiLineStringBuilder(org.elasticsearch.common.geo.builders.MultiLineStringBuilder) Geometry(com.vividsolutions.jts.geom.Geometry) CoordinatesBuilder(org.elasticsearch.common.geo.builders.CoordinatesBuilder) PointBuilder(org.elasticsearch.common.geo.builders.PointBuilder) MultiPointBuilder(org.elasticsearch.common.geo.builders.MultiPointBuilder) Coordinate(com.vividsolutions.jts.geom.Coordinate) MultiLineStringBuilder(org.elasticsearch.common.geo.builders.MultiLineStringBuilder) CoordinateCollection(org.elasticsearch.common.geo.builders.CoordinateCollection) PolygonBuilder(org.elasticsearch.common.geo.builders.PolygonBuilder)

Aggregations

InvalidShapeException (org.locationtech.spatial4j.exception.InvalidShapeException)8 Point (org.locationtech.spatial4j.shape.Point)3 ParseException (java.text.ParseException)2 SolrException (org.apache.solr.common.SolrException)2 CoordinatesBuilder (org.elasticsearch.common.geo.builders.CoordinatesBuilder)2 LineStringBuilder (org.elasticsearch.common.geo.builders.LineStringBuilder)2 PolygonBuilder (org.elasticsearch.common.geo.builders.PolygonBuilder)2 ConvexHull (com.vividsolutions.jts.algorithm.ConvexHull)1 Coordinate (com.vividsolutions.jts.geom.Coordinate)1 Geometry (com.vividsolutions.jts.geom.Geometry)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ElasticsearchException (org.elasticsearch.ElasticsearchException)1 CoordinateCollection (org.elasticsearch.common.geo.builders.CoordinateCollection)1 MultiLineStringBuilder (org.elasticsearch.common.geo.builders.MultiLineStringBuilder)1 MultiPointBuilder (org.elasticsearch.common.geo.builders.MultiPointBuilder)1 MultiPolygonBuilder (org.elasticsearch.common.geo.builders.MultiPolygonBuilder)1 PointBuilder (org.elasticsearch.common.geo.builders.PointBuilder)1 ShapeBuilder (org.elasticsearch.common.geo.builders.ShapeBuilder)1