use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class LineMerger method mergeDegree2FromEnds.
private void mergeDegree2FromEnds() {
final List<Node<LineString>> endNodes = this.graph.getNodes(node -> node.getDegree() != 2);
for (final Node<LineString> node : endNodes) {
if (!node.isRemoved()) {
for (final Edge<LineString> edge : Lists.toArray(node.getEdges())) {
if (!edge.isRemoved()) {
final List<LineString> lines = new ArrayList<>();
final List<Boolean> lineForwards = new ArrayList<>();
double forwardsLength = 0;
double reverseLength = 0;
Edge<LineString> previousEdge = null;
Node<LineString> currentNode = node;
Edge<LineString> currentEdge = edge;
do {
final LineString line = currentEdge.getLineString();
final double length = line.getLength();
final boolean forwards = currentEdge.getEnd(currentNode).isFrom();
if (forwards) {
forwardsLength += length;
} else {
reverseLength += length;
}
lines.add(line);
lineForwards.add(forwards);
currentNode = currentEdge.getOppositeNode(currentNode);
previousEdge = currentEdge;
currentEdge = currentNode.getNextEdge(previousEdge);
} while (currentNode.getDegree() == 2);
if (lines.size() > 1) {
LineString mergedLine = null;
final boolean mergeForwards = forwardsLength >= reverseLength;
int i = 0;
for (LineString line : lines) {
final boolean forwards = lineForwards.get(i);
if (forwards != mergeForwards) {
line = line.reverse();
}
if (mergedLine == null) {
mergedLine = line;
} else {
mergedLine = mergedLine.merge(line);
}
i++;
}
this.graph.addEdge(mergedLine);
this.graph.removeEdges(lines);
}
}
}
}
}
if (this.allowLoops) {
final List<Node<LineString>> psudeoNodes = this.graph.getNodes(node -> node.getDegree() == 2);
for (final Node<LineString> node : psudeoNodes) {
if (!node.isRemoved()) {
final List<Edge<LineString>> edges = node.getEdges();
if (edges.size() == 2) {
final Edge<LineString> edge1 = edges.get(0);
final Edge<LineString> edge2 = edges.get(1);
if (edge1 != edge2) {
final LineString line1 = edge1.getLineString();
final LineString line2 = edge2.getLineString();
final LineString mergedLine = line1.merge(line2);
this.graph.addEdge(mergedLine);
this.graph.remove(edge1);
this.graph.remove(edge2);
}
}
}
}
}
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class LineStringGraph method getPointsOnEdges.
public Map<Edge<LineSegment>, List<Node<LineSegment>>> getPointsOnEdges(final Graph<LineSegment> graph1, final double tolerance) {
final Map<Edge<LineSegment>, List<Node<LineSegment>>> pointsOnEdge1 = new HashMap<>();
for (final Edge<LineSegment> edge : getEdges()) {
final Node<LineSegment> fromNode = edge.getFromNode();
final Node<LineSegment> toNode = edge.getToNode();
final LineSegment lineSegment = edge.getObject();
final PointOnLineSegment coordinatesFilter = new PointOnLineSegment(lineSegment, tolerance);
final NodeCoordinatesFilter<LineSegment> nodeFilter = new NodeCoordinatesFilter<>(coordinatesFilter);
final NodeDistanceComparator<LineSegment> comparator = new NodeDistanceComparator<>(fromNode);
final List<Node<LineSegment>> nodes = graph1.getNodes(nodeFilter, comparator);
for (final Iterator<Node<LineSegment>> iterator = nodes.iterator(); iterator.hasNext(); ) {
final Node<LineSegment> node = iterator.next();
if (node.equals(2, fromNode)) {
iterator.remove();
} else if (node.equals(2, toNode)) {
iterator.remove();
}
}
if (!nodes.isEmpty()) {
pointsOnEdge1.put(edge, nodes);
}
}
return pointsOnEdge1;
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class MergeRecordsDialog method run.
public void run() {
try {
final List<LayerRecord> originalRecords = this.layer.getMergeableSelectedRecords();
String errorMessage = "";
final DataType geometryType = this.layer.getGeometryType();
this.mergedRecords = new HashMap<>();
if (originalRecords.size() < 2) {
errorMessage = " at least two records must be selected to merge.";
} else if (!DataTypes.LINE_STRING.equals(geometryType) && !DataTypes.MULTI_LINE_STRING.equals(geometryType)) {
errorMessage = "Merging " + geometryType + " not currently supported";
} else {
final RecordGraph graph = new RecordGraph();
for (final LayerRecord originalRecord : originalRecords) {
Geometry geometry = originalRecord.getGeometry();
if (geometry != null && !geometry.isEmpty()) {
geometry = this.layer.getGeometryFactory().geometry(LineString.class, geometry);
if (geometry instanceof LineString) {
final Record mergeableRecord = new ArrayRecord(originalRecord);
mergeableRecord.setGeometryValue(geometry);
this.mergeableToOiginalRecordMap.put(mergeableRecord, originalRecord);
graph.addEdge(mergeableRecord);
}
}
}
for (final Node<Record> node : graph.nodes()) {
if (node != null) {
final List<Edge<Record>> edges = node.getEdges();
if (edges.size() == 2) {
final Edge<Record> edge1 = edges.get(0);
final Record record1 = edge1.getObject();
final Edge<Record> edge2 = edges.get(1);
final Record record2 = edge2.getObject();
if (record1 != record2) {
final Record mergedRecord = this.layer.getMergedRecord(node, record1, record2);
graph.addEdge(mergedRecord);
edge1.remove();
edge2.remove();
final Set<LayerRecord> sourceRecords = new LinkedHashSet<>();
// TODO verify orientation to ensure they are in the correct
// order
// and see if they are reversed
CollectionUtil.addIfNotNull(sourceRecords, this.mergeableToOiginalRecordMap.get(record1));
CollectionUtil.addAllIfNotNull(sourceRecords, this.mergedRecords.remove(record1));
CollectionUtil.addIfNotNull(sourceRecords, this.mergeableToOiginalRecordMap.get(record2));
CollectionUtil.addAllIfNotNull(sourceRecords, this.mergedRecords.remove(record2));
this.mergedRecords.put(mergedRecord, sourceRecords);
replaceRecord(mergedRecord, record1);
replaceRecord(mergedRecord, record2);
}
}
}
}
}
final String message = errorMessage;
Invoke.later(() -> setMergedRecords(message, this.mergedRecords));
} catch (final Throwable e) {
Logs.error(this, "Error " + this, e);
}
}
Aggregations