QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsattributes.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributes.h - QgsAttributes
3 
4  ---------------------
5  begin : 29.3.2017
6  copyright : (C) 2017 by Denis Rouzaud
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 
18 #ifndef QGSATTRIBUTES_H
19 #define QGSATTRIBUTES_H
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 
24 #include <QMap>
25 #include <QString>
26 #include <QVariant>
27 #include <QList>
28 #include <QVector>
29 #include <QSet>
30 #include <QExplicitlySharedDataPointer>
31 
32 
33 #include "qgsfields.h"
34 #include "qgsvariantutils.h"
35 
36 
37 class QgsRectangle;
38 class QgsFeature;
39 class QgsFeaturePrivate;
40 
41 // key = field index, value = field value
42 typedef QMap<int, QVariant> QgsAttributeMap;
43 
44 // key = field index, value = field name
45 typedef QMap<int, QString> QgsFieldNameMap;
46 
47 #ifdef SIP_RUN
48 typedef QMap<int, QgsField> QgsFieldMap;
49 #endif
50 
51 
57 #ifndef SIP_RUN
58 class QgsAttributes : public QVector<QVariant>
59 {
60  public:
61 
63  QgsAttributes() = default;
64 
70  QgsAttributes( int size )
71  : QVector<QVariant>( size )
72  {}
73 
79  QgsAttributes( int size, const QVariant &v )
80  : QVector<QVariant>( size, v )
81  {}
82 
87  QgsAttributes( const QVector<QVariant> &v )
88  : QVector<QVariant>( v )
89  {}
90 
100  bool operator==( const QgsAttributes &v ) const
101  {
102  if ( size() != v.size() )
103  return false;
104  const QVariant *b = constData();
105  const QVariant *i = b + size();
106  const QVariant *j = v.constData() + size();
107 
108  // note that for non-null values, we need to check that the type is equal too!
109  // QVariant == comparisons do some weird things, like reporting that a QDateTime(2021, 2, 10, 0, 0) variant is equal
110  // to a QString "2021-02-10 00:00" variant!
111  while ( i != b )
112  if ( !( QgsVariantUtils::isNull( *( --i ) ) == QgsVariantUtils::isNull( *( --j ) ) && ( QgsVariantUtils::isNull( *i ) || i->type() == j->type() ) && *i == *j ) )
113  return false;
114  return true;
115  }
116 
122  CORE_EXPORT QgsAttributeMap toMap() const SIP_SKIP;
123 
129  bool isUnsetValue( int index ) const
130  {
131  if ( index < 0 || index >= size() )
132  return false;
133 
134  return at( index ).userType() == QMetaType::type( "QgsUnsetAttributeValue" );
135  }
136 
137  inline bool operator!=( const QgsAttributes &v ) const { return !( *this == v ); }
138 };
139 
141 CORE_EXPORT uint qHash( const QgsAttributes &attributes );
142 
143 #else
144 typedef QVector<QVariant> QgsAttributes;
145 
146 % MappedType QgsAttributes
147 {
148  % TypeHeaderCode
149 #include "qgsfeature.h"
150  % End
151 
152  % ConvertFromTypeCode
153  // Create the list.
154  PyObject *l;
155 
156  if ( ( l = PyList_New( sipCpp->size() ) ) == NULL )
157  return NULL;
158 
159  // Set the list elements.
160  for ( int i = 0; i < sipCpp->size(); ++i )
161  {
162  QVariant *v = new QVariant( sipCpp->at( i ) );
163  PyObject *tobj;
164 
165  if ( ( tobj = sipConvertFromNewType( v, sipType_QVariant, Py_None ) ) == NULL )
166  {
167  Py_DECREF( l );
168  delete v;
169 
170  return NULL;
171  }
172 
173  PyList_SET_ITEM( l, i, tobj );
174  }
175 
176  return l;
177  % End
178 
179  % ConvertToTypeCode
180  // Check the type if that is all that is required.
181  if ( sipIsErr == NULL )
182  {
183  if ( !PyList_Check( sipPy ) )
184  return 0;
185 
186  for ( SIP_SSIZE_T i = 0; i < PyList_GET_SIZE( sipPy ); ++i )
187  if ( !sipCanConvertToType( PyList_GET_ITEM( sipPy, i ), sipType_QVariant, SIP_NOT_NONE ) )
188  return 0;
189 
190  return 1;
191  }
192 
193  QgsAttributes *qv = new QgsAttributes;
194  SIP_SSIZE_T listSize = PyList_GET_SIZE( sipPy );
195  qv->reserve( listSize );
196 
197  for ( SIP_SSIZE_T i = 0; i < listSize; ++i )
198  {
199  PyObject *obj = PyList_GET_ITEM( sipPy, i );
200  if ( obj == Py_None )
201  {
202  qv->append( QVariant( QVariant::Int ) );
203  }
204  else
205  {
206  int state;
207  QVariant *t = reinterpret_cast<QVariant *>( sipConvertToType( obj, sipType_QVariant, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr ) );
208 
209  if ( *sipIsErr )
210  {
211  sipReleaseType( t, sipType_QVariant, state );
212 
213  delete qv;
214  return 0;
215  }
216 
217  qv->append( *t );
218  sipReleaseType( t, sipType_QVariant, state );
219  }
220  }
221 
222  *sipCppPtr = qv;
223 
224  return sipGetState( sipTransferObj );
225  % End
226 };
227 #endif
228 
229 
230 #endif // QGSATTRIBUTES_H
A vector of attributes.
Definition: qgsattributes.h:59
bool operator!=(const QgsAttributes &v) const
QgsAttributes(int size)
Create a new vector of attributes with the given size.
Definition: qgsattributes.h:70
bool isUnsetValue(int index) const
Returns true if the attribute at the specified index is an unset value.
QgsAttributes(int size, const QVariant &v)
Constructs a vector with an initial size of size elements.
Definition: qgsattributes.h:79
bool operator==(const QgsAttributes &v) const
Compares two vectors of attributes.
QgsAttributes()=default
Constructor for QgsAttributes.
QgsAttributes(const QVector< QVariant > &v)
Copies another vector of attributes.
Definition: qgsattributes.h:87
CORE_EXPORT QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
A rectangle specified with double values.
Definition: qgsrectangle.h:42
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define SIP_SKIP
Definition: qgis_sip.h:126
CORE_EXPORT uint qHash(const QgsAttributes &attributes)
Hash for QgsAttributes.
QMap< int, QString > QgsFieldNameMap
Definition: qgsattributes.h:45
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:39