[WFS provider] Succesfully analyze DescribeFeatureType response with <complexType> as inline element of <element> (#15395)

This commit is contained in:
Even Rouault 2016-08-08 15:11:50 +02:00
parent 23c83b1e93
commit 4bcbc1e4e7
2 changed files with 111 additions and 14 deletions

View File

@ -1161,17 +1161,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();
@ -1206,8 +1212,10 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
elementTypeString = elementTypeString.section( ':', 1 );
}
if ( complexTypeElement.isNull() )
{
//the <complexType> element corresponding to the feature type
QDomElement complexTypeElement = schemaElement.firstChildElement( "complexType" );
complexTypeElement = schemaElement.firstChildElement( "complexType" );
while ( !complexTypeElement.isNull() )
{
QString name = complexTypeElement.attribute( "name" );
@ -1222,6 +1230,7 @@ bool QgsWFSProvider::readAttributesFromSchema( QDomDocument& schemaDoc,
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
QDomNodeList attributeNodeList = complexTypeElement.elementsByTagNameNS( QgsWFSConstants::XMLSCHEMA_NAMESPACE, "element" );

View File

@ -2102,6 +2102,94 @@ class TestPyQgsWFSProvider(unittest.TestCase, ProviderTestCase):
</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')