@@ -872,10 +872,10 @@ static void collectTopLevelAndNodes( const QgsExpressionNode *node,
872
872
topAndNodes.push_back ( node );
873
873
}
874
874
875
- QString QgsOapifSharedData::translateNodeToServer (
875
+ QString QgsOapifSharedData::compileExpressionNodeUsingPart1 (
876
876
const QgsExpressionNode *rootNode,
877
877
QgsOapifProvider::FilterTranslationState &translationState,
878
- QString &untranslatedPart )
878
+ QString &untranslatedPart ) const
879
879
{
880
880
std::vector<const QgsExpressionNode *> topAndNodes;
881
881
collectTopLevelAndNodes ( rootNode, topAndNodes );
@@ -1035,18 +1035,15 @@ QString QgsOapifSharedData::translateNodeToServer(
1035
1035
return ret;
1036
1036
}
1037
1037
1038
- bool QgsOapifSharedData::computeServerFilter ( QString &errorMsg )
1038
+ bool QgsOapifSharedData::computeFilter ( const QgsExpression &expr,
1039
+ QgsOapifProvider::FilterTranslationState &translationState,
1040
+ QString &serverSideParameters,
1041
+ QString &clientSideFilterExpression ) const
1039
1042
{
1040
- errorMsg.clear ();
1041
- mClientSideFilterExpression = mURI .filter ();
1042
- mServerFilter .clear ();
1043
- if ( mClientSideFilterExpression .isEmpty () )
1044
- {
1045
- mFilterTranslationState = QgsOapifProvider::FilterTranslationState::FULLY_SERVER;
1046
- return true ;
1047
- }
1043
+ const auto rootNode = expr.rootNode ();
1044
+ if ( !rootNode )
1045
+ return false ;
1048
1046
1049
- const QgsExpression expr ( mClientSideFilterExpression );
1050
1047
if ( mServerSupportsFilterCql2Text )
1051
1048
{
1052
1049
const bool invertAxisOrientation = mSourceCrs .hasAxisInverted ();
@@ -1056,54 +1053,73 @@ bool QgsOapifSharedData::computeServerFilter( QString &errorMsg )
1056
1053
QgsOapifCql2TextExpressionCompiler::Result res = compiler.compile ( &expr );
1057
1054
if ( res == QgsOapifCql2TextExpressionCompiler::Fail )
1058
1055
{
1059
- QgsDebugMsg ( " Whole filter will be evaluated on client-side " );
1060
- mFilterTranslationState = QgsOapifProvider::FilterTranslationState::FULLY_CLIENT;
1056
+ clientSideFilterExpression = expr. rootNode ()-> dump ( );
1057
+ translationState = QgsOapifProvider::FilterTranslationState::FULLY_CLIENT;
1061
1058
return true ;
1062
1059
}
1063
- mServerFilter = getEncodedQueryParam ( QStringLiteral ( " filter" ), compiler.result () );
1064
- mServerFilter += QStringLiteral ( " &filter-lang=cql2-text" );
1060
+ serverSideParameters = getEncodedQueryParam ( QStringLiteral ( " filter" ), compiler.result () );
1061
+ serverSideParameters += QStringLiteral ( " &filter-lang=cql2-text" );
1065
1062
if ( compiler.geometryLiteralUsed () )
1066
1063
{
1067
1064
if ( mSourceCrs
1068
1065
!= QgsCoordinateReferenceSystem::fromOgcWmsCrs ( QgsOapifProvider::OAPIF_PROVIDER_DEFAULT_CRS ) )
1069
1066
{
1070
- mServerFilter += QStringLiteral ( " &filter-crs=%1" ).arg ( mSourceCrs .toOgcUri () );
1067
+ serverSideParameters += QStringLiteral ( " &filter-crs=%1" ).arg ( mSourceCrs .toOgcUri () );
1071
1068
}
1072
1069
}
1073
1070
1071
+ clientSideFilterExpression.clear ();
1074
1072
if ( res == QgsOapifCql2TextExpressionCompiler::Partial )
1075
1073
{
1076
- mFilterTranslationState = QgsOapifProvider::FilterTranslationState::PARTIAL;
1077
- QgsDebugMsg ( " Part of the filter will be evaluated on client-side" );
1074
+ translationState = QgsOapifProvider::FilterTranslationState::PARTIAL;
1078
1075
}
1079
1076
else
1080
1077
{
1081
- mFilterTranslationState = QgsOapifProvider::FilterTranslationState::FULLY_SERVER;
1078
+ translationState = QgsOapifProvider::FilterTranslationState::FULLY_SERVER;
1082
1079
}
1083
1080
return true ;
1084
1081
}
1085
1082
1086
- const auto rootNode = expr. rootNode ( );
1087
- if ( !rootNode )
1088
- return false ;
1083
+ serverSideParameters = compileExpressionNodeUsingPart1 ( rootNode, translationState, clientSideFilterExpression );
1084
+ return true ;
1085
+ }
1089
1086
1090
- mServerFilter = translateNodeToServer ( rootNode, mFilterTranslationState , mClientSideFilterExpression );
1091
- if ( mFilterTranslationState == QgsOapifProvider::FilterTranslationState::PARTIAL )
1087
+ bool QgsOapifSharedData::computeServerFilter ( QString &errorMsg )
1088
+ {
1089
+ errorMsg.clear ();
1090
+ mClientSideFilterExpression = mURI .filter ();
1091
+ mServerFilter .clear ();
1092
+ if ( mClientSideFilterExpression .isEmpty () )
1092
1093
{
1093
- QgsDebugMsg ( QStringLiteral ( " Part of the filter will be evaluated on client-side: %1" ).arg ( mClientSideFilterExpression ) );
1094
+ mFilterTranslationState = QgsOapifProvider::FilterTranslationState::FULLY_SERVER;
1095
+ return true ;
1094
1096
}
1095
- else if ( mFilterTranslationState == QgsOapifProvider::FilterTranslationState::FULLY_CLIENT )
1097
+
1098
+ const QgsExpression expr ( mClientSideFilterExpression );
1099
+ bool ret = computeFilter ( expr, mFilterTranslationState , mServerFilter , mClientSideFilterExpression );
1100
+ if ( ret )
1096
1101
{
1097
- QgsDebugMsg ( " Whole filter will be evaluated on client-side" );
1102
+ if ( mFilterTranslationState == QgsOapifProvider::FilterTranslationState::PARTIAL )
1103
+ {
1104
+ QgsDebugMsg ( QStringLiteral ( " Part of the filter will be evaluated on client-side: %1" ).arg ( mClientSideFilterExpression ) );
1105
+ }
1106
+ else if ( mFilterTranslationState == QgsOapifProvider::FilterTranslationState::FULLY_CLIENT )
1107
+ {
1108
+ QgsDebugMsg ( " Whole filter will be evaluated on client-side" );
1109
+ }
1098
1110
}
1099
-
1100
- return true ;
1111
+ return ret;
1101
1112
}
1102
1113
1103
1114
QString QgsOapifSharedData::computedExpression ( const QgsExpression &expression ) const
1104
1115
{
1105
- Q_UNUSED ( expression );
1106
- return QString ();
1116
+ if ( !expression.isValid () )
1117
+ return QString ();
1118
+ QgsOapifProvider::FilterTranslationState translationState;
1119
+ QString serverParameters;
1120
+ QString clientSideFilterExpression;
1121
+ computeFilter ( expression, translationState, serverParameters, clientSideFilterExpression );
1122
+ return serverParameters;
1107
1123
}
1108
1124
1109
1125
void QgsOapifSharedData::pushError ( const QString &errorMsg ) const
@@ -1178,10 +1194,50 @@ void QgsOapifFeatureDownloaderImpl::run( bool serializeFeatures, long long maxFe
1178
1194
hasQueryParam = true ;
1179
1195
}
1180
1196
1197
+ // mServerFilter comes from the translation of the uri "filter" parameter
1198
+ // mServerExpression comes from the translation of a getFeatures() expression
1181
1199
if ( !mShared ->mServerFilter .isEmpty () )
1182
1200
{
1183
1201
url += ( hasQueryParam ? QStringLiteral ( " &" ) : QStringLiteral ( " ?" ) );
1184
- url += mShared ->mServerFilter ;
1202
+ if ( !mShared ->mServerExpression .isEmpty () )
1203
+ {
1204
+ // Combine mServerFilter and mServerExpression
1205
+ QStringList components1 = mShared ->mServerFilter .split ( QLatin1Char ( ' &' ) );
1206
+ QStringList components2 = mShared ->mServerExpression .split ( QLatin1Char ( ' &' ) );
1207
+ Q_ASSERT ( components1[0 ].startsWith ( QStringLiteral ( " filter=" ) ) );
1208
+ Q_ASSERT ( components2[0 ].startsWith ( QStringLiteral ( " filter=" ) ) );
1209
+ url += QStringLiteral ( " filter=" );
1210
+ url += ' (' ;
1211
+ url += components1[0 ].mid ( static_cast <int >( strlen ( " filter=" ) ) );
1212
+ url += QStringLiteral ( " ) AND (" );
1213
+ url += components2[0 ].mid ( static_cast <int >( strlen ( " filter=" ) ) );
1214
+ url += ' )' ;
1215
+ // Add components1 extra parameters: filter-lang and filter-crs
1216
+ for ( int i = 1 ; i < components1.size (); ++i )
1217
+ {
1218
+ url += ' &' ;
1219
+ url += components1[i];
1220
+ }
1221
+ // Add components2 extra parameters, not already included in components1
1222
+ for ( int i = 1 ; i < components2.size (); ++i )
1223
+ {
1224
+ if ( !components1.contains ( components2[i] ) )
1225
+ {
1226
+ url += ' &' ;
1227
+ url += components1[i];
1228
+ }
1229
+ }
1230
+ }
1231
+ else
1232
+ {
1233
+ url += mShared ->mServerFilter ;
1234
+ }
1235
+ hasQueryParam = true ;
1236
+ }
1237
+ else if ( !mShared ->mServerExpression .isEmpty () )
1238
+ {
1239
+ url += ( hasQueryParam ? QStringLiteral ( " &" ) : QStringLiteral ( " ?" ) );
1240
+ url += mShared ->mServerExpression ;
1185
1241
hasQueryParam = true ;
1186
1242
}
1187
1243
0 commit comments