Skip to content
Permalink
Browse files

[WFS provider] Succesfully analyze DescribeFeatureType response with …

…<complexType> as inline element of <element> (#15395)
  • Loading branch information
rouault committed Aug 8, 2016
1 parent cb02b9f commit f17f6ac1396b555b27adacdd23edf3d5c318ec5f
Showing with 110 additions and 13 deletions.
  1. +22 −13 src/providers/wfs/qgswfsprovider.cpp
  2. +88 −0 tests/src/python/test_provider_wfs.py
@@ -1162,17 +1162,23 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
// collect the correspond type.
QDomElement elementElement = schemaElement.firstChildElement( "element" );
QString elementTypeString;
QDomElement complexTypeElement;
while ( !elementElement.isNull() )
{
QString name = elementElement.attribute( "name" );
if ( name == unprefixedTypename )
{
elementTypeString = elementElement.attribute( "type" );
if ( elementTypeString.isEmpty() )
{
// e.g http://afnemers.ruimtelijkeplannen.nl/afnemers2012/services?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=app:Bouwvlak
complexTypeElement = elementElement.firstChildElement( "complexType" );
}
break;
}
elementElement = elementElement.nextSiblingElement( "element" );
}
if ( elementTypeString.isEmpty() )
if ( elementTypeString.isEmpty() && complexTypeElement.isNull() )
{
// "http://demo.deegree.org/inspire-workspace/services/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=ad:Address"
QDomElement iter = schemaElement.firstChildElement();
@@ -1207,21 +1213,24 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
elementTypeString = elementTypeString.section( ':', 1 );
}

//the <complexType> element corresponding to the feature type
QDomElement complexTypeElement = schemaElement.firstChildElement( "complexType" );
while ( !complexTypeElement.isNull() )
if ( complexTypeElement.isNull() )
{
QString name = complexTypeElement.attribute( "name" );
if ( name == elementTypeString )
//the <complexType> element corresponding to the feature type
complexTypeElement = schemaElement.firstChildElement( "complexType" );
while ( !complexTypeElement.isNull() )
{
break;
QString name = complexTypeElement.attribute( "name" );
if ( name == elementTypeString )
{
break;
}
complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
}
if ( complexTypeElement.isNull() )
{
errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
return false;
}
complexTypeElement = complexTypeElement.nextSiblingElement( "complexType" );
}
if ( complexTypeElement.isNull() )
{
errorMsg = tr( "Cannot find ComplexType element '%1'" ).arg( elementTypeString );
return false;
}

//we have the relevant <complexType> element. Now find out the geometry and the thematic attributes
@@ -2102,6 +2102,94 @@ def testMapServerWFS1_1_EPSG_4326(self):
</gml:featureMember>
</wfs:FeatureCollection>
""".encode('UTF-8'))

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

got_f = [f for f in vl.getFeatures()]
got = got_f[0].geometry().geometry()
self.assertEqual((got.x(), got.y()), (2.0, 49.0))

def testDescribeFeatureTypeWithInlineType(self):
"""Test a DescribeFeatureType response with a inline ComplexType (#15395)."""

endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_testDescribeFeatureTypeWithInlineType'

with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.1.0'), 'wb') as f:
f.write("""
<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">
<FeatureTypeList>
<FeatureType>
<Name>my:typename</Name>
<Title>Title</Title>
<Abstract>Abstract</Abstract>
<DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>2 49</ows:LowerCorner>
<ows:UpperCorner>2 49</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
</FeatureTypeList>
</wfs:WFS_Capabilities>""".encode('UTF-8'))

with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=my:typename'), 'wb') as f:
f.write("""
<schema
targetNamespace="http://my"
xmlns:my="http://my"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:gml="http://www.opengis.net/gml"
elementFormDefault="qualified" version="0.1" >
<import namespace="http://www.opengis.net/gml"
schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
<element name="typename"
substitutionGroup="gml:_Feature">
<complexType>
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element name="geometryProperty" type="gml:GeometryPropertyType" minOccurs="0" maxOccurs="1"/>
</sequence>
</extension>
</complexContent>
</complexType>
</element>
</schema>
""".encode('UTF-8'))

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:
f.write("""
<wfs:FeatureCollection
xmlns:my="http://my"
xmlns:gml="http://www.opengis.net/gml"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:ogc="http://www.opengis.net/ogc">
<gml:boundedBy>
<gml:Envelope srsName="EPSG:4326">
<gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
<gml:upperCorner>49.000000 2.000000</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<gml:featureMember>
<my:typename gml:id="typename.1">
<gml:boundedBy>
<gml:Envelope srsName="EPSG:4326">
<gml:lowerCorner>49.000000 2.000000</gml:lowerCorner>
<gml:upperCorner>49.000000 2.000000</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<my:geometryProperty>
<gml:Point srsName="EPSG:4326">
<gml:pos>49.000000 2.000000</gml:pos>
</gml:Point>
</my:geometryProperty>
</my:typename>
</gml:featureMember>
</wfs:FeatureCollection>
""".encode('UTF-8'))

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

0 comments on commit f17f6ac

Please sign in to comment.
You can’t perform that action at this time.