From 608303d2f5c4f96f47c67caa8741a8e05cbea452 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 11 Mar 2021 18:01:09 -0800 Subject: [PATCH] REMOVE JTS COMMENTS --- geo/src/algorithm/relate/edge_end_builder.rs | 124 ---- geo/src/algorithm/relate/geomgraph/edge.rs | 214 ------- .../algorithm/relate/geomgraph/edge_end.rs | 112 ---- .../relate/geomgraph/edge_end_bundle.rs | 160 ----- .../relate/geomgraph/edge_end_bundle_star.rs | 336 ----------- .../relate/geomgraph/edge_intersection.rs | 66 +-- .../relate/geomgraph/geometry_graph.rs | 447 +------------- .../geomgraph/index/edge_set_intersector.rs | 13 - .../geomgraph/index/segment_intersector.rs | 179 ------ .../index/simple_edge_set_intersector.rs | 56 -- .../relate/geomgraph/intersection_matrix.rs | 561 ------------------ geo/src/algorithm/relate/geomgraph/label.rs | 184 ------ .../relate/geomgraph/line_intersector.rs | 353 ----------- geo/src/algorithm/relate/geomgraph/node.rs | 158 ----- .../algorithm/relate/geomgraph/node_map.rs | 94 --- .../relate/geomgraph/planar_graph.rs | 215 ------- .../algorithm/relate/geomgraph/quadrant.rs | 118 ---- .../geomgraph/robust_line_intersector.rs | 39 -- .../relate/geomgraph/topology_position.rs | 165 ------ geo/src/algorithm/relate/relate_operation.rs | 367 ------------ 20 files changed, 2 insertions(+), 3959 deletions(-) diff --git a/geo/src/algorithm/relate/edge_end_builder.rs b/geo/src/algorithm/relate/edge_end_builder.rs index bfa869bae3..e19ad00655 100644 --- a/geo/src/algorithm/relate/edge_end_builder.rs +++ b/geo/src/algorithm/relate/edge_end_builder.rs @@ -4,29 +4,6 @@ use crate::GeoFloat; use std::cell::RefCell; use std::rc::Rc; -// JTS: /** -// JTS: * An EdgeEndBuilder creates EdgeEnds for all the "split edges" -// JTS: * created by the -// JTS: * intersections determined for an Edge. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: import java.util.ArrayList; -// JTS: import java.util.Iterator; -// JTS: import java.util.List; -// JTS: -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geomgraph.Edge; -// JTS: import org.locationtech.jts.geomgraph.EdgeEnd; -// JTS: import org.locationtech.jts.geomgraph.EdgeIntersection; -// JTS: import org.locationtech.jts.geomgraph.EdgeIntersectionList; -// JTS: import org.locationtech.jts.geomgraph.Label; -// JTS: -// JTS: /** -// JTS: * Computes the {@link EdgeEnd}s which arise from a noded {@link Edge}. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ /// Computes the [`EdgeEnd`]s which arise from an [`Edge`] who has had it's `edge_intersections` /// populated with self and proper [`EdgeIntersection`]s. /// @@ -35,10 +12,6 @@ pub(crate) struct EdgeEndBuilder { _marker: std::marker::PhantomData, } -// JTS: public class EdgeEndBuilder { -// JTS: -// JTS: public EdgeEndBuilder() { -// JTS: } impl EdgeEndBuilder { pub fn new() -> Self { EdgeEndBuilder { @@ -46,15 +19,6 @@ impl EdgeEndBuilder { } } - // JTS: public List computeEdgeEnds(Iterator edges) - // JTS: { - // JTS: List l = new ArrayList(); - // JTS: for (Iterator i = edges; i.hasNext(); ) { - // JTS: Edge e = (Edge) i.next(); - // JTS: computeEdgeEnds(e, l); - // JTS: } - // JTS: return l; - // JTS: } pub fn compute_ends_for_edges(&self, edges: &[Rc>>]) -> Vec> { let mut list = vec![]; for edge in edges { @@ -63,28 +27,11 @@ impl EdgeEndBuilder { list } - // JTS: /** - // JTS: * Creates stub edges for all the intersections in this - // JTS: * Edge (if any) and inserts them into the graph. - // JTS: */ - // JTS: public void computeEdgeEnds(Edge edge, List l) - // JTS: { /// Creates stub edges for all the intersections in the [`Edge`] (if any) and inserts them into /// the graph's `list`. fn compute_ends_for_edge(&self, edge: &mut Edge, list: &mut Vec>) { - // JTS: EdgeIntersectionList eiList = edge.getEdgeIntersectionList(); - // JTS: //Debug.print(eiList); - // JTS: // ensure that the list has entries for the first and last point of the edge - // JTS: eiList.addEndpoints(); edge.add_edge_intersection_list_endpoints(); - // JTS: Iterator it = eiList.iterator(); - // JTS: EdgeIntersection eiPrev = null; - // JTS: EdgeIntersection eiCurr = null; - // JTS: // no intersections, so there is nothing to do - // JTS: if (! it.hasNext()) return; - // JTS: EdgeIntersection eiNext = (EdgeIntersection) it.next(); - let mut ei_iter = edge.edge_intersections().iter(); let mut ei_prev; let mut ei_curr = None; @@ -93,48 +40,21 @@ impl EdgeEndBuilder { return; } - // JTS: do { loop { - // JTS: eiPrev = eiCurr; - // JTS: eiCurr = eiNext; - // JTS: eiNext = null; - // JTS: if (it.hasNext()) eiNext = (EdgeIntersection) it.next(); ei_prev = ei_curr; ei_curr = ei_next; ei_next = ei_iter.next(); - // JTS: - // JTS: if (eiCurr != null) { - // JTS: createEdgeEndForPrev(edge, l, eiCurr, eiPrev); - // JTS: createEdgeEndForNext(edge, l, eiCurr, eiNext); - // JTS: } if let Some(ei_curr) = ei_curr { self.create_edge_end_for_prev(edge, list, ei_curr, ei_prev); self.create_edge_end_for_next(edge, list, ei_curr, ei_next); } - // JTS: } while (eiCurr != null); if ei_curr.is_none() { break; } } - // JTS: - // JTS: } } - // JTS: /** - // JTS: * Create a EdgeStub for the edge before the intersection eiCurr. - // JTS: * The previous intersection is provided - // JTS: * in case it is the endpoint for the stub edge. - // JTS: * Otherwise, the previous point from the parent edge will be the endpoint. - // JTS: *
- // JTS: * eiCurr will always be an EdgeIntersection, but eiPrev may be null. - // JTS: */ - // JTS: void createEdgeEndForPrev( - // JTS: Edge edge, - // JTS: List l, - // JTS: EdgeIntersection eiCurr, - // JTS: EdgeIntersection eiPrev) - // JTS: { /// Adds a `EdgeEnd`, if any, to `list` for the edge before the intersection ei_curr. /// /// The previous intersection is provided in case it is the endpoint for the stub edge. @@ -146,12 +66,6 @@ impl EdgeEndBuilder { ei_curr: &EdgeIntersection, ei_prev: Option<&EdgeIntersection>, ) { - // JTS: int iPrev = eiCurr.segmentIndex; - // JTS: if (eiCurr.dist == 0.0) { - // JTS: // if at the start of the edge there is no previous edge - // JTS: if (iPrev == 0) return; - // JTS: iPrev--; - // JTS: } let mut i_prev = ei_curr.segment_index(); if ei_curr.distance().is_zero() { // if at the start of the edge there is no previous edge @@ -161,11 +75,6 @@ impl EdgeEndBuilder { i_prev -= 1; } - // JTS: Coordinate pPrev = edge.getCoordinate(iPrev); - // JTS: // if prev intersection is past the previous vertex, use it instead - // JTS: if (eiPrev != null && eiPrev.segmentIndex >= iPrev) - // JTS: pPrev = eiPrev.coord; - // JTS: let mut coord_prev = edge.coords()[i_prev]; // if prev intersection is past the previous vertex, use it instead if let Some(ei_prev) = ei_prev { @@ -174,35 +83,14 @@ impl EdgeEndBuilder { } } - // JTS: Label label = new Label(edge.getLabel()); let mut label = edge.label().clone(); - // JTS: // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label - // JTS: label.flip(); // since edgeStub is oriented opposite to its parent edge, have to flip sides for edge label label.flip(); - // JTS: EdgeEnd e = new EdgeEnd(edge, eiCurr.coord, pPrev, label); - // JTS: //e.print(System.out); System.out.println(); - // JTS: l.add(e); - // JTS: } let edge_end = EdgeEnd::new(ei_curr.coordinate(), coord_prev, label); list.push(edge_end); } - // JTS: /** - // JTS: * Create a StubEdge for the edge after the intersection eiCurr. - // JTS: * The next intersection is provided - // JTS: * in case it is the endpoint for the stub edge. - // JTS: * Otherwise, the next point from the parent edge will be the endpoint. - // JTS: *
- // JTS: * eiCurr will always be an EdgeIntersection, but eiNext may be null. - // JTS: */ - // JTS: void createEdgeEndForNext( - // JTS: Edge edge, - // JTS: List l, - // JTS: EdgeIntersection eiCurr, - // JTS: EdgeIntersection eiNext) - // JTS: { /// Adds a `EdgeEnd`, if any, to `list` for the edge after the intersection ei_curr. /// /// The next intersection is provided in case it is the endpoint for the stub edge. @@ -214,22 +102,15 @@ impl EdgeEndBuilder { ei_curr: &EdgeIntersection, ei_next: Option<&EdgeIntersection>, ) { - // JTS: int iNext = eiCurr.segmentIndex + 1; let i_next = ei_curr.segment_index() + 1; - // JTS: // if there is no next edge there is nothing to do - // JTS: if (iNext >= edge.getNumPoints() && eiNext == null) return; // if there is no next edge there is nothing to do if i_next >= edge.coords().len() && ei_next.is_none() { return; } - // JTS: Coordinate pNext = edge.getCoordinate(iNext); let mut coord_next = edge.coords()[i_next]; - // JTS: // if the next intersection is in the same segment as the current, use it as the endpoint - // JTS: if (eiNext != null && eiNext.segmentIndex == eiCurr.segmentIndex) - // JTS: pNext = eiNext.coord; // if the next intersection is in the same segment as the current, use it as the endpoint if let Some(ei_next) = ei_next { if ei_next.segment_index() == ei_curr.segment_index() { @@ -237,13 +118,8 @@ impl EdgeEndBuilder { } } - // JTS: EdgeEnd e = new EdgeEnd(edge, eiCurr.coord, pNext, new Label(edge.getLabel())); - // JTS: //Debug.println(e); - // JTS: l.add(e); let label = edge.label().clone(); let edge_end = EdgeEnd::new(ei_curr.coordinate(), coord_next, label); list.push(edge_end); - // JTS: } } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/edge.rs b/geo/src/algorithm/relate/geomgraph/edge.rs index bd65222f7c..041c8f781f 100644 --- a/geo/src/algorithm/relate/geomgraph/edge.rs +++ b/geo/src/algorithm/relate/geomgraph/edge.rs @@ -22,21 +22,7 @@ pub(crate) struct Edge { label: Label, } -// JTS: /** -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class Edge -// JTS: extends GraphComponent -// JTS: { impl Edge { - // JTS: private Depth depth = new Depth(); - // JTS: private int depthDelta = 0; // the change in area depth from the R to L side of this edge - // JTS: - // JTS: public Edge(Coordinate[] pts, Label label) - // JTS: { - // JTS: this.pts = pts; - // JTS: this.label = label; - // JTS: } /// Create a new Edge. /// /// - `coords` a *non-empty* Vec of Coordinates @@ -60,17 +46,10 @@ impl Edge { &mut self.label } - // JTS: Coordinate[] pts; pub fn coords(&self) -> &[Coordinate] { &self.coords } - // JTS: private Envelope env; - // JTS: EdgeIntersectionList eiList = new EdgeIntersectionList(this); - // JTS: private String name; - // JTS: private MonotoneChainEdge mce; - - // JTS: private boolean isIsolated = true; pub fn is_isolated(&self) -> bool { self.is_isolated } @@ -78,50 +57,6 @@ impl Edge { self.is_isolated = false; } - // JTS: public Edge(Coordinate[] pts) - // JTS: { - // JTS: this(pts, null); - // JTS: } - // JTS: - // JTS: public int getNumPoints() { return pts.length; } - // JTS: public void setName(String name) { this.name = name; } - // JTS: public Coordinate[] getCoordinates() { return pts; } - // JTS: public Coordinate getCoordinate(int i) - // JTS: { - // JTS: return pts[i]; - // JTS: } - // JTS: public Coordinate getCoordinate() - // JTS: { - // JTS: if (pts.length > 0) return pts[0]; - // JTS: return null; - // JTS: } - // JTS: public Envelope getEnvelope() - // JTS: { - // JTS: // compute envelope lazily - // JTS: if (env == null) { - // JTS: env = new Envelope(); - // JTS: for (int i = 0; i < pts.length; i++) { - // JTS: env.expandToInclude(pts[i]); - // JTS: } - // JTS: } - // JTS: return env; - // JTS: } - // JTS: - // JTS: public Depth getDepth() { return depth; } - // JTS: - // JTS: /** - // JTS: * The depthDelta is the change in depth as an edge is crossed from R to L - // JTS: * @return the change in depth as the edge is crossed from R to L - // JTS: */ - // JTS: public int getDepthDelta() { return depthDelta; } - // JTS: public void setDepthDelta(int depthDelta) { this.depthDelta = depthDelta; } - // JTS: - // JTS: public int getMaximumSegmentIndex() - // JTS: { - // JTS: return pts.length - 1; - // JTS: } - - // JTS: public EdgeIntersectionList getEdgeIntersectionList() { return eiList; } pub fn edge_intersections(&self) -> &BTreeSet> { &self.edge_intersections } @@ -143,59 +78,10 @@ impl Edge { )); } - // JTS: - // JTS: public MonotoneChainEdge getMonotoneChainEdge() - // JTS: { - // JTS: if (mce == null) mce = new MonotoneChainEdge(this); - // JTS: return mce; - // JTS: } - - // JTS: public boolean isClosed() - // JTS: { - // JTS: return pts[0].equals(pts[pts.length - 1]); - // JTS: } pub fn is_closed(&self) -> bool { self.coords().first() == self.coords().last() } - // JTS: /** - // JTS: * An Edge is collapsed if it is an Area edge and it consists of - // JTS: * two segments which are equal and opposite (eg a zero-width V). - // JTS: */ - // JTS: public boolean isCollapsed() - // JTS: { - // JTS: if (! label.isArea()) return false; - // JTS: if (pts.length != 3) return false; - // JTS: if (pts[0].equals(pts[2]) ) return true; - // JTS: return false; - // JTS: } - // JTS: public Edge getCollapsedEdge() - // JTS: { - // JTS: Coordinate newPts[] = new Coordinate[2]; - // JTS: newPts[0] = pts[0]; - // JTS: newPts[1] = pts[1]; - // JTS: Edge newe = new Edge(newPts, Label.toLineLabel(label)); - // JTS: return newe; - // JTS: } - // JTS: - // JTS: public void setIsolated(boolean isIsolated) - // JTS: { - // JTS: this.isIsolated = isIsolated; - // JTS: } - // JTS: public boolean isIsolated() - // JTS: { - // JTS: return isIsolated; - // JTS: } - // JTS: /** - // JTS: * Adds EdgeIntersections for one or both - // JTS: * intersections found for a segment of an edge to the edge intersection list. - // JTS: */ - // JTS: public void addIntersections(LineIntersector li, int segmentIndex, int geomIndex) - // JTS: { - // JTS: for (int i = 0; i < li.getIntersectionNum(); i++) { - // JTS: addIntersection(li, segmentIndex, geomIndex, i); - // JTS: } - // JTS: } /// Adds EdgeIntersections for one or both intersections found for a segment of an edge to the /// edge intersection list. pub fn add_intersections( @@ -215,13 +101,6 @@ impl Edge { } } - // JTS: /** - // JTS: * Add an EdgeIntersection for intersection intIndex. - // JTS: * An intersection that falls exactly on a vertex of the edge is normalized - // JTS: * to use the higher of the two possible segmentIndexes - // JTS: */ - // JTS: public void addIntersection(LineIntersector li, int segmentIndex, int geomIndex, int intIndex) - // JTS: { /// Add an EdgeIntersection for intersection intIndex. /// An intersection that falls exactly on a vertex of the edge is normalized to use the higher /// of the two possible segmentIndexes @@ -231,68 +110,24 @@ impl Edge { line: Line, segment_index: usize, ) { - // JTS: Coordinate intPt = new Coordinate(li.getIntersection(intIndex)); - // JTS: int normalizedSegmentIndex = segmentIndex; - // JTS: double dist = li.getEdgeDistance(geomIndex, intIndex); let mut normalized_segment_index = segment_index; let mut distance = RobustLineIntersector::compute_edge_distance(intersection_coord, line); - // JTS: //Debug.println("edge intpt: " + intPt + " dist: " + dist); - // JTS: // normalize the intersection point location - // JTS: int nextSegIndex = normalizedSegmentIndex + 1; let next_segment_index = normalized_segment_index + 1; - // JTS: if (nextSegIndex < pts.length) { if next_segment_index < self.coords.len() { - // JTS: Coordinate nextPt = pts[nextSegIndex]; let next_coord = self.coords[next_segment_index]; - // JTS: //Debug.println("next pt: " + nextPt); - // JTS: - // JTS: // Normalize segment index if intPt falls on vertex - // JTS: // The check for point equality is 2D only - Z values are ignored - // JTS: if (intPt.equals2D(nextPt)) { - // JTS: //Debug.println("normalized distance"); - // JTS: normalizedSegmentIndex = nextSegIndex; - // JTS: dist = 0.0; - // JTS: } if intersection_coord == next_coord { normalized_segment_index = next_segment_index; distance = F::zero(); } - // JTS: } } - // JTS: /** - // JTS: * Add the intersection point to edge intersection list. - // JTS: */ - // JTS: EdgeIntersection ei = eiList.add(intPt, normalizedSegmentIndex, dist); - // JTS: //ei.print(System.out); self.edge_intersections.insert(EdgeIntersection::new( intersection_coord, normalized_segment_index, distance, )); } - // JTS: - // JTS: /** - // JTS: * Update the IM with the contribution for this component. - // JTS: * A component only contributes if it has a labelling for both parent geometries - // JTS: */ - // JTS: public void computeIM(IntersectionMatrix im) - // JTS: { - // JTS: updateIM(label, im); - // JTS: } - // JTS: /** - // JTS: * Updates an IM from the label for an edge. - // JTS: * Handles edges from both L and A geometries. - // JTS: */ - // JTS: public static void updateIM(Label label, IntersectionMatrix im) - // JTS: { - // JTS: im.setAtLeastIfValid(label.getLocation(0, Position.ON), label.getLocation(1, Position.ON), 1); - // JTS: if (label.isArea()) { - // JTS: im.setAtLeastIfValid(label.getLocation(0, Position.LEFT), label.getLocation(1, Position.LEFT), 2); - // JTS: im.setAtLeastIfValid(label.getLocation(0, Position.RIGHT), label.getLocation(1, Position.RIGHT), 2); - // JTS: } - // JTS: } pub fn update_intersection_matrix(label: &Label, intersection_matrix: &mut IntersectionMatrix) { intersection_matrix.set_at_least_if_valid( label.position(0, Direction::On), @@ -314,52 +149,3 @@ impl Edge { } } } - -// JTS: /** -// JTS: * @return true if the coordinate sequences of the Edges are identical -// JTS: */ -// JTS: public boolean isPointwiseEqual(Edge e) -// JTS: { -// JTS: if (pts.length != e.pts.length) return false; -// JTS: -// JTS: for (int i = 0; i < pts.length; i++) { -// JTS: if (! pts[i].equals2D(e.pts[i])) { -// JTS: return false; -// JTS: } -// JTS: } -// JTS: return true; -// JTS: } -// JTS: -// JTS: public String toString() -// JTS: { -// JTS: StringBuilder builder = new StringBuilder(); -// JTS: builder.append("edge " + name + ": "); -// JTS: builder.append("LINESTRING ("); -// JTS: for (int i = 0; i < pts.length; i++) { -// JTS: if (i > 0) builder.append(","); -// JTS: builder.append(pts[i].x + " " + pts[i].y); -// JTS: } -// JTS: builder.append(") " + label + " " + depthDelta); -// JTS: return builder.toString(); -// JTS: } -// JTS: public void print(PrintStream out) -// JTS: { -// JTS: out.print("edge " + name + ": "); -// JTS: out.print("LINESTRING ("); -// JTS: for (int i = 0; i < pts.length; i++) { -// JTS: if (i > 0) out.print(","); -// JTS: out.print(pts[i].x + " " + pts[i].y); -// JTS: } -// JTS: out.print(") " + label + " " + depthDelta); -// JTS: } -// JTS: public void printReverse(PrintStream out) -// JTS: { -// JTS: out.print("edge " + name + ": "); -// JTS: for (int i = pts.length - 1; i >= 0; i--) { -// JTS: out.print(pts[i] + " "); -// JTS: } -// JTS: out.println(""); -// JTS: } -// JTS: -// JTS: } -// JTS: diff --git a/geo/src/algorithm/relate/geomgraph/edge_end.rs b/geo/src/algorithm/relate/geomgraph/edge_end.rs index 511e54cad0..a0595d75e2 100644 --- a/geo/src/algorithm/relate/geomgraph/edge_end.rs +++ b/geo/src/algorithm/relate/geomgraph/edge_end.rs @@ -4,24 +4,6 @@ use crate::{Coordinate, GeoFloat}; use std::cell::RefCell; use std::fmt; -// JTS: import org.locationtech.jts.algorithm.BoundaryNodeRule; -// JTS: import org.locationtech.jts.algorithm.Orientation; -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.util.Assert; -// JTS: -// JTS: /** -// JTS: * Models the end of an edge incident on a node. -// JTS: * EdgeEnds have a direction -// JTS: * determined by the direction of the ray from the initial -// JTS: * point to the next point. -// JTS: * EdgeEnds are comparable under the ordering -// JTS: * "a has a greater angle with the x-axis than b". -// JTS: * This ordering is used to sort EdgeEnds around a node. -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class EdgeEnd -// JTS: implements Comparable - /// Models the end of an edge incident on a node. /// /// EdgeEnds have a direction determined by the direction of the ray from the initial @@ -69,28 +51,6 @@ impl EdgeEnd where F: GeoFloat, { - // JTS: { - // JTS: protected Edge edge; // the parent edge of this edge end - // JTS: protected Label label; - // JTS: - // JTS: private Node node; // the node this edge end originates at - // JTS: private Coordinate p0, p1; // points of initial line segment - // JTS: private double dx, dy; // the direction vector for this edge from its starting point - // JTS: private int quadrant; - // JTS: - // JTS: protected EdgeEnd(Edge edge) - // JTS: { - // JTS: this.edge = edge; - // JTS: } - // JTS: public EdgeEnd(Edge edge, Coordinate p0, Coordinate p1) { - // JTS: this(edge, p0, p1, null); - // JTS: } - - // JTS: public EdgeEnd(Edge edge, Coordinate p0, Coordinate p1, Label label) { - // JTS: this(edge); - // JTS: init(p0, p1); - // JTS: this.label = label; - // JTS: } pub fn new(coord_0: Coordinate, coord_1: Coordinate, label: Label) -> EdgeEnd { let delta = coord_1 - coord_0; let quadrant = Quadrant::new(delta.x, delta.y); @@ -105,18 +65,6 @@ where } } - // JTS: protected void init(Coordinate p0, Coordinate p1) - // JTS: { - // JTS: this.p0 = p0; - // JTS: this.p1 = p1; - // JTS: dx = p1.x - p0.x; - // JTS: dy = p1.y - p0.y; - // JTS: quadrant = Quadrant.quadrant(dx, dy); - // JTS: Assert.isTrue(! (dx == 0 && dy == 0), "EdgeEnd with identical endpoints found"); - // JTS: } - // JTS: - // JTS: public Edge getEdge() { return edge; } - // JTS: public Label getLabel() { return label; } pub fn label(&self) -> &Label { &self.label } @@ -125,7 +73,6 @@ where &mut self.label } - // JTS: public Coordinate getCoordinate() { return p0; } pub fn coordinate(&self) -> &Coordinate { &self.key.coord_0 } @@ -133,14 +80,6 @@ where pub fn key(&self) -> &EdgeEndKey { &self.key } - - // JTS: public Coordinate getDirectedCoordinate() { return p1; } - // JTS: public int getQuadrant() { return quadrant; } - // JTS: public double getDx() { return dx; } - // JTS: public double getDy() { return dy; } - // JTS: - // JTS: public void setNode(Node node) { this.node = node; } - // JTS: public Node getNode() { return node; } } impl std::cmp::Eq for EdgeEndKey where F: GeoFloat {} @@ -167,11 +106,6 @@ impl std::cmp::Ord for EdgeEndKey where F: GeoFloat, { - // JTS: public int compareTo(Object obj) - // JTS: { - // JTS: EdgeEnd e = (EdgeEnd) obj; - // JTS: return compareDirection(e); - // JTS: } fn cmp(&self, other: &EdgeEndKey) -> std::cmp::Ordering { self.compare_direction(other) } @@ -181,30 +115,6 @@ impl EdgeEndKey where F: GeoFloat, { - // JTS: /** - // JTS: * Implements the total order relation: - // JTS: *

- // JTS: * a has a greater angle with the positive x-axis than b - // JTS: *

