QGIS API Documentation 3.43.0-Master (ebb4087afc0)
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 // PyObject_GetIter has added a ref to attrs - we need to decrement the ref from sipConvertFromType,
80 // so that the garbage collector will delete attrs when the iterator is deleted
81 Py_DECREF( attrs );
82 % End
83#endif
84
85#ifdef SIP_PYQT5_RUN
86#ifdef SIP_RUN
87 SIP_PYOBJECT __getitem__( int key ) SIP_HOLDGIL;
88 % MethodCode
89 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
90 {
91 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
92 sipIsErr = 1;
93 }
94 else
95 {
96 const QVariant v = sipCpp->attribute( a0 );
97 if ( !v.isValid() )
98 {
99 Py_INCREF( Py_None );
100 sipRes = Py_None;
101 }
102 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
103 else if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
104 {
105 PyObject *vartype = sipConvertFromEnum( v.type(), sipType_QVariant_Type );
106 PyObject *args = PyTuple_Pack( 1, vartype );
107 PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant );
108 sipRes = PyObject_Call( ( PyObject * )typeObj, args, nullptr );
109 Py_DECREF( args );
110 Py_DECREF( vartype );
111 }
112 else
113 {
114 switch ( v.userType() )
115 {
116 case QMetaType::Type::Int:
117 sipRes = PyLong_FromLong( v.toInt() );
118 break;
119
120 case QMetaType::Type::UInt:
121 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
122 break;
123
124 case QMetaType::Type::Long:
125 case QMetaType::Type::LongLong:
126 sipRes = PyLong_FromLongLong( v.toLongLong() );
127 break;
128
129 case QMetaType::Type::ULong:
130 case QMetaType::Type::ULongLong:
131 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
132 break;
133
134 case QMetaType::Type::Bool:
135 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
136 break;
137
138 case QMetaType::Type::Float:
139 case QMetaType::Type::Double:
140 sipRes = PyFloat_FromDouble( v.toDouble() );
141 break;
142
143 case QMetaType::Type::QString:
144 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
145 break;
146
147 default:
148 {
149 QVariant *newV = new QVariant( v );
150 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
151 break;
152 }
153 }
154 }
155 }
156 % End
157
158 SIP_PYOBJECT __getitem__( const QString &name ) SIP_HOLDGIL;
159 % MethodCode
160 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
161 if ( fieldIdx == -1 )
162 {
163 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
164 sipIsErr = 1;
165 }
166 else
167 {
168 const QVariant v = sipCpp->attribute( fieldIdx );
169 if ( !v.isValid() )
170 {
171 Py_INCREF( Py_None );
172 sipRes = Py_None;
173 }
174 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
175 else if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
176 {
177 PyObject *vartype = sipConvertFromEnum( v.type(), sipType_QVariant_Type );
178 PyObject *args = PyTuple_Pack( 1, vartype );
179 PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant );
180 sipRes = PyObject_Call( ( PyObject * )typeObj, args, nullptr );
181 Py_DECREF( args );
182 Py_DECREF( vartype );
183 }
184 else
185 {
186 switch ( v.userType() )
187 {
188 case QMetaType::Type::Int:
189 sipRes = PyLong_FromLong( v.toInt() );
190 break;
191
192 case QMetaType::Type::UInt:
193 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
194 break;
195
196 case QMetaType::Type::Long:
197 case QMetaType::Type::LongLong:
198 sipRes = PyLong_FromLongLong( v.toLongLong() );
199 break;
200
201 case QMetaType::Type::ULong:
202 case QMetaType::Type::ULongLong:
203 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
204 break;
205
206 case QMetaType::Type::Bool:
207 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
208 break;
209
210 case QMetaType::Type::Float:
211 case QMetaType::Type::Double:
212 sipRes = PyFloat_FromDouble( v.toDouble() );
213 break;
214
215 case QMetaType::Type::QString:
216 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
217 break;
218
219 default:
220 {
221 QVariant *newV = new QVariant( v );
222 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
223 break;
224 }
225 }
226 }
227 }
228 % End
229#endif
230#endif
231
232#ifdef SIP_PYQT6_RUN
233#ifdef SIP_RUN
234 SIP_PYOBJECT __getitem__( int key ) SIP_HOLDGIL;
235 % MethodCode
236 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
237 {
238 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
239 sipIsErr = 1;
240 }
241 else
242 {
243 const QVariant v = sipCpp->attribute( a0 );
244 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
245 if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
246 {
247 Py_INCREF( Py_None );
248 sipRes = Py_None;
249 }
250 else
251 {
252 switch ( v.userType() )
253 {
254 case QMetaType::Type::Int:
255 sipRes = PyLong_FromLong( v.toInt() );
256 break;
257
258 case QMetaType::Type::UInt:
259 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
260 break;
261
262 case QMetaType::Type::Long:
263 case QMetaType::Type::LongLong:
264 sipRes = PyLong_FromLongLong( v.toLongLong() );
265 break;
266
267 case QMetaType::Type::ULong:
268 case QMetaType::Type::ULongLong:
269 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
270 break;
271
272 case QMetaType::Type::Bool:
273 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
274 break;
275
276 case QMetaType::Type::Float:
277 case QMetaType::Type::Double:
278 sipRes = PyFloat_FromDouble( v.toDouble() );
279 break;
280
281 case QMetaType::Type::QString:
282 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
283 break;
284
285 default:
286 {
287 QVariant *newV = new QVariant( v );
288 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
289 break;
290 }
291 }
292 }
293 }
294 % End
295
296 SIP_PYOBJECT __getitem__( const QString &name ) SIP_HOLDGIL;
297 % MethodCode
298 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
299 if ( fieldIdx == -1 )
300 {
301 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
302 sipIsErr = 1;
303 }
304 else
305 {
306 const QVariant v = sipCpp->attribute( fieldIdx );
307 // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
308 if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
309 {
310 Py_INCREF( Py_None );
311 sipRes = Py_None;
312 }
313 else
314 {
315 switch ( v.userType() )
316 {
317 case QMetaType::Type::Int:
318 sipRes = PyLong_FromLong( v.toInt() );
319 break;
320
321 case QMetaType::Type::UInt:
322 sipRes = PyLong_FromUnsignedLong( v.toUInt() );
323 break;
324
325 case QMetaType::Type::Long:
326 case QMetaType::Type::LongLong:
327 sipRes = PyLong_FromLongLong( v.toLongLong() );
328 break;
329
330 case QMetaType::Type::ULong:
331 case QMetaType::Type::ULongLong:
332 sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
333 break;
334
335 case QMetaType::Type::Bool:
336 sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
337 break;
338
339 case QMetaType::Type::Float:
340 case QMetaType::Type::Double:
341 sipRes = PyFloat_FromDouble( v.toDouble() );
342 break;
343
344 case QMetaType::Type::QString:
345 sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
346 break;
347
348 default:
349 {
350 QVariant *newV = new QVariant( v );
351 sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
352 break;
353 }
354 }
355 }
356 }
357 % End
358#endif
359#endif
360
361#ifdef SIP_RUN
362 void __setitem__( int key, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
363 % MethodCode
364 bool rv;
365
366 if ( a1 == Py_None )
367 {
368 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
369 }
370 else if ( PyBool_Check( a1 ) )
371 {
372 rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
373 }
374 else if ( PyLong_Check( a1 ) )
375 {
376 rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
377 }
378 else if ( PyFloat_Check( a1 ) )
379 {
380 rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
381 }
382 else if ( PyUnicode_Check( a1 ) )
383 {
384 rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
385 }
386 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
387 {
388 int state;
389 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
390 if ( sipIsErr )
391 {
392 rv = false;
393 }
394 else
395 {
396 rv = sipCpp->setAttribute( a0, *qvariant );
397 }
398 sipReleaseType( qvariant, sipType_QVariant, state );
399 }
400 else
401 {
402 rv = false;
403 }
404
405 if ( !rv )
406 {
407 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
408 sipIsErr = 1;
409 }
410 % End
411
412 void __setitem__( const QString &key, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
413 % MethodCode
414 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
415 if ( fieldIdx == -1 )
416 {
417 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
418 sipIsErr = 1;
419 }
420 else
421 {
422 if ( a1 == Py_None )
423 {
424 sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
425 }
426 else if ( PyBool_Check( a1 ) )
427 {
428 sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
429 }
430 else if ( PyLong_Check( a1 ) )
431 {
432 sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
433 }
434 else if ( PyFloat_Check( a1 ) )
435 {
436 sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
437 }
438 else if ( PyUnicode_Check( a1 ) )
439 {
440 sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
441 }
442 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
443 {
444 int state;
445 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
446 if ( !sipIsErr )
447 {
448 sipCpp->setAttribute( fieldIdx, *qvariant );
449 }
450 sipReleaseType( qvariant, sipType_QVariant, state );
451 }
452 else
453 {
454 sipIsErr = 1;
455 }
456 }
457 % End
458
459 void __delitem__( int key ) SIP_HOLDGIL;
460 % MethodCode
461 if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
462 sipCpp->deleteAttribute( a0 );
463 else
464 {
465 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
466 sipIsErr = 1;
467 }
468 % End
469
470 void __delitem__( const QString &name ) SIP_HOLDGIL;
471 % MethodCode
472 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
473 if ( fieldIdx == -1 )
474 {
475 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
476 sipIsErr = 1;
477 }
478 else
479 sipCpp->deleteAttribute( fieldIdx );
480 % End
481
482 long __hash__() const SIP_HOLDGIL;
483 % MethodCode
484 sipRes = qHash( *sipCpp );
485 % End
486#endif
487
492#ifndef SIP_RUN
494#else
495 QgsFeature( qint64 id = FID_NULL ) SIP_HOLDGIL;
496#endif
497
503#ifndef SIP_RUN
504 QgsFeature( const QgsFields &fields, QgsFeatureId id = FID_NULL );
505#else
506 QgsFeature( const QgsFields &fields, qint64 id = FID_NULL ) SIP_HOLDGIL;
507#endif
508
509 QgsFeature( const QgsFeature &rhs ) SIP_HOLDGIL;
510 QgsFeature &operator=( const QgsFeature &rhs ) SIP_HOLDGIL;
511 bool operator==( const QgsFeature &other ) const SIP_HOLDGIL;
512 bool operator!=( const QgsFeature &other ) const SIP_HOLDGIL;
513
514 virtual ~QgsFeature();
515
520 QgsFeatureId id() const SIP_HOLDGIL;
521
530 void setId( QgsFeatureId id ) SIP_HOLDGIL;
531
548 QgsAttributes attributes() const SIP_HOLDGIL;
549
550#ifndef SIP_RUN
551
561 QVariantMap attributeMap() const;
562#else
563
575 SIP_PYOBJECT attributeMap() const SIP_HOLDGIL SIP_TYPEHINT( Dict[str, Optional[object]] );
576 % MethodCode
577 const int fieldSize = sipCpp->fields().size();
578 const int attributeSize = sipCpp->attributeCount();
579 if ( fieldSize == 0 && attributeSize != 0 )
580 {
581 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
582 sipIsErr = 1;
583 }
584 else if ( fieldSize != attributeSize )
585 {
586 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
587 sipIsErr = 1;
588 }
589 else
590 {
591 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
592 const sipTypeDef *qvariantmap_type = sipFindType( "QMap<QString,QVariant>" );
593 sipRes = sipConvertFromNewType( v, qvariantmap_type, Py_None );
594 }
595 % End
596#endif
597
602 int attributeCount() const SIP_HOLDGIL;
603
620 void setAttributes( const QgsAttributes &attrs ) SIP_HOLDGIL;
621
622#ifndef SIP_RUN
623
634 Q_INVOKABLE bool setAttribute( int field, const QVariant &attr );
635#else
636
661 bool setAttribute( int field, SIP_PYOBJECT attr SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
662 % MethodCode
663 bool rv;
664
665 if ( a1 == Py_None )
666 {
667 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
668 }
669 else if ( PyBool_Check( a1 ) )
670 {
671 rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
672 }
673 else if ( PyLong_Check( a1 ) )
674 {
675 rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
676 }
677 else if ( PyFloat_Check( a1 ) )
678 {
679 rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
680 }
681 else if ( PyUnicode_Check( a1 ) )
682 {
683 rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
684 }
685 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
686 {
687 int state;
688 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
689 if ( sipIsErr )
690 {
691 rv = false;
692 }
693 else
694 {
695 rv = sipCpp->setAttribute( a0, *qvariant );
696 }
697 sipReleaseType( qvariant, sipType_QVariant, state );
698 }
699 else
700 {
701 rv = false;
702 }
703
704 if ( !rv )
705 {
706 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
707 sipIsErr = 1;
708 }
709
710 sipRes = rv;
711 % End
712#endif
713
723 void initAttributes( int fieldCount ) SIP_HOLDGIL;
724
738 void resizeAttributes( int fieldCount ) SIP_HOLDGIL;
739
746 void padAttributes( int count ) SIP_HOLDGIL;
747
748#ifndef SIP_RUN
749
757 void deleteAttribute( int field );
758#else
759
784 void deleteAttribute( int field ) SIP_HOLDGIL;
785 % MethodCode
786 if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
787 sipCpp->deleteAttribute( a0 );
788 else
789 {
790 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
791 sipIsErr = 1;
792 }
793 % End
794#endif
795
804 bool isValid() const SIP_HOLDGIL;
805
813 void setValid( bool validity ) SIP_HOLDGIL;
814
819 bool hasGeometry() const SIP_HOLDGIL;
820
827 QgsGeometry geometry() const SIP_HOLDGIL;
828
838 void setGeometry( const QgsGeometry &geometry ) SIP_HOLDGIL;
839
870#ifndef SIP_RUN
871 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
872#else
873 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_HOLDGIL;
874 % MethodCode
875 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
876 % End
877#endif
878
884 void clearGeometry() SIP_HOLDGIL;
885
892 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) ) SIP_HOLDGIL;
893
898 QgsFields fields() const SIP_HOLDGIL;
899
900#ifndef SIP_RUN
901
916 Q_INVOKABLE bool setAttribute( const QString &name, const QVariant &value );
917#else
918
945 void setAttribute( const QString &name, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
946 % MethodCode
947 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
948 if ( fieldIdx == -1 )
949 {
950 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
951 sipIsErr = 1;
952 }
953 else
954 {
955 if ( a1 == Py_None )
956 {
957 sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
958 }
959 else if ( PyBool_Check( a1 ) )
960 {
961 sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
962 }
963 else if ( PyLong_Check( a1 ) )
964 {
965 sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
966 }
967 else if ( PyFloat_Check( a1 ) )
968 {
969 sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
970 }
971 else if ( PyUnicode_Check( a1 ) )
972 {
973 sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
974 }
975 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
976 {
977 int state;
978 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
979 if ( !sipIsErr )
980 {
981 sipCpp->setAttribute( fieldIdx, *qvariant );
982 }
983 sipReleaseType( qvariant, sipType_QVariant, state );
984 }
985 else
986 {
987 sipIsErr = 1;
988 }
989 }
990 % End
991#endif
992
993#ifndef SIP_RUN
994
1004 bool deleteAttribute( const QString &name );
1005#else
1006
1036 bool deleteAttribute( const QString &name ) SIP_HOLDGIL;
1037 % MethodCode
1038 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1039 if ( fieldIdx == -1 )
1040 {
1041 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1042 sipIsErr = 1;
1043 sipRes = false;
1044 }
1045 else
1046 {
1047 sipCpp->deleteAttribute( fieldIdx );
1048 sipRes = true;
1049 }
1050 % End
1051#endif
1052
1053#ifndef SIP_RUN
1054
1064 Q_INVOKABLE QVariant attribute( const QString &name ) const;
1065#else
1066
1092 Q_INVOKABLE SIP_PYOBJECT attribute( const QString &name ) const SIP_HOLDGIL;
1093 % MethodCode
1094 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1095 if ( fieldIdx == -1 )
1096 {
1097 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1098 sipIsErr = 1;
1099 }
1100 else
1101 {
1102 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
1103 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1104 }
1105 % End
1106#endif
1107
1108#ifndef SIP_RUN
1109
1117 QVariant attribute( int fieldIdx ) const;
1118#else
1119
1144 SIP_PYOBJECT attribute( int fieldIdx ) const SIP_HOLDGIL;
1145 % MethodCode
1146 {
1147 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1148 {
1149 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1150 sipIsErr = 1;
1151 }
1152 else
1153 {
1154 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
1155 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1156 }
1157 }
1158 % End
1159#endif
1160
1161
1162#ifndef SIP_RUN
1163
1170 bool isUnsetValue( int fieldIdx ) const;
1171#else
1172
1180 bool isUnsetValue( int fieldIdx ) const SIP_HOLDGIL;
1181 % MethodCode
1182 {
1183 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1184 {
1185 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1186 sipIsErr = 1;
1187 }
1188 else
1189 {
1190 sipRes = sipCpp->isUnsetValue( a0 );
1191 }
1192 }
1193 % End
1194#endif
1195
1201 const QgsSymbol *embeddedSymbol() const SIP_HOLDGIL;
1202
1210 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER ) SIP_HOLDGIL;
1211
1221 int fieldNameIndex( const QString &fieldName ) const SIP_HOLDGIL;
1222
1232 int approximateMemoryUsage() const;
1233
1235 operator QVariant() const
1236 {
1237 return QVariant::fromValue( *this );
1238 }
1239
1240 private:
1241
1242 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
1243
1244}; // class QgsFeature
1245
1247CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
1249CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
1250
1251// key = feature id, value = changed attributes
1252#ifndef SIP_RUN
1253typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
1254#else
1255typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
1256#endif
1257
1258#include "qgsgeometry.h"
1259
1260// key = feature id, value = changed geometry
1261#ifndef SIP_RUN
1262typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
1263#else
1264typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
1265#endif
1266
1267typedef QList<QgsFeature> QgsFeatureList;
1268
1269CORE_EXPORT uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
1270
1273
1274#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)