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

git at osgeo.org git at osgeo.org
Tue Dec 11 14:32:35 PST 2018


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  b61e66308e8d2b00ac025ac9ad4ab78b55d5f1d7 (commit)
      from  72b256ec6d6c5f321c2db65d3d1aa5e586f65f8c (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 b61e66308e8d2b00ac025ac9ad4ab78b55d5f1d7
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Tue Dec 11 14:32:12 2018 -0800

    Blind port for RayCrossingCounterDD and some minor
    changes to existing files

diff --git a/.gitignore b/.gitignore
index 40bf331..3539e0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ tests/perf/operation/predicate/RectangleIntersectsPerfTest
 tests/perf/capi/memleak_mp_prep
 tests/perf/ClassSizes
 include/geos/platform.h
+include/geos/platform.h.disabled
 include/geos/stamp-h2
 include/geos/version.h
 include/stamp-h1
diff --git a/include/geos/algorithm/CGAlgorithmsDD.h b/include/geos/algorithm/CGAlgorithmsDD.h
index 20e9972..d67660e 100644
--- a/include/geos/algorithm/CGAlgorithmsDD.h
+++ b/include/geos/algorithm/CGAlgorithmsDD.h
@@ -54,7 +54,8 @@ public:
     enum {
         RIGHT=-1,
         LEFT=1,
-        STRAIGHT=0
+        STRAIGHT=0,
+        FAILURE=2
     };
 
     /**
@@ -96,11 +97,11 @@ public:
                                       const geom::Coordinate& pb,
                                       const geom::Coordinate& pc);
 
-    static int signum(double x)
+    static int orientation(double x)
     {
-        if (x > 0) return 1;
-        if (x < 0) return -1;
-        return 0;
+        if (x < 0) return CGAlgorithmsDD::RIGHT;
+        if (x > 0) return CGAlgorithmsDD::LEFT;
+        return CGAlgorithmsDD::STRAIGHT;
     }
 
     static void intersection(const geom::Coordinate& p1, const geom::Coordinate& p2,
diff --git a/include/geos/algorithm/Makefile.am b/include/geos/algorithm/Makefile.am
index d88faa9..5df8b26 100644
--- a/include/geos/algorithm/Makefile.am
+++ b/include/geos/algorithm/Makefile.am
@@ -11,27 +11,28 @@ EXTRA_DIST =
 geosdir = $(includedir)/geos/algorithm
 
 geos_HEADERS = \
-    Angle.h \
-    BoundaryNodeRule.h \
-    CentralEndpointIntersector.h \
-    Centroid.h \
-    CentroidArea.h \
-    CentroidLine.h \
-    CentroidPoint.h \
-    CGAlgorithms.h \
-    ConvexHull.h \
-    ConvexHull.inl \
-    HCoordinate.h \
-    InteriorPointArea.h \
-    InteriorPointLine.h \
-    InteriorPointPoint.h \
-    LineIntersector.h \
-    MCPointInRing.h \
-    MinimumDiameter.h \
-    NotRepresentableException.h \
-    PointInRing.h \
-    PointLocator.h \
-    RayCrossingCounter.h \
-    RobustDeterminant.h \
-    SimplePointInRing.h \
-    SIRtreePointInRing.h
+	Angle.h \
+	BoundaryNodeRule.h \
+	CentralEndpointIntersector.h \
+	Centroid.h \
+	CentroidArea.h \
+	CentroidLine.h \
+	CentroidPoint.h \
+	CGAlgorithms.h \
+	ConvexHull.h \
+	ConvexHull.inl \
+	HCoordinate.h \
+	InteriorPointArea.h \
+	InteriorPointLine.h \
+	InteriorPointPoint.h \
+	LineIntersector.h \
+	MCPointInRing.h \
+	MinimumDiameter.h \
+	NotRepresentableException.h \
+	PointInRing.h \
+	PointLocator.h \
+	RayCrossingCounter.h \
+	RayCrossingCounterDD.h \
+	RobustDeterminant.h \
+	SimplePointInRing.h \
+	SIRtreePointInRing.h
diff --git a/include/geos/algorithm/RayCrossingCounterDD.h b/include/geos/algorithm/RayCrossingCounterDD.h
new file mode 100644
index 0000000..1bb431b
--- /dev/null
+++ b/include/geos/algorithm/RayCrossingCounterDD.h
@@ -0,0 +1,167 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2018 Paul Ramsey <pramsey at cleverelephant.ca>
+ *
+ * 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: algorithm/RayCrossingCounterDD.java rev. 1.2 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_ALGORITHM_RAYCROSSINGCOUNTERDD_H
+#define GEOS_ALGORITHM_RAYCROSSINGCOUNTERDD_H
+
+#include <geos/export.h>
+#include <geos/algorithm/ttmath/ttmath.h>
+
+#include <vector>
+
+// forward declarations
+namespace geos {
+namespace geom {
+class Coordinate;
+class CoordinateSequence;
+}
+}
+
+
+namespace geos {
+namespace algorithm {
+
+/**
+ * Counts the number of segments crossed by a horizontal ray extending to the right
+ * from a given point, in an incremental fashion.
+ * This can be used to determine whether a point lies in a {@link Polygonal} geometry.
+ * The class determines the situation where the point lies exactly on a segment.
+ * When being used for Point-In-Polygon determination, this case allows short-circuiting
+ * the evaluation.
+ * <p>
+ * This class handles polygonal geometries with any number of shells and holes.
+ * The orientation of the shell and hole rings is unimportant.
+ * In order to compute a correct location for a given polygonal geometry,
+ * it is essential that <b>all</b> segments are counted which
+ * <ul>
+ * <li>touch the ray
+ * <li>lie in in any ring which may contain the point
+ * </ul>
+ * The only exception is when the point-on-segment situation is detected, in which
+ * case no further processing is required.
+ * The implication of the above rule is that segments
+ * which can be a priori determined to <i>not</i> touch the ray
+ * (i.e. by a test of their bounding box or Y-extent)
+ * do not need to be counted.  This allows for optimization by indexing.
+ */
+
+class GEOS_DLL RayCrossingCounterDD {
+private:
+    const geom::Coordinate& point;
+
+    int crossingCount;
+
+    // true if the test point lies on an input segment
+    bool isPointOnSegment;
+
+    // Declare type as noncopyable
+    RayCrossingCounterDD(const RayCrossingCounterDD& other) = delete;
+    RayCrossingCounterDD& operator=(const RayCrossingCounterDD& rhs) = delete;
+
+public:
+    /**
+     * Determines the {@link Location} of a point in a ring.
+     * This method is an exemplar of how to use this class.
+     *
+     * @param p the point to test
+     * @param ring an array of Coordinates forming a ring
+     * @return the location of the point in the ring
+     */
+    static int locatePointInRing(const geom::Coordinate& p,
+                                 const geom::CoordinateSequence& ring);
+
+    /// Semantically equal to the above, just different args encoding
+    static int locatePointInRing(const geom::Coordinate& p,
+                                 const std::vector<const geom::Coordinate*>& ring);
+
+    /** \brief
+     * Returns the index of the direction of the point <code>q</code>
+     * relative to a vector specified by <code>p1-p2</code>.
+     *
+     * @param p1 the origin point of the vector
+     * @param p2 the final point of the vector
+     * @param q the point to compute the direction to
+     *
+     * @return 1 if q is counter-clockwise (left) from p1-p2
+     * @return -1 if q is clockwise (right) from p1-p2
+     * @return 0 if q is collinear with p1-p2
+     */
+    static int orientationIndex(const geom::Coordinate& p1,
+                                const geom::Coordinate& p2,
+                                const geom::Coordinate& q);
+
+    RayCrossingCounterDD(const geom::Coordinate& p_point):
+        point(p_point),
+        crossingCount(0),
+        isPointOnSegment(false)
+    { }
+
+    /**
+     * Counts a segment
+     *
+     * @param p1 an endpoint of the segment
+     * @param p2 another endpoint of the segment
+     */
+    void countSegment(const geom::Coordinate& p1,
+                      const geom::Coordinate& p2);
+
+    /**
+     * Reports whether the point lies exactly on one of the supplied segments.
+     * This method may be called at any time as segments are processed.
+     * If the result of this method is <tt>true</tt>,
+     * no further segments need be supplied, since the result
+     * will never change again.
+     *
+     * @return true if the point lies exactly on a segment
+     */
+    bool isOnSegment()
+    {
+        return isPointOnSegment;
+    }
+
+    /**
+     * Gets the {@link Location} of the point relative to
+     * the ring, polygon
+     * or multipolygon from which the processed segments were provided.
+     * <p>
+     * This method only determines the correct location
+     * if <b>all</b> relevant segments must have been processed.
+     *
+     * @return the Location of the point
+     */
+    int getLocation();
+
+    /**
+     * Tests whether the point lies in or on
+     * the ring, polygon
+     * or multipolygon from which the processed segments were provided.
+     * <p>
+     * This method only determines the correct location
+     * if <b>all</b> relevant segments must have been processed.
+     *
+     * @return true if the point lies in or on the supplied polygon
+     */
+    bool isPointInPolygon();
+
+};
+
+} // geos::algorithm
+} // geos
+
+#endif // GEOS_ALGORITHM_RAYCROSSINGCOUNTERDD_H
diff --git a/src/algorithm/CGAlgorithmsDD.cpp b/src/algorithm/CGAlgorithmsDD.cpp
index 6663691..dedd617 100644
--- a/src/algorithm/CGAlgorithmsDD.cpp
+++ b/src/algorithm/CGAlgorithmsDD.cpp
@@ -22,27 +22,28 @@
 #include <sstream>
 
 using namespace geos::geom;
