QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsfeaturerequest.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfeaturerequest.cpp
3  ---------------------
4  begin : Mai 2012
5  copyright : (C) 2012 by Martin Dobias
6  email : wonder dot sk at gmail dot 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 #include "qgsfeaturerequest.h"
16 
17 #include "qgsfield.h"
18 #include "qgsgeometry.h"
19 
20 #include <QStringList>
21 
22 //constants
23 const QString QgsFeatureRequest::AllAttributes = QString( "#!allattributes!#" );
24 
26  : mFilter( FilterNone )
27  , mFilterFid( -1 )
28  , mFilterExpression( nullptr )
29  , mFlags( nullptr )
30  , mLimit( -1 )
31 {
32 }
33 
35  : mFilter( FilterFid )
36  , mFilterFid( fid )
37  , mFilterExpression( nullptr )
38  , mFlags( nullptr )
39  , mLimit( -1 )
40 {
41 }
42 
44  : mFilter( FilterRect )
45  , mFilterRect( rect )
46  , mFilterFid( -1 )
47  , mFilterExpression( nullptr )
48  , mFlags( nullptr )
49  , mLimit( -1 )
50 {
51 }
52 
55  , mFilterFid( -1 )
56  , mFilterExpression( new QgsExpression( expr ) )
57  , mExpressionContext( context )
58  , mFlags( nullptr )
59  , mLimit( -1 )
60 {
61 }
62 
64 {
65  operator=( rh );
66 }
67 
69 {
70  mFlags = rh.mFlags;
71  mFilter = rh.mFilter;
75  if ( rh.mFilterExpression )
76  {
78  }
79  else
80  {
81  mFilterExpression = nullptr;
82  }
84  mAttrs = rh.mAttrs;
86  mLimit = rh.mLimit;
87  mOrderBy = rh.mOrderBy;
88  return *this;
89 }
90 
92 {
93  delete mFilterExpression;
94 }
95 
97 {
98  if ( mFilter == FilterNone )
100  mFilterRect = rect;
101  return *this;
102 }
103 
105 {
106  mFilter = FilterFid;
107  mFilterFid = fid;
108  return *this;
109 }
110 
112 {
114  mFilterFids = fids;
115  return *this;
116 }
117 
119 {
121  delete mFilterExpression;
122  mFilterExpression = new QgsExpression( expression );
123  return *this;
124 }
125 
127 {
128  if ( mFilterExpression )
129  {
130  setFilterExpression( QString( "(%1) AND (%2)" ).arg( mFilterExpression->expression(), expression ) );
131  }
132  else
133  {
134  setFilterExpression( expression );
135  }
136  return *this;
137 }
138 
140 {
141  mExpressionContext = context;
142  return *this;
143 }
144 
145 QgsFeatureRequest& QgsFeatureRequest::addOrderBy( const QString& expression, bool ascending )
146 {
147  mOrderBy.append( OrderByClause( expression, ascending ) );
148  return *this;
149 }
150 
151 QgsFeatureRequest& QgsFeatureRequest::addOrderBy( const QString& expression, bool ascending, bool nullsfirst )
152 {
153  mOrderBy.append( OrderByClause( expression, ascending, nullsfirst ) );
154  return *this;
155 }
156 
158 {
159  return mOrderBy;
160 }
161 
163 {
164  mOrderBy = orderBy;
165  return *this;
166 }
167 
169 {
170  mLimit = limit;
171  return *this;
172 }
173 
174 QgsFeatureRequest& QgsFeatureRequest::setFlags( const QgsFeatureRequest::Flags& flags )
175 {
176  mFlags = flags;
177  return *this;
178 }
179 
181 {
183  mAttrs = attrs;
184  return *this;
185 }
186 
188 {
189  if ( attrNames.contains( QgsFeatureRequest::AllAttributes ) )
190  {
191  //attribute string list contains the all attributes flag, so we must fetch all attributes
192  return *this;
193  }
194 
196  mAttrs.clear();
197 
198  Q_FOREACH ( const QString& attrName, attrNames )
199  {
200  int attrNum = fields.fieldNameIndex( attrName );
201  if ( attrNum != -1 && !mAttrs.contains( attrNum ) )
202  mAttrs.append( attrNum );
203  }
204 
205  return *this;
206 }
207 
209 {
211  return *this;
212 }
213 
215 {
216  switch ( mFilter )
217  {
219  return true;
220 
222  if ( feature.constGeometry() && feature.constGeometry()->intersects( mFilterRect ) )
223  return true;
224  else
225  return false;
226 
228  if ( feature.id() == mFilterFid )
229  return true;
230  else
231  return false;
232 
234  mExpressionContext.setFeature( feature );
236  return true;
237  else
238  return false;
239 
241  if ( mFilterFids.contains( feature.id() ) )
242  return true;
243  else
244  return false;
245  }
246 
247  return true;
248 }
249 
250 
251 #include "qgsfeatureiterator.h"
252 #include "qgslogger.h"
253 
255 {
256  while ( !mActiveIterators.empty() )
257  {
258  QgsAbstractFeatureIterator *it = *mActiveIterators.begin();
259  QgsDebugMsg( "closing active iterator" );
260  it->close();
261  }
262 }
263 
265 {
266  mActiveIterators.insert( it );
267 }
268 
270 {
271  mActiveIterators.remove( it );
272 }
273 
274 
275 
276 QgsFeatureRequest::OrderByClause::OrderByClause( const QString& expression, bool ascending )
277  : mExpression( expression )
278  , mAscending( ascending )
279 {
280  // postgres behavior: default for ASC: NULLS LAST, default for DESC: NULLS FIRST
281  mNullsFirst = !ascending;
282 }
283 
285  : mExpression( expression )
286  , mAscending( ascending )
287  , mNullsFirst( nullsfirst )
288 {
289 }
290 
292 {
293  return mAscending;
294 }
295 
297 {
298  mAscending = ascending;
299 }
300 
302 {
303  return mNullsFirst;
304 }
305 
307 {
308  mNullsFirst = nullsFirst;
309 }
310 
312 {
313  return QString( "%1 %2 %3" )
314  .arg( mExpression.expression(),
315  mAscending ? "ASC" : "DESC",
316  mNullsFirst ? "NULLS FIRST" : "NULLS LAST" );
317 }
318 
320 {
321  return mExpression;
322 }
323 
325 {
326  Q_FOREACH ( const QgsFeatureRequest::OrderByClause& clause, other )
327  {
328  append( clause );
329  }
330 }
331 
333 {
334  return *this;
335 }
336 
338 {
339  QDomDocument doc = elem.ownerDocument();
341  for ( it = constBegin(); it != constEnd(); ++it )
342  {
343  const OrderByClause& clause = *it;
344  QDomElement clauseElem = doc.createElement( "orderByClause" );
345  clauseElem.setAttribute( "asc", clause.ascending() );
346  clauseElem.setAttribute( "nullsFirst", clause.nullsFirst() );
347  clauseElem.appendChild( doc.createTextNode( clause.expression().expression() ) );
348 
349  elem.appendChild( clauseElem );
350  }
351 }
352 
354 {
355  clear();
356 
357  QDomNodeList clauses = elem.childNodes();
358 
359  for ( int i = 0; i < clauses.size(); ++i )
360  {
361  QDomElement clauseElem = clauses.at( i ).toElement();
362  QString expression = clauseElem.text();
363  bool asc = clauseElem.attribute( "asc" ).toInt() != 0;
364  bool nullsFirst = clauseElem.attribute( "nullsFirst" ).toInt() != 0;
365 
366  append( OrderByClause( expression, asc, nullsFirst ) );
367  }
368 }
369 
371 {
372  QSet<QString> usedAttributes;
373 
375  for ( it = constBegin(); it != constEnd(); ++it )
376  {
377  const OrderByClause& clause = *it;
378 
379  usedAttributes.unite( clause.expression().referencedColumns().toSet() );
380  }
381 
382  return usedAttributes;
383 }
384 
386 {
387  QStringList results;
388 
390  for ( it = constBegin(); it != constEnd(); ++it )
391  {
392  const OrderByClause& clause = *it;
393 
394  results << clause.dump();
395  }
396 
397  return results.join( ", " );
398 }
Class for parsing and evaluation of expressions (formerly called "search strings").
void clear()
QgsFeatureIds mFilterFids
virtual bool close()=0
end of iterating: free the resources / lock
A rectangle specified with double values.
Definition: qgsrectangle.h:35
long limit() const
Returns the maximum number of features to request, or -1 if no limit set.
bool nullsFirst() const
Set if NULLS should be returned first.
bool acceptFeature(const QgsFeature &feature)
Check if a feature is accepted by this requests filter.
QSet< QString > CORE_EXPORT usedAttributes() const
Returns a set of used attributes.
Filter using feature ID.
Filter using feature IDs.
QgsSimplifyMethod mSimplifyMethod
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
QgsExpression * mFilterExpression
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
bool ascending() const
Order ascending.
const Flags & flags() const
QString dump() const
Dumps the content to an SQL equivalent.
void iteratorClosed(QgsAbstractFeatureIterator *it)
QDomNode appendChild(const QDomNode &newChild)
QList< OrderByClause > CORE_EXPORT list() const
Get a copy as a list of OrderByClauses.
QString attribute(const QString &name, const QString &defValue) const
QString CORE_EXPORT dump() const
Dumps the content to an SQL equivalent syntax.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QStringList referencedColumns() const
Get list of columns referenced by the expression.
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
Definition: qgsfield.h:252
void CORE_EXPORT load(const QDomElement &elem)
Deserialize from XML.
QgsFeatureRequest & addOrderBy(const QString &expression, bool ascending=true)
Adds a new OrderByClause, appending it as the least important one.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
QSet< T > toSet() const
QString join(const QString &separator) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QgsFeatureRequest & operator=(const QgsFeatureRequest &rh)
Assignment operator.
QDomNodeList childNodes() const
QgsExpressionContext mExpressionContext
QDomElement toElement() const
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void append(const T &value)
QDomDocument ownerDocument() const
QString text() const
OrderByClause(const QString &expression, bool ascending=true)
Creates a new OrderByClause for a QgsFeatureRequest.
void setAttribute(const QString &name, const QString &value)
Internal feature iterator to be implemented within data providers.
int toInt(bool *ok, int base) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsFeatureRequest()
construct a default request: for all features get attributes and geometries
static const QString AllAttributes
A special attribute that if set matches all attributes.
Obsolete, will be ignored. If a filterRect is set it will be used anyway. Filter using a rectangle...
QgsRectangle mFilterRect
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
QDomText createTextNode(const QString &value)
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
int fieldNameIndex(const QString &fieldName) const
Look up field&#39;s index from name also looks up case-insensitive if there is no match otherwise...
Definition: qgsfield.cpp:571
QString expression() const
Return the original, unmodified expression string.
bool contains(const T &value) const
QgsFeatureRequest & setSimplifyMethod(const QgsSimplifyMethod &simplifyMethod)
Set a simplification method for geometries that will be fetched.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
QgsFeatureId mFilterFid
bool contains(const T &value) const
QgsExpression expression() const
The expression.
No filter is applied.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
QSet< T > & unite(const QSet< T > &other)
void setAscending(bool ascending)
Set if ascending order is requested.
QgsAttributeList mAttrs
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
bool toBool() const
qint64 QgsFeatureId
Definition: qgsfeature.h:31
This class contains information about how to simplify geometries fetched from a QgsFeatureIterator.
QgsFeatureRequest & setOrderBy(const OrderBy &orderBy)
Set a list of order by clauses.
int size() const
QDomElement createElement(const QString &tagName)
OrderBy orderBy() const
Return a list of order by clauses specified for this feature request.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
const QgsSimplifyMethod & simplifyMethod() const
Get simplification method for geometries that will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rect)
Set rectangle from which features will be taken.
CORE_EXPORT OrderBy()
Create a new empty order by.
Represents a list of OrderByClauses, with the most important first and the least important last...
void iteratorOpened(QgsAbstractFeatureIterator *it)
QDomNode at(int index) const
void setNullsFirst(bool nullsFirst)
Set if NULLS should be returned first.