QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
32class QgsVectorLayer;
33
41class ANALYSIS_EXPORT QgsGeometrySnapper : public QObject
42{
43 Q_OBJECT
44
45 public:
46
49 {
50 PreferNodes = 0,
57 };
58
64 QgsGeometrySnapper( QgsFeatureSource *referenceSource );
65
71 QgsGeometry snapGeometry( const QgsGeometry &geometry, double snapTolerance, SnapMode mode = PreferNodes ) const;
72
78 QgsFeatureList snapFeatures( const QgsFeatureList &features, double snapTolerance, SnapMode mode = PreferNodes );
79
83 static QgsGeometry snapGeometry( const QgsGeometry &geometry, double snapTolerance, const QList<QgsGeometry> &referenceGeometries, SnapMode mode = PreferNodes );
84
85 signals:
86
89
90 private:
91 struct ProcessFeatureWrapper
92 {
93 QgsGeometrySnapper *instance = nullptr;
94 double snapTolerance;
95 SnapMode mode;
96 explicit ProcessFeatureWrapper( QgsGeometrySnapper *_instance, double snapTolerance, SnapMode mode )
97 : instance( _instance )
98 , snapTolerance( snapTolerance )
99 , mode( mode )
100 {}
101 void operator()( QgsFeature &feature ) { instance->processFeature( feature, snapTolerance, mode ); }
102 };
103
104 enum PointFlag { SnappedToRefNode, SnappedToRefSegment, Unsnapped };
105
106 QgsFeatureSource *mReferenceSource = nullptr;
107 QHash<QgsFeatureId, QgsGeometry> mCachedReferenceGeometries;
108
109 QgsSpatialIndex mIndex;
110 mutable QMutex mIndexMutex;
111 mutable QMutex mReferenceLayerMutex;
112
113 void processFeature( QgsFeature &feature, double snapTolerance, SnapMode mode );
114
115 static int polyLineSize( const QgsAbstractGeometry *geom, int iPart, int iRing );
116
117};
118
119
134class ANALYSIS_EXPORT QgsInternalGeometrySnapper
135{
136
137 public:
138
144
149 QgsGeometry snapFeature( const QgsFeature &feature );
150
154 QgsGeometryMap snappedGeometries() const { return mProcessedGeometries; }
155
156 private:
157
158 bool mFirstFeature = true;
159 double mSnapTolerance = 0;
161 QgsSpatialIndex mProcessedIndex;
162 QgsGeometryMap mProcessedGeometries;
163
164};
165
166#ifndef SIP_RUN
167
169class QgsSnapIndex
170{
171 public:
172 struct CoordIdx
173 {
174 CoordIdx( const QgsAbstractGeometry *_geom, QgsVertexId _vidx )
175 : geom( _geom )
176 , vidx( _vidx )
177 {}
178 QgsPoint point() const { return geom->vertexAt( vidx ); }
179
180 const QgsAbstractGeometry *geom = nullptr;
181 QgsVertexId vidx;
182 };
183
184 enum SnapType { SnapPoint, SnapEndPoint, SnapSegment };
185
186 class SnapItem
187 {
188 public:
189 virtual ~SnapItem() = default;
190 SnapType type;
191 virtual QgsPoint getSnapPoint( const QgsPoint &p ) const = 0;
192
193 protected:
194 explicit SnapItem( SnapType _type ) : type( _type ) {}
195 };
196
197 class PointSnapItem : public QgsSnapIndex::SnapItem
198 {
199 public:
200 explicit PointSnapItem( const CoordIdx *_idx, bool isEndPoint );
201 QgsPoint getSnapPoint( const QgsPoint &/*p*/ ) const override;
202 const CoordIdx *idx = nullptr;
203 };
204
205 class SegmentSnapItem : public QgsSnapIndex::SnapItem
206 {
207 public:
208 SegmentSnapItem( const CoordIdx *_idxFrom, const CoordIdx *_idxTo );
209 QgsPoint getSnapPoint( const QgsPoint &p ) const override;
210 bool getIntersection( const QgsPoint &p1, const QgsPoint &p2, QgsPoint &inter ) const;
211 bool getProjection( const QgsPoint &p, QgsPoint &pProj ) const;
212 bool withinSquaredDistance( const QgsPoint &p, const double squaredDistance );
213 const CoordIdx *idxFrom = nullptr;
214 const CoordIdx *idxTo = nullptr;
215 };
216
217 QgsSnapIndex();
218 ~QgsSnapIndex();
219
220 QgsSnapIndex( const QgsSnapIndex &rh ) = delete;
221 QgsSnapIndex &operator=( const QgsSnapIndex &rh ) = delete;
222
223 void addGeometry( const QgsAbstractGeometry *geom );
224 QgsPoint getClosestSnapToPoint( const QgsPoint &startPoint, const QgsPoint &midPoint );
225 SnapItem *getSnapItem( const QgsPoint &pos, const double tolerance, PointSnapItem **pSnapPoint = nullptr, SegmentSnapItem **pSnapSegment = nullptr, bool endPointOnly = false ) const;
226
227 private:
228 QList<CoordIdx *> mCoordIdxs;
229 QList<SnapItem *> mSnapItems;
230
231 void addPoint( const CoordIdx *idx, bool isEndPoint );
232 void addSegment( const CoordIdx *idxFrom, const CoordIdx *idxTo );
233
234 GEOSSTRtree *mSTRTree = nullptr;
235 std::vector< geos::unique_ptr > mSTRTreeItems;
236};
237
239
240#endif
241
242#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:162
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:522
A spatial index for QgsFeature objects.
Represents a vector layer which manages a vector based data sets.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:912
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30