QGIS API Documentation  3.25.0-Master (10b47c2603)
qgsabstractgeometry.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsabstractgeometry.h
3  -------------------------------------------------------------------
4 Date : 04 Sept 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : marco.hugentobler at sourcepole dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSABSTRACTGEOMETRYV2
17 #define QGSABSTRACTGEOMETRYV2
18 
19 #include <array>
20 #include <functional>
21 #include <type_traits>
22 #include <QString>
23 
24 #include "qgis_core.h"
25 #include "qgis.h"
26 #include "qgswkbtypes.h"
27 #include "qgswkbptr.h"
28 
29 #ifndef SIP_RUN
30 #include "json_fwd.hpp"
31 using namespace nlohmann;
32 #endif
33 
34 class QgsMapToPixel;
35 class QgsCurve;
36 class QgsMultiCurve;
37 class QgsMultiPoint;
38 
39 struct QgsVertexId;
40 class QgsVertexIterator;
41 class QPainter;
42 class QDomDocument;
43 class QDomElement;
46 class QgsConstWkbPtr;
47 class QPainterPath;
49 class QgsFeedback;
51 class QgsPoint;
52 class QgsRectangle;
53 
54 typedef QVector< QgsPoint > QgsPointSequence;
55 #ifndef SIP_RUN
56 typedef QVector< QgsPointSequence > QgsRingSequence;
57 typedef QVector< QgsRingSequence > QgsCoordinateSequence;
58 #else
59 typedef QVector< QVector< QgsPoint > > QgsRingSequence;
60 typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence;
61 #endif
62 
63 
79 class CORE_EXPORT QgsAbstractGeometry
80 {
81 
82 #ifdef SIP_RUN
84  if ( qgsgeometry_cast<QgsPoint *>( sipCpp ) != nullptr )
85  sipType = sipType_QgsPoint;
86  else if ( qgsgeometry_cast<QgsLineString *>( sipCpp ) != nullptr )
87  sipType = sipType_QgsLineString;
88  else if ( qgsgeometry_cast<QgsCircularString *>( sipCpp ) != nullptr )
89  sipType = sipType_QgsCircularString;
90  else if ( qgsgeometry_cast<QgsCompoundCurve *>( sipCpp ) != nullptr )
91  sipType = sipType_QgsCompoundCurve;
92  else if ( qgsgeometry_cast<QgsTriangle *>( sipCpp ) != nullptr )
93  sipType = sipType_QgsTriangle;
94  else if ( qgsgeometry_cast<QgsPolygon *>( sipCpp ) != nullptr )
95  sipType = sipType_QgsPolygon;
96  else if ( qgsgeometry_cast<QgsCurvePolygon *>( sipCpp ) != nullptr )
97  sipType = sipType_QgsCurvePolygon;
98  else if ( qgsgeometry_cast<QgsMultiPoint *>( sipCpp ) != nullptr )
99  sipType = sipType_QgsMultiPoint;
100  else if ( qgsgeometry_cast<QgsMultiLineString *>( sipCpp ) != nullptr )
101  sipType = sipType_QgsMultiLineString;
102  else if ( qgsgeometry_cast<QgsMultiPolygon *>( sipCpp ) != nullptr )
103  sipType = sipType_QgsMultiPolygon;
104  else if ( qgsgeometry_cast<QgsMultiSurface *>( sipCpp ) != nullptr )
105  sipType = sipType_QgsMultiSurface;
106  else if ( qgsgeometry_cast<QgsMultiCurve *>( sipCpp ) != nullptr )
107  sipType = sipType_QgsMultiCurve;
108  else if ( qgsgeometry_cast<QgsGeometryCollection *>( sipCpp ) != nullptr )
109  sipType = sipType_QgsGeometryCollection;
110  else
111  sipType = 0;
112  SIP_END
113 #endif
114 
115  Q_GADGET
116 
117  public:
118 
121  {
122 
127  MaximumAngle = 0,
128 
133  MaximumDifference
134  };
135  Q_ENUM( SegmentationToleranceType )
136 
137 
139  {
140 
144  XY = 0,
145 
149  YX
150  };
152 
153 
156  QgsAbstractGeometry() = default;
157  virtual ~QgsAbstractGeometry() = default;
159  QgsAbstractGeometry &operator=( const QgsAbstractGeometry &geom );
160 
161  virtual bool operator==( const QgsAbstractGeometry &other ) const = 0;
162  virtual bool operator!=( const QgsAbstractGeometry &other ) const = 0;
163 
167  virtual QgsAbstractGeometry *clone() const = 0 SIP_FACTORY;
168 
174  virtual int compareTo( const QgsAbstractGeometry *other ) const;
175 
179  virtual void clear() = 0;
180 
184  virtual QgsRectangle boundingBox() const = 0;
185 
186  //mm-sql interface
187 
192  virtual int dimension() const = 0;
193 
199  virtual QString geometryType() const = 0;
200 
206  inline QgsWkbTypes::Type wkbType() const SIP_HOLDGIL { return mWkbType; }
207 
213  QString wktTypeStr() const;
214 
219  bool is3D() const SIP_HOLDGIL
220  {
221  return QgsWkbTypes::hasZ( mWkbType );
222  }
223 
228  bool isMeasure() const SIP_HOLDGIL
229  {
230  return QgsWkbTypes::hasM( mWkbType );
231  }
232 
240 
250  virtual void normalize() = 0;
251 
252  //import
253 
259  virtual bool fromWkb( QgsConstWkbPtr &wkb ) = 0;
260 
265  virtual bool fromWkt( const QString &wkt ) = 0;
266 
267  //export
268 
273  enum WkbFlag
274  {
275  FlagExportTrianglesAsPolygons = 1 << 0,
276  };
277  Q_DECLARE_FLAGS( WkbFlags, WkbFlag )
278 
279 
286  virtual int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const = 0;
287 
299  virtual QByteArray asWkb( WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const = 0;
300 
309  virtual QString asWkt( int precision = 17 ) const = 0;
310 
322  virtual QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
323 
335  virtual QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const = 0;
336 
346  QString asJson( int precision = 17 );
347 
358  virtual json asJsonObject( int precision = 17 ) SIP_SKIP const;
359 
364  virtual QString asKml( int precision = 17 ) const = 0;
365 
366 
367  //render pipeline
368 
379  virtual void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) SIP_THROW( QgsCsException ) = 0;
380 
387  virtual void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0,
388  double mTranslate = 0.0, double mScale = 1.0 ) = 0;
389 
394  virtual void draw( QPainter &p ) const = 0;
395 
404  virtual QPainterPath asQPainterPath() const = 0;
405 
416  virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0;
417 
425  virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const = 0;
426 
431  virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const = 0;
432 
437  virtual QgsCoordinateSequence coordinateSequence() const = 0;
438 
442  virtual int nCoordinates() const;
443 
447  virtual QgsPoint vertexAt( QgsVertexId id ) const = 0;
448 
461  virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT,
462  QgsVertexId &vertexAfter SIP_OUT,
463  int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const = 0;
464 
465  //low-level editing
466 
475  virtual bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) = 0;
476 
485  virtual bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) = 0;
486 
494  virtual bool deleteVertex( QgsVertexId position ) = 0;
495 
508  virtual double length() const;
509 
522  virtual double perimeter() const;
523 
536  virtual double area() const;
537 
546  virtual double segmentLength( QgsVertexId startVertex ) const = 0;
547 
549  virtual QgsPoint centroid() const;
550 
554  virtual bool isEmpty() const;
555 
559  virtual bool hasCurvedSegments() const;
560 
569  virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const SIP_HOLDGIL;
570 
577  virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
578 
585  virtual QgsAbstractGeometry *toCurveType() const = 0 SIP_FACTORY;
586 
609  virtual QgsAbstractGeometry *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const = 0 SIP_FACTORY;
610 
631  virtual bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) = 0;
632 
640  virtual double vertexAngle( QgsVertexId vertex ) const = 0;
641 
645  virtual int vertexCount( int part = 0, int ring = 0 ) const = 0;
646 
650  virtual int ringCount( int part = 0 ) const = 0;
651 
657  virtual int partCount() const = 0;
658 
667  virtual bool addZValue( double zValue = 0 ) = 0;
668 
677  virtual bool addMValue( double mValue = 0 ) = 0;
678 
686  virtual bool dropZValue() = 0;
687 
695  virtual bool dropMValue() = 0;
696 
703  virtual void swapXy() = 0;
704 
710  virtual bool convertTo( QgsWkbTypes::Type type );
711 
730  virtual const QgsAbstractGeometry *simplifiedTypeRef() const SIP_HOLDGIL;
731 
743  virtual bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const = 0;
744 
758  virtual bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) = 0;
759 
760 #ifndef SIP_RUN
761 
771  virtual void filterVertices( const std::function< bool( const QgsPoint & ) > &filter );
772 
787  virtual void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform );
788 
794  class CORE_EXPORT part_iterator
795  {
796  private:
797 
798  int mIndex = 0;
799  QgsAbstractGeometry *mGeometry = nullptr;
800 
801  public:
803  part_iterator() = default;
804 
806  part_iterator( QgsAbstractGeometry *g, int index );
807 
812  part_iterator &operator++();
813 
815  part_iterator operator++( int );
816 
819 
821  int partNumber() const;
822 
823  bool operator==( part_iterator other ) const;
824  bool operator!=( part_iterator other ) const { return !( *this == other ); }
825  };
826 
836  {
837  return part_iterator( this, 0 );
838  }
839 
848  part_iterator parts_end();
849 
857  QgsGeometryConstPartIterator parts() const;
858 
864  class CORE_EXPORT const_part_iterator
865  {
866  private:
867 
868  int mIndex = 0;
869  const QgsAbstractGeometry *mGeometry = nullptr;
870 
871  public:
873  const_part_iterator() = default;
874 
876  const_part_iterator( const QgsAbstractGeometry *g, int index );
877 
882  const_part_iterator &operator++();
883 
885  const_part_iterator operator++( int );
886 
888  const QgsAbstractGeometry *operator*() const;
889 
891  int partNumber() const;
892 
893  bool operator==( const_part_iterator other ) const;
894  bool operator!=( const_part_iterator other ) const { return !( *this == other ); }
895  };
896 
905  {
906  return const_part_iterator( this, 0 );
907  }
908 
916  const_part_iterator const_parts_end() const;
917 
918 
924  class CORE_EXPORT vertex_iterator
925  {
926  private:
927 
933  struct Level
934  {
935  const QgsAbstractGeometry *g = nullptr;
936  int index = 0;
937 
938  bool operator==( const Level &other ) const;
939  };
940 
941  std::array<Level, 3> levels;
942  int depth = -1;
943 
944  void digDown();
945 
946  public:
948  vertex_iterator() = default;
949 
951  vertex_iterator( const QgsAbstractGeometry *g, int index );
952 
957  vertex_iterator &operator++();
958 
960  vertex_iterator operator++( int );
961 
963  QgsPoint operator*() const;
964 
966  QgsVertexId vertexId() const;
967 
968  bool operator==( const vertex_iterator &other ) const;
969  bool operator!=( const vertex_iterator &other ) const { return !( *this == other ); }
970  };
971 
981  {
982  return vertex_iterator( this, 0 );
983  }
984 
994  {
995  return vertex_iterator( this, childCount() );
996  }
997 #endif
998 
1032  QgsGeometryPartIterator parts();
1033 
1034 
1058  QgsVertexIterator vertices() const;
1059 
1067 
1068  protected:
1069 
1076  int sortIndex() const;
1077 
1088  virtual int compareToSameClass( const QgsAbstractGeometry *other ) const = 0;
1089 
1095  virtual bool hasChildGeometries() const;
1096 
1102  virtual int childCount() const { return 0; }
1103 
1109  virtual QgsAbstractGeometry *childGeometry( int index ) const { Q_UNUSED( index ) return nullptr; }
1110 
1116  virtual QgsPoint childPoint( int index ) const;
1117 
1118  protected:
1120 
1124  void setZMTypeFromSubGeometry( const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType );
1125 
1130  virtual QgsRectangle calculateBoundingBox() const;
1131 
1135  virtual void clearCache() const;
1136 
1137  friend class TestQgsGeometry;
1138 };
1139 
1140 
1141 #ifndef SIP_RUN
1142 
1143 template <class T>
1144 inline T qgsgeometry_cast( const QgsAbstractGeometry *geom )
1145 {
1146  return const_cast<T>( std::remove_pointer<T>::type::cast( geom ) );
1147 }
1148 
1149 #endif
1150 
1151 // clazy:excludeall=qstring-allocations
1152 
1158 class CORE_EXPORT QgsVertexIterator
1159 {
1160  public:
1162  QgsVertexIterator() = default;
1163 
1166  : g( geometry )
1167  , i( g->vertices_begin() )
1168  , n( g->vertices_end() )
1169  {
1170  }
1171 
1173  bool hasNext() const
1174  {
1175  return g && g->vertices_end() != i;
1176  }
1177 
1179  QgsPoint next();
1180 
1181 #ifdef SIP_RUN
1182  QgsVertexIterator *__iter__();
1183  % MethodCode
1184  sipRes = sipCpp;
1185  % End
1186 
1187  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsPoint );
1188  % MethodCode
1189  if ( sipCpp->hasNext() )
1190  sipRes = sipConvertFromType( new QgsPoint( sipCpp->next() ), sipType_QgsPoint, Py_None );
1191  else
1192  PyErr_SetString( PyExc_StopIteration, "" );
1193  % End
1194 #endif
1195 
1196  private:
1197  const QgsAbstractGeometry *g = nullptr;
1199 
1200 };
1201 
1207 class CORE_EXPORT QgsGeometryPartIterator
1208 {
1209  public:
1212 
1215  : g( geometry )
1216  , i( g->parts_begin() )
1217  , n( g->parts_end() )
1218  {
1219  }
1220 
1222  bool hasNext() const SIP_HOLDGIL
1223  {
1224  return g && g->parts_end() != i;
1225  }
1226 
1228  QgsAbstractGeometry *next();
1229 
1230 #ifdef SIP_RUN
1231  QgsGeometryPartIterator *__iter__();
1232  % MethodCode
1233  sipRes = sipCpp;
1234  % End
1235 
1236  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1237  % MethodCode
1238  if ( sipCpp->hasNext() )
1239  sipRes = sipConvertFromType( sipCpp->next(), sipType_QgsAbstractGeometry, NULL );
1240  else
1241  PyErr_SetString( PyExc_StopIteration, "" );
1242  % End
1243 #endif
1244 
1245  private:
1246  QgsAbstractGeometry *g = nullptr;
1248 
1249 };
1250 
1251 
1258 {
1259  public:
1262 
1265  : g( geometry )
1266  , i( g->const_parts_begin() )
1267  , n( g->const_parts_end() )
1268  {
1269  }
1270 
1272  bool hasNext() const SIP_HOLDGIL
1273  {
1274  return g && g->const_parts_end() != i;
1275  }
1276 
1278  const QgsAbstractGeometry *next();
1279 
1280 #ifdef SIP_RUN
1281  QgsGeometryConstPartIterator *__iter__();
1282  % MethodCode
1283  sipRes = sipCpp;
1284  % End
1285 
1286  SIP_PYOBJECT __next__() SIP_TYPEHINT( QgsAbstractGeometry );
1287  % MethodCode
1288  if ( sipCpp->hasNext() )
1289  sipRes = sipConvertFromType( const_cast< QgsAbstractGeometry * >( sipCpp->next() ), sipType_QgsAbstractGeometry, NULL );
1290  else
1291  PyErr_SetString( PyExc_StopIteration, "" );
1292  % End
1293 #endif
1294 
1295  private:
1296  const QgsAbstractGeometry *g = nullptr;
1298 
1299 };
1300 
1301 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAbstractGeometry::WkbFlags )
1302 
1303 #endif //QGSABSTRACTGEOMETRYV2
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
An abstract base class for classes which transform geometries by transforming input points to output ...
The part_iterator class provides STL-style iterator for const references to geometry parts.
bool operator!=(const_part_iterator other) const
const_part_iterator()=default
Create invalid iterator.
The part_iterator class provides STL-style iterator for geometry parts.
part_iterator()=default
Create invalid iterator.
bool operator!=(part_iterator other) const
The vertex_iterator class provides STL-style iterator for vertices.
vertex_iterator()=default
Create invalid iterator.
bool operator!=(const vertex_iterator &other) const
Abstract base class for all geometries.
virtual bool fromWkb(QgsConstWkbPtr &wkb)=0
Sets the geometry from a WKB string.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int childCount() const
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
AxisOrder
Axis order for GML generation.
virtual QgsAbstractGeometry * createEmptyWithSameType() const =0
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool fromWkt(const QString &wkt)=0
Sets the geometry from a WKT string.
virtual void normalize()=0
Reorganizes the geometry into a normalized form (or "canonical" form).
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
virtual QgsAbstractGeometry * childGeometry(int index) const
Returns pointer to child geometry (for geometries with child geometries - i.e.
WkbFlag
WKB export flags.
const_part_iterator const_parts_begin() const
Returns STL-style iterator pointing to the const first part of the geometry.
virtual int compareToSameClass(const QgsAbstractGeometry *other) const =0
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
part_iterator parts_begin()
Returns STL-style iterator pointing to the first part of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
A const WKB pointer.
Definition: qgswkbptr.h:138
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
Java-style iterator for const traversal of parts of a geometry.
QgsGeometryConstPartIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
QgsGeometryConstPartIterator()=default
Constructor for QgsGeometryConstPartIterator.
bool hasNext() const SIP_HOLDGIL
Find out whether there are more parts.
Java-style iterator for traversal of parts of a geometry.
QgsGeometryPartIterator()=default
Constructor for QgsGeometryPartIterator.
bool hasNext() const SIP_HOLDGIL
Find out whether there are more parts.
QgsGeometryPartIterator(QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
Multi curve geometry collection.
Definition: qgsmulticurve.h:30
Multi point geometry collection.
Definition: qgsmultipoint.h:30
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Java-style iterator for traversal of vertices of a geometry.
bool hasNext() const
Find out whether there are more vertices.
QgsVertexIterator()=default
Constructor for QgsVertexIterator.
QgsVertexIterator(const QgsAbstractGeometry *geometry)
Constructs iterator for the given geometry.
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1080
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
Definition: MathUtils.cpp:292
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
#define SIP_THROW(name)
Definition: qgis_sip.h:198
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:227
#define SIP_CONVERT_TO_SUBCLASS_CODE(code)
Definition: qgis_sip.h:186
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:166
#define SIP_FACTORY
Definition: qgis_sip.h:76
#define SIP_END
Definition: qgis_sip.h:203
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
QgsMargins operator*(const QgsMargins &margins, double factor)
Returns a QgsMargins object that is formed by multiplying each component of the given margins by fact...
Definition: qgsmargins.h:242
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:69
int precision
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:31