Skip to content

Commit 85fdf4e

Browse files
authoredOct 12, 2018
Merge pull request #8159 from rldhont/server-wfs-enhance-describeFeatureType-218
[Bugfix][Server] WFS: enhancing the way DescribeFeatureType response is build
2 parents 942a560 + fde6d93 commit 85fdf4e

File tree

1 file changed

+156
-169
lines changed

1 file changed

+156
-169
lines changed
 

‎src/server/qgswfsprojectparser.cpp

Lines changed: 156 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgsvectordataprovider.h"
2323
#include "qgsmapserviceexception.h"
2424
#include "qgsaccesscontrol.h"
25+
#include "qgsmessagelog.h"
2526

2627
QgsWFSProjectParser::QgsWFSProjectParser(
2728
const QString& filePath
@@ -321,36 +322,18 @@ QSet<QString> QgsWFSProjectParser::wfstDeleteLayers() const
321322

322323
void QgsWFSProjectParser::describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const
323324
{
324-
const QList<QDomElement>& projectLayerElements = mProjectParser->projectLayerElements();
325-
if ( projectLayerElements.size() < 1 )
326-
{
327-
return;
328-
}
329-
330325
QStringList wfsLayersId = mProjectParser->wfsLayers();
331-
QStringList typeNameList;
332-
if ( aTypeName != "" )
326+
if ( wfsLayersId.size() < 1 )
333327
{
334-
QStringList typeNameSplit = aTypeName.split( "," );
335-
Q_FOREACH ( const QString &str, typeNameSplit )
336-
{
337-
if ( str.contains( ":" ) )
338-
typeNameList << str.section( ":", 1, 1 );
339-
else
340-
typeNameList << str;
341-
}
328+
return;
342329
}
343330

344-
Q_FOREACH ( const QDomElement &elem, projectLayerElements )
331+
QList<QgsMapLayer*> layerList = mapLayerFromTypeName( aTypeName );
332+
Q_FOREACH ( QgsMapLayer* currentLayer, layerList )
345333
{
346-
QString type = elem.attribute( "type" );
347-
if ( type == "vector" )
334+
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( currentLayer );
335+
if ( layer && wfsLayersId.contains( layer->id() ) )
348336
{
349-
QgsMapLayer *mLayer = mProjectParser->createLayerFromElement( elem );
350-
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( mLayer );
351-
if ( !layer )
352-
continue;
353-
354337
#ifdef HAVE_SERVER_PYTHON_PLUGINS
355338
if ( !mAccessControl->layerReadPermission( layer ) )
356339
{
@@ -363,164 +346,161 @@ void QgsWFSProjectParser::describeFeatureType( const QString& aTypeName, QDomEle
363346
typeName = layer->shortName();
364347
typeName = typeName.replace( " ", "_" );
365348

366-
if ( wfsLayersId.contains( layer->id() ) && ( aTypeName == "" || typeNameList.contains( typeName ) ) )
349+
//do a select with searchRect and go through all the features
350+
QgsVectorDataProvider* provider = layer->dataProvider();
351+
if ( !provider )
367352
{
368-
//do a select with searchRect and go through all the features
369-
QgsVectorDataProvider* provider = layer->dataProvider();
370-
if ( !provider )
371-
{
372-
continue;
373-
}
353+
continue;
354+
}
374355

375-
//hidden attributes for this layer
376-
const QSet<QString>& layerExcludedAttributes = layer->excludeAttributesWFS();
356+
//hidden attributes for this layer
357+
const QSet<QString>& layerExcludedAttributes = layer->excludeAttributesWFS();
377358

378-
//xsd:element
379-
QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ );
380-
elementElem.setAttribute( "name", typeName );
381-
elementElem.setAttribute( "type", "qgs:" + typeName + "Type" );
382-
elementElem.setAttribute( "substitutionGroup", "gml:_Feature" );
383-
parentElement.appendChild( elementElem );
384-
385-
//xsd:complexType
386-
QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ );
387-
complexTypeElem.setAttribute( "name", typeName + "Type" );
388-
parentElement.appendChild( complexTypeElem );
389-
390-
//xsd:complexType
391-
QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ );
392-
complexTypeElem.appendChild( complexContentElem );
393-
394-
//xsd:extension
395-
QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ );
396-
extensionElem.setAttribute( "base", "gml:AbstractFeatureType" );
397-
complexContentElem.appendChild( extensionElem );
398-
399-
//xsd:sequence
400-
QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ );
401-
extensionElem.appendChild( sequenceElem );
359+
//xsd:element
360+
QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ );
361+
elementElem.setAttribute( "name", typeName );
362+
elementElem.setAttribute( "type", "qgs:" + typeName + "Type" );
363+
elementElem.setAttribute( "substitutionGroup", "gml:_Feature" );
364+
parentElement.appendChild( elementElem );
402365

