GEOS  3.6.2
DiscreteHausdorffDistance.h
00001 /**********************************************************************
00002  *
00003  * GEOS - Geometry Engine Open Source
00004  * http://geos.osgeo.org
00005  *
00006  * Copyright (C) 2009  Sandro Santilli <strk@keybit.net>
00007  *
00008  * This is free software; you can redistribute and/or modify it under
00009  * the terms of the GNU Lesser General Public Licence as published
00010  * by the Free Software Foundation. 
00011  * See the COPYING file for more information.
00012  *
00013  **********************************************************************
00014  *
00015  * Last port: algorithm/distance/DiscreteHausdorffDistance.java 1.5 (JTS-1.10)
00016  *
00017  **********************************************************************/
00018 
00019 #ifndef GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
00020 #define GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
00021 
00022 #include <geos/export.h>
00023 #include <geos/algorithm/distance/PointPairDistance.h> // for composition
00024 #include <geos/algorithm/distance/DistanceToPoint.h> // for composition
00025 #include <geos/util/IllegalArgumentException.h> // for inlines
00026 #include <geos/geom/Geometry.h> // for inlines
00027 #include <geos/util/math.h> // for inlines
00028 #include <geos/geom/CoordinateFilter.h> // for inheritance
00029 #include <geos/geom/CoordinateSequenceFilter.h> // for inheritance
00030 
00031 #include <cstddef>
00032 #include <vector>
00033 
00034 #ifdef _MSC_VER
00035 #pragma warning(push)
00036 #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
00037 #endif
00038 
00039 namespace geos {
00040         namespace algorithm {
00041                 //class RayCrossingCounter;
00042         }
00043         namespace geom {
00044                 class Geometry;
00045                 class Coordinate; 
00046                 //class CoordinateSequence; 
00047         }
00048         namespace index {
00049                 namespace intervalrtree {
00050                         //class SortedPackedIntervalRTree;
00051                 }
00052         }
00053 }
00054 
00055 namespace geos {
00056 namespace algorithm { // geos::algorithm
00057 namespace distance { // geos::algorithm::distance
00058 
00100 class GEOS_DLL DiscreteHausdorffDistance
00101 {
00102 public:
00103 
00104         static double distance(const geom::Geometry& g0,
00105                                const geom::Geometry& g1);
00106 
00107         static double distance(const geom::Geometry& g0,
00108                                const geom::Geometry& g1, double densifyFrac);
00109 
00110         DiscreteHausdorffDistance(const geom::Geometry& g0,
00111                                   const geom::Geometry& g1)
00112                 :
00113                 g0(g0),
00114                 g1(g1),
00115                 ptDist(),
00116                 densifyFrac(0.0)
00117         {}
00118 
00127         void setDensifyFraction(double dFrac)
00128         {
00129                 if ( dFrac > 1.0 || dFrac <= 0.0 )
00130                 {
00131                         throw util::IllegalArgumentException(
00132                                 "Fraction is not in range (0.0 - 1.0]");
00133                 }
00134 
00135                 densifyFrac = dFrac;
00136         }
00137 
00138         double distance()
00139         {
00140                 compute(g0, g1);
00141                 return ptDist.getDistance();
00142         }
00143 
00144         double orientedDistance()
00145         {
00146                 computeOrientedDistance(g0, g1, ptDist);
00147                 return ptDist.getDistance();
00148         }
00149 
00150         const std::vector<geom::Coordinate> getCoordinates() const
00151         {
00152                 return ptDist.getCoordinates();
00153         }
00154 
00155         class MaxPointDistanceFilter : public geom::CoordinateFilter
00156         {
00157         public:
00158                 MaxPointDistanceFilter(const geom::Geometry& geom)
00159                         :
00160                         geom(geom)
00161                 {}
00162 
00163                 void filter_ro(const geom::Coordinate* pt)
00164                 {
00165                         minPtDist.initialize();
00166                         DistanceToPoint::computeDistance(geom, *pt,
00167                                                                  minPtDist);
00168                         maxPtDist.setMaximum(minPtDist);
00169                 }
00170 
00171                 const PointPairDistance& getMaxPointDistance() const
00172                 {
00173                         return maxPtDist;
00174                 }
00175 
00176         private:
00177                 PointPairDistance maxPtDist;
00178                 PointPairDistance minPtDist;
00179                 DistanceToPoint euclideanDist;
00180                 const geom::Geometry& geom;
00181 
00182         // Declare type as noncopyable
00183         MaxPointDistanceFilter(const MaxPointDistanceFilter& other);
00184         MaxPointDistanceFilter& operator=(const MaxPointDistanceFilter& rhs);
00185         };
00186 
00187         class MaxDensifiedByFractionDistanceFilter
00188                         : public geom::CoordinateSequenceFilter
00189         {
00190         public:
00191 
00192                 MaxDensifiedByFractionDistanceFilter(
00193                                 const geom::Geometry& geom, double fraction)
00194                         :
00195                         geom(geom),
00196                 numSubSegs( std::size_t(util::round(1.0/fraction)) )
00197                 {
00198                 }
00199 
00200                 void filter_ro(const geom::CoordinateSequence& seq,
00201                                std::size_t index);
00202 
00203                 bool isGeometryChanged() const { return false; }
00204 
00205                 bool isDone() const { return false; }
00206 
00207                 const PointPairDistance& getMaxPointDistance() const {
00208                         return maxPtDist;
00209                 }
00210 
00211         private:
00212                 PointPairDistance maxPtDist;
00213                 PointPairDistance minPtDist;
00214                 const geom::Geometry& geom;
00215                 std::size_t numSubSegs; // = 0;
00216 
00217         // Declare type as noncopyable
00218         MaxDensifiedByFractionDistanceFilter(const MaxDensifiedByFractionDistanceFilter& other);
00219         MaxDensifiedByFractionDistanceFilter& operator=(const MaxDensifiedByFractionDistanceFilter& rhs);
00220         };
00221 
00222 private:
00223 
00224         void compute(const geom::Geometry& g0,
00225                      const geom::Geometry& g1)
00226         {
00227                 computeOrientedDistance(g0, g1, ptDist);
00228                 computeOrientedDistance(g1, g0, ptDist);
00229         }
00230 
00231         void computeOrientedDistance(const geom::Geometry& discreteGeom,
00232                                      const geom::Geometry& geom,
00233                                      PointPairDistance& ptDist);
00234 
00235         const geom::Geometry& g0;
00236 
00237         const geom::Geometry& g1;
00238 
00239         PointPairDistance ptDist;
00240 
00242     double densifyFrac; // = 0.0;
00243 
00244     // Declare type as noncopyable
00245     DiscreteHausdorffDistance(const DiscreteHausdorffDistance& other);
00246     DiscreteHausdorffDistance& operator=(const DiscreteHausdorffDistance& rhs);
00247 };
00248 
00249 } // geos::algorithm::distance
00250 } // geos::algorithm
00251 } // geos
00252 
00253 #ifdef _MSC_VER
00254 #pragma warning(pop)
00255 #endif
00256 
00257 #endif // GEOS_ALGORITHM_DISTANCE_DISCRETEHAUSDORFFDISTANCE_H
00258