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

git at osgeo.org git at osgeo.org
Mon Nov 16 02:50:25 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  d66382ff8150a468a2f376da5ebb74c8cabdc437 (commit)
       via  a68486f56213b6744a080f263aead7b55c74fd11 (commit)
      from  7dc03c1a9f7046563e3890dfc1b265e0bd551dd5 (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 d66382ff8150a468a2f376da5ebb74c8cabdc437
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Nov 13 19:12:19 2020 +0100

    Put prepared polygon distance in its own class

diff --git a/include/geos/geom/prep/Makefile.am b/include/geos/geom/prep/Makefile.am
index 77e60fb..edae9b0 100644
--- a/include/geos/geom/prep/Makefile.am
+++ b/include/geos/geom/prep/Makefile.am
@@ -20,6 +20,7 @@ geos_HEADERS = \
     PreparedPolygonContains.h \
     PreparedPolygonContainsProperly.h \
     PreparedPolygonCovers.h \
+    PreparedPolygonDistance.h \
     PreparedPolygon.h \
     PreparedPolygonIntersects.h \
     PreparedPolygonPredicate.h
diff --git a/include/geos/geom/prep/PreparedLineStringDistance.h b/include/geos/geom/prep/PreparedLineStringDistance.h
index 00aaad6..91cfe37 100644
--- a/include/geos/geom/prep/PreparedLineStringDistance.h
+++ b/include/geos/geom/prep/PreparedLineStringDistance.h
@@ -24,6 +24,8 @@ namespace geos {
 namespace geom { // geos::geom
 namespace prep { // geos::geom::prep
 
+class PreparedLineString;
+
 class PreparedLineStringDistance {
 public:
 
diff --git a/include/geos/geom/prep/PreparedPolygon.h b/include/geos/geom/prep/PreparedPolygon.h
index f97a4ed..88c565c 100644
--- a/include/geos/geom/prep/PreparedPolygon.h
+++ b/include/geos/geom/prep/PreparedPolygon.h
@@ -3,6 +3,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.osgeo.org
  *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
  * Copyright (C) 2006 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -55,7 +56,6 @@ private:
     mutable std::unique_ptr<algorithm::locate::PointOnGeometryLocator> ptOnGeomLoc;
     mutable noding::SegmentString::ConstVect segStrings;
     mutable std::unique_ptr<operation::distance::IndexedFacetDistance> indexedDistance;
-    operation::distance::IndexedFacetDistance* getIndexedFacetDistance() const;
 
 protected:
 public:
@@ -64,6 +64,7 @@ public:
 
     noding::FastSegmentSetIntersectionFinder* getIntersectionFinder() const;
     algorithm::locate::PointOnGeometryLocator* getPointLocator() const;
+    operation::distance::IndexedFacetDistance* getIndexedFacetDistance() const;
 
     bool contains(const geom::Geometry* g) const override;
     bool containsProperly(const geom::Geometry* g) const override;
diff --git a/include/geos/geom/prep/PreparedLineStringDistance.h b/include/geos/geom/prep/PreparedPolygonDistance.h
similarity index 54%
copy from include/geos/geom/prep/PreparedLineStringDistance.h
copy to include/geos/geom/prep/PreparedPolygonDistance.h
index 00aaad6..938daf2 100644
--- a/include/geos/geom/prep/PreparedLineStringDistance.h
+++ b/include/geos/geom/prep/PreparedPolygonDistance.h
@@ -17,39 +17,51 @@
  *
  **********************************************************************/
 
-#ifndef GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
-#define GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
+#ifndef GEOS_GEOM_PREP_PREPAREDPOLYGONDISTANCE_H
+#define GEOS_GEOM_PREP_PREPAREDPOLYGONDISTANCE_H
+
+// Forward declarations
+namespace geos {
+    namespace geom {
+        class Geometry;
+        namespace prep {
+            class PreparedPolygon;
+        }
+    }
+}
 
 namespace geos {
 namespace geom { // geos::geom
 namespace prep { // geos::geom::prep
 
-class PreparedLineStringDistance {
+class PreparedPolygon;
+
+class PreparedPolygonDistance {
 public:
 
-    static double distance(const PreparedLineString& prep, const geom::Geometry* geom)
+    static double distance(const PreparedPolygon& prep, const geom::Geometry* geom)
     {
-        PreparedLineStringDistance op(prep);
+        PreparedPolygonDistance op(prep);
         return op.distance(geom);
     }
 
-    PreparedLineStringDistance(const PreparedLineString& prep)
-        : prepLine(prep)
+    PreparedPolygonDistance(const PreparedPolygon& prep)
+        : prepPoly(prep)
     { }
 
     double distance(const geom::Geometry* g) const;
 
 protected:
 
-    const PreparedLineString& prepLine;
+    const PreparedPolygon& prepPoly;
 
     // Declare type as noncopyable
-    PreparedLineStringDistance(const PreparedLineStringDistance& other) = delete;
-    PreparedLineStringDistance& operator=(const PreparedLineStringDistance& rhs) = delete;
+    PreparedPolygonDistance(const PreparedPolygonDistance& other) = delete;
+    PreparedPolygonDistance& operator=(const PreparedPolygonDistance& rhs) = delete;
 };
 
 } // namespace geos::geom::prep
 } // namespace geos::geom
 } // namespace geos
 
-#endif // GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
+#endif // GEOS_GEOM_PREP_PREPAREDPOLYGONDISTANCE_H
diff --git a/src/geom/prep/Makefile.am b/src/geom/prep/Makefile.am
index 354bdbc..abd2bd9 100644
--- a/src/geom/prep/Makefile.am
+++ b/src/geom/prep/Makefile.am
@@ -20,9 +20,10 @@ libgeomprep_la_SOURCES = \
     PreparedLineStringIntersects.cpp \
     PreparedLineStringNearestPoints.cpp \
     PreparedPoint.cpp \
+    PreparedPolygon.cpp \
     PreparedPolygonContains.cpp \
     PreparedPolygonContainsProperly.cpp \
     PreparedPolygonCovers.cpp \
-    PreparedPolygon.cpp \
+		PreparedPolygonDistance.cpp \
     PreparedPolygonIntersects.cpp \
     PreparedPolygonPredicate.cpp
diff --git a/src/geom/prep/PreparedPolygon.cpp b/src/geom/prep/PreparedPolygon.cpp
index b07dc8f..f49626a 100644
--- a/src/geom/prep/PreparedPolygon.cpp
+++ b/src/geom/prep/PreparedPolygon.cpp
@@ -21,6 +21,7 @@
 #include <geos/geom/prep/PreparedPolygonContains.h>
 #include <geos/geom/prep/PreparedPolygonContainsProperly.h>
 #include <geos/geom/prep/PreparedPolygonCovers.h>
+#include <geos/geom/prep/PreparedPolygonDistance.h>
 #include <geos/geom/prep/PreparedPolygonIntersects.h>
 #include <geos/geom/prep/PreparedPolygonPredicate.h>
 #include <geos/noding/FastSegmentSetIntersectionFinder.h>
@@ -143,7 +144,7 @@ intersects(const geom::Geometry* g) const
     return PreparedPolygonIntersects::intersects(this, g);
 }
 
-/* private */
+/* public */
 operation::distance::IndexedFacetDistance*
 PreparedPolygon::
 getIndexedFacetDistance() const
@@ -157,16 +158,7 @@ getIndexedFacetDistance() const
 double
 PreparedPolygon::distance(const geom::Geometry* g) const
 {
-    if ( getGeometry().isEmpty() || g->isEmpty() )
-    {
-        return std::numeric_limits<double>::infinity();
-    }
-
-    if ( intersects(g) ) return 0.0;
-
-    /* Not intersecting, compute distance from facets */
-    operation::distance::IndexedFacetDistance *idf = getIndexedFacetDistance();
-    return idf->distance(g);
+    return PreparedPolygonDistance::distance(*this, g);
 }
 
 } // namespace geos.geom.prep
diff --git a/src/geom/prep/PreparedPolygonDistance.cpp b/src/geom/prep/PreparedPolygonDistance.cpp
new file mode 100644
index 0000000..22db8ce
--- /dev/null
+++ b/src/geom/prep/PreparedPolygonDistance.cpp
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: ORIGINAL WORK
+ *
+ **********************************************************************/
+
+#include <geos/geom/prep/PreparedPolygonDistance.h>
+#include <geos/geom/prep/PreparedPolygon.h>
+#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>
+#include <geos/geom/Geometry.h>
+
+// std
+#include <cstddef>
+
+namespace geos {
+namespace geom { // geos.geom
+namespace prep { // geos.geom.prep
+
+double
+PreparedPolygonDistance::distance(const geom::Geometry* g) const
+{
+    if ( prepPoly.getGeometry().isEmpty() || g->isEmpty() )
+    {
+        return std::numeric_limits<double>::infinity();
+    }
+
+    if ( prepPoly.intersects(g) ) return 0.0;
+
+    /* Not intersecting, compute distance from facets */
+    operation::distance::IndexedFacetDistance *idf = prepPoly.getIndexedFacetDistance();
+    return idf->distance(g);
+}
+
+} // namespace geos.geom.prep
+} // namespace geos.geom
+} // namespace geos

commit a68486f56213b6744a080f263aead7b55c74fd11
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Nov 13 17:12:53 2020 +0100

    Add GEOSPreparedDistance to C-API
    
    References #1066
    
    By default implemented by computing distance between nearest
    points. Custom implementation for polygon and linestring.

diff --git a/NEWS b/NEWS
index 641eff7..5e70eab 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Changes in 3.9.0
   - MaximumInscribedCircle and LargestEmptyCircle (JTS-530, Paul Ramsey)
   - CAPI: Fixed precision overlay operations (Sandro Santilli, Paul Ramsey)
   - CAPI: GEOSPreparedNearestPoints (#1007, Sandro Santilli)
+  - CAPI: GEOSPreparedDistance (#1066, Sandro Santilli)
 
 - Improvements:
   - Stack allocate segments in OverlapUnion (Paul Ramsey)
diff --git a/capi/geos_c.cpp b/capi/geos_c.cpp
index ac14777..44fb257 100644
--- a/capi/geos_c.cpp
+++ b/capi/geos_c.cpp
@@ -1305,6 +1305,12 @@ extern "C" {
         return GEOSPreparedNearestPoints_r(handle, g1, g2);
     }
 
+    int
+    GEOSPreparedDistance(const geos::geom::prep::PreparedGeometry* g1, const Geometry* g2, double *dist)
+    {
+        return GEOSPreparedDistance_r(handle, g1, g2, dist);
+    }
+
     STRtree*
     GEOSSTRtree_create(size_t nodeCapacity)
     {
diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index dd0b2bd..7cb3d57 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -890,6 +890,11 @@ extern GEOSCoordSequence GEOS_DLL *GEOSPreparedNearestPoints_r(
                                           const GEOSPreparedGeometry* pg1,
                                           const GEOSGeometry* g2);
 
+extern int GEOS_DLL GEOSPreparedDistance_r(
+                                GEOSContextHandle_t handle,
+                                const GEOSPreparedGeometry* pg1,
+                                const GEOSGeometry* g2, double *dist);
+
 /************************************************************************
  *
  *  STRtree functions
@@ -1877,6 +1882,7 @@ extern char GEOS_DLL GEOSPreparedOverlaps(const GEOSPreparedGeometry* pg1, const
 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);
+extern int GEOS_DLL GEOSPreparedDistance(const GEOSPreparedGeometry* pg1, const GEOSGeometry* g2, double *dist);
 
 /************************************************************************
  *
diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index 6a9f6ce..b13a6e0 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -2951,6 +2951,17 @@ extern "C" {
         });
     }
 
+    int
+    GEOSPreparedDistance_r(GEOSContextHandle_t extHandle,
+                         const geos::geom::prep::PreparedGeometry* pg,
+                         const Geometry* g, double* dist)
+    {
+        return execute(extHandle, 0, [&]() {
+            *dist = pg->distance(g);
+            return 1;
+        });
+    }
+
 //-----------------------------------------------------------------
 // STRtree
 //-----------------------------------------------------------------
diff --git a/include/geos/geom/prep/BasicPreparedGeometry.h b/include/geos/geom/prep/BasicPreparedGeometry.h
index 49c0f65..29639e9 100644
--- a/include/geos/geom/prep/BasicPreparedGeometry.h
+++ b/include/geos/geom/prep/BasicPreparedGeometry.h
@@ -176,6 +176,11 @@ public:
      */
     std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const override;
 
+    /**
+     * Default implementation.
+     */
+    double distance(const geom::Geometry* g) const override;
+
     std::string toString();
 
 };
diff --git a/include/geos/geom/prep/Makefile.am b/include/geos/geom/prep/Makefile.am
index e6d1d9a..77e60fb 100644
--- a/include/geos/geom/prep/Makefile.am
+++ b/include/geos/geom/prep/Makefile.am
@@ -1,9 +1,9 @@
 #
-# This file is part of project GEOS (http://trac.osgeo.org/geos/) 
+# This file is part of project GEOS (http://trac.osgeo.org/geos/)
 #
-#SUBDIRS = 
+#SUBDIRS =
 
-#EXTRA_DIST = 
+#EXTRA_DIST =
 
 geosdir = $(includedir)/geos/geom/prep
 
@@ -13,7 +13,9 @@ geos_HEADERS = \
     PreparedGeometryFactory.h \
     PreparedGeometry.h \
     PreparedLineString.h \
+    PreparedLineStringDistance.h \
     PreparedLineStringIntersects.h \
+    PreparedLineStringNearestPoints.h \
     PreparedPoint.h \
     PreparedPolygonContains.h \
     PreparedPolygonContainsProperly.h \
diff --git a/include/geos/geom/prep/PreparedGeometry.h b/include/geos/geom/prep/PreparedGeometry.h
index 21e19e3..29b7786 100644
--- a/include/geos/geom/prep/PreparedGeometry.h
+++ b/include/geos/geom/prep/PreparedGeometry.h
@@ -206,6 +206,16 @@ public:
      *
      */
     virtual std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* geom) const = 0;
+
+    /** \brief
+     * Compute the minimum distance between the base {@link Geometry} and
+     * the given geometry.
+     *
+     * @param geom the Geometry to compute the distance to
+     * @return the minimum distance between the two geometries
+     *
+     */
+    virtual double distance(const geom::Geometry* geom) const = 0;
 };
 
 
diff --git a/include/geos/geom/prep/PreparedLineString.h b/include/geos/geom/prep/PreparedLineString.h
index 33c4322..302e312 100644
--- a/include/geos/geom/prep/PreparedLineString.h
+++ b/include/geos/geom/prep/PreparedLineString.h
@@ -3,6 +3,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.osgeo.org
  *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
  * Copyright (C) 2006 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -43,7 +44,6 @@ 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:
@@ -59,6 +59,8 @@ public:
 
     bool intersects(const geom::Geometry* g) const override;
     std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const override;
+    double distance(const geom::Geometry* g) const override;
+    operation::distance::IndexedFacetDistance* getIndexedFacetDistance() const;
 
 };
 
diff --git a/include/geos/geom/prep/PreparedLineStringDistance.h b/include/geos/geom/prep/PreparedLineStringDistance.h
new file mode 100644
index 0000000..00aaad6
--- /dev/null
+++ b/include/geos/geom/prep/PreparedLineStringDistance.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ *
+ **********************************************************************
+ *
+ * Last port: ORIGINAL WORK
+ *
+ **********************************************************************/
+
+#ifndef GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
+#define GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
+
+namespace geos {
+namespace geom { // geos::geom
+namespace prep { // geos::geom::prep
+
+class PreparedLineStringDistance {
+public:
+
+    static double distance(const PreparedLineString& prep, const geom::Geometry* geom)
+    {
+        PreparedLineStringDistance op(prep);
+        return op.distance(geom);
+    }
+
+    PreparedLineStringDistance(const PreparedLineString& prep)
+        : prepLine(prep)
+    { }
+
+    double distance(const geom::Geometry* g) const;
+
+protected:
+
+    const PreparedLineString& prepLine;
+
+    // Declare type as noncopyable
+    PreparedLineStringDistance(const PreparedLineStringDistance& other) = delete;
+    PreparedLineStringDistance& operator=(const PreparedLineStringDistance& rhs) = delete;
+};
+
+} // namespace geos::geom::prep
+} // namespace geos::geom
+} // namespace geos
+
+#endif // GEOS_GEOM_PREP_PREPAREDLINESTRINGDISTANCE_H
diff --git a/include/geos/geom/prep/PreparedLineStringNearestPoints.h b/include/geos/geom/prep/PreparedLineStringNearestPoints.h
new file mode 100644
index 0000000..d03d632
--- /dev/null
+++ b/include/geos/geom/prep/PreparedLineStringNearestPoints.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ *
+ **********************************************************************
+ *
+ * Last port: ORIGINAL WORK
+ *
+ **********************************************************************/
+
+#ifndef GEOS_GEOM_PREP_PREPAREDLINESTRINGNEARESTPOINTS_H
+#define GEOS_GEOM_PREP_PREPAREDLINESTRINGNEARESTPOINTS_H
+
+namespace geos {
+namespace geom { // geos::geom
+namespace prep { // geos::geom::prep
+
+class PreparedLineStringNearestPoints {
+public:
+
+    static std::unique_ptr<geom::CoordinateSequence>
+    nearestPoints(const PreparedLineString& prep, const geom::Geometry* geom)
+    {
+        PreparedLineStringNearestPoints op(prep);
+        return op.nearestPoints(geom);
+    }
+
+    PreparedLineStringNearestPoints(const PreparedLineString& prep)
+        : prepLine(prep)
+    { }
+
+    std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const;
+
+protected:
+
+    const PreparedLineString& prepLine;
+
+    // Declare type as noncopyable
+    PreparedLineStringNearestPoints(const PreparedLineStringNearestPoints& other) = delete;
+    PreparedLineStringNearestPoints& operator=(const PreparedLineStringNearestPoints& rhs) = delete;
+};
+
+} // namespace geos::geom::prep
+} // namespace geos::geom
+} // namespace geos
+
+#endif // GEOS_GEOM_PREP_PREPAREDLINESTRINGNEARESTPOINTS_H
diff --git a/include/geos/geom/prep/PreparedPolygon.h b/include/geos/geom/prep/PreparedPolygon.h
index 04b8ca7..f97a4ed 100644
--- a/include/geos/geom/prep/PreparedPolygon.h
+++ b/include/geos/geom/prep/PreparedPolygon.h
@@ -22,6 +22,7 @@
 
 #include <geos/geom/prep/BasicPreparedGeometry.h> // for inheritance
 #include <geos/noding/SegmentString.h>
+#include <geos/operation/distance/IndexedFacetDistance.h>
 
 #include <memory>
 
@@ -53,6 +54,8 @@ private:
     mutable std::unique_ptr<noding::FastSegmentSetIntersectionFinder> segIntFinder;
     mutable std::unique_ptr<algorithm::locate::PointOnGeometryLocator> ptOnGeomLoc;
     mutable noding::SegmentString::ConstVect segStrings;
+    mutable std::unique_ptr<operation::distance::IndexedFacetDistance> indexedDistance;
+    operation::distance::IndexedFacetDistance* getIndexedFacetDistance() const;
 
 protected:
 public:
@@ -66,6 +69,7 @@ public:
     bool containsProperly(const geom::Geometry* g) const override;
     bool covers(const geom::Geometry* g) const override;
     bool intersects(const geom::Geometry* g) const override;
+    double distance(const geom::Geometry* g) const override;
 
 };
 
diff --git a/src/geom/prep/BasicPreparedGeometry.cpp b/src/geom/prep/BasicPreparedGeometry.cpp
index 27f0c9f..d637401 100644
--- a/src/geom/prep/BasicPreparedGeometry.cpp
+++ b/src/geom/prep/BasicPreparedGeometry.cpp
@@ -155,6 +155,14 @@ BasicPreparedGeometry::nearestPoints(const geom::Geometry* g) const
     return dist.nearestPoints();
 }
 
+double
+BasicPreparedGeometry::distance(const geom::Geometry* g) const
+{
+    std::unique_ptr<geom::CoordinateSequence> coords = nearestPoints(g);
+    if ( ! coords ) return std::numeric_limits<double>::infinity();
+    return coords->getAt(0).distance( coords->getAt(1) );
+}
+
 std::string
 BasicPreparedGeometry::toString()
 {
diff --git a/src/geom/prep/Makefile.am b/src/geom/prep/Makefile.am
index db773c5..354bdbc 100644
--- a/src/geom/prep/Makefile.am
+++ b/src/geom/prep/Makefile.am
@@ -1,14 +1,14 @@
 #
-# This file is part of project GEOS (http://trac.osgeo.org/geos/) 
+# This file is part of project GEOS (http://trac.osgeo.org/geos/)
 #
 noinst_LTLIBRARIES = libgeomprep.la
 
-AM_CPPFLAGS = -I$(top_srcdir)/include 
+AM_CPPFLAGS = -I$(top_srcdir)/include
 
 ## these are full inlined
-# PolygonExtracter.cpp 
-# PointExtracter.cpp 
-# LinearComponentExtracter.cpp 
+# PolygonExtracter.cpp
+# PointExtracter.cpp
+# LinearComponentExtracter.cpp
 
 libgeomprep_la_SOURCES = \
     AbstractPreparedPolygonContains.cpp \
@@ -16,7 +16,9 @@ libgeomprep_la_SOURCES = \
     PreparedGeometry.cpp \
     PreparedGeometryFactory.cpp \
     PreparedLineString.cpp \
+    PreparedLineStringDistance.cpp \
     PreparedLineStringIntersects.cpp \
+    PreparedLineStringNearestPoints.cpp \
     PreparedPoint.cpp \
     PreparedPolygonContains.cpp \
     PreparedPolygonContainsProperly.cpp \
diff --git a/src/geom/prep/PreparedLineString.cpp b/src/geom/prep/PreparedLineString.cpp
index da9d022..0a936d6 100644
--- a/src/geom/prep/PreparedLineString.cpp
+++ b/src/geom/prep/PreparedLineString.cpp
@@ -3,6 +3,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.osgeo.org
  *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -18,7 +19,9 @@
 
 
 #include <geos/geom/prep/PreparedLineString.h>
+#include <geos/geom/prep/PreparedLineStringDistance.h>
 #include <geos/geom/prep/PreparedLineStringIntersects.h>
+#include <geos/geom/prep/PreparedLineStringNearestPoints.h>
 #include <geos/geom/GeometryFactory.h>
 #include <geos/geom/CoordinateSequenceFactory.h>
 #include <geos/noding/SegmentStringUtil.h>
@@ -64,7 +67,7 @@ PreparedLineString::intersects(const geom::Geometry* g) const
     return PreparedLineStringIntersects::intersects(prep, g);
 }
 
-/* private */
+/* public */
 operation::distance::IndexedFacetDistance*
 PreparedLineString::
 getIndexedFacetDistance() const
@@ -79,10 +82,13 @@ getIndexedFacetDistance() const
 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));
