QGIS API Documentation  2.99.0-Master (f867b65)
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.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 
33 class QgsFeature;
34 class QgsFeaturePrivate;
35 class QgsField;
36 class QgsGeometry;
38 
39 
40 /***************************************************************************
41  * This class is considered CRITICAL and any change MUST be accompanied with
42  * full unit tests in testqgsfeature.cpp.
43  * See details in QEP #17
44  ****************************************************************************/
45 
46 // feature id class (currently 64 bit)
47 
48 // 64 bit feature ids
49 typedef qint64 QgsFeatureId SIP_SKIP;
50 #define FID_IS_NEW(fid) (fid<0)
51 #define FID_TO_NUMBER(fid) static_cast<qint64>(fid)
52 #define FID_TO_STRING(fid) QString::number( fid )
53 #define STRING_TO_FID(str) (str).toLongLong()
54 
55 
61 class CORE_EXPORT QgsFeature
62 {
63 #ifdef SIP_RUN
64 #if (SIP_VERSION >= 0x040900 && SIP_VERSION < 0x040c01)
65 #define sipType_QVariant ((sipWrapperType *) sipTypeAsPyTypeObject (sipType_QVariant))
66 #endif
67 #endif
68  Q_GADGET
69 
70  Q_PROPERTY( QgsFeatureId id READ id WRITE setId )
71  Q_PROPERTY( QgsAttributes attributes READ attributes WRITE setAttributes )
72  Q_PROPERTY( QgsFields fields READ fields WRITE setFields )
73 
74  public:
75 
76 #ifdef SIP_RUN
77  SIP_PYOBJECT __iter__();
78  % MethodCode
79  QgsAttributes attributes = sipCpp->attributes();
80  PyObject *attrs = sipConvertFromType( &attributes, sipType_QgsAttributes, Py_None );
81  sipRes = PyObject_GetIter( attrs );
82  % End
83 
84  SIP_PYOBJECT __getitem__( int key );
85  % MethodCode
86  QgsAttributes attrs = sipCpp->attributes();
87  if ( a0 < 0 || a0 >= attrs.count() )
88  {
89  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
90  sipIsErr = 1;
91  }
92  else
93  {
94  QVariant *v = new QVariant( attrs.at( a0 ) );
95  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
96  }
97  % End
98 
99  SIP_PYOBJECT __getitem__( const QString &name );
100  % MethodCode
101  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
102  if ( fieldIdx == -1 )
103  {
104  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
105  sipIsErr = 1;
106  }
107  else
108  {
109  QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
110  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
111  }
112  % End
113 
114  void __setitem__( int key, QVariant value / GetWrapper / );
115  % MethodCode
116  bool rv;
117 
118  if ( a1Wrapper == Py_None )
119  {
120  rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
121  }
122  else
123  {
124  rv = sipCpp->setAttribute( a0, *a1 );
125  }
126 
127  if ( !rv )
128  {
129  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
130  sipIsErr = 1;
131  }
132  % End
133 
134  void __setitem__( const QString &key, QVariant value / GetWrapper / );
135  % MethodCode
136  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
137  if ( fieldIdx == -1 )
138  {
139  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
140  sipIsErr = 1;
141  }
142  else
143  {
144  if ( a1Wrapper == Py_None )
145  {
146  sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
147  }
148  else
149  {
150  sipCpp->setAttribute( fieldIdx, *a1 );
151  }
152  }
153  % End
154 
155  void __delitem__( int key );
156  % MethodCode
157  if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
158  sipCpp->deleteAttribute( a0 );
159  else
160  {
161  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
162  sipIsErr = 1;
163  }
164  % End
165 
166  void __delitem__( const QString &name );
167  % MethodCode
168  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
169  if ( fieldIdx == -1 )
170  {
171  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
172  sipIsErr = 1;
173  }
174  else
175  sipCpp->deleteAttribute( fieldIdx );
176  % End
177 #endif
178 
182 #ifndef SIP_RUN
184 #else
185  QgsFeature( qint64 id = 0 );
186 #endif
187 
192 #ifndef SIP_RUN
193  QgsFeature( const QgsFields &fields, QgsFeatureId id = QgsFeatureId() );
194 #else
195  QgsFeature( const QgsFields &fields, qint64 id = 0 );
196 #endif
197 
200  QgsFeature( const QgsFeature &rhs );
201 
204  QgsFeature &operator=( const QgsFeature &rhs ) SIP_SKIP;
205 
209  bool operator==( const QgsFeature &other ) const SIP_SKIP;
210 
214  bool operator!=( const QgsFeature &other ) const SIP_SKIP;
215 
216  virtual ~QgsFeature();
217 
222  QgsFeatureId id() const;
223 
228  void setId( QgsFeatureId id );
229 
236  QgsAttributes attributes() const;
237 
244  void setAttributes( const QgsAttributes &attrs );
245 
255 #ifndef SIP_RUN
256  bool setAttribute( int field, const QVariant &attr );
257 #else
258  bool setAttribute( int field, const QVariant &attr / GetWrapper / );
259  % MethodCode
260  bool rv;
261 
262  if ( a1Wrapper == Py_None )
263  {
264  rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
265  }
266  else
267  {
268  rv = sipCpp->setAttribute( a0, *a1 );
269  }
270 
271  if ( !rv )
272  {
273  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
274  sipIsErr = 1;
275  }
276 
277  sipRes = rv;
278  % End
279 #endif
280 
284  void initAttributes( int fieldCount );
285 
292  void deleteAttribute( int field );
293 #ifdef SIP_RUN
294  % MethodCode
295  if ( a0 >= 0 && a0 < sipCpp->attributes().count() )
296  sipCpp->deleteAttribute( a0 );
297  else
298  {
299  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
300  sipIsErr = 1;
301  }
302  % End
303 #endif
304 
310  bool isValid() const;
311 
316  void setValid( bool validity );
317 
322  bool hasGeometry() const;
323 
329  QgsGeometry geometry() const;
330 
336  void setGeometry( const QgsGeometry &geometry );
337 
343  void clearGeometry();
344 
353  void setFields( const QgsFields &fields, bool initAttributes = false SIP_PYARGDEFAULT( true ) );
354 
358  QgsFields fields() const;
359 
370 #ifndef SIP_RUN
371  bool setAttribute( const QString &name, const QVariant &value );
372 #else
373  void setAttribute( const QString &name, const QVariant &value / GetWrapper / );
374  % MethodCode
375  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
376  if ( fieldIdx == -1 )
377  {
378  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
379  sipIsErr = 1;
380  }
381  else
382  {
383  if ( a1Wrapper == Py_None )
384  {
385  sipCpp->setAttribute( *a0, QVariant( QVariant::Int ) );
386  }
387  else
388  {
389  sipCpp->setAttribute( fieldIdx, *a1 );
390  }
391  }
392  % End
393 #endif
394 
403  bool deleteAttribute( const QString &name );
404 #ifdef SIP_RUN
405  % MethodCode
406  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
407  if ( fieldIdx == -1 )
408  {
409  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
410  sipIsErr = 1;
411  sipRes = false;
412  }
413  else
414  {
415  sipCpp->deleteAttribute( fieldIdx );
416  sipRes = true;
417  }
418  % End
419 #endif
420 
429 #ifndef SIP_RUN
430  QVariant attribute( const QString &name ) const;
431 #else
432  SIP_PYOBJECT attribute( const QString &name ) const;
433  % MethodCode
434  int fieldIdx = sipCpp->fieldNameIndex( *a0 );
435  if ( fieldIdx == -1 )
436  {
437  PyErr_SetString( PyExc_KeyError, a0->toAscii() );
438  sipIsErr = 1;
439  }
440  else
441  {
442  QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
443  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
444  }
445  % End
446 #endif
447 
456 #ifndef SIP_RUN
457  QVariant attribute( int fieldIdx ) const;
458 #else
459  SIP_PYOBJECT attribute( int fieldIdx ) const;
460  % MethodCode
461  {
462  if ( a0 < 0 || a0 >= sipCpp->attributes().count() )
463  {
464  PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
465  sipIsErr = 1;
466  }
467  else
468  {
469  QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
470  sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
471  }
472  }
473  % End
474 #endif
475 
482  int fieldNameIndex( const QString &fieldName ) const;
483 
485  operator QVariant() const
486  {
487  return QVariant::fromValue( *this );
488  }
489 
490  private:
491 
492  QExplicitlySharedDataPointer<QgsFeaturePrivate> d;
493 
494 }; // class QgsFeature
495 
497 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsFeature &feature ) SIP_SKIP;
499 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsFeature &feature ) SIP_SKIP;
500 
501 // key = feature id, value = changed attributes
502 #ifndef SIP_RUN
503 typedef QMap<QgsFeatureId, QgsAttributeMap> QgsChangedAttributesMap;
504 #else
505 typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
506 #endif
507 
508 #include "qgsgeometry.h"
509 
510 // key = feature id, value = changed geometry
511 #ifndef SIP_RUN
512 typedef QMap<QgsFeatureId, QgsGeometry> QgsGeometryMap;
513 #else
514 typedef QMap<qint64, QgsGeometry> QgsGeometryMap;
515 #endif
516 
517 
518 #ifndef SIP_RUN
519 typedef QSet<QgsFeatureId> QgsFeatureIds;
520 #else
521 typedef QSet<qint64> QgsFeatureIds;
522 #endif
523 
524 typedef QList<QgsFeature> QgsFeatureList;
525 
526 uint qHash( const QgsFeature &key, uint seed = 0 ) SIP_SKIP;
527 
529 Q_DECLARE_METATYPE( QgsFeatureList )
530 
531 #endif
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:512
A rectangle specified with double values.
Definition: qgsrectangle.h:38
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:519
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:524
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
Container of fields for a vector layer.
Definition: qgsfields.h:41
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:96
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:61
Q_DECLARE_METATYPE(QModelIndex)
#define SIP_SKIP
Definition: qgis_sip.h:119
void seed(uint32_t value)
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:46
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:503
uint qHash(const QgsFeature &key, uint seed=0)
Definition: qgsfeature.cpp:312
qint64 QgsFeatureId
Definition: qgsfeature.h:37
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:298
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:281
A vector of attributes.
Definition: qgsattributes.h:57
#define SIP_PYARGDEFAULT(value)
Definition: qgis_sip.h:134