Geographic Information Systems Asked by Nick B on August 27, 2021
I was wondering if a JTS expert would be able to explain how to detect the below intersection of an inner polygon inside an outer polygon.
I would have thought that at least the "contains" check be false due to the point at 1000/500 being along the right-edge of Polygon1.
Polygon1: POLYGON ((0 0, 1000 0, 1000 1000, 0 1000, 0 0))
Polygon2: POLYGON ((500 500, 1000 500, 600 600, 500 600, 500 500))
Results in:
polygon1.contains(polygon2) = true
polygon1.covers(polygon2) = true
polygon1.touches(polygon2) = false
The only way I can detect this this inner polygon touching the edge of polygon 1 is by iterating through polygon2 points and creating separate points and checking:
polygon1.touches(eachPolygon2Point)
but I’m worried about the performance impacts of doing this on a routine basis. Note sometimes polygon2 might be outside polygon1 so I don’t really want to rely on say creating polygon2 as an inner ring of polygon1 every time either.
Touch is a bit odd when considered naively, but if you look at the JavaDocs you will see the problem with the way you are looking at it. (Emphasis added):
Tests whether this geometry touches the argument geometry. The touches predicate has the following equivalent definitions:
The geometries have at least one point in common, but their interiors do not intersect.
The DE-9IM Intersection Matrix for the two geometries matches at least one of the following patterns
[FT*******] [F**T*****] [F***T****]
If both geometries have dimension 0, the predicate returns false, since points have only interiors. This predicate is symmetric.
In your case the interiors of the two polygons do intersect so the polygons are said to not touch.
If you change polygon 2 to be "POLYGON ((1500 500, 1000 500, 1500 600, 1600 600, 1500 500))" then it does touch polygon 1.
If you want to find polygons that are entirely within a polygon and not touching the boundary, I set up a quick test using the relate
method and a 2nd polygon that doesn't touch polygon1.
WKTReader2 reader = new WKTReader2();
Polygon p1 = (Polygon) reader.read("POLYGON ((0 0, 1000 0, 1000 1000, 0 1000, 0 0))");
Polygon p2 = (Polygon) reader.read("POLYGON ((500 500, 1000 500, 600 600, 500 600, 500 500))");
Polygon p3 = (Polygon) reader.read("POLYGON ((500 500, 600 600, 500 600, 500 500))");
IntersectionMatrix relate1 = p1.relate(p2);
System.out.println("relate " + relate1);
IntersectionMatrix relate2 = p1.relate(p3);
System.out.println("relate " + relate2);
This gives:
relate 212F01FF2
relate 212FF1FF2
And there is a difference, so referring to the wikipedia page for DE-9IM, I can find out that this is saying that in one case the boundaries have a point (0
dimension) in common and do not interact in the other (F
).
I don't think there is a named operation for this but you could use relate.get(1,1) >= 0
to check for interactions (False
returns -1
).
Correct answer by Ian Turton on August 27, 2021
The OGC named predicates don't cover all topological situations of interest, and this is one of those. As it happens, JTS does implement this relationship test in PreparedGeometry
(and as a bonus that is optimized for repeated tests). See Javadoc here.
Answered by dr_jts on August 27, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP