QGIS API Documentation  3.17.0-Master (eba9ffa46e)
qgsfeature.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeature.h - Spatial Feature Class
3  --------------------------------------
4 Date : 09-Sep-2003
5 Copyright : (C) 2003 by Gary E.Sherman
6 email : 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>
34 class QgsFeature;
35 class QgsFeaturePrivate;
36 class QgsField;
37 class QgsGeometry;
38 class QgsRectangle;
40 
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 
55 class 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 ) SIP_SKIP;
204 
208  bool operator==( const QgsFeature &other ) const SIP_SKIP;
209 
213  bool operator!=( const QgsFeature &other ) const SIP_SKIP;
214 
215  virtual ~QgsFeature();
216 
222  QgsFeatureId id() const;
223 
229  void setId( QgsFeatureId id );
230 
238  QgsAttributes attributes() const;
239 
244  int attributeCount() const;
245 
253  void setAttributes( const QgsAttributes &attrs );
254 
265 #ifndef SIP_RUN
266  bool setAttribute( int field, const QVariant &attr );
267 #else
268  bool setAttribute( int field, const QVariant &attr / GetWrapper / );
269  % MethodCode
270  bool rv;
271 
272  if ( a1Wrapper == Py_None )
273  {
274  rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
275  }
276  else
277  {
278  rv = sipCpp->setAttribute( a0, *a1 );
279  }
280 
281  if ( !rv )
282  {
283  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
284  sipIsErr = 1;
285  }
286 
287  sipRes = rv;
288  % End
289 #endif
290 
297  void initAttributes( int fieldCount );
298 
312  void resizeAttributes( int fieldCount );
313 
320  void padAttributes( int count );
321 
329  void deleteAttribute( int field );
330 #ifdef SIP_RUN
331  % MethodCode
332  if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
333  sipCpp->deleteAttribute( a0 );
334  else
335  {
336  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
337  sipIsErr = 1;
338  }
339  % End
340 #endif
341 
348  bool isValid() const;
349 
355  void setValid( bool validity );
356 
362  bool hasGeometry() const;
363 
370  QgsGeometry geometry() const;
371 
378  void setGeometry( const QgsGeometry &geometry );
379 
407 #ifndef SIP_RUN
408  void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry );
409 #else
410  void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER );
411  % MethodCode
412  sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
413  % End
414 #endif
415 
422  void clearGeometry();
423 
433  void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) );
434 
439  QgsFields fields() const;
440 
452 #ifndef SIP_RUN
453  bool setAttribute( const QString &name, const QVariant &value );
454 #else
455  void setAttribute( const QString &name, const QVariant &value / GetWrapper / );
456  % MethodCode
457  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
458  if ( fieldIdx == -1 )
459  {
460  PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
461  sipIsErr = 1;
462  }
463  else
464  {
465  if ( a1Wrapper == Py_None )
466  {
467  sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
468  }
469  else
470  {
471  sipCpp->setAttribute( fieldIdx, *a1 );
472  }
473  }
474  % End
475 #endif
476 
486  bool deleteAttribute( const QString &name );
487 #ifdef SIP_RUN
488  % MethodCode
489  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
490  if ( fieldIdx == -1 )
491  {
492  PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
493  sipIsErr = 1;
494  sipRes = false;
495  }
496  else
497  {
498  sipCpp->deleteAttribute( fieldIdx );
499  sipRes = true;
500  }
501  % End
502 #endif
503 
513 #ifndef SIP_RUN
514  QVariant attribute( const QString &name ) const;
515 #else
516  SIP_PYOBJECT attribute( const QString &name ) const;
517  % MethodCode
518  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
519  if ( fieldIdx == -1 )
520  {
521  PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
522  sipIsErr = 1;
523  }
524  else
525  {
526  QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
527  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
528  }
529  % End
530 #endif
531 
541 #ifndef SIP_RUN
542  QVariant attribute( int fieldIdx ) const;
543 #else
544  SIP_PYOBJECT attribute( int fieldIdx ) const;
545  % MethodCode
546  {
547  if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
548  {
549  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
550  sipIsErr = 1;
551  }
552  else
553  {
554  QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
555  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
556  }
557  }
558  % End
559 #endif
560 
568  int fieldNameIndex( const QString &fieldName ) const;
569 
579  int approximateMemoryUsage() const;
580 
582  operator QVariant() const
583  {
584  return QVariant::fromValue( *this );
585  }
586 
587  private:
588 
589  QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
590 
591 }; // class QgsFeature
592 
594 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
596 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
597 
598 // key = feature id, value = changed attributes
599 #ifndef SIP_RUN
600 typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
601 #else
602 typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
603 #endif
604 
605 #include "qgsgeometry.h"
606 
607 // key = feature id, value = changed geometry
608 #ifndef SIP_RUN
609 typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
610 #else
611 typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
612 #endif
613 
614 typedef QList<QgsFeature> QgsFeatureList;
615 
616 uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
617 
619 Q_DECLARE_METATYPE( QgsFeatureList )
620 
621 #endif
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:609
A rectangle specified with double values.
Definition: qgsrectangle.h:41
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
#define FID_NULL
Definition: qgsfeatureid.h:29
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:614
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features ...
Definition: qgsfeatureid.h:28
Container of fields for a vector layer.
Definition: qgsfields.h:44
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:49
Abstract base class for all geometries.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:600
uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:396
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:382
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:365
A vector of attributes.
Definition: qgsattributes.h:57
#define SIP_PYARGDEFAULT(value)
Definition: qgis_sip.h:141
const QgsField & field
Definition: qgsfield.h:471