- // JTS: * Using the obvious algorithm of simply computing the angle is not robust, - // JTS: * since the angle calculation is obviously susceptible to roundoff. - // JTS: * A robust algorithm is: - // JTS: * - first compare the quadrant. If the quadrants - // JTS: * are different, it it trivial to determine which vector is "greater". - // JTS: * - if the vectors lie in the same quadrant, the computeOrientation function - // JTS: * can be used to decide the relative orientation of the vectors. - // JTS: */ - // JTS: public int compareDirection(EdgeEnd e) - // JTS: { - // JTS: if (dx == e.dx && dy == e.dy) - // JTS: return 0; - // JTS: // if the rays are in different quadrants, determining the ordering is trivial - // JTS: if (quadrant > e.quadrant) return 1; - // JTS: if (quadrant < e.quadrant) return -1; - // JTS: // vectors are in the same quadrant - check relative orientation of direction vectors - // JTS: // this is > e if it is CCW of e - // JTS: return Orientation.index(e.p0, e.p1, p1); - // JTS: } pub(crate) fn compare_direction(&self, other: &EdgeEndKey) -> std::cmp::Ordering { use std::cmp::Ordering; if self.delta == other.delta { @@ -224,28 +134,6 @@ where } } } - - // JTS: public void computeLabel(BoundaryNodeRule boundaryNodeRule) - // JTS: { - // JTS: // subclasses should override this if they are using labels - // JTS: } - // JTS: public void print(PrintStream out) - // JTS: { - // JTS: double angle = Math.atan2(dy, dx); - // JTS: String className = getClass().getName(); - // JTS: int lastDotPos = className.lastIndexOf('.'); - // JTS: String name = className.substring(lastDotPos + 1); - // JTS: out.print(" " + name + ": " + p0 + " - " + p1 + " " + quadrant + ":" + angle + " " + label); - // JTS: } - // JTS: public String toString() - // JTS: { - // JTS: double angle = Math.atan2(dy, dx); - // JTS: String className = getClass().getName(); - // JTS: int lastDotPos = className.lastIndexOf('.'); - // JTS: String name = className.substring(lastDotPos + 1); - // JTS: return " " + name + ": " + p0 + " - " + p1 + " " + quadrant + ":" + angle + " " + label; - // JTS: } - // JTS: } } #[cfg(test)] diff --git a/geo/src/algorithm/relate/geomgraph/edge_end_bundle.rs b/geo/src/algorithm/relate/geomgraph/edge_end_bundle.rs index cf1bf2fd02..4b8bcfa67a 100644 --- a/geo/src/algorithm/relate/geomgraph/edge_end_bundle.rs +++ b/geo/src/algorithm/relate/geomgraph/edge_end_bundle.rs @@ -1,23 +1,6 @@ use super::{CoordPos, Direction, Edge, EdgeEnd, GeometryGraph, IntersectionMatrix, Label}; use crate::{Coordinate, GeoFloat}; -// JTS: import org.locationtech.jts.algorithm.BoundaryNodeRule; -// JTS: import org.locationtech.jts.geom.IntersectionMatrix; -// JTS: import org.locationtech.jts.geom.Location; -// JTS: import org.locationtech.jts.geomgraph.Edge; -// JTS: import org.locationtech.jts.geomgraph.EdgeEnd; -// JTS: import org.locationtech.jts.geomgraph.GeometryGraph; -// JTS: import org.locationtech.jts.geomgraph.Label; -// JTS: import org.locationtech.jts.geomgraph.Position; -// JTS: -// JTS: /** -// JTS: * A collection of {@link EdgeEnd}s which obey the following invariant: -// JTS: * They originate at the same node and have the same direction. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class EdgeEndBundle -// JTS: extends EdgeEnd /// A collection of [`EdgeEnds`](EdgeEnd) which obey the following invariant: /// They originate at the same node and have the same direction. /// @@ -35,26 +18,6 @@ impl EdgeEndBundle where F: GeoFloat, { - // JTS: { - // JTS: // private BoundaryNodeRule boundaryNodeRule; - // JTS: private List edgeEnds = new ArrayList(); - // JTS: - // JTS: public EdgeEndBundle(BoundaryNodeRule boundaryNodeRule, EdgeEnd e) - // JTS: { - // JTS: super(e.getEdge(), e.getCoordinate(), e.getDirectedCoordinate(), new Label(e.getLabel())); - // JTS: insert(e); - // JTS: /* - // JTS: if (boundaryNodeRule != null) - // JTS: this.boundaryNodeRule = boundaryNodeRule; - // JTS: else - // JTS: boundaryNodeRule = BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE; - // JTS: */ - // JTS: } - // JTS: - // JTS: public EdgeEndBundle(EdgeEnd e) - // JTS: { - // JTS: this(null, e); - // JTS: } pub(crate) fn new(coordinate: Coordinate) -> Self { Self { coordinate, @@ -62,10 +25,6 @@ where } } - // JTS: public Label getLabel() { return label; } - - // JTS: public Iterator iterator() { return edgeEnds.iterator(); } - // JTS: public List getEdgeEnds() { return edgeEnds; } fn edge_ends_iter(&self) -> impl Iterator> { self.edge_ends.iter() } @@ -74,53 +33,21 @@ where self.edge_ends.iter_mut() } - // JTS: - // JTS: public void insert(EdgeEnd e) - // JTS: { - // JTS: // Assert: start point is the same - // JTS: // Assert: direction is the same - // JTS: edgeEnds.add(e); - // JTS: } pub(crate) fn insert(&mut self, edge_end: EdgeEnd) { self.edge_ends.push(edge_end); } - // JTS: /** - // JTS: * This computes the overall edge label for the set of - // JTS: * edges in this EdgeStubBundle. It essentially merges - // JTS: * the ON and side labels for each edge. These labels must be compatible - // JTS: */ - // JTS: public void computeLabel(BoundaryNodeRule boundaryNodeRule) - // JTS: { pub(crate) fn into_labeled(mut self) -> LabeledEdgeEndBundle { - // JTS: // create the label. If any of the edges belong to areas, - // JTS: // the label must be an area label - // JTS: boolean isArea = false; - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: if (e.getLabel().isArea()) isArea = true; - // JTS: } let is_area = self .edge_ends_iter() .any(|edge_end| edge_end.label().is_area()); - // JTS: if (isArea) - // JTS: label = new Label(Location.NONE, Location.NONE, Location.NONE); - // JTS: else - // JTS: label = new Label(Location.NONE); let mut label = if is_area { Label::empty_area() } else { Label::empty_line_or_point() }; - // JTS: // compute the On label, and the side labels if present - // JTS: for (int i = 0; i < 2; i++) { - // JTS: computeLabelOn(i, boundaryNodeRule); - // JTS: if (isArea) - // JTS: computeLabelSides(i); - // JTS: } - // JTS: } for i in 0..2 { self.compute_label_on(&mut label, i); if is_area { @@ -135,28 +62,6 @@ where } } - // JTS: /** - // JTS: * Compute the overall ON location for the list of EdgeStubs. - // JTS: * (This is essentially equivalent to computing the self-overlay of a single Geometry) - // JTS: * edgeStubs can be either on the boundary (e.g. Polygon edge) - // JTS: * OR in the interior (e.g. segment of a LineString) - // JTS: * of their parent Geometry. - // JTS: * In addition, GeometryCollections use a {@link BoundaryNodeRule} to determine - // JTS: * whether a segment is on the boundary or not. - // JTS: * Finally, in GeometryCollections it can occur that an edge is both - // JTS: * on the boundary and in the interior (e.g. a LineString segment lying on - // JTS: * top of a Polygon edge.) In this case the Boundary is given precedence. - // JTS: *
- // JTS: * These observations result in the following rules for computing the ON location: - // JTS: *

    - // JTS: *
  • if there are an odd number of Bdy edges, the attribute is Bdy - // JTS: *
  • if there are an even number >= 2 of Bdy edges, the attribute is Int - // JTS: *
  • if there are any Int edges, the attribute is Int - // JTS: *
  • otherwise, the attribute is NULL. - // JTS: *
- // JTS: */ - // JTS: private void computeLabelOn(int geomIndex, BoundaryNodeRule boundaryNodeRule) - // JTS: { /// Compute the overall ON position for the list of EdgeEnds. /// (This is essentially equivalent to computing the self-overlay of a single Geometry) /// @@ -178,18 +83,9 @@ where /// - otherwise, the attribute is None /// fn compute_label_on(&mut self, label: &mut Label, geom_index: usize) { - // JTS: // compute the ON location value - // JTS: int boundaryCount = 0; - // JTS: boolean foundInterior = false; let mut boundary_count = 0; let mut found_interior = false; - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: int loc = e.getLabel().getLocation(geomIndex); - // JTS: if (loc == Location.BOUNDARY) boundaryCount++; - // JTS: if (loc == Location.INTERIOR) foundInterior = true; - // JTS: } for edge_end in self.edge_ends_iter() { match edge_end.label().on_position(geom_index) { Some(CoordPos::OnBoundary) => { @@ -202,11 +98,6 @@ where } } - // JTS: int loc = Location.NONE; - // JTS: if (foundInterior) loc = Location.INTERIOR; - // JTS: if (boundaryCount > 0) { - // JTS: loc = GeometryGraph.determineBoundary(boundaryNodeRule, boundaryCount); - // JTS: } let mut position = None; if found_interior { position = Some(CoordPos::Inside); @@ -216,9 +107,6 @@ where position = Some(GeometryGraph::<'_, F>::determine_boundary(boundary_count)); } - // JTS: label.setLocation(geomIndex, loc); - // JTS: - // JTS: } if let Some(location) = position { label.set_on_position(geom_index, location); } else { @@ -234,22 +122,6 @@ where } } - // JTS: /** - // JTS: * To compute the summary label for a side, the algorithm is: - // JTS: * FOR all edges - // JTS: * IF any edge's location is INTERIOR for the side, side location = INTERIOR - // JTS: * ELSE IF there is at least one EXTERIOR attribute, side location = EXTERIOR - // JTS: * ELSE side location = NULL - // JTS: *
- // JTS: * Note that it is possible for two sides to have apparently contradictory information - // JTS: * i.e. one edge side may indicate that it is in the interior of a geometry, while - // JTS: * another edge side may indicate the exterior of the same geometry. This is - // JTS: * not an incompatibility - GeometryCollections may contain two Polygons that touch - // JTS: * along an edge. This is the reason for Interior-primacy rule above - it - // JTS: * results in the summary label having the Geometry interior on both sides. - // JTS: */ - // JTS: private void computeLabelSide(int geomIndex, int side) - // JTS: { /// To compute the summary label for a side, the algorithm is: /// FOR all edges /// IF any edge's location is INTERIOR for the side, side location = INTERIOR @@ -263,20 +135,8 @@ where /// results in the summary label having the Geometry interior on _both_ sides. fn compute_label_side(&mut self, label: &mut Label, geom_index: usize, side: Direction) { let mut position = None; - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); for edge_end in self.edge_ends_iter_mut() { - // JTS: if (e.getLabel().isArea()) { if edge_end.label().is_area() { - // JTS: int loc = e.getLabel().getLocation(geomIndex, side); - // JTS: if (loc == Location.INTERIOR) { - // JTS: label.setLocation(geomIndex, side, Location.INTERIOR); - // JTS: return; - // JTS: } - // JTS: else if (loc == Location.EXTERIOR) - // JTS: label.setLocation(geomIndex, side, Location.EXTERIOR); - // JTS: } - // JTS: } match edge_end.label_mut().position(geom_index, side) { Some(CoordPos::Inside) => { position = Some(CoordPos::Inside); @@ -292,28 +152,8 @@ where if let Some(position) = position { label.set_position(geom_index, side, position); - // JTS: } } } - - // JTS: /** - // JTS: * Update the IM with the contribution for the computed label for the EdgeStubs. - // JTS: */ - // JTS: void updateIM(IntersectionMatrix im) - // JTS: { - // JTS: Edge.updateIM(label, im); - // JTS: } - - // JTS: public void print(PrintStream out) - // JTS: { - // JTS: out.println("EdgeEndBundle--> Label: " + label); - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd ee = (EdgeEnd) it.next(); - // JTS: ee.print(out); - // JTS: out.println(); - // JTS: } - // JTS: } - // JTS: } } /// An [`EdgeEndBundle`] whose topological relationships have been aggregated into a single diff --git a/geo/src/algorithm/relate/geomgraph/edge_end_bundle_star.rs b/geo/src/algorithm/relate/geomgraph/edge_end_bundle_star.rs index d0b2b3964c..fff740d17c 100644 --- a/geo/src/algorithm/relate/geomgraph/edge_end_bundle_star.rs +++ b/geo/src/algorithm/relate/geomgraph/edge_end_bundle_star.rs @@ -5,22 +5,6 @@ use super::{ use crate::algorithm::coordinate_position::{CoordPos, CoordinatePosition}; use crate::{Coordinate, GeoFloat, GeometryCow}; -// JTS: /** -// JTS: * An ordered list of {@link EdgeEndBundle}s around a {@link RelateNode}. -// JTS: * They are maintained in CCW order (starting with the positive x-axis) around the node -// JTS: * for efficient lookup and topology building. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class EdgeEndBundleStar -// JTS: extends EdgeEndStar -// JTS: { -// JTS: /** -// JTS: * Creates a new empty EdgeEndBundleStar -// JTS: */ -// JTS: public EdgeEndBundleStar() { -// JTS: } -// JTS: /// An ordered list of [`EdgeEndBundle`]s around a [`RelateNodeFactory::Node`]. /// /// They are maintained in CCW order (starting with the positive x-axis) around the node @@ -57,56 +41,8 @@ impl LabeledEdgeEndBundleStar { /// Compute a label for the star based on the labels of its EdgeEndBundles. fn compute_labeling(&mut self, graph_a: &GeometryGraph, graph_b: &GeometryGraph) { - // JTS: // Propagate side labels around the edges in the star - // JTS: // for each parent Geometry - // JTS: //Debug.print(this); - // JTS: propagateSideLabels(0); - // JTS: //Debug.print(this); - // JTS: //Debug.printIfWatch(this); - // JTS: propagateSideLabels(1); - // JTS: //Debug.print(this); - // JTS: //Debug.printIfWatch(this); self.propagate_side_labels(0); self.propagate_side_labels(1); - // JTS: - // JTS: /** - // JTS: * If there are edges that still have null labels for a geometry - // JTS: * this must be because there are no area edges for that geometry incident on this node. - // JTS: * In this case, to label the edge for that geometry we must test whether the - // JTS: * edge is in the interior of the geometry. - // JTS: * To do this it suffices to determine whether the node for the edge is in the interior of an area. - // JTS: * If so, the edge has location INTERIOR for the geometry. - // JTS: * In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge - // JTS: * has the location EXTERIOR for the geometry. - // JTS: *

- // JTS: * Note that the edge cannot be on the BOUNDARY of the geometry, since then - // JTS: * there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY - // JTS: * and this edge would have been labelled in the previous step. - // JTS: *

- // JTS: * This code causes a problem when dimensional collapses are present, since it may try and - // JTS: * determine the location of a node where a dimensional collapse has occurred. - // JTS: * The point should be considered to be on the EXTERIOR - // JTS: * of the polygon, but locate() will return INTERIOR, since it is passed - // JTS: * the original Geometry, not the collapsed version. - // JTS: * - // JTS: * If there are incident edges which are Line edges labelled BOUNDARY, - // JTS: * then they must be edges resulting from dimensional collapses. - // JTS: * In this case the other edges can be labelled EXTERIOR for this Geometry. - // JTS: * - // JTS: * MD 8/11/01 - NOT TRUE! The collapsed edges may in fact be in the interior of the Geometry, - // JTS: * which means the other edges should be labelled INTERIOR for this Geometry. - // JTS: * Not sure how solve this... Possibly labelling needs to be split into several phases: - // JTS: * area label propagation, symLabel merging, then finally null label resolution. - // JTS: */ - // JTS: boolean[] hasDimensionalCollapseEdge = { false, false }; - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: Label label = e.getLabel(); - // JTS: for (int geomi = 0; geomi < 2; geomi++) { - // JTS: if (label.isLine(geomi) && label.getLocation(geomi) == Location.BOUNDARY) - // JTS: hasDimensionalCollapseEdge[geomi] = true; - // JTS: } - // JTS: } let mut has_dimensional_collapse_edge = [false, false]; for edge_end in self.edges.iter() { let label = edge_end.label(); @@ -115,29 +51,12 @@ impl LabeledEdgeEndBundleStar { && label.on_position(geom_index) == Some(CoordPos::OnBoundary); } } - // JTS: //Debug.print(this); - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: Label label = e.getLabel(); - // JTS: //Debug.println(e); - // JTS: for (int geomi = 1; geomi < 2; geomi++) { for edge_end_bundle in &mut self.edges { let coord = *edge_end_bundle.coordinate(); let label = edge_end_bundle.label_mut(); for (geom_index, is_dimensionally_collapsed) in has_dimensional_collapse_edge.iter().enumerate() { - // JTS: if (label.isAnyNull(geomi)) { - // JTS: int loc = Location.NONE; - // JTS: if (hasDimensionalCollapseEdge[geomi]) { - // JTS: loc = Location.EXTERIOR; - // JTS: } - // JTS: else { - // JTS: Coordinate p = e.getCoordinate(); - // JTS: loc = getLocation(geomi, p, geomGraph); - // JTS: } - // JTS: label.setAllLocationsIfNull(geomi, loc); - // JTS: } if label.is_any_empty(geom_index) { let position: CoordPos = if *is_dimensionally_collapsed { CoordPos::Outside @@ -164,22 +83,9 @@ impl LabeledEdgeEndBundleStar { debug!("edge_end_bundle_star: {:?}", self); } - // JTS: void propagateSideLabels(int geomIndex) - // JTS: { fn propagate_side_labels(&mut self, geom_index: usize) { - // JTS: // Since edges are stored in CCW order around the node, - // JTS: // As we move around the ring we move from the right to the left side of the edge - // JTS: int startLoc = Location.NONE ; let mut start_position = None; - // JTS: // initialize loc to location of last L side (if any) - // JTS: //System.out.println("finding start location"); - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: Label label = e.getLabel(); - // JTS: if (label.isArea(geomIndex) && label.getLocation(geomIndex, Position.LEFT) != Location.NONE) - // JTS: startLoc = label.getLocation(geomIndex, Position.LEFT); - // JTS: } for edge_ends in self.edge_end_bundles_iter() { let label = edge_ends.label(); if label.is_geom_area(geom_index) { @@ -188,62 +94,25 @@ impl LabeledEdgeEndBundleStar { } } } - // JTS: // no labelled sides found, so no labels to propagate - // JTS: if (startLoc == Location.NONE) return; if start_position.is_none() { return; } let mut current_position = start_position.unwrap(); - // JTS: int currLoc = startLoc; - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { for edge_ends in self.edge_end_bundles_iter_mut() { - // JTS: EdgeEnd e = (EdgeEnd) it.next(); - // JTS: Label label = e.getLabel(); let label = edge_ends.label_mut(); - // JTS: // set null ON values to be in current location - // JTS: if (label.getLocation(geomIndex, Position.ON) == Location.NONE) - // JTS: label.setLocation(geomIndex, Position.ON, currLoc); if label.position(geom_index, Direction::On).is_none() { label.set_position(geom_index, Direction::On, current_position); } - // JTS: // set side labels (if any) - // JTS: if (label.isArea(geomIndex)) { if label.is_geom_area(geom_index) { - // JTS: int leftLoc = label.getLocation(geomIndex, Position.LEFT); - // JTS: int rightLoc = label.getLocation(geomIndex, Position.RIGHT); let left_position = label.position(geom_index, Direction::Left); let right_position = label.position(geom_index, Direction::Right); - // JTS: // if there is a right location, that is the next location to propagate - // JTS: if (rightLoc != Location.NONE) { - // JTS: //Debug.print(rightLoc != currLoc, this); - // JTS: if (rightLoc != currLoc) - // JTS: throw new TopologyException("side location conflict", e.getCoordinate()); - // JTS: if (leftLoc == Location.NONE) { - // JTS: Assert.shouldNeverReachHere("found single null side (at " + e.getCoordinate() + ")"); - // JTS: } - // JTS: currLoc = leftLoc; if let Some(right_position) = right_position { debug_assert!(right_position == current_position, "side_location conflict with coordinate: {:?}, right_location: {:?}, current_location: {:?}", edge_ends.coordinate(), right_position, current_position); assert!(left_position.is_some(), "found single null side"); current_position = left_position.unwrap(); } else { - // JTS: } - // JTS: else { - // JTS: /** RHS is null - LHS must be null too. - // JTS: * This must be an edge from the other geometry, which has no location - // JTS: * labelling for this geometry. This edge must lie wholly inside or outside - // JTS: * the other geometry (which is determined by the current location). - // JTS: * Assign both sides to be the current location. - // JTS: */ - // JTS: Assert.isTrue(label.getLocation(geomIndex, Position.LEFT) == Location.NONE, "found single null side"); - // JTS: label.setLocation(geomIndex, Position.RIGHT, currLoc); - // JTS: label.setLocation(geomIndex, Position.LEFT, currLoc); - // JTS: } - // JTS: } - // JTS: } - // JTS: } debug_assert!(label.position(geom_index, Direction::Left).is_none()); label.set_position(geom_index, Direction::Right, current_position); label.set_position(geom_index, Direction::Left, current_position); @@ -260,16 +129,6 @@ impl LabeledEdgeEndBundleStar { self.edges.iter_mut() } - // JTS: /** - // JTS: * Update the IM with the contribution for the EdgeStubs around the node. - // JTS: */ - // JTS: void updateIM(IntersectionMatrix im) - // JTS: { - // JTS: for (Iterator it = iterator(); it.hasNext(); ) { - // JTS: EdgeEndBundle esb = (EdgeEndBundle) it.next(); - // JTS: esb.updateIM(im); - // JTS: } - // JTS: } pub fn update_intersection_matrix(&self, intersection_matrix: &mut IntersectionMatrix) { for edge_end_bundle in self.edge_end_bundles_iter() { edge_end_bundle.update_intersection_matrix(intersection_matrix); @@ -292,24 +151,6 @@ where } } - // JTS: /** - // JTS: * Insert a EdgeEnd in order in the list. - // JTS: * If there is an existing EdgeStubBundle which is parallel, the EdgeEnd is - // JTS: * added to the bundle. Otherwise, a new EdgeEndBundle is created - // JTS: * to contain the EdgeEnd. - // JTS: *
- // JTS: */ - // JTS: public void insert(EdgeEnd e) - // JTS: { - // JTS: EdgeEndBundle eb = (EdgeEndBundle) edgeMap.get(e); - // JTS: if (eb == null) { - // JTS: eb = new EdgeEndBundle(e); - // JTS: insertEdgeEnd(e, eb); - // JTS: } - // JTS: else { - // JTS: eb.insert(e); - // JTS: } - // JTS: } pub(crate) fn insert(&mut self, edge_end: EdgeEnd) { let bundle = self .edge_map @@ -349,7 +190,6 @@ where graph_b: &GeometryGraph, ) -> LabeledEdgeEndBundleStar { debug!("edge_end_bundle_star: {:?}", self); - // JTS: computeEdgeEndLabels(geomGraph[0].getBoundaryNodeRule()); let labeled_edges = self .edge_map .into_iter() @@ -358,179 +198,3 @@ where LabeledEdgeEndBundleStar::new(labeled_edges, graph_a, graph_b) } } - -// JTS: -// JTS: /** -// JTS: * A map which maintains the edges in sorted order around the node -// JTS: */ -// JTS: protected Map edgeMap = new TreeMap(); -// JTS: /** -// JTS: * A list of all outgoing edges in the result, in CCW order -// JTS: */ -// JTS: protected List edgeList; -// JTS: /** -// JTS: * The location of the point for this star in Geometry i Areas -// JTS: */ -// JTS: private int[] ptInAreaLocation = { Location.NONE, Location.NONE }; -// JTS: -// JTS: public EdgeEndStar() -// JTS: { -// JTS: -// JTS: } -// JTS: -// JTS: /** -// JTS: * Insert a EdgeEnd into this EdgeEndStar -// JTS: */ -// JTS: abstract public void insert(EdgeEnd e); -// JTS: -// JTS: /** -// JTS: * Insert an EdgeEnd into the map, and clear the edgeList cache, -// JTS: * since the list of edges has now changed -// JTS: */ -// JTS: protected void insertEdgeEnd(EdgeEnd e, Object obj) -// JTS: { -// JTS: edgeMap.put(e, obj); -// JTS: edgeList = null; // edge list has changed - clear the cache -// JTS: } -// JTS: -// JTS: /** -// JTS: * @return the coordinate for the node this star is based at -// JTS: */ -// JTS: public Coordinate getCoordinate() -// JTS: { -// JTS: Iterator it = iterator(); -// JTS: if (! it.hasNext()) return null; -// JTS: EdgeEnd e = (EdgeEnd) it.next(); -// JTS: return e.getCoordinate(); -// JTS: } -// JTS: public int getDegree() -// JTS: { -// JTS: return edgeMap.size(); -// JTS: } -// JTS: -// JTS: /** -// JTS: * Iterator access to the ordered list of edges is optimized by -// JTS: * copying the map collection to a list. (This assumes that -// JTS: * once an iterator is requested, it is likely that insertion into -// JTS: * the map is complete). -// JTS: */ -// JTS: public Iterator iterator() -// JTS: { -// JTS: return getEdges().iterator(); -// JTS: } - -// JTS: public List getEdges() -// JTS: { -// JTS: if (edgeList == null) { -// JTS: edgeList = new ArrayList(edgeMap.values()); -// JTS: } -// JTS: return edgeList; -// JTS: } -// JTS: public EdgeEnd getNextCW(EdgeEnd ee) -// JTS: { -// JTS: getEdges(); -// JTS: int i = edgeList.indexOf(ee); -// JTS: int iNextCW = i - 1; -// JTS: if (i == 0) -// JTS: iNextCW = edgeList.size() - 1; -// JTS: return (EdgeEnd) edgeList.get(iNextCW); -// JTS: } - -// JTS: public void computeLabelling(GeometryGraph[] geomGraph) -// JTS: { - -// JTS: private void computeEdgeEndLabels(BoundaryNodeRule boundaryNodeRule) -// JTS: { -// JTS: // Compute edge label for each EdgeEnd -// JTS: for (Iterator it = iterator(); it.hasNext(); ) { -// JTS: EdgeEnd ee = (EdgeEnd) it.next(); -// JTS: ee.computeLabel(boundaryNodeRule); -// JTS: } -// JTS: } - -// JTS: private int getLocation(int geomIndex, Coordinate p, GeometryGraph[] geom) -// JTS: { -// JTS: // compute location only on demand -// JTS: if (ptInAreaLocation[geomIndex] == Location.NONE) { -// JTS: ptInAreaLocation[geomIndex] = SimplePointInAreaLocator.locate(p, geom[geomIndex].getGeometry()); -// JTS: } -// JTS: return ptInAreaLocation[geomIndex]; -// JTS: } - -// JTS: public boolean isAreaLabelsConsistent(GeometryGraph geomGraph) -// JTS: { -// JTS: computeEdgeEndLabels(geomGraph.getBoundaryNodeRule()); -// JTS: return checkAreaLabelsConsistent(0); -// JTS: } -// JTS: -// JTS: private boolean checkAreaLabelsConsistent(int geomIndex) -// JTS: { -// JTS: // Since edges are stored in CCW order around the node, -// JTS: // As we move around the ring we move from the right to the left side of the edge -// JTS: List edges = getEdges(); -// JTS: // if no edges, trivially consistent -// JTS: if (edges.size() <= 0) -// JTS: return true; -// JTS: // initialize startLoc to location of last L side (if any) -// JTS: int lastEdgeIndex = edges.size() - 1; -// JTS: Label startLabel = ((EdgeEnd) edges.get(lastEdgeIndex)).getLabel(); -// JTS: int startLoc = startLabel.getLocation(geomIndex, Position.LEFT); -// JTS: Assert.isTrue(startLoc != Location.NONE, "Found unlabelled area edge"); -// JTS: -// JTS: int currLoc = startLoc; -// JTS: for (Iterator it = iterator(); it.hasNext(); ) { -// JTS: EdgeEnd e = (EdgeEnd) it.next(); -// JTS: Label label = e.getLabel(); -// JTS: // we assume that we are only checking a area -// JTS: Assert.isTrue(label.isArea(geomIndex), "Found non-area edge"); -// JTS: int leftLoc = label.getLocation(geomIndex, Position.LEFT); -// JTS: int rightLoc = label.getLocation(geomIndex, Position.RIGHT); -// JTS: //System.out.println(leftLoc + " " + rightLoc); -// JTS: //Debug.print(this); -// JTS: // check that edge is really a boundary between inside and outside! -// JTS: if (leftLoc == rightLoc) { -// JTS: return false; -// JTS: } -// JTS: // check side location conflict -// JTS: //Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr); -// JTS: if (rightLoc != currLoc) { -// JTS: //Debug.print(this); -// JTS: return false; -// JTS: } -// JTS: currLoc = leftLoc; -// JTS: } -// JTS: return true; -// JTS: } - -// JTS: public int findIndex(EdgeEnd eSearch) -// JTS: { -// JTS: iterator(); // force edgelist to be computed -// JTS: for (int i = 0; i < edgeList.size(); i++ ) { -// JTS: EdgeEnd e = (EdgeEnd) edgeList.get(i); -// JTS: if (e == eSearch) return i; -// JTS: } -// JTS: return -1; -// JTS: } -// JTS: -// JTS: public void print(PrintStream out) -// JTS: { -// JTS: System.out.println("EdgeEndStar: " + getCoordinate()); -// JTS: for (Iterator it = iterator(); it.hasNext(); ) { -// JTS: EdgeEnd e = (EdgeEnd) it.next(); -// JTS: e.print(out); -// JTS: } -// JTS: } -// JTS: -// JTS: public String toString() -// JTS: { -// JTS: StringBuffer buf = new StringBuffer(); -// JTS: buf.append("EdgeEndStar: " + getCoordinate()); -// JTS: buf.append("\n"); -// JTS: for (Iterator it = iterator(); it.hasNext(); ) { -// JTS: EdgeEnd e = (EdgeEnd) it.next(); -// JTS: buf.append(e); -// JTS: buf.append("\n"); -// JTS: } -// JTS: return buf.toString(); -// JTS: } -// JTS: } diff --git a/geo/src/algorithm/relate/geomgraph/edge_intersection.rs b/geo/src/algorithm/relate/geomgraph/edge_intersection.rs index 8be29c30a5..f6a596a00c 100644 --- a/geo/src/algorithm/relate/geomgraph/edge_intersection.rs +++ b/geo/src/algorithm/relate/geomgraph/edge_intersection.rs @@ -1,19 +1,5 @@ use crate::{Coordinate, GeoFloat}; -// JTS: /** -// JTS: * Represents a point on an -// JTS: * edge which intersects with another edge. -// JTS: *

