use of com.revolsys.geometry.model.segment.LineSegment in project com.revolsys.open by revolsys.
the class NonEncroachingSplitPointFinder method findSplitPoint.
/**
* A basic strategy for finding split points when nothing extra is known about the geometry of
* the situation.
*
* @param seg the encroached segment
* @param encroachPt the encroaching point
* @return the point at which to split the encroached segment
*/
@Override
public Point findSplitPoint(final LineSegmentDoubleData seg, final Point encroachPt) {
final LineSegment lineSeg = seg;
final double segLen = lineSeg.getLength();
final double midPtLen = segLen / 2;
final SplitSegment splitSeg = new SplitSegment(lineSeg);
final Point projPt = projectedSplitPoint(seg, encroachPt);
/**
* Compute the largest diameter (length) that will produce a split segment which is not
* still encroached upon by the encroaching point (The length is reduced slightly by a
* safety factor)
*/
// .99;
final double nonEncroachDiam = projPt.distancePoint(encroachPt) * 2 * 0.8;
double maxSplitLen = nonEncroachDiam;
if (maxSplitLen > midPtLen) {
maxSplitLen = midPtLen;
}
splitSeg.setMinimumLength(maxSplitLen);
splitSeg.splitAt(projPt);
return splitSeg.getSplitPoint();
}
use of com.revolsys.geometry.model.segment.LineSegment in project com.revolsys.open by revolsys.
the class LineMatchGraph method getDuplicateMatchLength.
public double getDuplicateMatchLength(final Node<LineSegmentMatch> node, final boolean direction, final int index1, final int index2) {
List<Edge<LineSegmentMatch>> edges;
if (direction) {
edges = node.getOutEdges();
} else {
edges = node.getInEdges();
}
for (final Edge<LineSegmentMatch> edge : edges) {
final LineSegmentMatch lineSegmentMatch = edge.getObject();
if (lineSegmentMatch.getMatchCount(index1) > 2) {
if (lineSegmentMatch.hasMatches(index1, index2)) {
final LineSegment segment = lineSegmentMatch.getSegment(index2);
final double length = segment.getLength();
final Node<LineSegmentMatch> nextNode = edge.getOppositeNode(node);
return length + getDuplicateMatchLength(nextNode, direction, index1, index2);
}
}
}
return 0;
}
use of com.revolsys.geometry.model.segment.LineSegment in project com.revolsys.open by revolsys.
the class LineMatchGraph method integrateLine.
/**
* Integrate the line, splitting any edges which the nodes from this line are
* on the other edges.
*
* @param line
* @param index
*/
private void integrateLine(final LineString line, final int index) {
final Set<Edge<LineSegmentMatch>> edgesToProcess = getEdgesWithoutMatch(line, index);
if (!edgesToProcess.isEmpty()) {
for (final Edge<LineSegmentMatch> edge : edgesToProcess) {
if (!edge.isRemoved()) {
final LineSegmentMatch lineSegmentMatch = edge.getObject();
final LineSegment segment = lineSegmentMatch.getSegment();
if (!lineSegmentMatch.hasMatches(index)) {
final List<Edge<LineSegmentMatch>> matchEdges = BoundingBoxIntersectsEdgeVisitor.getEdges(this, edge, this.tolerance);
if (!matchEdges.isEmpty()) {
final boolean allowSplit = edge.getLength() >= 2 * this.tolerance;
final Set<Node<LineSegmentMatch>> splitNodes = new TreeSet<>(new NodeDistanceComparator<>(edge.getFromNode()));
final Node<LineSegmentMatch> lineStart = edge.getFromNode();
final Node<LineSegmentMatch> lineEnd = edge.getToNode();
for (final ListIterator<Edge<LineSegmentMatch>> iterator = matchEdges.listIterator(); iterator.hasNext(); ) {
final Edge<LineSegmentMatch> matchEdge = iterator.next();
iterator.remove();
final LineSegmentMatch matchLineSegmentMatch = matchEdge.getObject();
if (!matchLineSegmentMatch.hasSegment(index) && matchLineSegmentMatch.hasOtherSegment(index)) {
final Node<LineSegmentMatch> line2Start = matchEdge.getFromNode();
final Node<LineSegmentMatch> line2End = matchEdge.getToNode();
final Set<Node<LineSegmentMatch>> matchSplitNodes = new TreeSet<>(new NodeDistanceComparator<>(line2Start));
final LineSegment matchSegment = matchLineSegmentMatch.getSegment();
if (matchEdge.getLength() >= 2 * this.tolerance) {
if (matchSegment.isPointOnLineMiddle(lineStart, this.tolerance)) {
matchSplitNodes.add(lineStart);
}
if (matchSegment.isPointOnLineMiddle(lineEnd, this.tolerance)) {
matchSplitNodes.add(lineEnd);
}
}
if (!matchSplitNodes.isEmpty()) {
final List<Edge<LineSegmentMatch>> splitEdges = splitEdge(matchEdge, matchSplitNodes);
for (final Edge<LineSegmentMatch> splitEdge : splitEdges) {
iterator.add(splitEdge);
}
} else if (allowSplit) {
if (segment.isPointOnLineMiddle(line2Start, this.tolerance)) {
splitNodes.add(line2Start);
}
if (segment.isPointOnLineMiddle(line2End, this.tolerance)) {
splitNodes.add(line2End);
}
}
}
}
if (!splitNodes.isEmpty() && allowSplit) {
splitEdge(edge, splitNodes);
}
}
}
}
}
}
}
use of com.revolsys.geometry.model.segment.LineSegment in project com.revolsys.open by revolsys.
the class LineSegmentMatch method hasMatches.
public boolean hasMatches(final int index1, final int index2) {
if (index1 < this.segments.size() && index2 < this.segments.size()) {
final LineSegment segment1 = this.segments.get(index1);
final LineSegment segment2 = this.segments.get(index2);
return segment1 != null && segment2 != null;
} else {
return false;
}
}
use of com.revolsys.geometry.model.segment.LineSegment in project com.revolsys.open by revolsys.
the class Lineal method addIsSimpleErrors.
static boolean addIsSimpleErrors(final Lineal lineal, final List<GeometryValidationError> errors, final boolean shortCircuit) {
final LineSegmentIndex index = new LineSegmentIndex(lineal);
for (final Segment segment : lineal.segments()) {
final int segmentIndex = segment.getSegmentIndex();
final int partIndex = segment.getPartIndex();
if (segment.getLength() == 0) {
errors.add(new DuplicateVertexError(segment.getGeometryVertex(0)));
} else {
final List<LineSegment> segments = index.queryBoundingBox(segment);
for (final LineSegment lineSegment : segments) {
final Segment segment2 = (Segment) lineSegment;
final int partIndex2 = segment2.getPartIndex();
final int segmentIndex2 = segment2.getSegmentIndex();
if (partIndex2 > partIndex || partIndex == partIndex2 && segmentIndex2 > segmentIndex) {
if (segment.equals(lineSegment)) {
final SelfOverlapSegmentError error = new SelfOverlapSegmentError(segment);
errors.add(error);
if (shortCircuit) {
return false;
}
} else {
final Geometry intersection = segment.getIntersection(lineSegment);
if (intersection instanceof Point) {
final Point pointIntersection = (Point) intersection;
boolean isIntersection = true;
// Process segments on the same linestring part
if (partIndex == partIndex2) {
// segment
if (segmentIndex + 1 == segmentIndex2) {
if (lineSegment.equalsVertex(2, 0, pointIntersection)) {
isIntersection = false;
}
// A loop can touch itself at the start/end
} else if (segment.isLineClosed()) {
if (segment.isLineStart() && segment2.isLineEnd()) {
if (segment.equalsVertex(2, 0, pointIntersection)) {
isIntersection = false;
}
}
}
} else {
if (!segment.isLineClosed() && !segment2.isLineClosed()) {
final boolean segment1EndIntersection = segment.isEndIntersection(pointIntersection);
final boolean segment2EndIntersection = segment2.isEndIntersection(pointIntersection);
if (segment1EndIntersection && segment2EndIntersection) {
isIntersection = false;
}
}
}
if (isIntersection) {
GeometryValidationError error;
if (segment.equalsVertex(2, 0, pointIntersection)) {
final Vertex vertex = segment.getGeometryVertex(0);
error = new SelfIntersectionVertexError(vertex);
} else if (segment.equalsVertex(2, 1, pointIntersection)) {
final Vertex vertex = segment.getGeometryVertex(1);
error = new SelfIntersectionVertexError(vertex);
} else {
error = new SelfIntersectionPointError(lineal, pointIntersection);
}
errors.add(error);
if (shortCircuit) {
return false;
}
}
} else if (intersection instanceof LineSegment) {
final LineSegment lineIntersection = (LineSegment) intersection;
GeometryValidationError error;
if (segment.equals(lineIntersection)) {
error = new SelfOverlapSegmentError(segment);
} else if (lineSegment.equals(lineIntersection)) {
error = new SelfOverlapSegmentError(segment2);
} else {
error = new SelfOverlapLineSegmentError(lineal, lineIntersection);
}
errors.add(error);
if (shortCircuit) {
return false;
}
}
}
}
}
}
}
return errors.isEmpty();
}
Aggregations