Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polygon contains returns different results from PreparedPolygon.contains #1079

Open
drozanesM opened this issue Sep 18, 2024 · 5 comments
Open

Comments

@drozanesM
Copy link

Hi, There are cases when polygon.contains returns different results from preparedPolygon.contains.
I think that the preparedPolygon results are more accurate, but I don't sure.

Here is a code example:

WKTReader reader = new WKTReader();
String wktPolygon = "POLYGON ((16.15984887585909 51.208344998117774, 16.1602053 51.2081523, 16.160338553587007 51.2080322102522, 16.1603838 51.2080093, 16.1604523 51.2079481, 16.160515800000002 51.2078913, 16.1605026 51.2078852, 16.160666609826887 51.20773805748743, 16.1608156 51.2076804, 16.1608258 51.2076706, 16.1608218 51.2076688, 16.1608467 51.207642, 16.1608455 51.2076416, 16.1608783 51.2076081, 16.1609047 51.2075815, 16.1609316 51.20755380000001, 16.1609573 51.207527600000006, 16.1609826 51.207500700000004, 16.161007400000003 51.207474500000004, 16.161037 51.20744740000001, 16.161069 51.2074165, 16.16108604739174 51.2073980778186, 16.1610902 51.2073976, 16.1610991 51.2073887, 16.1610908 51.207385300000006, 16.161083678589154 51.20738598513111, 16.161068200000003 51.207380500000006, 16.1610717 51.20738, 16.1610814 51.2073703, 16.161079 51.207369400000005, 16.161110158084792 51.20733786347694, 16.1611717 51.2073364, 16.161189800000002 51.2073338, 16.1611894 51.20733310000001, 16.1611911 51.2073328, 16.161191692686554 51.2073315158458, 16.1611927 51.2073315, 16.161195600000003 51.207325000000004, 16.161200400000002 51.2073198, 16.1612066 51.207313000000006, 16.161215000000002 51.2073085, 16.1612146 51.2073078, 16.1612158 51.207307300000004, 16.1612158 51.207306, 16.161217100000002 51.207305600000005, 16.1612127 51.2072944, 16.161209 51.207292800000005, 16.1612093 51.207292300000006, 16.16119321025469 51.207291371220144, 16.1611814 51.207286700000004, 16.1611754 51.2072828, 16.1611684 51.207278300000006, 16.161215882113392 51.20722904100919, 16.161219000000003 51.207229600000005, 16.161228700000002 51.2072197, 16.161226900000003 51.207215600000005, 16.161212000000003 51.207209600000006, 16.16119929696821 51.20720687104001, 16.1611353 51.207181600000006, 16.1611368 51.207180300000005, 16.1611328 51.207178400000004, 16.161133500000002 51.207177800000004, 16.1611044 51.2071666, 16.1610813 51.207158, 16.1610815 51.207157300000006, 16.161027100000002 51.2071357, 16.16102051136203 51.20713396843602, 16.161005 51.2071273, 16.160999458516134 51.20712582408192, 16.1609753 51.2071156, 16.16094831240942 51.207108278278334, 16.1608939 51.207087300000005, 16.160895500000002 51.207085600000006, 16.1608789 51.207079300000004, 16.160524638866892 51.2069790117815, 16.160574 51.2069254, 16.1605162 51.206904900000005, 16.1604675 51.2068877, 16.1605063 51.206853800000005, 16.1605296 51.206822900000006, 16.1606697 51.206807600000005, 16.160679051021507 51.20680146546462, 16.1610236 51.2069709, 16.1610658 51.206941, 16.1610121 51.206910300000004, 16.161037108890483 51.20689257305202, 16.1612844 51.207044100000005, 16.1613086 51.2070494, 16.161317800000003 51.207030200000005, 16.161329875617536 51.20703270722568, 16.161377 51.207066100000006, 16.16138779859407 51.207067958774395, 16.1614484 51.2071119, 16.1614608 51.207108600000005, 16.16149005108248 51.20711563151021, 16.161516600000002 51.207137700000004, 16.161534 51.2071406, 16.1615368 51.207130600000006, 16.161541200000002 51.207132200000004, 16.161545200000003 51.207129800000004, 16.1615542 51.2071319, 16.161572500000002 51.207124900000004, 16.1615876 51.2071276, 16.161597404791475 51.207129377118456, 16.161618700000002 51.207158400000004, 16.1616344 51.2071618, 16.1616418 51.2071503, 16.161704298884363 51.20716288658088, 16.161707 51.2071752, 16.1617223 51.207178600000006, 16.1617269 51.207168200000005, 16.161784238522298 51.20718046545781, 16.1617813 51.2071898, 16.161798 51.207193000000004, 16.161803000000003 51.2071826, 16.1618594 51.2071935, 16.161864 51.2072021, 16.161877800000003 51.2071976, 16.161879161871656 51.20719636703383, 16.161957400000002 51.2071727, 16.1619578 51.207173600000004, 16.1619788 51.2071684, 16.161979710126765 51.20716781263749, 16.1620153 51.2071586, 16.1620156 51.2071588, 16.162034600000002 51.207153500000004, 16.162403111773934 51.20694203016768, 16.1624796 51.206985200000005, 16.162535792372555 51.20695956346365, 16.1625766 51.206982800000006, 16.1625647 51.206990700000006, 16.1625479 51.2070019, 16.1624324 51.207059300000004, 16.1624373 51.207065500000006, 16.1623834 51.2070882, 16.162328300000002 51.207110400000005, 16.1622492 51.2071424, 16.1620804 51.2072122, 16.1620364 51.2072276, 16.161895100000002 51.2072811, 16.1618891 51.2072834, 16.1618834 51.2072857, 16.1618797 51.2072872, 16.161878100000003 51.207287900000004, 16.161874100000002 51.207289900000006, 16.161873500000002 51.207290300000004, 16.1618728 51.2072907, 16.1618715 51.207291500000004, 16.1618704 51.207292200000005, 16.1618692 51.2072931, 16.1618681 51.2072939, 16.1618669 51.2072948, 16.1618648 51.207296500000005, 16.161862600000003 51.2072985, 16.1618017 51.207356000000004, 16.1618134 51.2073626, 16.161792600000002 51.2073801, 16.1616176 51.207528, 16.1614812 51.2074714, 16.15991220326994 51.20837378580331, 16.1598931 51.2083651, 16.15984887585909 51.208344998117774))";
String wktLine = "LINESTRING (16.161739400000002 51.2073229, 16.161739400000002 51.2073229)";
try{
Geometry geometry = reader.read(wktPolygon);
Polygon polygon = (Polygon) geometry;
PreparedPolygon preparedPolygon = new PreparedPolygon(polygon);

        geometry = reader.read(wktLine);
        LineString line = (LineString) geometry;
        boolean contains = polygon.contains(line);      // return false
        boolean contains2 = preparedPolygon.contains(line);    //return true


    } catch (ParseException e) {
        e.printStackTrace();
    }
