Skip to content

Commit

Permalink
Change API
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed May 4, 2024
1 parent 466a637 commit 0d101c8
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static Geometry intersects(Geometry a, final Geometry mask)
{
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return RelateNG.evaluate(TopologyPredicateFactory.intersects(), mask, g);
return RelateNG.relate(mask, g, TopologyPredicateFactory.intersects());
}
});
}
Expand All @@ -32,7 +32,7 @@ public static Geometry intersectsPrep(Geometry a, final Geometry mask)
RelateNG relateNG = RelateNG.prepare(mask);
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return relateNG.evaluate(TopologyPredicateFactory.intersects(), g);
return relateNG.relate(g, TopologyPredicateFactory.intersects());
}
});
}
Expand All @@ -41,7 +41,7 @@ public static Geometry covers(Geometry a, final Geometry mask)
{
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return RelateNG.evaluate(TopologyPredicateFactory.covers(), mask, g);
return RelateNG.relate(mask, g, TopologyPredicateFactory.covers());
}
});
}
Expand All @@ -51,7 +51,7 @@ public static Geometry coversPrep(Geometry a, final Geometry mask)
RelateNG relateNG = RelateNG.prepare(mask);
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return relateNG.evaluate(TopologyPredicateFactory.covers(), g);
return relateNG.relate(g, TopologyPredicateFactory.covers());
}
});
}
Expand All @@ -60,7 +60,7 @@ public static Geometry adjacentTo(Geometry a, final Geometry mask)
{
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return RelateNG.evaluate(TopologyPredicateFactory.relate("****1****"), mask, g);
return RelateNG.relate(mask, g, TopologyPredicateFactory.relate("****1****"));
}
});
}
Expand All @@ -70,7 +70,7 @@ public static Geometry adjacentToPrep(Geometry a, final Geometry mask)
RelateNG relateNG = RelateNG.prepare(mask);
return SelectionFunctions.select(a, new GeometryPredicate() {
public boolean isTrue(Geometry g) {
return relateNG.evaluate(TopologyPredicateFactory.relate("****1****"), g);
return relateNG.relate(g, TopologyPredicateFactory.relate("****1****"));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,49 @@

public class SpatialPredicateNGFunctions {
public static boolean contains(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.contains(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.contains());
}
public static boolean covers(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.covers(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.covers());
}
public static boolean coveredBy(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.coveredBy(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.coveredBy());
}
public static boolean disjoint(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.disjoint(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.disjoint());
}
public static boolean equals(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.equalsTopo(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.equalsTopo());
}
public static boolean equalsTopo(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.equalsTopo(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.equalsTopo());
}
public static boolean intersects(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.intersects(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.intersects());
}
public static boolean crosses(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.crosses(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.crosses());
}
public static boolean overlaps(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.overlaps(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.overlaps());
}
public static boolean touches(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.touches(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.touches());
}
public static boolean within(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.within(), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.within());
}

public static boolean adjacent(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.relate(TopologyPredicateFactory.ADJACENT), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.relate(TopologyPredicateFactory.ADJACENT));
}

public static boolean containsProperly(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.relate(TopologyPredicateFactory.CONTAINS_PROPERLY), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.relate(TopologyPredicateFactory.CONTAINS_PROPERLY));
}

public static boolean interiorIntersects(Geometry a, Geometry b) {
return RelateNG.evaluate(TopologyPredicateFactory.relate(TopologyPredicateFactory.INTERIOR_INTERSECTS), a, b);
return RelateNG.relate(a, b, TopologyPredicateFactory.relate(TopologyPredicateFactory.INTERIOR_INTERSECTS));
}

public static boolean relate(Geometry a, Geometry b, String mask) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
* between two geometries.
* Standard and custom topological predicates are provided by {@link TopologyPredicateFactory}.
* <p>
* The algorithm used provides the following:
* The RelateNG algorithm provides the following:
* <ol>
* <li>Efficient short-circuited evaluation of all topological predicates
* (including custom DE-9IM matrix patterns)
* (including matching custom DE-9IM matrix patterns)
* <li>Optimized repeated evaluation of predicates against a single geometry
* via cached spatial indexes (AKA "prepared mode")
* <li>Robust computation (only point-local topology is required,
Expand All @@ -51,6 +51,19 @@
* <li>Support for {@link BoundaryNodeRule}s
* </ol>
*
* <h3>DE-9IM Pattern Matching</h3>
* Matrix patterns are specified as a 9-character string
* containing the row-wise pattern symbols for the DE-9IM matrix entries.
* The pattern symbols are:
* <ul>
* <li><tt>0</tt> - dimension of topological interaction is 0
* <li><tt>1</tt> - dimension of topological interaction is 1
* <li><tt>2</tt> - dimension of topological interaction is 2
* <li><tt>T</tt> - there is topological interaction of any dimension
* <li><tt>F</tt> - there is no topological interaction
* <li><tt>*</tt> - any topological interaction is allowed (including none)
* </ul>
*
* This implementation replaces {@link RelateOp} and {@link PreparedGeometry}.
*
* <h3>FUTURE WORK</h3>
Expand All @@ -67,14 +80,14 @@
public class RelateNG
{

public static boolean evaluate(TopologyPredicate pred, Geometry a, Geometry b) {
public static boolean relate(Geometry a, Geometry b, TopologyPredicate pred) {
RelateNG rng = new RelateNG(a, false);
return rng.evaluate(pred, b);
return rng.relate(b, pred);
}

public static boolean evaluate(TopologyPredicate pred, Geometry a, Geometry b, BoundaryNodeRule bnRule) {
public static boolean relate(Geometry a, Geometry b, TopologyPredicate pred, BoundaryNodeRule bnRule) {
RelateNG rng = new RelateNG(a, false, bnRule);
return rng.evaluate(pred, b);
return rng.relate(b, pred);
}

public static boolean relate(Geometry a, Geometry b, String imPattern) {
Expand All @@ -92,10 +105,25 @@ public static IntersectionMatrix relate(Geometry a, Geometry b, BoundaryNodeRule
return rng.relate(b);
}

/**
* Creates a prepared RelateNG instance to optimize the
* evaluation of relationships against a single geometry.
*
* @param a the input A
* @return a prepared instance
*/
public static RelateNG prepare(Geometry a) {
return new RelateNG(a, true);
}

/**
* Creates a prepared RelateNG instance to optimize the
* computation of predicates against a single geometry.
*
* @param a the input A
* @param bnRule the required BoundaryNodeRule
* @return a prepared instance
*/
public static RelateNG prepare(Geometry a, BoundaryNodeRule bnRule) {
return new RelateNG(a, true, bnRule);
}
Expand All @@ -113,20 +141,38 @@ private RelateNG(Geometry inputA, boolean isPrepared, BoundaryNodeRule bnRule) {
geomA = new RelateGeometry(inputA, isPrepared, boundaryNodeRule);
}

public boolean relate(Geometry b, String imPattern) {
RelatePatternPredicate rel = new RelatePatternPredicate(imPattern);
return evaluate(rel, b);
}

public IntersectionMatrix relate(Geometry b) {
RelateMatrixPredicate rel = new RelateMatrixPredicate();
evaluate(rel, b);
relate(b, rel);
return rel.getIM();
}
}

/**
* Tests whether the topological relationship against a geometry
* matches the given DE-9IM matrix pattern.
*
* @param b the geometry to test against
* @param imPattern the DE-9IM pattern to match
* @return whether the geometries relationship matches the DE-9IM pattern
*
* @see IntersectionMatrix
*/
public boolean relate(Geometry b, String imPattern) {
RelatePatternPredicate rel = new RelatePatternPredicate(imPattern);
return relate(b, rel);
}

public boolean evaluate(TopologyPredicate predicate, Geometry inputB) {
/**
* Tests whether the topological relationship to a geometry
* satisfies the specified topology predicate.
*
* @param b the geometry to test against
* @param predicate the topological predicate
* @return true if the predicate is satisfied
*/
public boolean relate(Geometry b, TopologyPredicate predicate) {

RelateGeometry geomB = new RelateGeometry(inputB, boundaryNodeRule);
RelateGeometry geomB = new RelateGeometry(b, boundaryNodeRule);

if (geomA.isEmpty() && geomB.isEmpty()) {
//TODO: what if predicate is disjoint? Perhaps use result on disjoint envs?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* The algorithm has the following capabilities:
* <ol>
* <li>Efficient short-circuited evaluation of all topological predicates
* (including custom DE-9IM patterns)
* (including matching custom DE-9IM patterns)
* <li>Optimized repeated evaluation of predicates against a single geometry
* via cached spatial indexes (AKA "prepared mode")
* <li>Robust computation (since only point-local topology is required,
Expand Down Expand Up @@ -71,8 +71,8 @@
* <h3>Union Semantics for GeometryCollections</h3>
* GeometryCollections may contain geometries of different dimensions, nested to any level.
* The element geometries may overlap in any combination.
* To provide consistent results when evaluating topological predicates,
* RelateNG uses "union semantics".
* To extend the definition of the DE-9IM model to arbitrary collections
* and provide consistent results, RelateNG uses "union semantics".
* This is specified by:
* <ul>
* <li>GeometryCollections are evaluated as if they were replaced by the topological union
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected void checkRelate(String wkta, String wktb, String expectedValue) {
Geometry b = read(wktb);
RelateMatrixPredicate rel = new RelateMatrixPredicate();
TopologyPredicate predTrace = new TopologyPredicateTracer(rel);
RelateNG.evaluate(predTrace, a, b);
RelateNG.relate(a, b, predTrace);
String actualVal = rel.getIM().toString();
assertEquals(expectedValue, actualVal);
}
Expand All @@ -74,7 +74,7 @@ protected void checkRelatePattern(String wkta, String wktb, String pattern, bool
Geometry b = read(wktb);
RelatePatternPredicate rel = new RelatePatternPredicate(pattern);
TopologyPredicate predTrace = new TopologyPredicateTracer(rel);
RelateNG.evaluate(predTrace, a, b);
RelateNG.relate(a, b, predTrace);
boolean actualVal = rel.value();
assertEquals(expectedValue, actualVal);
}
Expand All @@ -84,7 +84,7 @@ protected void checkPredicate(TopologyPredicate pred, String wkta, String wktb,
Geometry b = read(wktb);
System.out.println("Pred: " + pred.name());
TopologyPredicate predTrace = new TopologyPredicateTracer(pred);
boolean actualVal = RelateNG.evaluate(predTrace, a, b);
boolean actualVal = RelateNG.relate(a, b, predTrace);
assertEquals(expectedValue, actualVal);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ public void runIntersectsOldPrep()
public void runIntersectsNG()
{
for (Geometry b : geomB) {
RelateNG.evaluate(TopologyPredicateFactory.intersects(), geomA, b);
RelateNG.relate(geomA, b, TopologyPredicateFactory.intersects());
}
}

public void runIntersectsNGPrep()
{
RelateNG rng = RelateNG.prepare(geomA);
for (Geometry b : geomB) {
rng.evaluate(TopologyPredicateFactory.intersects(), b);
rng.relate(b, TopologyPredicateFactory.intersects());
}
}

Expand All @@ -133,23 +133,23 @@ public void runContainsOldPrep()
public void runContainsNG()
{
for (Geometry b : geomB) {
RelateNG.evaluate(TopologyPredicateFactory.contains(), geomA, b);
RelateNG.relate(geomA, b, TopologyPredicateFactory.contains());
}
}

public void runContainsNGPrep()
{
RelateNG rng = RelateNG.prepare(geomA);
for (Geometry b : geomB) {
rng.evaluate(TopologyPredicateFactory.contains(), b);
rng.relate(b, TopologyPredicateFactory.contains());
}
}

public void xrunContainsNGPrepValidate()
{
RelateNG rng = RelateNG.prepare(geomA);
for (Geometry b : geomB) {
boolean resultNG = rng.evaluate(TopologyPredicateFactory.contains(), b);
boolean resultNG = rng.relate(b, TopologyPredicateFactory.contains());
boolean resultOld = geomA.contains(b);
assertEquals(resultNG, resultOld);
}
Expand Down
Loading

0 comments on commit 0d101c8

Please sign in to comment.