QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgsgeometrysnapper.h
Go to the documentation of this file.
1 /***************************************************************************
2  * qgsgeometrysnapper.h *
3  * ------------------- *
4  * copyright : (C) 2014 by Sandro Mani / Sourcepole AG *
5  * email : [email protected] *
6  ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #ifndef QGS_GEOMETRY_SNAPPER_H
18 #define QGS_GEOMETRY_SNAPPER_H
19 
20 #include "qgsspatialindex.h"
21 #include "qgsabstractgeometry.h"
22 #include "qgspoint.h"
23 #include "qgsgeometry.h"
24 #include "qgsgeos.h"
25 #include "qgis_analysis.h"
26 
27 #include <QMutex>
28 #include <QFuture>
29 #include <QStringList>
30 #include <geos_c.h>
31 
32 class QgsVectorLayer;
33 
42 class ANALYSIS_EXPORT QgsGeometrySnapper : public QObject
43 {
44  Q_OBJECT
45 
46  public:
47 
49  enum SnapMode
50  {
51  PreferNodes = 0,
58  };
59 
65  QgsGeometrySnapper( QgsFeatureSource *referenceSource );
66 
72  QgsGeometry snapGeometry( const QgsGeometry &geometry, double snapTolerance, SnapMode mode = PreferNodes ) const;
73 
79  QgsFeatureList snapFeatures( const QgsFeatureList &features, double snapTolerance, SnapMode mode = PreferNodes );
80 
84  static QgsGeometry snapGeometry( const QgsGeometry &geometry, double snapTolerance, const QList<QgsGeometry> &referenceGeometries, SnapMode mode = PreferNodes );
85 
86  signals:
87 
90 
91  private:
92  struct ProcessFeatureWrapper
93  {
94  QgsGeometrySnapper *instance = nullptr;
95  double snapTolerance;
96  SnapMode mode;
97  explicit ProcessFeatureWrapper( QgsGeometrySnapper *_instance, double snapTolerance, SnapMode mode )
98  : instance( _instance )
99  , snapTolerance( snapTolerance )
100  , mode( mode )
101  {}
102  void operator()( QgsFeature &feature ) { instance->processFeature( feature, snapTolerance, mode ); }
103  };
104 
105  enum PointFlag { SnappedToRefNode, SnappedToRefSegment, Unsnapped };
106 
107  QgsFeatureSource *mReferenceSource = nullptr;
108  QHash<QgsFeatureId, QgsGeometry> mCachedReferenceGeometries;
109 
110  QgsSpatialIndex mIndex;
111  mutable QMutex mIndexMutex;
112  mutable QMutex mReferenceLayerMutex;
113 
114  void processFeature( QgsFeature &feature, double snapTolerance, SnapMode mode );
115 
116  static int polyLineSize( const QgsAbstractGeometry *geom, int iPart, int iRing );
117 
118 };
119 
120 
136 class ANALYSIS_EXPORT QgsInternalGeometrySnapper
137 {
138 
139  public:
140 
146 
151  QgsGeometry snapFeature( const QgsFeature &feature );
152 
156  QgsGeometryMap snappedGeometries() const { return mProcessedGeometries; }
157 
158  private:
159 
160  bool mFirstFeature = true;
161  double mSnapTolerance = 0;
163  QgsSpatialIndex mProcessedIndex;
164  QgsGeometryMap mProcessedGeometries;
165 
166 };
167 
168 #ifndef SIP_RUN
169 
171 class QgsSnapIndex
172 {
173  public:
174  struct CoordIdx
175  {
176  CoordIdx( const QgsAbstractGeometry *_geom, QgsVertexId _vidx )
177  : geom( _geom )
178  , vidx( _vidx )
179  {}
180  QgsPoint point() const { return geom->vertexAt( vidx ); }
181 
182  const QgsAbstractGeometry *geom = nullptr;
183  QgsVertexId vidx;
184  };
185 
186  enum SnapType { SnapPoint, SnapEndPoint, SnapSegment };
187 
188  class SnapItem
189  {
190  public:
191  virtual ~SnapItem() = default;
192  SnapType type;
193  virtual QgsPoint getSnapPoint( const QgsPoint &p ) const = 0;
194 
195  protected:
196  explicit SnapItem( SnapType _type ) : type( _type ) {}
197  };
198 
199  class PointSnapItem : public QgsSnapIndex::SnapItem
200  {
201  public:
202  explicit PointSnapItem( const CoordIdx *_idx, bool isEndPoint );
203  QgsPoint getSnapPoint( const QgsPoint &/*p*/ ) const override;
204  const CoordIdx *idx = nullptr;
205  };
206 
207  class SegmentSnapItem : public QgsSnapIndex::SnapItem
208  {
209  public:
210  SegmentSnapItem( const CoordIdx *_idxFrom, const CoordIdx *_idxTo );
211  QgsPoint getSnapPoint( const QgsPoint &p ) const override;
212  bool getIntersection( const QgsPoint &p1, const QgsPoint &p2, QgsPoint &inter ) const;
213  bool getProjection( const QgsPoint &p, QgsPoint &pProj );
214  bool withinDistance( const QgsPoint &p, const double distance );
215  const CoordIdx *idxFrom = nullptr;
216  const CoordIdx *idxTo = nullptr;
217  };
218 
219  QgsSnapIndex();
220  ~QgsSnapIndex();
221 
222  QgsSnapIndex( const QgsSnapIndex &rh ) = delete;
223  QgsSnapIndex &operator=( const QgsSnapIndex &rh ) = delete;
224 
225  void addGeometry( const QgsAbstractGeometry *geom );
226  QgsPoint getClosestSnapToPoint( const QgsPoint &startPoint, const QgsPoint &midPoint );
227  SnapItem *getSnapItem( const QgsPoint &pos, const double tolerance, PointSnapItem **pSnapPoint = nullptr, SegmentSnapItem **pSnapSegment = nullptr, bool endPointOnly = false ) const;
228 
229  private:
230  QList<CoordIdx *> mCoordIdxs;
231  QList<SnapItem *> mSnapItems;
232 
233  void addPoint( const CoordIdx *idx, bool isEndPoint );
234  void addSegment( const CoordIdx *idxFrom, const CoordIdx *idxTo );
235 
236  GEOSSTRtree *mSTRTree = nullptr;
237  std::vector< geos::unique_ptr > mSTRTreeItems;
238 };
239 
241 
242 #endif
243 
244 #endif // QGS_GEOMETRY_SNAPPER_H
Abstract base class for all geometries.
An interface for objects which provide features via a getFeatures method.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometrySnapper allows a geometry to be snapped to the geometries within a different reference lay...
void featureSnapped()
Emitted each time a feature has been processed when calling snapFeatures()
SnapMode
Snapping modes.
@ EndPointPreferClosest
Only snap start/end points of lines (point features will also be snapped, polygon features will not b...
@ PreferClosestNoExtraVertices
Snap to closest point, regardless of it is a node or a segment. No new nodes will be inserted.
@ EndPointPreferNodes
Only snap start/end points of lines (point features will also be snapped, polygon features will not b...
@ PreferNodes
Prefer to snap to nodes, even when a segment may be closer than a node. New nodes will be inserted to...
@ PreferClosest
Snap to closest point, regardless of it is a node or a segment. New nodes will be inserted to make ge...
@ EndPointToEndPoint
Only snap the start/end points of lines to other start/end points of lines.
@ PreferNodesNoExtraVertices
Prefer to snap to nodes, even when a segment may be closer than a node. No new nodes will be inserted...
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsInternalGeometrySnapper allows a set of geometries to be snapped to each other.
QgsGeometryMap snappedGeometries() const
Returns a QgsGeometryMap of all feature geometries snapped by this object.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
Definition: qgspoint.cpp:525
A spatial index for QgsFeature objects.
Represents a vector layer which manages a vector based data sets.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:829
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:834
Utility class for identifying a unique vertex within a geometry.