QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsserverfeatureid.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsserverfeatureid.cpp
3  -----------------------
4  begin : May 17, 2019
5  copyright : (C) 2019 by RenĂ©-Luc DHONT
6  email : rldhont at 3liz dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsserverfeatureid.h"
19 #include "qgsfeature.h"
20 #include "qgsfeaturerequest.h"
21 #include "qgsvectordataprovider.h"
22 #include "qgsexpression.h"
23 
24 QString QgsServerFeatureId::getServerFid( const QgsFeature &feature, const QgsAttributeList &pkAttributes )
25 {
26  if ( pkAttributes.isEmpty() )
27  {
28  return QString::number( feature.id() );
29  }
30 
31  QStringList pkValues;
32  for ( const auto &attrIdx : std::as_const( pkAttributes ) )
33  {
34  pkValues.append( feature.attribute( attrIdx ).toString() );
35  }
36  return pkValues.join( pkSeparator() );
37 }
38 
40 {
41  const QgsAttributeList &pkAttributes = provider->pkAttributeIndexes();
42 
43  if ( pkAttributes.isEmpty() )
44  {
45  QgsFeatureIds fids;
46  for ( const QString &serverFid : serverFids )
47  {
48  fids.insert( STRING_TO_FID( serverFid ) );
49  }
50  featureRequest.setFilterFids( fids );
51  return featureRequest;
52  }
53 
54  QStringList expList;
55  for ( const QString &serverFid : serverFids )
56  {
57  expList.append( QgsServerFeatureId::getExpressionFromServerFid( serverFid, provider ) );
58  }
59 
60  if ( expList.count() == 1 )
61  {
62  featureRequest.combineFilterExpression( expList.at( 0 ) );
63  }
64  else
65  {
66  QString fullExpression;
67  for ( const QString &exp : std::as_const( expList ) )
68  {
69  if ( !fullExpression.isEmpty() )
70  {
71  fullExpression.append( QStringLiteral( " OR " ) );
72  }
73  fullExpression.append( QStringLiteral( "( " ) );
74  fullExpression.append( exp );
75  fullExpression.append( QStringLiteral( " )" ) );
76  }
77  featureRequest.combineFilterExpression( fullExpression );
78  }
79 
80  return featureRequest;
81 }
82 
83 QString QgsServerFeatureId::getExpressionFromServerFid( const QString &serverFid, const QgsVectorDataProvider *provider )
84 {
85  const QgsAttributeList &pkAttributes = provider->pkAttributeIndexes();
86 
87  if ( pkAttributes.isEmpty() )
88  {
89  return QString();
90  }
91 
92  const QgsFields &fields = provider->fields();
93 
94  QString expressionString;
95  QStringList pkValues = serverFid.split( pkSeparator() );
96  int pkExprSize = std::min( pkAttributes.size(), pkValues.size() );
97  for ( int i = 0; i < pkExprSize; ++i )
98  {
99  if ( i > 0 )
100  {
101  expressionString.append( QStringLiteral( " AND " ) );
102  }
103 
104  QString fieldName = fields[ pkAttributes.at( i ) ].name();
105  expressionString.append( QgsExpression::createFieldEqualityExpression( fieldName, QVariant( pkValues.at( i ) ) ) );
106  }
107 
108  return expressionString;
109 }
110 
112 {
113  return QStringLiteral( "@@" );
114 }
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:302
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
This is the base class for vector data providers.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
SERVER_EXPORT QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
SERVER_EXPORT QString pkSeparator()
Returns the primary keys separator.
SERVER_EXPORT QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
SERVER_EXPORT QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
#define STRING_TO_FID(str)
Definition: qgsfeatureid.h:34
QList< int > QgsAttributeList
Definition: qgsfield.h:26