2222#include " qgsvectordataprovider.h"
2323#include " qgsmapserviceexception.h"
2424#include " qgsaccesscontrol.h"
25+ #include " qgsmessagelog.h"
2526
2627QgsWFSProjectParser::QgsWFSProjectParser (
2728 const QString& filePath
@@ -321,36 +322,18 @@ QSet<QString> QgsWFSProjectParser::wfstDeleteLayers() const
321322
322323void 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