QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmultipoint.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsmultipoint.h
3 -------------------------------------------------------------------
4Date : 29 Oct 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : 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"
22
28class 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:1648
@ 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