QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsmultipoint.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmultipoint.h
3  -------------------------------------------------------------------
4 Date : 29 Oct 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 QGSMULTIPOINT_H
17 #define QGSMULTIPOINT_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 #include "qgsgeometrycollection.h"
22 
28 class CORE_EXPORT QgsMultiPoint: public QgsGeometryCollection
29 {
30  public:
31 
36 
37 #ifndef SIP_RUN
38 
46  QgsMultiPoint( const QVector<QgsPoint> &points );
47 
57  QgsMultiPoint( const QVector<QgsPoint *> &points );
58 
65  QgsMultiPoint( const QVector<QgsPointXY> &points );
66 #else
67 
75  QgsMultiPoint( SIP_PYOBJECT points SIP_TYPEHINT( Sequence[Union[QgsPoint, QgsPointXY, Sequence[float]]] ) ) SIP_HOLDGIL [( const QVector<QgsPoint> &points )];
76  % MethodCode
77  if ( !PySequence_Check( a0 ) )
78  {
79  PyErr_SetString( PyExc_TypeError, QStringLiteral( "A sequence of QgsPoint, QgsPointXY or array of floats is expected" ).toUtf8().constData() );
80  sipIsErr = 1;
81  }
82  else
83  {
84  int state;
85  const int size = PySequence_Size( a0 );
86  QVector< QgsPoint * > pointList;
87  pointList.reserve( size );
88 
89  sipIsErr = 0;
90  for ( int i = 0; i < size; ++i )
91  {
92  PyObject *value = PySequence_GetItem( a0, i );
93  if ( !value )
94  {
95  qDeleteAll( pointList );
96  pointList.clear();
97  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
98  sipIsErr = 1;
99  break;
100  }
101 
102  if ( PySequence_Check( value ) )
103  {
104  const int elementSize = PySequence_Size( value );
105  if ( elementSize < 2 || elementSize > 4 )
106  {
107  qDeleteAll( pointList );
108  pointList.clear();
109  sipIsErr = 1;
110  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid sequence size at index %1. Expected an array of 2-4 float values, got %2." ).arg( i ).arg( elementSize ).toUtf8().constData() );
111  Py_DECREF( value );
112  break;
113  }
114  else
115  {
116  sipIsErr = 0;
117 
118  PyObject *element = PySequence_GetItem( value, 0 );
119  if ( !element )
120  {
121  qDeleteAll( pointList );
122  pointList.clear();
123  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
124  sipIsErr = 1;
125  break;
126  }
127 
128  PyErr_Clear();
129  const double x = PyFloat_AsDouble( element );
130  Py_DECREF( element );
131  if ( PyErr_Occurred() )
132  {
133  qDeleteAll( pointList );
134  pointList.clear();
135  Py_DECREF( value );
136  sipIsErr = 1;
137  break;
138  }
139 
140  element = PySequence_GetItem( value, 1 );
141  if ( !element )
142  {
143  qDeleteAll( pointList );
144  pointList.clear();
145  Py_DECREF( value );
146  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
147  sipIsErr = 1;
148  break;
149  }
150 
151  PyErr_Clear();
152  const double y = PyFloat_AsDouble( element );
153  Py_DECREF( element );
154  if ( PyErr_Occurred() )
155  {
156  qDeleteAll( pointList );
157  pointList.clear();
158  Py_DECREF( value );
159  sipIsErr = 1;
160  break;
161  }
162 
163  std::unique_ptr< QgsPoint > point = std::make_unique< QgsPoint >( x, y );
164  if ( elementSize > 2 )
165  {
166  element = PySequence_GetItem( value, 2 );
167  if ( !element )
168  {
169  qDeleteAll( pointList );
170  pointList.clear();
171  Py_DECREF( value );
172  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
173  sipIsErr = 1;
174  break;
175  }
176 
177  PyErr_Clear();
178  const double z = PyFloat_AsDouble( element );
179  Py_DECREF( element );
180  if ( PyErr_Occurred() )
181  {
182  qDeleteAll( pointList );
183  pointList.clear();
184  Py_DECREF( value );
185  sipIsErr = 1;
186  break;
187  }
188  point->addZValue( z );
189  }
190  if ( elementSize > 3 )
191  {
192  element = PySequence_GetItem( value, 3 );
193  if ( !element )
194  {
195  qDeleteAll( pointList );
196  pointList.clear();
197  Py_DECREF( value );
198  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
199  sipIsErr = 1;
200  break;
201  }
202 
203  PyErr_Clear();
204  const double m = PyFloat_AsDouble( element );
205  Py_DECREF( element );
206  if ( PyErr_Occurred() )
207  {
208  qDeleteAll( pointList );
209  pointList.clear();
210  Py_DECREF( value );
211  sipIsErr = 1;
212  break;
213  }
214  point->addMValue( m );
215  }
216  pointList.append( point.release() );
217 
218  Py_DECREF( value );
219  if ( sipIsErr )
220  {
221  qDeleteAll( pointList );
222  pointList.clear();
223  break;
224  }
225  }
226  }
227  else
228  {
229  if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
230  {
231  sipIsErr = 0;
232  QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
233  if ( !sipIsErr )
234  {
235  pointList.append( new QgsPoint( p->x(), p->y() ) );
236  }
237  sipReleaseType( p, sipType_QgsPointXY, state );
238  }
239  else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
240  {
241  sipIsErr = 0;
242  QgsPoint *p = reinterpret_cast<QgsPoint *>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
243  if ( !sipIsErr )
244  {
245  pointList.append( p->clone() );
246  }
247  sipReleaseType( p, sipType_QgsPoint, state );
248  }
249  else
250  {
251  sipIsErr = 1;
252  }
253 
254  Py_DECREF( value );
255 
256  if ( sipIsErr )
257  {
258  qDeleteAll( pointList );
259  pointList.clear();
260  // couldn't convert the sequence value to a QgsPoint or QgsPointXY
261  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats." ).arg( i ) .toUtf8().constData() );
262  break;
263  }
264  }
265  }
266  if ( sipIsErr == 0 )
267  sipCpp = new sipQgsMultiPoint( QgsMultiPoint( pointList ) );
268  }
269  % End
270 #endif
271 
283  QgsMultiPoint( const QVector<double> &x, const QVector<double> &y,
284  const QVector<double> &z = QVector<double>(),
285  const QVector<double> &m = QVector<double>() ) SIP_HOLDGIL;
286 
287 #ifndef SIP_RUN
288 
294  QgsPoint *pointN( int index );
295 #else
296 
304  SIP_PYOBJECT pointN( int index ) SIP_TYPEHINT( QgsPoint );
305  % MethodCode
306  if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
307  {
308  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
309  sipIsErr = 1;
310  }
311  else
312  {
313  return sipConvertFromType( sipCpp->pointN( a0 ), sipType_QgsPoint, NULL );
314  }
315  % End
316 #endif
317 
318 #ifndef SIP_RUN
319 
327  const QgsPoint *pointN( int index ) const;
328 #endif
329 
330  QString geometryType() const override;
331  QgsMultiPoint *clone() const override SIP_FACTORY;
332  QgsMultiPoint *toCurveType() const override SIP_FACTORY;
333  bool fromWkt( const QString &wkt ) override;
334  void clear() override;
335  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
336  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
337  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
338  int nCoordinates() const override SIP_HOLDGIL;
339  bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override;
340  bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override;
341  QgsAbstractGeometry *boundary() const override SIP_FACTORY;
342  int vertexNumberFromVertexId( QgsVertexId id ) const override;
343  double segmentLength( QgsVertexId startVertex ) const override;
344  bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override SIP_HOLDGIL;
345 
346 #ifndef SIP_RUN
347  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
348 
355  inline static const QgsMultiPoint *cast( const QgsAbstractGeometry *geom )
356  {
357  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == Qgis::WkbType::MultiPoint )
358  return static_cast<const QgsMultiPoint *>( geom );
359  return nullptr;
360  }
361 #endif
362 
364 
365 #ifdef SIP_RUN
366  SIP_PYOBJECT __repr__();
367  % MethodCode
368  QString wkt = sipCpp->asWkt();
369  if ( wkt.length() > 1000 )
370  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
371  QString str = QStringLiteral( "<QgsMultiPoint: %1>" ).arg( wkt );
372  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
373  % End
374 #endif
375 
376  protected:
377 
378  bool wktOmitChildType() const override;
379 
380 };
381 
382 // clazy:excludeall=qstring-allocations
383 
384 #endif // QGSMULTIPOINT_H
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
Definition: qgis.h:1629
@ MultiPoint
MultiPoint.
Abstract base class for all geometries.
AxisOrder
Axis order for GML generation.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
Geometry collection.
QgsGeometryCollection * toCurveType() const override
Returns the geometry converted to the more generic curve type.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
QgsGeometryCollection * clone() const override
Clones the geometry by performing a deep copy.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
Multi point geometry collection.
Definition: qgsmultipoint.h:29
static const QgsMultiPoint * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
A class to represent a 2D point.
Definition: qgspointxy.h:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspoint.cpp:105
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:628
#define str(x)
Definition: qgis.cpp:38
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:232
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:171
#define SIP_FACTORY
Definition: qgis_sip.h:76
int precision
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30