Complete Note#1 in the http://wiki.osgeo.org/wiki/GEOS_Provenance_Review to get out...
[geos.git] / src / algorithm / distance / DistanceToPoint.cpp
blob7bd9a0cc6393dc7732927fc1b5ec4cc99be945ff
1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2009 Sandro Santilli <strk@keybit.net>
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
13 **********************************************************************
15 * Last port: algorithm/distance/DistanceToPoint.java 1.1 (JTS-1.9)
17 **********************************************************************/
19 #include <geos/algorithm/distance/DistanceToPoint.h>
20 #include <geos/algorithm/distance/PointPairDistance.h>
21 #include <geos/geom/Coordinate.h>
22 #include <geos/geom/CoordinateSequence.h>
23 #include <geos/geom/LineSegment.h>
24 #include <geos/geom/LineString.h>
25 #include <geos/geom/Polygon.h>
26 #include <geos/geom/GeometryCollection.h>
28 #include <typeinfo> // for dynamic_cast
29 #include <cassert>
31 using namespace geos::geom;
33 namespace geos {
34 namespace algorithm { // geos.algorithm
35 namespace distance { // geos.algorithm.distance
37 /* public static */
38 void
39 DistanceToPoint::computeDistance(const geom::Geometry& geom,
40 const geom::Coordinate& pt,
41 PointPairDistance& ptDist)
43 if ( const LineString* ls = dynamic_cast<const LineString*>(&geom) )
45 computeDistance(*ls, pt, ptDist);
47 else if ( const Polygon* pl = dynamic_cast<const Polygon*>(&geom) )
49 computeDistance(*pl, pt, ptDist);
51 else if ( const GeometryCollection* gc = dynamic_cast<const GeometryCollection*>(&geom) )
53 for (size_t i = 0; i < gc->getNumGeometries(); i++)
55 const Geometry* g = gc->getGeometryN(i);
56 computeDistance(*g, pt, ptDist);
59 else
61 // assume geom is Point
62 ptDist.setMinimum(*(geom.getCoordinate()), pt);
66 /* public static */
67 void
68 DistanceToPoint::computeDistance(const geom::LineString& line,
69 const geom::Coordinate& pt,
70 PointPairDistance& ptDist)
72 const CoordinateSequence* coordsRO = line.getCoordinatesRO();
73 const CoordinateSequence& coords = *coordsRO;
75 size_t npts = coords.size();
76 if ( ! npts ) return; // can this ever be ?
78 LineSegment tempSegment;
79 Coordinate closestPt;
81 Coordinate* segPts[2] = { &(tempSegment.p0), &(tempSegment.p1) };
82 tempSegment.p0 = coords.getAt(0);
83 for (size_t i=1; i<npts; ++i)
85 *(segPts[i%2]) = coords.getAt(i);
87 // this is somewhat inefficient - could do better
88 tempSegment.closestPoint(pt, closestPt);
89 ptDist.setMinimum(closestPt, pt);
93 /* public static */
94 void
95 DistanceToPoint::computeDistance(const geom::LineSegment& segment,
96 const geom::Coordinate& pt,
97 PointPairDistance& ptDist)
99 Coordinate closestPt;
100 segment.closestPoint(pt, closestPt);
101 ptDist.setMinimum(closestPt, pt);
104 /* public static */
105 void
106 DistanceToPoint::computeDistance(const geom::Polygon& poly,
107 const geom::Coordinate& pt,
108 PointPairDistance& ptDist)
110 computeDistance(*(poly.getExteriorRing()), pt, ptDist);
111 for (size_t i=0, n=poly.getNumInteriorRing(); i<n; ++i)
113 computeDistance(*(poly.getInteriorRingN(i)), pt, ptDist);
118 } // namespace geos.algorithm.distance
119 } // namespace geos.algorithm
120 } // namespace geos