QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
254 QgsAttributes attributes() const;
255
256#ifndef SIP_RUN
257
267 QVariantMap attributeMap() const;
268#else
269
281 SIP_PYOBJECT attributeMap() const SIP_TYPEHINT( Dict[str, Optional[object]] );
282 % MethodCode
283 const int fieldSize = sipCpp->fields().size();
284 const int attributeSize = sipCpp->attributes().size();
285 if ( fieldSize == 0 && attributeSize != 0 )
286 {
287 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
288 sipIsErr = 1;
289 }
290 else if ( fieldSize != attributeSize )
291 {
292 PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
293 sipIsErr = 1;
294 }
295 else
296 {
297 QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
298 const sipTypeDef *qvariantmap_type = sipFindType( "QMap<QString,QVariant>" );
299 sipRes = sipConvertFromNewType( v, qvariantmap_type, 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
495 bool hasGeometry() const;
496
503 QgsGeometry geometry() const;
504
514 void setGeometry( const QgsGeometry &geometry );
515
546#ifndef SIP_RUN
547 void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
548#else
549 void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER );
550 % MethodCode
551 sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
552 % End
553#endif
554
560 void clearGeometry();
561
568 void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) );
569
574 QgsFields fields() const;
575
576#ifndef SIP_RUN
577
592 bool setAttribute( const QString &name, const QVariant &value );
593#else
594
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
919CORE_EXPORT uint 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: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:162
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: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
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:912
CORE_EXPORT uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:444
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
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)