+    return PreparedLineStringNearestPoints::nearestPoints(*this, g);
+}
+
+double
+PreparedLineString::distance(const geom::Geometry* g) const
+{
+    return PreparedLineStringDistance::distance(*this, g);
 }
 
 
diff --git a/src/geom/prep/PreparedLineStringDistance.cpp b/src/geom/prep/PreparedLineStringDistance.cpp
new file mode 100644
index 0000000..740d8e3
--- /dev/null
+++ b/src/geom/prep/PreparedLineStringDistance.cpp
@@ -0,0 +1,46 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: ORIGINAL WORK
+ *
+ **********************************************************************/
+
+
+#include <geos/geom/prep/PreparedLineString.h>
+#include <geos/geom/prep/PreparedLineStringDistance.h>
+
+namespace geos {
+namespace geom { // geos.geom
+namespace prep { // geos.geom.prep
+
+double
+PreparedLineStringDistance::distance(const geom::Geometry* g) const
+{
+    if ( prepLine.getGeometry().isEmpty() || g->isEmpty() )
+    {
+        return std::numeric_limits<double>::infinity();
+    }
+
+    // TODO: test if this shortcut be any useful
+    //if ( prepLine.intersects(g) ) return 0.0;
+
+    /* Not intersecting, compute distance from facets */
+    operation::distance::IndexedFacetDistance *idf = prepLine.getIndexedFacetDistance();
+    return idf->distance(g);
+}
+
+
+} // namespace geos.geom.prep
+} // namespace geos.geom
+} // namespace geos
diff --git a/src/geom/prep/PreparedLineStringNearestPoints.cpp b/src/geom/prep/PreparedLineStringNearestPoints.cpp
new file mode 100644
index 0000000..227ae8d
--- /dev/null
+++ b/src/geom/prep/PreparedLineStringNearestPoints.cpp
@@ -0,0 +1,41 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2020 Sandro Santilli <strk at kbt.io>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: ORIGINAL WORK
+ *
+ **********************************************************************/
+
+
+#include <geos/geom/prep/PreparedLineString.h>
+#include <geos/geom/prep/PreparedLineStringNearestPoints.h>
+#include <geos/operation/distance/IndexedFacetDistance.h>
+#include <geos/geom/CoordinateSequenceFactory.h>
+#include <geos/geom/GeometryFactory.h>
+
+namespace geos {
+namespace geom { // geos.geom
+namespace prep { // geos.geom.prep
+
+std::unique_ptr<geom::CoordinateSequence>
+PreparedLineStringNearestPoints::nearestPoints(const geom::Geometry* g) const
+{
+    const GeometryFactory *gf = prepLine.getGeometry().getFactory();
+    const CoordinateSequenceFactory *cf = gf->getCoordinateSequenceFactory();
+    operation::distance::IndexedFacetDistance *idf = prepLine.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 001a547..b07dc8f 100644
--- a/src/geom/prep/PreparedPolygon.cpp
+++ b/src/geom/prep/PreparedPolygon.cpp
@@ -143,6 +143,32 @@ intersects(const geom::Geometry* g) const
     return PreparedPolygonIntersects::intersects(this, g);
 }
 
+/* private */
+operation::distance::IndexedFacetDistance*
+PreparedPolygon::
+getIndexedFacetDistance() const
+{
+    if(! indexedDistance ) {
+        indexedDistance.reset(new operation::distance::IndexedFacetDistance(&getGeometry()));
+    }
+    return indexedDistance.get();
+}
+
+double
+PreparedPolygon::distance(const geom::Geometry* g) const
+{
+    if ( getGeometry().isEmpty() || g->isEmpty() )
+    {
+        return std::numeric_limits<double>::infinity();
+    }
+
+    if ( intersects(g) ) return 0.0;
+
+    /* Not intersecting, compute distance from facets */
+    operation::distance::IndexedFacetDistance *idf = getIndexedFacetDistance();
+    return idf->distance(g);
+}
+
 } // namespace geos.geom.prep
 } // namespace geos.geom
 } // namespace geos
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index edda8c1..505fb96 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -106,6 +106,7 @@ geos_unit_SOURCES = \
 	capi/GEOSOrientationIndexTest.cpp \
 	capi/GEOSPointOnSurfaceTest.cpp \
 	capi/GEOSPolygonizeTest.cpp \
