1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
7 * Copyright (C) 2005-2006 Refractions Research Inc.
8 * Copyright (C) 2001-2002 Vivid Solutions Inc.
10 * This is free software; you can redistribute and/or modify it under
11 * the terms of the GNU Lesser General Public Licence as published
12 * by the Free Software Foundation.
13 * See the COPYING file for more information.
15 **********************************************************************
17 * Last port: linearref/LocationIndexOfPoint.java r466
19 **********************************************************************/
22 #include <geos/geom/LineSegment.h>
23 #include <geos/linearref/LinearIterator.h>
24 #include <geos/linearref/LinearLocation.h>
25 #include <geos/linearref/LocationIndexOfPoint.h>
26 #include <geos/util/IllegalArgumentException.h>
33 using namespace geos::geom
;
37 namespace linearref
// geos.linearref
41 LocationIndexOfPoint::indexOfFromStart(const Coordinate
& inputPt
,
42 const LinearLocation
* minIndex
) const
44 double minDistance
= numeric_limits
<double>::max();
45 int minComponentIndex
= 0;
46 int minSegmentIndex
= 0;
47 double minFrac
= -1.0;
50 for (LinearIterator
it(linearGeom
);
51 it
.hasNext(); it
.next())
53 if (! it
.isEndOfLine())
55 seg
.p0
= it
.getSegmentStart();
56 seg
.p1
= it
.getSegmentEnd();
57 double segDistance
= seg
.distance(inputPt
);
58 double segFrac
= seg
.segmentFraction(inputPt
);
60 int candidateComponentIndex
= it
.getComponentIndex();
61 int candidateSegmentIndex
= it
.getVertexIndex();
62 if (segDistance
< minDistance
)
64 // ensure after minLocation, if any
66 minIndex
->compareLocationValues(candidateComponentIndex
, candidateSegmentIndex
, segFrac
) < 0)
68 // otherwise, save this as new minimum
69 minComponentIndex
= candidateComponentIndex
;
70 minSegmentIndex
= candidateSegmentIndex
;
72 minDistance
= segDistance
;
77 LinearLocation
loc(minComponentIndex
, minSegmentIndex
, minFrac
);
82 LinearLocation
LocationIndexOfPoint::indexOf(const Geometry
*linearGeom
, const Coordinate
& inputPt
)
84 LocationIndexOfPoint
locater(linearGeom
);
85 return locater
.indexOf(inputPt
);
88 LinearLocation
LocationIndexOfPoint::indexOfAfter(const Geometry
*linearGeom
, const Coordinate
& inputPt
, const LinearLocation
* minIndex
)
90 LocationIndexOfPoint
locater(linearGeom
);
91 return locater
.indexOfAfter(inputPt
, minIndex
);
94 LocationIndexOfPoint::LocationIndexOfPoint(const Geometry
*linearGeom
) :
95 linearGeom(linearGeom
)
98 LinearLocation
LocationIndexOfPoint::indexOf(const Coordinate
& inputPt
) const
100 return indexOfFromStart(inputPt
, 0);
104 LocationIndexOfPoint::indexOfAfter(const Coordinate
& inputPt
,
105 const LinearLocation
* minIndex
) const
107 if (!minIndex
) return indexOf(inputPt
);
109 // sanity check for minLocation at or past end of line
110 LinearLocation endLoc
= LinearLocation::getEndLocation(linearGeom
);
111 if (endLoc
.compareTo(*minIndex
) <= 0)
114 LinearLocation closestAfter
= indexOfFromStart(inputPt
, minIndex
);
116 * Return the minDistanceLocation found.
117 * This will not be null, since it was initialized to minLocation
119 if (closestAfter
.compareTo(*minIndex
) < 0)
121 throw util::IllegalArgumentException("computed location is before specified minimum location");