403-
//xsd:element
404-
if ( layer->hasGeometryType() )
366+
//xsd:complexType
367+
QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ );
368+
complexTypeElem.setAttribute( "name", typeName + "Type" );
369+
parentElement.appendChild( complexTypeElem );
370+
371+
//xsd:complexType
372+
QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ );
373+
complexTypeElem.appendChild( complexContentElem );
374+
375+
//xsd:extension
376+
QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ );
377+
extensionElem.setAttribute( "base", "gml:AbstractFeatureType" );
378+
complexContentElem.appendChild( extensionElem );
379+
380+
//xsd:sequence
381+
QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ );
382+
extensionElem.appendChild( sequenceElem );
383+
384+
//xsd:element
385+
if ( layer->hasGeometryType() )
386+
{
387+
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
388+
geomElem.setAttribute( "name", "geometry" );
389+
if ( provider->name() == "ogr" )
405390
{
406-
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
407-
geomElem.setAttribute( "name", "geometry" );
408-
if ( provider->name() == "ogr" )
409-
{
410-
// because some ogr drivers (e.g. ESRI ShapeFile, GML)
411-
// are not able to determine the geometry type of a layer.
412-
// we set to GeometryType
413-
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
414-
}
415-
else
391+
// because some ogr drivers (e.g. ESRI ShapeFile, GML)
392+
// are not able to determine the geometry type of a layer.
393+
// we set to GeometryType
394+
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
395+
}
396+
else
397+
{
398+
QGis::WkbType wkbType = layer->wkbType();
399+
switch ( wkbType )
416400
{
417-
QGis::WkbType wkbType = layer->wkbType();
418-
switch ( wkbType )
419-
{
420-
case QGis::WKBPoint25D:
421-
case QGis::WKBPoint:
422-
geomElem.setAttribute( "type", "gml:PointPropertyType" );
423-
break;
424-
case QGis::WKBLineString25D:
425-
case QGis::WKBLineString:
426-
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
427-
break;
428-
case QGis::WKBPolygon25D:
429-
case QGis::WKBPolygon:
430-
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
431-
break;
432-
case QGis::WKBMultiPoint25D:
433-
case QGis::WKBMultiPoint:
434-
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
435-
break;
436-
case QGis::WKBMultiLineString25D:
437-
case QGis::WKBMultiLineString:
438-
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
439-
break;
440-
case QGis::WKBMultiPolygon25D:
441-
case QGis::WKBMultiPolygon:
442-
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
443-
break;
444-
default:
445-
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
446-
break;
447-
}
401+
case QGis::WKBPoint25D:
402+
case QGis::WKBPoint:
403+
geomElem.setAttribute( "type", "gml:PointPropertyType" );
404+
break;
405+
case QGis::WKBLineString25D:
406+
case QGis::WKBLineString:
407+
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
408+
break;
409+
case QGis::WKBPolygon25D:
410+
case QGis::WKBPolygon:
411+
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
412+
break;
413+
case QGis::WKBMultiPoint25D:
414+
case QGis::WKBMultiPoint:
415+
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
416+
break;
417+
case QGis::WKBMultiLineString25D:
418+
case QGis::WKBMultiLineString:
419+
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
420+
break;
421+
case QGis::WKBMultiPolygon25D:
422+
case QGis::WKBMultiPolygon:
423+
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
424+
break;
425+
default:
426+
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
427+
break;
448428
}
449-
geomElem.setAttribute( "minOccurs", "0" );
450-
geomElem.setAttribute( "maxOccurs", "1" );
451-
sequenceElem.appendChild( geomElem );
452429
}
430+
geomElem.setAttribute( "minOccurs", "0" );
431+
geomElem.setAttribute( "maxOccurs", "1" );
432+
sequenceElem.appendChild( geomElem );
433+
}
453434

