QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
173 long __hash__() const;
174 % MethodCode
175 sipRes = qHash( *sipCpp );
176 % End
177#endif
178
183#ifndef SIP_RUN
185#else
186 QgsFeature( qint64 id = FID_NULL );
187#endif
188
194#ifndef SIP_RUN
195 QgsFeature( const QgsFields &fields, QgsFeatureId id = FID_NULL );
196#else
197 QgsFeature( const QgsFields &fields, qint64 id = FID_NULL );
198#endif
199
203 QgsFeature( const QgsFeature &rhs );
204
208 QgsFeature &operator=( const QgsFeature &rhs );
209
213 bool operator==( const QgsFeature &other ) const;
214
218 bool operator!=( const QgsFeature &other ) const;
219
220 virtual ~QgsFeature();
221
226 QgsFeatureId id() const;
227
236 void setId( QgsFeatureId id );
237
255 QgsAttributes attributes() const;
256
257#ifndef SIP_RUN
258
268 QVariantMap attributeMap() const;
269#else
270
282 SIP_PYOBJECT attributeMap() const SIP_TYPEHINT( Dict[str, Optional[object]] );
283 % MethodCode
284 const int fieldSize = sipCpp->fields().size();
285 const int attributeSize = sipCpp->attributes().size();
286 if ( fieldSize == 0 && attributeSize != 0 )
287 {
288 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
289 sipIsErr = 1;
290 }
291 else if ( fieldSize != attributeSize )
292 {
293 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
294 sipIsErr = 1;
295 }
296 else
297 {
298 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
299 sipRes = sipConvertFromNewType( v, sipType_QVariantMap, Py_None );
300 }
301 % End
302#endif
303
308 int attributeCount() const;
309
326 void setAttributes( const QgsAttributes &attrs );
327
328#ifndef SIP_RUN
329
340 bool setAttribute( int field, const QVariant &attr );
341#else
342
367 bool setAttribute( int field, const QVariant &attr / GetWrapper / );
368 % MethodCode
369 bool rv;
370
371 if ( a1Wrapper == Py_None )
372 {
373 rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
374 }
375 else
376 {
377 rv = sipCpp->setAttribute( a0, *a1 );
378 }
379
380 if ( !rv )
381 {
382 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
383 sipIsErr = 1;
384 }
385
386 sipRes = rv;
387 % End
388#endif
389
399 void initAttributes( int fieldCount );
400
414 void resizeAttributes( int fieldCount );
415
422 void padAttributes( int count );
423
424#ifndef SIP_RUN
425
433 void deleteAttribute( int field );
434#else
435
460 void deleteAttribute( int field );
461 % MethodCode
462 if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
463 sipCpp->deleteAttribute( a0 );
464 else
465 {
466 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
467 sipIsErr = 1;
468 }
469 % End
470#endif
471
480 bool isValid() const;
481
489 void setValid( bool validity );
490
496 bool hasGeometry() const;
497
504 QgsGeometry geometry() const;
505
515 void setGeometry( const QgsGeometry &geometry );
516
547#ifndef SIP_RUN
548 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
549#else
550 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER );
551 % MethodCode
552 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
553 % End
554#endif
555
562 void clearGeometry();
563
571 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) );
572
577 QgsFields fields() const;
578
579#ifndef SIP_RUN
580
595 bool setAttribute( const QString &name, const QVariant &value );
596#else
597
626 void setAttribute( const QString &name, const QVariant &value / GetWrapper / );
627 % MethodCode
628 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
629 if ( fieldIdx == -1 )
630 {
631 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
632 sipIsErr = 1;
633 }
634 else
635 {
636 if ( a1Wrapper == Py_None )
637 {
638 sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
639 }
640 else
641 {
642 sipCpp->setAttribute( fieldIdx, *a1 );
643 }
644 }
645 % End
646#endif
647
648#ifndef SIP_RUN
649
659 bool deleteAttribute( const QString &name );
660#else
661
691 bool deleteAttribute( const QString &name );
692 % MethodCode
693 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
694 if ( fieldIdx == -1 )
695 {
696 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
697 sipIsErr = 1;
698 sipRes = false;
699 }
700 else
701 {
702 sipCpp->deleteAttribute( fieldIdx );
703 sipRes = true;
704 }
705 % End
706#endif
707
708#ifndef SIP_RUN
709
719 QVariant attribute( const QString &name ) const;
720#else
721
747 SIP_PYOBJECT attribute( const QString &name ) const;
748 % MethodCode
749 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
750 if ( fieldIdx == -1 )
751 {
752 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
753 sipIsErr = 1;
754 }
755 else
756 {
757 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
758 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
759 }
760 % End
761#endif
762
763#ifndef SIP_RUN
764
772 QVariant attribute( int fieldIdx ) const;
773#else
774
799 SIP_PYOBJECT attribute( int fieldIdx ) const;
800 % MethodCode
801 {
802 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
803 {
804 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
805 sipIsErr = 1;
806 }
807 else
808 {
809 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
810 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
811 }
812 }
813 % End
814#endif
815
816
817#ifndef SIP_RUN
818
825 bool isUnsetValue( int fieldIdx ) const;
826#else
827
835 bool isUnsetValue( int fieldIdx ) const;
836 % MethodCode
837 {
838 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
839 {
840 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
841 sipIsErr = 1;
842 }
843 else
844 {
845 sipRes = sipCpp->isUnsetValue( a0 );
846 }
847 }
848 % End
849#endif
850
856 const QgsSymbol *embeddedSymbol() const;
857
865 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER );
866
876 int fieldNameIndex( const QString &fieldName ) const;
877
887 int approximateMemoryUsage() const;
888
890 operator QVariant() const
891 {
892 return QVariant::fromValue( *this );
893 }
894
895 private:
896
897 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
898
899}; // class QgsFeature
900
902CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
904CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
905
906// key = feature id, value = changed attributes
907#ifndef SIP_RUN
908typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
909#else
910typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
911#endif
912
913#include "qgsgeometry.h"
914
915// key = feature id, value = changed geometry
916#ifndef SIP_RUN
917typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
918#else
919typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
920#endif
921
922typedef QList<QgsFeature> QgsFeatureList;
923
924CORE_EXPORT uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
925
928
929#endif
Abstract base class for all geometries.
A vector of attributes.
Definition: qgsattributes.h:59
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:164
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:917
CORE_EXPORT uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:447
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:908
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:416
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:433
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:922
#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