69 const QList<QgsFeatureId> ids = index.
intersects( rect );
90 static void assignAnchors(
QgsSpatialIndex &index, QVector<AnchorPoint> &pnts,
double thresh )
92 const double thresh2 = thresh * thresh;
93 int nanchors = 0, ntosnap = 0;
94 for (
int point = 0; point < pnts.count(); ++point )
96 if ( pnts[point].anchor >= 0 )
99 pnts[point].anchor = -2;
103 double x = pnts[point].x, y = pnts[point].y;
104 const QgsRectangle rect( x - thresh, y - thresh, x + thresh, y + thresh );
106 const QList<QgsFeatureId> ids = index.
intersects( rect );
109 if ( pointb == point )
112 const double dx = pnts[pointb].x - pnts[point].x;
113 const double dy = pnts[pointb].y - pnts[point].y;
114 const double dist2 = dx * dx + dy * dy;
115 if ( dist2 > thresh2 )
118 if ( pnts[pointb].anchor == -1 )
121 pnts[pointb].anchor = point;
124 else if ( pnts[pointb].anchor >= 0 )
127 const double dx2 = pnts[pnts[pointb].anchor].x - pnts[pointb].x;
128 const double dy2 = pnts[pnts[pointb].anchor].y - pnts[pointb].y;
129 const double dist2_a = dx2 * dx2 + dy2 * dy2;
130 if ( dist2 < dist2_a )
131 pnts[pointb].anchor = point;
142 Q_ASSERT( fids.count() == 1 );
144 const int spoint = fids[0];
145 const int anchor = pnts[spoint].anchor;
150 pt->
setX( pnts[anchor].x );
151 pt->
setY( pnts[anchor].y );
161 QVector<QgsPoint> newPoints;
162 QVector<int> anchors;
163 const double thresh2 = thresh * thresh;
164 double minDistX, minDistY;
165 bool changed =
false;
168 for (
int v = 0; v < linestring->
numPoints(); v++ )
170 const double x = linestring->
xAt( v );
171 const double y = linestring->
yAt( v );
175 QList<QgsFeatureId> fids = index.
intersects( rect );
176 Q_ASSERT( fids.count() == 1 );
178 const int spoint = fids.first();
179 const int anchor = pnts[spoint].anchor;
183 linestring->
setXAt( v, pnts[anchor].x );
184 linestring->
setYAt( v, pnts[anchor].y );
185 anchors.append( anchor );
190 anchors.append( spoint );
195 for (
int v = 0; v < linestring->
numPoints() - 1; v++ )
197 const double x1 = linestring->
xAt( v );
198 const double x2 = linestring->
xAt( v + 1 );
199 const double y1 = linestring->
yAt( v );
200 const double y2 = linestring->
yAt( v + 1 );
202 newPoints << linestring->
pointN( v );
205 double xmin = x1, xmax = x2, ymin = y1, ymax = y2;
207 std::swap( xmin, xmax );
209 std::swap( ymin, ymax );
211 const QgsRectangle rect( xmin - thresh, ymin - thresh, xmax + thresh, ymax + thresh );
214 const QList<QgsFeatureId> fids = index.
intersects( rect );
216 QVector<AnchorAlongSegment> newVerticesAlongSegment;
221 const int spoint = fid;
223 if ( spoint == anchors[v] || spoint == anchors[v + 1] )
225 if ( pnts[spoint].anchor >= 0 )
231 double dx1 = minDistX - x1, dx2 = minDistX - x2;
232 double dy1 = minDistY - y1, dy2 = minDistY - y2;
234 if ( isOnSegment && dist2 <= thresh2 )
240 newVerticesAlongSegment << item;
244 if ( !newVerticesAlongSegment.isEmpty() )
249 return p1.along < p2.along;
253 for (
int i = 0; i < newVerticesAlongSegment.count(); i++ )
255 const int anchor = newVerticesAlongSegment[i].anchor;
256 newPoints <<
QgsPoint( pnts[anchor].x, pnts[anchor].y, 0 );
275 bool changed =
false;
276 if (
QgsLineString *linestring = qgsgeometry_cast<QgsLineString *>( g ) )
278 changed |= snapLineString( linestring, index, pnts, thresh );
280 else if (
QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( g ) )
282 if (
QgsLineString *exteriorRing = qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing() ) )
283 changed |= snapLineString( exteriorRing, index, pnts, thresh );
284 for (
int i = 0; i < polygon->numInteriorRings(); ++i )
286 if (
QgsLineString *interiorRing = qgsgeometry_cast<QgsLineString *>( polygon->interiorRing( i ) ) )
287 changed |= snapLineString( interiorRing, index, pnts, thresh );
292 for (
int i = 0; i < collection->numGeometries(); ++i )
293 changed |= snapGeometry( collection->geometryN( i ), index, pnts, thresh );
295 else if (
QgsPoint *pt = qgsgeometry_cast<QgsPoint *>( g ) )
297 changed |= snapPoint( pt, index, pnts );
315 QVector<AnchorPoint> pnts;
319 buildSnapIndex( fi, index, pnts, feedback, count, totalCount );
327 assignAnchors( index, pnts, thresh );
343 if ( snapGeometry( geom.
get(), index, pnts, thresh ) )
352 feedback->
setProgress( 100. * count / totalCount );