QGIS API Documentation  2.99.0-Master (0a63d1f)
qgsfeature.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeature.cpp - Spatial Feature Implementation
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 #include "qgsfeature.h"
17 #include "qgsfeature_p.h"
18 #include "qgsfields.h"
19 #include "qgsgeometry.h"
20 #include "qgsrectangle.h"
21 
22 #include "qgsmessagelog.h"
23 
24 #include <QDataStream>
25 
26 /***************************************************************************
27  * This class is considered CRITICAL and any change MUST be accompanied with
28  * full unit tests in testqgsfeature.cpp.
29  * See details in QEP #17
30  ****************************************************************************/
31 
32 
34 {
35  QgsAttributeMap map;
36  for ( int idx = 0; idx < count(); ++idx )
37  {
38  QVariant v = at( idx );
39  if ( v.isValid() )
40  map.insert( idx, v );
41  }
42  return map;
43 }
44 
45 //
46 // QgsFeature
47 //
48 
50 {
51  d = new QgsFeaturePrivate( id );
52 }
53 
55 {
56  d = new QgsFeaturePrivate( id );
57  d->fields = fields;
58  initAttributes( d->fields.count() );
59 }
60 
62  : d( rhs.d )
63 {
64 }
65 
67 {
68  d = rhs.d;
69  return *this;
70 }
71 
72 bool QgsFeature::operator ==( const QgsFeature& other ) const
73 {
74  if ( d == other.d )
75  return true;
76 
77  if ( d->fid == other.d->fid
78  && d->valid == other.d->valid
79  && d->fields == other.d->fields
80  && d->attributes == other.d->attributes
81  && d->geometry.equals( other.d->geometry ) )
82  return true;
83 
84  return false;
85 }
86 
87 bool QgsFeature::operator!=( const QgsFeature& other ) const
88 {
89  return !( *this == other );
90 }
91 
93 {
94 }
95 
96 /***************************************************************************
97  * This class is considered CRITICAL and any change MUST be accompanied with
98  * full unit tests in testqgsfeature.cpp.
99  * See details in QEP #17
100  ****************************************************************************/
101 
103 {
104  return d->fid;
105 }
106 
108 {
109  d.detach();
110  d->attributes.remove( field );
111 }
112 
114 {
115  return d->geometry;
116 }
117 
118 /***************************************************************************
119  * This class is considered CRITICAL and any change MUST be accompanied with
120  * full unit tests in testqgsfeature.cpp.
121  * See details in QEP #17
122  ****************************************************************************/
123 
125 {
126  if ( id == d->fid )
127  return;
128 
129  d.detach();
130  d->fid = id;
131 }
132 
134 {
135  return d->attributes;
136 }
137 
139 {
140  if ( attrs == d->attributes )
141  return;
142 
143  d.detach();
144  d->attributes = attrs;
145 }
146 
148 {
149  d.detach();
150  d->geometry = geometry;
151 }
152 
154 {
156 }
157 
158 /***************************************************************************
159  * This class is considered CRITICAL and any change MUST be accompanied with
160  * full unit tests in testqgsfeature.cpp.
161  * See details in QEP #17
162  ****************************************************************************/
163 
164 void QgsFeature::setFields( const QgsFields &fields, bool init )
165 {
166  d.detach();
167  d->fields = fields;
168  if ( init )
169  {
170  initAttributes( d->fields.count() );
171  }
172 }
173 
175 {
176  return d->fields;
177 }
178 
179 /***************************************************************************
180  * This class is considered CRITICAL and any change MUST be accompanied with
181  * full unit tests in testqgsfeature.cpp.
182  * See details in QEP #17
183  ****************************************************************************/
184 
186 {
187  return d->valid;
188 }
189 
190 void QgsFeature::setValid( bool validity )
191 {
192  if ( d->valid == validity )
193  return;
194 
195  d.detach();
196  d->valid = validity;
197 }
198 
200 {
201  return !d->geometry.isEmpty();
202 }
203 
204 void QgsFeature::initAttributes( int fieldCount )
205 {
206  d.detach();
207  d->attributes.resize( fieldCount );
208  QVariant* ptr = d->attributes.data();
209  for ( int i = 0; i < fieldCount; ++i, ++ptr )
210  ptr->clear();
211 }
212 
213 bool QgsFeature::setAttribute( int idx, const QVariant &value )
214 {
215  if ( idx < 0 || idx >= d->attributes.size() )
216  {
217  QgsMessageLog::logMessage( QObject::tr( "Attribute index %1 out of bounds [0;%2]" ).arg( idx ).arg( d->attributes.size() ), QString::null, QgsMessageLog::WARNING );
218  return false;
219  }
220 
221  d.detach();
222  d->attributes[idx] = value;
223  return true;
224 }
225 
226 /***************************************************************************
227  * This class is considered CRITICAL and any change MUST be accompanied with
228  * full unit tests in testqgsfeature.cpp.
229  * See details in QEP #17
230  ****************************************************************************/
231 
232 bool QgsFeature::setAttribute( const QString& name, const QVariant& value )
233 {
234  int fieldIdx = fieldNameIndex( name );
235  if ( fieldIdx == -1 )
236  return false;
237 
238  d.detach();
239  d->attributes[fieldIdx] = value;
240  return true;
241 }
242 
243 bool QgsFeature::deleteAttribute( const QString& name )
244 {
245  int fieldIdx = fieldNameIndex( name );
246  if ( fieldIdx == -1 )
247  return false;
248 
249  d.detach();
250  d->attributes[fieldIdx].clear();
251  return true;
252 }
253 
254 QVariant QgsFeature::attribute( int fieldIdx ) const
255 {
256  if ( fieldIdx < 0 || fieldIdx >= d->attributes.count() )
257  return QVariant();
258 
259  return d->attributes.at( fieldIdx );
260 }
261 
262 QVariant QgsFeature::attribute( const QString& name ) const
263 {
264  int fieldIdx = fieldNameIndex( name );
265  if ( fieldIdx == -1 )
266  return QVariant();
267 
268  return d->attributes.at( fieldIdx );
269 }
270 
271 /***************************************************************************
272  * This class is considered CRITICAL and any change MUST be accompanied with
273  * full unit tests in testqgsfeature.cpp.
274  * See details in QEP #17
275  ****************************************************************************/
276 
277 int QgsFeature::fieldNameIndex( const QString& fieldName ) const
278 {
279  return d->fields.lookupField( fieldName );
280 }
281 
282 /***************************************************************************
283  * This class is considered CRITICAL and any change MUST be accompanied with
284  * full unit tests in testqgsfeature.cpp.
285  * See details in QEP #17
286  ****************************************************************************/
287 
288 QDataStream& operator<<( QDataStream& out, const QgsFeature& feature )
289 {
290  out << feature.id();
291  out << feature.attributes();
292  if ( feature.hasGeometry() )
293  {
294  out << ( feature.geometry() );
295  }
296  else
297  {
299  out << geometry;
300  }
301  out << feature.isValid();
302  return out;
303 }
304 
305 QDataStream& operator>>( QDataStream& in, QgsFeature& feature )
306 {
309  bool valid;
310  QgsAttributes attr;
311  in >> id >> attr >> geometry >> valid;
312  feature.setId( id );
313  feature.setGeometry( geometry );
314  feature.setAttributes( attr );
315  feature.setValid( valid );
316  return in;
317 }
318 
319 uint qHash( const QgsFeature& key, uint seed )
320 {
321  uint hash = seed;
322  Q_FOREACH ( const QVariant& attr, key.attributes() )
323  {
324  hash ^= qHash( attr.toString() );
325  }
326 
327  hash ^= qHash( key.geometry().exportToWkt() );
328  hash ^= qHash( key.id() );
329 
330  return hash;
331 }
332 
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:185
QgsFeatureId id
Definition: qgsfeature.h:140
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
QgsFields fields() const
Returns the field map associated with the feature.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Definition: qgsfeature.cpp:164
QMap< int, QVariant > QgsAttributeMap
Definition: qgsfeature.h:45
virtual ~QgsFeature()
Definition: qgsfeature.cpp:92
QgsFeature & operator=(const QgsFeature &rhs)
Assignment operator.
Definition: qgsfeature.cpp:66
bool operator!=(const QgsFeature &other) const
Compares two features.
Definition: qgsfeature.cpp:87
uint qHash(const QgsFeature &key, uint seed)
Definition: qgsfeature.cpp:319
Container of fields for a vector layer.
Definition: qgsfields.h:39
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:79
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:138
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:213
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:136
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
QDataStream & operator>>(QDataStream &in, QgsFeature &feature)
Reads a feature from stream in into feature. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:305
void deleteAttribute(int field)
Deletes an attribute and its value.
Definition: qgsfeature.cpp:107
QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:288
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:204
void seed(uint32_t value)
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
Definition: qgsfeature.cpp:33
QString exportToWkt(int precision=17) const
Exports the geometry to WKT.
void setId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:124
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:113
QgsFeature(QgsFeatureId id=QgsFeatureId())
Constructor for QgsFeature.
Definition: qgsfeature.cpp:49
bool operator==(const QgsFeature &other) const
Compares two features.
Definition: qgsfeature.cpp:72
QgsFeatureId id() const
Get the feature ID for this feature.
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:190
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
Definition: qgsfeature.cpp:277
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:153
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:147
qint64 QgsFeatureId
Definition: qgsfeature.h:33
A vector of attributes.
Definition: qgsfeature.h:56
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
QgsAttributes attributes
Definition: qgsfeature.h:141