[geos-commits] r2361 - in trunk: . source/algorithm source/algorithm/distance source/headers/geos/algorithm source/headers/geos/algorithm/distance source/headers/geos/geom

svn_geos at osgeo.org svn_geos at osgeo.org
Tue Apr 14 12:43:40 EDT 2009


Author: strk
Date: 2009-04-14 12:43:40 -0400 (Tue, 14 Apr 2009)
New Revision: 2361

Added:
   trunk/source/algorithm/distance/
   trunk/source/algorithm/distance/DiscreteHausdorffDistance.cpp
   trunk/source/algorithm/distance/EuclideanDistanceToPoint.cpp
   trunk/source/algorithm/distance/Makefile.am
   trunk/source/headers/geos/algorithm/distance/
   trunk/source/headers/geos/algorithm/distance/DiscreteHausdorffDistance.h
   trunk/source/headers/geos/algorithm/distance/EuclideanDistanceToPoint.h
   trunk/source/headers/geos/algorithm/distance/Makefile.am
   trunk/source/headers/geos/algorithm/distance/PointPairDistance.h
Modified:
   trunk/configure.in
   trunk/source/algorithm/Makefile.am
   trunk/source/headers/geos/algorithm/Makefile.am
   trunk/source/headers/geos/geom/CoordinateSequenceFilter.h
Log:
Port the algorithm::distance package from JTS 1.9


Modified: trunk/configure.in
===================================================================
--- trunk/configure.in	2009-04-14 15:25:58 UTC (rev 2360)
+++ trunk/configure.in	2009-04-14 16:43:40 UTC (rev 2361)
@@ -270,6 +270,7 @@
 	source/Makefile 
 	source/algorithm/Makefile
 	source/algorithm/locate/Makefile
+	source/algorithm/distance/Makefile
 	source/geom/Makefile
 	source/geom/prep/Makefile
 	source/geom/util/Makefile
@@ -279,6 +280,7 @@
 	source/headers/geos/Makefile
 	source/headers/geos/algorithm/Makefile
 	source/headers/geos/algorithm/locate/Makefile
+	source/headers/geos/algorithm/distance/Makefile
 	source/headers/geos/geom/Makefile
 	source/headers/geos/geom/prep/Makefile
 	source/headers/geos/geom/util/Makefile

Modified: trunk/source/algorithm/Makefile.am
===================================================================
--- trunk/source/algorithm/Makefile.am	2009-04-14 15:25:58 UTC (rev 2360)
+++ trunk/source/algorithm/Makefile.am	2009-04-14 16:43:40 UTC (rev 2361)
@@ -1,5 +1,6 @@
 SUBDIRS = \
-	locate
+	locate \
+	distance
 
 noinst_LTLIBRARIES = libalgorithm.la
 
@@ -32,5 +33,6 @@
 #RobustLineIntersector.cpp
 
 libalgorithm_la_LIBADD =  \
-        locate/liblocation.la           
+        locate/liblocation.la \
+        distance/libdistance.la
 

Added: trunk/source/algorithm/distance/DiscreteHausdorffDistance.cpp
===================================================================
--- trunk/source/algorithm/distance/DiscreteHausdorffDistance.cpp	                        (rev 0)
+++ trunk/source/algorithm/distance/DiscreteHausdorffDistance.cpp	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,70 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * 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/distance/DiscreteHausdorffDistance.java 1.4 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#include <geos/algorithm/distance/DiscreteHausdorffDistance.h>
+#include <geos/geom/CoordinateSequence.h>
+
+//#include <geos/algorithm/CGAlgorithms.h>
+//#include <geos/geom/Geometry.h>
+//#include <geos/geom/Polygon.h>
+//#include <geos/geom/GeometryCollection.h>
+//#include <geos/geom/Location.h>
+//#include <geos/geom/LineString.h>
+
+#include <typeinfo>
+#include <cassert>
+
+using namespace geos::geom;
+
+namespace geos {
+namespace algorithm { // geos.algorithm
+namespace distance { // geos.algorithm.distance
+
+void
+DiscreteHausdorffDistance::MaxDensifiedByFractionDistanceFilter::filter_ro(
+	const geom::CoordinateSequence& seq, size_t index)
+{
+    /**
+     * This logic also handles skipping Point geometries
+     */
+    if (index == 0)
+      return;
+
+    const geom::Coordinate& p0 = seq.getAt(index - 1);
+    const geom::Coordinate& p1 = seq.getAt(index);
+
+    double delx = (p1.x - p0.x)/numSubSegs;
+    double dely = (p1.y - p0.y)/numSubSegs;
+
+    for (size_t i = 0; i < numSubSegs; ++i) {
+      double x = p0.x + i*delx;
+      double y = p0.y + i*dely;
+      Coordinate pt(x, y);
+      minPtDist.initialize();
+      EuclideanDistanceToPoint::computeDistance(geom, pt, minPtDist);
+      maxPtDist.setMaximum(minPtDist);
+    }
+
+}
+
+
+} // namespace geos.algorithm.distance
+} // namespace geos.algorithm
+} // namespace geos
+

