QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsfeature.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsfeature.h - Spatial Feature Class
3 --------------------------------------
4Date : 09-Sep-2003
5Copyright : (C) 2003 by Gary E.Sherman
6email : sherman at mrcc.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 QGSFEATURE_H
17#define QGSFEATURE_H
18
19#include "qgis_core.h"
20#include "qgis_sip.h"
21
22#include <QExplicitlySharedDataPointer>
23#include <QList>
24#include <QMap>
25#include <QSet>
26#include <QString>
27#include <QVariant>
28#include <QVector>
29
30#include "qgsattributes.h"
31#include "qgsfields.h"
32#include "qgsfeatureid.h"
33#include "qgsvariantutils.h"
34
35#include <memory>
36class QgsFeature;
37class QgsFeaturePrivate;
38class QgsField;
39class QgsGeometry;
40class QgsRectangle;
42class QgsSymbol;
43
44/***************************************************************************
45 * This class is considered CRITICAL and any change MUST be accompanied with
46 * full unit tests in testqgsfeature.cpp.
47 * See details in QEP #17
48 ****************************************************************************/
49
50
57class CORE_EXPORT QgsFeature
58{
59#ifdef SIP_RUN
60#if (SIP_VERSION >= 0x040900 && SIP_VERSION < 0x040c01)
61#define sipType_QVariant ((sipWrapperType *) sipTypeAsPyTypeObject (sipType_QVariant))
62#endif
63#endif
64 Q_GADGET
65
66 Q_PROPERTY( QgsFeatureId id READ id WRITE setId )
67 Q_PROPERTY( QgsAttributes attributes READ attributes WRITE setAttributes )
68 Q_PROPERTY( QgsFields fields READ fields WRITE setFields )
69 Q_PROPERTY( QgsGeometry geometry READ geometry WRITE setGeometry )
70
71 public:
72
73#ifdef SIP_RUN
74 SIP_PYOBJECT __iter__() SIP_HOLDGIL;
75 % MethodCode
76 QgsAttributes attributes = sipCpp->attributes();
77 PyObject *attrs = sipConvertFromType( &attributes, sipType_QgsAttributes, Py_None );
78 sipRes = PyObject_GetIter( attrs );
79 % End
80#endif
81
82#ifdef SIP_PYQT5_RUN
83#ifdef SIP_RUN
84 SIP_PYOBJECT __getitem__( int key ) SIP_HOLDGIL;
85 % MethodCode
86 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
87 {
88 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
89 sipIsErr = 1;
90 }
91 else
92 {
93 const QVariant v = sipCpp->attribute( a0 );
94 if ( !v.isValid() )
95 {
96 Py_INCREF( Py_None );
97 sipRes = Py_None;
98 }
99 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
100 else if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
101 {
102 PyObject *vartype = sipConvertFromEnum( v.type(), sipType_QVariant_Type );
103 PyObject *args = PyTuple_Pack( 1, vartype );
104 PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant );
105 sipRes = PyObject_Call( ( PyObject * )typeObj, args, nullptr );
106 Py_DECREF( args );
107 Py_DECREF( vartype );
108 }
109 else
110 {
111 switch ( v.userType() )
112 {
113 case QMetaType::Type::Int:
114 sipRes = PyLong_FromLong( v.toInt() );
115 break;
116
117 case QMetaType::Type::UInt:
118 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
119 break;
120
121 case QMetaType::Type::Long:
122 case QMetaType::Type::LongLong:
123 sipRes = PyLong_FromLongLong( v.toLongLong() );
124 break;
125
126 case QMetaType::Type::ULong:
127 case QMetaType::Type::ULongLong:
128 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
129 break;
130
131 case QMetaType::Type::Bool:
132 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
133 break;
134
135 case QMetaType::Type::Float:
136 case QMetaType::Type::Double:
137 sipRes = PyFloat_FromDouble( v.toDouble() );
138 break;
139
140 case QMetaType::Type::QString:
141 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
142 break;
143
144 default:
145 {
146 QVariant *newV = new QVariant( v );
147 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
148 break;
149 }
150 }
151 }
152 }
153 % End
154
155 SIP_PYOBJECT __getitem__( const QString &name ) SIP_HOLDGIL;
156 % MethodCode
157 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
158 if ( fieldIdx == -1 )
159 {
160 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
161 sipIsErr = 1;
162 }
163 else
164 {
165 const QVariant v = sipCpp->attribute( fieldIdx );
166 if ( !v.isValid() )
167 {
168 Py_INCREF( Py_None );
169 sipRes = Py_None;
170 }
171 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
172 else if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
173 {
174 PyObject *vartype = sipConvertFromEnum( v.type(), sipType_QVariant_Type );
175 PyObject *args = PyTuple_Pack( 1, vartype );
176 PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant );
177 sipRes = PyObject_Call( ( PyObject * )typeObj, args, nullptr );
178 Py_DECREF( args );
179 Py_DECREF( vartype );
180 }
181 else
182 {
183 switch ( v.userType() )
184 {
185 case QMetaType::Type::Int:
186 sipRes = PyLong_FromLong( v.toInt() );
187 break;
188
189 case QMetaType::Type::UInt:
190 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
191 break;
192
193 case QMetaType::Type::Long:
194 case QMetaType::Type::LongLong:
195 sipRes = PyLong_FromLongLong( v.toLongLong() );
196 break;
197
198 case QMetaType::Type::ULong:
199 case QMetaType::Type::ULongLong:
200 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
201 break;
202
203 case QMetaType::Type::Bool:
204 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
205 break;
206
207 case QMetaType::Type::Float:
208 case QMetaType::Type::Double:
209 sipRes = PyFloat_FromDouble( v.toDouble() );
210 break;
211
212 case QMetaType::Type::QString:
213 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
214 break;
215
216 default:
217 {
218 QVariant *newV = new QVariant( v );
219 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
220 break;
221 }
222 }
223 }
224 }
225 % End
226#endif
227#endif
228
229#ifdef SIP_PYQT6_RUN
230#ifdef SIP_RUN
231 SIP_PYOBJECT __getitem__( int key ) SIP_HOLDGIL;
232 % MethodCode
233 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
234 {
235 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
236 sipIsErr = 1;
237 }
238 else
239 {
240 const QVariant v = sipCpp->attribute( a0 );
241 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
242 if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
243 {
244 Py_INCREF( Py_None );
245 sipRes = Py_None;
246 }
247 else
248 {
249 switch ( v.userType() )
250 {
251 case QMetaType::Type::Int:
252 sipRes = PyLong_FromLong( v.toInt() );
253 break;
254
255 case QMetaType::Type::UInt:
256 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
257 break;
258
259 case QMetaType::Type::Long:
260 case QMetaType::Type::LongLong:
261 sipRes = PyLong_FromLongLong( v.toLongLong() );
262 break;
263
264 case QMetaType::Type::ULong:
265 case QMetaType::Type::ULongLong:
266 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
267 break;
268
269 case QMetaType::Type::Bool:
270 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
271 break;
272
273 case QMetaType::Type::Float:
274 case QMetaType::Type::Double:
275 sipRes = PyFloat_FromDouble( v.toDouble() );
276 break;
277
278 case QMetaType::Type::QString:
279 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
280 break;
281
282 default:
283 {
284 QVariant *newV = new QVariant( v );
285 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
286 break;
287 }
288 }
289 }
290 }
291 % End
292
293 SIP_PYOBJECT __getitem__( const QString &name ) SIP_HOLDGIL;
294 % MethodCode
295 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
296 if ( fieldIdx == -1 )
297 {
298 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
299 sipIsErr = 1;
300 }
301 else
302 {
303 const QVariant v = sipCpp->attribute( fieldIdx );
304 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
305 if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
306 {
307 Py_INCREF( Py_None );
308 sipRes = Py_None;
309 }
310 else
311 {
312 switch ( v.userType() )
313 {
314 case QMetaType::Type::Int:
315 sipRes = PyLong_FromLong( v.toInt() );
316 break;
317
318 case QMetaType::Type::UInt:
319 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
320 break;
321
322 case QMetaType::Type::Long:
323 case QMetaType::Type::LongLong:
324 sipRes = PyLong_FromLongLong( v.toLongLong() );
325 break;
326
327 case QMetaType::Type::ULong:
328 case QMetaType::Type::ULongLong:
329 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
330 break;
331
332 case QMetaType::Type::Bool:
333 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
334 break;
335
336 case QMetaType::Type::Float:
337 case QMetaType::Type::Double:
338 sipRes = PyFloat_FromDouble( v.toDouble() );
339 break;
340
341 case QMetaType::Type::QString:
342 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
343 break;
344
345 default:
346 {
347 QVariant *newV = new QVariant( v );
348 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
349 break;
350 }
351 }
352 }
353 }
354 % End
355#endif
356#endif
357
358#ifdef SIP_RUN
359 void __setitem__( int key, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
360 % MethodCode
361 bool rv;
362
363 if ( a1 == Py_None )
364 {
365 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
366 }
367 else if ( PyBool_Check( a1 ) )
368 {
369 rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
370 }
371 else if ( PyLong_Check( a1 ) )
372 {
373 rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
374 }
375 else if ( PyFloat_Check( a1 ) )
376 {
377 rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
378 }
379 else if ( PyUnicode_Check( a1 ) )
380 {
381 rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
382 }
383 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
384 {
385 int state;
386 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
387 if ( sipIsErr )
388 {
389 rv = false;
390 }
391 else
392 {
393 rv = sipCpp->setAttribute( a0, *qvariant );
394 }
395 sipReleaseType( qvariant, sipType_QVariant, state );
396 }
397 else
398 {
399 rv = false;
400 }
401
402 if ( !rv )
403 {
404 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
405 sipIsErr = 1;
406 }
407 % End
408
409 void __setitem__( const QString &key, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
410 % MethodCode
411 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
412 if ( fieldIdx == -1 )
413 {
414 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
415 sipIsErr = 1;
416 }
417 else
418 {
419 if ( a1 == Py_None )
420 {
421 sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
422 }
423 else if ( PyBool_Check( a1 ) )
424 {
425 sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
426 }
427 else if ( PyLong_Check( a1 ) )
428 {
429 sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
430 }
431 else if ( PyFloat_Check( a1 ) )
432 {
433 sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
434 }
435 else if ( PyUnicode_Check( a1 ) )
436 {
437 sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
438 }
439 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
440 {
441 int state;
442 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
443 if ( !sipIsErr )
444 {
445 sipCpp->setAttribute( fieldIdx, *qvariant );
446 }
447 sipReleaseType( qvariant, sipType_QVariant, state );
448 }
449 else
450 {
451 sipIsErr = 1;
452 }
453 }
454 % End
455
456 void __delitem__( int key ) SIP_HOLDGIL;
457 % MethodCode
458 if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
459 sipCpp->deleteAttribute( a0 );
460 else
461 {
462 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
463 sipIsErr = 1;
464 }
465 % End
466
467 void __delitem__( const QString &name ) SIP_HOLDGIL;
468 % MethodCode
469 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
470 if ( fieldIdx == -1 )
471 {
472 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
473 sipIsErr = 1;
474 }
475 else
476 sipCpp->deleteAttribute( fieldIdx );
477 % End
478
479 long __hash__() const SIP_HOLDGIL;
480 % MethodCode
481 sipRes = qHash( *sipCpp );
482 % End
483#endif
484
489#ifndef SIP_RUN
491#else
492 QgsFeature( qint64 id = FID_NULL ) SIP_HOLDGIL;
493#endif
494
500#ifndef SIP_RUN
501 QgsFeature( const QgsFields &fields, QgsFeatureId id = FID_NULL );
502#else
503 QgsFeature( const QgsFields &fields, qint64 id = FID_NULL ) SIP_HOLDGIL;
504#endif
505
506 QgsFeature( const QgsFeature &rhs ) SIP_HOLDGIL;
507 QgsFeature &operator=( const QgsFeature &rhs ) SIP_HOLDGIL;
508 bool operator==( const QgsFeature &other ) const SIP_HOLDGIL;
509 bool operator!=( const QgsFeature &other ) const SIP_HOLDGIL;
510
511 virtual ~QgsFeature();
512
517 QgsFeatureId id() const SIP_HOLDGIL;
518
527 void setId( QgsFeatureId id ) SIP_HOLDGIL;
528
545 QgsAttributes attributes() const SIP_HOLDGIL;
546
547#ifndef SIP_RUN
548
558 QVariantMap attributeMap() const;
559#else
560
572 SIP_PYOBJECT attributeMap() const SIP_HOLDGIL SIP_TYPEHINT( Dict[str, Optional[object]] );
573 % MethodCode
574 const int fieldSize = sipCpp->fields().size();
575 const int attributeSize = sipCpp->attributeCount();
576 if ( fieldSize == 0 && attributeSize != 0 )
577 {
578 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
579 sipIsErr = 1;
580 }
581 else if ( fieldSize != attributeSize )
582 {
583 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
584 sipIsErr = 1;
585 }
586 else
587 {
588 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
589 const sipTypeDef *qvariantmap_type = sipFindType( "QMap<QString,QVariant>" );
590 sipRes = sipConvertFromNewType( v, qvariantmap_type, Py_None );
591 }
592 % End
593#endif
594
599 int attributeCount() const SIP_HOLDGIL;
600
617 void setAttributes( const QgsAttributes &attrs ) SIP_HOLDGIL;
618
619#ifndef SIP_RUN
620
631 Q_INVOKABLE bool setAttribute( int field, const QVariant &attr );
632#else
633
658 bool setAttribute( int field, SIP_PYOBJECT attr SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
659 % MethodCode
660 bool rv;
661
662 if ( a1 == Py_None )
663 {
664 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
665 }
666 else if ( PyBool_Check( a1 ) )
667 {
668 rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
669 }
670 else if ( PyLong_Check( a1 ) )
671 {
672 rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
673 }
674 else if ( PyFloat_Check( a1 ) )
675 {
676 rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
677 }
678 else if ( PyUnicode_Check( a1 ) )
679 {
680 rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
681 }
682 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
683 {
684 int state;
685 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
686 if ( sipIsErr )
687 {
688 rv = false;
689 }
690 else
691 {
692 rv = sipCpp->setAttribute( a0, *qvariant );
693 }
694 sipReleaseType( qvariant, sipType_QVariant, state );
695 }
696 else
697 {
698 rv = false;
699 }
700
701 if ( !rv )
702 {
703 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
704 sipIsErr = 1;
705 }
706
707 sipRes = rv;
708 % End
709#endif
710
720 void initAttributes( int fieldCount ) SIP_HOLDGIL;
721
735 void resizeAttributes( int fieldCount ) SIP_HOLDGIL;
736
743 void padAttributes( int count ) SIP_HOLDGIL;
744
745#ifndef SIP_RUN
746
754 void deleteAttribute( int field );
755#else
756
781 void deleteAttribute( int field ) SIP_HOLDGIL;
782 % MethodCode
783 if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
784 sipCpp->deleteAttribute( a0 );
785 else
786 {
787 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
788 sipIsErr = 1;
789 }
790 % End
791#endif
792
801 bool isValid() const SIP_HOLDGIL;
802
810 void setValid( bool validity ) SIP_HOLDGIL;
811
816 bool hasGeometry() const SIP_HOLDGIL;
817
824 QgsGeometry geometry() const SIP_HOLDGIL;
825
835 void setGeometry( const QgsGeometry &geometry ) SIP_HOLDGIL;
836
867#ifndef SIP_RUN
868 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
869#else
870 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_HOLDGIL;
871 % MethodCode
872 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
873 % End
874#endif
875
881 void clearGeometry() SIP_HOLDGIL;
882
889 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) ) SIP_HOLDGIL;
890
895 QgsFields fields() const SIP_HOLDGIL;
896
897#ifndef SIP_RUN
898
913 Q_INVOKABLE bool setAttribute( const QString &name, const QVariant &value );
914#else
915
942 void setAttribute( const QString &name, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
943 % MethodCode
944 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
945 if ( fieldIdx == -1 )
946 {
947 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
948 sipIsErr = 1;
949 }
950 else
951 {
952 if ( a1 == Py_None )
953 {
954 sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
955 }
956 else if ( PyBool_Check( a1 ) )
957 {
958 sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
959 }
960 else if ( PyLong_Check( a1 ) )
961 {
962 sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
963 }
964 else if ( PyFloat_Check( a1 ) )
965 {
966 sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
967 }
968 else if ( PyUnicode_Check( a1 ) )
969 {
970 sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
971 }
972 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
973 {
974 int state;
975 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
976 if ( !sipIsErr )
977 {
978 sipCpp->setAttribute( fieldIdx, *qvariant );
979 }
980 sipReleaseType( qvariant, sipType_QVariant, state );
981 }
982 else
983 {
984 sipIsErr = 1;
985 }
986 }
987 % End
988#endif
989
990#ifndef SIP_RUN
991
1001 bool deleteAttribute( const QString &name );
1002#else
1003
1033 bool deleteAttribute( const QString &name ) SIP_HOLDGIL;
1034 % MethodCode
1035 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1036 if ( fieldIdx == -1 )
1037 {
1038 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1039 sipIsErr = 1;
1040 sipRes = false;
1041 }
1042 else
1043 {
1044 sipCpp->deleteAttribute( fieldIdx );
1045 sipRes = true;
1046 }
1047 % End
1048#endif
1049
1050#ifndef SIP_RUN
1051
1061 Q_INVOKABLE QVariant attribute( const QString &name ) const;
1062#else
1063
1089 Q_INVOKABLE SIP_PYOBJECT attribute( const QString &name ) const SIP_HOLDGIL;
1090 % MethodCode
1091 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1092 if ( fieldIdx == -1 )
1093 {
1094 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1095 sipIsErr = 1;
1096 }
1097 else
1098 {
1099 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
1100 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1101 }
1102 % End
1103#endif
1104
1105#ifndef SIP_RUN
1106
1114 QVariant attribute( int fieldIdx ) const;
1115#else
1116
1141 SIP_PYOBJECT attribute( int fieldIdx ) const SIP_HOLDGIL;
1142 % MethodCode
1143 {
1144 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1145 {
1146 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1147 sipIsErr = 1;
1148 }
1149 else
1150 {
1151 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
1152 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1153 }
1154 }
1155 % End
1156#endif
1157
1158
1159#ifndef SIP_RUN
1160
1167 bool isUnsetValue( int fieldIdx ) const;
1168#else
1169
1177 bool isUnsetValue( int fieldIdx ) const SIP_HOLDGIL;
1178 % MethodCode
1179 {
1180 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1181 {
1182 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1183 sipIsErr = 1;
1184 }
1185 else
1186 {
1187 sipRes = sipCpp->isUnsetValue( a0 );
1188 }
1189 }
1190 % End
1191#endif
1192
1198 const QgsSymbol *embeddedSymbol() const SIP_HOLDGIL;
1199
1207 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER ) SIP_HOLDGIL;
1208
1218 int fieldNameIndex( const QString &fieldName ) const SIP_HOLDGIL;
1219
1229 int approximateMemoryUsage() const;
1230
1232 operator QVariant() const
1233 {
1234 return QVariant::fromValue( *this );
1235 }
1236
1237 private:
1238
1239 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
1240
1241}; // class QgsFeature
1242
1244CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
1246CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
1247
1248// key = feature id, value = changed attributes
1249#ifndef SIP_RUN
1250typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
1251#else
1252typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
1253#endif
1254
1255#include "qgsgeometry.h"
1256
1257// key = feature id, value = changed geometry
1258#ifndef SIP_RUN
1259typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
1260#else
1261typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
1262#endif
1263
1264typedef QList<QgsFeature> QgsFeatureList;
1265
1266CORE_EXPORT uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
1267
1270
1271#endif
Abstract base class for all geometries.
A vector of attributes.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
Container of fields for a vector layer.
Definition qgsfields.h:46
A geometry is the spatial representation of a feature.
A rectangle specified with double values.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
uint qHash(const QVariant &variant)
Hash for QVariant.
Definition qgis.cpp:199
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:232
#define SIP_PYARGDEFAULT(value)
Definition qgis_sip.h:146
#define SIP_SKIP
Definition qgis_sip.h:126
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_HOLDGIL
Definition qgis_sip.h:171
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
CORE_EXPORT uint qHash(const QgsFeature &key, uint seed=0)
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsFeature &feature)
Reads a feature from stream in into feature. QGIS version compatibility is not guaranteed.
QList< QgsFeature > QgsFeatureList
#define FID_NULL
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)