[geos-commits] [SCM] GEOS branch main updated. 930487a20b6b5860eba91f9719ce0881973defc2

git at osgeo.org git at osgeo.org
Sat Nov 23 13:29:34 PST 2024


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, main has been updated
       via  930487a20b6b5860eba91f9719ce0881973defc2 (commit)
      from  1ab10dd64bcb0032adbd76b91fa699bacba8d4e2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 930487a20b6b5860eba91f9719ce0881973defc2
Author: Martin Davis <mtnclimb at gmail.com>
Date:   Sat Nov 23 13:29:08 2024 -0800

    Add options to TopologyPredicatePerfTest

diff --git a/benchmarks/geom/TopologyPredicatePerfTest.cpp b/benchmarks/geom/TopologyPredicatePerfTest.cpp
index e21ffce77..c3ea05bae 100644
--- a/benchmarks/geom/TopologyPredicatePerfTest.cpp
+++ b/benchmarks/geom/TopologyPredicatePerfTest.cpp
@@ -4,7 +4,12 @@
  * Tests a target geometry against grids of points, lines and polygons covering the target. 
  * Target is either a geometry from a WKT file or a set of generated sine stars increasing in size.
  * 
- * Usage: perf_topo_predicate [WKT file] [ intersects | contains | covers | touches ] [num target geoms]
+ * Usage: perf_topo_predicate [-v] [WKT file] [ pred ] [num target geoms]
+ *   where pred ::= intersects | contains | covers | touches | relate:PPPPPPPPP
+ *   with PPPPPPPPP being a DE-9IM pattern 
+ *   (e.g. T******** (INTERIOR_INTERSECTS) or  T**FF*FF* (CONTAINS_PROPERLY)
+ *   - -v enables verbose mode. The test geometries are printed
+ * 
 ******************************************************/
 
 #include <geos/geom/util/SineStarFactory.h>
@@ -31,14 +36,17 @@ std::size_t MAX_ITER = 1;
 std::size_t NUM_GEOM = 1000; 
 std::size_t NUM_PTS = 100;
 
-#define INTERSECTS 0
-#define CONTAINS 1
-#define COVERS 2
-#define TOUCHES 3
+#define PRED_INTERSECTS 0
+#define PRED_CONTAINS 1
+#define PRED_COVERS 2
+#define PRED_TOUCHES 3
+#define PRED_RELATE 4
 
+bool isVerbose = false;
 std::string inputFilename{""};
 std::string predicateName{"intersects"};
-int predicateOp = INTERSECTS;
+std::string relatePattern{"********"};
+int predicateOp = PRED_INTERSECTS;
 std::size_t numTestGeometries = NUM_GEOM;
 
 int testRelateOpIntersects(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
@@ -77,6 +85,15 @@ int testRelateOpTouches(const Geometry& g, const std::vector<std::unique_ptr<Geo
     return count;
 }
 
+int testRelateOpRelate(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
+    int count = 0;
+    for (const auto& geom : geoms) {
+        auto im = RelateOp::relate(&g, geom.get());
+        count += im->matches(relatePattern.c_str());
+    }
+    return count;
+}
+
 int testGeometryIntersects(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
     int count = 0;
     for (const auto& geom : geoms) {
@@ -109,6 +126,14 @@ int testGeometryTouches(const Geometry& g, const std::vector<std::unique_ptr<Geo
     return count;
 }
 
+int testGeometryRelate(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
+    int count = 0;
+    for (const auto& geom : geoms) {
+        count += g.relate(geom.get(), relatePattern.c_str());
+    }
+    return count;
+}
+
 int testPrepGeomIntersects(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geoms) {
     int count = 0;
     auto prep = prep::PreparedGeometryFactory::prepare(&g);
@@ -172,6 +197,15 @@ int testRelateNGPreparedTouches(const Geometry& g, const std::vector<std::unique
     return count;
 }
 
+int testRelateNGPreparedRelate(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::matches(relatePattern.c_str()));
+    }
+    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)
 {
@@ -187,12 +221,12 @@ double test(const Geometry& g, const std::vector<std::unique_ptr<Geometry>>& geo
     double tot = sw.getTot();
     double timesFaster = baseTime == 0 ? 1 : baseTime / tot;
     std::cout << std::fixed << std::setprecision(0);
-    std::cout << g.getNumPoints() << "," 
-        << MAX_ITER * geoms.size() << "," 
-        << count << "," << geoms[0]->getGeometryType() << "," 
-        << geoms[0]->getNumPoints() << "," 
-        << method << " - " << predicateName << "," 
-        << tot << ",";
+    std::cout << g.getNumPoints() << ", " 
+        << MAX_ITER * geoms.size() << ", " 
+        << count << ", " << geoms[0]->getGeometryType() << ", " 
+        << geoms[0]->getNumPoints() << ", " 
+        << method << " - " << predicateName << ", " 
+        << tot << ", ";
     std::cout << std::fixed << std::setprecision(1);
     std::cout << timesFaster 
         << std::endl;
@@ -215,7 +249,27 @@ loadWKT(std::string& fname) {
     return geom;
 }
 
+void dump(std::vector<std::unique_ptr<Geometry>>& geoms)
+{
+    for (const auto& geom : geoms) {
+        std::cout << geom->toString() << std::endl;
+    }
+}
+
+double computeSize(Geometry& target, size_t numGeoms)
+{
+    const Envelope* env = target.getEnvelopeInternal();
+    double w = env->getWidth();
+    double h = env->getHeight();
+    double d = std::min(w, h);
+    double size = d / std::sqrt(numGeoms);
+    return size;
+}
+
 void testTarget(int dim, Geometry& target) {
+
+    double size = computeSize(target, numTestGeometries);
+
     std::vector<std::unique_ptr<Geometry>> geoms;
     switch (dim) {
     case 0:
@@ -224,43 +278,52 @@ void testTarget(int dim, Geometry& target) {
         break;
     case 1:
         geoms = geos::benchmark::createLines(*target.getEnvelopeInternal(), 
-            numTestGeometries, 1.0, NUM_PTS);
+            numTestGeometries, size, NUM_PTS);
         break;
     case 2:
         geoms = geos::benchmark::createPolygons(*target.getEnvelopeInternal(), 
-            numTestGeometries, 1.0, NUM_PTS);
+            numTestGeometries, size, NUM_PTS);
         break;
     }
+    if (isVerbose) dump(geoms);
     double baseTime;
     switch (predicateOp) {
-    case INTERSECTS:
+    case PRED_INTERSECTS:
         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:
+    case PRED_CONTAINS:
         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:
+    case PRED_COVERS:
         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:
+    case PRED_TOUCHES:
         baseTime = test(target, geoms, "RelateOp", testRelateOpTouches, 0);
         test(target, geoms, "Geometry", testGeometryTouches, baseTime);
         test(target, geoms, "RelateNGPrepared", testRelateNGPreparedTouches, baseTime);
         break;
+    case PRED_RELATE:
+        baseTime = test(target, geoms, "RelateOp", testRelateOpRelate, 0);
+        test(target, geoms, "Geometry", testGeometryRelate, baseTime);
+        test(target, geoms, "RelateNGPrepared", testRelateNGPreparedRelate, baseTime);
+        break;
     }
 }
 
 void testStar(int dim, std::size_t npts) {
     std::unique_ptr<Geometry> star = geos::benchmark::createSineStar({0, 0}, 100, npts);
+    if (isVerbose) {
+        std::cout << star->toString() << std::endl << std::endl;
+    }
     testTarget(dim, *star);
 }
 
@@ -276,45 +339,67 @@ void testStarAll(int dim)
     testStar(dim, 16000);
 }
 
-void parseArgs(int argc, char** argv) {
-    int iPred = -1;
-    int iFile = -1;
-    //-- parse filename, predicate, num geoms, if present
-    for (int i = 1; i < argc; i++) {
-        std::string arg = argv[i];
-        if (arg.find(".") != std::string::npos)
-            iFile = i;
-        else {
-            bool isInt = (arg.find_first_not_of( "0123456789" ) == std::string::npos);
-            if (isInt) {
-                numTestGeometries = (size_t) std::stoi(arg);
-            }
-            else {
-                iPred = i;
-            }
+void parsePredicate(std::string& predArg)
+{
+    predicateName = predArg;
+    if (predicateName.substr(0, 6) == "relate") {
+        if (predicateName.length() != 16) {
+            std::cerr << "Invalid relate pattern: " << predicateName << std::endl;
+            exit(1); 
         }
-    }
-
-    if (iPred > 0) {
-        predicateName = argv[iPred];
-    }
-    if (iFile > 0) {
-        inputFilename = argv[iFile]; 
+        relatePattern = predicateName.substr(7, 9);
     }
 
     //------------------
     //-- interpret args
     
-    predicateOp = INTERSECTS;
+    predicateOp = PRED_INTERSECTS;
     if (predicateName == "contains") {
-        predicateOp = CONTAINS;
+        predicateOp = PRED_CONTAINS;
     }
     else if (predicateName == "covers") {
-        predicateOp = COVERS;
+        predicateOp = PRED_COVERS;
     }
     else if (predicateName == "touches") {
-        predicateOp = TOUCHES;
+        predicateOp = PRED_TOUCHES;
     }
+    else if (predicateName.substr(0, 6) == "relate") {
+        predicateOp = PRED_RELATE;
+    }
+}
+
+void parseArgs(int argc, char** argv) {
+    int iArg = 1;
+
+    //-- parse verbose flag, if present
+    if (iArg >= argc) return;
+    std::string arg = argv[iArg];
+    if (arg == "-v") {
+        isVerbose = true;
+        iArg++;
+    }
+
+    //-- parse filename, if present
+    if (iArg >= argc) return;
+    arg = argv[iArg];
+    if (arg.find(".") != std::string::npos) {
+        inputFilename = arg;
+        iArg++;
+    }
+
+    //-- parse predicate, if present
+    if (iArg >= argc) return;
+    arg = argv[iArg];
+    bool isInt = (arg.find_first_not_of( "0123456789" ) == std::string::npos);
+    if (! isInt) {
+        parsePredicate(arg);
+        iArg++;
+    }
+
+    //-- parse predicate, if present
+    if (iArg >= argc) return;
+    arg = argv[iArg];
+    numTestGeometries = (size_t) std::stoi(arg);
 }
 
 int main(int argc, char** argv) {

-----------------------------------------------------------------------

Summary of changes:
 benchmarks/geom/TopologyPredicatePerfTest.cpp | 175 +++++++++++++++++++-------
 1 file changed, 130 insertions(+), 45 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list