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
31 using namespace geos::geom
;
34 namespace algorithm
{ // geos.algorithm
35 namespace distance
{ // geos.algorithm.distance
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
);
61 // assume geom is Point
62 ptDist
.setMinimum(*(geom
.getCoordinate()), pt
);
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
;
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
);
95 DistanceToPoint::computeDistance(const geom::LineSegment
& segment
,
96 const geom::Coordinate
& pt
,
97 PointPairDistance
& ptDist
)
100 segment
.closestPoint(pt
, closestPt
);
101 ptDist
.setMinimum(closestPt
, pt
);
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