QGIS API Documentation  2.17.0-Master (8784312)
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 "qgsfield.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 
33 {
34  d = new QgsFeaturePrivate( id );
35 }
36 
38 {
39  d = new QgsFeaturePrivate( id );
40  d->fields = fields;
41  initAttributes( d->fields.count() );
42 }
43 
45  : d( rhs.d )
46 {
47 }
48 
50 {
51  d = rhs.d;
52  return *this;
53 }
54 
56 {
57 }
58 
59 /***************************************************************************
60  * This class is considered CRITICAL and any change MUST be accompanied with
61  * full unit tests in testqgsfeature.cpp.
62  * See details in QEP #17
63  ****************************************************************************/
64 
66 {
67  return d->fid;
68 }
69 
70 void QgsFeature::deleteAttribute( int field )
71 {
72  d.detach();
73  d->attributes.remove( field );
74 }
75 
77 {
78  d.detach();
79  return d->geometry;
80 }
81 
83 {
84  return d->geometry;
85 }
86 
88 {
89  d.detach();
90  d->ownsGeometry = false;
91 
92  return d->geometry;
93 }
94 
95 /***************************************************************************
96  * This class is considered CRITICAL and any change MUST be accompanied with
97  * full unit tests in testqgsfeature.cpp.
98  * See details in QEP #17
99  ****************************************************************************/
100 
102 {
103  if ( id == d->fid )
104  return;
105 
106  d.detach();
107  d->fid = id;
108 }
109 
111 {
112  return d->attributes;
113 }
114 
116 {
117  if ( attrs == d->attributes )
118  return;
119 
120  d.detach();
121  d->attributes = attrs;
122 }
123 
125 {
126  setGeometry( new QgsGeometry( geom ) );
127 }
128 
130 {
131  // we do a little bit of trickery here to avoid an unnecessary deep copy
132  // of the existing geometry by the detach function
133  // (since we are replacing the geometry anyway)
134 
135  //first, store the old ownsGeometry status
136  QgsFeaturePrivate* old_d = d.data();
137  bool ownedGeom = d->ownsGeometry;
138 
139  //then set owns geometry to false before the detach, so that the deep copy
140  //is not made
141  d->ownsGeometry = false;
142  d.detach();
143 
144  //restore ownsGeometry setting if a detach was made
145  if ( old_d != d.data() )
146  {
147  old_d->ownsGeometry = ownedGeom;
148  }
149  else if ( ownedGeom )
150  {
151  delete d->geometry;
152  }
153 
154  d->geometry = geom;
155  d->ownsGeometry = true;
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 
166 void QgsFeature::setGeometryAndOwnership( unsigned char *geom, int length )
167 {
168  QgsGeometry *g = new QgsGeometry();
169  g->fromWkb( geom, length );
170  setGeometry( g );
171 }
172 
173 void QgsFeature::setFields( const QgsFields* fields, bool init )
174 {
175  setFields( *fields, init );
176 }
177 
178 void QgsFeature::setFields( const QgsFields &fields, bool init )
179 {
180  d.detach();
181  d->fields = fields;
182  if ( init )
183  {
184  initAttributes( d->fields.count() );
185  }
186 }
187 
189 {
190  return &( d->fields );
191 }
192 
193 /***************************************************************************
194  * This class is considered CRITICAL and any change MUST be accompanied with
195  * full unit tests in testqgsfeature.cpp.
196  * See details in QEP #17
197  ****************************************************************************/
198 
200 {
201  return d->valid;
202 }
203 
204 void QgsFeature::setValid( bool validity )
205 {
206  if ( d->valid == validity )
207  return;
208 
209  d.detach();
210  d->valid = validity;
211 }
212 
213 void QgsFeature::initAttributes( int fieldCount )
214 {
215  d.detach();
216  d->attributes.resize( fieldCount );
217  QVariant* ptr = d->attributes.data();
218  for ( int i = 0; i < fieldCount; ++i, ++ptr )
219  ptr->clear();
220 }
221 
222 bool QgsFeature::setAttribute( int idx, const QVariant &value )
223 {
224  if ( idx < 0 || idx >= d->attributes.size() )
225  {
226  QgsMessageLog::logMessage( QObject::tr( "Attribute index %1 out of bounds [0;%2]" ).arg( idx ).arg( d->attributes.size() ), QString::null, QgsMessageLog::WARNING );
227  return false;
228  }
229 
230  d.detach();
231  d->attributes[idx] = value;
232  return true;
233 }
234 
235 /***************************************************************************
236  * This class is considered CRITICAL and any change MUST be accompanied with
237  * full unit tests in testqgsfeature.cpp.
238  * See details in QEP #17
239  ****************************************************************************/
240 
241 bool QgsFeature::setAttribute( const QString& name, const QVariant& value )
242 {
243  int fieldIdx = fieldNameIndex( name );
244  if ( fieldIdx == -1 )
245  return false;
246 
247  d.detach();
248  d->attributes[fieldIdx] = value;
249  return true;
250 }
251 
253 {
254  int fieldIdx = fieldNameIndex( name );
255  if ( fieldIdx == -1 )
256  return false;
257 
258  d.detach();
259  d->attributes[fieldIdx].clear();
260  return true;
261 }
262 
263 QVariant QgsFeature::attribute( int fieldIdx ) const
264 {
265  if ( fieldIdx < 0 || fieldIdx >= d->attributes.count() )
266  return QVariant();
267 
268  return d->attributes.at( fieldIdx );
269 }
270 
272 {
273  int fieldIdx = fieldNameIndex( name );
274  if ( fieldIdx == -1 )
275  return QVariant();
276 
277  return d->attributes.at( fieldIdx );
278 }
279 
280 /***************************************************************************
281  * This class is considered CRITICAL and any change MUST be accompanied with
282  * full unit tests in testqgsfeature.cpp.
283  * See details in QEP #17
284  ****************************************************************************/
285 
286 int QgsFeature::fieldNameIndex( const QString& fieldName ) const
287 {
288  return d->fields.fieldNameIndex( fieldName );
289 }
290 
291 /***************************************************************************
292  * This class is considered CRITICAL and any change MUST be accompanied with
293  * full unit tests in testqgsfeature.cpp.
294  * See details in QEP #17
295  ****************************************************************************/
296 
298 {
299  out << feature.id();
300  out << feature.attributes();
301  if ( feature.constGeometry() )
302  {
303  out << *( feature.constGeometry() );
304  }
305  else
306  {
308  out << geometry;
309  }
310  out << feature.isValid();
311  return out;
312 }
313 
315 {
318  bool valid;
319  QgsAttributes attr;
320  in >> id >> attr >> *geometry >> valid;
321  feature.setFeatureId( id );
322  feature.setGeometry( geometry );
323  feature.setAttributes( attr );
324  feature.setValid( valid );
325  return in;
326 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:199
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
Definition: qgsfeature.cpp:286
virtual ~QgsFeature()
Destructor.
Definition: qgsfeature.cpp:55
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer&#39;s length...
Container of fields for a vector layer.
Definition: qgsfield.h:193
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:115
bool setAttribute(int field, const QVariant &attr)
Set an attribute&#39;s value by field index.
Definition: qgsfeature.cpp:222
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QString tr(const char *sourceText, const char *disambiguation, int n)
QDataStream & operator>>(QDataStream &in, QgsFeature &feature)
Reads a feature from stream in into feature.
Definition: qgsfeature.cpp:314
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
void deleteAttribute(int field)
Deletes an attribute and its value.
Definition: qgsfeature.cpp:70
void setFeatureId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:101
QgsAttributes attributes() const
Returns the feature&#39;s attributes.
Definition: qgsfeature.cpp:110
QDataStream & operator<<(QDataStream &out, const QgsFeature &feature)
Writes the feature to stream out.
Definition: qgsfeature.cpp:297
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Definition: qgsfeature.cpp:213
const QgsFields * fields() const
Returns the field map associated with the feature.
Definition: qgsfeature.cpp:188
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)
QgsFeature & operator=(QgsFeature const &rhs)
Assignment operator.
Definition: qgsfeature.cpp:49
Q_DECL_DEPRECATED 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:173
QgsFeature(QgsFeatureId id=QgsFeatureId())
Constructor for QgsFeature.
Definition: qgsfeature.cpp:32
void clear()
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:204
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
Q_DECL_DEPRECATED void setGeometryAndOwnership(unsigned char *geom, int length)
Set this feature&#39;s geometry from WKB.
Definition: qgsfeature.cpp:166
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
qint64 QgsFeatureId
Definition: qgsfeature.h:31
Q_DECL_DEPRECATED QgsGeometry * geometryAndOwnership()
Get the geometry object associated with this feature, and transfer ownership of the geometry to the c...
Definition: qgsfeature.cpp:87
A vector of attributes.
Definition: qgsfeature.h:115