package com.revolsys.geometry.graph.visitor;
import com.revolsys.geometry.graph.Edge;
import com.revolsys.geometry.graph.EdgeVisitor;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.LineString;
import com.revolsys.geometry.model.Point;
import com.revolsys.geometry.model.coordinates.LineSegmentUtil;
import com.revolsys.math.Angle;
public class NearParallelEdgeVisitor<T> extends EdgeVisitor<T> {
private final LineString line;
private final double maxDistance;
public NearParallelEdgeVisitor(final LineString line, final double maxDistance) {
this.line = line;
this.maxDistance = maxDistance;
}
@Override
public void accept(final Edge<T> edge) {
final LineString matchLine = edge.getLine();
if (isAlmostParallel(matchLine)) {
super.accept(edge);
}
}
@Override
public BoundingBox getEnvelope() {
BoundingBox envelope = this.line.getBoundingBox();
envelope = envelope.expand(this.maxDistance);
return envelope;
}
private boolean isAlmostParallel(final LineString matchLine) {
if (this.line.getBoundingBox().distance(matchLine.getBoundingBox()) > this.maxDistance) {
return false;
}
final LineString coords = this.line;
final LineString matchCoords = this.line;
Point previousCoordinate = coords.getPoint(0);
for (int i = 1; i < coords.getVertexCount(); i++) {
final Point coordinate = coords.getPoint(i);
Point previousMatchCoordinate = matchCoords.getPoint(0);
for (int j = 1; j < coords.getVertexCount(); j++) {
final Point matchCoordinate = matchCoords.getPoint(i);
final double distance = LineSegmentUtil.distanceLineLine(previousCoordinate, coordinate,
previousMatchCoordinate, matchCoordinate);
if (distance <= this.maxDistance) {
final double angle1 = Angle.normalizePositive(previousCoordinate.angle2d(coordinate));
final double angle2 = Angle
.normalizePositive(previousMatchCoordinate.angle2d(matchCoordinate));
final double angleDiff = Math.abs(angle1 - angle2);
if (angleDiff <= Math.PI / 6) {
return true;
}
}
previousMatchCoordinate = matchCoordinate;
}
previousCoordinate = coordinate;
}
return false;
}
}