QGIS API Documentation 3.39.0-Master (f6cef42644e)
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
509 QgsFeature( const QgsFeature &rhs ) SIP_HOLDGIL;
510
514 QgsFeature &operator=( const QgsFeature &rhs ) SIP_HOLDGIL;
515
519 bool operator==( const QgsFeature &other ) const SIP_HOLDGIL;
520
524 bool operator!=( const QgsFeature &other ) const SIP_HOLDGIL;
525
526 virtual ~QgsFeature();
527
532 QgsFeatureId id() const SIP_HOLDGIL;
533
542 void setId( QgsFeatureId id ) SIP_HOLDGIL;
543
560 QgsAttributes attributes() const SIP_HOLDGIL;
561
562#ifndef SIP_RUN
563
573 QVariantMap attributeMap() const;
574#else
575
587 SIP_PYOBJECT attributeMap() const SIP_HOLDGIL SIP_TYPEHINT( Dict[str, Optional[object]] );
588 % MethodCode
589 const int fieldSize = sipCpp->fields().size();
590 const int attributeSize = sipCpp->attributeCount();
591 if ( fieldSize == 0 && attributeSize != 0 )
592 {
593 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
594 sipIsErr = 1;
595 }
596 else if ( fieldSize != attributeSize )
597 {
598 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
599 sipIsErr = 1;
600 }
601 else
602 {
603 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
604 const sipTypeDef *qvariantmap_type = sipFindType( "QMap<QString,QVariant>" );
605 sipRes = sipConvertFromNewType( v, qvariantmap_type, Py_None );
606 }
607 % End
608#endif
609
614 int attributeCount() const SIP_HOLDGIL;
615
632 void setAttributes( const QgsAttributes &attrs ) SIP_HOLDGIL;
633
634#ifndef SIP_RUN
635
646 Q_INVOKABLE bool setAttribute( int field, const QVariant &attr );
647#else
648
673 bool setAttribute( int field, SIP_PYOBJECT attr SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
674 % MethodCode
675 bool rv;
676
677 if ( a1 == Py_None )
678 {
679 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
680 }
681 else if ( PyBool_Check( a1 ) )
682 {
683 rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
684 }
685 else if ( PyLong_Check( a1 ) )
686 {
687 rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
688 }
689 else if ( PyFloat_Check( a1 ) )
690 {
691 rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
692 }
693 else if ( PyUnicode_Check( a1 ) )
694 {
695 rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
696 }
697 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
698 {
699 int state;
700 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
701 if ( sipIsErr )
702 {
703 rv = false;
704 }
705 else
706 {
707 rv = sipCpp->setAttribute( a0, *qvariant );
708 }
709 sipReleaseType( qvariant, sipType_QVariant, state );
710 }
711 else
712 {
713 rv = false;
714 }
715
716 if ( !rv )
717 {
718 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
719 sipIsErr = 1;
720 }
721
722 sipRes = rv;
723 % End
724#endif
725
735 void initAttributes( int fieldCount ) SIP_HOLDGIL;
736
750 void resizeAttributes( int fieldCount ) SIP_HOLDGIL;
751
758 void padAttributes( int count ) SIP_HOLDGIL;
759
760#ifndef SIP_RUN
761
769 void deleteAttribute( int field );
770#else
771
796 void deleteAttribute( int field ) SIP_HOLDGIL;
797 % MethodCode
798 if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
799 sipCpp->deleteAttribute( a0 );
800 else
801 {
802 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
803 sipIsErr = 1;
804 }
805 % End
806#endif
807
816 bool isValid() const SIP_HOLDGIL;
817
825 void setValid( bool validity ) SIP_HOLDGIL;
826
831 bool hasGeometry() const SIP_HOLDGIL;
832
839 QgsGeometry geometry() const SIP_HOLDGIL;
840
850 void setGeometry( const QgsGeometry &geometry ) SIP_HOLDGIL;
851
882#ifndef SIP_RUN
883 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
884#else
885 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER ) SIP_HOLDGIL;
886 % MethodCode
887 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
888 % End
889#endif
890
896 void clearGeometry() SIP_HOLDGIL;
897
904 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) ) SIP_HOLDGIL;
905
910 QgsFields fields() const SIP_HOLDGIL;
911
912#ifndef SIP_RUN
913
928 Q_INVOKABLE bool setAttribute( const QString &name, const QVariant &value );
929#else
930
957 void setAttribute( const QString &name, SIP_PYOBJECT value SIP_TYPEHINT( Optional[Union[bool, int, float, str, QVariant]] ) ) SIP_HOLDGIL;
958 % MethodCode
959 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
960 if ( fieldIdx == -1 )
961 {
962 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
963 sipIsErr = 1;
964 }
965 else
966 {
967 if ( a1 == Py_None )
968 {
969 sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
970 }
971 else if ( PyBool_Check( a1 ) )
972 {
973 sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
974 }
975 else if ( PyLong_Check( a1 ) )
976 {
977 sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
978 }
979 else if ( PyFloat_Check( a1 ) )
980 {
981 sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
982 }
983 else if ( PyUnicode_Check( a1 ) )
984 {
985 sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
986 }
987 else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
988 {
989 int state;
990 QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
991 if ( !sipIsErr )
992 {
993 sipCpp->setAttribute( fieldIdx, *qvariant );
994 }
995 sipReleaseType( qvariant, sipType_QVariant, state );
996 }
997 else
998 {
999 sipIsErr = 1;
1000 }
1001 }
1002 % End
1003#endif
1004
1005#ifndef SIP_RUN
1006
1016 bool deleteAttribute( const QString &name );
1017#else
1018
1048 bool deleteAttribute( const QString &name ) SIP_HOLDGIL;
1049 % MethodCode
1050 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1051 if ( fieldIdx == -1 )
1052 {
1053 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1054 sipIsErr = 1;
1055 sipRes = false;
1056 }
1057 else
1058 {
1059 sipCpp->deleteAttribute( fieldIdx );
1060 sipRes = true;
1061 }
1062 % End
1063#endif
1064
1065#ifndef SIP_RUN
1066
1076 Q_INVOKABLE QVariant attribute( const QString &name ) const;
1077#else
1078
1104 Q_INVOKABLE SIP_PYOBJECT attribute( const QString &name ) const SIP_HOLDGIL;
1105 % MethodCode
1106 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
1107 if ( fieldIdx == -1 )
1108 {
1109 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
1110 sipIsErr = 1;
1111 }
1112 else
1113 {
1114 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
1115 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1116 }
1117 % End
1118#endif
1119
1120#ifndef SIP_RUN
1121
1129 QVariant attribute( int fieldIdx ) const;
1130#else
1131
1156 SIP_PYOBJECT attribute( int fieldIdx ) const SIP_HOLDGIL;
1157 % MethodCode
1158 {
1159 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1160 {
1161 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1162 sipIsErr = 1;
1163 }
1164 else
1165 {
1166 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
1167 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
1168 }
1169 }
1170 % End
1171#endif
1172
1173
1174#ifndef SIP_RUN
1175
1182 bool isUnsetValue( int fieldIdx ) const;
1183#else
1184
1192 bool isUnsetValue( int fieldIdx ) const SIP_HOLDGIL;
1193 % MethodCode
1194 {
1195 if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
1196 {
1197 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
1198 sipIsErr = 1;
1199 }
1200 else
1201 {
1202 sipRes = sipCpp->isUnsetValue( a0 );
1203 }
1204 }
1205 % End
1206#endif
1207
1213 const QgsSymbol *embeddedSymbol() const SIP_HOLDGIL;
1214
1222 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER ) SIP_HOLDGIL;
1223
1233 int fieldNameIndex( const QString &fieldName ) const SIP_HOLDGIL;
1234
1244 int approximateMemoryUsage() const;
1245
1247 operator QVariant() const
1248 {
1249 return QVariant::fromValue( *this );
1250 }
1251
1252 private:
1253
1254 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
1255
1256}; // class QgsFeature
1257
1259CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
1261CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
1262
1263// key = feature id, value = changed attributes
1264#ifndef SIP_RUN
1265typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
1266#else
1267typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
1268#endif
1269
1270#include "qgsgeometry.h"
1271
1272// key = feature id, value = changed geometry
1273#ifndef SIP_RUN
1274typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
1275#else
1276typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
1277#endif
1278
1279typedef QList<QgsFeature> QgsFeatureList;
1280
1281CORE_EXPORT uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
1282
1285
1286#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:94
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:198
#define str(x)
Definition qgis.cpp:38
#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)