NodeSections.java
/*
* Copyright (c) 2024 Martin Davis.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jts.operation.relateng;
import java.util.ArrayList;
import java.util.List;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
class NodeSections {
private Coordinate nodePt;
private List<NodeSection> sections = new ArrayList<NodeSection>();;
public NodeSections(Coordinate pt) {
this.nodePt = pt;
}
public Coordinate getCoordinate() {
return nodePt;
}
public void addNodeSection(NodeSection e) {
//System.out.println(e);
sections.add(e);
}
public boolean hasInteractionAB() {
boolean isA = false;
boolean isB = false;
for (NodeSection ns : sections) {
if (ns.isA())
isA = true;
else
isB = true;
if (isA && isB)
return true;
}
return false;
}
public Geometry getPolygonal(boolean isA) {
for (NodeSection ns : sections) {
if (ns.isA() == isA) {
Geometry poly = ns.getPolygonal();
if (poly != null)
return poly;
}
}
return null;
}
public RelateNode createNode() {
prepareSections();
RelateNode node = new RelateNode(nodePt);
int i = 0;
while (i < sections.size()) {
NodeSection ns = sections.get(i);
//-- if there multiple polygon sections incident at node convert them to maximal-ring structure
if (ns.isArea() && hasMultiplePolygonSections(sections, i)) {
List<NodeSection> polySections = collectPolygonSections(sections, i);
List<NodeSection> nsConvert = PolygonNodeConverter.convert(polySections);
node.addEdges(nsConvert);
i += polySections.size();
}
else {
//-- the most common case is a line or a single polygon ring section
node.addEdges(ns);
i += 1;
}
}
return node;
}
/**
* Sorts the sections so that:
* <ul>
* <li>lines are before areas
* <li>edges from the same polygon are contiguous
* </ul>
*/
private void prepareSections() {
sections.sort(null);
//TODO: remove duplicate sections
}
private static boolean hasMultiplePolygonSections(List<NodeSection> sections, int i) {
//-- if last section can only be one
if (i >= sections.size() - 1)
return false;
//-- check if there are at least two sections for same polygon
NodeSection ns = sections.get(i);
NodeSection nsNext = sections.get(i + 1);
return ns.isSamePolygon(nsNext);
}
private static List<NodeSection> collectPolygonSections(List<NodeSection> sections, int i) {
List<NodeSection> polySections = new ArrayList<NodeSection>();
//-- note ids are only unique to a geometry
NodeSection polySection = sections.get(i);
while (i < sections.size() &&
polySection.isSamePolygon(sections.get(i))) {
polySections.add(sections.get(i));
i++;
}
return polySections;
}
}