Skip to content

Commit f17f6ac

Browse files
committed
[WFS provider] Succesfully analyze DescribeFeatureType response with <complexType> as inline element of <element> (#15395)
1 parent cb02b9f commit f17f6ac

File tree

2 files changed

+110
-13
lines changed

2 files changed

+110
-13
lines changed

src/providers/wfs/qgswfsprovider.cpp

+22-13
Original file line numberDiff line numberDiff line change
@@ -1162,17 +1162,23 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
11621162
// collect the correspond type.
11631163
QDomElement elementElement = schemaElement.firstChildElement( "element" );
11641164
QString elementTypeString;
1165+
QDomElement complexTypeElement;
11651166
while ( !elementElement.isNull() )
11661167
{
11671168
QString name = elementElement.attribute( "name" );
11681169
if ( name == unprefixedTypename )
11691170
{
11701171
elementTypeString = elementElement.attribute( "type" );
1172+
if ( elementTypeString.isEmpty() )
1173+
{
1174+
// e.g http://afnemers.ruimtelijkeplannen.nl/afnemers2012/services?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=app:Bouwvlak
1175+
complexTypeElement = elementElement.firstChildElement( "complexType" );
1176+
}
11711177
break;
11721178
}
11731179
elementElement = elementElement.nextSiblingElement( "element" );
11741180
}
1175-
if ( elementTypeString.isEmpty() )
1181+
if ( elementTypeString.isEmpty() && complexTypeElement.isNull() )
11761182
{
11771183
// "http://demo.deegree.org/inspire-workspace/services/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=ad:Address"
11781184
QDomElement iter = schemaElement.firstChildElement();
@@ -1207,21 +1213,24 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
12071213
elementTypeString = elementTypeString.section( ':', 1 );
12081214
}
12091215

1210-
//the <complexType> element corresponding to the feature type
1211-
QDomElement complexTypeElement = schemaElement.firstChildElement( "complexType" );
1212-
while ( !complexTypeElement.isNull() )
1216+
if ( complexTypeElement.isNull() )
12131217
{
1214-
QString name = complexTypeElement.attribute( "name" );
1215-
if ( name == elementTypeString )
1218+
//the <complexType> element corresponding to the feature type
1219+
complexTypeElement = schemaElement.firstChildElement( "complexType" );
1220+
while ( !complexTypeElement.isNull() )
12161221
{
1217-
break;
1222+
QString name = complexTypeElement.attribute( "name" );
1223+
if ( name == elementTypeString )
1224+
{
1225+
break;
1226+
}
1227+
complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
1228+
}
1229+
if ( complexTypeElement.isNull() )
1230+
{
1231+
errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
1232+
return false;
12181233
}
1219-
complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
1220-
}
1221-
if ( complexTypeElement.isNull() )
1222-
{
1223-
errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
1224-
return false;
12251234
}
12261235

12271236
//we have the relevant <complexType> element. Now find out the geometry and the thematic attributes

tests/src/python/test_provider_wfs.py

+88
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,94 @@ def testMapServerWFS1_1_EPSG_4326(self):
21022102
</gml:featureMember>
21032103
</wfs:FeatureCollection>
21042104
2105+
""".encode('UTF-8'))
2106+
2107+
vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename' version='1.1.0'", u'test', u'WFS')
2108+
assert vl.isValid()
2109+
2110+
got_f = [f for f in vl.getFeatures()]
2111+
got = got_f[0].geometry().geometry()
2112+
self.assertEqual((got.x(), got.y()), (2.0, 49.0))
2113+
2114+
def testDescribeFeatureTypeWithInlineType(self):
2115+
"""Test a DescribeFeatureType response with a inline ComplexType (#15395)."""
2116+
2117+
endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_testDescribeFeatureTypeWithInlineType'
2118+
2119+
with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.1.0'), 'wb') as f:
2120+
f.write("""
2121+
<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">
2122+
<FeatureTypeList>
2123+
<FeatureType>
2124+
<Name>my:typename</Name>
2125+
<Title>Title</Title>
2126+
<Abstract>Abstract</Abstract>
2127+
<DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
2128+
<ows:WGS84BoundingBox>
2129+
<ows:LowerCorner>2 49</ows:LowerCorner>
2130+
<ows:UpperCorner>2 49</ows:UpperCorner>
2131+
</ows:WGS84BoundingBox>
2132+
</FeatureType>
2133+
</FeatureTypeList>
2134+
</wfs:WFS_Capabilities>""".encode('UTF-8'))
2135+
2136+
with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=my:typename'), 'wb') as f:
2137+
f.write("""
2138+
<schema
2139+
targetNamespace="http://my"
2140+
xmlns:my="http://my"
2141+
xmlns:ogc="http://www.opengis.net/ogc"
2142+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
2143+
xmlns="http://www.w3.org/2001/XMLSchema"
2144+
xmlns:gml="http://www.opengis.net/gml"
2145+
elementFormDefault="qualified" version="0.1" >
2146+
<import namespace="http://www.opengis.net/gml"
2147+
schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
2148+
<element name="typename"
2149+
substitutionGroup="gml:_Feature">
2150+
<complexType>
2151+
<complexContent>
2152+
<extension base="gml:AbstractFeatureType">
2153+
<sequence>
2154+
<element name="geometryProperty" type="gml:GeometryPropertyType" minOccurs="0" maxOccurs="1"/>
2155+
</sequence>
2156+
</extension>
2157+
</complexContent>
2158+
</complexType>
2159+
</element>
2160+
</schema>
2161+
""".encode('UTF-8'))
2162+
2163+
with open(sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&SRSNAME=urn:ogc:def:crs:EPSG::4326"""), 'wb') as f:
2164+
f.write("""
2165+
<wfs:FeatureCollection
2166+
xmlns:my="http://my"
2167+
xmlns:gml="http://www.opengis.net/gml"
2168+
xmlns:wfs="http://www.opengis.net/wfs"
2169+
xmlns:ogc="http://www.opengis.net/ogc">
2170+
<gml:boundedBy>
2171+
<gml:Envelope srsName="EPSG:4326">
2172+
<gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
2173+
<gml:upperCorner>49.000000 2.000000</gml:upperCorner>
2174+
</gml:Envelope>
2175+
</gml:boundedBy>
2176+
<gml:featureMember>
2177+
<my:typename gml:id="typename.1">
2178+
<gml:boundedBy>
2179+
<gml:Envelope srsName="EPSG:4326">
2180+
<gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
2181+
<gml:upperCorner>49.000000 2.000000</gml:upperCorner>
2182+
</gml:Envelope>
2183+
</gml:boundedBy>
2184+
<my:geometryProperty>
2185+
<gml:Point srsName="EPSG:4326">
2186+
<gml:pos>49.000000 2.000000</gml:pos>
2187+
</gml:Point>
2188+
</my:geometryProperty>
2189+
</my:typename>
2190+
</gml:featureMember>
2191+
</wfs:FeatureCollection>
2192+
21052193
""".encode('UTF-8'))
21062194

21072195
vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename' version='1.1.0'", u'test', u'WFS')

0 commit comments

Comments
 (0)