From 8aae1cf6c1f3edc0076edb6fcba14f7dff898f22 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 8 Aug 2024 11:44:31 -0700 Subject: [PATCH 1/4] Rename TopologyPredicatePerfTest --- benchmarks/geom/CMakeLists.txt | 8 ++++---- ...tersectsPerfTest.cpp => TopologyPredicatePerfTest.cpp} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename benchmarks/geom/{PreparedPolygonIntersectsPerfTest.cpp => TopologyPredicatePerfTest.cpp} (100%) diff --git a/benchmarks/geom/CMakeLists.txt b/benchmarks/geom/CMakeLists.txt index 63a25ed05a..2d68291f77 100644 --- a/benchmarks/geom/CMakeLists.txt +++ b/benchmarks/geom/CMakeLists.txt @@ -32,8 +32,8 @@ IF(benchmark_FOUND) benchmark::benchmark geos_cxx_flags) endif() -add_executable(perf_prepared_polygon_intersects - PreparedPolygonIntersectsPerfTest.cpp) -target_include_directories(perf_prepared_polygon_intersects PUBLIC +add_executable(perf_topo_predicate + TopologyPredicatePerfTest.cpp) +target_include_directories(perf_topo_predicate PUBLIC $) -target_link_libraries(perf_prepared_polygon_intersects PRIVATE geos) +target_link_libraries(perf_topo_predicate PRIVATE geos) diff --git a/benchmarks/geom/PreparedPolygonIntersectsPerfTest.cpp b/benchmarks/geom/TopologyPredicatePerfTest.cpp similarity index 100% rename from benchmarks/geom/PreparedPolygonIntersectsPerfTest.cpp rename to benchmarks/geom/TopologyPredicatePerfTest.cpp From 5746c2afa30767843421ae661df5b45b6403f8f9 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 8 Aug 2024 12:49:15 -0700 Subject: [PATCH 2/4] Add touches to TopoPredicatePerfTest --- benchmarks/geom/TopologyPredicatePerfTest.cpp | 89 +++++++++++++------ 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/benchmarks/geom/TopologyPredicatePerfTest.cpp b/benchmarks/geom/TopologyPredicatePerfTest.cpp index 4af6637691..571bcbc70d 100644 --- a/benchmarks/geom/TopologyPredicatePerfTest.cpp +++ b/benchmarks/geom/TopologyPredicatePerfTest.cpp @@ -1,7 +1,7 @@ /****************************************************** - * Performance tests for spatial predicates + * Performance tests for topological predicates * - * Usage: perf_prepared_polygon_intersects [ intersects | contains ] + * Usage: perf_topo_predicate [ intersects | contains ] ******************************************************/ #include @@ -25,7 +25,9 @@ std::size_t NUM_LINES_PTS = 100; #define INTERSECTS 0 #define CONTAINS 1 #define COVERS 2 +#define TOUCHES 3 +std::string op{"intersects"}; int predicateOp = INTERSECTS; int testRelateOpIntersects(const Geometry& g, const std::vector>& geoms) { @@ -55,6 +57,15 @@ int testRelateOpCovers(const Geometry& g, const std::vector>& geoms) { + int count = 0; + for (const auto& geom : geoms) { + auto im = g.relate(geom.get()); + count += im->isTouches(g.getDimension(), geom.get()->getDimension()); + } + return count; +} + int testGeometryIntersects(const Geometry& g, const std::vector>& geoms) { int count = 0; for (const auto& geom : geoms) { @@ -79,6 +90,14 @@ int testGeometryCovers(const Geometry& g, const std::vector>& geoms) { + int count = 0; + for (const auto& geom : geoms) { + count += g.touches(geom.get()); + } + return count; +} + int testPrepGeomIntersects(const Geometry& g, const std::vector>& geoms) { int count = 0; auto prep = prep::PreparedGeometryFactory::prepare(&g); @@ -133,10 +152,19 @@ int testRelateNGPreparedCovers(const Geometry& g, const std::vector>& geoms) { + int count = 0; + auto prep = geos::operation::relateng::RelateNG::prepare(&g); + for (const auto& line : geoms) { + count += prep->evaluate(line.get(), *geos::operation::relateng::RelatePredicate::touches()); + } + return count; +} + template double test(const Geometry& g, const std::vector>& geoms, const std::string& method, F&& fun, double baseTime) { - geos::util::Profile sw("PreparedPolygonIntersects"); + geos::util::Profile sw("TopologuyPredicatePerf"); sw.start(); int count = 0; @@ -153,8 +181,9 @@ double test(const Geometry& g, const std::vector>& geo << count << "," << geoms[0]->getGeometryType() << "," << geoms[0]->getNumPoints() << "," << method << "," - << tot << "," - << timesFaster + << tot << ","; + std::cout << std::fixed << std::setprecision(1); + std::cout << timesFaster << std::endl; return tot; } @@ -177,22 +206,28 @@ void test(int dim, std::size_t npts) { double baseTime; switch (predicateOp) { case INTERSECTS: - baseTime = test(*target, geoms, "RelateOp intersects", testRelateOpIntersects, 0); - test(*target, geoms, "Geometry::intersects", testGeometryIntersects, baseTime); - test(*target, geoms, "PreparedGeom", testPrepGeomIntersects, baseTime); - test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedIntersects, baseTime); + baseTime = test(*target, geoms, "RelateOp-intersects", testRelateOpIntersects, 0); + test(*target, geoms, "Geometry-intersects", testGeometryIntersects, baseTime); + test(*target, geoms, "PreparedGeom-intersects", testPrepGeomIntersects, baseTime); + test(*target, geoms, "RelateNGPrepared-intersects", testRelateNGPreparedIntersects, baseTime); break; case CONTAINS: - baseTime = test(*target, geoms, "RelateOp contains", testRelateOpIntersects, 0); - test(*target, geoms, "Geometry::contains", testGeometryIntersects, baseTime); - test(*target, geoms, "PreparedGeom contains", testPrepGeomContains, baseTime); - test(*target, geoms, "RelateNGPrepared contains", testRelateNGPreparedContains, baseTime); + baseTime = test(*target, geoms, "RelateOp-contains", testRelateOpIntersects, 0); + test(*target, geoms, "Geometry-contains", testGeometryIntersects, baseTime); + test(*target, geoms, "PreparedGeom-contains", testPrepGeomContains, baseTime); + test(*target, geoms, "RelateNGPrepared-contains", testRelateNGPreparedContains, baseTime); break; case COVERS: - baseTime = test(*target, geoms, "RelateOp covers", testRelateOpCovers, 0); - test(*target, geoms, "Geometry::covers", testGeometryCovers, baseTime); - test(*target, geoms, "PreparedGeom covers", testPrepGeomCovers, baseTime); - test(*target, geoms, "RelateNGPrepared covers", testRelateNGPreparedCovers, baseTime); + baseTime = test(*target, geoms, "RelateOp-covers", testRelateOpCovers, 0); + test(*target, geoms, "Geometry-covers", testGeometryCovers, baseTime); + test(*target, geoms, "PreparedGeom-covers", testPrepGeomCovers, baseTime); + test(*target, geoms, "RelateNGPrepared-covers", testRelateNGPreparedCovers, baseTime); + break; + case TOUCHES: + baseTime = test(*target, geoms, "RelateOp-touches", testRelateOpTouches, 0); + test(*target, geoms, "Geometry-touches", testGeometryTouches, baseTime); + test(*target, geoms, "RelateNGPrepared-touches", testRelateNGPreparedTouches, baseTime); + break; } } @@ -209,15 +244,19 @@ void testAll(int dim) } int main(int argc, char** argv) { - predicateOp = INTERSECTS; + op = "intersects"; if (argc >= 2) { - std::string op{argv[1]}; - if (op == "contains") { - predicateOp = CONTAINS; - } - else if (op == "covers") { - predicateOp = COVERS; - } + op = argv[1]; + } + predicateOp = INTERSECTS; + if (op == "contains") { + predicateOp = CONTAINS; + } + else if (op == "covers") { + predicateOp = COVERS; + } + else if (op == "touches") { + predicateOp = TOUCHES; } std::cout << "target_points,num_tests,num_hits,test_type,pts_in_test,method,time,factor" << std::endl; From 852381011dd5c778b4fa0e4460807a8dc8a729e7 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 8 Aug 2024 14:18:20 -0700 Subject: [PATCH 3/4] Add robustness unit test --- .../operation/relateng/RelateNGRobustnessTest.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/unit/operation/relateng/RelateNGRobustnessTest.cpp b/tests/unit/operation/relateng/RelateNGRobustnessTest.cpp index 879329073d..6761655f47 100644 --- a/tests/unit/operation/relateng/RelateNGRobustnessTest.cpp +++ b/tests/unit/operation/relateng/RelateNGRobustnessTest.cpp @@ -266,6 +266,17 @@ void object::test<19> () checkIntersectsDisjoint(a, b, true); } - +//https://gis.stackexchange.com/questions/484691/topologyexception-side-location-conflict-while-intersects-on-valid-polygons +//testGISSE_484691 +template<> +template<> +void object::test<20> () +{ + std::string a = "POLYGON ((1.839012980156925 43.169860517728324, 1.838983490127865 43.169860200336274, 1.838898525601717 43.169868281549725, 1.838918565176068 43.1699719478626, 1.838920733577112 43.16998636433192, 1.838978629555589 43.16997979090823, 1.838982586839382 43.169966339940714, 1.838974943184281 43.169918580432174, 1.839020497362873 43.169914572864634, 1.839012980156925 43.169860517728324))"; + std::string b = "POLYGON ((1.8391355300979277 43.16987802887805, 1.83913336164737 43.16986361241434, 1.8390129801569248 43.169860517728324, 1.8390790978572837 43.16987292371998, 1.8390909520103162 43.16995581178317, 1.8391377530291442 43.16995091801345, 1.8391293863398452 43.16987796276235, 1.8391355300979277 43.16987802887805))"; + checkRelate(a, b, "2F2101212"); + checkIntersectsDisjoint(a, b, true); +} + } // namespace tut From fc3621df2e5dfe01861b0ab1c98d54e3beb77f5f Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 8 Aug 2024 14:39:38 -0700 Subject: [PATCH 4/4] Refine TopologyPredicatePerfTest --- benchmarks/geom/TopologyPredicatePerfTest.cpp | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/benchmarks/geom/TopologyPredicatePerfTest.cpp b/benchmarks/geom/TopologyPredicatePerfTest.cpp index 571bcbc70d..05c9ae6947 100644 --- a/benchmarks/geom/TopologyPredicatePerfTest.cpp +++ b/benchmarks/geom/TopologyPredicatePerfTest.cpp @@ -27,7 +27,7 @@ std::size_t NUM_LINES_PTS = 100; #define COVERS 2 #define TOUCHES 3 -std::string op{"intersects"}; +std::string predicateName{"intersects"}; int predicateOp = INTERSECTS; int testRelateOpIntersects(const Geometry& g, const std::vector>& geoms) { @@ -180,7 +180,7 @@ double test(const Geometry& g, const std::vector>& geo << MAX_ITER * geoms.size() << "," << count << "," << geoms[0]->getGeometryType() << "," << geoms[0]->getNumPoints() << "," - << method << "," + << method << " - " << predicateName << "," << tot << ","; std::cout << std::fixed << std::setprecision(1); std::cout << timesFaster @@ -206,27 +206,27 @@ void test(int dim, std::size_t npts) { double baseTime; switch (predicateOp) { case INTERSECTS: - baseTime = test(*target, geoms, "RelateOp-intersects", testRelateOpIntersects, 0); - test(*target, geoms, "Geometry-intersects", testGeometryIntersects, baseTime); - test(*target, geoms, "PreparedGeom-intersects", testPrepGeomIntersects, baseTime); - test(*target, geoms, "RelateNGPrepared-intersects", testRelateNGPreparedIntersects, baseTime); + baseTime = test(*target, geoms, "RelateOp", testRelateOpIntersects, 0); + test(*target, geoms, "Geometry", testGeometryIntersects, baseTime); + test(*target, geoms, "PreparedGeom", testPrepGeomIntersects, baseTime); + test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedIntersects, baseTime); break; case CONTAINS: - baseTime = test(*target, geoms, "RelateOp-contains", testRelateOpIntersects, 0); - test(*target, geoms, "Geometry-contains", testGeometryIntersects, baseTime); - test(*target, geoms, "PreparedGeom-contains", testPrepGeomContains, baseTime); - test(*target, geoms, "RelateNGPrepared-contains", testRelateNGPreparedContains, baseTime); + baseTime = test(*target, geoms, "RelateOp", testRelateOpIntersects, 0); + test(*target, geoms, "Geometry", testGeometryIntersects, baseTime); + test(*target, geoms, "PreparedGeom", testPrepGeomContains, baseTime); + test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedContains, baseTime); break; case COVERS: - baseTime = test(*target, geoms, "RelateOp-covers", testRelateOpCovers, 0); - test(*target, geoms, "Geometry-covers", testGeometryCovers, baseTime); - test(*target, geoms, "PreparedGeom-covers", testPrepGeomCovers, baseTime); - test(*target, geoms, "RelateNGPrepared-covers", testRelateNGPreparedCovers, baseTime); + baseTime = test(*target, geoms, "RelateOp", testRelateOpCovers, 0); + test(*target, geoms, "Geometry", testGeometryCovers, baseTime); + test(*target, geoms, "PreparedGeom", testPrepGeomCovers, baseTime); + test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedCovers, baseTime); break; case TOUCHES: - baseTime = test(*target, geoms, "RelateOp-touches", testRelateOpTouches, 0); - test(*target, geoms, "Geometry-touches", testGeometryTouches, baseTime); - test(*target, geoms, "RelateNGPrepared-touches", testRelateNGPreparedTouches, baseTime); + baseTime = test(*target, geoms, "RelateOp", testRelateOpTouches, 0); + test(*target, geoms, "Geometry", testGeometryTouches, baseTime); + test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedTouches, baseTime); break; } } @@ -244,18 +244,18 @@ void testAll(int dim) } int main(int argc, char** argv) { - op = "intersects"; + predicateName = "intersects"; if (argc >= 2) { - op = argv[1]; + predicateName = argv[1]; } predicateOp = INTERSECTS; - if (op == "contains") { + if (predicateName == "contains") { predicateOp = CONTAINS; } - else if (op == "covers") { + else if (predicateName == "covers") { predicateOp = COVERS; } - else if (op == "touches") { + else if (predicateName == "touches") { predicateOp = TOUCHES; }