+	capi/GEOSPreparedDistanceTest.cpp \
 	capi/GEOSPreparedGeometryTest.cpp \
 	capi/GEOSPreparedNearestPointsTest.cpp \
 	capi/GEOSProjectTest.cpp \
diff --git a/tests/unit/capi/GEOSPreparedDistanceTest.cpp b/tests/unit/capi/GEOSPreparedDistanceTest.cpp
new file mode 100644
index 0000000..892cc43
--- /dev/null
+++ b/tests/unit/capi/GEOSPreparedDistanceTest.cpp
@@ -0,0 +1,181 @@
+//
+// Test Suite for C-API GEOSPreparedDistance
+
+#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_capigeosprepareddistance_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_capigeosprepareddistance_data()
+        : geom1_(nullptr), geom2_(nullptr), pgeom1_(nullptr)
+    {
+        initGEOS(notice, notice);
+    }
+
+    ~test_capigeosprepareddistance_data()
+    {
+        GEOSGeom_destroy(geom2_);
+        GEOSPreparedGeom_destroy(pgeom1_);
+        GEOSGeom_destroy(geom1_);
+        geom1_ = nullptr;
+        geom2_ = nullptr;
+        geom1_ = nullptr;
+        finishGEOS();
+    }
+
+    void checkDistance(const char* wkt1, const char* wkt2,
+                       double dist, double tol=0)
+    {
+        geom1_ = GEOSGeomFromWKT(wkt1);
+        ensure(nullptr != geom1_);
+        pgeom1_ = GEOSPrepare(geom1_);
+        ensure(nullptr != pgeom1_);
+        geom2_ = GEOSGeomFromWKT(wkt2);
+        ensure(nullptr != geom2_);
+
+
+        double obt_dist;
+        int ret = GEOSPreparedDistance(pgeom1_, geom2_, &obt_dist);
+        ensure_equals("return code", ret, 1);
+        ensure_equals("distance", obt_dist, dist, tol);
+
+    }
+
+
+};
+
+typedef test_group<test_capigeosprepareddistance_data> group;
+typedef group::object object;
+
+group test_capigeosprepareddistance_group("capi::GEOSPreparedDistance");
+
+//
+// Test Cases
+//
+
+template<>
+template<>
+void object::test<1>
+()
+{
+    checkDistance(
+        "POLYGON EMPTY",
+        "POLYGON EMPTY",
+        std::numeric_limits<double>::infinity()
+    );
+}
+
+template<>
+template<>
+void object::test<2>
+()
+{
+    checkDistance(
+        "POLYGON((1 1,1 5,5 5,5 1,1 1))",
+        "POLYGON((8 8, 9 9, 9 10, 8 8))",
+        4.242640687119285, 1e-12
+    );
+
+}
+
+template<>
+template<>
+void object::test<3>
+()
+{
+    checkDistance(
+        "POLYGON((1 1,1 5,5 5,5 1,1 1))",
+        "POINT(2 2)",
+        0
+    );
+}
+
+template<>
+template<>
+void object::test<4>
+()
+{
+    checkDistance(
+        "LINESTRING(1 5,5 5,5 1,1 1)",
+        "POINT(2 2)",
+        1
+    );
+}
+
+template<>
+template<>
+void object::test<5>
+()
+{
+    checkDistance(
+        "LINESTRING(0 0,10 10)",
+        "LINESTRING(0 10,10 0)",
+        0
+    );
+}
+
+template<>
+template<>
+void object::test<6>
+()
+{
+    checkDistance(
+        "POLYGON((0 0,10 0,10 10,0 10,0 0))",
+        "LINESTRING(8 5,12 5)",
+        0
+    );
+}
+
+template<>
+template<>
+void object::test<7>
+()
+{
+    checkDistance(
+        "LINESTRING EMPTY",
+        "POINT EMPTY",
+        std::numeric_limits<double>::infinity()
+    );
+}
+
+template<>
+template<>
+void object::test<8>
+()
+{
+    checkDistance(
+        "POINT EMPTY",
+        "LINESTRING EMPTY",
+        std::numeric_limits<double>::infinity()
+    );
+}
+
+} // namespace tut
+

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