@dr-jts
Copy link
Contributor

dr-jts commented Sep 18, 2024

This is because the LineString input is a zero-length line. Technically in JTS this is an invalid geometry, so according to the contract for topological predicates the result is undefined. Geometry.contains happens to return false for the result. PreparedGeometry is better able to handle this case and so returns true, the more obviously correct answer.

The new RelateNG API (just released in JTS 1.20) fixes this problem. You can use it via setting the jts.relate=ng system property.

@dr-jts
Copy link
Contributor

dr-jts commented Sep 18, 2024

See also #345 and #1050.

@drozanesM
Copy link
Author

thanks

@drozanesM
Copy link
Author

@dr-jts Here is another case, with a valid LineString (here Polygon.contains return true and PreparedPolygon.contains return false):

GeometryFactory geometryFactory = new GeometryFactory();
Polygon polygon = geometryFactory.createPolygon(new Coordinate[]{new Coordinate(16.949476554954934, 52.39745665857356), new Coordinate(16.9495155, 52.3973974), new Coordinate(16.9495109, 52.397389800000006), new Coordinate(16.949507800000003, 52.3973905), new Coordinate(16.949491548039767, 52.39736413378792), new Coordinate(16.9495456, 52.3973516), new Coordinate(16.94954167669903, 52.39734535177994), new Coordinate(16.9495419, 52.397345300000005), new Coordinate(16.949527812299458, 52.397321312834244), new Coordinate(16.9495283, 52.397320500000006), new Coordinate(16.9495282, 52.3973195), new Coordinate(16.949523537577793, 52.3973108986349), new Coordinate(16.949558, 52.3973656), new Coordinate(16.949573700000002, 52.3973875), new Coordinate(16.949682412266327, 52.39752638862495), new Coordinate(16.950163500000002, 52.398290200000005), new Coordinate(16.950149, 52.3982936), new Coordinate(16.950146526506874, 52.39831679735449), new Coordinate(16.9500697, 52.398193400000004), new Coordinate(16.9500378, 52.3981433), new Coordinate(16.9499707, 52.3980365), new Coordinate(16.949920600000002, 52.3979566), new Coordinate(16.949871700000003, 52.3978788), new Coordinate(16.9498439, 52.3978345), new Coordinate(16.949819700000003, 52.397795800000004), new Coordinate(16.9497997, 52.3977639), new Coordinate(16.9497848, 52.3977404), new Coordinate(16.949691, 52.3975908), new Coordinate(16.949690422787413, 52.39759071308382), new Coordinate(16.949676, 52.3975669), new Coordinate(16.949630600000003, 52.3974946), new Coordinate(16.9496077, 52.3974619), new Coordinate(16.94958667421356, 52.39743811802433), new Coordinate(16.949555, 52.397371400000004), new Coordinate(16.949554300000003, 52.3973705), new Coordinate(16.949553100000003, 52.3973698), new Coordinate(16.949551500000002, 52.3973694), new Coordinate(16.9495499, 52.3973694), new Coordinate(16.9495484, 52.3973698), new Coordinate(16.9495472, 52.3973706), new Coordinate(16.9495466, 52.397371500000006), new Coordinate(16.949549997229216, 52.39743910486127), new Coordinate(16.9495429, 52.397440800000005), new Coordinate(16.949476554954934, 52.39745665857356)});
PreparedPolygon preparedPolygon = new PreparedPolygon(polygon);
LineString lineString = geometryFactory.createLineString(new Coordinate[]{new Coordinate(16.9495387, 52.397353200000005), new Coordinate(16.9495429, 52.3973473)});
boolean polygonContains = polygon.contains(lineString); //return true
boolean preparedPolygonContains = preparedPolygon.contains(lineString); //return false

@drozanesM drozanesM reopened this Sep 19, 2024
@dr-jts
Copy link
Contributor

dr-jts commented Sep 19, 2024

Here is another case, with a valid LineString (here Polygon.contains return true and PreparedPolygon.contains return false):

I can't reproduce this. In JTS 1.20 both tests produce the same result of false (as does RelateNG).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants