QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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
624 void setAttribute( const QString &name, const QVariant &value / GetWrapper / );
625 % MethodCode
626 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
627 if ( fieldIdx == -1 )
628 {
629 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
630 sipIsErr = 1;
631 }
632 else
633 {
634 if ( a1Wrapper == Py_None )
635 {
636 sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
637 }
638 else
639 {
640 sipCpp->setAttribute( fieldIdx, *a1 );
641 }
642 }
643 % End
644#endif
645
646#ifndef SIP_RUN
647
657 bool deleteAttribute( const QString &name );
658#else
659
689 bool deleteAttribute( const QString &name );
690 % MethodCode
691 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
692 if ( fieldIdx == -1 )
693 {
694 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
695 sipIsErr = 1;
696 sipRes = false;
697 }
698 else
699 {
700 sipCpp->deleteAttribute( fieldIdx );
701 sipRes = true;
702 }
703 % End
704#endif
705
706#ifndef SIP_RUN
707
717 QVariant attribute( const QString &name ) const;
718#else
719
745 SIP_PYOBJECT attribute( const QString &name ) const;
746 % MethodCode
747 int fieldIdx = sipCpp->fieldNameIndex( *a0 );
748 if ( fieldIdx == -1 )
749 {
750 PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
751 sipIsErr = 1;
752 }
753 else
754 {
755 QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
756 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
757 }
758 % End
759#endif
760
761#ifndef SIP_RUN
762
770 QVariant attribute( int fieldIdx ) const;
771#else
772
797 SIP_PYOBJECT attribute( int fieldIdx ) const;
798 % MethodCode
799 {
800 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
801 {
802 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
803 sipIsErr = 1;
804 }
805 else
806 {
807 QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
808 sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
809 }
810 }
811 % End
812#endif
813
814
815#ifndef SIP_RUN
816
823 bool isUnsetValue( int fieldIdx ) const;
824#else
825
833 bool isUnsetValue( int fieldIdx ) const;
834 % MethodCode
835 {
836 if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
837 {
838 PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
839 sipIsErr = 1;
840 }
841 else
842 {
843 sipRes = sipCpp->isUnsetValue( a0 );
844 }
845 }
846 % End
847#endif
848
854 const QgsSymbol *embeddedSymbol() const;
855
863 void setEmbeddedSymbol( QgsSymbol *symbol SIP_TRANSFER );
864
874 int fieldNameIndex( const QString &fieldName ) const;
875
885 int approximateMemoryUsage() const;
886
888 operator QVariant() const
889 {
890 return QVariant::fromValue( *this );
891 }
892
893 private:
894
895 QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
896
897}; // class QgsFeature
898
900CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
902CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
903
904// key = feature id, value = changed attributes
905#ifndef SIP_RUN
906typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
907#else
908typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
909#endif
910
911#include "qgsgeometry.h"
912
913// key = feature id, value = changed geometry
914#ifndef SIP_RUN
915typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
916#else
917typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
918#endif
919
920typedef QList<QgsFeature> QgsFeatureList;
921
922CORE_EXPORT uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
923
926
927#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:53
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:94
#define str(x)
Definition: qgis.cpp:38
#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:915
CORE_EXPORT uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:444
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:906
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
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:920
#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:554