Summary of changes:
 NEWS                                               |   1 +
 capi/geos_c.cpp                                    |   6 +
 capi/geos_c.h.in                                   |   6 +
 capi/geos_ts_c.cpp                                 |  11 ++
 include/geos/geom/prep/BasicPreparedGeometry.h     |   5 +
 include/geos/geom/prep/Makefile.am                 |   9 +-
 include/geos/geom/prep/PreparedGeometry.h          |  10 ++
 include/geos/geom/prep/PreparedLineString.h        |   4 +-
 .../geos/geom/prep/PreparedLineStringDistance.h    |  57 +++++++
 .../geom/prep/PreparedLineStringNearestPoints.h    |  56 +++++++
 include/geos/geom/prep/PreparedPolygon.h           |   5 +
 include/geos/geom/prep/PreparedPolygonDistance.h   |  67 ++++++++
 src/geom/prep/BasicPreparedGeometry.cpp            |   8 +
 src/geom/prep/Makefile.am                          |  15 +-
 src/geom/prep/PreparedLineString.cpp               |  16 +-
 ...redPoint.cpp => PreparedLineStringDistance.cpp} |  25 ++-
 src/geom/prep/PreparedLineStringNearestPoints.cpp  |  41 +++++
 src/geom/prep/PreparedPolygon.cpp                  |  18 ++
 ...gonContains.cpp => PreparedPolygonDistance.cpp} |  39 ++---
 tests/unit/Makefile.am                             |   1 +
 tests/unit/capi/GEOSPreparedDistanceTest.cpp       | 181 +++++++++++++++++++++
 21 files changed, 536 insertions(+), 45 deletions(-)
 create mode 100644 include/geos/geom/prep/PreparedLineStringDistance.h
 create mode 100644 include/geos/geom/prep/PreparedLineStringNearestPoints.h
 create mode 100644 include/geos/geom/prep/PreparedPolygonDistance.h
 copy src/geom/prep/{PreparedPoint.cpp => PreparedLineStringDistance.cpp} (51%)
 create mode 100644 src/geom/prep/PreparedLineStringNearestPoints.cpp
 copy src/geom/prep/{PreparedPolygonContains.cpp => PreparedPolygonDistance.cpp} (54%)
 create mode 100644 tests/unit/capi/GEOSPreparedDistanceTest.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list