use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.
the class LineStringGraph method splitEdge.
@Override
public <V extends Point> List<Edge<LineSegment>> splitEdge(final Edge<LineSegment> edge, final Collection<V> nodes) {
final List<Edge<LineSegment>> newEdges = new ArrayList<>();
if (!edge.isRemoved()) {
final Node<LineSegment> fromNode = edge.getFromNode();
final Node<LineSegment> toNode = edge.getToNode();
final CoordinatesDistanceComparator comparator = new CoordinatesDistanceComparator(fromNode.getX(), toNode.getY());
final Set<Point> newPoints = new TreeSet<>(comparator);
for (final Point point : nodes) {
newPoints.add(point);
}
newPoints.add(toNode);
final List<Integer> index = edge.getProperty(INDEX);
int i = 0;
Point previousPoint = fromNode;
for (final Point point : newPoints) {
final LineSegment lineSegment = new LineSegmentDoubleGF(previousPoint, point);
final Edge<LineSegment> newEdge = addEdge(lineSegment, previousPoint, point);
final List<Integer> newIndecies = new ArrayList<>(index);
newIndecies.add(i++);
newEdge.setProperty(INDEX, newIndecies);
newEdges.add(newEdge);
previousPoint = point;
}
remove(edge);
}
return newEdges;
}
use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.
the class LineSegmentUtil method getIntersection.
/**
* Get the intersection between line (segment) 1 and line (segment) 2. The
* result will be either and empty collection, a single coordinates value for
* a crosses intersection or a pair of coordinates for a linear intersection.
* The results will be rounded according to the precision model. Any z-value
* interpolation will be calculated using the z-values from line (segment) 1.
* For linear intersections the order of the points will be the same as the
* orientation of line1.
*
* @param geometryFactory
* @param line1Start
* @param line1End
* @param line2Start
* @param line2End
* @return
*/
public static LineString getIntersection(final GeometryFactory geometryFactory, Point line1Start, Point line1End, Point line2Start, Point line2End) {
line1Start = line1Start.convertGeometry(geometryFactory);
line1End = line1End.convertGeometry(geometryFactory);
line2Start = line2Start.convertGeometry(geometryFactory);
line2End = line2End.convertGeometry(geometryFactory);
if (RectangleUtil.intersects(line1Start, line1End, line2Start, line2End)) {
final Set<Point> intersections = new TreeSet<>(new CoordinatesDistanceComparator(line1Start.getX(), line1Start.getY()));
if (LineSegmentUtil.isPointOnLine(geometryFactory, line2Start, line2End, line1Start)) {
intersections.add(line1Start);
}
if (LineSegmentUtil.isPointOnLine(geometryFactory, line2Start, line2End, line1End)) {
intersections.add(line1End);
}
if (LineSegmentUtil.isPointOnLine(geometryFactory, line1Start, line1End, line2Start)) {
final Point intersection = getElevation(geometryFactory, line1Start, line1End, line2Start);
intersections.add(intersection);
}
if (LineSegmentUtil.isPointOnLine(geometryFactory, line1Start, line1End, line2End)) {
final Point intersection = getElevation(geometryFactory, line1Start, line1End, line2End);
intersections.add(intersection);
}
if (intersections.isEmpty()) {
final double line1x1 = line1Start.getX();
final double line1y1 = line1Start.getY();
final double line1x2 = line1End.getX();
final double line1y2 = line1End.getY();
final double line2x1 = line2Start.getX();
final double line2y1 = line2Start.getY();
final double line2x2 = line2End.getX();
final double line2y2 = line2End.getY();
final int Pq1 = CoordinatesListUtil.orientationIndex(line1x1, line1y1, line1x2, line1y2, line2x1, line2y1);
final int Pq2 = CoordinatesListUtil.orientationIndex(line1x1, line1y1, line1x2, line1y2, line2x2, line2y2);
if (!(Pq1 > 0 && Pq2 > 0 || Pq1 < 0 && Pq2 < 0)) {
final int Qp1 = CoordinatesListUtil.orientationIndex(line2x1, line2y1, line2x2, line2y2, line1x1, line1y1);
final int Qp2 = CoordinatesListUtil.orientationIndex(line2x1, line2y1, line2x2, line2y2, line1x2, line1y2);
if (!(Qp1 > 0 && Qp2 > 0 || Qp1 < 0 && Qp2 < 0)) {
final double detLine1StartLine1End = LineSegmentUtil.det(line1x1, line1y1, line1x2, line1y2);
final double detLine2StartLine2End = LineSegmentUtil.det(line2x1, line2y1, line2x2, line2y2);
final double x = LineSegmentUtil.det(detLine1StartLine1End, line1x1 - line1x2, detLine2StartLine2End, line2x1 - line2x2) / LineSegmentUtil.det(line1x1 - line1x2, line1y1 - line1y2, line2x1 - line2x2, line2y1 - line2y2);
final double y = LineSegmentUtil.det(detLine1StartLine1End, line1y1 - line1y2, detLine2StartLine2End, line2y1 - line2y2) / LineSegmentUtil.det(line1x1 - line1x2, line1y1 - line1y2, line2x1 - line2x2, line2y1 - line2y2);
Point intersection = geometryFactory.point(x, y);
intersection = getElevation(geometryFactory, line1Start, line1End, intersection);
final LineStringDouble points = new LineStringDouble(geometryFactory.getAxisCount(), intersection);
return points;
}
}
} else {
return geometryFactory.lineString(intersections);
}
}
return geometryFactory.lineString();
}
use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.
the class Graph method splitEdge.
public <V extends Point> List<Edge<T>> splitEdge(final Edge<T> edge, final Collection<V> splitPoints, final double maxDistance) {
final Collection<V> nodes = new ArrayList<>(splitPoints);
if (edge.isRemoved()) {
return Collections.emptyList();
} else {
final LineString line = edge.getLineString();
final LineString points = line;
final Set<Integer> splitVertices = new TreeSet<>();
final Set<Integer> splitIndexes = new TreeSet<>();
for (final Iterator<V> nodeIter = nodes.iterator(); nodeIter.hasNext(); ) {
final Point node = nodeIter.next();
final double distance = points.distanceVertex(0, node);
if (distance < maxDistance) {
nodeIter.remove();
}
}
final Map<Point, Double> nodeDistanceMap = new HashMap<>();
final Map<Point, Integer> nodeSegment = new HashMap<>();
for (int i = 1; i < points.getVertexCount() && !nodes.isEmpty(); i++) {
for (final Iterator<V> nodeIter = nodes.iterator(); nodeIter.hasNext(); ) {
final Point node = nodeIter.next();
final double nodeDistance = points.distanceVertex(i, node);
if (nodeDistance < maxDistance) {
if (i < points.getVertexCount() - 1) {
splitVertices.add(i);
splitIndexes.add(i);
}
nodeDistanceMap.remove(node);
nodeSegment.remove(node);
nodeIter.remove();
} else {
final int segmentIndex = i - 1;
final double x = node.getX();
final double y = node.getY();
final double x1 = points.getX(segmentIndex);
final double y1 = points.getY(segmentIndex);
final double x2 = points.getX(i);
final double y2 = points.getY(i);
final double segmentDistance = LineSegmentUtil.distanceLinePoint(x1, y1, x2, y2, x, y);
if (segmentDistance == 0) {
nodeDistanceMap.put(node, segmentDistance);
nodeSegment.put(node, segmentIndex);
nodeIter.remove();
} else {
final double projectionFactor = LineSegmentUtil.projectionFactor(x1, y1, x2, y2, x, y);
if (projectionFactor >= 0.0 && projectionFactor <= 1.0) {
final Double closestDistance = nodeDistanceMap.get(node);
if (closestDistance == null) {
nodeSegment.put(node, segmentIndex);
nodeDistanceMap.put(node, segmentDistance);
} else if (closestDistance.compareTo(segmentDistance) > 0) {
nodeSegment.put(node, segmentIndex);
nodeDistanceMap.put(node, segmentDistance);
}
}
}
}
}
}
final T object = edge.getObject();
final GeometryFactory geometryFactory = line.getGeometryFactory();
final Map<Integer, Set<Point>> segmentSplitNodes = new TreeMap<>();
for (final Entry<Point, Integer> entry : nodeSegment.entrySet()) {
final Point node = entry.getKey();
final Integer index = entry.getValue();
Set<Point> splitNodes = segmentSplitNodes.get(index);
if (splitNodes == null) {
final double x = points.getX(index);
final double y = points.getY(index);
splitNodes = new TreeSet<>(new CoordinatesDistanceComparator(x, y));
segmentSplitNodes.put(index, splitNodes);
splitIndexes.add(index);
}
splitNodes.add(node);
nodes.remove(node);
}
if (nodes.isEmpty()) {
final List<LineString> newLines = new ArrayList<>();
int startIndex = 0;
Point startPoint = null;
for (final Integer index : splitIndexes) {
if (splitVertices.contains(index)) {
final LineString newPoints = points.subLine(startPoint, startIndex, index - startIndex + 1, null);
newLines.add(newPoints);
startPoint = null;
startIndex = index;
}
final Set<Point> splitNodes = segmentSplitNodes.get(index);
if (splitNodes != null) {
for (final Point splitPoint : splitNodes) {
final Node<T> node = getNode(splitPoint);
final String typePath = edge.getTypeName();
Point point = splitPoint;
double splitPointZ = splitPoint.getZ();
if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
if (splitPoint instanceof Node<?>) {
final Node<?> splitNode = (Node<?>) splitPoint;
point = splitNode.get3dCoordinates(typePath);
splitPointZ = point.getZ();
}
if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
point = node.get3dCoordinates(typePath);
}
if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
final Point p1 = points.getPoint(index);
final Point p2 = points.getPoint(index + 1);
final double z = LineSegmentUtil.getElevation(p1, p2, point);
point = new PointDoubleXYZ(point.getX(), point.getY(), z);
}
}
final LineString newPoints;
if (startIndex > index) {
newPoints = new LineStringDouble(points.getAxisCount(), startPoint, point);
} else {
newPoints = points.subLine(startPoint, startIndex, index - startIndex + 1, point);
}
newLines.add(newPoints);
startPoint = point;
startIndex = index + 1;
}
}
}
final LineString newPoints = points.subLine(startPoint, startIndex, points.getVertexCount(), null);
newLines.add(newPoints);
if (newLines.size() > 1) {
final List<Edge<T>> newEdges = new ArrayList<>();
for (final LineString edgePoints : newLines) {
final Edge<T> newEdge = newEdge(geometryFactory, object, edgePoints);
newEdges.add(newEdge);
}
edge.remove();
return newEdges;
} else {
return Collections.singletonList(edge);
}
} else {
return Collections.singletonList(edge);
}
}
}
Aggregations