diff --git a/src/mapserver/qgsconfigparser.h b/src/mapserver/qgsconfigparser.h index 682463d..09b3bad 100644 --- a/src/mapserver/qgsconfigparser.h +++ b/src/mapserver/qgsconfigparser.h @@ -44,6 +44,8 @@ class QgsConfigParser virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0; + virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const = 0; + /**Returns one or possibly several maplayers for a given layer name and style. If there are several layers, the layers should be drawn in inverse list order. If no layers/style are found, an empty list is returned @param allowCache true if layer can be read from / written to cache*/ diff --git a/src/mapserver/qgsprojectparser.cpp b/src/mapserver/qgsprojectparser.cpp index 5bd1080..4ab27ca 100644 --- a/src/mapserver/qgsprojectparser.cpp +++ b/src/mapserver/qgsprojectparser.cpp @@ -25,6 +25,7 @@ #include "qgsrasterlayer.h" #include "qgsrenderer.h" #include "qgsvectorlayer.h" +#include "qgsvectordataprovider.h" #include "qgscomposition.h" #include "qgscomposerarrow.h" @@ -212,6 +213,151 @@ void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument return; } +void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const +{ + if ( mProjectLayerElements.size() < 1 ) + { + return; + } + + QStringList wfsLayersId = wfsLayers(); + QMap< QString, QMap< int, QString > > aliasInfo = layerAliasInfo(); + QMap< QString, QSet > hiddenAttrs = hiddenAttributes(); + + foreach( const QDomElement &elem, mProjectLayerElements ) + { + QString type = elem.attribute( "type" ); + if ( type == "vector" ) + { + QgsMapLayer *mLayer = createLayerFromElement( elem ); + QgsVectorLayer* layer = dynamic_cast( mLayer ); + if ( layer && wfsLayersId.contains( layer->id() ) && ( aTypeName == "" || layer->name() == aTypeName ) ) + { + //do a select with searchRect and go through all the features + QgsVectorDataProvider* provider = layer->dataProvider(); + if ( !provider ) + { + continue; + } + + //is there alias info for this vector layer? + QMap< int, QString > layerAliasInfo; + QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( mLayer->id() ); + if ( aliasIt != aliasInfo.constEnd() ) + { + layerAliasInfo = aliasIt.value(); + } + + //hidden attributes for this layer + QSet layerHiddenAttributes; + QMap< QString, QSet >::const_iterator hiddenIt = hiddenAttrs.find( mLayer->id() ); + if ( hiddenIt != hiddenAttrs.constEnd() ) + { + layerHiddenAttributes = hiddenIt.value(); + } + + QString typeName = layer->name(); + typeName = typeName.replace( QString( " " ), QString( "_" ) ); + + //xsd:element + QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ ); + elementElem.setAttribute( "name", typeName ); + elementElem.setAttribute( "type", "qgs:" + typeName + "Type" ); + elementElem.setAttribute( "substitutionGroup", "gml:_Feature" ); + parentElement.appendChild( elementElem ); + + //xsd:complexType + QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ ); + complexTypeElem.setAttribute( "name", typeName + "Type" ); + parentElement.appendChild( complexTypeElem ); + + //xsd:complexType + QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ ); + complexTypeElem.appendChild( complexContentElem ); + + //xsd:extension + QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ ); + extensionElem.setAttribute( "base", "gml:AbstractFeatureType" ); + complexContentElem.appendChild( extensionElem ); + + //xsd:sequence + QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ ); + extensionElem.appendChild( sequenceElem ); + + //xsd:element + QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); + geomElem.setAttribute( "name", "geometry" ); + QGis::WkbType wkbType = layer->wkbType(); + switch ( wkbType ) + { + case QGis::WKBPoint25D: + case QGis::WKBPoint: + geomElem.setAttribute( "type", "gml:PointPropertyType" ); + break; + case QGis::WKBLineString25D: + case QGis::WKBLineString: + geomElem.setAttribute( "type", "gml:LineStringPropertyType" ); + break; + case QGis::WKBPolygon25D: + case QGis::WKBPolygon: + geomElem.setAttribute( "type", "gml:PolygonPropertyType" ); + break; + case QGis::WKBMultiPoint25D: + case QGis::WKBMultiPoint: + geomElem.setAttribute( "type", "gml:MultiPointPropertyType" ); + break; + case QGis::WKBMultiLineString25D: + case QGis::WKBMultiLineString: + geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" ); + break; + case QGis::WKBMultiPolygon25D: + case QGis::WKBMultiPolygon: + geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" ); + break; + default: + geomElem.setAttribute( "type", "gml:GeometryPropertyType" ); + break; + } + geomElem.setAttribute( "minOccurs", "0" ); + geomElem.setAttribute( "maxOccurs", "1" ); + sequenceElem.appendChild( geomElem ); + + const QgsFieldMap& fields = provider->fields(); + for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it ) + { + + QString attributeName = it.value().name(); + //skip attribute if it has edit type 'hidden' + if ( layerHiddenAttributes.contains( attributeName ) ) + { + continue; + } + + //xsd:element + QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); + geomElem.setAttribute( "name", attributeName ); + if ( it.value().type() == 2 ) + geomElem.setAttribute( "type", "integer" ); + else if ( it.value().type() == 6 ) + geomElem.setAttribute( "type", "double" ); + else + geomElem.setAttribute( "type", "string" ); + + sequenceElem.appendChild( geomElem ); + + //check if the attribute name should be replaced with an alias + QMap::const_iterator aliasIt = layerAliasInfo.find( it.key() ); + if ( aliasIt != layerAliasInfo.constEnd() ) + { + geomElem.setAttribute( "alias", aliasIt.value() ); + } + } + } + } + } + return; +} + void QgsProjectParser::addLayers( QDomDocument &doc, QDomElement &parentElem, const QDomElement &legendElem, diff --git a/src/mapserver/qgsprojectparser.h b/src/mapserver/qgsprojectparser.h index b513800..4a39a1e 100644 --- a/src/mapserver/qgsprojectparser.h +++ b/src/mapserver/qgsprojectparser.h @@ -40,6 +40,8 @@ class QgsProjectParser: public QgsConfigParser virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const; + virtual void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const; + int numberOfLayers() const; /**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/ diff --git a/src/mapserver/qgssldparser.h b/src/mapserver/qgssldparser.h index 0a3422e..d286084 100644 --- a/src/mapserver/qgssldparser.h +++ b/src/mapserver/qgssldparser.h @@ -57,6 +57,8 @@ class QgsSLDParser: public QgsConfigParser void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const; void featureTypeList( QDomElement &, QDomDocument & ) const {}; + + void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const {}; /**Returns number of layers in configuration*/ int numberOfLayers() const; diff --git a/src/mapserver/qgswfsserver.cpp b/src/mapserver/qgswfsserver.cpp index 6ca2ebe..de06202 100644 --- a/src/mapserver/qgswfsserver.cpp +++ b/src/mapserver/qgswfsserver.cpp @@ -263,143 +263,9 @@ QDomDocument QgsWFSServer::describeFeatureType() } else { - return doc; + typeName = ""; } - - QStringList wfsLayersId = mConfigParser->wfsLayers(); - QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); - QMap< QString, QSet > hiddenAttributes = mConfigParser->hiddenAttributes(); - - QList layerList; - QgsMapLayer* currentLayer = 0; - - layerList = mConfigParser->mapLayerFromStyle( typeName, "" ); - currentLayer = layerList.at( 0 ); - - QgsVectorLayer* layer = dynamic_cast( currentLayer ); - if ( layer && wfsLayersId.contains( layer->id() ) ) - { - //is there alias info for this vector layer? - QMap< int, QString > layerAliasInfo; - QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); - if ( aliasIt != aliasInfo.constEnd() ) - { - layerAliasInfo = aliasIt.value(); - } - - //hidden attributes for this layer - QSet layerHiddenAttributes; - QMap< QString, QSet >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); - if ( hiddenIt != hiddenAttributes.constEnd() ) - { - layerHiddenAttributes = hiddenIt.value(); - } - - //do a select with searchRect and go through all the features - QgsVectorDataProvider* provider = layer->dataProvider(); - if ( !provider ) - { - return doc; - } - - typeName = typeName.replace( QString( " " ), QString( "_" ) ); - - //xsd:element - QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ ); - elementElem.setAttribute( "name", typeName ); - elementElem.setAttribute( "type", "qgs:" + typeName + "Type" ); - elementElem.setAttribute( "substitutionGroup", "gml:_Feature" ); - schemaElement.appendChild( elementElem ); - - //xsd:complexType - QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ ); - complexTypeElem.setAttribute( "name", typeName + "Type" ); - schemaElement.appendChild( complexTypeElem ); - - //xsd:complexType - QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ ); - complexTypeElem.appendChild( complexContentElem ); - - //xsd:extension - QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ ); - extensionElem.setAttribute( "base", "gml:AbstractFeatureType" ); - complexContentElem.appendChild( extensionElem ); - - //xsd:sequence - QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ ); - extensionElem.appendChild( sequenceElem ); - - //xsd:element - QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); - geomElem.setAttribute( "name", "geometry" ); - QGis::WkbType wkbType = layer->wkbType(); - switch ( wkbType ) - { - case QGis::WKBPoint25D: - case QGis::WKBPoint: - geomElem.setAttribute( "type", "gml:PointPropertyType" ); - break; - case QGis::WKBLineString25D: - case QGis::WKBLineString: - geomElem.setAttribute( "type", "gml:LineStringPropertyType" ); - break; - case QGis::WKBPolygon25D: - case QGis::WKBPolygon: - geomElem.setAttribute( "type", "gml:PolygonPropertyType" ); - break; - case QGis::WKBMultiPoint25D: - case QGis::WKBMultiPoint: - geomElem.setAttribute( "type", "gml:MultiPointPropertyType" ); - break; - case QGis::WKBMultiLineString25D: - case QGis::WKBMultiLineString: - geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" ); - break; - case QGis::WKBMultiPolygon25D: - case QGis::WKBMultiPolygon: - geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" ); - break; - default: - geomElem.setAttribute( "type", "gml:GeometryPropertyType" ); - break; - } - geomElem.setAttribute( "minOccurs", "0" ); - geomElem.setAttribute( "maxOccurs", "1" ); - sequenceElem.appendChild( geomElem ); - - const QgsFieldMap& fields = provider->fields(); - for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it ) - { - - QString attributeName = it.value().name(); - //skip attribute if it has edit type 'hidden' - if ( layerHiddenAttributes.contains( attributeName ) ) - { - continue; - } - - //xsd:element - QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); - geomElem.setAttribute( "name", attributeName ); - if ( it.value().type() == 2 ) - geomElem.setAttribute( "type", "integer" ); - else if ( it.value().type() == 6 ) - geomElem.setAttribute( "type", "double" ); - else - geomElem.setAttribute( "type", "string" ); - - sequenceElem.appendChild( geomElem ); - - //check if the attribute name should be replaced with an alias - QMap::const_iterator aliasIt = layerAliasInfo.find( it.key() ); - if ( aliasIt != layerAliasInfo.constEnd() ) - { - geomElem.setAttribute( "alias", aliasIt.value() ); - } - - } - } - + mConfigParser->describeFeatureType( typeName, schemaElement, doc); return doc; }