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;
 
  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 );
 
Abstract base class for all geometries.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
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 SIP_HOLDGIL
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) SIP_HOLDGIL
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 SIP_HOLDGIL
Returns the number of points in the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
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 SIP_HOLDGIL
Returns the distance between this point and a specified x, y coordinate.
Point geometry type, with support for z-dimension and m-values.
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
QgsRectangle boundingBox() const override SIP_HOLDGIL
Returns the minimal bounding box for the geometry.
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...