[geos-commits] [SCM] GEOS branch main updated. ba10ba4508af887a1a78bbc632ab45d89ce3242c

git at osgeo.org git at osgeo.org
Wed Sep 29 12:59:14 PDT 2021


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  ba10ba4508af887a1a78bbc632ab45d89ce3242c (commit)
      from  beb9207f650abeff96e9872903cf2a20b8011654 (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 ba10ba4508af887a1a78bbc632ab45d89ce3242c
Author: Sandro Santilli <strk at kbt.io>
Date:   Wed Sep 29 21:57:13 2021 +0200

    Add GEOSDistanceWithin and GEOSPreparedDistanceWithin
    
    Closes #1124
    
    The implementations are just a stubs, wrapping GEOSDistance, but
    can be improved in the future.

diff --git a/NEWS b/NEWS
index f73de05..3612578 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ Changes in 3.10.0
 2020-xx-xx
 
 - New things:
+
+  - CAPI: GEOSDistanceWithin, GEOSPreparedDistanceWithin
+          (#1124, Sandro Santilli)
   - Output WKT using positional precision with the ryu
     library (#868, Paul Ramsey)
   - geosop CLI for GEOS (Martin Davis)
diff --git a/capi/geos_c.cpp b/capi/geos_c.cpp
index 3c7c8bc..c3f80df 100644
--- a/capi/geos_c.cpp
+++ b/capi/geos_c.cpp
@@ -273,6 +273,12 @@ extern "C" {
         return GEOSDistance_r(handle, g1, g2, dist);
     }
 
+    char
+    GEOSDistanceWithin(const Geometry* g1, const Geometry* g2, double dist)
+    {
+        return GEOSDistanceWithin_r(handle, g1, g2, dist);
+    }
+
     int
     GEOSDistanceIndexed(const Geometry* g1, const Geometry* g2, double* dist)
     {
@@ -1432,6 +1438,12 @@ extern "C" {
         return GEOSPreparedDistance_r(handle, g1, g2, dist);
     }
 
+    char
+    GEOSPreparedDistanceWithin(const geos::geom::prep::PreparedGeometry* g1, const Geometry* g2, double dist)
+    {
+        return GEOSPreparedDistanceWithin_r(handle, g1, g2, dist);
+    }
+
     GEOSSTRtree*
     GEOSSTRtree_create(std::size_t nodeCapacity)
     {
diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index cdf8469..5fe5bda 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -1116,6 +1116,12 @@ extern int GEOS_DLL GEOSPreparedDistance_r(
     const GEOSPreparedGeometry* pg1,
     const GEOSGeometry* g2, double *dist);
 
+/** \see GEOSPreparedDistanceWithin */
+extern char GEOS_DLL GEOSPreparedDistanceWithin_r(
+    GEOSContextHandle_t handle,
+    const GEOSPreparedGeometry* pg1,
+    const GEOSGeometry* g2, double dist);
+
 /* ========== STRtree ========== */
 
 /** \see GEOSSTRtree_create */
@@ -1515,6 +1521,13 @@ extern int GEOS_DLL GEOSDistance_r(
     const GEOSGeometry* g2,
     double *dist);
 
+/** \see GEOSDistanceWithin */
+extern char GEOS_DLL GEOSDistanceWithin_r(
+    GEOSContextHandle_t handle,
+    const GEOSGeometry* g1,
+    const GEOSGeometry* g2,
+    double dist);
+
 /** \see GEOSDistanceIndexed */
 extern int GEOS_DLL GEOSDistanceIndexed_r(
     GEOSContextHandle_t handle,
@@ -3286,7 +3299,7 @@ extern GEOSCoordSequence GEOS_DLL *GEOSPreparedNearestPoints(
     const GEOSGeometry* g2);
 
 /**
-* Using a \ref GEOSPreparedDisjoint do a high performance
+* Using a \ref GEOSPreparedDistance do a high performance
 * calculation to find the distance points between the
 * prepared and provided geometry. Useful for situations where
 * one geometry is large and static and needs to be tested
@@ -3301,6 +3314,23 @@ extern int GEOS_DLL GEOSPreparedDistance(
     const GEOSGeometry* g2,
     double *dist);
 
+/**
+* Using a \ref GEOSPreparedDistanceWithin do a high performance
+* calculation to find whether the prepared and provided geometry
+* is within the given max distance.
+* Useful for situations where
+* one geometry is large and static and needs to be tested
+* against a large number of other geometries.
+* \param[in] pg1 The prepared geometry
+* \param[in] g2 The geometry to test
+* \param[in] dist The max distance
+* \return 1 on success
+*/
+extern char GEOS_DLL GEOSPreparedDistanceWithin(
+    const GEOSPreparedGeometry* pg1,
+    const GEOSGeometry* g2,
+    double dist);
+
 /* ========== STRtree functions ========== */
 
 /**
@@ -3957,6 +3987,18 @@ extern int GEOS_DLL GEOSDistance(
     double *dist);
 
 /**
+* Calculate the distance between two geometries.
+* \param[in] g1 Input geometry
+* \param[in] g2 Input geometry
+* \param[in] dist max distance
+* \returns 1 on true, 0 on false, 2 on exception
+*/
+extern char GEOS_DLL GEOSDistanceWithin(
+    const GEOSGeometry* g1,
+    const GEOSGeometry* g2,
+    double dist);
+
+/**
 * Calculate the distance between two geometries, using the
 * indexed facet distance, which first indexes the geometries
 * internally, then calculates the distance. Useful when one
diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index 56078eb..64d44bf 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -805,6 +805,15 @@ extern "C" {
         });
     }
 
+    char
+    GEOSDistanceWithin_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double dist)
+    {
+        // TODO: optimize this
+        return execute(extHandle, 2, [&]() {
+            return g1->distance(g2) <= dist;
+        });
+    }
+
     int
     GEOSDistanceIndexed_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double* dist)
     {
@@ -3273,6 +3282,17 @@ extern "C" {
         });
     }
 
+    char
+    GEOSPreparedDistanceWithin_r(GEOSContextHandle_t extHandle,
+                         const geos::geom::prep::PreparedGeometry* pg,
+                         const Geometry* g, double dist)
+    {
+        // TODO: optimize this
+        return execute(extHandle, 2, [&]() {
+            return pg->distance(g) <= dist;
+        });
+    }
+
 //-----------------------------------------------------------------
 // STRtree
 //-----------------------------------------------------------------
diff --git a/tests/unit/capi/GEOSDistanceWithinTest.cpp b/tests/unit/capi/GEOSDistanceWithinTest.cpp
new file mode 100644
index 0000000..6d18b4e
--- /dev/null
+++ b/tests/unit/capi/GEOSDistanceWithinTest.cpp
@@ -0,0 +1,55 @@
+//
+// Test Suite for C-API GEOSDistance
+
+#include <tut/tut.hpp>
+// geos
+#include <geos_c.h>
+#include <geos/constants.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+#include <math.h>
+
+#include "capi_test_utils.h"
+
+namespace tut {
+//
+// Test Group
+//
+
+// Common data used in test cases.
+struct test_capigeosdistancewithin_data : public capitest::utility {
+    test_capigeosdistancewithin_data() {
+        GEOSWKTWriter_setTrim(wktw_, 1);
+    }
+};
+
+typedef test_group<test_capigeosdistancewithin_data> group;
+typedef group::object object;
+
+group test_capigeosdistancewithin_group("capi::GEOSDistanceWithin");
+
+//
+// Test Cases
+//
+
+template<>
+template<>
+void object::test<1>
+()
+{
+    geom1_ = GEOSGeomFromWKT("POINT(10 10)");
+    geom2_ = GEOSGeomFromWKT("POINT(3 6)");
+
+    double dist = 8.1;
+    char ret = GEOSDistanceWithin(geom1_, geom2_, dist);
+    ensure_equals(ret, 1);
+
+    ret = GEOSDistanceWithin(geom1_, geom2_, dist-0.1);
+    ensure_equals(ret, 0);
+}
+
+} // namespace tut
+
diff --git a/tests/unit/capi/GEOSPreparedDistanceWithinTest.cpp b/tests/unit/capi/GEOSPreparedDistanceWithinTest.cpp
new file mode 100644
index 0000000..96a654c
--- /dev/null
+++ b/tests/unit/capi/GEOSPreparedDistanceWithinTest.cpp
@@ -0,0 +1,166 @@
+//
+// Test Suite for C-API GEOSPreparedDistance
+
+#include <tut/tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+#include "capi_test_utils.h"
+
+namespace tut {
+//
+// Test Group
+//
+
+// Common data used in test cases.
+struct test_capigeosprepareddistancewithin_data : public capitest::utility {
+    const GEOSPreparedGeometry* pgeom1_;
+
+    test_capigeosprepareddistancewithin_data()
+        : pgeom1_(nullptr)
+    {}
+
+    ~test_capigeosprepareddistancewithin_data()
+    {
+        GEOSPreparedGeom_destroy(pgeom1_);
+    }
+
+    void checkDistanceWithin(const char* wkt1, const char* wkt2,
+                       double dist, char expectedResult)
+    {
+        geom1_ = GEOSGeomFromWKT(wkt1);
+        ensure(nullptr != geom1_);
+        pgeom1_ = GEOSPrepare(geom1_);
+        ensure(nullptr != pgeom1_);
+        geom2_ = GEOSGeomFromWKT(wkt2);
+        ensure(nullptr != geom2_);
+
+
+        int ret = GEOSPreparedDistanceWithin(pgeom1_, geom2_, dist);
+        ensure_equals("return code", (int)ret, (int)expectedResult);
+
+    }
+
+
+};
+
+typedef test_group<test_capigeosprepareddistancewithin_data> group;
+typedef group::object object;
+
+group test_capigeosprepareddistancewithin_group("capi::GEOSPreparedDistanceWithin");
+
+//
+// Test Cases
+//
+
+template<>
+template<>
+void object::test<1>
+()
+{
+    checkDistanceWithin(
+        "POLYGON EMPTY",
+        "POLYGON EMPTY",
+        std::numeric_limits<double>::infinity(),
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<2>
+()
+{
+    checkDistanceWithin(
+        "POLYGON((1 1,1 5,5 5,5 1,1 1))",
+        "POLYGON((8 8, 9 9, 9 10, 8 8))",
+        4.25,
+        1
+    );
+
+}
+
+template<>
+template<>
+void object::test<3>
+()
+{
+    checkDistanceWithin(
+        "POLYGON((1 1,1 5,5 5,5 1,1 1))",
+        "POINT(2 2)",
+        0,
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<4>
+()
+{
+    checkDistanceWithin(
+        "LINESTRING(1 5,5 5,5 1,1 1)",
+        "POINT(2 2)",
+        1,
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<5>
+()
+{
+    checkDistanceWithin(
+        "LINESTRING(0 0,10 10)",
+        "LINESTRING(0 10,10 0)",
+        0,
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<6>
+()
+{
+    checkDistanceWithin(
+        "POLYGON((0 0,10 0,10 10,0 10,0 0))",
+        "LINESTRING(8 5,12 5)",
+        0,
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<7>
+()
+{
+    checkDistanceWithin(
+        "LINESTRING EMPTY",
+        "POINT EMPTY",
+        std::numeric_limits<double>::infinity(),
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<8>
+()
+{
+    checkDistanceWithin(
+        "POINT EMPTY",
+        "LINESTRING EMPTY",
+        std::numeric_limits<double>::infinity(),
+        1
+    );
+}
+
+} // namespace tut
+

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

Summary of changes:
 NEWS                                               |  3 ++
 capi/geos_c.cpp                                    | 12 +++++
 capi/geos_c.h.in                                   | 44 +++++++++++++++-
 capi/geos_ts_c.cpp                                 | 20 ++++++++
 tests/unit/capi/GEOSDistanceWithinTest.cpp         | 55 ++++++++++++++++++++
 ...Test.cpp => GEOSPreparedDistanceWithinTest.cpp} | 58 ++++++++++++----------
 6 files changed, 165 insertions(+), 27 deletions(-)
 create mode 100644 tests/unit/capi/GEOSDistanceWithinTest.cpp
 copy tests/unit/capi/{GEOSPreparedDistanceTest.cpp => GEOSPreparedDistanceWithinTest.cpp} (61%)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list