QGIS API Documentation 3.99.0-Master (357b655ed83)
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
23#include <QString>
24
25using namespace Qt::StringLiterals;
26
32class CORE_EXPORT QgsMultiPoint: public QgsGeometryCollection
33{
34 public:
35
40
41#ifndef SIP_RUN
42
50 QgsMultiPoint( const QVector<QgsPoint> &points );
51
61 QgsMultiPoint( const QVector<QgsPoint *> &points );
62
69 QgsMultiPoint( const QVector<QgsPointXY> &points );
70#else
71
79 QgsMultiPoint( SIP_PYOBJECT points SIP_TYPEHINT( Sequence[Union[QgsPoint, QgsPointXY, Sequence[float]]] ) ) SIP_HOLDGIL [( const QVector<QgsPoint> &points )];
80 % MethodCode
81 if ( !PySequence_Check( a0 ) )
82 {
83 PyErr_SetString( PyExc_TypeError, u"A sequence of QgsPoint, QgsPointXY or array of floats is expected"_s.toUtf8().constData() );
84 sipIsErr = 1;
85 }
86 else
87 {
88 int state;
89 const int size = PySequence_Size( a0 );
90 QVector< QgsPoint * > pointList;
91 pointList.reserve( size );
92
93 sipIsErr = 0;
94 for ( int i = 0; i < size; ++i )
95 {
96 PyObject *value = PySequence_GetItem( a0, i );
97 if ( !value )
98 {
99 qDeleteAll( pointList );
100 pointList.clear();
101 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
102 sipIsErr = 1;
103 break;
104 }
105
106 if ( PySequence_Check( value ) )
107 {
108 const int elementSize = PySequence_Size( value );
109 if ( elementSize < 2 || elementSize > 4 )
110 {
111 qDeleteAll( pointList );
112 pointList.clear();
113 sipIsErr = 1;
114 PyErr_SetString( PyExc_TypeError, u"Invalid sequence size at index %1. Expected an array of 2-4 float values, got %2."_s.arg( i ).arg( elementSize ).toUtf8().constData() );
115 Py_DECREF( value );
116 break;
117 }
118 else
119 {
120 sipIsErr = 0;
121
122 PyObject *element = PySequence_GetItem( value, 0 );
123 if ( !element )
124 {
125 qDeleteAll( pointList );
126 pointList.clear();
127 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
128 sipIsErr = 1;
129 break;
130 }
131
132 PyErr_Clear();
133 const double x = PyFloat_AsDouble( element );
134 Py_DECREF( element );
135 if ( PyErr_Occurred() )
136 {
137 qDeleteAll( pointList );
138 pointList.clear();
139 Py_DECREF( value );
140 sipIsErr = 1;
141 break;
142 }
143
144 element = PySequence_GetItem( value, 1 );
145 if ( !element )
146 {
147 qDeleteAll( pointList );
148 pointList.clear();
149 Py_DECREF( value );
150 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
151 sipIsErr = 1;
152 break;
153 }
154
155 PyErr_Clear();
156 const double y = PyFloat_AsDouble( element );
157 Py_DECREF( element );
158 if ( PyErr_Occurred() )
159 {
160 qDeleteAll( pointList );
161 pointList.clear();
162 Py_DECREF( value );
163 sipIsErr = 1;
164 break;
165 }
166
167 auto point = std::make_unique< QgsPoint >( x, y );
168 if ( elementSize > 2 )
169 {
170 element = PySequence_GetItem( value, 2 );
171 if ( !element )
172 {
173 qDeleteAll( pointList );
174 pointList.clear();
175 Py_DECREF( value );
176 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
177 sipIsErr = 1;
178 break;
179 }
180
181 PyErr_Clear();
182 const double z = PyFloat_AsDouble( element );
183 Py_DECREF( element );
184 if ( PyErr_Occurred() )
185 {
186 qDeleteAll( pointList );
187 pointList.clear();
188 Py_DECREF( value );
189 sipIsErr = 1;
190 break;
191 }
192 point->addZValue( z );
193 }
194 if ( elementSize > 3 )
195 {
196 element = PySequence_GetItem( value, 3 );
197 if ( !element )
198 {
199 qDeleteAll( pointList );
200 pointList.clear();
201 Py_DECREF( value );
202 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
203 sipIsErr = 1;
204 break;
205 }
206
207 PyErr_Clear();
208 const double m = PyFloat_AsDouble( element );
209 Py_DECREF( element );
210 if ( PyErr_Occurred() )
211 {
212 qDeleteAll( pointList );
213 pointList.clear();
214 Py_DECREF( value );
215 sipIsErr = 1;
216 break;
217 }
218 point->addMValue( m );
219 }
220 pointList.append( point.release() );
221
222 Py_DECREF( value );
223 if ( sipIsErr )
224 {
225 qDeleteAll( pointList );
226 pointList.clear();
227 break;
228 }
229 }
230 }
231 else
232 {
233 if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
234 {
235 sipIsErr = 0;
236 QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
237 if ( !sipIsErr )
238 {
239 pointList.append( new QgsPoint( p->x(), p->y() ) );
240 }
241 sipReleaseType( p, sipType_QgsPointXY, state );
242 }
243 else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
244 {
245 sipIsErr = 0;
246 QgsPoint *p = reinterpret_cast<QgsPoint *>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
247 if ( !sipIsErr )
248 {
249 pointList.append( p->clone() );
250 }
251 sipReleaseType( p, sipType_QgsPoint, state );
252 }
253 else
254 {
255 sipIsErr = 1;
256 }
257
258 Py_DECREF( value );
259
260 if ( sipIsErr )
261 {
262 qDeleteAll( pointList );
263 pointList.clear();
264 // couldn't convert the sequence value to a QgsPoint or QgsPointXY
265 PyErr_SetString( PyExc_TypeError, u"Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats."_s.arg( i ) .toUtf8().constData() );
266 break;
267 }
268 }
269 }
270 if ( sipIsErr == 0 )
271 sipCpp = new sipQgsMultiPoint( QgsMultiPoint( pointList ) );
272 }
273 % End
274#endif
275
287 QgsMultiPoint( const QVector<double> &x, const QVector<double> &y,
288 const QVector<double> &z = QVector<double>(),
289 const QVector<double> &m = QVector<double>() ) SIP_HOLDGIL;
290
291#ifndef SIP_RUN
292
298 QgsPoint *pointN( int index );
299#else
300
308 SIP_PYOBJECT pointN( int index ) SIP_TYPEHINT( QgsPoint );
309 % MethodCode
310 if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
311 {
312 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
313 sipIsErr = 1;
314 }
315 else
316 {
317 return sipConvertFromType( sipCpp->pointN( a0 ), sipType_QgsPoint, NULL );
318 }
319 % End
320#endif
321
322#ifndef SIP_RUN
323
331 const QgsPoint *pointN( int index ) const;
332#endif
333
334 QString geometryType() const override;
335 QgsMultiPoint *clone() const override SIP_FACTORY;
336 QgsMultiPoint *toCurveType() const override SIP_FACTORY;
337 bool fromWkt( const QString &wkt ) override;
338 void clear() override;
339 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
340 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
341 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
342 int nCoordinates() const override SIP_HOLDGIL;
343 bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override;
344 bool addGeometries( const QVector< QgsAbstractGeometry * > &geometries SIP_TRANSFER ) final;
345 bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override;
346 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
347 int vertexNumberFromVertexId( QgsVertexId id ) const override;
348 double segmentLength( QgsVertexId startVertex ) const override;
349 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override SIP_HOLDGIL;
350 QgsMultiPoint *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
351
352#ifndef SIP_RUN
353 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
354
363 inline static const QgsMultiPoint *cast( const QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
364 {
365 if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == Qgis::WkbType::MultiPoint )
366 return static_cast<const QgsMultiPoint *>( geom );
367 return nullptr;
368 }
369
378 inline static QgsMultiPoint *cast( QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
379 {
380 if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == Qgis::WkbType::MultiPoint )
381 return static_cast<QgsMultiPoint *>( geom );
382 return nullptr;
383 }
384#endif
385
387
388#ifdef SIP_RUN
389 SIP_PYOBJECT __repr__();
390 % MethodCode
391 QString wkt = sipCpp->asWkt();
392 if ( wkt.length() > 1000 )
393 wkt = wkt.left( 1000 ) + u"..."_s;
394 QString str = u"<QgsMultiPoint: %1>"_s.arg( wkt );
395 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
396 % End
397#endif
398
399 protected:
400
401 bool wktOmitChildType() const override;
402
403};
404
405// clazy:excludeall=qstring-allocations
406
407#endif // QGSMULTIPOINT_H
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
Definition qgis.h:2133
@ MultiPoint
MultiPoint.
Definition qgis.h:286
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.
QgsAbstractGeometry()=default
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.
QgsGeometryCollection * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
QgsGeometryCollection()
Constructor for an empty geometry collection.
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.
virtual bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries)
Adds a list of geometries to the collection, transferring ownership to the collection.
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 QgsMultiPoint * cast(QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
QgsPoint * pointN(int index)
Returns the point with the specified index.
QgsMultiPoint()
Constructor for an empty multipoint geometry.
static const QgsMultiPoint * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
Represents a 2D point.
Definition qgspointxy.h:62
double y
Definition qgspointxy.h:66
double x
Definition qgspointxy.h:65
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition qgspoint.cpp:129
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:240
#define SIP_SKIP
Definition qgis_sip.h:134
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_OUT
Definition qgis_sip.h:58
#define SIP_HOLDGIL
Definition qgis_sip.h:179
#define SIP_FACTORY
Definition qgis_sip.h:84
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:34