37 #ifdef HAVE_SERVER_PYTHON_PLUGINS
41 const QDomDocument *describeDocument =
nullptr;
43 #ifdef HAVE_SERVER_PYTHON_PLUGINS
45 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
47 describeDocument = &doc;
57 describeDocument = &doc;
61 describeDocument = &doc;
63 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
64 response.
write( describeDocument->toByteArray() );
79 if ( oFormat == QgsWfsParameters::Format::NONE )
81 QStringLiteral(
"OUTPUTFORMAT %1 is not supported" ).arg( wfsParameters.
outputFormatAsString() ) );
83 #ifdef HAVE_SERVER_PYTHON_PLUGINS
90 QDomElement schemaElement = doc.createElement( QStringLiteral(
"schema" ) );
91 schemaElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
92 schemaElement.setAttribute( QStringLiteral(
"xmlns:xsd" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
93 schemaElement.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
94 schemaElement.setAttribute( QStringLiteral(
"xmlns:gml" ),
GML_NAMESPACE );
95 schemaElement.setAttribute( QStringLiteral(
"xmlns:qgs" ),
QGS_NAMESPACE );
96 schemaElement.setAttribute( QStringLiteral(
"targetNamespace" ),
QGS_NAMESPACE );
97 schemaElement.setAttribute( QStringLiteral(
"elementFormDefault" ), QStringLiteral(
"qualified" ) );
98 schemaElement.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
99 doc.appendChild( schemaElement );
102 QDomElement importElement = doc.createElement( QStringLiteral(
"import" ) );
103 importElement.setAttribute( QStringLiteral(
"namespace" ),
GML_NAMESPACE );
104 if ( oFormat == QgsWfsParameters::Format::GML2 )
105 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
106 else if ( oFormat == QgsWfsParameters::Format::GML3 )
107 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
108 schemaElement.appendChild( importElement );
110 QStringList typeNameList;
111 QDomDocument queryDoc;
113 if ( queryDoc.setContent( request.
data(),
true, &errorMsg ) )
116 const QDomElement queryDocElem = queryDoc.documentElement();
117 const QDomNodeList docChildNodes = queryDocElem.childNodes();
118 if ( docChildNodes.size() )
120 for (
int i = 0; i < docChildNodes.size(); i++ )
122 const QDomElement docChildElem = docChildNodes.at( i ).toElement();
123 if ( docChildElem.tagName() == QLatin1String(
"TypeName" ) )
125 const QString
typeName = docChildElem.text().trimmed();
127 typeNameList <<
typeName.section(
':', 1, 1 );
136 typeNameList = wfsParameters.
typeNames();
150 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
154 #ifdef HAVE_SERVER_PYTHON_PLUGINS
157 if ( !typeNameList.isEmpty() )
189 QDomElement elementElem = doc.createElement( QStringLiteral(
"element" ) );
190 elementElem.setAttribute( QStringLiteral(
"name" ),
typeName );
191 elementElem.setAttribute( QStringLiteral(
"type" ),
"qgs:" +
typeName +
"Type" );
192 elementElem.setAttribute( QStringLiteral(
"substitutionGroup" ), QStringLiteral(
"gml:_Feature" ) );
193 parentElement.appendChild( elementElem );
196 QDomElement complexTypeElem = doc.createElement( QStringLiteral(
"complexType" ) );
197 complexTypeElem.setAttribute( QStringLiteral(
"name" ),
typeName +
"Type" );
198 parentElement.appendChild( complexTypeElem );
201 QDomElement complexContentElem = doc.createElement( QStringLiteral(
"complexContent" ) );
202 complexTypeElem.appendChild( complexContentElem );
205 QDomElement extensionElem = doc.createElement( QStringLiteral(
"extension" ) );
206 extensionElem.setAttribute( QStringLiteral(
"base" ), QStringLiteral(
"gml:AbstractFeatureType" ) );
207 complexContentElem.appendChild( extensionElem );
210 QDomElement sequenceElem = doc.createElement( QStringLiteral(
"sequence" ) );
211 extensionElem.appendChild( sequenceElem );
216 QDomElement geomElem = doc.createElement( QStringLiteral(
"element" ) );
217 geomElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
218 geomElem.setAttribute( QStringLiteral(
"type" ),
getGmlGeometryType( layer, format ) );
219 geomElem.setAttribute( QStringLiteral(
"minOccurs" ), QStringLiteral(
"0" ) );
220 geomElem.setAttribute( QStringLiteral(
"maxOccurs" ), QStringLiteral(
"1" ) );
221 sequenceElem.appendChild( geomElem );
227 for (
int idx = 0; idx < fields.
count(); ++idx )
238 QDomElement attElem = doc.createElement( QStringLiteral(
"element" ) );
239 attElem.setAttribute( QStringLiteral(
"name" ), attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
240 const QVariant::Type attributeType =
field.
type();
241 if ( attributeType == QVariant::Int )
243 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
245 else if ( attributeType == QVariant::UInt )
247 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedInt" ) );
249 else if ( attributeType == QVariant::LongLong )
251 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"long" ) );
253 else if ( attributeType == QVariant::ULongLong )
255 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedLong" ) );
257 else if ( attributeType == QVariant::Double )
260 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
262 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
264 else if ( attributeType == QVariant::Bool )
266 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"boolean" ) );
268 else if ( attributeType == QVariant::Date )
270 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
272 else if ( attributeType == QVariant::Time )
274 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
276 else if ( attributeType == QVariant::DateTime )
278 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
282 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"string" ) );
286 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
288 const QVariantMap config = setup.
config();
290 if ( fieldFormat == QLatin1String(
"yyyy-MM-dd" ) )
291 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
292 else if ( fieldFormat == QLatin1String(
"HH:mm:ss" ) )
293 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
295 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
297 else if ( setup.
type() == QStringLiteral(
"Range" ) )
299 const QVariantMap config = setup.
config();
300 if ( config.contains( QStringLiteral(
"Precision" ) ) )
305 const int configPrec( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
308 if ( configPrec == 0 )
309 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
311 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
318 attElem.setAttribute( QStringLiteral(
"nillable" ), QStringLiteral(
"true" ) );
321 sequenceElem.appendChild( attElem );
324 if ( !alias.isEmpty() )
326 attElem.setAttribute( QStringLiteral(
"alias" ), alias );
336 case QgsWfsParameters::Format::GML2:
341 return QStringLiteral(
"gml:PointPropertyType" );
345 return QStringLiteral(
"gml:LineStringPropertyType" );
349 return QStringLiteral(
"gml:PolygonPropertyType" );
353 return QStringLiteral(
"gml:MultiPointPropertyType" );
358 return QStringLiteral(
"gml:MultiLineStringPropertyType" );
363 return QStringLiteral(
"gml:MultiPolygonPropertyType" );
366 return QStringLiteral(
"gml:GeometryPropertyType" );
369 case QgsWfsParameters::Format::GML3:
374 return QStringLiteral(
"gml:PointPropertyType" );
378 return QStringLiteral(
"gml:LineStringPropertyType" );
382 return QStringLiteral(
"gml:PolygonPropertyType" );
386 return QStringLiteral(
"gml:MultiPointPropertyType" );
391 return QStringLiteral(
"gml:MultiCurvePropertyType" );
396 return QStringLiteral(
"gml:MultiSurfacePropertyType" );
399 return QStringLiteral(
"gml:GeometryPropertyType" );
402 return QStringLiteral(
"gml:GeometryPropertyType" );
A helper class that centralizes restrictions given by all the access control filter plugins.
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
Q_GADGET Constraints constraints
Encapsulate a field in an attribute table or data source.
ConfigurationFlags configurationFlags
QgsFieldConstraints constraints
@ HideFromWfs
Field is not available if layer is served as WFS from QGIS server.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Base class for all map layer types.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
A helper class that centralizes caches accesses given by all the server cache filter plugins.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
bool getCachedDocument(QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Returns cached document (or 0 if document not in cache) like capabilities.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
virtual QByteArray data() const
Returns post/put data Check for QByteArray::isNull() to check if data is available.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Exception thrown in case of malformed request.
Exception thrown when data access violates access controls.
Provides an interface to retrieve and manipulate WFS parameters received from the client.
QStringList typeNames() const
Returns TYPENAME parameter as list.
QString outputFormatAsString() const
Returns OUTPUTFORMAT parameter as a string.
Format
Output format for the response.
Format outputFormat() const
Returns format.
Type
The WKB type describes the number of dimensions a geometry has.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
QDomDocument createDescribeFeatureTypeDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create get capabilities document.
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
const QString OGC_NAMESPACE
const QString GML_NAMESPACE
void setSchemaLayer(QDomElement &parentElement, QDomDocument &doc, const QgsVectorLayer *layer, QgsWfsParameters::Format format)
QString getGmlGeometryType(const QgsVectorLayer *layer, QgsWfsParameters::Format format)
Returns the GML geometry type.
const QString QGS_NAMESPACE
void writeDescribeFeatureType(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS GetCapabilities response.
const QRegExp cleanTagNameRegExp("(?![\\w\\d\\.-]).")