69 QList<QgsFeatureId> ids = index.
intersects( rect );
90 static void assignAnchors(
QgsSpatialIndex &index, QVector<AnchorPoint> &pnts,
double thresh )
92 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 QgsRectangle rect( x - thresh,
y - thresh, x + thresh,
y + thresh );
106 const QList<QgsFeatureId> ids = index.
intersects( rect );
109 if ( pointb == point )
112 double dx = pnts[pointb].x - pnts[point].x;
113 double dy = pnts[pointb].y - pnts[point].y;
114 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 double dx2 = pnts[pnts[pointb].anchor].x - pnts[pointb].x;
128 double dy2 = pnts[pnts[pointb].anchor].y - pnts[pointb].y;
129 double dist2_a = dx2 * dx2 + dy2 * dy2;
130 if ( dist2 < dist2_a )
131 pnts[pointb].anchor = point;
142 Q_ASSERT( fids.count() == 1 );
144 int spoint = fids[0];
145 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 double thresh2 = thresh * thresh;
164 double minDistX, minDistY;
165 bool changed =
false;
168 for (
int v = 0; v < linestring->
numPoints(); v++ )
170 double x = linestring->
xAt( v );
171 double y = linestring->
yAt( v );
175 QList<QgsFeatureId> fids = index.
intersects( rect );
176 Q_ASSERT( fids.count() == 1 );
178 int spoint = fids.first();
179 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 double x1 = linestring->
xAt( v );
198 double x2 = linestring->
xAt( v + 1 );
199 double y1 = linestring->
yAt( v );
200 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 QgsRectangle rect( xmin - thresh, ymin - thresh, xmax + thresh, ymax + thresh );
214 const QList<QgsFeatureId> fids = index.
intersects( rect );
216 QVector<AnchorAlongSegment> newVerticesAlongSegment;
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 ? -1 : ( p1.
along > p2.along ) );
253 for (
int i = 0; i < newVerticesAlongSegment.count(); i++ )
255 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 );
Wrapper for iterator of features from vector data provider or vector layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
A rectangle specified with double values.
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry...
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
double x
coordinates of the point
A class to represent a 2D point.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void setProgress(double progress)
Sets the current progress for the feedback object.
An interface for objects which accept features via addFeature(s) methods.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
A geometry is the spatial representation of a feature.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
int numPoints() const override
Returns the number of points in the curve.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr)
Adds a single feature to the sink.
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...
Abstract base class for all geometries.
Point geometry type, with support for z-dimension and m-values.
void setX(double x)
Sets the point's x-coordinate.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
void setY(double y)
Sets the point's y-coordinate.
record about anchor being along a segment
A spatial index for QgsFeature objects.
An interface for objects which provide features via a getFeatures method.
Line string geometry type, with support for z-dimension and m-values.
int anchor
Index of the anchor point.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
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.
double along
Distance of the anchor point along the segment.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a feature to the index.
bool nextFeature(QgsFeature &f)
int anchor
Anchor information: 0+ - index of anchor to which this point should be snapped -1 - initial value (un...
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown...
record about vertex coordinates and index of anchor to which it is snapped