@@ -153,6 +153,47 @@ namespace QgsWfs
153153 request.setFlags ( QgsFeatureRequest::ExactIntersect | QgsFeatureRequest::NoFlags );
154154 return request;
155155 }
156+ // Apply BBOX through filterRect even inside an And to use spatial index
157+ else if ( filterElem.firstChildElement ().tagName () == QLatin1String ( " And" ) &&
158+ !filterElem.firstChildElement ().firstChildElement ( QLatin1String ( " BBOX" ) ).isNull () )
159+ {
160+ QDomElement childElem = filterElem.firstChildElement ().firstChildElement ();
161+ while ( !childElem.isNull () )
162+ {
163+ QDomElement childFilterElement = filterElem.ownerDocument ().createElement ( QLatin1String ( " Filter" ) );
164+ childFilterElement.appendChild ( childElem.cloneNode ( true ) );
165+ QgsFeatureRequest childRequest = parseFilterElement ( typeName, childFilterElement );
166+ if ( childElem.tagName () == QLatin1String ( " BBOX" ) )
167+ {
168+ if ( request.filterRect ().isEmpty () )
169+ {
170+ request.setFilterRect ( childRequest.filterRect () );
171+ }
172+ else
173+ {
174+ request.setFilterRect ( request.filterRect ().intersect ( &childRequest.filterRect () ) );
175+ }
176+ }
177+ else
178+ {
179+ if ( !request.filterExpression () )
180+ {
181+ request.setFilterExpression ( childRequest.filterExpression ()->expression () );
182+ }
183+ else
184+ {
185+ QgsExpressionNode *opLeft = request.filterExpression ()->rootNode ()->clone ();
186+ QgsExpressionNode *opRight = childRequest.filterExpression ()->rootNode ()->clone ();
187+ std::unique_ptr<QgsExpressionNodeBinaryOperator> node = qgis::make_unique<QgsExpressionNodeBinaryOperator>( QgsExpressionNodeBinaryOperator::boAnd, opLeft, opRight );
188+ QgsExpression expr ( node->dump () );
189+ request.setFilterExpression ( expr );
190+ }
191+ }
192+ childElem = childElem.nextSiblingElement ();
193+ }
194+ request.setFlags ( QgsFeatureRequest::ExactIntersect | QgsFeatureRequest::NoFlags );
195+ return request;
196+ }
156197 else
157198 {
158199 std::shared_ptr<QgsExpression> filter ( QgsOgcUtils::expressionFromOgcFilter ( filterElem ) );
0 commit comments