Search in sources :

Example 1 with Point

use of org.opensearch.geometry.Point in project OpenSearch by opensearch-project.

the class GeoPolygonDecomposer method getOrientation.

/**
 * @return whether the points are clockwise (true) or anticlockwise (false)
 */
private static boolean getOrientation(Point[] points, int offset, int length) {
    // calculate the direction of the points: find the southernmost point
    // and check its neighbors orientation.
    final int top = top(points, offset, length);
    final int prev = (top + length - 1) % length;
    final int next = (top + 1) % length;
    final int determinantSign = orient(points[offset + prev].getX(), points[offset + prev].getY(), points[offset + top].getX(), points[offset + top].getY(), points[offset + next].getX(), points[offset + next].getY());
    if (determinantSign == 0) {
        // Points are collinear, but `top` is not in the middle if so, so the edges either side of `top` are intersecting.
        throw new InvalidShapeException("Cannot determine orientation: edges adjacent to (" + points[offset + top].getX() + "," + points[offset + top].getY() + ") coincide");
    }
    return determinantSign < 0;
}
Also used : InvalidShapeException(org.locationtech.spatial4j.exception.InvalidShapeException) Point(org.opensearch.geometry.Point)

Example 2 with Point

use of org.opensearch.geometry.Point in project OpenSearch by opensearch-project.

the class GeoPolygonDecomposer method intersections.

/**
 * Calculate all intersections of line segments and a vertical line. The
 * Array of edges will be ordered asc by the y-coordinate of the
 * intersections of edges.
 *
 * @param dateline x-coordinate of the dateline
 * @param edges    set of edges that may intersect with the dateline
 * @return number of intersecting edges
 */
private static int intersections(double dateline, Edge[] edges) {
    int numIntersections = 0;
    assert !Double.isNaN(dateline);
    for (int i = 0; i < edges.length; i++) {
        Point p1 = edges[i].coordinate;
        Point p2 = edges[i].next.coordinate;
        assert !Double.isNaN(p2.getX()) && !Double.isNaN(p1.getX());
        edges[i].intersect = Edge.MAX_COORDINATE;
        double position = intersection(p1.getX(), p2.getX(), dateline);
        if (!Double.isNaN(position)) {
            edges[i].intersection(position);
            numIntersections++;
        }
    }
    Arrays.sort(edges, INTERSECTION_ORDER);
    return numIntersections;
}
Also used : Point(org.opensearch.geometry.Point) Point(org.opensearch.geometry.Point)

Example 3 with Point

use of org.opensearch.geometry.Point in project OpenSearch by opensearch-project.

the class GeoPolygonDecomposer method range.

private static double[] range(Point[] points, int offset, int length) {
    double minX = points[0].getX();
    double maxX = minX;
    double minY = points[0].getY();
    double maxY = minY;
    // compute the bounding coordinates (@todo: cleanup brute force)
    for (int i = 1; i < length; ++i) {
        Point point = points[offset + i];
        if (point.getX() < minX) {
            minX = point.getX();
        }
        if (point.getX() > maxX) {
            maxX = point.getX();
        }
        if (point.getY() < minY) {
            minY = point.getY();
        }
        if (point.getY() > maxY) {
            maxY = point.getY();
        }
    }
    return new double[] { minX, maxX, minY, maxY };
}
Also used : Point(org.opensearch.geometry.Point) Point(org.opensearch.geometry.Point)

Example 4 with Point

use of org.opensearch.geometry.Point in project OpenSearch by opensearch-project.

the class GeoPolygonDecomposer 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, Point[] 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(new Point(points[pointOffset].getX(), points[pointOffset].getY()), null);
    for (int i = 1; i < length; i++) {
        Point nextPoint = new Point(points[pointOffset + i].getX(), points[pointOffset + i].getY());
        if (direction) {
            edges[edgeOffset + i] = new Edge(nextPoint, edges[edgeOffset + i - 1]);
            edges[edgeOffset + i].component = component;
        } else if (!edges[edgeOffset + i - 1].coordinate.equals(nextPoint)) {
            edges[edgeOffset + i - 1].next = edges[edgeOffset + i] = new Edge(nextPoint, null);
            edges[edgeOffset + i - 1].component = component;
        } else {
            throw new InvalidShapeException("Provided shape has duplicate consecutive coordinates at: (" + nextPoint + ")");
        }
    }
    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) Point(org.opensearch.geometry.Point) Point(org.opensearch.geometry.Point)

Example 5 with Point

use of org.opensearch.geometry.Point in project OpenSearch by opensearch-project.

the class GeoPolygonDecomposer method validateHole.

private static void validateHole(LinearRing shell, LinearRing hole) {
    Set<Point> exterior = new HashSet<>();
    Set<Point> interior = new HashSet<>();
    for (int i = 0; i < shell.length(); i++) {
        exterior.add(new Point(shell.getX(i), shell.getY(i)));
    }
    for (int i = 0; i < hole.length(); i++) {
        interior.add(new Point(hole.getX(i), hole.getY(i)));
    }
    exterior.retainAll(interior);
    if (exterior.size() >= 2) {
        throw new IllegalArgumentException("Invalid polygon, interior cannot share more than one point with the exterior");
    }
}
Also used : Point(org.opensearch.geometry.Point) Point(org.opensearch.geometry.Point) HashSet(java.util.HashSet)

Aggregations

Point (org.opensearch.geometry.Point)34 MultiPoint (org.opensearch.geometry.MultiPoint)14 XContentBuilder (org.opensearch.common.xcontent.XContentBuilder)9 ArrayList (java.util.ArrayList)6 Geometry (org.opensearch.geometry.Geometry)5 IOException (java.io.IOException)4 InvalidShapeException (org.locationtech.spatial4j.exception.InvalidShapeException)4 XContentParser (org.opensearch.common.xcontent.XContentParser)4 Line (org.opensearch.geometry.Line)4 LinearRing (org.opensearch.geometry.LinearRing)4 Polygon (org.opensearch.geometry.Polygon)4 OpenSearchParseException (org.opensearch.OpenSearchParseException)3 GeometryCollection (org.opensearch.geometry.GeometryCollection)3 PointBuilder (org.opensearch.common.geo.builders.PointBuilder)2 MultiLine (org.opensearch.geometry.MultiLine)2 ParseException (java.text.ParseException)1 Collection (java.util.Collection)1 Collections.singletonMap (java.util.Collections.singletonMap)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1