Skip to content

Commit

Permalink
Improve GC scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed May 1, 2024
1 parent 41774b9 commit 8afdd16
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

Expand All @@ -24,9 +25,9 @@
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryCollectionIterator;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Location;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
Expand All @@ -45,14 +46,17 @@ public static String name(boolean isA) {
}

private Geometry geom;
private int dim;
//private LinearBoundary lineBoundary;
private boolean isPrepared = false;

private int dim = Dimension.FALSE;
private List<Coordinate> pts;
private Set<Coordinate> uniquePoints;
private BoundaryNodeRule boundaryNodeRule;
private RelatePointLocator locator;
private int elementId = 0;
private boolean hasPoints;
private boolean hasLines;
private boolean hasAreas;

public RelateGeometry(Geometry input) {
this(input, false, BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE);
Expand All @@ -67,12 +71,51 @@ public RelateGeometry(Geometry input, boolean isPrepared, BoundaryNodeRule bnRul
this.isPrepared = isPrepared;
this.boundaryNodeRule = bnRule;
dim = input.getDimension();
analyzeDimensions();
}

private RelatePointLocator getLocator() {
if (locator == null)
locator = new RelatePointLocator(geom, isPrepared, boundaryNodeRule);
return locator;
private void analyzeDimensions() {
if (geom.isEmpty()) {
return;
}
if (geom instanceof Point || geom instanceof MultiPoint) {
hasPoints = true;
dim = Dimension.P;
return;
}
if (geom instanceof LineString || geom instanceof MultiLineString) {
hasLines = true;
dim = Dimension.L;
return;
}
if (geom instanceof Polygon || geom instanceof MultiPolygon) {
hasAreas = true;
dim = Dimension.A;
return;
}
//-- analyze a (possibly mixed type) collection
Iterator geomi = new GeometryCollectionIterator(geom);
while (geomi.hasNext()) {
Geometry elem = (Geometry) geomi.next();
if (elem.isEmpty())
continue;
if (elem instanceof Point) {
hasPoints = true;
if (dim < Dimension.P) dim = Dimension.P;
}
if (elem instanceof LineString) {
hasLines = true;
if (dim < Dimension.L) dim = Dimension.L;
}
if (elem instanceof Polygon) {
hasAreas = true;
if (dim < Dimension.A) dim = Dimension.A;
}
}
}

public Geometry getGeometry() {
return geom;
}

public boolean isPrepared() {
Expand All @@ -86,32 +129,38 @@ public Envelope getEnvelope() {
public int getDimension() {
return dim;
}

public boolean hasDimension(int dim) {
switch (dim) {
case Dimension.P: return hasPoints;
case Dimension.L: return hasLines;
case Dimension.A: return hasAreas;
}
return false;
}

public int getDimensionEffective() {
if (geom.isEmpty()) return Dimension.FALSE;
if (getDimension() == 1 && geom.getLength() == 0)
return Dimension.P;
//TODO: for mixed-dim collections, return largest non-empty dim
return geom.getDimension();
}

public boolean isDimension(int dimension) {
return dim == dimension;
}

public Geometry getGeometry() {
return geom;
return dim;
}

public boolean hasEdges() {
return getDimensionEffective() > Dimension.P;
return hasLines || hasAreas;
}

public boolean isZeroLength() {
//TODO: evaluate component-wise and short-circuit
return geom.getLength() <= 0;
}

private RelatePointLocator getLocator() {
if (locator == null)
locator = new RelatePointLocator(geom, isPrepared, boundaryNodeRule);
return locator;
}

public boolean isNodeInArea(Coordinate nodePt, Geometry parentPolygonal) {
int loc = getLocator().locateNodeWithDim(nodePt, parentPolygonal);
return loc == DimensionLocation.AREA_INTERIOR;
Expand Down Expand Up @@ -166,20 +215,6 @@ public boolean isPolygonal() {
return geom instanceof Polygon
|| geom instanceof MultiPolygon;
}

public boolean hasPoints() {
if (geom instanceof LineString
|| geom instanceof MultiLineString
|| geom instanceof Polygon
|| geom instanceof MultiPolygon)
return false;
//TODO: analyze GCs for containing points
return true;
}

public boolean hasAnyPoints() {
return getDimension() == Dimension.P;
}

public boolean isEmpty() {
return geom.isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ private void computeAtPoints(RelateGeometry geomSrc, boolean isA,

private boolean computePoints(RelateGeometry geom, boolean isA, RelateGeometry geomTarget,
TopologyComputer topoComputer) {
if (! geom.hasPoints()) {
if (! geom.hasDimension(Dimension.P)) {
return false;
}

Expand All @@ -255,9 +255,9 @@ private boolean computePoints(RelateGeometry geom, boolean isA, RelateGeometry g

private boolean computeLineEnds(RelateGeometry geom, boolean isA, RelateGeometry geomTarget,
TopologyComputer topoComputer) {
//TODO: handle mixed GCs
if (geom.getDimension() != Dimension.L)
if (! geom.hasDimension(Dimension.L)) {
return false;
}

Iterator geomi = new GeometryCollectionIterator(geom.getGeometry());
while (geomi.hasNext()) {
Expand Down Expand Up @@ -297,6 +297,9 @@ private void computeLineEnd(RelateGeometry geom, boolean isA, Coordinate pt,
}

private boolean computeAreaVertices(RelateGeometry geom, boolean isA, RelateGeometry geomTarget, TopologyComputer topoComputer) {
if (! geom.hasDimension(Dimension.A)) {
return false;
}
//-- evaluate for line and area targets only, since points will be handled in the reverse direction
if (geomTarget.getDimension() < Dimension.L)
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ private int locateWithDim(Coordinate p, boolean isNode, Geometry parentPolygonal

/**
* In a polygonal geometry a node must be on the boundary.
* This is not the case for a mixed collection, since
* the node may be in the interior of a polygon
* (This is not the case for a mixed collection, since
* the node may be in the interior of a polygon.)
*/
if (isNode && (geom instanceof Polygon || geom instanceof MultiPolygon))
return DimensionLocation.AREA_BOUNDARY;
Expand Down

0 comments on commit 8afdd16

Please sign in to comment.