Added: trunk/source/algorithm/distance/EuclideanDistanceToPoint.cpp
===================================================================
--- trunk/source/algorithm/distance/EuclideanDistanceToPoint.cpp	                        (rev 0)
+++ trunk/source/algorithm/distance/EuclideanDistanceToPoint.cpp	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,119 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * 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/distance/EuclideanDistanceToPoint.java 1.1 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#include <geos/algorithm/distance/EuclideanDistanceToPoint.h>
+#include <geos/algorithm/distance/PointPairDistance.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/LineSegment.h>
+#include <geos/geom/LineString.h>
+#include <geos/geom/Polygon.h>
+#include <geos/geom/GeometryCollection.h>
+
+#include <typeinfo> // for dynamic_cast
+#include <cassert>
+
+using namespace geos::geom;
+
+namespace geos {
+namespace algorithm { // geos.algorithm
+namespace distance { // geos.algorithm.distance
+
+/* static */
+LineSegment EuclideanDistanceToPoint::tempSegment;
+
+
+/* public static */
+void
+EuclideanDistanceToPoint::computeDistance(const geom::Geometry& geom,
+                                          const geom::Coordinate& pt,
+                                          PointPairDistance& ptDist)
+{
+	if ( const LineString* ls = dynamic_cast<const LineString*>(&geom) )
+	{
+		computeDistance(*ls, pt, ptDist);
+	}
+	else if ( const Polygon* pl = dynamic_cast<const Polygon*>(&geom) )
+	{
+		computeDistance(*pl, pt, ptDist);
+	}
+	else if ( const GeometryCollection* gc = dynamic_cast<const GeometryCollection*>(&geom) )
+	{
+		for (size_t i = 0; i < gc->getNumGeometries(); i++)
+		{
+			const Geometry* g = gc->getGeometryN(i);
+			computeDistance(*g, pt, ptDist);
+		}
+	}
+	else
+	{
+		// assume geom is Point
+		ptDist.setMinimum(*(geom.getCoordinate()), pt);
+	}
+}
+
+/* public static */
+void
+EuclideanDistanceToPoint::computeDistance(const geom::LineString& line,
+                                          const geom::Coordinate& pt,
+                                          PointPairDistance& ptDist)
+{
+	const CoordinateSequence* coordsRO = line.getCoordinatesRO();
+	const CoordinateSequence& coords = *coordsRO;
+	for (size_t i=0, n=coords.size()-1; i<n; ++i)
+	{
+		// NOT THREAD SAFE
+		tempSegment.setCoordinates(coords[i], coords[i + 1]);
+		// this is somewhat inefficient - could do better
+		Coordinate closestPt;
+		tempSegment.closestPoint(pt, closestPt);
+		ptDist.setMinimum(closestPt, pt);
+	}
+
+}
+
+/* public static */
+void
+EuclideanDistanceToPoint::computeDistance(const geom::LineSegment& segment,
+                                          const geom::Coordinate& pt,
+                                          PointPairDistance& ptDist)
+{
+	Coordinate closestPt;
+	segment.closestPoint(pt, closestPt);
+	ptDist.setMinimum(closestPt, pt);
+}
+
+/* public static */
+void
+EuclideanDistanceToPoint::computeDistance(const geom::Polygon& poly,
+                                          const geom::Coordinate& pt,
+                                          PointPairDistance& ptDist)
+{
+	computeDistance(*(poly.getExteriorRing()), pt, ptDist);
+	for (size_t i=0, n=poly.getNumInteriorRing(); i<n; ++i)
+	{
+		computeDistance(*(poly.getInteriorRingN(i)), pt, ptDist);
+	}
+}
+
+
+} // namespace geos.algorithm.distance
+} // namespace geos.algorithm
+} // namespace geos
+

