QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
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
29class CORE_EXPORT QgsMultiPoint: public QgsGeometryCollection
30{
31 public:
32
37
38#ifndef SIP_RUN
39
47 QgsMultiPoint( const QVector<QgsPoint> &points );
48
58 QgsMultiPoint( const QVector<QgsPoint *> &points );
59
66 QgsMultiPoint( const QVector<QgsPointXY> &points );
67#else
68
76 QgsMultiPoint( SIP_PYOBJECT points SIP_TYPEHINT( Sequence[Union[QgsPoint, QgsPointXY, Sequence[float]]] ) ) SIP_HOLDGIL [( const QVector<QgsPoint> &points )];
77 % MethodCode
78 if ( !PySequence_Check( a0 ) )
79 {
80 PyErr_SetString( PyExc_TypeError, QStringLiteral( "A sequence of QgsPoint, QgsPointXY or array of floats is expected" ).toUtf8().constData() );
81 sipIsErr = 1;
82 }
83 else
84 {
85 int state;
86 const int size = PySequence_Size( a0 );
87 QVector< QgsPoint * > pointList;
88 pointList.reserve( size );
89
90 sipIsErr = 0;
91 for ( int i = 0; i < size; ++i )
92 {
93 PyObject *value = PySequence_GetItem( a0, i );
94 if ( !value )
95 {
96 qDeleteAll( pointList );
97 pointList.clear();
98 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
99 sipIsErr = 1;
100 break;
101 }
102
103 if ( PySequence_Check( value ) )
104 {
105 const int elementSize = PySequence_Size( value );
106 if ( elementSize < 2 || elementSize > 4 )
107 {
108 qDeleteAll( pointList );
109 pointList.clear();
110 sipIsErr = 1;
111 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() );
112 Py_DECREF( value );
113 break;
114 }
115 else
116 {
117 sipIsErr = 0;
118
119 PyObject *element = PySequence_GetItem( value, 0 );
120 if ( !element )
121 {
122 qDeleteAll( pointList );
123 pointList.clear();
124 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
125 sipIsErr = 1;
126 break;
127 }
128
129 PyErr_Clear();
130 const double x = PyFloat_AsDouble( element );
131 Py_DECREF( element );
132 if ( PyErr_Occurred() )
133 {
134 qDeleteAll( pointList );
135 pointList.clear();
136 Py_DECREF( value );
137 sipIsErr = 1;
138 break;
139 }
140
141 element = PySequence_GetItem( value, 1 );
142 if ( !element )
143 {
144 qDeleteAll( pointList );
145 pointList.clear();
146 Py_DECREF( value );
147 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
148 sipIsErr = 1;
149 break;
150 }
151
152 PyErr_Clear();
153 const double y = PyFloat_AsDouble( element );
154 Py_DECREF( element );
155 if ( PyErr_Occurred() )
156 {
157 qDeleteAll( pointList );
158 pointList.clear();
159 Py_DECREF( value );
160 sipIsErr = 1;
161 break;
162 }
163
164 std::unique_ptr< QgsPoint > point = std::make_unique< QgsPoint >( x, y );
165 if ( elementSize > 2 )
166 {
167 element = PySequence_GetItem( value, 2 );
168 if ( !element )
169 {
170 qDeleteAll( pointList );
171 pointList.clear();
172 Py_DECREF( value );
173 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
174 sipIsErr = 1;
175 break;
176 }
177
178 PyErr_Clear();
179 const double z = PyFloat_AsDouble( element );
180 Py_DECREF( element );
181 if ( PyErr_Occurred() )
182 {
183 qDeleteAll( pointList );
184 pointList.clear();
185 Py_DECREF( value );
186 sipIsErr = 1;
187 break;
188 }
189 point->addZValue( z );
190 }
191 if ( elementSize > 3 )
192 {
193 element = PySequence_GetItem( value, 3 );
194 if ( !element )
195 {
196 qDeleteAll( pointList );
197 pointList.clear();
198 Py_DECREF( value );
199 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
200 sipIsErr = 1;
201 break;
202 }
203
204 PyErr_Clear();
205 const double m = PyFloat_AsDouble( element );
206 Py_DECREF( element );
207 if ( PyErr_Occurred() )
208 {
209 qDeleteAll( pointList );
210 pointList.clear();
211 Py_DECREF( value );
212 sipIsErr = 1;
213 break;
214 }
215 point->addMValue( m );
216 }
217 pointList.append( point.release() );
218
219 Py_DECREF( value );
220 if ( sipIsErr )
221 {
222 qDeleteAll( pointList );
223 pointList.clear();
224 break;
225 }
226 }
227 }
228 else
229 {
230 if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
231 {
232 sipIsErr = 0;
233 QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
234 if ( !sipIsErr )
235 {
236 pointList.append( new QgsPoint( p->x(), p->y() ) );
237 }
238 sipReleaseType( p, sipType_QgsPointXY, state );
239 }
240 else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
241 {
242 sipIsErr = 0;
243 QgsPoint *p = reinterpret_cast<QgsPoint *>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
244 if ( !sipIsErr )
245 {
246 pointList.append( p->clone() );
247 }
248 sipReleaseType( p, sipType_QgsPoint, state );
249 }
250 else
251 {
252 sipIsErr = 1;
253 }
254
255 Py_DECREF( value );
256
257 if ( sipIsErr )
258 {
259 qDeleteAll( pointList );
260 pointList.clear();
261 // couldn't convert the sequence value to a QgsPoint or QgsPointXY
262 PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats." ).arg( i ) .toUtf8().constData() );
263 break;
264 }
265 }
266 }
267 if ( sipIsErr == 0 )
268 sipCpp = new sipQgsMultiPoint( QgsMultiPoint( pointList ) );
269 }
270 % End
271#endif
272
284 QgsMultiPoint( const QVector<double> &x, const QVector<double> &y,
285 const QVector<double> &z = QVector<double>(),
286 const QVector<double> &m = QVector<double>() ) SIP_HOLDGIL;
287
288#ifndef SIP_RUN
289
295 QgsPoint *pointN( int index );
296#else
297
305 SIP_PYOBJECT pointN( int index ) SIP_TYPEHINT( QgsPoint );
306 % MethodCode
307 if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
308 {
309 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
310 sipIsErr = 1;
311 }
312 else
313 {
314 return sipConvertFromType( sipCpp->pointN( a0 ), sipType_QgsPoint, NULL );
315 }
316 % End
317#endif
318
319#ifndef SIP_RUN
320
328 const QgsPoint *pointN( int index ) const;
329#endif
330
331 QString geometryType() const override;
332 QgsMultiPoint *clone() const override SIP_FACTORY;
333 QgsMultiPoint *toCurveType() const override SIP_FACTORY;
334 bool fromWkt( const QString &wkt ) override;
335 void clear() override;
336 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
337 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
338 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
339 int nCoordinates() const override SIP_HOLDGIL;
340 bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override;
341 bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override;
342 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
343 int vertexNumberFromVertexId( QgsVertexId id ) const override;
344 double segmentLength( QgsVertexId startVertex ) const override;
345 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override SIP_HOLDGIL;
346
347#ifndef SIP_RUN
348 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
349
357 inline static const QgsMultiPoint *cast( const QgsAbstractGeometry *geom )
358 {
359 if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == Qgis::WkbType::MultiPoint )
360 return static_cast<const QgsMultiPoint *>( geom );
361 return nullptr;
362 }
363#endif
364
366
367#ifdef SIP_RUN
368 SIP_PYOBJECT __repr__();
369 % MethodCode
370 QString wkt = sipCpp->asWkt();
371 if ( wkt.length() > 1000 )
372 wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
373 QString str = QStringLiteral( "<QgsMultiPoint: %1>" ).arg( wkt );
374 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
375 % End
376#endif
377
378 protected:
379
380 bool wktOmitChildType() const override;
381
382};
383
384// clazy:excludeall=qstring-allocations
385
386#endif // QGSMULTIPOINT_H
@ MultiPoint
MultiPoint.
Abstract base class for all geometries.
AxisOrder
Axis order for GML generation.
@ XY
X comes before Y (or lon before lat)
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
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.
static const QgsMultiPoint * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
A class to represent a 2D point.
Definition qgspointxy.h:59
double y
Definition qgspointxy.h:63
double x
Definition qgspointxy.h:62
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.
#define str(x)
Definition qgis.cpp:38
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:227
#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:166
#define SIP_FACTORY
Definition qgis_sip.h:76
int precision
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:31