From af7b6be3111d4eac8b5c8319758ddbb926065f56 Mon Sep 17 00:00:00 2001 From: Marco Hugentobler Date: Wed, 2 Apr 2014 21:46:42 +0200 Subject: [PATCH] Re-enable WFS Server --- src/mapserver/qgswfsprojectparser.cpp | 203 ++++++++++++++++++++++++++ src/mapserver/qgswfsprojectparser.h | 6 + src/mapserver/qgswfsserver.cpp | 16 -- 3 files changed, 209 insertions(+), 16 deletions(-) diff --git a/src/mapserver/qgswfsprojectparser.cpp b/src/mapserver/qgswfsprojectparser.cpp index 251d81fed0ff..f0a94ac46e41 100644 --- a/src/mapserver/qgswfsprojectparser.cpp +++ b/src/mapserver/qgswfsprojectparser.cpp @@ -17,6 +17,7 @@ #include "qgswfsprojectparser.h" #include "qgsconfigparserutils.h" +#include "qgsmaplayerregistry.h" #include "qgsvectordataprovider.h" QgsWFSProjectParser::QgsWFSProjectParser( QDomDocument* xmlDoc, const QString& filePath ): @@ -392,3 +393,205 @@ QStringList QgsWFSProjectParser::wfstDeleteLayers() const } return wfsList; } + +void QgsWFSProjectParser::describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const +{ + const QList& projectLayerElements = mProjectParser.projectLayerElements(); + if ( projectLayerElements.size() < 1 ) + { + return; + } + + QStringList wfsLayersId = mProjectParser.wfsLayers(); + QStringList typeNameList; + if ( aTypeName != "" ) + { + QStringList typeNameSplit = aTypeName.split( "," ); + foreach ( const QString &str, typeNameSplit ) + { + if ( str.contains( ":" ) ) + typeNameList << str.section( ":", 1, 1 ); + else + typeNameList << str; + } + } + + foreach ( const QDomElement &elem, projectLayerElements ) + { + QString type = elem.attribute( "type" ); + if ( type == "vector" ) + { + //addJoinLayersForElement( elem ); //todo: fixme + QgsMapLayer *mLayer = mProjectParser.createLayerFromElement( elem ); + QgsVectorLayer* layer = dynamic_cast( mLayer ); + if ( !layer ) + continue; + + QString typeName = layer->name(); + typeName = typeName.replace( " ", "_" ); + + if ( wfsLayersId.contains( layer->id() ) && ( aTypeName == "" || typeNameList.contains( typeName ) ) ) + { + //do a select with searchRect and go through all the features + QgsVectorDataProvider* provider = layer->dataProvider(); + if ( !provider ) + { + continue; + } + + //hidden attributes for this layer + const QSet& layerExcludedAttributes = layer->excludeAttributesWFS(); + + //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(); + if ( wkbType != QGis::WKBNoGeometry ) + { + 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 QgsFields& fields = provider->fields(); + const QgsFields& fields = layer->pendingFields(); + for ( int idx = 0; idx < fields.count(); ++idx ) + { + + QString attributeName = fields[idx].name(); + //skip attribute if excluded from WFS publication + if ( layerExcludedAttributes.contains( attributeName ) ) + { + continue; + } + + //xsd:element + QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); + geomElem.setAttribute( "name", attributeName ); + QVariant::Type attributeType = fields[idx].type(); + if ( attributeType == QVariant::Int ) + geomElem.setAttribute( "type", "integer" ); + else if ( attributeType == QVariant::Double ) + geomElem.setAttribute( "type", "double" ); + else + geomElem.setAttribute( "type", "string" ); + + sequenceElem.appendChild( geomElem ); + + QString alias = layer->attributeAlias( idx ); + if ( !alias.isEmpty() ) + { + geomElem.setAttribute( "alias", alias ); + } + } + } + } + } + QgsMapLayerRegistry::instance()->removeAllMapLayers(); + return; +} + +QStringList QgsWFSProjectParser::wfsLayers() const +{ + return mProjectParser.wfsLayers(); +} + +QList QgsWFSProjectParser::mapLayerFromTypeName( const QString& aTypeName, bool useCache ) const +{ + QList layerList; + const QList& projectLayerElements = mProjectParser.projectLayerElements(); + + if ( projectLayerElements.size() < 1 ) + { + return layerList; + } + QStringList wfsLayersId = wfsLayers(); + + QStringList typeNameList; + if ( aTypeName != "" ) + { + QStringList typeNameSplit = aTypeName.split( "," ); + foreach ( const QString &str, typeNameSplit ) + { + if ( str.contains( ":" ) ) + typeNameList << str.section( ":", 1, 1 ); + else + typeNameList << str; + } + } + + foreach ( const QDomElement &elem, projectLayerElements ) + { + QString type = elem.attribute( "type" ); + if ( type == "vector" ) + { + //addJoinLayersForElement( elem, useCache ); //todo: fixme + QgsMapLayer *mLayer = mProjectParser.createLayerFromElement( elem ); + QgsVectorLayer* layer = dynamic_cast( mLayer ); + if ( !layer ) + continue; + + QString typeName = layer->name(); + typeName = typeName.replace( " ", "_" ); + + if ( wfsLayersId.contains( layer->id() ) && ( aTypeName == "" || typeNameList.contains( typeName ) ) ) + layerList.push_back( mLayer ); + } + } + return layerList; +} diff --git a/src/mapserver/qgswfsprojectparser.h b/src/mapserver/qgswfsprojectparser.h index 37f52a5e2a7f..a3c4bcff70e2 100644 --- a/src/mapserver/qgswfsprojectparser.h +++ b/src/mapserver/qgswfsprojectparser.h @@ -31,6 +31,12 @@ class QgsWFSProjectParser QString wfsServiceUrl() const; void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const; + void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const; + + QStringList wfsLayers() const; + + QList mapLayerFromTypeName( const QString& aTypeName, bool useCache = true ) const; + private: QgsServerProjectParser mProjectParser; diff --git a/src/mapserver/qgswfsserver.cpp b/src/mapserver/qgswfsserver.cpp index e9d1a6036b29..09c9a0a36852 100644 --- a/src/mapserver/qgswfsserver.cpp +++ b/src/mapserver/qgswfsserver.cpp @@ -307,8 +307,6 @@ QDomDocument QgsWFSServer::describeFeatureType() QgsDebugMsg( "Entering." ); QDomDocument doc; -#if 0 //todo: fixme - //xsd:schema QDomElement schemaElement = doc.createElement( "schema"/*xsd:schema*/ ); schemaElement.setAttribute( "xmlns", "http://www.w3.org/2001/XMLSchema" ); @@ -364,14 +362,11 @@ QDomDocument QgsWFSServer::describeFeatureType() mConfigParser->describeFeatureType( typeName, schemaElement, doc ); } -#endif //0 //todo: fixme - return doc; } int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format ) { -#if 0 //todo: fixme QgsDebugMsg( "Info format is:" + format ); QStringList wfsLayersId = mConfigParser->wfsLayers(); @@ -1080,14 +1075,11 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format else endGetFeature( request, format ); -#endif // 0 //todo: fixme - return 0; } void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect ) { -#if 0 //todo: fixme QByteArray result; QString fcString; if ( format == "GeoJSON" ) @@ -1214,9 +1206,6 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f request.sendGetFeatureResponse( &result ); } fcString = ""; - -#endif //0 //todo: fixme - } void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QgsAttributeList attrIndexes, QSet excludedAttributes ) /*const*/ @@ -1286,9 +1275,6 @@ QDomDocument QgsWFSServer::transaction( const QString& requestBody ) { // Getting the transaction document QDomDocument doc; - return doc; - -#if 0 //todo: fixme QString errorMsg; if ( !doc.setContent( requestBody, true, &errorMsg ) ) @@ -1650,8 +1636,6 @@ QDomDocument QgsWFSServer::transaction( const QString& requestBody ) respElem.appendChild( trElem ); return resp; - -#endif //0 //todo: fixme } QgsFeatureIds QgsWFSServer::getFeatureIdsFromFilter( QDomElement filterElem, QgsVectorLayer* layer )