+using namespace geos::algorithm;
 
 namespace {
 
 double const DP_SAFE_EPSILON =  1e-15;
 
-inline int SigNumDD(DD const& dd)
+inline int OrientationDD(DD const& dd)
 {
     static DD const zero(0.0);
     if (dd < zero)
-        return -1;
+        return CGAlgorithmsDD::RIGHT;
 
     if (dd > zero)
-        return 1;
+        return CGAlgorithmsDD::LEFT;
 
-    return 0;
+    return CGAlgorithmsDD::STRAIGHT;
 }
 
-inline std::string ToStringDD(DD const& dd)
-{
-    return dd.ToString();
-}
+// inline std::string ToStringDD(DD const& dd)
+// {
+//     return dd.ToString();
+// }
 }
 
 namespace geos {
@@ -52,6 +53,7 @@ int CGAlgorithmsDD::orientationIndex(const Coordinate& p1,
                                      const Coordinate& p2,
                                      const Coordinate& q)
 {
+    static DD const zero(0.0);
     DD dx1 = DD(p2.x) + DD(-p1.x);
     DD dy1 = DD(p2.y) + DD(-p1.y);
     DD dx2 = DD(q.x) + DD(-p2.x);
@@ -59,7 +61,7 @@ int CGAlgorithmsDD::orientationIndex(const Coordinate& p1,
     DD mx1y2(dx1 * dy2);
     DD my1x2(dy1 * dx2);
     DD d = mx1y2 - my1x2;
-    return SigNumDD(d);
+    return OrientationDD(d);
 }
 
 int CGAlgorithmsDD::signOfDet2x2(DD &x1, DD &y1, DD &x2, DD &y2)
@@ -67,7 +69,7 @@ int CGAlgorithmsDD::signOfDet2x2(DD &x1, DD &y1, DD &x2, DD &y2)
     DD mx1y2(x1 * y2);
     DD my1x2(y1 * x2);
     DD d = mx1y2 - my1x2;
-    return SigNumDD(d);
+    return OrientationDD(d);
 }
 
 int CGAlgorithmsDD::orientationIndexFilter(const Coordinate& pa,
@@ -81,7 +83,7 @@ int CGAlgorithmsDD::orientationIndexFilter(const Coordinate& pa,
 
     if (detleft > 0.0) {
         if (detright <= 0.0) {
-            return signum(det);
+            return orientation(det);
         }
         else {
             detsum = detleft + detright;
@@ -89,21 +91,21 @@ int CGAlgorithmsDD::orientationIndexFilter(const Coordinate& pa,
     }
     else if (detleft < 0.0) {
         if (detright >= 0.0) {
-            return signum(det);
+            return orientation(det);
         }
         else {
             detsum = -detleft - detright;
         }
     }
     else {
-        return signum(det);
+        return orientation(det);
     }
 
     double const errbound = DP_SAFE_EPSILON * detsum;
     if ((det >= errbound) || (-det >= errbound)) {
-        return signum(det);
+        return orientation(det);
     }
-    return 2;
+    return CGAlgorithmsDD::FAILURE;
 }
 
 void CGAlgorithmsDD::intersection(const Coordinate& p1, const Coordinate& p2,
diff --git a/src/algorithm/Makefile.am b/src/algorithm/Makefile.am
index a9181ff..f735bce 100644
--- a/src/algorithm/Makefile.am
+++ b/src/algorithm/Makefile.am
@@ -1,43 +1,40 @@
 #
-# 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 = \
-    locate \
-    distance
+	locate \
+	distance
 
 noinst_LTLIBRARIES = libalgorithm.la
 
-AM_CPPFLAGS = -I$(top_srcdir)/include 
+AM_CPPFLAGS = -I$(top_srcdir)/include
 
 libalgorithm_la_SOURCES = \
-    Angle.cpp \
-    BoundaryNodeRule.cpp \
-    Centroid.cpp \
-    CentroidArea.cpp \
-    CentroidLine.cpp \
-    CentroidPoint.cpp \
-    CGAlgorithms.cpp \
-    CGAlgorithmsDD.cpp \
-    ConvexHull.cpp \
-    HCoordinate.cpp \
-    InteriorPointArea.cpp \
-    InteriorPointLine.cpp \
-    InteriorPointPoint.cpp \
-    LineIntersector.cpp \
-    MCPointInRing.cpp \
-    MinimumDiameter.cpp \
-    NotRepresentableException.cpp \
-    PointLocator.cpp \
-    RayCrossingCounter.cpp \
-    RobustDeterminant.cpp \
-    SimplePointInRing.cpp \
-    SIRtreePointInRing.cpp 
+	Angle.cpp \
+	BoundaryNodeRule.cpp \
+	Centroid.cpp \
+	CentroidArea.cpp \
+	CentroidLine.cpp \
+	CentroidPoint.cpp \
+	CGAlgorithms.cpp \
+	CGAlgorithmsDD.cpp \
+	ConvexHull.cpp \
+	HCoordinate.cpp \
+	InteriorPointArea.cpp \
+	InteriorPointLine.cpp \
+	InteriorPointPoint.cpp \
+	LineIntersector.cpp \
+	MCPointInRing.cpp \
+	MinimumDiameter.cpp \
+	NotRepresentableException.cpp \
+	PointLocator.cpp \
+	RayCrossingCounter.cpp \
+	RayCrossingCounterDD.cpp \
+	RobustDeterminant.cpp \
+	SimplePointInRing.cpp \
+	SIRtreePointInRing.cpp
 
-# Deprecated files
-# (http://geos.osgeo.org/pipermail/geos-devel/2006-March/001828.html):
-#NonRobustLineIntersector.cpp
-#RobustLineIntersector.cpp
 
-libalgorithm_la_LIBADD =  \
-        locate/liblocation.la \
-        distance/libdistance.la
+libalgorithm_la_LIBADD = \
+	locate/liblocation.la \
+	distance/libdistance.la
diff --git a/src/algorithm/RayCrossingCounterDD.cpp b/src/algorithm/RayCrossingCounterDD.cpp
new file mode 100644
index 0000000..44a7bf6
--- /dev/null
+++ b/src/algorithm/RayCrossingCounterDD.cpp
@@ -0,0 +1,171 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2018 Paul Ramsey <pramsey at cleverelephant.ca>
+ *
+ * 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: algorithm/RayCrossingCounterDD.java rev. 1.2 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#include <geos/algorithm/RayCrossingCounterDD.h>
+#include <geos/algorithm/CGAlgorithmsDD.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/Location.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateSequence.h>
+
+
+namespace geos {
+namespace algorithm {
+//
+// private:
+//
+
+//
+// protected:
+//
+
+//
+// public:
+//
+/*static*/
+int
+RayCrossingCounterDD::locatePointInRing(const geom::Coordinate& point,
+                                        const geom::CoordinateSequence& ring)
+{
+    RayCrossingCounterDD rcc(point);
+
+    for (std::size_t i = 1, ni = ring.size(); i < ni; i++) {
+        const geom::Coordinate & p1 = ring[ i - 1 ];
+        const geom::Coordinate & p2 = ring[ i ];
+
+        rcc.countSegment(p1, p2);
+
+        if (rcc.isOnSegment())
+            return rcc.getLocation();
+    }
+    return rcc.getLocation();
+}
+
+/*static*/
+int
+RayCrossingCounterDD::locatePointInRing(const geom::Coordinate& point,
+                                        const std::vector<const geom::Coordinate*>& ring)
+{
+    RayCrossingCounterDD rcc(point);
+
+    for (std::size_t i = 1, ni = ring.size(); i < ni; i++) {
+        const geom::Coordinate & p1 = *ring[ i - 1 ];
+        const geom::Coordinate & p2 = *ring[ i ];
+
+        rcc.countSegment(p1, p2);
+
+        if (rcc.isOnSegment())
+            return rcc.getLocation();
+    }
+    return rcc.getLocation();
+}
+
+/*public static*/
+int
+RayCrossingCounterDD::orientationIndex(const geom::Coordinate& p1,
+                                       const geom::Coordinate& p2, const geom::Coordinate& q)
+{
+    return CGAlgorithmsDD::orientationIndex(p1, p2, q);
+}
+
+void
+RayCrossingCounterDD::countSegment(const geom::Coordinate& p1,
+                                   const geom::Coordinate& p2)
+{
+    // For each segment, check if it crosses
+    // a horizontal ray running from the test point in
+    // the positive x direction.
+
+    // check if the segment is strictly to the left of the test point
+    if (p1.x < point.x && p2.x < point.x)
+        return;
+
+    // check if the point is equal to the current ring vertex
+    if (point.x == p2.x && point.y == p2.y) {
+        isPointOnSegment = true;
+        return;
+    }
+
+    // For horizontal segments, check if the point is on the segment.
+    // Otherwise, horizontal segments are not counted.
+    if (p1.y == point.y && p2.y == point.y) {
+        double minx = p1.x;
+        double maxx = p2.x;
+
+        if (minx > maxx) {
+            minx = p2.x;
+            maxx = p1.x;
+        }
+
+        if (point.x >= minx && point.x <= maxx)
+            isPointOnSegment = true;
+
+        return;
+    }
+
+    // Evaluate all non-horizontal segments which cross a horizontal ray
+    // to the right of the test pt.
+    // To avoid double-counting shared vertices, we use the convention that
+    // - an upward edge includes its starting endpoint, and excludes its
+    //   final endpoint
+    // - a downward edge excludes its starting endpoint, and includes its
+    //   final endpoint
+    if (((p1.y > point.y) && (p2.y <= point.y)) ||
+            ((p2.y > point.y) && (p1.y <= point.y))) {
+        // For an upward edge, orientationIndex will be positive when p1->p2
+        // crosses ray. Conversely, downward edges should have negative sign.
+        int sign = CGAlgorithmsDD::orientationIndex(p1, p2, point);
+        if (sign == CGAlgorithmsDD::STRAIGHT) {
+            isPointOnSegment = true;
+            return;
+        }
+
+        if (p2.y < p1.y)
+            sign = -sign;
+
+        // The segment crosses the ray if the sign is strictly positive.
+        if (sign == CGAlgorithmsDD::LEFT)
+            crossingCount++;
+    }
+}
+
+
+int
+RayCrossingCounterDD::getLocation()
+{
+    if (isPointOnSegment)
+        return geom::Location::BOUNDARY;
+
+    // The point is in the interior of the ring if the number
+    // of X-crossings is odd.
+    if ((crossingCount % 2) == 1)
+        return geom::Location::INTERIOR;
+
+    return geom::Location::EXTERIOR;
+}
+
+
+bool
+RayCrossingCounterDD::isPointInPolygon()
+{
+    return getLocation() != geom::Location::EXTERIOR;
+}
+
+
+} // geos::algorithm
+} // geos
diff --git a/src/geom/util/Densifier.cpp b/src/geom/util/Densifier.cpp
index 11fd73b..ff427a5 100644
--- a/src/geom/util/Densifier.cpp
+++ b/src/geom/util/Densifier.cpp
@@ -106,7 +106,6 @@ Densifier::densifyPoints(const Coordinate::Vect pts, double distanceTolerance, c
 {
 	geom::LineSegment seg;
 	geom::CoordinateList coordList;
-	geom::CoordinateList::iterator it = coordList.begin();
 
 	for (Coordinate::Vect::const_iterator it=pts.begin(), itEnd=pts.end()-1; it < itEnd; ++it)
 	{

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

Summary of changes:
 .gitignore                                    |   1 +
 include/geos/algorithm/CGAlgorithmsDD.h       |  11 +-
 include/geos/algorithm/Makefile.am            |  49 ++++----
 include/geos/algorithm/RayCrossingCounterDD.h | 167 +++++++++++++++++++++++++
 src/algorithm/CGAlgorithmsDD.cpp              |  32 ++---
 src/algorithm/Makefile.am                     |  63 +++++-----
 src/algorithm/RayCrossingCounterDD.cpp        | 171 ++++++++++++++++++++++++++
 src/geom/util/Densifier.cpp                   |   1 -
 8 files changed, 417 insertions(+), 78 deletions(-)
 create mode 100644 include/geos/algorithm/RayCrossingCounterDD.h
 create mode 100644 src/algorithm/RayCrossingCounterDD.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list