QGIS API Documentation  2.99.0-Master (40f86b2)
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 
61 QgsFeature::QgsFeature( const QgsFeature &rhs ) //NOLINT
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  d->valid = true;
132 }
133 
135 {
136  return d->attributes;
137 }
138 
140 {
141  if ( attrs == d->attributes )
142  return;
143 
144  d.detach();
145  d->attributes = attrs;
146  d->valid = true;
147 }
148 
150 {
151  d.detach();
152  d->geometry = geometry;
153  d->valid = true;
154 }
155 
157 {
159 }
160 
161 /***************************************************************************
162  * This class is considered CRITICAL and any change MUST be accompanied with
163  * full unit tests in testqgsfeature.cpp.
164  * See details in QEP #17
165  ****************************************************************************/
166 
167 void QgsFeature::setFields( const QgsFields &fields, bool init )
168 {
169  d.detach();
170  d->fields = fields;
171  if ( init )
172  {
173  initAttributes( d->fields.count() );
174  }
175 }
176 
178 {
179  return d->fields;
180 }
181 
182 /***************************************************************************
183  * This class is considered CRITICAL and any change MUST be accompanied with
184  * full unit tests in testqgsfeature.cpp.
185  * See details in QEP #17
186  ****************************************************************************/
187 
189 {
190  return d->valid;
191 }
192 
193 void QgsFeature::setValid( bool validity )
194 {
195  if ( d->valid == validity )
196  return;
197 
198  d.detach();
199  d->valid = validity;
200 }
201 
203 {
204  return !d->geometry.isNull();
205 }
206 
207 void QgsFeature::initAttributes( int fieldCount )
208 {
209  d.detach();
210  d->attributes.resize( fieldCount );
211  QVariant *ptr = d->attributes.data();
212  for ( int i = 0; i < fieldCount; ++i, ++ptr )
213  ptr->clear();
214 }
215 
216 bool QgsFeature::setAttribute( int idx, const QVariant &value )
217 {
218  if ( idx < 0 || idx >= d->attributes.size() )
219  {
220  QgsMessageLog::logMessage( QObject::tr( "Attribute index %1 out of bounds [0;%2]" ).arg( idx ).arg( d->attributes.size() ), QString::null, QgsMessageLog::WARNING );
221  return false;
222  }
223 
224  d.detach();
225  d->attributes[idx] = value;
226  d->valid = true;
227  return true;
228 }
229 
230 /***************************************************************************
231  * This class is considered CRITICAL and any change MUST be accompanied with
232  * full unit tests in testqgsfeature.cpp.
233  * See details in QEP #17
234  ****************************************************************************/
235 
236 bool QgsFeature::setAttribute( const QString &name, const QVariant &value )
237 {
238  int fieldIdx = fieldNameIndex( name );
239  if ( fieldIdx == -1 )
240  return false;
241 
242  d.detach();
243  d->attributes[fieldIdx] = value;
244  d->valid = true;
245  return true;
246 }
247 
248 bool QgsFeature::deleteAttribute( const QString &name )
249 {
250  int fieldIdx = fieldNameIndex( name );
251  if ( fieldIdx == -1 )
252  return false;
253 
254  d.detach();
255  d->attributes[fieldIdx].clear();
256  return true;
257 }
258 
259 QVariant QgsFeature::attribute( int fieldIdx ) const
260 {
261  if ( fieldIdx < 0 || fieldIdx >= d->attributes.count() )
262  return QVariant();
263 
264  return d->attributes.at( fieldIdx );
265 }
266 
267 QVariant QgsFeature::attribute( const QString &name ) const
268 {
269  int fieldIdx = fieldNameIndex( name );
270  if ( fieldIdx == -1 )
271  return QVariant();
272 
273  return d->attributes.at( fieldIdx );
274 }
275 
276 /***************************************************************************
277  * This class is considered CRITICAL and any change MUST be accompanied with
278  * full unit tests in testqgsfeature.cpp.
279  * See details in QEP #17
280  ****************************************************************************/
281 
282 int QgsFeature::fieldNameIndex( const QString &fieldName ) const
283 {
284  return d->fields.lookupField( fieldName );
285 }
286 
287 /***************************************************************************
288  * This class is considered CRITICAL and any change MUST be accompanied with
289  * full unit tests in testqgsfeature.cpp.
290  * See details in QEP #17
291  ****************************************************************************/
292 
293 QDataStream &operator<<( QDataStream &out, const QgsFeature &feature )
294 {
295  out << feature.id();
296  out << feature.attributes();
297  if ( feature.hasGeometry() )
298  {
299  out << ( feature.geometry() );
300  }
301  else
302  {
304  out << geometry;
305  }
306  out << feature.isValid();
307  return out;
308 }
309 
310 QDataStream &operator>>( QDataStream &in, QgsFeature &feature )
311 {
314  bool valid;
315  QgsAttributes attr;
316  in >> id >> attr >> geometry >> valid;
317  feature.setId( id );
318  feature.setGeometry( geometry );
319  feature.setAttributes( attr );
320  feature.setValid( valid );
321  return in;
322 }
323 
324 uint qHash( const QgsFeature &key, uint seed )
325 {
326  uint hash = seed;
327  Q_FOREACH ( const QVariant &attr, key.attributes() )
328  {
329  hash ^= qHash( attr.toString() );
330  }
331 
332  hash ^= qHash( key.geometry().exportToWkt() );
333  hash ^= qHash( key.id() );
334 
335  return hash;
336 }
337 
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:188
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:167
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:324
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:139
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:216
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:202
QDataStream & operator>>(QDataStream &in, QgsFeature &feature)
Reads a feature from stream in into feature. QGIS version compatibility is not guaranteed.
Definition: qgsfeature.cpp:310
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:293
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:207
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:193
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
Definition: qgsfeature.cpp:282
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:156
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:149
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:267
QgsAttributes attributes
Definition: qgsfeature.h:141