From svn_geos at osgeo.org Fri Dec 5 01:37:26 2014 From: svn_geos at osgeo.org (svn_geos at osgeo.org) Date: Fri, 5 Dec 2014 01:37:26 -0800 Subject: [geos-commits] r4038 - in trunk/tests/unit: algorithm capi Message-ID: <20141205093726.DFD1A3902C2@trac.osgeo.org> Author: mloskot Date: 2014-12-05 01:37:26 -0800 (Fri, 05 Dec 2014) New Revision: 4038 Modified: trunk/tests/unit/algorithm/RobustLineIntersectorTest.cpp trunk/tests/unit/capi/GEOSPreparedGeometryTest.cpp Log: Add two test cases, point-on-segment and point-on-vertex. Curious detail of the tests is that points of interest have nearly exact X of tested points, the values differ after 14th decimal place. The tests provided test geometries for intersection with and without coordinates trimming after the 14th place (as per Martin Davis suggestion). It has been extensively discussed in Ticket #591 and https://github.com/libgeos/libgeos/pull/40 with Martin Davis' input. Modified: trunk/tests/unit/algorithm/RobustLineIntersectorTest.cpp =================================================================== --- trunk/tests/unit/algorithm/RobustLineIntersectorTest.cpp 2014-11-26 15:33:49 UTC (rev 4037) +++ trunk/tests/unit/algorithm/RobustLineIntersectorTest.cpp 2014-12-05 09:37:26 UTC (rev 4038) @@ -3,6 +3,7 @@ #include // geos +#include #include #include #include @@ -251,5 +252,68 @@ } + // Test intersects: point on segment with FLOAT PM + // X coordinate of 3rd and 4th vertises of the line are not + // float-point exact with X coordinate of the point. + // The X values differ after 14th decimal place: + // POINT (-23.1094689600055080 50.5195368635957180) + // --------------------^^^^^^^------------^^^^^^^^ + // LINESTRING 3rd and 4th points + // -23.1094689600055150 50.5223376452201340, + // -23.1094689600055010 50.5169177629559480, + // --------------------^^^^^^^------------^^^^^^^^ + // So, in float-point precision model, the point does DOES NOT intersect the segment. + template<> + template<> + void object::test<14>() + { + geos::io::WKBReader reader; + + // POINT located between 3rd and 4th vertex of LINESTRING + // POINT(-23.1094689600055080 50.5195368635957180) + std::string point("01010000009a266328061c37c0e21a172f80424940"); + // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409) + std::string line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940"); + std::stringstream sPoint(point); + GeomPtr gPoint(reader.readHEX(sPoint)); + std::stringstream sLine(line); + GeomPtr gLine(reader.readHEX(sLine)); + int ret = gLine->intersects(gPoint.get()); + ensure_equals(ret, 0); + } + + // Test intersects: point on segment with FIXED PM + // X coordinate of 3rd and 4th vertises of the line are not + // float-point exact with X coordinate of the point. + // The X values differ after 14th decimal place: + // POINT (-23.1094689600055080 50.5195368635957180) + // --------------------^^^^^^^------------^^^^^^^^ + // LINESTRING 3rd and 4th points + // -23.1094689600055150 50.5223376452201340, + // -23.1094689600055010 50.5169177629559480, + // --------------------^^^^^^^------------^^^^^^^^ + // So, if float-point values are trimmed up to 14 decimal digits, the point DOES intersect the segment. + + template<> + template<> + void object::test<15>() + { + geos::geom::PrecisionModel pm(1e+13); + geos::geom::GeometryFactory factory(&pm); + geos::io::WKBReader reader(factory); + + // POINT located between 3rd and 4th vertex of LINESTRING + // POINT(-23.1094689600055080 50.5195368635957180) + std::string point("01010000009a266328061c37c0e21a172f80424940"); + // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409) + std::string line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940"); + std::stringstream sPoint(point); + GeomPtr gPoint(reader.readHEX(sPoint)); + std::stringstream sLine(line); + GeomPtr gLine(reader.readHEX(sLine)); + int ret = gLine->intersects(gPoint.get()); + ensure_equals(ret, 1); + } + } // namespace tut Modified: trunk/tests/unit/capi/GEOSPreparedGeometryTest.cpp =================================================================== --- trunk/tests/unit/capi/GEOSPreparedGeometryTest.cpp 2014-11-26 15:33:49 UTC (rev 4037) +++ trunk/tests/unit/capi/GEOSPreparedGeometryTest.cpp 2014-12-05 09:37:26 UTC (rev 4038) @@ -4,6 +4,7 @@ #include // geos #include +#include // std #include #include @@ -170,6 +171,95 @@ } + // Test PreparedIntersects: point on segment with FLOAT PM + // X coordinate of 3rd and 4th vertises of the line are not + // float-point exact with X coordinate of the point. + // The X values differ after 14th decimal place: + // POINT (-23.1094689600055080 50.5195368635957180) + // --------------------^^^^^^^------------^^^^^^^^ + // LINESTRING 3rd and 4th points + // -23.1094689600055150 50.5223376452201340, + // -23.1094689600055010 50.5169177629559480, + // --------------------^^^^^^^------------^^^^^^^^ + // So, in float-point precision model, the point does DOES NOT intersect the segment. + // See RobustLineIntersectorTest.cpp for similar test cases. + template<> + template<> + void object::test<7>() + { + geos::io::WKBReader reader; + + // POINT located between 3rd and 4th vertex of LINESTRING + // POINT(-23.1094689600055080 50.5195368635957180) + std::string point("01010000009a266328061c37c0e21a172f80424940"); + // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409) + std::string line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940"); + std::stringstream sPoint(point); + geom2_ = reinterpret_cast(reader.readHEX(sPoint)); + std::stringstream sLine(line); + geom1_ = reinterpret_cast(reader.readHEX(sLine)); + + prepGeom1_ = GEOSPrepare(geom1_); + ensure(0 != prepGeom1_); + int ret = GEOSPreparedIntersects(prepGeom1_, geom2_); + ensure_equals(ret, 0); + } + + // Test PreparedIntersects: point on segment with FIXED PM + // X coordinate of 3rd and 4th vertises of the line are not + // float-point exact with X coordinate of the point. + // The X values differ after 14th decimal place: + // POINT (-23.1094689600055080 50.5195368635957180) + // --------------------^^^^^^^------------^^^^^^^^ + // LINESTRING 3rd and 4th points + // -23.1094689600055150 50.5223376452201340, + // -23.1094689600055010 50.5169177629559480, + // --------------------^^^^^^^------------^^^^^^^^ + // So, if float-point values are trimmed up to 14 decimal digits, the point DOES intersect the segment. + // See RobustLineIntersectorTest.cpp for similar test cases. + template<> + template<> + void object::test<8>() + { + geos::geom::PrecisionModel pm(1e+13); + geos::geom::GeometryFactory factory(&pm); + geos::io::WKBReader reader(factory); + + // POINT located between 3rd and 4th vertex of LINESTRING + // POINT(-23.1094689600055080 50.5195368635957180) + std::string point("01010000009a266328061c37c0e21a172f80424940"); + // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055150 50.5223376452201340,-23.1094689600055010 50.5169177629559480,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409) + std::string line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940"); + std::stringstream sPoint(point); + geom2_ = reinterpret_cast(reader.readHEX(sPoint)); + std::stringstream sLine(line); + geom1_ = reinterpret_cast(reader.readHEX(sLine)); + + prepGeom1_ = GEOSPrepare(geom1_); + ensure(0 != prepGeom1_); + int ret = GEOSPreparedIntersects(prepGeom1_, geom2_); + ensure_equals(ret, 1); + } + + // Test PreparedIntersects: point on vertex (default FLOAT PM) + template<> + template<> + void object::test<9>() + { + // POINT located on the 3rd vertex of LINESTRING + // POINT(-23.1094689600055 50.5223376452201) + std::string point("01010000009c266328061c37c056d8bff5db424940"); + // LINESTRING(-23.122057005539 50.5201976774794,-23.1153476966995 50.5133404815199,-23.1094689600055 50.5223376452201,-23.1094689600055 50.5169177629559,-23.0961967920942 50.5330464848094,-23.0887991006034 50.5258515213185,-23.0852302622362 50.5264582238409) + std::string line("0102000000070000009909bf203f1f37c05c1d66d6954249404afe386d871d37c0a7eb1124b54149409c266328061c37c056d8bff5db42494098266328061c37c0034f7b5c2a42494060065c5aa01837c08ac001de3a4449408401b189bb1637c0b04e471a4f43494014ef84a6d11537c0b20dabfb62434940"); + geom1_ = GEOSGeomFromHEX_buf(reinterpret_cast(line.data()), line.size()); + geom2_ = GEOSGeomFromHEX_buf(reinterpret_cast(point.data()), point.size()); + prepGeom1_ = GEOSPrepare(geom1_); + ensure(0 != prepGeom1_); + + int ret = GEOSPreparedIntersects(prepGeom1_, geom2_); + ensure_equals(ret, 1); + } + // TODO: add lots of more tests } // namespace tut