Search in sources :

Example 1 with AbstractVertex

use of com.revolsys.geometry.model.vertex.AbstractVertex in project com.revolsys.open by revolsys.

the class LineString method findClosestGeometryComponent.

@Override
default Pair<GeometryComponent, Double> findClosestGeometryComponent(final double x, final double y) {
    if (isEmpty()) {
        return new Pair<>();
    } else {
        final GeometryFactory geometryFactory = getGeometryFactory();
        boolean closestIsVertex = false;
        int closestIndex = 0;
        double x1 = getX(0);
        double y1 = getY(0);
        if (x == x1 && y == y1) {
            final AbstractVertex closestVertex = getVertex(0);
            return new Pair<>(closestVertex, 0.0);
        } else {
            double closestDistance = geometryFactory.makePrecise(0, MathUtil.distance(x, y, x1, y1));
            final int vertexCount = getVertexCount();
            for (int vertexIndex = 1; vertexIndex < vertexCount; vertexIndex++) {
                final double x2 = getX(vertexIndex);
                final double y2 = getY(vertexIndex);
                if (x == x2 && y == y2) {
                    final AbstractVertex closestVertex = getVertex(vertexIndex);
                    return new Pair<>(closestVertex, 0.0);
                } else {
                    final double toDistance = geometryFactory.makePrecise(0, MathUtil.distance(x, y, x2, y2));
                    if (toDistance <= closestDistance) {
                        if (!closestIsVertex || toDistance < closestDistance) {
                            closestIndex = vertexIndex;
                            closestIsVertex = true;
                            closestDistance = toDistance;
                        }
                    }
                    final double segmentDistance = geometryFactory.makePrecise(0, LineSegmentUtil.distanceLinePoint(x1, y1, x2, y2, x, y));
                    if (segmentDistance == 0) {
                        final Segment closestSegment = getSegment(vertexIndex - 1);
                        return new Pair<>(closestSegment, 0.0);
                    } else if (segmentDistance < closestDistance) {
                        closestIsVertex = false;
                        closestIndex = vertexIndex - 1;
                        closestDistance = segmentDistance;
                    }
                }
                x1 = x2;
                y1 = y2;
            }
            if (closestIsVertex) {
                final Vertex closestVertex = getVertex(closestIndex);
                return new Pair<>(closestVertex, closestDistance);
            } else {
                final Segment closestSegment = getSegment(closestIndex);
                return new Pair<>(closestSegment, closestDistance);
            }
        }
    }
}
Also used : AbstractVertex(com.revolsys.geometry.model.vertex.AbstractVertex) Vertex(com.revolsys.geometry.model.vertex.Vertex) LineStringVertex(com.revolsys.geometry.model.vertex.LineStringVertex) AbstractVertex(com.revolsys.geometry.model.vertex.AbstractVertex) LineStringSegment(com.revolsys.geometry.model.segment.LineStringSegment) Segment(com.revolsys.geometry.model.segment.Segment) Pair(com.revolsys.util.Pair)

Aggregations

LineStringSegment (com.revolsys.geometry.model.segment.LineStringSegment)1 Segment (com.revolsys.geometry.model.segment.Segment)1 AbstractVertex (com.revolsys.geometry.model.vertex.AbstractVertex)1 LineStringVertex (com.revolsys.geometry.model.vertex.LineStringVertex)1 Vertex (com.revolsys.geometry.model.vertex.Vertex)1 Pair (com.revolsys.util.Pair)1