-// JTS: * The intersection may either be a single point, or a line segment -// JTS: * (in which case this point is the start of the line segment) -// JTS: * The intersection point must be precise. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class EdgeIntersection -// JTS: implements Comparable -// JTS: { - /// Represents a point on an edge which intersects with another edge. /// /// The intersection may either be a single point, or a line segment (in which case this point is @@ -27,17 +13,8 @@ pub(crate) struct EdgeIntersection { dist: F, } -// JTS: public Coordinate coord; // the point of intersection -// JTS: public int segmentIndex; // the index of the containing line segment in the parent edge -// JTS: public double dist; // the edge distance of this point along the containing line segment -// JTS: impl EdgeIntersection { - // JTS: public EdgeIntersection(Coordinate coord, int segmentIndex, double dist) { pub fn new(coord: Coordinate, segment_index: usize, dist: F) -> EdgeIntersection { - // JTS: this.coord = new Coordinate(coord); - // JTS: this.segmentIndex = segmentIndex; - // JTS: this.dist = dist; - // JTS: } EdgeIntersection { coord, segment_index, @@ -45,17 +22,14 @@ impl EdgeIntersection { } } - // JTS: public Coordinate getCoordinate() { return coord; } pub fn coordinate(&self) -> Coordinate { self.coord } - // JTS: public int getSegmentIndex() { return segmentIndex; } pub fn segment_index(&self) -> usize { self.segment_index } - // JTS: public double getDistance() { return dist; } pub fn distance(&self) -> F { self.dist } @@ -77,24 +51,6 @@ impl std::cmp::PartialOrd for EdgeIntersection { impl std::cmp::Ord for EdgeIntersection { fn cmp(&self, other: &EdgeIntersection) -> std::cmp::Ordering { - // JTS: public int compareTo(Object obj) - // JTS: { - // JTS: EdgeIntersection other = (EdgeIntersection) obj; - // JTS: return compare(other.segmentIndex, other.dist); - // JTS: } - // JTS: /** - // JTS: * @return -1 this EdgeIntersection is located before the argument location - // JTS: * @return 0 this EdgeIntersection is at the argument location - // JTS: * @return 1 this EdgeIntersection is located after the argument location - // JTS: */ - // JTS: public int compare(int segmentIndex, double dist) - // JTS: { - // JTS: if (this.segmentIndex < segmentIndex) return -1; - // JTS: if (this.segmentIndex > segmentIndex) return 1; - // JTS: if (this.dist < dist) return -1; - // JTS: if (this.dist > dist) return 1; - // JTS: return 0; - // JTS: } if self.segment_index < other.segment_index { return std::cmp::Ordering::Less; } @@ -116,24 +72,4 @@ impl std::cmp::Ord for EdgeIntersection { } } -impl EdgeIntersection { - // JTS: - // JTS: public boolean isEndPoint(int maxSegmentIndex) - // JTS: { - // JTS: if (segmentIndex == 0 && dist == 0.0) return true; - // JTS: if (segmentIndex == maxSegmentIndex) return true; - // JTS: return false; - // JTS: } - // JTS: - // JTS: public void print(PrintStream out) - // JTS: { - // JTS: out.print(coord); - // JTS: out.print(" seg # = " + segmentIndex); - // JTS: out.println(" dist = " + dist); - // JTS: } - // JTS: public String toString() - // JTS: { - // JTS: return coord + " seg # = " + segmentIndex + " dist = " + dist; - // JTS: } - // JTS: } -} +impl EdgeIntersection {} diff --git a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs index 48303f9f7e..543b3e6b86 100644 --- a/geo/src/algorithm/relate/geomgraph/geometry_graph.rs +++ b/geo/src/algorithm/relate/geomgraph/geometry_graph.rs @@ -1,8 +1,3 @@ -// JTS: import java.util.HashMap; -// JTS: import java.util.Iterator; -// JTS: import java.util.List; -// JTS: import java.util.Map; - use super::{ index::{EdgeSetIntersector, SegmentIntersector, SimpleEdgeSetIntersector}, CoordNode, CoordPos, Direction, Edge, Label, LineIntersector, PlanarGraph, TopologyPosition, @@ -14,38 +9,6 @@ use crate::{Coordinate, GeoFloat, GeometryCow, Line, LineString, Point, Polygon} use std::cell::RefCell; use std::rc::Rc; -// JTS: import org.locationtech.jts.algorithm.BoundaryNodeRule; -// JTS: import org.locationtech.jts.algorithm.LineIntersector; -// JTS: import org.locationtech.jts.algorithm.Orientation; -// JTS: import org.locationtech.jts.algorithm.PointLocator; -// JTS: import org.locationtech.jts.algorithm.locate.IndexedPointInAreaLocator; -// JTS: import org.locationtech.jts.algorithm.locate.PointOnGeometryLocator; -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.CoordinateArrays; -// JTS: import org.locationtech.jts.geom.Geometry; -// JTS: import org.locationtech.jts.geom.GeometryCollection; -// JTS: import org.locationtech.jts.geom.LineString; -// JTS: import org.locationtech.jts.geom.LinearRing; -// JTS: import org.locationtech.jts.geom.Location; -// JTS: import org.locationtech.jts.geom.MultiLineString; -// JTS: import org.locationtech.jts.geom.MultiPoint; -// JTS: import org.locationtech.jts.geom.MultiPolygon; -// JTS: import org.locationtech.jts.geom.Point; -// JTS: import org.locationtech.jts.geom.Polygon; -// JTS: import org.locationtech.jts.geom.Polygonal; -// JTS: import org.locationtech.jts.geomgraph.index.EdgeSetIntersector; -// JTS: import org.locationtech.jts.geomgraph.index.SegmentIntersector; -// JTS: import org.locationtech.jts.geomgraph.index.SimpleMCSweepLineIntersector; -// JTS: import org.locationtech.jts.util.Assert; - -// JTS: /** -// JTS: * A GeometryGraph is a graph that models a given Geometry -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class GeometryGraph -// JTS: extends PlanarGraph -// JTS: { - /// The computation of the [`IntersectionMatrix`] relies on the use of a /// structure called a "topology graph". The topology graph contains [nodes](CoordNode) and /// [edges](Edge) corresponding to the nodes and line segments of a [`Geometry`]. Each @@ -104,23 +67,6 @@ impl<'a, F> GeometryGraph<'a, F> where F: GeoFloat, { - // JTS: public GeometryGraph(int argIndex, Geometry parentGeom) - // JTS: { - // JTS: this(argIndex, parentGeom, - // JTS: BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE - // JTS: ); - // JTS: } - // JTS: - // JTS: public GeometryGraph(int argIndex, Geometry parentGeom, BoundaryNodeRule boundaryNodeRule) { - // JTS: this.argIndex = argIndex; - // JTS: this.parentGeom = parentGeom; - // JTS: this.boundaryNodeRule = boundaryNodeRule; - // JTS: if (parentGeom != null) { - // JTS: // precisionModel = parentGeom.getPrecisionModel(); - // JTS: // SRID = parentGeom.getSRID(); - // JTS: add(parentGeom); - // JTS: } - // JTS: } pub fn new(arg_index: usize, parent_geometry: &'a GeometryCow) -> Self { let mut graph = GeometryGraph { arg_index, @@ -132,62 +78,10 @@ where graph } - // JTS: - // JTS: /** - // JTS: * This constructor is used by clients that wish to add Edges explicitly, - // JTS: * rather than adding a Geometry. (An example is BufferOp). - // JTS: */ - // JTS: // no longer used - // JTS: // public GeometryGraph(int argIndex, PrecisionModel precisionModel, int SRID) { - // JTS: // this(argIndex, null); - // JTS: // this.precisionModel = precisionModel; - // JTS: // this.SRID = SRID; - // JTS: // } - // JTS: // public PrecisionModel getPrecisionModel() - // JTS: // { - // JTS: // return precisionModel; - // JTS: // } - // JTS: // public int getSRID() { return SRID; } - // JTS: - // JTS: public boolean hasTooFewPoints() { return hasTooFewPoints; } - // JTS: - // JTS: public Coordinate getInvalidPoint() { return invalidPoint; } - // JTS: - // JTS: public Geometry getGeometry() { return parentGeom; } pub fn geometry(&self) -> &GeometryCow { self.parent_geometry } - // JTS: /** - // JTS: * This method implements the Boundary Determination Rule - // JTS: * for determining whether - // JTS: * a component (node or edge) that appears multiple times in elements - // JTS: * of a MultiGeometry is in the boundary or the interior of the Geometry - // JTS: *
- // JTS: * The SFS uses the "Mod-2 Rule", which this function implements - // JTS: *
- // JTS: * An alternative (and possibly more intuitive) rule would be - // JTS: * the "At Most One Rule": - // JTS: * isInBoundary = (componentCount == 1) - // JTS: */ - // JTS: /* - // JTS: public static boolean isInBoundary(int boundaryCount) - // JTS: { - // JTS: // the "Mod-2 Rule" - // JTS: return boundaryCount % 2 == 1; - // JTS: } - // JTS: public static int determineBoundary(int boundaryCount) - // JTS: { - // JTS: return isInBoundary(boundaryCount) ? Location.BOUNDARY : Location.INTERIOR; - // JTS: } - // JTS: */ - // JTS: - // JTS: public static int determineBoundary(BoundaryNodeRule boundaryNodeRule, int boundaryCount) - // JTS: { - // JTS: return boundaryNodeRule.isInBoundary(boundaryCount) - // JTS: ? Location.BOUNDARY : Location.INTERIOR; - // JTS: } - /// Determine whether a component (node or edge) that appears multiple times in elements /// of a Multi-Geometry is in the boundary or the interior of the Geometry pub fn determine_boundary(boundary_count: usize) -> CoordPos { @@ -200,105 +94,20 @@ where } } - // JTS: private Geometry parentGeom; - // JTS: - // JTS: /** - // JTS: * The lineEdgeMap is a map of the linestring components of the - // JTS: * parentGeometry to the edges which are derived from them. - // JTS: * This is used to efficiently perform findEdge queries - // JTS: */ - // JTS: private Map lineEdgeMap = new HashMap(); - // JTS: - // JTS: private BoundaryNodeRule boundaryNodeRule = null; - // JTS: - // JTS: /** - // JTS: * If this flag is true, the Boundary Determination Rule will used when deciding - // JTS: * whether nodes are in the boundary or not - // JTS: */ - // JTS: private boolean useBoundaryDeterminationRule = true; - // JTS: private int argIndex; // the index of this geometry as an argument to a spatial function (used for labelling) - // JTS: private Collection boundaryNodes; - // JTS: private boolean hasTooFewPoints = false; - // JTS: private Coordinate invalidPoint = null; - // JTS: - // JTS: private PointOnGeometryLocator areaPtLocator = null; - // JTS: // for use if geometry is not Polygonal - // JTS: private final PointLocator ptLocator = new PointLocator(); - // JTS: - // JTS: private EdgeSetIntersector createEdgeSetIntersector() - // JTS: { fn create_edge_set_intersector() -> Box> { - // JTS: // various options for computing intersections, from slowest to fastest - // JTS: - // JTS: //private EdgeSetIntersector esi = new SimpleEdgeSetIntersector(); - // JTS: //private EdgeSetIntersector esi = new MonotoneChainIntersector(); - // JTS: //private EdgeSetIntersector esi = new NonReversingChainIntersector(); - // JTS: //private EdgeSetIntersector esi = new SimpleSweepLineIntersector(); - // JTS: //private EdgeSetIntersector esi = new MCSweepLineIntersector(); - // JTS: - // JTS: //return new SimpleEdgeSetIntersector(); // PERF: faster algorithms exist. This one was chosen for simplicity of implementation and // debugging Box::new(SimpleEdgeSetIntersector::new()) - // JTS: return new SimpleMCSweepLineIntersector(); - // JTS: } } - // JTS: public BoundaryNodeRule getBoundaryNodeRule() { return boundaryNodeRule; } - // JTS: - // JTS: public Collection getBoundaryNodes() - // JTS: { - // JTS: if (boundaryNodes == null) - // JTS: boundaryNodes = nodes.getBoundaryNodes(argIndex); - // JTS: return boundaryNodes; - // JTS: } fn boundary_nodes(&self) -> impl Iterator> { self.planar_graph.boundary_nodes(self.arg_index) } - // JTS: - // JTS: public Coordinate[] getBoundaryPoints() - // JTS: { - // JTS: Collection coll = getBoundaryNodes(); - // JTS: Coordinate[] pts = new Coordinate[coll.size()]; - // JTS: int i = 0; - // JTS: for (Iterator it = coll.iterator(); it.hasNext(); ) { - // JTS: Node node = (Node) it.next(); - // JTS: pts[i++] = node.getCoordinate().copy(); - // JTS: } - // JTS: return pts; - // JTS: } - // JTS: - // JTS: public Edge findEdge(LineString line) - // JTS: { - // JTS: return (Edge) lineEdgeMap.get(line); - // JTS: } - // JTS: - // JTS: public void computeSplitEdges(List edgelist) - // JTS: { - // JTS: for (Iterator i = edges.iterator(); i.hasNext(); ) { - // JTS: Edge e = (Edge) i.next(); - // JTS: e.eiList.addSplitEdges(edgelist); - // JTS: } - // JTS: } - - // JTS: private void add(Geometry g) - // JTS: { + pub fn add_geometry(&mut self, geometry: &GeometryCow) { - // JTS: if (g.isEmpty()) return; if geometry.is_empty() { return; } - // JTS: - // JTS: if (g instanceof Polygon) addPolygon((Polygon) g); - // JTS: // LineString also handles LinearRings - // JTS: else if (g instanceof LineString) addLineString((LineString) g); - // JTS: else if (g instanceof Point) addPoint((Point) g); - // JTS: else if (g instanceof MultiPoint) addCollection((MultiPoint) g); - // JTS: else if (g instanceof MultiLineString) addCollection((MultiLineString) g); - // JTS: else if (g instanceof MultiPolygon) addCollection((MultiPolygon) g); - // JTS: else if (g instanceof GeometryCollection) addCollection((GeometryCollection) g); - // JTS: else throw new UnsupportedOperationException(g.getClass().getName()); - // JTS: } match geometry { GeometryCow::Line(line) => self.add_line(line), GeometryCow::Rect(rect) => { @@ -320,10 +129,6 @@ where } } GeometryCow::MultiPolygon(multi_polygon) => { - // JTS: // check if this Geometry should obey the Boundary Determination Rule - // JTS: // all collections except MultiPolygons obey the rule - // JTS: if (g instanceof MultiPolygon) - // JTS: useBoundaryDeterminationRule = false; // check if this Geometry should obey the Boundary Determination Rule // all collections except MultiPolygons obey the rule self.use_boundary_determination_rule = false; @@ -344,32 +149,6 @@ where } } - // JTS: private void addCollection(GeometryCollection gc) - // JTS: { - // JTS: for (int i = 0; i < gc.getNumGeometries(); i++) { - // JTS: Geometry g = gc.getGeometryN(i); - // JTS: add(g); - // JTS: } - // JTS: } - // JTS: /** - // JTS: * Add a Point to the graph. - // JTS: */ - // JTS: private void addPoint(Point p) - // JTS: { - // JTS: Coordinate coord = p.getCoordinate(); - // JTS: insertPoint(argIndex, coord, Location.INTERIOR); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Adds a polygon ring to the graph. - // JTS: * Empty rings are ignored. - // JTS: * - // JTS: * The left and right topological location arguments assume that the ring is oriented CW. - // JTS: * If the ring is in the opposite orientation, - // JTS: * the left and right locations must be interchanged. - // JTS: */ - // JTS: private void addPolygonRing(LinearRing lr, int cwLeft, int cwRight) - // JTS: { fn add_polygon_ring( &mut self, linear_ring: &LineString, @@ -377,13 +156,10 @@ where cw_right: CoordPos, ) { debug_assert!(linear_ring.is_closed()); - // JTS: // don't bother adding empty holes - // JTS: if (lr.isEmpty()) return; if linear_ring.is_empty() { return; } - // JTS: Coordinate[] coord = CoordinateArrays.removeRepeatedPoints(lr.getCoordinates()); let mut coords: Vec> = vec![]; // remove repeated coords for coord in &linear_ring.0 { @@ -392,11 +168,6 @@ where } } - // JTS: if (coord.length < 4) { - // JTS: hasTooFewPoints = true; - // JTS: invalidPoint = coord[0]; - // JTS: return; - // JTS: } if coords.len() < 4 { // TODO: we could return an Err here, but this has ramifications for how we can // use this code in other operations - do we want all our methods, like `contains` to @@ -405,13 +176,6 @@ where } let first_point = coords[0]; - // JTS: - // JTS: int left = cwLeft; - // JTS: int right = cwRight; - // JTS: if (Orientation.isCCW(coord)) { - // JTS: left = cwRight; - // JTS: right = cwLeft; - // JTS: } use crate::algorithm::winding_order::{Winding, WindingOrder}; let (left, right) = match linear_ring.winding_order() { Some(WindingOrder::Clockwise) => (cw_left, cw_right), @@ -422,10 +186,6 @@ where } }; - // JTS: Edge e = new Edge(coord, - // JTS: new Label(argIndex, Location.BOUNDARY, left, right)); - // JTS: lineEdgeMap.put(lr, e); - // JTS: insertEdge(e); let edge = Edge::new( coords, Label::new( @@ -435,33 +195,12 @@ where ); self.insert_edge(edge); - // JTS: // insert the endpoint as a node, to mark that it is on the boundary - // JTS: insertPoint(argIndex, coord[0], Location.BOUNDARY); // insert the endpoint as a node, to mark that it is on the boundary self.insert_point(self.arg_index, first_point, CoordPos::OnBoundary); - // JTS: } } - // JTS: private void addPolygon(Polygon p) - // JTS: { fn add_polygon(&mut self, polygon: &Polygon) { - // JTS: addPolygonRing( - // JTS: p.getExteriorRing(), - // JTS: Location.EXTERIOR, - // JTS: Location.INTERIOR); self.add_polygon_ring(polygon.exterior(), CoordPos::Outside, CoordPos::Inside); - // JTS: for (int i = 0; i < p.getNumInteriorRing(); i++) { - // JTS: LinearRing hole = p.getInteriorRingN(i); - // JTS: - // JTS: // Holes are topologically labelled opposite to the shell, since - // JTS: // the interior of the polygon lies on their opposite side - // JTS: // (on the left, if the hole is oriented CW) - // JTS: addPolygonRing( - // JTS: hole, - // JTS: Location.INTERIOR, - // JTS: Location.EXTERIOR); - // JTS: } - // JTS: } // Holes are topologically labeled opposite to the shell, since // the interior of the polygon lies on their opposite side // (on the left, if the hole is oriented CW) @@ -470,14 +209,11 @@ where } } - // JTS: private void addLineString(LineString line) - // JTS: { fn add_line_string(&mut self, line_string: &LineString) { if line_string.is_empty() { return; } - // JTS: Coordinate[] coord = CoordinateArrays.removeRepeatedPoints(line.getCoordinates()); let mut coords: Vec> = vec![]; for coord in &line_string.0 { if coords.last() != Some(coord) { @@ -485,11 +221,6 @@ where } } - // JTS: if (coord.length < 2) { - // JTS: hasTooFewPoints = true; - // JTS: invalidPoint = coord[0]; - // JTS: return; - // JTS: } if coords.len() < 2 { // TODO: we could return an Err here, but this has ramifications for how we can // use this code in other operations - do we want all our methods, like `contains` to @@ -499,12 +230,6 @@ where self.insert_boundary_point(*coords.first().unwrap()); self.insert_boundary_point(*coords.last().unwrap()); - // JTS: - // JTS: // add the edge for the LineString - // JTS: // line edges do not have locations for their left and right sides - // JTS: Edge e = new Edge(coord, new Label(argIndex, Location.INTERIOR)); - // JTS: lineEdgeMap.put(line, e); - // JTS: insertEdge(e); let edge = Edge::new( coords, Label::new( @@ -513,16 +238,6 @@ where ), ); self.insert_edge(edge); - - // JTS: /** - // JTS: * Add the boundary points of the LineString, if any. - // JTS: * Even if the LineString is closed, add both points as if they were endpoints. - // JTS: * This allows for the case that the node already exists and is a boundary point. - // JTS: */ - // JTS: Assert.isTrue(coord.length >= 2, "found LineString with single point"); - // JTS: insertBoundaryPoint(argIndex, coord[0]); - // JTS: insertBoundaryPoint(argIndex, coord[coord.length - 1]); - // JTS: } } fn add_line(&mut self, line: &Line) { @@ -540,60 +255,12 @@ where self.insert_edge(edge); } - // JTS: - // JTS: /** - // JTS: * Add an Edge computed externally. The label on the Edge is assumed - // JTS: * to be correct. - // JTS: */ - // JTS: public void addEdge(Edge e) - // JTS: { - // JTS: insertEdge(e); - // JTS: Coordinate[] coord = e.getCoordinates(); - // JTS: // insert the endpoint as a node, to mark that it is on the boundary - // JTS: insertPoint(argIndex, coord[0], Location.BOUNDARY); - // JTS: insertPoint(argIndex, coord[coord.length - 1], Location.BOUNDARY); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Add a point computed externally. The point is assumed to be a - // JTS: * Point Geometry part, which has a location of INTERIOR. - // JTS: */ - // JTS: public void addPoint(Coordinate pt) - // JTS: { - // JTS: insertPoint(argIndex, pt, Location.INTERIOR); - // JTS: } /// Add a point computed externally. The point is assumed to be a /// Point Geometry part, which has a location of INTERIOR. fn add_point(&mut self, point: &Point) { self.insert_point(self.arg_index, point.clone().into(), CoordPos::Inside); } - // JTS: /** - // JTS: * Compute self-nodes, taking advantage of the Geometry type to - // JTS: * minimize the number of intersection tests. (E.g. rings are - // JTS: * not tested for self-intersection, since they are assumed to be valid). - // JTS: * - // JTS: * @param li the LineIntersector to use - // JTS: * @param computeRingSelfNodes if false, intersection checks are optimized to not test rings for self-intersection - // JTS: * @return the computed SegmentIntersector containing information about the intersections found - // JTS: */ - // JTS: public SegmentIntersector computeSelfNodes(LineIntersector li, boolean computeRingSelfNodes) - // JTS: { - // JTS: return computeSelfNodes(li, computeRingSelfNodes, false); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Compute self-nodes, taking advantage of the Geometry type to - // JTS: * minimize the number of intersection tests. (E.g. rings are - // JTS: * not tested for self-intersection, since they are assumed to be valid). - // JTS: * - // JTS: * @param li the LineIntersector to use - // JTS: * @param computeRingSelfNodes if false, intersection checks are optimized to not test rings for self-intersection - // JTS: * @param isDoneIfProperInt short-circuit the intersection computation if a proper intersection is found - // JTS: * @return the computed SegmentIntersector containing information about the intersections found - // JTS: */ - // JTS: public SegmentIntersector computeSelfNodes(LineIntersector li, boolean computeRingSelfNodes, boolean isDoneIfProperInt) - // JTS: { /// Compute self-nodes, taking advantage of the Geometry type to minimize the number of /// intersection tests. (E.g. rings are not tested for self-intersection, since they are /// assumed to be valid). @@ -603,19 +270,10 @@ where &mut self, line_intersector: Box>, ) -> SegmentIntersector { - // JTS: SegmentIntersector si = new SegmentIntersector(li, true, false); let mut segment_intersector = SegmentIntersector::new(line_intersector, true); - // JTS: si.setIsDoneIfProperInt(isDoneIfProperInt); - - // JTS: EdgeSetIntersector esi = createEdgeSetIntersector(); let mut edge_set_intersector = Self::create_edge_set_intersector(); - // JTS: // optimize intersection search for valid Polygons and LinearRings - // JTS: boolean isRings = parentGeom instanceof LinearRing - // JTS: || parentGeom instanceof Polygon - // JTS: || parentGeom instanceof MultiPolygon; - // JTS: boolean computeAllSegments = computeRingSelfNodes || ! isRings; // optimize intersection search for valid Polygons and LinearRings let is_rings = match self.geometry() { GeometryCow::LineString(ls) => ls.is_closed(), @@ -625,43 +283,28 @@ where }; let check_for_self_intersecting_edges = !is_rings; - // JTS: esi.computeIntersections(edges, si, computeAllSegments); edge_set_intersector.compute_intersections_within_set( self.edges(), check_for_self_intersecting_edges, &mut segment_intersector, ); - // JTS: //System.out.println("SegmentIntersector # tests = " + si.numTests); - // JTS: addSelfIntersectionNodes(argIndex); self.add_self_intersection_nodes(); - // JTS: return si; - // JTS: } segment_intersector } - // JTS: public SegmentIntersector computeEdgeIntersections( - // JTS: GeometryGraph g, - // JTS: LineIntersector li, - // JTS: boolean includeProper) - // JTS: { pub fn compute_edge_intersections( &self, other: &GeometryGraph, line_intersector: Box>, ) -> SegmentIntersector { - // JTS: SegmentIntersector si = new SegmentIntersector(li, includeProper, true); - // JTS: si.setBoundaryNodes(this.getBoundaryNodes(), g.getBoundaryNodes()); let mut segment_intersector = SegmentIntersector::new(line_intersector, false); segment_intersector.set_boundary_nodes( self.boundary_nodes().into_iter().cloned().collect(), other.boundary_nodes().into_iter().cloned().collect(), ); - // JTS: - // JTS: EdgeSetIntersector esi = createEdgeSetIntersector(); - // JTS: esi.computeIntersections(edges, g.edges, si); let mut edge_set_intersector = Self::create_edge_set_intersector(); edge_set_intersector.compute_intersections_between_sets( self.edges(), @@ -669,56 +312,21 @@ where &mut segment_intersector, ); - // JTS: /* - // JTS: for (Iterator i = g.edges.iterator(); i.hasNext();) { - // JTS: Edge e = (Edge) i.next(); - // JTS: Debug.print(e.getEdgeIntersectionList()); - // JTS: } - // JTS: */ - // JTS: return si; segment_intersector - // JTS: } } - // JTS: private void insertPoint(int argIndex, Coordinate coord, int onLocation) - // JTS: { - // JTS: Node n = nodes.addNode(coord); - // JTS: Label lbl = n.getLabel(); - // JTS: if (lbl == null) { - // JTS: n.label = new Label(argIndex, onLocation); - // JTS: } - // JTS: else - // JTS: lbl.setLocation(argIndex, onLocation); - // JTS: } fn insert_point(&mut self, arg_index: usize, coord: Coordinate, position: CoordPos) { let node: &mut CoordNode = self.add_node_with_coordinate(coord); node.label_mut().set_on_position(arg_index, position); } - // JTS: /** - // JTS: * Adds candidate boundary points using the current {@link BoundaryNodeRule}. - // JTS: * This is used to add the boundary - // JTS: * points of dim-1 geometries (Curves/MultiCurves). - // JTS: */ - // JTS: private void insertBoundaryPoint(int argIndex, Coordinate coord) - // JTS: { /// Add the boundary points of 1-dim (line) geometries. fn insert_boundary_point(&mut self, coord: Coordinate) { - // JTS: Node n = nodes.addNode(coord); let arg_index = self.arg_index; let node: &mut CoordNode = self.add_node_with_coordinate(coord); - // JTS: // nodes always have labels - // JTS: Label lbl = n.getLabel(); let label: &mut Label = node.label_mut(); - // JTS: // the new point to insert is on a boundary - // JTS: int boundaryCount = 1; - // JTS: // determine the current location for the point (if any) - // JTS: int loc = Location.NONE; - // JTS: loc = lbl.getLocation(argIndex, Position.ON); - // JTS: if (loc == Location.BOUNDARY) boundaryCount++; - // determine the current location for the point (if any) let boundary_count = { let prev_boundary_count = @@ -730,27 +338,10 @@ where prev_boundary_count + 1 }; - // JTS: // determine the boundary status of the point according to the Boundary Determination Rule - // JTS: int newLoc = determineBoundary(boundaryNodeRule, boundaryCount); - // JTS: lbl.setLocation(argIndex, newLoc); let new_position = Self::determine_boundary(boundary_count); label.set_on_position(arg_index, new_position); - // JTS: } } - // JTS: - // JTS: private void addSelfIntersectionNodes(int argIndex) - // JTS: { fn add_self_intersection_nodes(&mut self) { - // JTS: for (Iterator i = edges.iterator(); i.hasNext(); ) { - // JTS: Edge e = (Edge) i.next(); - // JTS: int eLoc = e.getLabel().getLocation(argIndex); - // JTS: for (Iterator eiIt = e.eiList.iterator(); eiIt.hasNext(); ) { - // JTS: EdgeIntersection ei = (EdgeIntersection) eiIt.next(); - // JTS: addSelfIntersectionNode(argIndex, ei.coord, eLoc); - // JTS: } - // JTS: } - // JTS: } - let positions_and_intersections: Vec<(CoordPos, Vec>)> = self .edges() .iter() @@ -776,56 +367,20 @@ where } } - // JTS: /** - // JTS: * Add a node for a self-intersection. - // JTS: * If the node is a potential boundary node (e.g. came from an edge which - // JTS: * is a boundary) then insert it as a potential boundary node. - // JTS: * Otherwise, just add it as a regular node. - // JTS: */ - // JTS: private void addSelfIntersectionNode(int argIndex, Coordinate coord, int loc) - // JTS: { /// Add a node for a self-intersection. /// /// If the node is a potential boundary node (e.g. came from an edge which is a boundary), then /// insert it as a potential boundary node. Otherwise, just add it as a regular node. fn add_self_intersection_node(&mut self, coord: Coordinate, position: CoordPos) { - // JTS: // if this node is already a boundary node, don't change it - // JTS: if (isBoundaryNode(argIndex, coord)) return; // if this node is already a boundary node, don't change it if self.is_boundary_node(coord) { return; } - // JTS: if (loc == Location.BOUNDARY && useBoundaryDeterminationRule) - // JTS: insertBoundaryPoint(argIndex, coord); - // JTS: else - // JTS: insertPoint(argIndex, coord, loc); if position == CoordPos::OnBoundary && self.use_boundary_determination_rule { self.insert_boundary_point(coord) } else { self.insert_point(self.arg_index, coord, position) } - // JTS: } } - // JTS: - // JTS: // MD - experimental for now - // JTS: /** - // JTS: * Determines the {@link Location} of the given {@link Coordinate} - // JTS: * in this geometry. - // JTS: * - // JTS: * @param pt the point to test - // JTS: * @return the location of the point in the geometry - // JTS: */ - // JTS: public int locate(Coordinate pt) - // JTS: { - // JTS: if (parentGeom instanceof Polygonal && parentGeom.getNumGeometries() > 50) { - // JTS: // lazily init point locator - // JTS: if (areaPtLocator == null) { - // JTS: areaPtLocator = new IndexedPointInAreaLocator(parentGeom); - // JTS: } - // JTS: return areaPtLocator.locate(pt); - // JTS: } - // JTS: return ptLocator.locate(pt, parentGeom); - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs index c0b49fc0c3..7f0e3df718 100644 --- a/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/edge_set_intersector.rs @@ -6,15 +6,6 @@ use std::cell::RefCell; use std::rc::Rc; pub(crate) trait EdgeSetIntersector { - // JTS: /** - // JTS: * Computes all self-intersections between edges in a set of edges, - // JTS: * allowing client to choose whether self-intersections are computed. - // JTS: * - // JTS: * @param edges a list of edges to test for intersections - // JTS: * @param si the SegmentIntersector to use - // JTS: * @param testAllSegments true if self-intersections are to be tested as well - // JTS: */ - // JTS: abstract public void computeIntersections(List edges, SegmentIntersector si, boolean testAllSegments); /// Compute all intersections between the edges within a set, recording those intersections on /// the intersecting edges. /// @@ -28,10 +19,6 @@ pub(crate) trait EdgeSetIntersector { segment_intersector: &mut SegmentIntersector, ); - // JTS: /** - // JTS: * Computes all mutual intersections between two sets of edges. - // JTS: */ - // JTS: abstract public void computeIntersections(List edges0, List edges1, SegmentIntersector si); /// Compute all intersections between two sets of edges, recording those intersections on /// the intersecting edges. fn compute_intersections_between_sets( diff --git a/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs index 3727b1f92a..5f714fb22f 100644 --- a/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/segment_intersector.rs @@ -3,14 +3,6 @@ use crate::{Coordinate, GeoFloat, Line}; use std::cell::{Ref, RefCell}; -// JTS: /** -// JTS: * Computes the intersection of line segments, -// JTS: * and adds the intersection to the edges containing the segments. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class SegmentIntersector -// JTS: { /// Computes the intersection of line segments and adds the intersection to the [`Edge`s] containing /// the segments. pub(crate) struct SegmentIntersector @@ -29,48 +21,11 @@ impl SegmentIntersector where F: GeoFloat, { - // JTS: - // JTS: public static boolean isAdjacentSegments(int i1, int i2) - // JTS: { - // JTS: return Math.abs(i1 - i2) == 1; - // JTS: } fn is_adjacent_segments(i1: usize, i2: usize) -> bool { let difference = if i1 > i2 { i1 - i2 } else { i2 - i1 }; difference == 1 } - // JTS: - // JTS: /** - // JTS: * These variables keep track of what types of intersections were - // JTS: * found during ALL edges that have been intersected. - // JTS: */ - // JTS: private boolean hasIntersection = false; - // JTS: private boolean hasProper = false; - // JTS: private boolean hasProperInterior = false; - // JTS: // the proper intersection point found - // JTS: private Coordinate properIntersectionPoint = null; - // JTS: - // JTS: private LineIntersector li; - // JTS: private boolean includeProper; - // JTS: private boolean recordIsolated; - // JTS: private boolean isSelfIntersection; - // JTS: //private boolean intersectionFound; - // JTS: private int numIntersections = 0; - // JTS: - // JTS: // testing only - // JTS: public int numTests = 0; - // JTS: - // JTS: private Collection[] bdyNodes; - // JTS: private boolean isDone = false; - // JTS: private boolean isDoneWhenProperInt = false; - // JTS: - // JTS: - // JTS: public SegmentIntersector(LineIntersector li, boolean includeProper, boolean recordIsolated) - // JTS: { - // JTS: this.li = li; - // JTS: this.includeProper = includeProper; - // JTS: this.recordIsolated = recordIsolated; - // JTS: } pub fn new( line_intersector: Box>, edges_are_from_same_geometry: bool, @@ -83,14 +38,6 @@ where boundary_nodes: None, } } - // JTS: - // JTS: public void setBoundaryNodes( Collection bdyNodes0, - // JTS: Collection bdyNodes1) - // JTS: { - // JTS: bdyNodes = new Collection[2]; - // JTS: bdyNodes[0] = bdyNodes0; - // JTS: bdyNodes[1] = bdyNodes1; - // JTS: } pub fn set_boundary_nodes( &mut self, boundary_nodes_0: Vec>, @@ -103,51 +50,14 @@ where self.boundary_nodes = Some([boundary_nodes_0, boundary_nodes_1]); } - // JTS: public void setIsDoneIfProperInt(boolean isDoneWhenProperInt) { - // JTS: this.isDoneWhenProperInt = isDoneWhenProperInt; - // JTS: } - - // JTS: - // JTS: public boolean isDone() { - // JTS: return isDone; - // JTS: } - // JTS: /** - // JTS: * @return the proper intersection point, or null if none was found - // JTS: */ - // JTS: public Coordinate getProperIntersectionPoint() { return properIntersectionPoint; } - // JTS: - // JTS: public boolean hasIntersection() { return hasIntersection; } - // JTS: /** - // JTS: * A proper intersection is an intersection which is interior to at least two - // JTS: * line segments. Note that a proper intersection is not necessarily - // JTS: * in the interior of the entire Geometry, since another edge may have - // JTS: * an endpoint equal to the intersection, which according to SFS semantics - // JTS: * can result in the point being on the Boundary of the Geometry. - // JTS: */ - // JTS: public boolean hasProperIntersection() { return hasProper; } pub fn has_proper_intersection(&self) -> bool { self.proper_intersection_point.is_some() } - // JTS: /** - // JTS: * A proper interior intersection is a proper intersection which is not - // JTS: * contained in the set of boundary nodes set for this SegmentIntersector. - // JTS: */ - // JTS: public boolean hasProperInteriorIntersection() { return hasProperInterior; } pub fn has_proper_interior_intersection(&self) -> bool { self.has_proper_interior_intersection } - // JTS: - // JTS: - // JTS: /** - // JTS: * A trivial intersection is an apparent self-intersection which in fact - // JTS: * is simply the point shared by adjacent line segments. - // JTS: * Note that closed edges require a special check for the point shared by the beginning - // JTS: * and end segments. - // JTS: */ - // JTS: private boolean isTrivialIntersection(Edge e0, int segIndex0, Edge e1, int segIndex1) - // JTS: { /// A trivial intersection is an apparent self-intersection which in fact is simply the point /// shared by adjacent line segments. Note that closed edges require a special check for the /// point shared by the beginning and end segments. @@ -159,8 +69,6 @@ where edge1: &RefCell>, segment_index_1: usize, ) -> bool { - // JTS: if (e0 == e1) { - // JTS: if (li.getIntersectionNum() == 1) { if edge0.as_ptr() != edge1.as_ptr() { return false; } @@ -169,19 +77,10 @@ where return false; } - // JTS: if (isAdjacentSegments(segIndex0, segIndex1)) - // JTS: return true; if Self::is_adjacent_segments(segment_index_0, segment_index_1) { return true; } - // JTS: if (e0.isClosed()) { - // JTS: int maxSegIndex = e0.getNumPoints() - 1; - // JTS: if ( (segIndex0 == 0 && segIndex1 == maxSegIndex) - // JTS: || (segIndex1 == 0 && segIndex0 == maxSegIndex) ) { - // JTS: return true; - // JTS: } - // JTS: } let edge0 = edge0.borrow(); if edge0.is_closed() { // first and last coords in a ring are adjacent @@ -192,25 +91,9 @@ where return true; } } - // JTS: } - // JTS: } - // JTS: return false; - // JTS: } false } - // JTS: - // JTS: /** - // JTS: * This method is called by clients of the EdgeIntersector class to test for and add - // JTS: * intersections for two segments of the edges being intersected. - // JTS: * Note that clients (such as MonotoneChainEdges) may choose not to intersect - // JTS: * certain pairs of segments for efficiency reasons. - // JTS: */ - // JTS: public void addIntersections( - // JTS: Edge e0, int segIndex0, - // JTS: Edge e1, int segIndex1 - // JTS: ) - // JTS: { pub fn add_intersections( &mut self, edge0: &RefCell>, @@ -218,17 +101,11 @@ where edge1: &RefCell>, segment_index_1: usize, ) { - // JTS: if (e0 == e1 && segIndex0 == segIndex1) return; // avoid a segment spuriously "intersecting" with itself if edge0.as_ptr() == edge1.as_ptr() && segment_index_0 == segment_index_1 { return; } - // JTS: numTests++; - // JTS: Coordinate p00 = e0.getCoordinates()[segIndex0]; - // JTS: Coordinate p01 = e0.getCoordinates()[segIndex0 + 1]; - // JTS: Coordinate p10 = e1.getCoordinates()[segIndex1]; - // JTS: Coordinate p11 = e1.getCoordinates()[segIndex1 + 1]; let line_0 = Line::new( edge0.borrow().coords()[segment_index_0], edge0.borrow().coords()[segment_index_0 + 1], @@ -238,34 +115,17 @@ where edge1.borrow().coords()[segment_index_1 + 1], ); - // JTS: li.computeIntersection(p00, p01, p10, p11); let intersection = self.line_intersector.compute_intersection(line_0, line_1); - // JTS: //if (li.hasIntersection() && li.isProper()) Debug.println(li); - // JTS: /** - // JTS: * Always record any non-proper intersections. - // JTS: * If includeProper is true, record any proper intersections as well. - // JTS: */ - // JTS: if (li.hasIntersection()) { if intersection.is_none() { return; } let intersection = intersection.unwrap(); - // JTS: if (recordIsolated) { - // JTS: e0.setIsolated(false); - // JTS: e1.setIsolated(false); - // JTS: } if !self.edges_are_from_same_geometry { edge0.borrow_mut().mark_as_unisolated(); edge1.borrow_mut().mark_as_unisolated(); } - // JTS: //intersectionFound = true; - // JTS: numIntersections++; - // JTS: // if the segments are adjacent they have at least one trivial intersection, - // JTS: // the shared endpoint. Don't bother adding it if it is the - // JTS: // only intersection. - // JTS: if (! isTrivialIntersection(e0, segIndex0, e1, segIndex1)) { if !self.is_trivial_intersection( intersection, edge0, @@ -273,14 +133,6 @@ where edge1, segment_index_1, ) { - // JTS: hasIntersection = true; - - // JTS: if (includeProper || ! li.isProper() ) { - // JTS: //Debug.println(li); - // JTS: e0.addIntersections(li, segIndex0, 0); - // JTS: e1.addIntersections(li, segIndex1, 1); - // JTS: } - if self.edges_are_from_same_geometry || !intersection.is_proper() { // In the case of self-noding, `edge0` might alias `edge1`, so it's imperative that // the mutable borrow's are short lived and do not overlap. @@ -292,50 +144,25 @@ where .borrow_mut() .add_intersections(intersection, line_1, segment_index_1); } - // JTS: if (li.isProper()) { if let LineIntersection::SinglePoint { is_proper: true, intersection: intersection_coord, } = intersection { - // JTS: properIntersectionPoint = li.getIntersection(0).copy(); - // JTS: hasProper = true; self.proper_intersection_point = Some(intersection_coord); - // JTS: if (isDoneWhenProperInt) { - // JTS: isDone = true; - // JTS: } - - // JTS: if (! isBoundaryPoint(li, bdyNodes)) - // JTS: hasProperInterior = true; if !self.is_boundary_point(&intersection_coord, &self.boundary_nodes) { self.has_proper_interior_intersection = true } - // JTS: } - // JTS: //if (li.isCollinear()) - // JTS: //hasCollinear = true; - // JTS: } } - // JTS: } - // JTS: } } } - // JTS: private boolean isBoundaryPoint(LineIntersector li, Collection[] bdyNodes) - // JTS: { fn is_boundary_point( &self, intersection: &Coordinate, boundary_nodes: &Option<[Vec>; 2]>, ) -> bool { - // JTS: private boolean isBoundaryPointInternal(LineIntersector li, Collection bdyNodes) - // JTS: { - // JTS: for (Iterator i = bdyNodes.iterator(); i.hasNext(); ) { - // JTS: Node node = (Node) i.next(); - // JTS: Coordinate pt = node.getCoordinate(); - // JTS: if (li.isIntersection(pt)) return true; - // JTS: } - // JTS: return false; match &boundary_nodes { Some(boundary_nodes) => boundary_nodes .iter() @@ -344,13 +171,7 @@ where None => false, } - // JTS: } - // JTS: if (bdyNodes == null) return false; - // JTS: if (isBoundaryPointInternal(li, bdyNodes[0])) return true; - // JTS: if (isBoundaryPointInternal(li, bdyNodes[1])) return true; - // JTS: return false; // is_boundary(intersection, &boundary_nodes[0]) // || self.is_boundary_point_internal(intersection, &boundary_nodes[1]) - // JTS: } } } diff --git a/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs b/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs index b9d7eec1a3..db9cc98455 100644 --- a/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/index/simple_edge_set_intersector.rs @@ -5,13 +5,6 @@ use crate::GeoFloat; use std::cell::RefCell; use std::rc::Rc; -// JTS: /** -// JTS: * Finds all intersections in one or two sets of edges, -// JTS: * using the straightforward method of -// JTS: * comparing all segments. -// JTS: * This algorithm is too slow for production use, but is useful for testing purposes. -// JTS: * @version 1.7 -// JTS: */ pub(crate) struct SimpleEdgeSetIntersector; impl SimpleEdgeSetIntersector { @@ -19,27 +12,12 @@ impl SimpleEdgeSetIntersector { SimpleEdgeSetIntersector } - // JTS: - // JTS: /** - // JTS: * Performs a brute-force comparison of every segment in each Edge. - // JTS: * This has n^2 performance, and is about 100 times slower than using - // JTS: * monotone chains. - // JTS: */ - // JTS: private void computeIntersects(Edge e0, Edge e1, SegmentIntersector si) - // JTS: { fn compute_intersects( &mut self, edge0: &Rc>>, edge1: &Rc>>, segment_intersector: &mut SegmentIntersector, ) { - // JTS: Coordinate[] pts0 = e0.getCoordinates(); - // JTS: Coordinate[] pts1 = e1.getCoordinates(); - // JTS: for (int i0 = 0; i0 < pts0.length - 1; i0++) { - // JTS: for (int i1 = 0; i1 < pts1.length - 1; i1++) { - // JTS: si.addIntersections(e0, i0, e1, i1); - // JTS: } - // JTS: } let edge0_coords_len = edge0.borrow().coords().len() - 1; let edge1_coords_len = edge1.borrow().coords().len() - 1; for i0 in 0..edge0_coords_len { @@ -47,38 +25,16 @@ impl SimpleEdgeSetIntersector { segment_intersector.add_intersections(edge0, i0, edge1, i1); } } - // JTS: } } - // JTS: } } -// JTS: public class SimpleEdgeSetIntersector -// JTS: extends EdgeSetIntersector -// JTS: { impl EdgeSetIntersector for SimpleEdgeSetIntersector { - // JTS: // statistics information - // JTS: int nOverlaps; - // JTS: - // JTS: public SimpleEdgeSetIntersector() { - // JTS: } - // JTS: - // JTS: public void computeIntersections(List edges, SegmentIntersector si, boolean testAllSegments) - // JTS: { fn compute_intersections_within_set( &mut self, edges: &[Rc>>], check_for_self_intersecting_edges: bool, segment_intersector: &mut SegmentIntersector, ) { - // JTS: nOverlaps = 0; - // JTS: for (Iterator i0 = edges.iterator(); i0.hasNext(); ) { - // JTS: Edge edge0 = (Edge) i0.next(); - // JTS: for (Iterator i1 = edges.iterator(); i1.hasNext(); ) { - // JTS: Edge edge1 = (Edge) i1.next(); - // JTS: if (testAllSegments || edge0 != edge1) - // JTS: computeIntersects(edge0, edge1, si); - // JTS: } - // JTS: } for edge0 in edges.iter() { for edge1 in edges.iter() { if check_for_self_intersecting_edges || edge0.as_ptr() != edge1.as_ptr() { @@ -86,30 +42,18 @@ impl EdgeSetIntersector for SimpleEdgeSetIntersector { } } } - // JTS: } } - // JTS: public void computeIntersections(List edges0, List edges1, SegmentIntersector si) - // JTS: { fn compute_intersections_between_sets( &mut self, edges0: &[Rc>>], edges1: &[Rc>>], segment_intersector: &mut SegmentIntersector, ) { - // JTS: nOverlaps = 0; - // JTS: for (Iterator i0 = edges0.iterator(); i0.hasNext(); ) { - // JTS: Edge edge0 = (Edge) i0.next(); - // JTS: for (Iterator i1 = edges1.iterator(); i1.hasNext(); ) { - // JTS: Edge edge1 = (Edge) i1.next(); - // JTS: computeIntersects(edge0, edge1, si); - // JTS: } - // JTS: } for edge0 in edges0 { for edge1 in edges1 { self.compute_intersects(edge0, edge1, segment_intersector); } } - // JTS: } } } diff --git a/geo/src/algorithm/relate/geomgraph/intersection_matrix.rs b/geo/src/algorithm/relate/geomgraph/intersection_matrix.rs index 7b956f8cfd..cdf01e3a3b 100644 --- a/geo/src/algorithm/relate/geomgraph/intersection_matrix.rs +++ b/geo/src/algorithm/relate/geomgraph/intersection_matrix.rs @@ -1,49 +1,6 @@ use crate::algorithm::coordinate_position::CoordPos; use crate::algorithm::dimensions::Dimensions; -// JTS: /** -// JTS: * Models a Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix. -// JTS: * DE-9IM matrix values (such as "212FF1FF2") -// JTS: * specify the topological relationship between two {@link Geometry}s. -// JTS: * This class can also represent matrix patterns (such as "T*T******") -// JTS: * which are used for matching instances of DE-9IM matrices. -// JTS: *

