69 const QList<QgsFeatureId> ids = index.
intersects( rect );
90static void assignAnchors(
QgsSpatialIndex &index, QVector<AnchorPoint> &pnts,
double thresh )
92 const double thresh2 = thresh * thresh;
93 for (
int point = 0; point < pnts.count(); ++point )
95 if ( pnts[point].anchor >= 0 )
98 pnts[point].anchor = -2;
101 double x = pnts[point].x, y = pnts[point].y;
102 const QgsRectangle rect( x - thresh, y - thresh, x + thresh, y + thresh );
104 const QList<QgsFeatureId> ids = index.
intersects( rect );
107 if ( pointb == point )
110 const double dx = pnts[pointb].x - pnts[point].x;
111 const double dy = pnts[pointb].y - pnts[point].y;
112 const double dist2 = dx * dx + dy * dy;
113 if ( dist2 > thresh2 )
116 if ( pnts[pointb].anchor == -1 )
119 pnts[pointb].anchor = point;
121 else if ( pnts[pointb].anchor >= 0 )
124 const double dx2 = pnts[pnts[pointb].anchor].x - pnts[pointb].x;
125 const double dy2 = pnts[pnts[pointb].anchor].y - pnts[pointb].y;
126 const double dist2_a = dx2 * dx2 + dy2 * dy2;
127 if ( dist2 < dist2_a )
128 pnts[pointb].anchor = point;
139 Q_ASSERT( fids.count() == 1 );
141 const int spoint = fids[0];
142 const int anchor = pnts[spoint].anchor;
147 pt->
setX( pnts[anchor].x );
148 pt->
setY( pnts[anchor].y );
158 QVector<QgsPoint> newPoints;
159 QVector<int> anchors;
160 const double thresh2 = thresh * thresh;
161 double minDistX, minDistY;
162 bool changed =
false;
165 for (
int v = 0; v < linestring->
numPoints(); v++ )
167 const double x = linestring->
xAt( v );
168 const double y = linestring->
yAt( v );
172 QList<QgsFeatureId> fids = index.
intersects( rect );
173 Q_ASSERT( fids.count() == 1 );
175 const int spoint = fids.first();
176 const int anchor = pnts[spoint].anchor;
180 linestring->
setXAt( v, pnts[anchor].x );
181 linestring->
setYAt( v, pnts[anchor].y );
182 anchors.append( anchor );
187 anchors.append( spoint );
192 for (
int v = 0; v < linestring->
numPoints() - 1; v++ )
194 const double x1 = linestring->
xAt( v );
195 const double x2 = linestring->
xAt( v + 1 );
196 const double y1 = linestring->
yAt( v );
197 const double y2 = linestring->
yAt( v + 1 );
199 newPoints << linestring->
pointN( v );
202 double xmin = x1, xmax = x2, ymin = y1, ymax = y2;
204 std::swap( xmin, xmax );
206 std::swap( ymin, ymax );
208 const QgsRectangle rect( xmin - thresh, ymin - thresh, xmax + thresh, ymax + thresh );
211 const QList<QgsFeatureId> fids = index.
intersects( rect );
213 QVector<AnchorAlongSegment> newVerticesAlongSegment;
218 const int spoint = fid;
220 if ( spoint == anchors[v] || spoint == anchors[v + 1] )
222 if ( pnts[spoint].anchor >= 0 )
228 double dx1 = minDistX - x1, dx2 = minDistX - x2;
229 double dy1 = minDistY - y1, dy2 = minDistY - y2;
231 if ( isOnSegment && dist2 <= thresh2 )
237 newVerticesAlongSegment << item;
241 if ( !newVerticesAlongSegment.isEmpty() )
246 return p1.along < p2.along;
250 for (
int i = 0; i < newVerticesAlongSegment.count(); i++ )
252 const int anchor = newVerticesAlongSegment[i].anchor;
253 newPoints <<
QgsPoint( pnts[anchor].x, pnts[anchor].y, 0 );
272 bool changed =
false;
273 if (
QgsLineString *linestring = qgsgeometry_cast<QgsLineString *>( g ) )
275 changed |= snapLineString( linestring, index, pnts, thresh );
277 else if (
QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( g ) )
279 if (
QgsLineString *exteriorRing = qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing() ) )
280 changed |= snapLineString( exteriorRing, index, pnts, thresh );
281 for (
int i = 0; i < polygon->numInteriorRings(); ++i )
283 if (
QgsLineString *interiorRing = qgsgeometry_cast<QgsLineString *>( polygon->interiorRing( i ) ) )
284 changed |= snapLineString( interiorRing, index, pnts, thresh );
289 for (
int i = 0; i < collection->numGeometries(); ++i )
290 changed |= snapGeometry( collection->geometryN( i ), index, pnts, thresh );
292 else if (
QgsPoint *pt = qgsgeometry_cast<QgsPoint *>( g ) )
294 changed |= snapPoint( pt, index, pnts );
312 QVector<AnchorPoint> pnts;
316 buildSnapIndex( fi, index, pnts, feedback, count, totalCount );
324 assignAnchors( index, pnts, thresh );
340 if ( snapGeometry( geom.
get(), index, pnts, thresh ) )
349 feedback->
setProgress( 100. * count / totalCount );
Abstract base class for all geometries.
virtual QgsRectangle boundingBox() const
Returns the minimal bounding box for the geometry.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
An interface for objects which accept features via addFeature(s) methods.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
An interface for objects which provide features via a getFeatures method.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
static int run(const QgsFeatureSource &source, QgsFeatureSink &sink, double thresh, QgsFeedback *feedback)
Run the algorithm on given source and output results to the sink, using threshold value in the source...
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Line string geometry type, with support for z-dimension and m-values.
int numPoints() const override
Returns the number of points in the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
void setPoints(size_t size, const double *x, const double *y, const double *z=nullptr, const double *m=nullptr)
Resets the line string to match the specified point data.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
A class to represent a 2D point.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
Point geometry type, with support for z-dimension and m-values.
void setY(double y)
Sets the point's y-coordinate.
void setX(double x)
Sets the point's x-coordinate.
A rectangle specified with double values.
A spatial index for QgsFeature objects.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a feature to the index.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
record about anchor being along a segment
int anchor
Index of the anchor point.
double along
Distance of the anchor point along the segment.
record about vertex coordinates and index of anchor to which it is snapped
double x
coordinates of the point
int anchor
Anchor information: 0+ - index of anchor to which this point should be snapped -1 - initial value (un...