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