Added: trunk/source/algorithm/distance/Makefile.am
===================================================================
--- trunk/source/algorithm/distance/Makefile.am	                        (rev 0)
+++ trunk/source/algorithm/distance/Makefile.am	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,13 @@
+SUBDIRS = 
+
+noinst_LTLIBRARIES = libdistance.la
+
+INCLUDES = -I$(top_srcdir)/source/headers 
+
+libdistance_la_SOURCES = \
+	DiscreteHausdorffDistance.cpp \
+	EuclideanDistanceToPoint.cpp 
+
+libdistance_la_LIBADD = 
+
+

Modified: trunk/source/headers/geos/algorithm/Makefile.am
===================================================================
--- trunk/source/headers/geos/algorithm/Makefile.am	2009-04-14 15:25:58 UTC (rev 2360)
+++ trunk/source/headers/geos/algorithm/Makefile.am	2009-04-14 16:43:40 UTC (rev 2361)
@@ -1,5 +1,6 @@
 SUBDIRS = \
-	locate 
+	locate \
+	distance
 
 EXTRA_DIST = 
 

Added: trunk/source/headers/geos/algorithm/distance/DiscreteHausdorffDistance.h
===================================================================
--- trunk/source/headers/geos/algorithm/distance/DiscreteHausdorffDistance.h	                        (rev 0)
+++ trunk/source/headers/geos/algorithm/distance/DiscreteHausdorffDistance.h	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,257 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * 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/distance/DiscreteHausdorffDistance.java 1.4 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
+#define GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
+
+#include <geos/algorithm/distance/PointPairDistance.h> // for composition
+#include <geos/algorithm/distance/EuclideanDistanceToPoint.h> // for composition
+#include <geos/util/IllegalArgumentException.h> // for inlines
+#include <geos/geom/Geometry.h> // for inlines
+#include <geos/util/math.h> // for inlines
+#include <geos/geom/CoordinateFilter.h> // for inheritance
+#include <geos/geom/CoordinateSequenceFilter.h> // for inheritance
+
+#include <vector>
+
+namespace geos {
+	namespace algorithm {
+		//class RayCrossingCounter;
+	}
+	namespace geom {
+		class Geometry;
+		class Coordinate; 
+		//class CoordinateSequence; 
+	}
+	namespace index {
+		namespace intervalrtree {
+			//class SortedPackedIntervalRTree;
+		}
+	}
+}
+
+namespace geos {
+namespace algorithm { // geos::algorithm
+namespace distance { // geos::algorithm::distance
+
+/** \brief
+ * An algorithm for computing a distance metric
+ * which is an approximation to the Hausdorff Distance
+ * based on a discretization of the input {@link Geometry}.
+ *
+ * The algorithm computes the Hausdorff distance restricted to discrete points
+ * for one of the geometries.
+ * The points can be either the vertices of the geometries (the default),
+ * or the geometries with line segments densified by a given fraction.
+ * Also determines two points of the Geometries which are separated by the
+ * computed distance.
+ * 
+ * This algorithm is an approximation to the standard Hausdorff distance.
+ * Specifically,
+ * <pre>
+ *    for all geometries a, b:    DHD(a, b) <= HD(a, b)
+ * </pre>
+ * The approximation can be made as close as needed by densifying the
+ * input geometries.
+ * In the limit, this value will approach the true Hausdorff distance:
+ * <pre>
+ *    DHD(A, B, densifyFactor) -> HD(A, B) as densifyFactor -> 0.0
+ * </pre>
+ * The default approximation is exact or close enough for a large subset of
+ * useful cases.
+ * Examples of these are:
+ * 
+ * - computing distance between Linestrings that are roughly parallel to
+ *   each other, and roughly equal in length.  This occurs in matching
+ *   linear networks.
+ * - Testing similarity of geometries.
+ * 
+ * An example where the default approximation is not close is:
+ * <pre>
+ *   A = LINESTRING (0 0, 100 0, 10 100, 10 100)
+ *   B = LINESTRING (0 100, 0 10, 80 10)
+ *
+ *   DHD(A, B) = 22.360679774997898
+ *   HD(A, B) ~= 47.8
+ * </pre>
+ */
+class DiscreteHausdorffDistance
+{
+public:
+
+	static double distance(const geom::Geometry& g0,
+	                       const geom::Geometry& g1);
+
+	static double distance(const geom::Geometry& g0,
+	                       const geom::Geometry& g1, double densifyFrac);
+
+	DiscreteHausdorffDistance(const geom::Geometry& g0,
+	                          const geom::Geometry& g1)
+		:
+		g0(g0),
+		g1(g1),
+		ptDist(),
+		densifyFrac(0.0)
+	{}
+
+	/**
+	 * Sets the fraction by which to densify each segment.
+	 * Each segment will be (virtually) split into a number of equal-length
+	 * subsegments, whose fraction of the total length is closest
+	 * to the given fraction.
+	 *
+	 * @param dFrac
+	 */
+	void setDensifyFraction(double dFrac)
+	{
+		if ( dFrac > 1.0 || dFrac <= 0.0 )
+		{
+			throw util::IllegalArgumentException(
+				"Fraction is not in range (0.0 - 1.0]");
+		}
+
+		densifyFrac = dFrac;
+	}
+
+	double distance()
+	{
+		compute(g0, g1);
+		return ptDist.getDistance();
+	}
+
+	double orientedDistance()
+	{
+		computeOrientedDistance(g0, g1, ptDist);
+		return ptDist.getDistance();
+	}
+
+	const std::vector<geom::Coordinate> getCoordinates() const
+	{
+		return ptDist.getCoordinates();
+	}
+
+	class MaxPointDistanceFilter : public geom::CoordinateFilter
+	{
+	public:
+		MaxPointDistanceFilter(const geom::Geometry& geom)
+			:
+			geom(geom)
+		{}
+
+		void filter_ro(const geom::Coordinate* pt)
+		{
+			minPtDist.initialize();
+			EuclideanDistanceToPoint::computeDistance(geom, *pt,
+			                                         minPtDist);
+			maxPtDist.setMaximum(minPtDist);
+		}
+
+		const PointPairDistance& getMaxPointDistance() const
+		{
+			return maxPtDist;
+		}
+
+	private:
+		PointPairDistance maxPtDist;
+		PointPairDistance minPtDist;
+		EuclideanDistanceToPoint euclideanDist;
+		const geom::Geometry& geom;
+	};
+
+	class MaxDensifiedByFractionDistanceFilter
+			: public geom::CoordinateSequenceFilter
+	{
+	public:
+
+		MaxDensifiedByFractionDistanceFilter(
+				const geom::Geometry& geom, double fraction)
+			:
+			geom(geom),
+			numSubSegs( size_t(round(1.0/fraction)) )
+		{
+		}
+
+		void filter_ro(const geom::CoordinateSequence& seq,
+		               size_t index);
+
+		bool isGeometryChanged() const { return false; }
+
+		bool isDone() const { return false; }
+
+		const PointPairDistance& getMaxPointDistance() const {
+			return maxPtDist;
+		}
+
+	private:
+		PointPairDistance maxPtDist;
+		PointPairDistance minPtDist;
+		const geom::Geometry& geom;
+		size_t numSubSegs; // = 0;
+		
+	};
+
+private:
+
+	void compute(const geom::Geometry& g0,
+	             const geom::Geometry& g1)
+	{
+		computeOrientedDistance(g0, g1, ptDist);
+		computeOrientedDistance(g1, g0, ptDist);
+	}
+
+	void computeOrientedDistance(const geom::Geometry& discreteGeom,
+	                             const geom::Geometry& geom,
+	                             PointPairDistance& ptDist)
+	{
+		MaxPointDistanceFilter distFilter(geom);
+		discreteGeom.apply_ro(&distFilter);
+		ptDist.setMaximum(distFilter.getMaxPointDistance());
+
+		if (densifyFrac > 0)
+		{
+			MaxDensifiedByFractionDistanceFilter fracFilter(geom,
+			                                          densifyFrac);
+			discreteGeom.apply_ro(fracFilter);
+			ptDist.setMaximum(fracFilter.getMaxPointDistance());
+		}
+	}
+
+	const geom::Geometry& g0;
+
+	const geom::Geometry& g1;
+
+	PointPairDistance ptDist;
+
+	/// Value of 0.0 indicates that no densification should take place
+	double densifyFrac; // = 0.0;
+	
+};
+
+
+
+} // geos::algorithm::distance
+} // geos::algorithm
+} // geos
+
+#endif // GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
+
+/**********************************************************************
+ * $Log$
+ **********************************************************************/
+

