[geos-commits] [SCM] GEOS branch master updated. ba34ee20395a4d30027776de4a734a88bf8767b8

git at osgeo.org git at osgeo.org
Mon Nov 2 15:24:30 PST 2020


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, master has been updated
       via  ba34ee20395a4d30027776de4a734a88bf8767b8 (commit)
       via  d4c133f62167fcb780949c2a53cce8e9f13b6353 (commit)
      from  a1eed0f993839c4cff5ccfb1644e8b6a2ff2cc1d (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 ba34ee20395a4d30027776de4a734a88bf8767b8
Author: Sandro Santilli <strk at kbt.io>
Date:   Mon Nov 2 12:24:36 2020 +0100

    Add GEOSPreparedNearestPoints in C-API
    
    Implement for LineString input
    
    Closes #1007

diff --git a/NEWS b/NEWS
index 34d6548..641eff7 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Changes in 3.9.0
 - New things:
   - MaximumInscribedCircle and LargestEmptyCircle (JTS-530, Paul Ramsey)
   - CAPI: Fixed precision overlay operations (Sandro Santilli, Paul Ramsey)
+  - CAPI: GEOSPreparedNearestPoints (#1007, Sandro Santilli)
 
 - Improvements:
   - Stack allocate segments in OverlapUnion (Paul Ramsey)
diff --git a/capi/geos_c.cpp b/capi/geos_c.cpp
index 17a2fb2..ac14777 100644
--- a/capi/geos_c.cpp
+++ b/capi/geos_c.cpp
@@ -1299,6 +1299,12 @@ extern "C" {
         return GEOSPreparedWithin_r(handle, pg1, g2);
     }
 
+    CoordinateSequence*
+    GEOSPreparedNearestPoints(const geos::geom::prep::PreparedGeometry* g1, const Geometry* g2)
+    {
+        return GEOSPreparedNearestPoints_r(handle, g1, g2);
+    }
+
     STRtree*
     GEOSSTRtree_create(size_t nodeCapacity)
     {
diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index 903475c..dd0b2bd 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -882,6 +882,14 @@ extern char GEOS_DLL GEOSPreparedWithin_r(GEOSContextHandle_t handle,
                                           const GEOSPreparedGeometry* pg1,
                                           const GEOSGeometry* g2);
 
+/* Return 0 on exception, the closest points of the two geometries otherwise.
+ * The first point comes from pg1 geometry and the second point comes from g2.
+ */
+extern GEOSCoordSequence GEOS_DLL *GEOSPreparedNearestPoints_r(
+                                          GEOSContextHandle_t handle,
+                                          const GEOSPreparedGeometry* pg1,
+                                          const GEOSGeometry* g2);
+
 /************************************************************************
  *
  *  STRtree functions
@@ -1868,6 +1876,7 @@ extern char GEOS_DLL GEOSPreparedIntersects(const GEOSPreparedGeometry* pg1, con
 extern char GEOS_DLL GEOSPreparedOverlaps(const GEOSPreparedGeometry* pg1, const GEOSGeometry* g2);
 extern char GEOS_DLL GEOSPreparedTouches(const GEOSPreparedGeometry* pg1, const GEOSGeometry* g2);
 extern char GEOS_DLL GEOSPreparedWithin(const GEOSPreparedGeometry* pg1, const GEOSGeometry* g2);
+extern GEOSCoordSequence GEOS_DLL *GEOSPreparedNearestPoints(const GEOSPreparedGeometry* pg1, const GEOSGeometry* g2);
 
 /************************************************************************
  *
diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index c8abec2..6a9f6ce 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -2940,6 +2940,17 @@ extern "C" {
         });
     }
 
+    CoordinateSequence*
+    GEOSPreparedNearestPoints_r(GEOSContextHandle_t extHandle,
+                         const geos::geom::prep::PreparedGeometry* pg, const Geometry* g)
+    {
+        using namespace geos::geom;
+
+        return execute(extHandle, [&]() -> CoordinateSequence* {
+            return pg->nearestPoints(g).release();
+        });
+    }
+
 //-----------------------------------------------------------------
 // STRtree
 //-----------------------------------------------------------------
diff --git a/include/geos/geom/prep/BasicPreparedGeometry.h b/include/geos/geom/prep/BasicPreparedGeometry.h
index d66bc1d..49c0f65 100644
--- a/include/geos/geom/prep/BasicPreparedGeometry.h
+++ b/include/geos/geom/prep/BasicPreparedGeometry.h
@@ -171,6 +171,11 @@ public:
      */
     bool within(const geom::Geometry* g) const override;
 
+    /**
+     * Default implementation.
+     */
+    std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const override;
+
     std::string toString();
 
 };
diff --git a/include/geos/geom/prep/PreparedGeometry.h b/include/geos/geom/prep/PreparedGeometry.h
index 5e166ee..a8a0df3 100644
--- a/include/geos/geom/prep/PreparedGeometry.h
+++ b/include/geos/geom/prep/PreparedGeometry.h
@@ -19,13 +19,17 @@
 #ifndef GEOS_GEOM_PREP_PREPAREDGEOMETRY_H
 #define GEOS_GEOM_PREP_PREPAREDGEOMETRY_H
 
+#include <vector>
+#include <memory>
 #include <geos/export.h>
 
 // Forward declarations
 namespace geos {
-namespace geom {
-class Geometry;
-}
+    namespace geom {
+        class Geometry;
+        class Coordinate;
+        class CoordinateSequence;
+    }
 }
 
 
@@ -192,6 +196,16 @@ public:
      * @see Geometry#within(Geometry)
      */
     virtual bool within(const geom::Geometry* geom) const = 0;
+
+    /** \brief
+     * Compute the nearest locations on the base {@link Geometry} and
+     * the given geometry.
+     *
+     * @param geom the Geometry to compute the nearest point to
+     * @return true the nearest points
+     *
+     */
+    virtual std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const = 0;
 };
 
 
diff --git a/include/geos/geom/prep/PreparedLineString.h b/include/geos/geom/prep/PreparedLineString.h
index 7d70d2f..33c4322 100644
--- a/include/geos/geom/prep/PreparedLineString.h
+++ b/include/geos/geom/prep/PreparedLineString.h
@@ -23,6 +23,7 @@
 #include <geos/geom/prep/BasicPreparedGeometry.h> // for inheritance
 #include <geos/noding/SegmentString.h>
 #include <geos/noding/FastSegmentSetIntersectionFinder.h>
+#include <geos/operation/distance/IndexedFacetDistance.h>
 
 #include <memory>
 
@@ -41,6 +42,8 @@ class PreparedLineString : public BasicPreparedGeometry {
 private:
     std::unique_ptr<noding::FastSegmentSetIntersectionFinder> segIntFinder;
     mutable noding::SegmentString::ConstVect segStrings;
+    mutable std::unique_ptr<operation::distance::IndexedFacetDistance> indexedDistance;
+    operation::distance::IndexedFacetDistance* getIndexedFacetDistance() const;
 
 protected:
 public:
@@ -55,6 +58,7 @@ public:
     noding::FastSegmentSetIntersectionFinder* getIntersectionFinder();
 
     bool intersects(const geom::Geometry* g) const override;
+    std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const override;
 
 };
 
diff --git a/src/geom/prep/BasicPreparedGeometry.cpp b/src/geom/prep/BasicPreparedGeometry.cpp
index 65fca75..27f0c9f 100644
--- a/src/geom/prep/BasicPreparedGeometry.cpp
+++ b/src/geom/prep/BasicPreparedGeometry.cpp
@@ -21,6 +21,7 @@
 #include <geos/geom/Coordinate.h>
 #include <geos/algorithm/PointLocator.h>
 #include <geos/geom/util/ComponentCoordinateExtracter.h>
+#include <geos/operation/distance/DistanceOp.h>
 
 namespace geos {
 namespace geom { // geos.geom
@@ -147,6 +148,13 @@ BasicPreparedGeometry::within(const geom::Geometry* g) const
     return baseGeom->within(g);
 }
 
+std::unique_ptr<geom::CoordinateSequence>
+BasicPreparedGeometry::nearestPoints(const geom::Geometry* g) const
+{
+    operation::distance::DistanceOp dist(baseGeom, g);
+    return dist.nearestPoints();
+}
+
 std::string
 BasicPreparedGeometry::toString()
 {
diff --git a/src/geom/prep/PreparedLineString.cpp b/src/geom/prep/PreparedLineString.cpp
index 09ca4ea..da9d022 100644
--- a/src/geom/prep/PreparedLineString.cpp
+++ b/src/geom/prep/PreparedLineString.cpp
@@ -19,8 +19,11 @@
 
 #include <geos/geom/prep/PreparedLineString.h>
 #include <geos/geom/prep/PreparedLineStringIntersects.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/CoordinateSequenceFactory.h>
 #include <geos/noding/SegmentStringUtil.h>
 #include <geos/noding/FastSegmentSetIntersectionFinder.h>
+#include <geos/operation/distance/IndexedFacetDistance.h>
 
 namespace geos {
 namespace geom { // geos.geom
@@ -61,6 +64,28 @@ PreparedLineString::intersects(const geom::Geometry* g) const
     return PreparedLineStringIntersects::intersects(prep, g);
 }
 
+/* private */
+operation::distance::IndexedFacetDistance*
+PreparedLineString::
+getIndexedFacetDistance() const
+{
+    if(! indexedDistance ) {
+        indexedDistance.reset(new operation::distance::IndexedFacetDistance(&getGeometry()));
+    }
+    return indexedDistance.get();
+}
+
+
+std::unique_ptr<geom::CoordinateSequence>
+PreparedLineString::nearestPoints(const geom::Geometry* g) const
+{
+    const GeometryFactory *gf = getGeometry().getFactory();
+    const CoordinateSequenceFactory *cf = gf->getCoordinateSequenceFactory();
+    operation::distance::IndexedFacetDistance *idf = getIndexedFacetDistance();
+    return cf->create(idf->nearestPoints(g));
+}
+
+
 } // namespace geos.geom.prep
 } // namespace geos.geom
 } // namespace geos
diff --git a/src/geom/prep/PreparedPolygon.cpp b/src/geom/prep/PreparedPolygon.cpp
index 130562d..001a547 100644
--- a/src/geom/prep/PreparedPolygon.cpp
+++ b/src/geom/prep/PreparedPolygon.cpp
@@ -39,7 +39,7 @@ namespace prep { // geos.geom.prep
 // public:
 //
 PreparedPolygon::PreparedPolygon(const geom::Geometry* geom)
-    : BasicPreparedGeometry(geom), segIntFinder(nullptr), ptOnGeomLoc(nullptr)
+    : BasicPreparedGeometry(geom)
 {
     isRectangle = getGeometry().isRectangle();
 }
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 87a56b2..5949522 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -106,6 +106,7 @@ geos_unit_SOURCES = \
 	capi/GEOSPointOnSurfaceTest.cpp \
 	capi/GEOSPolygonizeTest.cpp \
 	capi/GEOSPreparedGeometryTest.cpp \
+	capi/GEOSPreparedNearestPointsTest.cpp \
 	capi/GEOSProjectTest.cpp \
 	capi/GEOSRelateBoundaryNodeRuleTest.cpp \
 	capi/GEOSRelatePatternMatchTest.cpp \
diff --git a/tests/unit/capi/GEOSPreparedNearestPointsTest.cpp b/tests/unit/capi/GEOSPreparedNearestPointsTest.cpp
new file mode 100644
index 0000000..3217668
--- /dev/null
+++ b/tests/unit/capi/GEOSPreparedNearestPointsTest.cpp
@@ -0,0 +1,205 @@
+// $Id: GEOSPreparedNearestPointsTest.cpp 2424 2009-04-29 23:52:36Z mloskot $
+//
+// Test Suite for C-API GEOSPreparedNearestPoints
+
+#include <tut/tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+namespace tut {
+//
+// Test Group
+//
+
+// Common data used in test cases.
+struct test_capigeospreparednearestpoints_data {
+    GEOSGeometry* geom1_;
+    GEOSGeometry* geom2_;
+    const GEOSPreparedGeometry* pgeom1_;
+
+    static void
+    notice(const char* fmt, ...)
+    {
+        std::fprintf(stdout, "NOTICE: ");
+
+        va_list ap;
+        va_start(ap, fmt);
+        std::vfprintf(stdout, fmt, ap);
+        va_end(ap);
+
+        std::fprintf(stdout, "\n");
+    }
+
+    test_capigeospreparednearestpoints_data()
+        : geom1_(nullptr), geom2_(nullptr), pgeom1_(nullptr)
+    {
+        initGEOS(notice, notice);
+    }
+
+    ~test_capigeospreparednearestpoints_data()
+    {
+        GEOSGeom_destroy(geom2_);
+        GEOSPreparedGeom_destroy(pgeom1_);
+        GEOSGeom_destroy(geom1_);
+        geom1_ = nullptr;
+        geom2_ = nullptr;
+        geom1_ = nullptr;
+        finishGEOS();
+    }
+
+};
+
+typedef test_group<test_capigeospreparednearestpoints_data> group;
+typedef group::object object;
+
+group test_capigeospreparednearestpoints_group("capi::GEOSPreparedNearestPoints");
+
+//
+// Test Cases
+//
+
+template<>
+template<>
+void object::test<1>
+()
+{
+    geom1_ = GEOSGeomFromWKT("POLYGON EMPTY");
+    pgeom1_ = GEOSPrepare(geom1_);
+    geom2_ = GEOSGeomFromWKT("POLYGON EMPTY");
+
+    ensure(nullptr != pgeom1_);
+    ensure(nullptr != geom2_);
+
+    GEOSCoordSequence* coords_;
+    coords_ = GEOSPreparedNearestPoints(pgeom1_, geom2_);
+
+    ensure(nullptr == coords_);
+}
+
+template<>
+template<>
+void object::test<2>
+()
+{
+    geom1_ = GEOSGeomFromWKT("POLYGON((1 1,1 5,5 5,5 1,1 1))");
+    pgeom1_ = GEOSPrepare(geom1_);
+    geom2_ = GEOSGeomFromWKT("POLYGON((8 8, 9 9, 9 10, 8 8))");
+
+    ensure(nullptr != pgeom1_);
+    ensure(nullptr != geom2_);
+
+    GEOSCoordSequence* coords_;
+    coords_ = GEOSPreparedNearestPoints(pgeom1_, geom2_);
+
+    ensure(nullptr != coords_);
+
+    unsigned int size;
+    GEOSCoordSeq_getSize(coords_, &size);
+    ensure_equals(size, 2u);
+
+    double  x1, x2, y1, y2;
+
+    /* Point in pgeom1_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 0, 0, &x1);
+    GEOSCoordSeq_getOrdinate(coords_, 0, 1, &y1);
+    ensure_equals(x1, 5);
+    ensure_equals(y1, 5);
+
+    /* Point in geom2_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 1, 0, &x2);
+    GEOSCoordSeq_getOrdinate(coords_, 1, 1, &y2);
+    ensure_equals(x2, 8);
+    ensure_equals(y2, 8);
+
+    GEOSCoordSeq_destroy(coords_);
+}
+
+template<>
+template<>
+void object::test<3>
+()
+{
+    geom1_ = GEOSGeomFromWKT("POLYGON((1 1,1 5,5 5,5 1,1 1))");
+    pgeom1_ = GEOSPrepare(geom1_);
+    geom2_ = GEOSGeomFromWKT("POINT(2 2)");
+
+    ensure(nullptr != geom1_);
+    ensure(nullptr != geom2_);
+
+    GEOSCoordSequence* coords_;
+    coords_ = GEOSPreparedNearestPoints(pgeom1_, geom2_);
+
+    ensure(nullptr != coords_);
+
+    unsigned int size;
+    GEOSCoordSeq_getSize(coords_, &size);
+    ensure_equals(size, 2u);
+
+    double  x1, x2, y1, y2;
+
+    /* Point in geom1_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 0, 0, &x1);
+    GEOSCoordSeq_getOrdinate(coords_, 0, 1, &y1);
+    ensure_equals(x1, 2);
+    ensure_equals(y1, 2);
+
+    /* Point in geom2_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 1, 0, &x2);
+    GEOSCoordSeq_getOrdinate(coords_, 1, 1, &y2);
+    ensure_equals(x2, 2);
+    ensure_equals(y2, 2);
+
+    GEOSCoordSeq_destroy(coords_);
+}
+
+template<>
+template<>
+void object::test<4>
+()
+{
+    geom1_ = GEOSGeomFromWKT("LINESTRING(1 5,5 5,5 1,1 1)");
+    pgeom1_ = GEOSPrepare(geom1_);
+    geom2_ = GEOSGeomFromWKT("POINT(2 2)");
+
+    ensure(nullptr != geom1_);
+    ensure(nullptr != geom2_);
+
+    GEOSCoordSequence* coords_;
+    coords_ = GEOSPreparedNearestPoints(pgeom1_, geom2_);
+
+    ensure(nullptr != coords_);
+
+    unsigned int size;
+    GEOSCoordSeq_getSize(coords_, &size);
+    ensure_equals(size, 2u);
+
+    double  x1, x2, y1, y2;
+
+    /* Point in geom1_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 0, 0, &x1);
+    GEOSCoordSeq_getOrdinate(coords_, 0, 1, &y1);
+    ensure_equals(x1, 2);
+    ensure_equals(y1, 1);
+
+
+    /* Point in geom2_
+     */
+    GEOSCoordSeq_getOrdinate(coords_, 1, 0, &x2);
+    GEOSCoordSeq_getOrdinate(coords_, 1, 1, &y2);
+    ensure_equals(x2, 2);
+    ensure_equals(y2, 2);
+
+    GEOSCoordSeq_destroy(coords_);
+}
+
+} // namespace tut
+

commit d4c133f62167fcb780949c2a53cce8e9f13b6353
Author: Sandro Santilli <strk at kbt.io>
Date:   Mon Nov 2 21:54:39 2020 +0100

    Fix debug build of Envelop.inl

diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index 3a7c049..73f32b3 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -25,6 +25,10 @@
 #include <geos/geom/Coordinate.h>
 #include <geos/geom/Envelope.h>
 
+#if GEOS_DEBUG
+# include <iostream>
+#endif
+
 namespace geos {
 namespace geom { // geos::geom
 

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

Summary of changes:
 NEWS                                               |  1 +
 capi/geos_c.cpp                                    |  6 ++
 capi/geos_c.h.in                                   |  9 ++
 capi/geos_ts_c.cpp                                 | 11 +++
 include/geos/geom/Envelope.inl                     |  4 +
 include/geos/geom/prep/BasicPreparedGeometry.h     |  5 ++
 include/geos/geom/prep/PreparedGeometry.h          | 20 ++++-
 include/geos/geom/prep/PreparedLineString.h        |  4 +
 src/geom/prep/BasicPreparedGeometry.cpp            |  8 ++
 src/geom/prep/PreparedLineString.cpp               | 25 ++++++
 src/geom/prep/PreparedPolygon.cpp                  |  2 +-
 tests/unit/Makefile.am                             |  1 +
 ...sTest.cpp => GEOSPreparedNearestPointsTest.cpp} | 98 ++++++++++++++++------
 13 files changed, 163 insertions(+), 31 deletions(-)
 copy tests/unit/capi/{GEOSNearestPointsTest.cpp => GEOSPreparedNearestPointsTest.cpp} (53%)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list