QGIS API Documentation 3.27.0-Master (f261cc1f8b)
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 <memory>
34class QgsFeature;
35class QgsFeaturePrivate;
36class QgsField;
37class QgsGeometry;
38class QgsRectangle;
40class QgsSymbol;
41
42/***************************************************************************
43 * This class is considered CRITICAL and any change MUST be accompanied with
44 * full unit tests in testqgsfeature.cpp.
45 * See details in QEP #17
46 ****************************************************************************/
47
48
55class CORE_EXPORT QgsFeature
56{
57#ifdef SIP_RUN
58#if (SIP_VERSION >= 0x040900 && SIP_VERSION < 0x040c01)
59#define sipType_QVariant ((sipWrapperType *) sipTypeAsPyTypeObject (sipType_QVariant))
60#endif
61#endif
62 Q_GADGET
63
64 Q_PROPERTY( QgsFeatureId id READ id WRITE setId )
65 Q_PROPERTY( QgsAttributes attributes READ attributes WRITE setAttributes )
66 Q_PROPERTY( QgsFields fields READ fields WRITE setFields )
67 Q_PROPERTY( QgsGeometry geometry READ geometry WRITE setGeometry )
68
69 public:
70
71#ifdef SIP_RUN
72 SIP_PYOBJECT __iter__();
73 % MethodCode
74 QgsAttributes attributes = sipCpp->attributes();
75 PyObject *attrs = sipConvertFromType( &attributes, sipType_QgsAttributes, Py_None );
76 sipRes = PyObject_GetIter( attrs );
77 % End
78
79 SIP_PYOBJECT __getitem__( int key );
80 % MethodCode
81 QgsAttributes attrs = sipCpp->attributes();
82 if ( a0 < 0 || a0 >= attrs.count() )
83 {
84 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
85 sipIsErr = 1;
86 }
87 else
88 {
89 QVariant *v = new QVariant( attrs.at( a0 ) );
90 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
91 }
92 % End
93
94 SIP_PYOBJECT __getitem__( const QString &name );
95 % MethodCode
96 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
97 if ( fieldIdx == -1 )
98 {
99 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
100 sipIsErr = 1;
101 }
102 else
103 {
104 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
105 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
106 }
107 % End
108
109 void __setitem__( int key, QVariant value / GetWrapper / );
110 % MethodCode
111 bool rv;
112
113 if ( a1Wrapper == Py_None )
114 {
115 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
116 }
117 else
118 {
119 rv = sipCpp->setAttribute( a0, *a1 );
120 }
121
122 if ( !rv )
123 {
124 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
125 sipIsErr = 1;
126 }
127 % End
128
129 void __setitem__( const QString &key, QVariant value / GetWrapper / );
130 % MethodCode
131 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
132 if ( fieldIdx == -1 )
133 {
134 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
135 sipIsErr = 1;
136 }
137 else
138 {
139 if ( a1Wrapper == Py_None )
140 {
141 sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
142 }
143 else
144 {
145 sipCpp->setAttribute( fieldIdx, *a1 );
146 }
147 }
148 % End
149
150 void __delitem__( int key );
151 % MethodCode
152 if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
153 sipCpp->deleteAttribute( a0 );
154 else
155 {
156 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
157 sipIsErr = 1;
158 }
159 % End
160
161 void __delitem__( const QString &name );
162 % MethodCode
163 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
164 if ( fieldIdx == -1 )
165 {
166 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
167 sipIsErr = 1;
168 }
169 else
170 sipCpp->deleteAttribute( fieldIdx );
171 % End
172#endif
173
178#ifndef SIP_RUN
180#else
181 QgsFeature( qint64 id = FID_NULL );
182#endif
183
189#ifndef SIP_RUN
190 QgsFeature( const QgsFields &fields, QgsFeatureId id = FID_NULL );
191#else
192 QgsFeature( const QgsFields &fields, qint64 id = FID_NULL );
193#endif
194
198 QgsFeature( const QgsFeature &rhs );
199
203 QgsFeature &operator=( const QgsFeature &rhs );
204
208 bool operator==( const QgsFeature &other ) const;
209
213 bool operator!=( const QgsFeature &other ) const;
214
215 virtual ~QgsFeature();
216
221 QgsFeatureId id() const;
222
231 void setId( QgsFeatureId id );
232
250 QgsAttributes attributes() const;
251
252#ifndef SIP_RUN
253
263 QVariantMap attributeMap() const;
264#else
265
277 SIP_PYOBJECT attributeMap() const SIP_TYPEHINT( Dict[str, Optional[object]] );
278 % MethodCode
279 const int fieldSize = sipCpp->fields().size();
280 const int attributeSize = sipCpp->attributes().size();
281 if ( fieldSize == 0 && attributeSize != 0 )
282 {
283 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
284 sipIsErr = 1;
285 }
286 else if ( fieldSize != attributeSize )
287 {
288 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
289 sipIsErr = 1;
290 }
291 else
292 {
293 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
294 sipRes = sipConvertFromNewType( v, sipType_QVariantMap, Py_None );
295 }
296 % End
297#endif
298
303 int attributeCount() const;
304
321 void setAttributes( const QgsAttributes &attrs );
322
323#ifndef SIP_RUN
324
335 bool setAttribute( int field, const QVariant &attr );
336#else
337
362 bool setAttribute( int field, const QVariant &attr / GetWrapper / );
363 % MethodCode
364 bool rv;
365
366 if ( a1Wrapper == Py_None )
367 {
368 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
369 }
370 else
371 {
372 rv = sipCpp->setAttribute( a0, *a1 );
373 }
374
375 if ( !rv )
376 {
377 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
378 sipIsErr = 1;
379 }
380
381 sipRes = rv;
382 % End
383#endif
384
394 void initAttributes( int fieldCount );
395
409 void resizeAttributes( int fieldCount );
410
417 void padAttributes( int count );
418
419#ifndef SIP_RUN
420
428 void deleteAttribute( int field );
429#else
430
455 void deleteAttribute( int field );
456 % MethodCode
457 if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
458 sipCpp->deleteAttribute( a0 );
459 else
460 {
461 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
462 sipIsErr = 1;
463 }
464 % End
465#endif
466
475 bool isValid() const;
476
484 void setValid( bool validity );
485
491 bool hasGeometry() const;
492
499 QgsGeometry geometry() const;
500
510 void setGeometry( const QgsGeometry &geometry );
511
542#ifndef SIP_RUN
543 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
544#else
545 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER );
546 % MethodCode
547 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
548 % End
549#endif
550
557 void clearGeometry();
558
566 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) );
567
572 QgsFields fields() const;
573
574#ifndef SIP_RUN
575
590 bool setAttribute( const QString &name, const QVariant &value );
591#else
592
621 void setAttribute( const QString &name, const QVariant &value / GetWrapper / );
622 % MethodCode
623 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
624 if ( fieldIdx == -1 )
625 {
626 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
627 sipIsErr = 1;
628 }
629 else
630 {
631 if ( a1Wrapper == Py_None )
632 {
633 sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
634 }
635 else
636 {
637 sipCpp->setAttribute( fieldIdx, *a1 );
638 }
639 }
640 % End
641#endif
642
643#ifndef SIP_RUN
644
654 bool deleteAttribute( const QString &name );
655#else
656
686 bool deleteAttribute( const QString &name );
687 % MethodCode
688 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
689 if ( fieldIdx == -1 )
690 {
691 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
692 sipIsErr = 1;
693 sipRes = false;
694 }
695 else
696 {
697 sipCpp->deleteAttribute( fieldIdx );
698 sipRes = true;
699 }
700 % End
701#endif
702
703#ifndef SIP_RUN
704
714 QVariant attribute( const QString &name ) const;
715#else
716
742 SIP_PYOBJECT attribute( const QString &name ) const;
743 % MethodCode
744 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
745 if ( fieldIdx == -1 )
746 {
747 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
748 sipIsErr = 1;
749 }
750 else
751 {
752 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
753 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
754 }
755 % End
756#endif
757
758#ifndef SIP_RUN
759
767 QVariant attribute( int fieldIdx ) const;
768#else
769
794 SIP_PYOBJECT attribute( int fieldIdx ) const;
795 % MethodCode
796 {
797 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
798 {
799 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
800 sipIsErr = 1;
801 }
802 else
803 {
804 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
805 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
806 }
807 }
808 % End
809#endif
810
811
812#ifndef SIP_RUN
813
820 bool isUnsetValue( int fieldIdx ) const;
821#else
822
830 bool isUnsetValue( int fieldIdx ) const;
831 % MethodCode
832 {
833 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
834 {
835 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
836 sipIsErr = 1;
837 }
838 else
839 {
840 sipRes = sipCpp->isUnsetValue( a0 );
841 }
842 }
843 % End
844#endif
845
851 const QgsSymbol *embeddedSymbol() const;
852
860 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER );
861
871 int fieldNameIndex( const QString &fieldName ) const;
872
882 int approximateMemoryUsage() const;
883
885 operator QVariant() const
886 {
887 return QVariant::fromValue( *this );
888 }
889
890 private:
891
892 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
893
894}; // class QgsFeature
895
897CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
899CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
900
901// key = feature id, value = changed attributes
902#ifndef SIP_RUN
903typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
904#else
905typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
906#endif
907
908#include "qgsgeometry.h"
909
910// key = feature id, value = changed geometry
911#ifndef SIP_RUN
912typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
913#else
914typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
915#endif
916
917typedef QList<QgsFeature> QgsFeatureList;
918
919uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
920
923
924#endif
Abstract base class for all geometries.
A vector of attributes.
Definition: qgsattributes.h:58
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
Container of fields for a vector layer.
Definition: qgsfields.h:45
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
#define str(x)
Definition: qgis.cpp:37
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:227
#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
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:912
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:903
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:413
uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:444
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsFeature &feature)
Reads a feature from stream in into feature. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:430
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917
#define FID_NULL
Definition: qgsfeatureid.h:29
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
const QgsField & field
Definition: qgsfield.h:463