-// JTS: * DE-9IM matrices are 3x3 matrices with integer entries. -// JTS: * The matrix indices {0,1,2} represent the topological locations -// JTS: * that occur in a geometry (Interior, Boundary, Exterior). -// JTS: * These are provided by the constants -// JTS: * {@link Location#INTERIOR}, {@link Location#BOUNDARY}, and {@link Location#EXTERIOR}. -// JTS: *

-// JTS: * When used to specify the topological relationship between two geometries, -// JTS: * the matrix entries represent the possible dimensions of each intersection: -// JTS: * {@link Dimension#A} = 2, {@link Dimension#L} = 1, {@link Dimension#P} = 0 and {@link Dimension#FALSE} = -1. -// JTS: * When used to represent a matrix pattern entries can have the additional values -// JTS: * {@link Dimension#TRUE} {"T") and {@link Dimension#DONTCARE} ("*"). -// JTS: *

-// JTS: * For a description of the DE-9IM and the spatial predicates derived from it, -// JTS: * see the following references: -// JTS: *

-// JTS: *

-// JTS: * Methods are provided to: -// JTS: *

    -// JTS: *
  • set and query the elements of the matrix in a convenient fashion -// JTS: *
  • convert to and from the standard string representation (specified in -// JTS: * SFS Section 2.1.13.2). -// JTS: *
  • test if a matrix matches a given pattern string. -// JTS: *
  • test if a matrix (possibly with geometry dimensions) matches a standard named spatial predicate -// JTS: *
-// JTS: * -// JTS: *@version 1.7 -// JTS: */ /// Models a *Dimensionally Extended Nine-Intersection Model (DE-9IM)* matrix. /// /// DE-9IM matrix values (such as "212FF1FF2") specify the topological relationship between @@ -64,7 +21,6 @@ use crate::algorithm::dimensions::Dimensions; /// - Wikipedia article on [DE-9IM](https://en.wikipedia.org/wiki/DE-9IM) /// /// This implementation is heavily based on that from the [JTS project](https://github.com/locationtech/jts/blob/master/modules/core/src/main/java/org/locationtech/jts/geom/IntersectionMatrix.java). -// JTS: public class IntersectionMatrix implements Cloneable { #[derive(PartialEq, Eq)] pub struct IntersectionMatrix(LocationArray>); @@ -138,148 +94,10 @@ impl std::fmt::Debug for IntersectionMatrix { } impl IntersectionMatrix { - // JTS: /** - // JTS: * Internal representation of this IntersectionMatrix. - // JTS: */ - // JTS: private int[][] matrix; - // JTS: - // JTS: /** - // JTS: * Creates an IntersectionMatrix with FALSE - // JTS: * dimension values. - // JTS: */ - // JTS: public IntersectionMatrix() { - // JTS: matrix = new int[3][3]; - // JTS: setAll(Dimension.FALSE); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Creates an IntersectionMatrix with the given dimension - // JTS: * symbols. - // JTS: * - // JTS: *@param elements a String of nine dimension symbols in row major order - // JTS: */ - // JTS: public IntersectionMatrix(String elements) { - // JTS: this(); - // JTS: set(elements); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Creates an IntersectionMatrix with the same elements as - // JTS: * other. - // JTS: * - // JTS: *@param other an IntersectionMatrix to copy - // JTS: */ - // JTS: public IntersectionMatrix(IntersectionMatrix other) { - // JTS: this(); - // JTS: matrix[Location.INTERIOR][Location.INTERIOR] = other.matrix[Location.INTERIOR][Location.INTERIOR]; - // JTS: matrix[Location.INTERIOR][Location.BOUNDARY] = other.matrix[Location.INTERIOR][Location.BOUNDARY]; - // JTS: matrix[Location.INTERIOR][Location.EXTERIOR] = other.matrix[Location.INTERIOR][Location.EXTERIOR]; - // JTS: matrix[Location.BOUNDARY][Location.INTERIOR] = other.matrix[Location.BOUNDARY][Location.INTERIOR]; - // JTS: matrix[Location.BOUNDARY][Location.BOUNDARY] = other.matrix[Location.BOUNDARY][Location.BOUNDARY]; - // JTS: matrix[Location.BOUNDARY][Location.EXTERIOR] = other.matrix[Location.BOUNDARY][Location.EXTERIOR]; - // JTS: matrix[Location.EXTERIOR][Location.INTERIOR] = other.matrix[Location.EXTERIOR][Location.INTERIOR]; - // JTS: matrix[Location.EXTERIOR][Location.BOUNDARY] = other.matrix[Location.EXTERIOR][Location.BOUNDARY]; - // JTS: matrix[Location.EXTERIOR][Location.EXTERIOR] = other.matrix[Location.EXTERIOR][Location.EXTERIOR]; - // JTS: } - pub fn empty() -> Self { IntersectionMatrix(LocationArray([LocationArray([Dimensions::Empty; 3]); 3])) } - // JTS: /** - // JTS: * Adds one matrix to another. - // JTS: * Addition is defined by taking the maximum dimension value of each position - // JTS: * in the summand matrices. - // JTS: * - // JTS: * @param im the matrix to add - // JTS: */ - // JTS: public void add(IntersectionMatrix im) - // JTS: { - // JTS: for (int i = 0; i < 3; i++) { - // JTS: for (int j = 0; j < 3; j++) { - // JTS: setAtLeast(i, j, im.get(i, j)); - // JTS: } - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests if the dimension value matches TRUE - // JTS: * (i.e. has value 0, 1, 2 or TRUE). - // JTS: * - // JTS: *@param actualDimensionValue a number that can be stored in the IntersectionMatrix - // JTS: * . Possible values are {TRUE, FALSE, DONTCARE, 0, 1, 2}. - // JTS: *@return true if the dimension value matches TRUE - // JTS: */ - // JTS: public static boolean isTrue(int actualDimensionValue) { - // JTS: if (actualDimensionValue >= 0 || actualDimensionValue == Dimension.TRUE) { - // JTS: return true; - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests if the dimension value satisfies the dimension symbol. - // JTS: * - // JTS: *@param actualDimensionValue a number that can be stored in the IntersectionMatrix - // JTS: * . Possible values are {TRUE, FALSE, DONTCARE, 0, 1, 2}. - // JTS: *@param requiredDimensionSymbol a character used in the string - // JTS: * representation of an IntersectionMatrix. Possible values - // JTS: * are {T, F, * , 0, 1, 2}. - // JTS: *@return true if the dimension symbol matches - // JTS: * the dimension value - // JTS: */ - // JTS: public static boolean matches(int actualDimensionValue, char requiredDimensionSymbol) { - // JTS: if (requiredDimensionSymbol == Dimension.SYM_DONTCARE) { - // JTS: return true; - // JTS: } - // JTS: if (requiredDimensionSymbol == Dimension.SYM_TRUE && (actualDimensionValue >= 0 || actualDimensionValue - // JTS: == Dimension.TRUE)) { - // JTS: return true; - // JTS: } - // JTS: if (requiredDimensionSymbol == Dimension.SYM_FALSE && actualDimensionValue == Dimension.FALSE) { - // JTS: return true; - // JTS: } - // JTS: if (requiredDimensionSymbol == Dimension.SYM_P && actualDimensionValue == Dimension.P) { - // JTS: return true; - // JTS: } - // JTS: if (requiredDimensionSymbol == Dimension.SYM_L && actualDimensionValue == Dimension.L) { - // JTS: return true; - // JTS: } - // JTS: if (requiredDimensionSymbol == Dimension.SYM_A && actualDimensionValue == Dimension.A) { - // JTS: return true; - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests if each of the actual dimension symbols in a matrix string satisfies the - // JTS: * corresponding required dimension symbol in a pattern string. - // JTS: * - // JTS: *@param actualDimensionSymbols nine dimension symbols to validate. - // JTS: * Possible values are {T, F, * , 0, 1, 2}. - // JTS: *@param requiredDimensionSymbols nine dimension symbols to validate - // JTS: * against. Possible values are {T, F, * , 0, 1, 2}. - // JTS: *@return true if each of the required dimension - // JTS: * symbols encompass the corresponding actual dimension symbol - // JTS: */ - // JTS: public static boolean matches(String actualDimensionSymbols, String requiredDimensionSymbols) { - // JTS: IntersectionMatrix m = new IntersectionMatrix(actualDimensionSymbols); - // JTS: return m.matches(requiredDimensionSymbols); - // JTS: } - // JTS: - // JTS: /** - // JTS: * Changes the value of one of this IntersectionMatrixs - // JTS: * elements. - // JTS: * - // JTS: *@param row the row of this IntersectionMatrix, - // JTS: * indicating the interior, boundary or exterior of the first Geometry - // JTS: *@param column the column of this IntersectionMatrix, - // JTS: * indicating the interior, boundary or exterior of the second Geometry - // JTS: *@param dimensionValue the new value of the element - // JTS: */ - // JTS: public void set(int row, int column, int dimensionValue) { - // JTS: matrix[row][column] = dimensionValue; - // JTS: } pub(crate) fn set( &mut self, position_a: CoordPos, @@ -289,38 +107,6 @@ impl IntersectionMatrix { self.0[position_a][position_b] = dimensionality; } - // JTS: /** - // JTS: * Changes the elements of this IntersectionMatrix to the - // JTS: * dimension symbols in dimensionSymbols. - // JTS: * - // JTS: *@param dimensionSymbols nine dimension symbols to which to set this IntersectionMatrix - // JTS: * s elements. Possible values are {T, F, * , 0, 1, 2} - // JTS: */ - // JTS: public void set(String dimensionSymbols) { - // JTS: for (int i = 0; i < dimensionSymbols.length(); i++) { - // JTS: int row = i / 3; - // JTS: int col = i % 3; - // JTS: matrix[row][col] = Dimension.toDimensionValue(dimensionSymbols.charAt(i)); - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Changes the specified element to minimumDimensionValue if the - // JTS: * element is less. - // JTS: * - // JTS: *@param row the row of this IntersectionMatrix - // JTS: * , indicating the interior, boundary or exterior of the first Geometry - // JTS: *@param column the column of this IntersectionMatrix - // JTS: * , indicating the interior, boundary or exterior of the second Geometry - // JTS: *@param minimumDimensionValue the dimension value with which to compare the - // JTS: * element. The order of dimension values from least to greatest is - // JTS: * {DONTCARE, TRUE, FALSE, 0, 1, 2}. - // JTS: */ - // JTS: public void setAtLeast(int row, int column, int minimumDimensionValue) { - // JTS: if (matrix[row][column] < minimumDimensionValue) { - // JTS: matrix[row][column] = minimumDimensionValue; - // JTS: } - // JTS: } pub(crate) fn set_at_least( &mut self, position_a: CoordPos, @@ -332,23 +118,6 @@ impl IntersectionMatrix { } } - // JTS: /** - // JTS: * If row >= 0 and column >= 0, changes the specified element to minimumDimensionValue - // JTS: * if the element is less. Does nothing if row <0 or column < 0. - // JTS: * - // JTS: *@param row the row of this IntersectionMatrix - // JTS: * , indicating the interior, boundary or exterior of the first Geometry - // JTS: *@param column the column of this IntersectionMatrix - // JTS: * , indicating the interior, boundary or exterior of the second Geometry - // JTS: *@param minimumDimensionValue the dimension value with which to compare the - // JTS: * element. The order of dimension values from least to greatest is - // JTS: * {DONTCARE, TRUE, FALSE, 0, 1, 2}. - // JTS: */ - // JTS: public void setAtLeastIfValid(int row, int column, int minimumDimensionValue) { - // JTS: if (row >= 0 && column >= 0) { - // JTS: setAtLeast(row, column, minimumDimensionValue); - // JTS: } - // JTS: } pub(crate) fn set_at_least_if_valid( &mut self, position_a: Option, @@ -362,23 +131,6 @@ impl IntersectionMatrix { } } - // JTS: /** - // JTS: * For each element in this IntersectionMatrix, changes the - // JTS: * element to the corresponding minimum dimension symbol if the element is - // JTS: * less. - // JTS: * - // JTS: *@param minimumDimensionSymbols nine dimension symbols with which to - // JTS: * compare the elements of this IntersectionMatrix. The - // JTS: * order of dimension values from least to greatest is {DONTCARE, TRUE, FALSE, 0, 1, 2} - // JTS: * . - // JTS: */ - // JTS: public void setAtLeast(String minimumDimensionSymbols) { - // JTS: for (int i = 0; i < minimumDimensionSymbols.length(); i++) { - // JTS: int row = i / 3; - // JTS: int col = i % 3; - // JTS: setAtLeast(row, col, Dimension.toDimensionValue(minimumDimensionSymbols.charAt(i))); - // JTS: } - // JTS: } pub(crate) fn set_at_least_from_string( &mut self, dimensions: &str, @@ -408,54 +160,6 @@ impl IntersectionMatrix { Ok(()) } - // JTS: - // JTS: /** - // JTS: * Changes the elements of this IntersectionMatrix to dimensionValue - // JTS: * . - // JTS: * - // JTS: *@param dimensionValue the dimension value to which to set this IntersectionMatrix - // JTS: * s elements. Possible values {TRUE, FALSE, DONTCARE, 0, 1, 2} - // JTS: * . - // JTS: */ - // JTS: public void setAll(int dimensionValue) { - // JTS: for (int ai = 0; ai < 3; ai++) { - // JTS: for (int bi = 0; bi < 3; bi++) { - // JTS: matrix[ai][bi] = dimensionValue; - // JTS: } - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns the value of one of this matrix - // JTS: * entries. - // JTS: * The value of the provided index is one of the - // JTS: * values from the {@link Location} class. - // JTS: * The value returned is a constant - // JTS: * from the {@link Dimension} class. - // JTS: * - // JTS: *@param row the row of this IntersectionMatrix, indicating - // JTS: * the interior, boundary or exterior of the first Geometry - // JTS: *@param column the column of this IntersectionMatrix, - // JTS: * indicating the interior, boundary or exterior of the second Geometry - // JTS: *@return the dimension value at the given matrix position. - // JTS: */ - // JTS: public int get(int row, int column) { - // JTS: return matrix[row][column]; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests if this matrix matches [FF*FF****]. - // JTS: * - // JTS: *@return true if the two Geometrys related by - // JTS: * this matrix are disjoint - // JTS: */ - // JTS: public boolean isDisjoint() { - // JTS: return - // JTS: matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.INTERIOR][Location.BOUNDARY] == Dimension.FALSE && - // JTS: matrix[Location.BOUNDARY][Location.INTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.BOUNDARY][Location.BOUNDARY] == Dimension.FALSE; - // JTS: } /// Tests if this matrix matches `[FF*FF****]`. /// /// returns `true` if the two geometries related by this matrix are disjoint @@ -466,16 +170,6 @@ impl IntersectionMatrix { && self.0[CoordPos::OnBoundary][CoordPos::OnBoundary] == Dimensions::Empty } - // JTS: - // JTS: /** - // JTS: * Tests if isDisjoint returns false. - // JTS: * - // JTS: *@return true if the two Geometrys related by - // JTS: * this matrix intersect - // JTS: */ - // JTS: public boolean isIntersects() { - // JTS: return ! isDisjoint(); - // JTS: } /// Tests if `is_disjoint` returns false. /// /// returns `true` if the two geometries related by this matrix intersect. @@ -483,89 +177,6 @@ impl IntersectionMatrix { !self.is_disjoint() } - // JTS: /** - // JTS: * Tests if this matrix matches - // JTS: * [FT*******], [F**T*****] or [F***T****]. - // JTS: * - // JTS: *@param dimensionOfGeometryA the dimension of the first Geometry - // JTS: *@param dimensionOfGeometryB the dimension of the second Geometry - // JTS: *@return true if the two Geometry - // JTS: * s related by this matrix touch; Returns false - // JTS: * if both Geometrys are points. - // JTS: */ - // JTS: public boolean isTouches(int dimensionOfGeometryA, int dimensionOfGeometryB) { - // JTS: if (dimensionOfGeometryA > dimensionOfGeometryB) { - // JTS: //no need to get transpose because pattern matrix is symmetrical - // JTS: return isTouches(dimensionOfGeometryB, dimensionOfGeometryA); - // JTS: } - // JTS: if ((dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A) || - // JTS: (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) || - // JTS: (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A) || - // JTS: (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) || - // JTS: (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L)) { - // JTS: return matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE && - // JTS: (isTrue(matrix[Location.INTERIOR][Location.BOUNDARY]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY])); - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether this geometry crosses the - // JTS: * specified geometry. - // JTS: *

- // JTS: * The crosses predicate has the following equivalent definitions: - // JTS: *

    - // JTS: *
  • The geometries have some but not all interior points in common. - // JTS: *
  • The DE-9IM Intersection Matrix for the two geometries matches - // JTS: *
      - // JTS: *
    • [T*T******] (for P/L, P/A, and L/A situations) - // JTS: *
    • [T*****T**] (for L/P, L/A, and A/L situations) - // JTS: *
    • [0********] (for L/L situations) - // JTS: *
    - // JTS: *
- // JTS: * For any other combination of dimensions this predicate returns false. - // JTS: *

- // JTS: * The SFS defined this predicate only for P/L, P/A, L/L, and L/A situations. - // JTS: * JTS extends the definition to apply to L/P, A/P and A/L situations as well. - // JTS: * This makes the relation symmetric. - // JTS: * - // JTS: *@param dimensionOfGeometryA the dimension of the first Geometry - // JTS: *@param dimensionOfGeometryB the dimension of the second Geometry - // JTS: *@return true if the two Geometrys - // JTS: * related by this matrix cross. - // JTS: */ - // JTS: public boolean isCrosses(int dimensionOfGeometryA, int dimensionOfGeometryB) { - // JTS: if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L) || - // JTS: (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) || - // JTS: (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A)) { - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) && - // JTS: isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]); - // JTS: } - // JTS: if ((dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.P) || - // JTS: (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.P) || - // JTS: (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.L)) { - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) && - // JTS: isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]); - // JTS: } - // JTS: if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) { - // JTS: return matrix[Location.INTERIOR][Location.INTERIOR] == 0; - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether this matrix matches [T*F**F***]. - // JTS: * - // JTS: *@return true if the first Geometry is within - // JTS: * the second - // JTS: */ - // JTS: public boolean isWithin() { - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) && - // JTS: matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE; - // JTS: } /// Tests whether this matrix matches `[T*F**F***]`. /// /// returns `true` if the first geometry is within the second. @@ -575,17 +186,6 @@ impl IntersectionMatrix { && self.0[CoordPos::OnBoundary][CoordPos::Outside] == Dimensions::Empty } - // JTS: /** - // JTS: * Tests whether this matrix matches [T*****FF*[. - // JTS: * - // JTS: *@return true if the first Geometry contains the - // JTS: * second - // JTS: */ - // JTS: public boolean isContains() { - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) && - // JTS: matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE; - // JTS: } /// Tests whether this matrix matches `[T*****FF*]`. /// /// returns `true` if the first geometry contains the second. @@ -594,167 +194,6 @@ impl IntersectionMatrix { && self.0[CoordPos::Outside][CoordPos::Inside] == Dimensions::Empty && self.0[CoordPos::Outside][CoordPos::OnBoundary] == Dimensions::Empty } - - // JTS: /** - // JTS: * Tests if this matrix matches - // JTS: * [T*****FF*] - // JTS: * or [*T****FF*] - // JTS: * or [***T**FF*] - // JTS: * or [****T*FF*] - // JTS: * - // JTS: *@return true if the first Geometry covers the - // JTS: * second - // JTS: */ - // JTS: public boolean isCovers() { - // JTS: boolean hasPointInCommon = - // JTS: isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) - // JTS: || isTrue(matrix[Location.INTERIOR][Location.BOUNDARY]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY]); - // JTS: - // JTS: return hasPointInCommon && - // JTS: matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE; - // JTS: } - // JTS: - // JTS: /** - // JTS: *Tests if this matrix matches - // JTS: * [T*F**F***] - // JTS: * or [*TF**F***] - // JTS: * or [**FT*F***] - // JTS: * or [**F*TF***] - // JTS: * - // JTS: *@return true if the first Geometry - // JTS: * is covered by the second - // JTS: */ - // JTS: public boolean isCoveredBy() { - // JTS: boolean hasPointInCommon = - // JTS: isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) - // JTS: || isTrue(matrix[Location.INTERIOR][Location.BOUNDARY]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR]) - // JTS: || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY]); - // JTS: - // JTS: return hasPointInCommon && - // JTS: matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether the argument dimensions are equal and - // JTS: * this matrix matches the pattern [T*F**FFF*]. - // JTS: *

- // JTS: * Note: This pattern differs from the one stated in - // JTS: * Simple feature access - Part 1: Common architecture. - // JTS: * That document states the pattern as [TFFFTFFFT]. This would - // JTS: * specify that - // JTS: * two identical POINTs are not equal, which is not desirable behaviour. - // JTS: * The pattern used here has been corrected to compute equality in this situation. - // JTS: * - // JTS: *@param dimensionOfGeometryA the dimension of the first Geometry - // JTS: *@param dimensionOfGeometryB the dimension of the second Geometry - // JTS: *@return true if the two Geometrys - // JTS: * related by this matrix are equal; the - // JTS: * Geometrys must have the same dimension to be equal - // JTS: */ - // JTS: public boolean isEquals(int dimensionOfGeometryA, int dimensionOfGeometryB) { - // JTS: if (dimensionOfGeometryA != dimensionOfGeometryB) { - // JTS: return false; - // JTS: } - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) && - // JTS: matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE && - // JTS: matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests if this matrix matches - // JTS: *

    - // JTS: *
  • [T*T***T**] (for two points or two surfaces) - // JTS: *
  • [1*T***T**] (for two curves) - // JTS: *
. - // JTS: * - // JTS: *@param dimensionOfGeometryA the dimension of the first Geometry - // JTS: *@param dimensionOfGeometryB the dimension of the second Geometry - // JTS: *@return true if the two Geometrys - // JTS: * related by this matrix overlap. For this - // JTS: * function to return true, the Geometrys must - // JTS: * be two points, two curves or two surfaces. - // JTS: */ - // JTS: public boolean isOverlaps(int dimensionOfGeometryA, int dimensionOfGeometryB) { - // JTS: if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.P) || - // JTS: (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A)) { - // JTS: return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) - // JTS: && isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]) - // JTS: && isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]); - // JTS: } - // JTS: if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) { - // JTS: return matrix[Location.INTERIOR][Location.INTERIOR] == 1 - // JTS: && isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]) - // JTS: && isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]); - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether this matrix matches the given matrix pattern. - // JTS: * - // JTS: *@param pattern A pattern containing nine dimension symbols with which to - // JTS: * compare the entries of this matrix. Possible - // JTS: * symbol values are {T, F, * , 0, 1, 2}. - // JTS: *@return true if this matrix matches the pattern - // JTS: */ - // JTS: public boolean matches(String pattern) { - // JTS: if (pattern.length() != 9) { - // JTS: throw new IllegalArgumentException("Should be length 9: " + pattern); - // JTS: } - // JTS: for (int ai = 0; ai < 3; ai++) { - // JTS: for (int bi = 0; bi < 3; bi++) { - // JTS: if (!matches(matrix[ai][bi], pattern.charAt(3 * ai + - // JTS: bi))) { - // JTS: return false; - // JTS: } - // JTS: } - // JTS: } - // JTS: return true; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Transposes this IntersectionMatrix. - // JTS: * - // JTS: *@return this IntersectionMatrix as a convenience - // JTS: */ - // JTS: public IntersectionMatrix transpose() { - // JTS: int temp = matrix[1][0]; - // JTS: matrix[1][0] = matrix[0][1]; - // JTS: matrix[0][1] = temp; - // JTS: temp = matrix[2][0]; - // JTS: matrix[2][0] = matrix[0][2]; - // JTS: matrix[0][2] = temp; - // JTS: temp = matrix[2][1]; - // JTS: matrix[2][1] = matrix[1][2]; - // JTS: matrix[1][2] = temp; - // JTS: return this; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns a nine-character String representation of this IntersectionMatrix - // JTS: * . - // JTS: * - // JTS: *@return the nine dimension symbols of this IntersectionMatrix - // JTS: * in row-major order. - // JTS: */ - // JTS: public String toString() { - // JTS: StringBuilder builder = new StringBuilder("123456789"); - // JTS: for (int ai = 0; ai < 3; ai++) { - // JTS: for (int bi = 0; bi < 3; bi++) { - // JTS: builder.setCharAt(3 * ai + bi, Dimension.toDimensionSymbol(matrix[ai][bi])); - // JTS: } - // JTS: } - // JTS: return builder.toString(); - // JTS: } - // JTS: } - // JTS: */ } impl std::str::FromStr for IntersectionMatrix { diff --git a/geo/src/algorithm/relate/geomgraph/label.rs b/geo/src/algorithm/relate/geomgraph/label.rs index 6a9b1064b7..f09831c01a 100644 --- a/geo/src/algorithm/relate/geomgraph/label.rs +++ b/geo/src/algorithm/relate/geomgraph/label.rs @@ -1,34 +1,7 @@ -// JTS: import org.locationtech.jts.geom.Location; use super::{CoordPos, Direction, TopologyPosition}; use std::fmt; -// JTS: -// JTS: /** -// JTS: * A Label indicates the topological relationship of a component -// JTS: * of a topology graph to a given Geometry. -// JTS: * This class supports labels for relationships to two Geometrys, -// JTS: * which is sufficient for algorithms for binary operations. -// JTS: *

-// JTS: * Topology graphs support the concept of labeling nodes and edges in the graph. -// JTS: * The label of a node or edge specifies its topological relationship to one or -// JTS: * more geometries. (In fact, since JTS operations have only two arguments labels -// JTS: * are required for only two geometries). A label for a node or edge has one or -// JTS: * two elements, depending on whether the node or edge occurs in one or both of the -// JTS: * input Geometrys. Elements contain attributes which categorize the -// JTS: * topological location of the node or edge relative to the parent -// JTS: * Geometry; that is, whether the node or edge is in the interior, -// JTS: * boundary or exterior of the Geometry. Attributes have a value -// JTS: * from the set {Interior, Boundary, Exterior}. In a node each -// JTS: * element has a single attribute <On>. For an edge each element has a -// JTS: * triplet of attributes <Left, On, Right>. -// JTS: *

-// JTS: * It is up to the client code to associate the 0 and 1 TopologyLocations -// JTS: * with specific geometries. -// JTS: * @version 1.7 -// JTS: * -// JTS: */ -// JTS: public class Label { /// A `Label` indicates the topological relationship of a node or edge of a topology graph to a given /// [`Geometry`]. /// @@ -57,28 +30,6 @@ impl fmt::Debug for Label { } impl Label { - // JTS: - // JTS: // converts a Label to a Line label (that is, one with no side Locations) - // JTS: public static Label toLineLabel(Label label) - // JTS: { - // JTS: Label lineLabel = new Label(Location.NONE); - // JTS: for (int i = 0; i < 2; i++) { - // JTS: lineLabel.setLocation(i, label.getLocation(i)); - // JTS: } - // JTS: return lineLabel; - // JTS: } - // JTS: - // JTS: TopologyLocation elt[] = new TopologyLocation[2]; - // JTS: - // JTS: /** - // JTS: * Construct a Label with a single location for both Geometries. - // JTS: * Initialize the locations to Null - // JTS: */ - // JTS: public Label(int onLoc) - // JTS: { - // JTS: elt[0] = new TopologyLocation(onLoc); - // JTS: elt[1] = new TopologyLocation(onLoc); - // JTS: } /// Construct an empty `Label` for relating a 1-D line or 0-D point to both geometries. pub fn empty_line_or_point() -> Label { Label { @@ -89,25 +40,6 @@ impl Label { } } - // JTS: /** - // JTS: * Construct a Label with a single location for both Geometries. - // JTS: * Initialize the location for the Geometry index. - // JTS: */ - // JTS: public Label(int geomIndex, int onLoc) - // JTS: { - // JTS: elt[0] = new TopologyLocation(Location.NONE); - // JTS: elt[1] = new TopologyLocation(Location.NONE); - // JTS: elt[geomIndex].setLocation(onLoc); - // JTS: } - // JTS: /** - // JTS: * Construct a Label with On, Left and Right locations for both Geometries. - // JTS: * Initialize the locations for both Geometries to the given values. - // JTS: */ - // JTS: public Label(int onLoc, int leftLoc, int rightLoc) - // JTS: { - // JTS: elt[0] = new TopologyLocation(onLoc, leftLoc, rightLoc); - // JTS: elt[1] = new TopologyLocation(onLoc, leftLoc, rightLoc); - // JTS: } /// Construct an empty `Label` for relating a 2-D area to both geometries. pub fn empty_area() -> Self { Self { @@ -118,16 +50,6 @@ impl Label { } } - // JTS: /** - // JTS: * Construct a Label with On, Left and Right locations for both Geometries. - // JTS: * Initialize the locations for the given Geometry index. - // JTS: */ - // JTS: public Label(int geomIndex, int onLoc, int leftLoc, int rightLoc) - // JTS: { - // JTS: elt[0] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE); - // JTS: elt[1] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE); - // JTS: elt[geomIndex].setLocations(onLoc, leftLoc, rightLoc); - // JTS: } /// Construct a `Label` initialized with `position` for the geometry specified by /// `geom_index`. /// @@ -141,94 +63,35 @@ impl Label { label } - // JTS: /** - // JTS: * Construct a Label with the same values as the argument Label. - // JTS: */ - // JTS: public Label(Label lbl) - // JTS: { - // JTS: elt[0] = new TopologyLocation(lbl.elt[0]); - // JTS: elt[1] = new TopologyLocation(lbl.elt[1]); - // JTS: } - - // JTS: public void flip() - // JTS: { - // JTS: elt[0].flip(); - // JTS: elt[1].flip(); - // JTS: } pub fn flip(&mut self) { self.geometry_topologies[0].flip(); self.geometry_topologies[1].flip(); } - // JTS: public int getLocation(int geomIndex, int posIndex) { return elt[geomIndex].get(posIndex); } pub fn position(&self, geom_index: usize, direction: Direction) -> Option { self.geometry_topologies[geom_index].get(direction) } - // JTS: public int getLocation(int geomIndex) { return elt[geomIndex].get(Position.ON); } pub fn on_position(&self, geom_index: usize) -> Option { self.geometry_topologies[geom_index].get(Direction::On) } - // JTS: public void setLocation(int geomIndex, int posIndex, int location) - // JTS: { - // JTS: elt[geomIndex].setLocation(posIndex, location); - // JTS: } pub fn set_position(&mut self, geom_index: usize, direction: Direction, position: CoordPos) { self.geometry_topologies[geom_index].set_position(direction, position); } - // JTS: public void setLocation(int geomIndex, int location) - // JTS: { - // JTS: elt[geomIndex].setLocation(Position.ON, location); - // JTS: } pub fn set_on_position(&mut self, geom_index: usize, position: CoordPos) { self.geometry_topologies[geom_index].set_position(Direction::On, position); } - // JTS: public void setAllLocations(int geomIndex, int location) - // JTS: { - // JTS: elt[geomIndex].setAllLocations(location); - // JTS: } pub fn set_all_positions(&mut self, geom_index: usize, position: CoordPos) { self.geometry_topologies[geom_index].set_all_positions(position) } - // JTS: public void setAllLocationsIfNull(int geomIndex, int location) - // JTS: { - // JTS: elt[geomIndex].setAllLocationsIfNull(location); - // JTS: } pub fn set_all_positions_if_empty(&mut self, geom_index: usize, postion: CoordPos) { self.geometry_topologies[geom_index].set_all_positions_if_empty(postion) } - // JTS: public void setAllLocationsIfNull(int location) - // JTS: { - // JTS: setAllLocationsIfNull(0, location); - // JTS: setAllLocationsIfNull(1, location); - // JTS: } - // JTS: /** - // JTS: * Merge this label with another one. - // JTS: * Merging updates any null attributes of this label with the attributes from lbl - // JTS: */ - // JTS: public void merge(Label lbl) - // JTS: { - // JTS: for (int i = 0; i < 2; i++) { - // JTS: if (elt[i] == null && lbl.elt[i] != null) { - // JTS: elt[i] = new TopologyLocation(lbl.elt[i]); - // JTS: } - // JTS: else { - // JTS: elt[i].merge(lbl.elt[i]); - // JTS: } - // JTS: } - // JTS: } - // JTS: public int getGeometryCount() - // JTS: { - // JTS: int count = 0; - // JTS: if (! elt[0].isNull()) count++; - // JTS: if (! elt[1].isNull()) count++; - // JTS: return count; - // JTS: } pub fn geometry_count(&self) -> usize { self.geometry_topologies .iter() @@ -236,19 +99,14 @@ impl Label { .count() } - // JTS: public boolean isNull(int geomIndex) { return elt[geomIndex].isNull(); } pub fn is_empty(&self, geom_index: usize) -> bool { self.geometry_topologies[geom_index].is_empty() } - // JTS: public boolean isAnyNull(int geomIndex) { return elt[geomIndex].isAnyNull(); } pub fn is_any_empty(&self, geom_index: usize) -> bool { self.geometry_topologies[geom_index].is_any_empty() } - // JTS: - // JTS: public boolean isArea() { return elt[0].isArea() || elt[1].isArea(); } - // JTS: public boolean isArea(int geomIndex) pub fn is_area(&self) -> bool { self.geometry_topologies[0].is_area() || self.geometry_topologies[1].is_area() } @@ -257,49 +115,7 @@ impl Label { self.geometry_topologies[geom_index].is_area() } - // JTS: { - // JTS: /* Testing - // JTS: if (elt[0].getLocations().length != elt[1].getLocations().length) { - // JTS: System.out.println(this); - // JTS: } - // JTS: */ - // JTS: return elt[geomIndex].isArea(); - // JTS: } - // JTS: public boolean isLine(int geomIndex) { return elt[geomIndex].isLine(); } pub fn is_line(&self, geom_index: usize) -> bool { self.geometry_topologies[geom_index].is_line() } - - // JTS: public boolean isEqualOnSide(Label lbl, int side) - // JTS: { - // JTS: return - // JTS: this.elt[0].isEqualOnSide(lbl.elt[0], side) - // JTS: && this.elt[1].isEqualOnSide(lbl.elt[1], side); - // JTS: } - // JTS: public boolean allPositionsEqual(int geomIndex, int loc) - // JTS: { - // JTS: return elt[geomIndex].allPositionsEqual(loc); - // JTS: } - // JTS: /** - // JTS: * Converts one GeometryLocation to a Line location - // JTS: */ - // JTS: public void toLine(int geomIndex) - // JTS: { - // JTS: if (elt[geomIndex].isArea()) - // JTS: elt[geomIndex] = new TopologyLocation(elt[geomIndex].location[0]); - // JTS: } - // JTS: public String toString() - // JTS: { - // JTS: StringBuffer buf = new StringBuffer(); - // JTS: if (elt[0] != null) { - // JTS: buf.append("A:"); - // JTS: buf.append(elt[0].toString()); - // JTS: } - // JTS: if (elt[1] != null) { - // JTS: buf.append(" B:"); - // JTS: buf.append(elt[1].toString()); - // JTS: } - // JTS: return buf.toString(); - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/line_intersector.rs b/geo/src/algorithm/relate/geomgraph/line_intersector.rs index 2620e78fec..bfd650c46f 100644 --- a/geo/src/algorithm/relate/geomgraph/line_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/line_intersector.rs @@ -1,359 +1,6 @@ -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.PrecisionModel; -// JTS: import org.locationtech.jts.io.WKTWriter; -// JTS: import org.locationtech.jts.util.Assert; pub(crate) use crate::algorithm::line_intersection::LineIntersection; use crate::{Coordinate, GeoFloat, Line}; -// JTS: /** -// JTS: * A LineIntersector is an algorithm that can both test whether -// JTS: * two line segments intersect and compute the intersection point(s) -// JTS: * if they do. -// JTS: *

-// JTS: * There are three possible outcomes when determining whether two line segments intersect: -// JTS: *

    -// JTS: *
  • {@link #NO_INTERSECTION} - the segments do not intersect -// JTS: *
  • {@link #POINT_INTERSECTION} - the segments intersect in a single point -// JTS: *
  • {@link #COLLINEAR_INTERSECTION} - the segments are collinear and they intersect in a line segment -// JTS: *
-// JTS: * For segments which intersect in a single point, the point may be either an endpoint -// JTS: * or in the interior of each segment. -// JTS: * If the point lies in the interior of both segments, -// JTS: * this is termed a proper intersection. -// JTS: * The method {@link #isProper()} test for this situation. -// JTS: *

-// JTS: * The intersection point(s) may be computed in a precise or non-precise manner. -// JTS: * Computing an intersection point precisely involves rounding it -// JTS: * via a supplied {@link PrecisionModel}. -// JTS: *

-// JTS: * LineIntersectors do not perform an initial envelope intersection test -// JTS: * to determine if the segments are disjoint. -// JTS: * This is because this class is likely to be used in a context where -// JTS: * envelope overlap is already known to occur (or be likely). -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public abstract class LineIntersector -// JTS: { - pub(crate) trait LineIntersector { - // JTS: /** - // JTS: * These are deprecated, due to ambiguous naming - // JTS: */ - // JTS: public final static int DONT_INTERSECT = 0; - // JTS: public final static int DO_INTERSECT = 1; - // JTS: public final static int COLLINEAR = 2; - // JTS: - // JTS: /** - // JTS: * Indicates that line segments do not intersect - // JTS: */ - // JTS: public final static int NO_INTERSECTION = 0; - // JTS: - // JTS: /** - // JTS: * Indicates that line segments intersect in a single point - // JTS: */ - // JTS: public final static int POINT_INTERSECTION = 1; - // JTS: - // JTS: /** - // JTS: * Indicates that line segments intersect in a line segment - // JTS: */ - // JTS: public final static int COLLINEAR_INTERSECTION = 2; - // JTS: - - // JTS: - // JTS: /** - // JTS: * This function is non-robust, since it may compute the square of large numbers. - // JTS: * Currently not sure how to improve this. - // JTS: */ - // JTS: public static double nonRobustComputeEdgeDistance( - // JTS: Coordinate p, - // JTS: Coordinate p1, - // JTS: Coordinate p2) - // JTS: { - // JTS: double dx = p.x - p1.x; - // JTS: double dy = p.y - p1.y; - // JTS: double dist = Math.sqrt(dx * dx + dy * dy); // dummy value - // JTS: Assert.isTrue(! (dist == 0.0 && ! p.equals(p1)), "Invalid distance calculation"); - // JTS: return dist; - // JTS: } - // JTS: - // JTS: protected int result; - // JTS: protected Coordinate[][] inputLines = new Coordinate[2][2]; - // JTS: protected Coordinate[] intPt = new Coordinate[2]; - // JTS: /** - // JTS: * The indexes of the endpoints of the intersection lines, in order along - // JTS: * the corresponding line - // JTS: */ - // JTS: protected int[][] intLineIndex; - // JTS: protected boolean isProper; - // JTS: protected Coordinate pa; - // JTS: protected Coordinate pb; - // JTS: /** - // JTS: * If makePrecise is true, computed intersection coordinates will be made precise - // JTS: * using Coordinate#makePrecise - // JTS: */ - // JTS: protected PrecisionModel precisionModel = null; - // JTS: //public int numIntersects = 0; - // JTS: - // JTS: public LineIntersector() { - // JTS: intPt[0] = new Coordinate(); - // JTS: intPt[1] = new Coordinate(); - // JTS: // alias the intersection points for ease of reference - // JTS: pa = intPt[0]; - // JTS: pb = intPt[1]; - // JTS: result = 0; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Force computed intersection to be rounded to a given precision model - // JTS: * @param precisionModel - // JTS: * @deprecated use setPrecisionModel instead - // JTS: */ - // JTS: public void setMakePrecise(PrecisionModel precisionModel) - // JTS: { - // JTS: this.precisionModel = precisionModel; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Force computed intersection to be rounded to a given precision model. - // JTS: * No getter is provided, because the precision model is not required to be specified. - // JTS: * @param precisionModel - // JTS: */ - // JTS: public void setPrecisionModel(PrecisionModel precisionModel) - // JTS: { - // JTS: this.precisionModel = precisionModel; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Gets an endpoint of an input segment. - // JTS: * - // JTS: * @param segmentIndex the index of the input segment (0 or 1) - // JTS: * @param ptIndex the index of the endpoint (0 or 1) - // JTS: * @return the specified endpoint - // JTS: */ - // JTS: public Coordinate getEndpoint(int segmentIndex, int ptIndex) - // JTS: { - // JTS: return inputLines[segmentIndex][ptIndex]; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Compute the intersection of a point p and the line p1-p2. - // JTS: * This function computes the boolean value of the hasIntersection test. - // JTS: * The actual value of the intersection (if there is one) - // JTS: * is equal to the value of p. - // JTS: */ - // JTS: public abstract void computeIntersection( - // JTS: Coordinate p, - // JTS: Coordinate p1, Coordinate p2); - // JTS: - // JTS: protected boolean isCollinear() { - // JTS: return result == COLLINEAR_INTERSECTION; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Computes the intersection of the lines p1-p2 and p3-p4. - // JTS: * This function computes both the boolean value of the hasIntersection test - // JTS: * and the (approximate) value of the intersection point itself (if there is one). - // JTS: */ - // JTS: public void computeIntersection( - // JTS: Coordinate p1, Coordinate p2, - // JTS: Coordinate p3, Coordinate p4) { fn compute_intersection(&mut self, l1: Line, l2: Line) -> Option>; - // JTS: inputLines[0][0] = p1; - // JTS: inputLines[0][1] = p2; - // JTS: inputLines[1][0] = p3; - // JTS: inputLines[1][1] = p4; - // JTS: result = computeIntersect(p1, p2, p3, p4); - // JTS: //numIntersects++; - // JTS: } - // JTS: - // JTS: protected abstract int computeIntersect( - // JTS: Coordinate p1, Coordinate p2, - // JTS: Coordinate q1, Coordinate q2); - // JTS: - // JTS: /* - // JTS: public String toString() { - // JTS: String str = inputLines[0][0] + "-" - // JTS: + inputLines[0][1] + " " - // JTS: + inputLines[1][0] + "-" - // JTS: + inputLines[1][1] + " : " - // JTS: + getTopologySummary(); - // JTS: return str; - // JTS: } - // JTS: */ - // JTS: - // JTS: public String toString() { - // JTS: return WKTWriter.toLineString(inputLines[0][0], inputLines[0][1]) + " - " - // JTS: + WKTWriter.toLineString(inputLines[1][0], inputLines[1][1]) - // JTS: + getTopologySummary(); - // JTS: } - // JTS: - // JTS: private String getTopologySummary() - // JTS: { - // JTS: StringBuilder catBuilder = new StringBuilder(); - // JTS: if (isEndPoint()) catBuilder.append(" endpoint"); - // JTS: if (isProper) catBuilder.append(" proper"); - // JTS: if (isCollinear()) catBuilder.append(" collinear"); - // JTS: return catBuilder.toString(); - // JTS: } - // JTS: - // JTS: protected boolean isEndPoint() { - // JTS: return hasIntersection() && !isProper; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether the input geometries intersect. - // JTS: * - // JTS: * @return true if the input geometries intersect - // JTS: */ - // JTS: public boolean hasIntersection() { - // JTS: return result != NO_INTERSECTION; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns the number of intersection points found. This will be either 0, 1 or 2. - // JTS: * - // JTS: * @return the number of intersection points found (0, 1, or 2) - // JTS: */ - // JTS: public int getIntersectionNum() { return result; } - - // JTS: - // JTS: /** - // JTS: * Returns the intIndex'th intersection point - // JTS: * - // JTS: * @param intIndex is 0 or 1 - // JTS: * - // JTS: * @return the intIndex'th intersection point - // JTS: */ - // JTS: public Coordinate getIntersection(int intIndex) { return intPt[intIndex]; } - - // JTS: - // JTS: protected void computeIntLineIndex() { - // JTS: if (intLineIndex == null) { - // JTS: intLineIndex = new int[2][2]; - // JTS: computeIntLineIndex(0); - // JTS: computeIntLineIndex(1); - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Test whether a point is a intersection point of two line segments. - // JTS: * Note that if the intersection is a line segment, this method only tests for - // JTS: * equality with the endpoints of the intersection segment. - // JTS: * It does not return true if - // JTS: * the input point is internal to the intersection segment. - // JTS: * - // JTS: * @return true if the input point is one of the intersection points. - // JTS: */ - // JTS: public boolean isIntersection(Coordinate pt) { - // JTS: for (int i = 0; i < result; i++) { - // JTS: if (intPt[i].equals2D(pt)) { - // JTS: return true; - // JTS: } - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether either intersection point is an interior point of one of the input segments. - // JTS: * - // JTS: * @return true if either intersection point is in the interior of one of the input segments - // JTS: */ - // JTS: public boolean isInteriorIntersection() - // JTS: { - // JTS: if (isInteriorIntersection(0)) return true; - // JTS: if (isInteriorIntersection(1)) return true; - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether either intersection point is an interior point of the specified input segment. - // JTS: * - // JTS: * @return true if either intersection point is in the interior of the input segment - // JTS: */ - // JTS: public boolean isInteriorIntersection(int inputLineIndex) - // JTS: { - // JTS: for (int i = 0; i < result; i++) { - // JTS: if (! ( intPt[i].equals2D(inputLines[inputLineIndex][0]) - // JTS: || intPt[i].equals2D(inputLines[inputLineIndex][1]) )) { - // JTS: return true; - // JTS: } - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Tests whether an intersection is proper. - // JTS: *
- // JTS: * The intersection between two line segments is considered proper if - // JTS: * they intersect in a single point in the interior of both segments - // JTS: * (e.g. the intersection is a single point and is not equal to any of the - // JTS: * endpoints). - // JTS: *

- // JTS: * The intersection between a point and a line segment is considered proper - // JTS: * if the point lies in the interior of the segment (e.g. is not equal to - // JTS: * either of the endpoints). - // JTS: * - // JTS: * @return true if the intersection is proper - // JTS: */ - // JTS: public boolean isProper() { - // JTS: return hasIntersection() && isProper; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Computes the intIndex'th intersection point in the direction of - // JTS: * a specified input line segment - // JTS: * - // JTS: * @param segmentIndex is 0 or 1 - // JTS: * @param intIndex is 0 or 1 - // JTS: * - // JTS: * @return the intIndex'th intersection point in the direction of the specified input line segment - // JTS: */ - // JTS: public Coordinate getIntersectionAlongSegment(int segmentIndex, int intIndex) { - // JTS: // lazily compute int line array - // JTS: computeIntLineIndex(); - // JTS: return intPt[intLineIndex[segmentIndex][intIndex]]; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Computes the index (order) of the intIndex'th intersection point in the direction of - // JTS: * a specified input line segment - // JTS: * - // JTS: * @param segmentIndex is 0 or 1 - // JTS: * @param intIndex is 0 or 1 - // JTS: * - // JTS: * @return the index of the intersection point along the input segment (0 or 1) - // JTS: */ - // JTS: public int getIndexAlongSegment(int segmentIndex, int intIndex) { - // JTS: computeIntLineIndex(); - // JTS: return intLineIndex[segmentIndex][intIndex]; - // JTS: } - // JTS: - // JTS: protected void computeIntLineIndex(int segmentIndex) { - // JTS: double dist0 = getEdgeDistance(segmentIndex, 0); - // JTS: double dist1 = getEdgeDistance(segmentIndex, 1); - // JTS: if (dist0 > dist1) { - // JTS: intLineIndex[segmentIndex][0] = 0; - // JTS: intLineIndex[segmentIndex][1] = 1; - // JTS: } - // JTS: else { - // JTS: intLineIndex[segmentIndex][0] = 1; - // JTS: intLineIndex[segmentIndex][1] = 0; - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Computes the "edge distance" of an intersection point along the specified input line segment. - // JTS: * - // JTS: * @param segmentIndex is 0 or 1 - // JTS: * @param intIndex is 0 or 1 - // JTS: * - // JTS: * @return the edge distance of the intersection point - // JTS: */ - // JTS: public double getEdgeDistance(int segmentIndex, int intIndex) { - // JTS: double dist = computeEdgeDistance(intPt[intIndex], inputLines[segmentIndex][0], - // JTS: inputLines[segmentIndex][1]); - // JTS: return dist; - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/node.rs b/geo/src/algorithm/relate/geomgraph/node.rs index ae03ccb970..0384ecf2f1 100644 --- a/geo/src/algorithm/relate/geomgraph/node.rs +++ b/geo/src/algorithm/relate/geomgraph/node.rs @@ -1,15 +1,6 @@ -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.IntersectionMatrix; -// JTS: import org.locationtech.jts.geom.Location; use super::{CoordPos, Dimensions, EdgeEnd, EdgeEndBundleStar, IntersectionMatrix, Label}; use crate::{Coordinate, GeoFloat}; -// JTS: /** -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class Node -// JTS: extends GraphComponent -// JTS: { #[derive(Debug, Clone)] pub(crate) struct CoordNode where @@ -37,22 +28,6 @@ impl CoordNode where F: GeoFloat, { - // JTS: protected Coordinate coord; // only non-null if this node is precise - // JTS: public void add(EdgeEnd e) - // JTS: { - // JTS: // Assert: start pt of e is equal to node point - // JTS: edges.insert(e); - // JTS: e.setNode(this); - // JTS: } - - // JTS: protected EdgeEndStar edges; - // JTS: - // JTS: public Node(Coordinate coord, EdgeEndStar edges) - // JTS: { - // JTS: this.coord = coord; - // JTS: this.edges = edges; - // JTS: label = new Label(0, Location.NONE); - // JTS: } pub fn new(coordinate: Coordinate) -> CoordNode { CoordNode { coordinate, @@ -60,97 +35,14 @@ where } } - // JTS: public Coordinate getCoordinate() { return coord; } pub fn coordinate(&self) -> &Coordinate { &self.coordinate } - // JTS: public EdgeEndStar getEdges() { return edges; } - - // JTS: - // JTS: /** - // JTS: * Tests whether any incident edge is flagged as - // JTS: * being in the result. - // JTS: * This test can be used to determine if the node is in the result, - // JTS: * since if any incident edge is in the result, the node must be in the result as well. - // JTS: * - // JTS: * @return true if any incident edge in the in the result - // JTS: */ - // JTS: public boolean isIncidentEdgeInResult() - // JTS: { - // JTS: for (Iterator it = getEdges().getEdges().iterator(); it.hasNext(); ) { - // JTS: DirectedEdge de = (DirectedEdge) it.next(); - // JTS: if (de.getEdge().isInResult()) - // JTS: return true; - // JTS: } - // JTS: return false; - // JTS: } - // JTS: - // JTS: public boolean isIsolated() - // JTS: { - // JTS: return (label.getGeometryCount() == 1); - // JTS: } - // JTS: /** - // JTS: * Basic nodes do not compute IMs - // JTS: */ - // JTS: protected void computeIM(IntersectionMatrix im) {} - // JTS: /** - // JTS: * Add the edge to the list of edges at this node - // JTS: */ - // JTS: public void mergeLabel(Node n) - // JTS: { - // JTS: mergeLabel(n.label); - // JTS: } - // JTS: - // JTS: /** - // JTS: * To merge labels for two nodes, - // JTS: * the merged location for each LabelElement is computed. - // JTS: * The location for the corresponding node LabelElement is set to the result, - // JTS: * as long as the location is non-null. - // JTS: */ - // JTS: - // JTS: public void mergeLabel(Label label2) - // JTS: { - // JTS: for (int i = 0; i < 2; i++) { - // JTS: int loc = computeMergedLocation(label2, i); - // JTS: int thisLoc = label.getLocation(i); - // JTS: if (thisLoc == Location.NONE) label.setLocation(i, loc); - // JTS: } - // JTS: } - // JTS: - // JTS: public void setLabel(int argIndex, int onLocation) - // JTS: { - // JTS: if (label == null) { - // JTS: label = new Label(argIndex, onLocation); - // JTS: } - // JTS: else - // JTS: label.setLocation(argIndex, onLocation); - // JTS: } pub fn set_label_on_position(&mut self, geom_index: usize, position: CoordPos) { self.label.set_on_position(geom_index, position) } - // JTS: /** - // JTS: * Updates the label of a node to BOUNDARY, - // JTS: * obeying the mod-2 boundaryDetermination rule. - // JTS: */ - // JTS: public void setLabelBoundary(int argIndex) - // JTS: { - // JTS: if (label == null) return; - // JTS: - // JTS: // determine the current location for the point (if any) - // JTS: int loc = Location.NONE; - // JTS: if (label != null) - // JTS: loc = label.getLocation(argIndex); - // JTS: // flip the loc - // JTS: int newLoc; - // JTS: switch (loc) { - // JTS: case Location.BOUNDARY: newLoc = Location.INTERIOR; break; - // JTS: case Location.INTERIOR: newLoc = Location.BOUNDARY; break; - // JTS: default: newLoc = Location.BOUNDARY; break; - // JTS: } - // JTS: label.setLocation(argIndex, newLoc); - // JTS: } /// Updates the label of a node to BOUNDARY, obeying the mod-2 rule. pub fn set_label_boundary(&mut self, geom_index: usize) { let new_position = match self.label.on_position(geom_index) { @@ -160,45 +52,11 @@ where }; self.label.set_on_position(geom_index, new_position); } - - // JTS: - // JTS: /** - // JTS: * The location for a given eltIndex for a node will be one - // JTS: * of { null, INTERIOR, BOUNDARY }. - // JTS: * A node may be on both the boundary and the interior of a geometry; - // JTS: * in this case, the rule is that the node is considered to be in the boundary. - // JTS: * The merged location is the maximum of the two input values. - // JTS: */ - // JTS: int computeMergedLocation(Label label2, int eltIndex) - // JTS: { - // JTS: int loc = Location.NONE; - // JTS: loc = label.getLocation(eltIndex); - // JTS: if (! label2.isNull(eltIndex)) { - // JTS: int nLoc = label2.getLocation(eltIndex); - // JTS: if (loc != Location.BOUNDARY) loc = nLoc; - // JTS: } - // JTS: return loc; - // JTS: } - // JTS: - // JTS: public void print(PrintStream out) - // JTS: { - // JTS: out.println("node " + coord + " lbl: " + label); - // JTS: } - // JTS: } } impl CoordNode { // from JTS#GraphComponent - seems like only node uses this impl, so implementing it directly // onto node rather than the GraphComponent trait - // JTS: /** - // JTS: * Update the IM with the contribution for this component. - // JTS: * A component only contributes if it has a labelling for both parent geometries - // JTS: */ - // JTS: public void updateIM(IntersectionMatrix im) - // JTS: { - // JTS: Assert.isTrue(label.getGeometryCount() >= 2, "found partial label"); - // JTS: computeIM(im); - // JTS: } pub fn update_intersection_matrix(&self, intersection_matrix: &mut IntersectionMatrix) { assert!(self.label.geometry_count() >= 2, "found partial label"); intersection_matrix.set_at_least_if_valid( @@ -213,20 +71,4 @@ impl CoordNode { } // from JTS#RelateNode, which we've squashed into the base Node class to avoid wrestling OO hierarchies into rust. - // JTS: /** - // JTS: * Update the IM with the contribution for this component. - // JTS: * A component only contributes if it has a labelling for both parent geometries - // JTS: */ - // JTS: protected void computeIM(IntersectionMatrix im) - // JTS: { - // JTS: im.setAtLeastIfValid(label.getLocation(0), label.getLocation(1), 0); - // JTS: } - // JTS: /** - // JTS: * Update the IM with the contribution for the EdgeEnds incident on this node. - // JTS: */ - // JTS: void updateIMFromEdges(IntersectionMatrix im) - // JTS: { - // JTS: ((EdgeEndBundleStar) edges).updateIM(im); - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/node_map.rs b/geo/src/algorithm/relate/geomgraph/node_map.rs index 766d6ecdd9..885c64cfc2 100644 --- a/geo/src/algorithm/relate/geomgraph/node_map.rs +++ b/geo/src/algorithm/relate/geomgraph/node_map.rs @@ -5,14 +5,6 @@ use std::collections::BTreeMap; use std::fmt; use std::marker::PhantomData; -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.Location; -// JTS: -// JTS: /** -// JTS: * A map of nodes, indexed by the coordinate of the node -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class NodeMap /// A map of nodes, indexed by the coordinate of the node pub(crate) struct NodeMap where @@ -77,42 +69,12 @@ where F: GeoFloat, NF: NodeFactory, { - // JTS: { - // JTS: //Map nodeMap = new HashMap(); - // JTS: Map nodeMap = new TreeMap(); - // JTS: NodeFactory nodeFact; - // JTS: - // JTS: public NodeMap(NodeFactory nodeFact) { - // JTS: this.nodeFact = nodeFact; - // JTS: } pub fn new() -> Self { NodeMap { map: BTreeMap::new(), _node_factory: PhantomData, } } - // JTS: - // JTS: /** - // JTS: * Factory function - subclasses can override to create their own types of nodes - // JTS: */ - // JTS: /* - // JTS: protected Node createNode(Coordinate coord) - // JTS: { - // JTS: return new Node(coord); - // JTS: } - // JTS: */ - // JTS: /** - // JTS: * This method expects that a node has a coordinate value. - // JTS: */ - // JTS: public Node addNode(Coordinate coord) - // JTS: { - // JTS: Node node = (Node) nodeMap.get(coord); - // JTS: if (node == null) { - // JTS: node = nodeFact.createNode(coord); - // JTS: nodeMap.put(coord, node); - // JTS: } - // JTS: return node; - // JTS: } /// Adds a `NF::Node` with the given `Coordinate`. /// /// Note: Coordinates must be non-NaN. @@ -127,41 +89,11 @@ where .or_insert_with(|| NF::create_node(coord)) } - // JTS: public Node addNode(Node n) - // JTS: { - // JTS: Node node = (Node) nodeMap.get(n.getCoordinate()); - // JTS: if (node == null) { - // JTS: nodeMap.put(n.getCoordinate(), n); - // JTS: return n; - // JTS: } - // JTS: node.mergeLabel(n); - // JTS: return node; - // JTS: } - - // JTS: * Adds a node for the start point of this EdgeEnd - // JTS: * (if one does not already exist in this map). - // JTS: * Adds the EdgeEnd to the (possibly new) node. - // JTS: */ - // JTS: public void add(EdgeEnd e) - // JTS: { - // JTS: Coordinate p = e.getCoordinate(); - // JTS: Node n = addNode(p); - // JTS: n.add(e); - // JTS: } - - // JTS: /** - // JTS: * @return the node if found; null otherwise - // JTS: */ - // JTS: public Node find(Coordinate coord) { return (Node) nodeMap.get(coord); } /// returns the `NF::Node`, if any, matching `coord` pub fn find(&self, coord: Coordinate) -> Option<&NF::Node> { self.map.get(&NodeKey(coord)) } - // JTS: public Iterator iterator() - // JTS: { - // JTS: return nodeMap.values().iterator(); - // JTS: } /// Iterates across `NF::Node`s in lexical order of their `Coordinate` pub fn iter(&self) -> impl Iterator { self.map.values() @@ -176,30 +108,4 @@ where pub fn into_iter(self) -> impl Iterator { self.map.into_iter().map(|(_k, v)| v) } - - // JTS: public Collection values() - // JTS: { - // JTS: return nodeMap.values(); - // JTS: } - - // JTS: public Collection getBoundaryNodes(int geomIndex) - // JTS: { - // JTS: Collection bdyNodes = new ArrayList(); - // JTS: for (Iterator i = iterator(); i.hasNext(); ) { - // JTS: Node node = (Node) i.next(); - // JTS: if (node.getLabel().getLocation(geomIndex) == Location.BOUNDARY) - // JTS: bdyNodes.add(node); - // JTS: } - // JTS: return bdyNodes; - // JTS: } - // JTS: - // JTS: public void print(PrintStream out) - // JTS: { - // JTS: for (Iterator it = iterator(); it.hasNext(); ) - // JTS: { - // JTS: Node n = (Node) it.next(); - // JTS: n.print(out); - // JTS: } - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/planar_graph.rs b/geo/src/algorithm/relate/geomgraph/planar_graph.rs index 63d3a13407..7643a08e96 100644 --- a/geo/src/algorithm/relate/geomgraph/planar_graph.rs +++ b/geo/src/algorithm/relate/geomgraph/planar_graph.rs @@ -7,31 +7,6 @@ use crate::{Coordinate, GeoFloat}; use std::cell::RefCell; use std::rc::Rc; -// JTS: import org.locationtech.jts.algorithm.Orientation; -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.Location; -// JTS: -// JTS: /** -// JTS: * The computation of the IntersectionMatrix relies on the use of a structure -// JTS: * called a "topology graph". The topology graph contains nodes and edges -// JTS: * corresponding to the nodes and line segments of a Geometry. Each -// JTS: * node and edge in the graph is labeled with its topological location relative to -// JTS: * the source geometry. -// JTS: *

-// JTS: * Note that there is no requirement that points of self-intersection be a vertex. -// JTS: * Thus to obtain a correct topology graph, Geometrys must be -// JTS: * self-noded before constructing their graphs. -// JTS: *

-// JTS: * Two fundamental operations are supported by topology graphs: -// JTS: *

    -// JTS: *
  • Computing the intersections between all the edges and nodes of a single graph -// JTS: *
  • Computing the intersections between the edges and nodes of two different graphs -// JTS: *
-// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class PlanarGraph -// JTS: { pub(crate) struct PlanarGraphNode; /// The basic node constructor does not allow for incident edges @@ -51,33 +26,10 @@ pub(crate) struct PlanarGraph { } impl PlanarGraph { - // JTS: /** - // JTS: * For nodes in the Collection, link the DirectedEdges at the node that are in the result. - // JTS: * This allows clients to link only a subset of nodes in the graph, for - // JTS: * efficiency (because they know that only a subset is of interest). - // JTS: */ - // JTS: public static void linkResultDirectedEdges(Collection nodes) - // JTS: { - // JTS: for (Iterator nodeit = nodes.iterator(); nodeit.hasNext(); ) { - // JTS: Node node = (Node) nodeit.next(); - // JTS: ((DirectedEdgeStar) node.getEdges()).linkResultDirectedEdges(); - // JTS: } - // JTS: } - // JTS: - // JTS: protected List edges = new ArrayList(); pub fn edges(&self) -> &[Rc>>] { &self.edges } - // JTS: protected NodeMap nodes; - // JTS: protected List edgeEndList = new ArrayList(); - // JTS: - // JTS: public PlanarGraph(NodeFactory nodeFact) { - // JTS: nodes = new NodeMap(nodeFact); - // JTS: } - // JTS: public PlanarGraph() { - // JTS: nodes = new NodeMap(new NodeFactory()); - // JTS: } pub fn new() -> Self { PlanarGraph { nodes: NodeMap::new(), @@ -85,17 +37,6 @@ impl PlanarGraph { } } - // JTS: public Iterator getEdgeIterator() { return edges.iterator(); } - // JTS: public Collection getEdgeEnds() { return edgeEndList; } - - // JTS: public boolean isBoundaryNode(int geomIndex, Coordinate coord) - // JTS: { - // JTS: Node node = nodes.find(coord); - // JTS: if (node == null) return false; - // JTS: Label label = node.getLabel(); - // JTS: if (label != null && label.getLocation(geomIndex) == Location.BOUNDARY) return true; - // JTS: return false; - // JTS: } pub fn is_boundary_node(&self, geom_index: usize, coord: Coordinate) -> bool { self.nodes .find(coord) @@ -104,24 +45,10 @@ impl PlanarGraph { .unwrap_or(false) } - // JTS: protected void insertEdge(Edge e) - // JTS: { - // JTS: edges.add(e); - // JTS: } pub fn insert_edge(&mut self, edge: Edge) { self.edges.push(Rc::new(RefCell::new(edge))); } - // JTS: public void add(EdgeEnd e) - // JTS: { - // JTS: nodes.add(e); - // JTS: edgeEndList.add(e); - // JTS: } - // JTS: - // JTS: public Iterator getNodeIterator() { return nodes.iterator(); } - // JTS: public Collection getNodes() { return nodes.values(); } - // JTS: public Node addNode(Node node) { return nodes.addNode(node); } - // JTS: public Node addNode(Coordinate coord) { return nodes.addNode(coord); } pub fn add_node_with_coordinate(&mut self, coord: Coordinate) -> &mut CoordNode { self.nodes.insert_node_with_coordinate(coord) } @@ -134,146 +61,4 @@ impl PlanarGraph { ) }) } - - // JTS: /** - // JTS: * @return the node if found; null otherwise - // JTS: */ - // JTS: public Node find(Coordinate coord) { return nodes.find(coord); } - // JTS: - // JTS: /** - // JTS: * Add a set of edges to the graph. For each edge two DirectedEdges - // JTS: * will be created. DirectedEdges are NOT linked by this method. - // JTS: */ - // JTS: public void addEdges(List edgesToAdd) - // JTS: { - // JTS: // create all the nodes for the edges - // JTS: for (Iterator it = edgesToAdd.iterator(); it.hasNext(); ) { - // JTS: Edge e = (Edge) it.next(); - // JTS: edges.add(e); - // JTS: - // JTS: DirectedEdge de1 = new DirectedEdge(e, true); - // JTS: DirectedEdge de2 = new DirectedEdge(e, false); - // JTS: de1.setSym(de2); - // JTS: de2.setSym(de1); - // JTS: - // JTS: add(de1); - // JTS: add(de2); - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Link the DirectedEdges at the nodes of the graph. - // JTS: * This allows clients to link only a subset of nodes in the graph, for - // JTS: * efficiency (because they know that only a subset is of interest). - // JTS: */ - // JTS: public void linkResultDirectedEdges() - // JTS: { - // JTS: for (Iterator nodeit = nodes.iterator(); nodeit.hasNext(); ) { - // JTS: Node node = (Node) nodeit.next(); - // JTS: ((DirectedEdgeStar) node.getEdges()).linkResultDirectedEdges(); - // JTS: } - // JTS: } - // JTS: /** - // JTS: * Link the DirectedEdges at the nodes of the graph. - // JTS: * This allows clients to link only a subset of nodes in the graph, for - // JTS: * efficiency (because they know that only a subset is of interest). - // JTS: */ - // JTS: public void linkAllDirectedEdges() - // JTS: { - // JTS: for (Iterator nodeit = nodes.iterator(); nodeit.hasNext(); ) { - // JTS: Node node = (Node) nodeit.next(); - // JTS: ((DirectedEdgeStar) node.getEdges()).linkAllDirectedEdges(); - // JTS: } - // JTS: } - // JTS: /** - // JTS: * Returns the EdgeEnd which has edge e as its base edge - // JTS: * (MD 18 Feb 2002 - this should return a pair of edges) - // JTS: * - // JTS: * @return the edge, if found - // JTS: * null if the edge was not found - // JTS: */ - // JTS: public EdgeEnd findEdgeEnd(Edge e) - // JTS: { - // JTS: for (Iterator i = getEdgeEnds().iterator(); i.hasNext(); ) { - // JTS: EdgeEnd ee = (EdgeEnd) i.next(); - // JTS: if (ee.getEdge() == e) - // JTS: return ee; - // JTS: } - // JTS: return null; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns the edge whose first two coordinates are p0 and p1 - // JTS: * - // JTS: * @return the edge, if found - // JTS: * null if the edge was not found - // JTS: */ - // JTS: public Edge findEdge(Coordinate p0, Coordinate p1) - // JTS: { - // JTS: for (int i = 0; i < edges.size(); i++) { - // JTS: Edge e = (Edge) edges.get(i); - // JTS: Coordinate[] eCoord = e.getCoordinates(); - // JTS: if (p0.equals(eCoord[0]) && p1.equals(eCoord[1]) ) - // JTS: return e; - // JTS: } - // JTS: return null; - // JTS: } - // JTS: /** - // JTS: * Returns the edge which starts at p0 and whose first segment is - // JTS: * parallel to p1 - // JTS: * - // JTS: * @return the edge, if found - // JTS: * null if the edge was not found - // JTS: */ - // JTS: public Edge findEdgeInSameDirection(Coordinate p0, Coordinate p1) - // JTS: { - // JTS: for (int i = 0; i < edges.size(); i++) { - // JTS: Edge e = (Edge) edges.get(i); - // JTS: - // JTS: Coordinate[] eCoord = e.getCoordinates(); - // JTS: if (matchInSameDirection(p0, p1, eCoord[0], eCoord[1]) ) - // JTS: return e; - // JTS: - // JTS: if (matchInSameDirection(p0, p1, eCoord[eCoord.length - 1], eCoord[eCoord.length - 2]) ) - // JTS: return e; - // JTS: } - // JTS: return null; - // JTS: } - // JTS: - // JTS: /** - // JTS: * The coordinate pairs match if they define line segments lying in the same direction. - // JTS: * E.g. the segments are parallel and in the same quadrant - // JTS: * (as opposed to parallel and opposite!). - // JTS: */ - // JTS: private boolean matchInSameDirection(Coordinate p0, Coordinate p1, Coordinate ep0, Coordinate ep1) - // JTS: { - // JTS: if (! p0.equals(ep0)) - // JTS: return false; - // JTS: - // JTS: if (Orientation.index(p0, p1, ep1) == Orientation.COLLINEAR - // JTS: && Quadrant.quadrant(p0, p1) == Quadrant.quadrant(ep0, ep1) ) - // JTS: return true; - // JTS: return false; - // JTS: } - // JTS: - // JTS: public void printEdges(PrintStream out) - // JTS: { - // JTS: out.println("Edges:"); - // JTS: for (int i = 0; i < edges.size(); i++) { - // JTS: out.println("edge " + i + ":"); - // JTS: Edge e = (Edge) edges.get(i); - // JTS: e.print(out); - // JTS: e.eiList.print(out); - // JTS: } - // JTS: } - // JTS: void debugPrint(Object o) - // JTS: { - // JTS: System.out.print(o); - // JTS: } - // JTS: void debugPrintln(Object o) - // JTS: { - // JTS: System.out.println(o); - // JTS: } - // JTS: - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/quadrant.rs b/geo/src/algorithm/relate/geomgraph/quadrant.rs index a23019963a..9b74f94bca 100644 --- a/geo/src/algorithm/relate/geomgraph/quadrant.rs +++ b/geo/src/algorithm/relate/geomgraph/quadrant.rs @@ -1,21 +1,5 @@ use crate::GeoNum; -// JTS: /** -// JTS: * Utility functions for working with quadrants, which are numbered as follows: -// JTS: *
-// JTS:  * 1 | 0
-// JTS:  * --+--
-// JTS:  * 2 | 3
-// JTS:  * 
-// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class Quadrant -// JTS: { -// JTS: public static final int NE = 0; -// JTS: public static final int NW = 1; -// JTS: public static final int SW = 2; -// JTS: public static final int SE = 3; /// Utility functions for working with quadrants of the cartesian plane, /// which are labeled as follows: /// (+) @@ -32,41 +16,17 @@ pub enum Quadrant { } impl Quadrant { - // JTS: - // JTS: /** - // JTS: * Returns the quadrant of a directed line segment (specified as x and y - // JTS: * displacements, which cannot both be 0). - // JTS: * - // JTS: * @throws IllegalArgumentException if the displacements are both 0 - // JTS: */ - // JTS: public static int quadrant(double dx, double dy) - // JTS: { pub fn new(dx: F, dy: F) -> Option { - // JTS: if (dx == 0.0 && dy == 0.0) - // JTS: throw new IllegalArgumentException("Cannot compute the quadrant for point ( "+ dx + ", " + dy + " )" ); if dx.is_zero() && dy.is_zero() { return None; } - // JTS: if (dx >= 0.0) { - // JTS: if (dy >= 0.0) - // JTS: return NE; - // JTS: else - // JTS: return SE; - // JTS: } if dx >= F::zero() { if dy >= F::zero() { Some(Quadrant::NE) } else { Some(Quadrant::SE) } - // JTS: else { } else { - // JTS: if (dy >= 0.0) - // JTS: return NW; - // JTS: else - // JTS: return SW; - // JTS: } - // JTS: } if dy >= F::zero() { Some(Quadrant::NW) } else { @@ -74,82 +34,4 @@ impl Quadrant { } } } - // JTS: - // JTS: /** - // JTS: * Returns the quadrant of a directed line segment from p0 to p1. - // JTS: * - // JTS: * @throws IllegalArgumentException if the points are equal - // JTS: */ - // JTS: public static int quadrant(Coordinate p0, Coordinate p1) - // JTS: { - // JTS: if (p1.x == p0.x && p1.y == p0.y) - // JTS: throw new IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0); - // JTS: - // JTS: if (p1.x >= p0.x) { - // JTS: if (p1.y >= p0.y) - // JTS: return NE; - // JTS: else - // JTS: return SE; - // JTS: } - // JTS: else { - // JTS: if (p1.y >= p0.y) - // JTS: return NW; - // JTS: else - // JTS: return SW; - // JTS: } - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns true if the quadrants are 1 and 3, or 2 and 4 - // JTS: */ - // JTS: public static boolean isOpposite(int quad1, int quad2) - // JTS: { - // JTS: if (quad1 == quad2) return false; - // JTS: int diff = (quad1 - quad2 + 4) % 4; - // JTS: // if quadrants are not adjacent, they are opposite - // JTS: if (diff == 2) return true; - // JTS: return false; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns the right-hand quadrant of the halfplane defined by the two quadrants, - // JTS: * or -1 if the quadrants are opposite, or the quadrant if they are identical. - // JTS: */ - // JTS: public static int commonHalfPlane(int quad1, int quad2) - // JTS: { - // JTS: // if quadrants are the same they do not determine a unique common halfplane. - // JTS: // Simply return one of the two possibilities - // JTS: if (quad1 == quad2) return quad1; - // JTS: int diff = (quad1 - quad2 + 4) % 4; - // JTS: // if quadrants are not adjacent, they do not share a common halfplane - // JTS: if (diff == 2) return -1; - // JTS: // - // JTS: int min = (quad1 < quad2) ? quad1 : quad2; - // JTS: int max = (quad1 > quad2) ? quad1 : quad2; - // JTS: // for this one case, the righthand plane is NOT the minimum index; - // JTS: if (min == 0 && max == 3) return 3; - // JTS: // in general, the halfplane index is the minimum of the two adjacent quadrants - // JTS: return min; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns whether the given quadrant lies within the given halfplane (specified - // JTS: * by its right-hand quadrant). - // JTS: */ - // JTS: public static boolean isInHalfPlane(int quad, int halfPlane) - // JTS: { - // JTS: if (halfPlane == SE) { - // JTS: return quad == SE || quad == SW; - // JTS: } - // JTS: return quad == halfPlane || quad == halfPlane + 1; - // JTS: } - // JTS: - // JTS: /** - // JTS: * Returns true if the given quadrant is 0 or 1. - // JTS: */ - // JTS: public static boolean isNorthern(int quad) - // JTS: { - // JTS: return quad == NE || quad == NW; - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/geomgraph/robust_line_intersector.rs b/geo/src/algorithm/relate/geomgraph/robust_line_intersector.rs index 92fbe19130..28c1f8ddd9 100644 --- a/geo/src/algorithm/relate/geomgraph/robust_line_intersector.rs +++ b/geo/src/algorithm/relate/geomgraph/robust_line_intersector.rs @@ -6,21 +6,11 @@ use crate::intersects::Intersects; use crate::num_traits::Zero; use crate::{Coordinate, GeoFloat, Line, Rect}; -// JTS: /** -// JTS: * A robust version of {@link LineIntersector}. -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class RobustLineIntersector -// JTS: extends LineIntersector -// JTS: { /// A robust version of [LineIntersector](traits.LineIntersector). #[derive(Clone)] pub(crate) struct RobustLineIntersector; impl RobustLineIntersector { - // JTS: public RobustLineIntersector() { - // JTS: } pub fn new() -> RobustLineIntersector { RobustLineIntersector } @@ -50,44 +40,18 @@ impl RobustLineIntersector { /// result of _rounding_ points which lie on the line, /// but not safe to use for _truncated_ points. pub fn compute_edge_distance(intersection: Coordinate, line: Line) -> F { - // JTS: double dx = Math.abs(p1.x - p0.x); - // JTS: double dy = Math.abs(p1.y - p0.y); let dx = (line.end.x - line.start.x).abs(); let dy = (line.end.y - line.start.y).abs(); - // JTS: double dist = -1.0; // sentinel value let mut dist: F; - // JTS: if (p.equals(p0)) { - // JTS: dist = 0.0; - // JTS: } if intersection == line.start { dist = F::zero(); - // JTS: else if (p.equals(p1)) { - // JTS: if (dx > dy) - // JTS: dist = dx; - // JTS: else - // JTS: dist = dy; - // JTS: } } else if intersection == line.end { if dx > dy { dist = dx; } else { dist = dy; } - // JTS: else { - // JTS: double pdx = Math.abs(p.x - p0.x); - // JTS: double pdy = Math.abs(p.y - p0.y); - // JTS: if (dx > dy) - // JTS: dist = pdx; - // JTS: else - // JTS: dist = pdy; - // JTS: // - // JTS: // hack to ensure that non-endpoints always have a non-zero distance - // JTS: if (dist == 0.0 && ! p.equals(p0)) - // JTS: { - // JTS: dist = Math.max(pdx, pdy); - // JTS: } - // JTS: } } else { let intersection_dx = (intersection.x - line.start.x).abs(); let intersection_dy = (intersection.y - line.start.y).abs(); @@ -101,13 +65,10 @@ impl RobustLineIntersector { dist = intersection_dx.max(intersection_dy); } } - // JTS: Assert.isTrue(! (dist == 0.0 && ! p.equals(p0)), "Bad distance calculation"); - // JTS: return dist; debug_assert!( !(dist == F::zero() && intersection != line.start), "Bad distance calculation" ); dist - // JTS: } } } diff --git a/geo/src/algorithm/relate/geomgraph/topology_position.rs b/geo/src/algorithm/relate/geomgraph/topology_position.rs index 597cd3a3df..cd92ef3409 100644 --- a/geo/src/algorithm/relate/geomgraph/topology_position.rs +++ b/geo/src/algorithm/relate/geomgraph/topology_position.rs @@ -1,33 +1,7 @@ -// JTS: import org.locationtech.jts.geom.Location; - use super::{CoordPos, Direction}; use std::fmt; -// JTS: -// JTS: /** -// JTS: * A TopologyLocation is the labelling of a -// JTS: * GraphComponent's topological relationship to a single Geometry. -// JTS: *

-// JTS: * If the parent component is an area edge, each side and the edge itself -// JTS: * have a topological location. These locations are named -// JTS: *

    -// JTS: *
  • ON: on the edge -// JTS: *
  • LEFT: left-hand side of the edge -// JTS: *
  • RIGHT: right-hand side -// JTS: *
-// JTS: * If the parent component is a line edge or node, there is a single -// JTS: * topological relationship attribute, ON. -// JTS: *

-// JTS: * The possible values of a topological location are -// JTS: * {Location.NONE, Location.EXTERIOR, Location.BOUNDARY, Location.INTERIOR} -// JTS: *

-// JTS: * The labelling is stored in an array location[j] where -// JTS: * where j has the values ON, LEFT, RIGHT -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class TopologyLocation { - /// A `TopologyPosition` is the labelling of a graph component's topological relationship to a /// single Geometry for each of the component's [`Direction`s](Direction). /// @@ -75,26 +49,6 @@ impl fmt::Debug for TopologyPosition { } impl TopologyPosition { - // JTS: - // JTS: int location[]; - // JTS: - // JTS: public TopologyLocation(int[] location) - // JTS: { - // JTS: init(location.length); - // JTS: } - // JTS: /** - // JTS: * Constructs a TopologyLocation specifying how points on, to the left of, and to the - // JTS: * right of some GraphComponent relate to some Geometry. Possible values for the - // JTS: * parameters are Location.NULL, Location.EXTERIOR, Location.BOUNDARY, - // JTS: * and Location.INTERIOR. - // JTS: * @see Location - // JTS: */ - // JTS: public TopologyLocation(int on, int left, int right) { - // JTS: init(3); - // JTS: location[Position.ON] = on; - // JTS: location[Position.LEFT] = left; - // JTS: location[Position.RIGHT] = right; - // JTS: } pub fn area(on: CoordPos, left: CoordPos, right: CoordPos) -> Self { Self::Area { on: Some(on), @@ -111,10 +65,6 @@ impl TopologyPosition { } } - // JTS: public TopologyLocation(int on) { - // JTS: init(1); - // JTS: location[Position.ON] = on; - // JTS: } pub fn line_or_point(on: CoordPos) -> Self { Self::LineOrPoint { on: Some(on) } } @@ -123,24 +73,6 @@ impl TopologyPosition { Self::LineOrPoint { on: None } } - // JTS: public TopologyLocation(TopologyLocation gl) { - // JTS: init(gl.location.length); - // JTS: if (gl != null) { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: location[i] = gl.location[i]; - // JTS: } - // JTS: } - // JTS: } - // JTS: private void init(int size) - // JTS: { - // JTS: location = new int[size]; - // JTS: setAllLocations(Location.NONE); - // JTS: } - // JTS: public int get(int posIndex) - // JTS: { - // JTS: if (posIndex < location.length) return location[posIndex]; - // JTS: return Location.NONE; - // JTS: } pub fn get(&self, direction: Direction) -> Option { match (direction, self) { (Direction::Left, Self::Area { left, .. }) => *left, @@ -154,16 +86,6 @@ impl TopologyPosition { } } - // JTS: /** - // JTS: * @return true if all locations are NULL - // JTS: */ - // JTS: public boolean isNull() - // JTS: { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: if (location[i] != Location.NONE) return false; - // JTS: } - // JTS: return true; - // JTS: } pub fn is_empty(&self) -> bool { matches!( self, @@ -176,16 +98,6 @@ impl TopologyPosition { ) } - // JTS: /** - // JTS: * @return true if any locations are NULL - // JTS: */ - // JTS: public boolean isAnyNull() - // JTS: { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: if (location[i] == Location.NONE) return true; - // JTS: } - // JTS: return false; - // JTS: } pub fn is_any_empty(&self) -> bool { !matches!( self, @@ -198,27 +110,14 @@ impl TopologyPosition { ) } - // JTS: public boolean isEqualOnSide(TopologyLocation le, int locIndex) - // JTS: { - // JTS: return location[locIndex] == le.location[locIndex]; - // JTS: } - // JTS: public boolean isArea() { return location.length > 1; } pub fn is_area(&self) -> bool { matches!(self, Self::Area { .. }) } - // JTS: public boolean isLine() { return location.length == 1; } pub fn is_line(&self) -> bool { matches!(self, Self::LineOrPoint { .. }) } - // JTS: public void flip() - // JTS: { - // JTS: if (location.length <= 1) return; - // JTS: int temp = location[Position.LEFT]; - // JTS: location[Position.LEFT] = location[Position.RIGHT]; - // JTS: location[Position.RIGHT] = temp; - // JTS: } pub fn flip(&mut self) { match self { Self::LineOrPoint { .. } => {} @@ -228,12 +127,6 @@ impl TopologyPosition { } } - // JTS: public void setAllLocations(int locValue) - // JTS: { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: location[i] = locValue; - // JTS: } - // JTS: } pub fn set_all_positions(&mut self, position: CoordPos) { match self { Self::LineOrPoint { on } => { @@ -247,12 +140,6 @@ impl TopologyPosition { } } - // JTS: public void setAllLocationsIfNull(int locValue) - // JTS: { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: if (location[i] == Location.NONE) location[i] = locValue; - // JTS: } - // JTS: } pub fn set_all_positions_if_empty(&mut self, position: CoordPos) { match self { Self::LineOrPoint { on } => { @@ -274,10 +161,6 @@ impl TopologyPosition { } } - // JTS: public void setLocation(int locIndex, int locValue) - // JTS: { - // JTS: location[locIndex] = locValue; - // JTS: } pub fn set_position(&mut self, direction: Direction, position: CoordPos) { match (direction, self) { (Direction::On, Self::LineOrPoint { on }) => *on = Some(position), @@ -290,10 +173,6 @@ impl TopologyPosition { } } - // JTS: public void setLocation(int locValue) - // JTS: { - // JTS: setLocation(Position.ON, locValue); - // JTS: } pub fn set_on_position(&mut self, position: CoordPos) { match self { Self::LineOrPoint { on } | Self::Area { on, .. } => { @@ -302,12 +181,6 @@ impl TopologyPosition { } } - // JTS: public int[] getLocations() { return location; } - // JTS: public void setLocations(int on, int left, int right) { - // JTS: location[Position.ON] = on; - // JTS: location[Position.LEFT] = left; - // JTS: location[Position.RIGHT] = right; - // JTS: } pub fn set_locations(&mut self, new_on: CoordPos, new_left: CoordPos, new_right: CoordPos) { match self { Self::LineOrPoint { .. } => { @@ -321,42 +194,4 @@ impl TopologyPosition { } } } - - // JTS: public boolean allPositionsEqual(int loc) - // JTS: { - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: if (location[i] != loc) return false; - // JTS: } - // JTS: return true; - // JTS: } - // JTS: - // JTS: /** - // JTS: * merge updates only the NULL attributes of this object - // JTS: * with the attributes of another. - // JTS: */ - // JTS: public void merge(TopologyLocation gl) - // JTS: { - // JTS: // if the src is an Area label & and the dest is not, increase the dest to be an Area - // JTS: if (gl.location.length > location.length) { - // JTS: int [] newLoc = new int[3]; - // JTS: newLoc[Position.ON] = location[Position.ON]; - // JTS: newLoc[Position.LEFT] = Location.NONE; - // JTS: newLoc[Position.RIGHT] = Location.NONE; - // JTS: location = newLoc; - // JTS: } - // JTS: for (int i = 0; i < location.length; i++) { - // JTS: if (location[i] == Location.NONE && i < gl.location.length) - // JTS: location[i] = gl.location[i]; - // JTS: } - // JTS: } - // JTS: - // JTS: public String toString() - // JTS: { - // JTS: StringBuffer buf = new StringBuffer(); - // JTS: if (location.length > 1) buf.append(Location.toLocationSymbol(location[Position.LEFT])); - // JTS: buf.append(Location.toLocationSymbol(location[Position.ON])); - // JTS: if (location.length > 1) buf.append(Location.toLocationSymbol(location[Position.RIGHT])); - // JTS: return buf.toString(); - // JTS: } - // JTS: } } diff --git a/geo/src/algorithm/relate/relate_operation.rs b/geo/src/algorithm/relate/relate_operation.rs index 6beee709d8..a228b5fe60 100644 --- a/geo/src/algorithm/relate/relate_operation.rs +++ b/geo/src/algorithm/relate/relate_operation.rs @@ -12,47 +12,6 @@ use crate::{Coordinate, GeoFloat, GeometryCow}; use std::cell::RefCell; use std::rc::Rc; -// JTS: /** -// JTS: * @version 1.7 -// JTS: */ -// JTS: import java.util.ArrayList; -// JTS: import java.util.Iterator; -// JTS: import java.util.List; -// JTS: -// JTS: import org.locationtech.jts.algorithm.LineIntersector; -// JTS: import org.locationtech.jts.algorithm.PointLocator; -// JTS: import org.locationtech.jts.algorithm.RobustLineIntersector; -// JTS: import org.locationtech.jts.geom.Coordinate; -// JTS: import org.locationtech.jts.geom.Geometry; -// JTS: import org.locationtech.jts.geom.IntersectionMatrix; -// JTS: import org.locationtech.jts.geom.Location; -// JTS: import org.locationtech.jts.geomgraph.Edge; -// JTS: import org.locationtech.jts.geomgraph.EdgeEnd; -// JTS: import org.locationtech.jts.geomgraph.EdgeIntersection; -// JTS: import org.locationtech.jts.geomgraph.GeometryGraph; -// JTS: import org.locationtech.jts.geomgraph.Label; -// JTS: import org.locationtech.jts.geomgraph.Node; -// JTS: import org.locationtech.jts.geomgraph.NodeMap; -// JTS: import org.locationtech.jts.geomgraph.index.SegmentIntersector; -// JTS: import org.locationtech.jts.util.Assert; -// JTS: -// JTS: /** -// JTS: * Computes the topological relationship between two Geometries. -// JTS: *

-// JTS: * RelateComputer does not need to build a complete graph structure to compute -// JTS: * the IntersectionMatrix. The relationship between the geometries can -// JTS: * be computed by simply examining the labelling of edges incident on each node. -// JTS: *

-// JTS: * RelateComputer does not currently support arbitrary GeometryCollections. -// JTS: * This is because GeometryCollections can contain overlapping Polygons. -// JTS: * In order to correct compute relate on overlapping Polygons, they -// JTS: * would first need to be noded and merged (if not explicitly, at least -// JTS: * implicitly). -// JTS: * -// JTS: * @version 1.7 -// JTS: */ -// JTS: public class RelateComputer -// JTS: { /// Computes an [`IntersectionMatrix`] describing the topological relationship between two /// Geometries. /// @@ -101,28 +60,8 @@ where } } - // JTS: private LineIntersector li = new RobustLineIntersector(); - // JTS: private PointLocator ptLocator = new PointLocator(); - // JTS: private GeometryGraph[] arg; // the arg(s) of the operation - // JTS: private NodeMap nodes = new NodeMap(new RelateNodeFactory()); - // JTS: // this intersection matrix will hold the results compute for the relate - // JTS: private IntersectionMatrix im = null; - // JTS: private ArrayList isolatedEdges = new ArrayList(); - // JTS: - // JTS: // the intersection point found (if any) - // JTS: private Coordinate invalidPoint; - // JTS: - // JTS: public RelateComputer(GeometryGraph[] arg) { - // JTS: this.arg = arg; - // JTS: } - // JTS: - // JTS: public IntersectionMatrix computeIM() - // JTS: { pub(crate) fn compute_intersection_matrix(&mut self) -> IntersectionMatrix { - // JTS: IntersectionMatrix im = new IntersectionMatrix(); let mut intersection_matrix = IntersectionMatrix::empty(); - // JTS: // since Geometries are finite and embedded in a 2-D space, the EE element must always be 2 - // JTS: im.set(Location.EXTERIOR, Location.EXTERIOR, 2); // since Geometries are finite and embedded in a 2-D space, // the `(Outside, Outside)` element must always be 2-D intersection_matrix.set( @@ -131,13 +70,6 @@ where Dimensions::TwoDimensional, ); - // JTS: // if the Geometries don't overlap there is nothing to do - // JTS: if (! arg[0].getGeometry().getEnvelopeInternal().intersects( - // JTS: arg[1].getGeometry().getEnvelopeInternal()) ) { - // JTS: computeDisjointIM(im); - // JTS: return im; - // JTS: } - use crate::algorithm::bounding_rect::BoundingRect; use crate::algorithm::intersects::Intersects; match ( @@ -153,8 +85,6 @@ where } } - // JTS: arg[0].computeSelfNodes(li, false); - // JTS: arg[1].computeSelfNodes(li, false); // Since changes to topology are inspected at nodes, we must crate a node for each // intersection. self.graph_a @@ -162,54 +92,21 @@ where self.graph_b .compute_self_nodes(Box::new(self.line_intersector.clone())); - // JTS: // compute intersections between edges of the two input geometries - // JTS: SegmentIntersector intersector = arg[0].computeEdgeIntersections(arg[1], li, false); // compute intersections between edges of the two input geometries let segment_intersector = self .graph_a .compute_edge_intersections(&self.graph_b, Box::new(self.line_intersector.clone())); - // JTS: //System.out.println("computeIM: # segment intersection tests: " + intersector.numTests); - // JTS: computeIntersectionNodes(0); - // JTS: computeIntersectionNodes(1); self.compute_intersection_nodes(0); self.compute_intersection_nodes(1); - // JTS: /** - // JTS: * Copy the labelling for the nodes in the parent Geometries. These override - // JTS: * any labels determined by intersections between the geometries. - // JTS: */ - // JTS: copyNodesAndLabels(0); - // JTS: copyNodesAndLabels(1); // Copy the labelling for the nodes in the parent Geometries. These override any labels // determined by intersections between the geometries. self.copy_nodes_and_labels(0); self.copy_nodes_and_labels(1); - // JTS: - // JTS: // complete the labelling for any nodes which only have a label for a single geometry - // JTS: //Debug.addWatch(nodes.find(new Coordinate(110, 200))); - // JTS: //Debug.printWatch(); - // JTS: labelIsolatedNodes(); // complete the labelling for any nodes which only have a label for a single geometry self.label_isolated_nodes(); - // JTS: //Debug.printWatch(); - // JTS: - // JTS: // If a proper intersection was found, we can set a lower bound on the IM. - // JTS: computeProperIntersectionIM(intersector, im); // If a proper intersection was found, we can set a lower bound on the IM. self.compute_proper_intersection_im(&segment_intersector, &mut intersection_matrix); - // JTS: - // JTS: /** - // JTS: * Now process improper intersections - // JTS: * (eg where one or other of the geometries has a vertex at the intersection point) - // JTS: * We need to compute the edge graph at all nodes to determine the IM. - // JTS: */ - // JTS: - // JTS: // build EdgeEnds for all intersections - // JTS: EdgeEndBuilder eeBuilder = new EdgeEndBuilder(); - // JTS: List ee0 = eeBuilder.computeEdgeEnds(arg[0].getEdgeIterator()); - // JTS: insertEdgeEnds(ee0); - // JTS: List ee1 = eeBuilder.computeEdgeEnds(arg[1].getEdgeIterator()); - // JTS: insertEdgeEnds(ee1); // Now process improper intersections // (eg where one or other of the geometries has a vertex at the intersection point) // We need to compute the edge graph at all nodes to determine the IM. @@ -218,11 +115,6 @@ where self.insert_edge_ends(edge_ends_a); let edge_ends_b: Vec<_> = edge_end_builder.compute_ends_for_edges(self.graph_b.edges()); self.insert_edge_ends(edge_ends_b); - // JTS: - // JTS: //Debug.println("==== NodeList ==="); - // JTS: //Debug.print(nodes); - // JTS: - // JTS: labelNodeEdges(); let mut nodes = NodeMap::new(); std::mem::swap(&mut self.nodes, &mut nodes); @@ -231,20 +123,6 @@ where .map(|(node, edges)| (node, edges.into_labeled(&self.graph_a, &self.graph_b))) .collect(); - // JTS: - // JTS: /** - // JTS: * Compute the labeling for isolated components - // JTS: *
- // JTS: * Isolated components are components that do not touch any other components in the graph. - // JTS: * They can be identified by the fact that they will - // JTS: * contain labels containing ONLY a single element, the one for their parent geometry. - // JTS: * We only need to check components contained in the input graphs, since - // JTS: * isolated components will not have been replaced by new components formed by intersections. - // JTS: */ - // JTS: //debugPrintln("Graph A isolated edges - "); - // JTS: labelIsolatedEdges(0, 1); - // JTS: //debugPrintln("Graph B isolated edges - "); - // JTS: labelIsolatedEdges(1, 0); // Compute the labeling for "isolated" components // // Isolated components are components that do not touch any other components in the graph. @@ -258,27 +136,16 @@ where self.label_isolated_edges(0, 1); self.label_isolated_edges(1, 0); - // JTS: // update the IM from all components - // JTS: updateIM(im); debug!( "before update_intersection_matrix: {:?}", &intersection_matrix ); self.update_intersection_matrix(labeled_node_edges, &mut intersection_matrix); - // JTS: return im; - // JTS: } intersection_matrix } - // JTS: private void insertEdgeEnds(List ee) - // JTS: { fn insert_edge_ends(&mut self, edge_ends: Vec>) { - // JTS: for (Iterator i = ee.iterator(); i.hasNext(); ) { - // JTS: EdgeEnd e = (EdgeEnd) i.next(); - // JTS: nodes.add(e); - // JTS: } - // JTS: } for edge_end in edge_ends { let (_node, edges) = self .nodes @@ -287,56 +154,33 @@ where } } - // JTS: private void computeProperIntersectionIM(SegmentIntersector intersector, IntersectionMatrix im) - // JTS: { fn compute_proper_intersection_im( &mut self, segment_intersector: &SegmentIntersector, intersection_matrix: &mut IntersectionMatrix, ) { - // JTS: // If a proper intersection is found, we can set a lower bound on the IM. - // JTS: int dimA = arg[0].getGeometry().getDimension(); - // JTS: int dimB = arg[1].getGeometry().getDimension(); // If a proper intersection is found, we can set a lower bound on the IM. let dim_a = self.graph_a.geometry().dimensions(); let dim_b = self.graph_b.geometry().dimensions(); - // JTS: boolean hasProper = intersector.hasProperIntersection(); - // JTS: boolean hasProperInterior = intersector.hasProperInteriorIntersection(); let has_proper = segment_intersector.has_proper_intersection(); let has_proper_interior = segment_intersector.has_proper_interior_intersection(); - // JTS: // For Geometry's of dim 0 there can never be proper intersections. debug_assert!( (dim_a != Dimensions::ZeroDimensional && dim_b != Dimensions::ZeroDimensional) || (!has_proper && !has_proper_interior) ); match (dim_a, dim_b) { - // JTS: /** - // JTS: * If edge segments of Areas properly intersect, the areas must properly overlap. - // JTS: */ - // JTS: if (dimA == 2 && dimB == 2) { // If edge segments of Areas properly intersect, the areas must properly overlap. (Dimensions::TwoDimensional, Dimensions::TwoDimensional) => { - // JTS: if (hasProper) im.setAtLeast("212101212"); if has_proper { intersection_matrix .set_at_least_from_string("212101212") .expect("error in hardcoded dimensions"); } - // JTS: } } - // JTS: /** - // JTS: * If an Line segment properly intersects an edge segment of an Area, - // JTS: * it follows that the Interior of the Line intersects the Boundary of the Area. - // JTS: * If the intersection is a proper interior intersection, then - // JTS: * there is an Interior-Interior intersection too. - // JTS: * Note that it does not follow that the Interior of the Line intersects the Exterior - // JTS: * of the Area, since there may be another Area component which contains the rest of the Line. - // JTS: */ - // JTS: else if (dimA == 2 && dimB == 1) { // If a Line segment properly intersects an edge segment of an Area, it follows that // the Interior of the Line intersects the Boundary of the Area. // If the intersection is a proper *interior* intersection, then there is an @@ -344,52 +188,33 @@ where // Note that it does not follow that the Interior of the Line intersects the Exterior // of the Area, since there may be another Area component which contains the rest of the Line. (Dimensions::TwoDimensional, Dimensions::OneDimensional) => { - // JTS: if (hasProper) im.setAtLeast("FFF0FFFF2"); if has_proper { intersection_matrix .set_at_least_from_string("FFF0FFFF2") .expect("error in hardcoded dimensions"); } - // JTS: if (hasProperInterior) im.setAtLeast("1FFFFF1FF"); if has_proper_interior { intersection_matrix .set_at_least_from_string("1FFFFF1FF") .expect("error in hardcoded dimensions"); } - - // JTS: } } - // JTS: else if (dimA == 1 && dimB == 2) { (Dimensions::OneDimensional, Dimensions::TwoDimensional) => { - // JTS: if (hasProper) im.setAtLeast("F0FFFFFF2"); if has_proper { intersection_matrix .set_at_least_from_string("F0FFFFFF2") .expect("error in hardcoded dimensions"); } - // JTS: if (hasProperInterior) im.setAtLeast("1F1FFFFFF"); if has_proper_interior { intersection_matrix .set_at_least_from_string("1F1FFFFFF") .expect("error in hardcoded dimensions"); } - - // JTS: } } - // JTS: /* If edges of LineStrings properly intersect *in an interior point*, all - // JTS: we can deduce is that - // JTS: the interiors intersect. (We can NOT deduce that the exteriors intersect, - // JTS: since some other segments in the geometries might cover the points in the - // JTS: neighbourhood of the intersection.) - // JTS: It is important that the point be known to be an interior point of - // JTS: both Geometries, since it is possible in a self-intersecting geometry to - // JTS: have a proper intersection on one segment that is also a boundary point of another segment. - // JTS: */ - // JTS: else if (dimA == 1 && dimB == 1) { // If edges of LineStrings properly intersect *in an interior point*, all we can deduce // is that the interiors intersect. (We can NOT deduce that the exteriors intersect, // since some other segments in the geometries might cover the points in the @@ -398,38 +223,16 @@ where // since it is possible in a self-intersecting geometry to have a proper intersection // on one segment that is also a boundary point of another segment. (Dimensions::OneDimensional, Dimensions::OneDimensional) => { - // JTS: if (hasProperInterior) im.setAtLeast("0FFFFFFFF"); - // JTS: } if has_proper_interior { intersection_matrix .set_at_least_from_string("0FFFFFFFF") .expect("error in hardcoded dimensions"); } } - // JTS: } _ => {} } } - // JTS: /** - // JTS: * Copy all nodes from an arg geometry into this graph. - // JTS: * The node label in the arg geometry overrides any previously computed - // JTS: * label for that argIndex. - // JTS: * (E.g. a node may be an intersection node with - // JTS: * a computed label of BOUNDARY, - // JTS: * but in the original arg Geometry it is actually - // JTS: * in the interior due to the Boundary Determination Rule) - // JTS: */ - // JTS: private void copyNodesAndLabels(int argIndex) - // JTS: { - // JTS: for (Iterator i = arg[argIndex].getNodeIterator(); i.hasNext(); ) { - // JTS: Node graphNode = (Node) i.next(); - // JTS: Node newNode = nodes.addNode(graphNode.getCoordinate()); - // JTS: newNode.setLabel(argIndex, graphNode.getLabel().getLocation(argIndex)); - // JTS: //node.print(System.out); - // JTS: } - // JTS: } - /// Copy all nodes from an arg geometry into this graph. /// /// The node label in the arg geometry overrides any previously computed label for that @@ -457,16 +260,6 @@ where } } - // JTS: /** - // JTS: * Insert nodes for all intersections on the edges of a Geometry. - // JTS: * Label the created nodes the same as the edge label if they do not already have a label. - // JTS: * This allows nodes created by either self-intersections or - // JTS: * mutual intersections to be labelled. - // JTS: * Endpoint nodes will already be labelled from when they were inserted. - // JTS: */ - // JTS: private void computeIntersectionNodes(int argIndex) - // JTS: { - /// Insert nodes for all intersections on the edges of a Geometry. /// /// Label the created nodes the same as the edge label if they do not already have a label. @@ -482,79 +275,27 @@ where &self.graph_b }; - // JTS: for (Iterator i = arg[argIndex].getEdgeIterator(); i.hasNext(); ) { - // JTS: Edge e = (Edge) i.next(); for edge in graph.edges() { let edge = edge.borrow(); - // JTS: int eLoc = e.getLabel().getLocation(argIndex); let edge_position = edge.label().on_position(geom_index); - // JTS: for (Iterator eiIt = e.getEdgeIntersectionList().iterator(); eiIt.hasNext(); ) { for edge_intersection in edge.edge_intersections() { - // JTS: EdgeIntersection ei = (EdgeIntersection) eiIt.next(); - // JTS: RelateNode n = (RelateNode) nodes.addNode(ei.coord); let (new_node, _edges) = self .nodes .insert_node_with_coordinate(edge_intersection.coordinate()); - // JTS: if (eLoc == Location.BOUNDARY) - // JTS: n.setLabelBoundary(argIndex); - // JTS: else { - // JTS: if (n.getLabel().isNull(argIndex)) - // JTS: n.setLabel(argIndex, Location.INTERIOR); - // JTS: } if edge_position == Some(CoordPos::OnBoundary) { new_node.set_label_boundary(geom_index); } else if new_node.label().is_empty(geom_index) { new_node.set_label_on_position(geom_index, CoordPos::Inside); } - // JTS: //Debug.println(n); - // JTS: } - // JTS: } - // JTS: } } } } - // JTS: /** - // JTS: * For all intersections on the edges of a Geometry, - // JTS: * label the corresponding node IF it doesn't already have a label. - // JTS: * This allows nodes created by either self-intersections or - // JTS: * mutual intersections to be labelled. - // JTS: * Endpoint nodes will already be labelled from when they were inserted. - // JTS: */ - // JTS: private void labelIntersectionNodes(int argIndex) - // JTS: { - // JTS: for (Iterator i = arg[argIndex].getEdgeIterator(); i.hasNext(); ) { - // JTS: Edge e = (Edge) i.next(); - // JTS: int eLoc = e.getLabel().getLocation(argIndex); - // JTS: for (Iterator eiIt = e.getEdgeIntersectionList().iterator(); eiIt.hasNext(); ) { - // JTS: EdgeIntersection ei = (EdgeIntersection) eiIt.next(); - // JTS: RelateNode n = (RelateNode) nodes.find(ei.coord); - // JTS: if (n.getLabel().isNull(argIndex)) { - // JTS: if (eLoc == Location.BOUNDARY) - // JTS: n.setLabelBoundary(argIndex); - // JTS: else - // JTS: n.setLabel(argIndex, Location.INTERIOR); - // JTS: } - // JTS: //n.print(System.out); - // JTS: } - // JTS: } - // JTS: } - // JTS: /** - // JTS: * If the Geometries are disjoint, we need to enter their dimension and - // JTS: * boundary dimension in the Ext rows in the IM - // JTS: */ - // JTS: private void computeDisjointIM(IntersectionMatrix im) - // JTS: { /// If the Geometries are disjoint, we need to enter their dimension and boundary dimension in /// the `Outside` rows in the IM fn compute_disjoint_intersection_matrix(&self, intersection_matrix: &mut IntersectionMatrix) { - // JTS: Geometry ga = arg[0].getGeometry(); - // JTS: if (! ga.isEmpty()) { - // JTS: im.set(Location.INTERIOR, Location.EXTERIOR, ga.getDimension()); - // JTS: im.set(Location.BOUNDARY, Location.EXTERIOR, ga.getBoundaryDimension()); - // JTS: } { let geometry_a = self.graph_a.geometry(); let dimensions = geometry_a.dimensions(); @@ -572,12 +313,6 @@ where } } - // JTS: Geometry gb = arg[1].getGeometry(); - // JTS: if (! gb.isEmpty()) { - // JTS: im.set(Location.EXTERIOR, Location.INTERIOR, gb.getDimension()); - // JTS: im.set(Location.EXTERIOR, Location.BOUNDARY, gb.getBoundaryDimension()); - // JTS: } - // JTS: } { let geometry_b = self.graph_b.geometry(); let dimensions = geometry_b.dimensions(); @@ -596,35 +331,6 @@ where } } - // JTS: private void labelNodeEdges() - // JTS: { - // JTS: for (Iterator ni = nodes.iterator(); ni.hasNext(); ) { - // JTS: RelateNode node = (RelateNode) ni.next(); - // JTS: node.getEdges().computeLabelling(arg); - // JTS: //Debug.print(node.getEdges()); - // JTS: //node.print(System.out); - // JTS: } - // JTS: } - // JTS: /** - // JTS: * update the IM with the sum of the IMs for each component - // JTS: */ - // JTS: private void updateIM(IntersectionMatrix im) - // JTS: { - // JTS: //Debug.println(im); - // JTS: for (Iterator ei = isolatedEdges.iterator(); ei.hasNext(); ) { - // JTS: Edge e = (Edge) ei.next(); - // JTS: e.updateIM(im); - // JTS: //Debug.println(im); - // JTS: } - // JTS: for (Iterator ni = nodes.iterator(); ni.hasNext(); ) { - // JTS: RelateNode node = (RelateNode) ni.next(); - // JTS: node.updateIM(im); - // JTS: //Debug.println(im); - // JTS: node.updateIMFromEdges(im); - // JTS: //Debug.println(im); - // JTS: //node.print(System.out); - // JTS: } - // JTS: } fn update_intersection_matrix( &self, labeled_node_edges: Vec<(CoordNode, LabeledEdgeEndBundleStar)>, @@ -651,24 +357,6 @@ where } } - // JTS: /** - // JTS: * Processes isolated edges by computing their labelling and adding them - // JTS: * to the isolated edges list. - // JTS: * Isolated edges are guaranteed not to touch the boundary of the target (since if they - // JTS: * did, they would have caused an intersection to be computed and hence would - // JTS: * not be isolated) - // JTS: */ - // JTS: private void labelIsolatedEdges(int thisIndex, int targetIndex) - // JTS: { - // JTS: for (Iterator ei = arg[thisIndex].getEdgeIterator(); ei.hasNext(); ) { - // JTS: Edge e = (Edge) ei.next(); - // JTS: if (e.isIsolated()) { - // JTS: labelIsolatedEdge(e, targetIndex, arg[targetIndex].getGeometry()); - // JTS: isolatedEdges.add(e); - // JTS: } - // JTS: } - // JTS: }' - /// Processes isolated edges by computing their labelling and adding them to the isolated edges /// list. /// @@ -691,26 +379,6 @@ where } } - // JTS: /** - // JTS: * Label an isolated edge of a graph with its relationship to the target geometry. - // JTS: * If the target has dim 2 or 1, the edge can either be in the interior or the exterior. - // JTS: * If the target has dim 0, the edge must be in the exterior - // JTS: */ - // JTS: private void labelIsolatedEdge(Edge e, int targetIndex, Geometry target) - // JTS: { - // JTS: // this won't work for GeometryCollections with both dim 2 and 1 geoms - // JTS: if ( target.getDimension() > 0) { - // JTS: // since edge is not in boundary, may not need the full generality of PointLocator? - // JTS: // Possibly should use ptInArea locator instead? We probably know here - // JTS: // that the edge does not touch the bdy of the target Geometry - // JTS: int loc = ptLocator.locate(e.getCoordinate(), target); - // JTS: e.getLabel().setAllLocations(targetIndex, loc); - // JTS: } - // JTS: else { - // JTS: e.getLabel().setAllLocations(targetIndex, Location.EXTERIOR); - // JTS: } - // JTS: //System.out.println(e.getLabel()); - // JTS: } /// Label an isolated edge of a graph with its relationship to the target geometry. /// If the target has dim 2 or 1, the edge can either be in the interior or the exterior. /// If the target has dim 0, the edge must be in the exterior @@ -728,23 +396,6 @@ where } } - // JTS: - // JTS: /** - // JTS: * Isolated nodes are nodes whose labels are incomplete - // JTS: * (e.g. the location for one Geometry is null). - // JTS: * This is the case because nodes in one graph which don't intersect - // JTS: * nodes in the other are not completely labelled by the initial process - // JTS: * of adding nodes to the nodeList. - // JTS: * To complete the labelling we need to check for nodes that lie in the - // JTS: * interior of edges, and in the interior of areas. - // JTS: */ - // JTS: private void labelIsolatedNodes() - // JTS: { - // JTS: for (Iterator ni = nodes.iterator(); ni.hasNext(); ) { - // JTS: Node n = (Node) ni.next(); - // JTS: Label label = n.getLabel(); - // JTS: // isolated nodes should always have at least one geometry in their label - // JTS: Assert.isTrue(label.getGeometryCount() > 0, "node with empty label found"); /// Isolated nodes are nodes whose labels are incomplete (e.g. the location for one Geometry is /// null). /// This is the case because nodes in one graph which don't intersect nodes in the other @@ -758,12 +409,6 @@ where let label = node.label(); // isolated nodes should always have at least one geometry in their label debug_assert!(label.geometry_count() > 0, "node with empty label found"); - // JTS: if (n.isIsolated()) { - // JTS: if (label.isNull(0)) - // JTS: labelIsolatedNode(n, 0); - // JTS: else - // JTS: labelIsolatedNode(n, 1); - // JTS: } if node.is_isolated() { if label.is_empty(0) { Self::label_isolated_node(node, 0, geometry_a) @@ -771,27 +416,15 @@ where Self::label_isolated_node(node, 1, geometry_b) } } - // JTS: } - // JTS: } } } - // JTS: /** - // JTS: * Label an isolated node with its relationship to the target geometry. - // JTS: */ - // JTS: private void labelIsolatedNode(Node n, int targetIndex) - // JTS: { fn label_isolated_node( node: &mut CoordNode, target_index: usize, geometry: &GeometryCow, ) { - // JTS: int loc = ptLocator.locate(n.getCoordinate(), arg[targetIndex].getGeometry()); let position = geometry.coordinate_position(node.coordinate()); - // JTS: n.getLabel().setAllLocations(targetIndex, loc); - // JTS: //debugPrintln(n.getLabel()); - // JTS: } - // JTS: } node.label_mut().set_all_positions(target_index, position); } }