Skip to content

Commit

Permalink
Merge branch 'main-relate-ng' of github.com:libgeos/geos into main-re…
Browse files Browse the repository at this point in the history
…late-ng
  • Loading branch information
pramsey committed Aug 8, 2024
2 parents 324cd19 + fc3621d commit eacbf9e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 29 deletions.
8 changes: 4 additions & 4 deletions benchmarks/geom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/benchmarks>)
target_link_libraries(perf_prepared_polygon_intersects PRIVATE geos)
target_link_libraries(perf_topo_predicate PRIVATE geos)
Original file line number Diff line number Diff line change
@@ -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 <geos/geom/util/SineStarFactory.h>
Expand All @@ -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 predicateName{"intersects"};
int predicateOp = INTERSECTS;

int testRelateOpIntersects(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
Expand Down Expand Up @@ -55,6 +57,15 @@ int testRelateOpCovers(const Geometry& g, const std::vector<std::unique_ptr<Geom
return count;
}

int testRelateOpTouches(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& 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<std::unique_ptr<Geometry>>& geoms) {
int count = 0;
for (const auto& geom : geoms) {
Expand All @@ -79,6 +90,14 @@ int testGeometryCovers(const Geometry& g, const std::vector<std::unique_ptr<Geom
return count;
}

int testGeometryTouches(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
int count = 0;
for (const auto& geom : geoms) {
count += g.touches(geom.get());
}
return count;
}

int testPrepGeomIntersects(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
int count = 0;
auto prep = prep::PreparedGeometryFactory::prepare(&g);
Expand Down Expand Up @@ -133,10 +152,19 @@ int testRelateNGPreparedCovers(const Geometry& g, const std::vector<std::unique_
return count;
}

int testRelateNGPreparedTouches(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& 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<typename F>
double test(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms, const std::string& method, F&& fun, double baseTime)
{
geos::util::Profile sw("PreparedPolygonIntersects");
geos::util::Profile sw("TopologuyPredicatePerf");
sw.start();

int count = 0;
Expand All @@ -152,9 +180,10 @@ double test(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geo
<< MAX_ITER * geoms.size() << ","
<< count << "," << geoms[0]->getGeometryType() << ","
<< geoms[0]->getNumPoints() << ","
<< method << ","
<< tot << ","
<< timesFaster
<< method << " - " << predicateName << ","
<< tot << ",";
std::cout << std::fixed << std::setprecision(1);
std::cout << timesFaster
<< std::endl;
return tot;
}
Expand All @@ -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);
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", testRelateOpTouches, 0);
test(*target, geoms, "Geometry", testGeometryTouches, baseTime);
test(*target, geoms, "RelateNGPrepared", testRelateNGPreparedTouches, baseTime);
break;
}
}

Expand All @@ -209,15 +244,19 @@ void testAll(int dim)
}

int main(int argc, char** argv) {
predicateOp = INTERSECTS;
predicateName = "intersects";
if (argc >= 2) {
std::string op{argv[1]};
if (op == "contains") {
predicateOp = CONTAINS;
}
else if (op == "covers") {
predicateOp = COVERS;
}
predicateName = argv[1];
}
predicateOp = INTERSECTS;
if (predicateName == "contains") {
predicateOp = CONTAINS;
}
else if (predicateName == "covers") {
predicateOp = COVERS;
}
else if (predicateName == "touches") {
predicateOp = TOUCHES;
}

std::cout << "target_points,num_tests,num_hits,test_type,pts_in_test,method,time,factor" << std::endl;
Expand Down
13 changes: 12 additions & 1 deletion tests/unit/operation/relateng/RelateNGRobustnessTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit eacbf9e

Please sign in to comment.