Added: trunk/source/headers/geos/algorithm/distance/EuclideanDistanceToPoint.h
===================================================================
--- trunk/source/headers/geos/algorithm/distance/EuclideanDistanceToPoint.h	                        (rev 0)
+++ trunk/source/headers/geos/algorithm/distance/EuclideanDistanceToPoint.h	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,86 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * 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/distance/EuclideanDistanceToPoint.java 1.1 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_ALGORITHM_DISTANCE_EUCLIDEANDISTANCETOPOINT_H
+#define GEOS_ALGORITHM_DISTANCE_EUCLIDEANDISTANCETOPOINT_H
+
+#include <geos/geom/LineSegment.h> // for composition
+
+namespace geos {
+	namespace algorithm {
+		namespace distance {
+			class PointPairDistance;
+		}
+	}
+	namespace geom {
+		class Geometry;
+		class Coordinate; 
+		class LineString; 
+		class Polygon; 
+	}
+}
+
+namespace geos {
+namespace algorithm { // geos::algorithm
+namespace distance { // geos::algorithm::distance
+
+/**
+ * Computes the Euclidean distance (L2 metric) from a Point to a Geometry.
+ *
+ * Also computes two points which are separated by the distance.
+ */
+class EuclideanDistanceToPoint
+{
+public:
+
+	EuclideanDistanceToPoint() {}
+
+	static void computeDistance(const geom::Geometry& geom,
+			            const geom::Coordinate& pt,
+	                            PointPairDistance& ptDist);
+
+	static void computeDistance(const geom::LineString& geom,
+			            const geom::Coordinate& pt,
+	                            PointPairDistance& ptDist);
+
+	static void computeDistance(const geom::LineSegment& geom,
+			            const geom::Coordinate& pt,
+	                            PointPairDistance& ptDist);
+
+	static void computeDistance(const geom::Polygon& geom,
+			            const geom::Coordinate& pt,
+	                            PointPairDistance& ptDist);
+
+private:
+
+	// used for point-line distance calculation
+	// NOT THREAD SAFE !!
+	static geom::LineSegment tempSegment;
+};
+
+} // geos::algorithm::distance
+} // geos::algorithm
+} // geos
+
+#endif // GEOS_ALGORITHM_DISTANCE_EUCLIDEANDISTANCETOPOINT_H
+
+/**********************************************************************
+ * $Log$
+ **********************************************************************/
+

