1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2009-2010 Sandro Santilli <strk@keybit.net>
7 * Copyright (C) 2006 Refractions Research Inc.
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
14 ***********************************************************************
16 * Last port: operation/overlay/snap/LineStringSnapper.java r320 (JTS-1.12)
18 **********************************************************************/
20 #ifndef GEOS_OP_OVERLAY_SNAP_LINESTRINGSNAPPER_H
21 #define GEOS_OP_OVERLAY_SNAP_LINESTRINGSNAPPER_H
23 #include <geos/geom/Coordinate.h>
24 #include <geos/geom/CoordinateSequence.h>
25 #include <geos/geom/CoordinateList.h>
29 // Forward declarations
32 //class PrecisionModel;
33 //class CoordinateSequence;
40 namespace operation
{ // geos::operation
41 namespace overlay
{ // geos::operation::overlay
42 namespace snap
{ // geos::operation::overlay::snap
45 * Snaps the vertices and segments of a LineString to a set
46 * of target snap vertices.
48 * A snapping distance tolerance is used to control where snapping is performed.
51 class GEOS_DLL LineStringSnapper
{
56 * Creates a new snapper using the given points
57 * as source points to be snapped.
59 * @param nSrcPts the points to snap
60 * @param nSnapTolerance the snap tolerance to use
62 LineStringSnapper(const geom::Coordinate::Vect
& nSrcPts
,
66 snapTolerance(nSnapTol
),
67 allowSnappingToSourceVertices(false)
69 size_t s
= srcPts
.size();
70 isClosed
= s
< 2 ? false : srcPts
[0].equals2D(srcPts
[s
-1]);
73 // Snap points are assumed to be all distinct points (a set would be better, uh ?)
74 std::auto_ptr
<geom::Coordinate::Vect
> snapTo(const geom::Coordinate::ConstVect
& snapPts
);
76 void setAllowSnappingToSourceVertices(bool allow
) {
77 allowSnappingToSourceVertices
= allow
;
82 const geom::Coordinate::Vect
& srcPts
;
86 bool allowSnappingToSourceVertices
;
91 void snapVertices(geom::CoordinateList
& srcCoords
,
92 const geom::Coordinate::ConstVect
& snapPts
);
95 // Returns snapPts.end() if no snap point is close enough (within snapTol distance)
96 geom::Coordinate::ConstVect::const_iterator
findSnapForVertex(const geom::Coordinate
& pt
,
97 const geom::Coordinate::ConstVect
& snapPts
);
100 * Snap segments of the source to nearby snap vertices.
102 * Source segments are "cracked" at a snap vertex.
103 * A single input segment may be snapped several times
104 * to different snap vertices.
106 * For each distinct snap vertex, at most one source segment
107 * is snapped to. This prevents "cracking" multiple segments
108 * at the same point, which would likely cause
109 * topology collapse when being used on polygonal linework.
111 * @param srcCoords the coordinates of the source linestring to be snapped
112 * the object will be modified (coords snapped)
113 * @param snapPts the target snap vertices */
114 void snapSegments(geom::CoordinateList
& srcCoords
,
115 const geom::Coordinate::ConstVect
& snapPts
);
118 /// Finds a src segment which snaps to (is close to) the given snap
121 /// Only a single segment is selected for snapping.
122 /// This prevents multiple segments snapping to the same snap vertex,
123 /// which would almost certainly cause invalid geometry
125 /// (The heuristic approach to snapping used here
126 /// is really only appropriate when
127 /// snap pts snap to a unique spot on the src geometry.)
129 /// Also, if the snap vertex occurs as a vertex in the src
130 /// coordinate list, no snapping is performed (may be changed
131 /// using setAllowSnappingToSourceVertices).
134 /// an iterator to first point of first segment to be checked
137 /// an iterator to last point of last segment to be checked
139 /// @returns an iterator to the snapped segment or
140 /// too_far if no segment needs snapping
141 /// (either none within snapTol distance,
142 /// or one found on the snapPt)
144 geom::CoordinateList::iterator
findSegmentToSnap(
145 const geom::Coordinate
& snapPt
,
146 geom::CoordinateList::iterator from
,
147 geom::CoordinateList::iterator too_far
);
149 // Declare type as noncopyable
150 LineStringSnapper(const LineStringSnapper
& other
);
151 LineStringSnapper
& operator=(const LineStringSnapper
& rhs
);
155 } // namespace geos::operation::overlay::snap
156 } // namespace geos::operation::overlay
157 } // namespace geos::operation
160 #endif // GEOS_OP_OVERLAY_SNAP_LINESTRINGSNAPPER_H