454-
//const QgsFields& fields = provider->fields();
455-
const QgsFields& fields = layer->pendingFields();
456-
for ( int idx = 0; idx < fields.count(); ++idx )
435+
//const QgsFields& fields = provider->fields();
436+
const QgsFields& fields = layer->pendingFields();
437+
for ( int idx = 0; idx < fields.count(); ++idx )
438+
{
439+
const QgsField field = fields.at( idx );
440+
QString attributeName = field.name();
441+
//skip attribute if excluded from WFS publication
442+
if ( layerExcludedAttributes.contains( attributeName ) )
457443
{
458-
const QgsField field = fields.at( idx );
459-
QString attributeName = field.name();
460-
//skip attribute if excluded from WFS publication
461-
if ( layerExcludedAttributes.contains( attributeName ) )
462-
{
463-
continue;
464-
}
444+
continue;
445+
}
465446

466-
//xsd:element
467-
QDomElement attElem = doc.createElement( "element"/*xsd:element*/ );
468-
attElem.setAttribute( "name", attributeName.replace( " ", "_" ).replace( mCleanTagNameRegExp, "" ) );
469-
QVariant::Type attributeType = field.type();
470-
if ( attributeType == QVariant::Int )
471-
{
472-
attElem.setAttribute( "type", "int" );
473-
}
474-
else if ( attributeType == QVariant::UInt )
475-
{
476-
attElem.setAttribute( "type", "unsignedInt" );
477-
}
478-
else if ( attributeType == QVariant::LongLong )
479-
{
480-
attElem.setAttribute( "type", "long" );
481-
}
482-
else if ( attributeType == QVariant::ULongLong )
483-
{
484-
attElem.setAttribute( "type", "unsignedLong" );
485-
}
486-
else if ( attributeType == QVariant::Double )
487-
{
488-
// if the size is well known, it may be an integer
489-
// else a decimal
490-
// in sqlite the length is unknown but int type can be used
491-
if ( field.length() != 0 && field.precision() == 0 )
492-
attElem.setAttribute( "type", "integer" );
493-
else
494-
attElem.setAttribute( "type", "decimal" );
495-
}
496-
else if ( attributeType == QVariant::Bool )
497-
{
498-
attElem.setAttribute( "type", "boolean" );
499-
}
500-
else if ( attributeType == QVariant::Date )
501-
{
502-
attElem.setAttribute( "type", "date" );
503-
}
504-
else if ( attributeType == QVariant::Time )
505-
{
506-
attElem.setAttribute( "type", "time" );
507-
}
508-
else if ( attributeType == QVariant::DateTime )
509-
{
510-
attElem.setAttribute( "type", "dateTime" );
511-
}
447+
//xsd:element
448+
QDomElement attElem = doc.createElement( "element"/*xsd:element*/ );
449+
attElem.setAttribute( "name", attributeName.replace( " ", "_" ).replace( mCleanTagNameRegExp, "" ) );
450+
QVariant::Type attributeType = field.type();
451+
if ( attributeType == QVariant::Int )
452+
{
453+
attElem.setAttribute( "type", "int" );
454+
}
455+
else if ( attributeType == QVariant::UInt )
456+
{
457+
attElem.setAttribute( "type", "unsignedInt" );
458+
}
459+
else if ( attributeType == QVariant::LongLong )
460+
{
461+
attElem.setAttribute( "type", "long" );
462+
}
463+
else if ( attributeType == QVariant::ULongLong )
464+
{
465+
attElem.setAttribute( "type", "unsignedLong" );
466+
}
467+
else if ( attributeType == QVariant::Double )
468+
{
469+
// if the size is well known, it may be an integer
470+
// else a decimal
471+
// in sqlite the length is unknown but int type can be used
472+
if ( field.length() != 0 && field.precision() == 0 )
473+
attElem.setAttribute( "type", "integer" );
512474
else
513-
{
514-
attElem.setAttribute( "type", "string" );
515-
}
475+
attElem.setAttribute( "type", "decimal" );
476+
}
477+
else if ( attributeType == QVariant::Bool )
478+
{
479+
attElem.setAttribute( "type", "boolean" );
480+
}
481+
else if ( attributeType == QVariant::Date )
482+
{
483+
attElem.setAttribute( "type", "date" );
484+
}
485+
else if ( attributeType == QVariant::Time )
486+
{
487+
attElem.setAttribute( "type", "time" );
488+
}
489+
else if ( attributeType == QVariant::DateTime )
490+
{
491+
attElem.setAttribute( "type", "dateTime" );
492+
}
493+
else
494+
{
495+
attElem.setAttribute( "type", "string" );
496+
}
516497

517-
sequenceElem.appendChild( attElem );
498+
sequenceElem.appendChild( attElem );
518499

519-
QString alias = field.alias();
520-
if ( !alias.isEmpty() )
521-
{
522-
attElem.setAttribute( "alias", alias );
523-
}
500+
QString alias = field.alias();
501+
if ( !alias.isEmpty() )
502+
{
503+
attElem.setAttribute( "alias", alias );
524504
}
525505
}
526506
}
@@ -575,10 +555,15 @@ QList<QgsMapLayer*> QgsWFSProjectParser::mapLayerFromTypeName( const QString& aT
575555
{
576556
return layerList;
577557
}
558+
578559
QStringList wfsLayersId = wfsLayers();
560+
if ( wfsLayersId.size() < 1 )
561+
{
562+
return layerList;
563+
}
579564

580565
QStringList typeNameList;
581-
if ( aTypeName != "" )
566+
if ( !aTypeName.isEmpty() )
582567
{
583568
QStringList typeNameSplit = aTypeName.split( "," );
584569
Q_FOREACH ( const QString &str, typeNameSplit )
@@ -613,6 +598,8 @@ QList<QgsMapLayer*> QgsWFSProjectParser::mapLayerFromTypeName( const QString& aT
613598
continue;
614599

615600
layerList.push_back( mLayer );
601+
if ( !aTypeName.isEmpty() && typeNameList.count() == layerList.count() )
602+
break;
616603
}
617604
}
618605
return layerList;

0 commit comments

Comments
 (0)
Please sign in to comment.