Added: trunk/source/headers/geos/algorithm/distance/Makefile.am
===================================================================
--- trunk/source/headers/geos/algorithm/distance/Makefile.am	                        (rev 0)
+++ trunk/source/headers/geos/algorithm/distance/Makefile.am	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,16 @@
+SUBDIRS = 
+
+EXTRA_DIST = 
+
+# Notes:
+#
+# 
+
+geosdir = $(includedir)/geos/algorithm/distance
+
+geos_HEADERS = 			
+
+noinst_HEADERS = 			\
+	DiscreteHausdorffDistance.h	\
+	EuclideanDistanceToPoint.h	\
+	PointPairDistance.h

Added: trunk/source/headers/geos/algorithm/distance/PointPairDistance.h
===================================================================
--- trunk/source/headers/geos/algorithm/distance/PointPairDistance.h	                        (rev 0)
+++ trunk/source/headers/geos/algorithm/distance/PointPairDistance.h	2009-04-14 16:43:40 UTC (rev 2361)
@@ -0,0 +1,160 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * 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/distance/PointPairDistance.java 1.1 (JTS-1.9)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_ALGORITHM_DISTANCE_POINTPAIRDISTANCE_H
+#define GEOS_ALGORITHM_DISTANCE_POINTPAIRDISTANCE_H
+
+//#include <geos/geom/LineSegment.h> // for composition
+#include <geos/platform.h> // for DoubleNotANumber
+#include <geos/geom/Coordinate.h> // for inlines
+
+#include <vector> // for composition
+#include <cassert>
+
+namespace geos {
+	namespace algorithm {
+		namespace distance {
+			//class PointPairDistance;
+		}
+	}
+	namespace geom {
+		//class Geometry;
+		class Coordinate; 
+		//class LineString; 
+		//class Polygon; 
+	}
+}
+
+namespace geos {
+namespace algorithm { // geos::algorithm
+namespace distance { // geos::algorithm::distance
+
+/**
+ * Contains a pair of points and the distance between them.
+ * Provides methods to update with a new point pair with
+ * either maximum or minimum distance.
+ */
+class PointPairDistance
+{
+public:
+
+	PointPairDistance()
+		:
+		pt(2),
+		distance(DoubleNotANumber),
+		isNull(true)
+	{
+		assert(pt.size() == 2);
+	}
+
+	void initialize()
+	{
+		isNull = true;
+	}
+
+	void initialize(const geom::Coordinate& p0, const geom::Coordinate& p1)
+	{
+		pt[0] = p0;
+		pt[1] = p1;
+		distance = p0.distance(p1);
+		isNull = false;
+	}
+
+	double getDistance() const
+	{
+		return distance;
+	}
+
+	const std::vector<geom::Coordinate>& getCoordinates() const
+	{
+		return pt;
+	}
+
+	const geom::Coordinate& getCoordinate(unsigned int i) const
+	{
+		assert(i<pt.size());
+		return pt[i];
+	}
+
+	void setMaximum(const PointPairDistance& ptDist)
+	{
+		setMaximum(ptDist.pt[0], ptDist.pt[1]);
+	}
+
+	void setMaximum(const geom::Coordinate& p0, const geom::Coordinate& p1)
+	{
+		if (isNull) {
+			initialize(p0, p1);
+			return;
+		}
+		double dist = p0.distance(p1);
+		if (dist > distance)
+			initialize(p0, p1, dist);
+	}
+
+	void setMinimum(const PointPairDistance& ptDist)
+	{
+		setMinimum(ptDist.pt[0], ptDist.pt[1]);
+	}
+
+	void setMinimum(const geom::Coordinate& p0, const geom::Coordinate& p1)
+	{
+		if (isNull) {
+			initialize(p0, p1);
+			return;
+		}
+		double dist = p0.distance(p1);
+		if (dist < distance)
+			initialize(p0, p1, dist);
+	}
+
+private:
+
+	/**
+	 * Initializes the points, avoiding recomputing the distance.
+	 * @param p0
+	 * @param p1
+	 * @param dist the distance between p0 and p1
+	 */
+	void initialize(const geom::Coordinate& p0, const geom::Coordinate& p1,
+	                double dist)
+	{
+		pt[0] = p0;
+		pt[1] = p1;
+		distance = distance;
+		isNull = false;
+	}
+
+	std::vector<geom::Coordinate> pt;
+
+	double distance;
+
+	bool isNull;
+};
+
+} // geos::algorithm::distance
+} // geos::algorithm
+} // geos
+
+#endif // GEOS_ALGORITHM_DISTANCE_POINTPAIRDISTANCE_H
+
+/**********************************************************************
+ * $Log$
+ **********************************************************************/
+

Modified: trunk/source/headers/geos/geom/CoordinateSequenceFilter.h
===================================================================
--- trunk/source/headers/geos/geom/CoordinateSequenceFilter.h	2009-04-14 15:25:58 UTC (rev 2360)
+++ trunk/source/headers/geos/geom/CoordinateSequenceFilter.h	2009-04-14 16:43:40 UTC (rev 2361)
@@ -68,7 +68,7 @@
    *             is applied
    * @param i the index of the coordinate to apply the filter to
    */
-  virtual void filter_rw(CoordinateSequence& /*seq*/, size_t i) const
+  virtual void filter_rw(CoordinateSequence& /*seq*/, size_t i)
   { assert(0); }
 
   /**
@@ -78,7 +78,7 @@
    *             is applied
    * @param i the index of the coordinate to apply the filter to
    */
-  virtual void filter_ro(const CoordinateSequence& /*seq*/, size_t i) const
+  virtual void filter_ro(const CoordinateSequence& /*seq*/, size_t i)
   { assert(0); }
 
   /**



More information about the geos-commits mailing list