Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsattributes.h - QgsAttributes 3 : : 4 : : --------------------- 5 : : begin : 29.3.2017 6 : : copyright : (C) 2017 by Denis Rouzaud 7 : : email : denis.rouzaud@gmail.com 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 : : 35 : : 36 : : class QgsRectangle; 37 : : class QgsFeature; 38 : : class QgsFeaturePrivate; 39 : : 40 : : // key = field index, value = field value 41 : : typedef QMap<int, QVariant> QgsAttributeMap; 42 : : 43 : : // key = field index, value = field name 44 : : typedef QMap<int, QString> QgsFieldNameMap; 45 : : 46 : : #ifdef SIP_RUN 47 : : typedef QMap<int, QgsField> QgsFieldMap; 48 : : #endif 49 : : 50 : : 51 : : /** 52 : : * \ingroup core 53 : : * \brief A vector of attributes. Mostly equal to QVector<QVariant>. 54 : : * \note QgsAttributes is implemented as a Python list of Python objects. 55 : : */ 56 : : #ifndef SIP_RUN 57 : 4327 : class QgsAttributes : public QVector<QVariant> 58 : : { 59 : : public: 60 : : 61 : : //! Constructor for QgsAttributes 62 : 2108 : QgsAttributes() = default; 63 : : 64 : : /** 65 : : * Create a new vector of attributes with the given size 66 : : * 67 : : * \param size Number of attributes 68 : : */ 69 : 0 : QgsAttributes( int size ) 70 : 0 : : QVector<QVariant>( size ) 71 : 0 : {} 72 : : 73 : : /** 74 : : * Constructs a vector with an initial size of size elements. Each element is initialized with value. 75 : : * \param size Number of elements 76 : : * \param v Initial value 77 : : */ 78 : : QgsAttributes( int size, const QVariant &v ) 79 : : : QVector<QVariant>( size, v ) 80 : : {} 81 : : 82 : : /** 83 : : * Copies another vector of attributes 84 : : * \param v Attributes to copy 85 : : */ 86 : 0 : QgsAttributes( const QVector<QVariant> &v ) 87 : 0 : : QVector<QVariant>( v ) 88 : 0 : {} 89 : : 90 : : /** 91 : : * \brief Compares two vectors of attributes. 92 : : * They are considered equal if all their members contain the same value and NULL flag. 93 : : * This was introduced because the default Qt implementation of QVariant comparison does not 94 : : * handle NULL values for certain types (like int). 95 : : * 96 : : * \param v The attributes to compare 97 : : * \returns TRUE if v is equal 98 : : */ 99 : 2 : bool operator==( const QgsAttributes &v ) const 100 : : { 101 : 2 : if ( size() != v.size() ) 102 : 2 : return false; 103 : 0 : const QVariant *b = constData(); 104 : 0 : const QVariant *i = b + size(); 105 : 0 : const QVariant *j = v.constData() + size(); 106 : : 107 : : // note that for non-null values, we need to check that the type is equal too! 108 : : // QVariant == comparisons do some weird things, like reporting that a QDateTime(2021, 2, 10, 0, 0) variant is equal 109 : : // to a QString "2021-02-10 00:00" variant! 110 : 0 : while ( i != b ) 111 : 0 : if ( !( ( --i )->isNull() == ( --j )->isNull() && ( i->isNull() || i->type() == j->type() ) && *i == *j ) ) 112 : 0 : return false; 113 : 0 : return true; 114 : 2 : } 115 : : 116 : : /** 117 : : * Returns a QgsAttributeMap of the attribute values. Null values are 118 : : * excluded from the map. 119 : : * \note not available in Python bindings 120 : : * \since QGIS 3.0 121 : : */ 122 : : CORE_EXPORT QgsAttributeMap toMap() const SIP_SKIP; 123 : : 124 : 0 : inline bool operator!=( const QgsAttributes &v ) const { return !( *this == v ); } 125 : : }; 126 : : 127 : : //! Hash for QgsAttributes 128 : : CORE_EXPORT uint qHash( const QgsAttributes &attributes ); 129 : : 130 : : #else 131 : : typedef QVector<QVariant> QgsAttributes; 132 : : 133 : : % MappedType QgsAttributes 134 : : { 135 : : % TypeHeaderCode 136 : : #include "qgsfeature.h" 137 : : % End 138 : : 139 : : % ConvertFromTypeCode 140 : : // Create the list. 141 : : PyObject *l; 142 : : 143 : : if ( ( l = PyList_New( sipCpp->size() ) ) == NULL ) 144 : : return NULL; 145 : : 146 : : // Set the list elements. 147 : : for ( int i = 0; i < sipCpp->size(); ++i ) 148 : : { 149 : : QVariant *v = new QVariant( sipCpp->at( i ) ); 150 : : PyObject *tobj; 151 : : 152 : : if ( ( tobj = sipConvertFromNewType( v, sipType_QVariant, Py_None ) ) == NULL ) 153 : : { 154 : : Py_DECREF( l ); 155 : : delete v; 156 : : 157 : : return NULL; 158 : : } 159 : : 160 : : PyList_SET_ITEM( l, i, tobj ); 161 : : } 162 : : 163 : : return l; 164 : : % End 165 : : 166 : : % ConvertToTypeCode 167 : : // Check the type if that is all that is required. 168 : : if ( sipIsErr == NULL ) 169 : : { 170 : : if ( !PyList_Check( sipPy ) ) 171 : : return 0; 172 : : 173 : : for ( SIP_SSIZE_T i = 0; i < PyList_GET_SIZE( sipPy ); ++i ) 174 : : if ( !sipCanConvertToType( PyList_GET_ITEM( sipPy, i ), sipType_QVariant, SIP_NOT_NONE ) ) 175 : : return 0; 176 : : 177 : : return 1; 178 : : } 179 : : 180 : : QgsAttributes *qv = new QgsAttributes; 181 : : SIP_SSIZE_T listSize = PyList_GET_SIZE( sipPy ); 182 : : qv->reserve( listSize ); 183 : : 184 : : for ( SIP_SSIZE_T i = 0; i < listSize; ++i ) 185 : : { 186 : : PyObject *obj = PyList_GET_ITEM( sipPy, i ); 187 : : if ( obj == Py_None ) 188 : : { 189 : : qv->append( QVariant( QVariant::Int ) ); 190 : : } 191 : : else 192 : : { 193 : : int state; 194 : : QVariant *t = reinterpret_cast<QVariant *>( sipConvertToType( obj, sipType_QVariant, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr ) ); 195 : : 196 : : if ( *sipIsErr ) 197 : : { 198 : : sipReleaseType( t, sipType_QVariant, state ); 199 : : 200 : : delete qv; 201 : : return 0; 202 : : } 203 : : 204 : : qv->append( *t ); 205 : : sipReleaseType( t, sipType_QVariant, state ); 206 : : } 207 : : } 208 : : 209 : : *sipCppPtr = qv; 210 : : 211 : : return sipGetState( sipTransferObj ); 212 : : % End 213 : : }; 214 : : #endif 215 : : 216 : : 217 : : #endif // QGSATTRIBUTES_H