Skip to content

Commit 38f05b5

Browse files
committed
Fix WFS context fields variable
because the fields in the (spatialite) cached iterator are not the same as the main iterator. Fix #21077 - Form Value relation based on WFS layer (nothing to do with value relations)
1 parent 861a8b7 commit 38f05b5

File tree

2 files changed

+173
-1
lines changed

2 files changed

+173
-1
lines changed

src/providers/wfs/qgswfsfeatureiterator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,15 @@ QgsFeatureRequest QgsWFSFeatureIterator::buildRequestCache( int genCounter )
991991
{
992992
if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression )
993993
{
994+
// Transfer and transform context
994995
requestCache.setFilterExpression( mRequest.filterExpression()->expression() );
996+
QgsExpressionContext ctx { *mRequest.expressionContext( ) };
997+
QgsExpressionContextScope *scope { ctx.activeScopeForVariable( QgsExpressionContext::EXPR_FIELDS ) };
998+
if ( scope )
999+
{
1000+
scope->setVariable( QgsExpressionContext::EXPR_FIELDS, mShared->mCacheDataProvider->fields() );
1001+
}
1002+
requestCache.setExpressionContext( ctx );
9951003
}
9961004
if ( genCounter >= 0 )
9971005
{

tests/src/python/test_provider_wfs.py

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
QgsVectorDataProvider,
3434
QgsFeatureRequest,
3535
QgsApplication,
36-
QgsSettings
36+
QgsSettings,
37+
QgsExpression,
38+
QgsExpressionContextUtils,
39+
QgsExpressionContext,
3740
)
3841
from qgis.testing import (start_app,
3942
unittest
@@ -3738,5 +3741,166 @@ def test_NullValues_regression_20961(self):
37383741
self.assertEqual(str(got_f2[1]['name']), 'sdf')
37393742

37403743

3744+
def testFilteredFeatureRequests(self):
3745+
"""Test https://issues.qgis.org/issues/21077 """
3746+
3747+
endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_filtered_feature_requests'
3748+
3749+
with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.1.0'), 'wb') as f:
3750+
f.write("""
3751+
<wfs:WFS_Capabilities version="1.1.0" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://schemas.opengis.net/gml">
3752+
<FeatureTypeList>
3753+
<FeatureType>
3754+
<Name>points</Name>
3755+
<Title>Title</Title>
3756+
<Abstract>Abstract</Abstract>
3757+
<DefaultCRS>urn:ogc:def:crs:OGC:1.3:CRS84</DefaultCRS>
3758+
<WGS84BoundingBox>
3759+
<LowerCorner>-98.6523 32.7233</LowerCorner>
3760+
<UpperCorner>23.2868 69.9882</UpperCorner>
3761+
</WGS84BoundingBox>
3762+
</FeatureType>
3763+
</FeatureTypeList>
3764+
</wfs:WFS_Capabilities>""".encode('UTF-8'))
3765+
3766+
with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=points'), 'wb') as f:
3767+
f.write("""
3768+
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" version="1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:qgs="http://www.qgis.org/gml" elementFormDefault="qualified" targetNamespace="http://www.qgis.org/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
3769+
<import schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" namespace="http://www.opengis.net/gml"/>
3770+
<element type="qgs:pointsType" name="points" substitutionGroup="gml:_Feature"/>
3771+
<complexType name="pointsType">
3772+
<complexContent>
3773+
<extension base="gml:AbstractFeatureType">
3774+
<sequence>
3775+
<element type="gml:MultiPointPropertyType" name="geometry" minOccurs="0" maxOccurs="1"/>
3776+
<element type="int" name="id"/>
3777+
<element type="string" name="name"/>
3778+
<element type="int" name="type" nillable="true"/>
3779+
<element type="decimal" name="elevation" nillable="true"/>
3780+
</sequence>
3781+
</extension>
3782+
</complexContent>
3783+
</complexType>
3784+
</schema>
3785+
""".encode('UTF-8'))
3786+
3787+
get_feature_1 = """<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:qgs="http://www.qgis.org/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.qgis.org/gml http://localhost:8000/ows/bug_20961_server?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=points&amp;OUTPUTFORMAT=text/xml; subtype%3Dgml/3.1.1">
3788+
<gml:boundedBy>
3789+
<gml:Envelope srsName="EPSG:3857">
3790+
<gml:lowerCorner>-10981925.67093 3858635.0686243</gml:lowerCorner>
3791+
<gml:upperCorner>2592274.0488407 11064877.6393476</gml:upperCorner>
3792+
</gml:Envelope>
3793+
</gml:boundedBy>
3794+
<gml:featureMember>
3795+
<qgs:points gml:id="points.177">
3796+
<gml:boundedBy>
3797+
<gml:Envelope srsName="EPSG:3857">
3798+
<gml:lowerCorner>1544231.80343599 5930698.04174612</gml:lowerCorner>
3799+
<gml:upperCorner>1544231.80343599 5930698.04174612</gml:upperCorner>
3800+
</gml:Envelope>
3801+
</gml:boundedBy>
3802+
<qgs:geometry>
3803+
<MultiPoint xmlns="http://www.opengis.net/gml" srsName="EPSG:3857">
3804+
<pointMember xmlns="http://www.opengis.net/gml">
3805+
<Point xmlns="http://www.opengis.net/gml">
3806+
<pos xmlns="http://www.opengis.net/gml" srsDimension="2">1544231.80343599 5930698.04174612</pos>
3807+
</Point>
3808+
</pointMember>
3809+
</MultiPoint>
3810+
</qgs:geometry>
3811+
<qgs:id>177</qgs:id>
3812+
<qgs:name>Xxx</qgs:name>
3813+
<qgs:elevation_source></qgs:elevation_source>
3814+
</qgs:points>
3815+
</gml:featureMember>
3816+
</wfs:FeatureCollection>
3817+
"""
3818+
get_features = """<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:qgs="http://www.qgis.org/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.qgis.org/gml http://localhost:8000/ows/bug_20961_server?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=points&amp;OUTPUTFORMAT=text/xml; subtype%3Dgml/3.1.1">
3819+
<gml:boundedBy>
3820+
<gml:Envelope srsName="EPSG:3857">
3821+
<gml:lowerCorner>-10981925.67093 3858635.0686243</gml:lowerCorner>
3822+
<gml:upperCorner>2592274.0488407 11064877.6393476</gml:upperCorner>
3823+
</gml:Envelope>
3824+
</gml:boundedBy>
3825+
<gml:featureMember>
3826+
<qgs:points gml:id="points.177">
3827+
<gml:boundedBy>
3828+
<gml:Envelope srsName="EPSG:3857">
3829+
<gml:lowerCorner>1544231.80343599 5930698.04174612</gml:lowerCorner>
3830+
<gml:upperCorner>1544231.80343599 5930698.04174612</gml:upperCorner>
3831+
</gml:Envelope>
3832+
</gml:boundedBy>
3833+
<qgs:geometry>
3834+
<MultiPoint xmlns="http://www.opengis.net/gml" srsName="EPSG:3857">
3835+
<pointMember xmlns="http://www.opengis.net/gml">
3836+
<Point xmlns="http://www.opengis.net/gml">
3837+
<pos xmlns="http://www.opengis.net/gml" srsDimension="2">1544231.80343599 5930698.04174612</pos>
3838+
</Point>
3839+
</pointMember>
3840+
</MultiPoint>
3841+
</qgs:geometry>
3842+
<qgs:id>177</qgs:id>
3843+
<qgs:name>Xxx</qgs:name>
3844+
<qgs:type xsi:nil="true"></qgs:type>
3845+
<qgs:elevation xsi:nil="true"></qgs:elevation>
3846+
</qgs:points>
3847+
</gml:featureMember>
3848+
<gml:featureMember>
3849+
<qgs:points gml:id="points.5">
3850+
<gml:boundedBy>
3851+
<gml:Envelope srsName="EPSG:3857">
3852+
<gml:lowerCorner>-10977033.701121 3897159.3308746</gml:lowerCorner>
3853+
<gml:upperCorner>-10977033.701121 3897159.3308746</gml:upperCorner>
3854+
</gml:Envelope>
3855+
</gml:boundedBy>
3856+
<qgs:geometry>
3857+
<MultiPoint xmlns="http://www.opengis.net/gml" srsName="EPSG:3857">
3858+
<pointMember xmlns="http://www.opengis.net/gml">
3859+
<Point xmlns="http://www.opengis.net/gml">
3860+
<pos xmlns="http://www.opengis.net/gml" srsDimension="2">-10977033.701121 3897159.3308746</pos>
3861+
</Point>
3862+
</pointMember>
3863+
</MultiPoint>
3864+
</qgs:geometry>
3865+
<qgs:id>5</qgs:id>
3866+
<qgs:name>qgis</qgs:name>
3867+
<qgs:type>0</qgs:type>
3868+
<qgs:elevation xsi:nil="true"></qgs:elevation>
3869+
</qgs:points>
3870+
</gml:featureMember>
3871+
</wfs:FeatureCollection>"""
3872+
3873+
with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=points&MAXFEATURES=1&SRSNAME=urn:ogc:def:crs:EPSG::4326"""), 'wb') as f:
3874+
f.write(get_feature_1.encode('UTF-8'))
3875+
3876+
with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=points&SRSNAME=urn:ogc:def:crs:EPSG::4326"""), 'wb') as f:
3877+
f.write(get_features.encode('UTF-8'))
3878+
3879+
vl = QgsVectorLayer("url='http://" + endpoint + "' typename='points' version='1.1.0'", 'test', 'WFS')
3880+
self.assertTrue(vl.isValid())
3881+
3882+
# Fill the cache
3883+
[f for f in vl.getFeatures()]
3884+
3885+
qgis_feat = next(vl.getFeatures(QgsFeatureRequest(QgsExpression('"name" = \'qgis\''))))
3886+
other_feat = next(vl.getFeatures(QgsFeatureRequest(QgsExpression('"name" != \'qgis\''))))
3887+
self.assertEqual(qgis_feat['name'], 'qgis')
3888+
self.assertEqual(other_feat['name'], 'Xxx')
3889+
3890+
form_scope = QgsExpressionContextUtils.formScope(qgis_feat)
3891+
form_exp = QgsExpression('current_value(\'name\') = "name"')
3892+
ctx = QgsExpressionContext()
3893+
ctx.appendScope(form_scope)
3894+
ctx.setFeature(qgis_feat)
3895+
self.assertEqual(form_exp.evaluate(ctx), 1)
3896+
ctx.setFeature(other_feat)
3897+
self.assertEqual(form_exp.evaluate(ctx), 0)
3898+
3899+
# For real now! (this failed in issue 21077)
3900+
req = QgsFeatureRequest(form_exp)
3901+
req.setExpressionContext(ctx)
3902+
qgis_feat = next(vl.getFeatures(req))
3903+
3904+
37413905
if __name__ == '__main__':
37423906
unittest.main()

0 commit comments

Comments
 (0)