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() );
80 if ( oFormat == QgsWfsParameters::Format::NONE )
82 QStringLiteral(
"OUTPUTFORMAT %1 is not supported" ).arg( wfsParameters.
outputFormatAsString() ) );
84 #ifdef HAVE_SERVER_PYTHON_PLUGINS
91 QDomElement schemaElement = doc.createElement( QStringLiteral(
"schema" ) );
92 schemaElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
93 schemaElement.setAttribute( QStringLiteral(
"xmlns:xsd" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
94 schemaElement.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
95 schemaElement.setAttribute( QStringLiteral(
"xmlns:gml" ),
GML_NAMESPACE );
96 schemaElement.setAttribute( QStringLiteral(
"xmlns:qgs" ),
QGS_NAMESPACE );
97 schemaElement.setAttribute( QStringLiteral(
"targetNamespace" ),
QGS_NAMESPACE );
98 schemaElement.setAttribute( QStringLiteral(
"elementFormDefault" ), QStringLiteral(
"qualified" ) );
99 schemaElement.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
100 doc.appendChild( schemaElement );
103 QDomElement importElement = doc.createElement( QStringLiteral(
"import" ) );
104 importElement.setAttribute( QStringLiteral(
"namespace" ),
GML_NAMESPACE );
105 if ( oFormat == QgsWfsParameters::Format::GML2 )
106 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
107 else if ( oFormat == QgsWfsParameters::Format::GML3 )
108 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
109 schemaElement.appendChild( importElement );
111 QStringList typeNameList;
112 QDomDocument queryDoc;
114 if ( queryDoc.setContent( request.
data(),
true, &errorMsg ) )
117 const QDomElement queryDocElem = queryDoc.documentElement();
118 const QDomNodeList docChildNodes = queryDocElem.childNodes();
119 if ( docChildNodes.size() )
121 for (
int i = 0; i < docChildNodes.size(); i++ )
123 const QDomElement docChildElem = docChildNodes.at( i ).toElement();
124 if ( docChildElem.tagName() == QLatin1String(
"TypeName" ) )
126 const QString
typeName = docChildElem.text().trimmed();
128 typeNameList <<
typeName.section(
':', 1, 1 );
137 typeNameList = wfsParameters.
typeNames();
151 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
155 #ifdef HAVE_SERVER_PYTHON_PLUGINS
158 if ( !typeNameList.isEmpty() )
190 QDomElement elementElem = doc.createElement( QStringLiteral(
"element" ) );
191 elementElem.setAttribute( QStringLiteral(
"name" ),
typeName );
192 elementElem.setAttribute( QStringLiteral(
"type" ),
"qgs:" +
typeName +
"Type" );
193 elementElem.setAttribute( QStringLiteral(
"substitutionGroup" ), QStringLiteral(
"gml:_Feature" ) );
194 parentElement.appendChild( elementElem );
197 QDomElement complexTypeElem = doc.createElement( QStringLiteral(
"complexType" ) );
198 complexTypeElem.setAttribute( QStringLiteral(
"name" ),
typeName +
"Type" );
199 parentElement.appendChild( complexTypeElem );
202 QDomElement complexContentElem = doc.createElement( QStringLiteral(
"complexContent" ) );
203 complexTypeElem.appendChild( complexContentElem );
206 QDomElement extensionElem = doc.createElement( QStringLiteral(
"extension" ) );
207 extensionElem.setAttribute( QStringLiteral(
"base" ), QStringLiteral(
"gml:AbstractFeatureType" ) );
208 complexContentElem.appendChild( extensionElem );
211 QDomElement sequenceElem = doc.createElement( QStringLiteral(
"sequence" ) );
212 extensionElem.appendChild( sequenceElem );
217 QDomElement geomElem = doc.createElement( QStringLiteral(
"element" ) );
218 geomElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
225 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PointPropertyType" ) );
229 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:LineStringPropertyType" ) );
233 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PolygonPropertyType" ) );
237 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPointPropertyType" ) );
240 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiCurvePropertyType" ) );
244 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiLineStringPropertyType" ) );
247 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiSurfacePropertyType" ) );
251 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPolygonPropertyType" ) );
254 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:GeometryPropertyType" ) );
257 geomElem.setAttribute( QStringLiteral(
"minOccurs" ), QStringLiteral(
"0" ) );
258 geomElem.setAttribute( QStringLiteral(
"maxOccurs" ), QStringLiteral(
"1" ) );
259 sequenceElem.appendChild( geomElem );
265 for (
int idx = 0; idx < fields.
count(); ++idx )
276 QDomElement attElem = doc.createElement( QStringLiteral(
"element" ) );
277 attElem.setAttribute( QStringLiteral(
"name" ), attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
278 const QVariant::Type attributeType =
field.
type();
279 if ( attributeType == QVariant::Int )
281 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
283 else if ( attributeType == QVariant::UInt )
285 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedInt" ) );
287 else if ( attributeType == QVariant::LongLong )
289 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"long" ) );
291 else if ( attributeType == QVariant::ULongLong )
293 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedLong" ) );
295 else if ( attributeType == QVariant::Double )
298 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
300 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
302 else if ( attributeType == QVariant::Bool )
304 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"boolean" ) );
306 else if ( attributeType == QVariant::Date )
308 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
310 else if ( attributeType == QVariant::Time )
312 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
314 else if ( attributeType == QVariant::DateTime )
316 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
320 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"string" ) );
324 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
327 const QVariantMap config = setup.
config();
328 const QString fieldFormat = config.value( QStringLiteral(
"field_format" ), fieldFormatter.
defaultFormat(
field.
type() ) ).toString();
329 if ( fieldFormat == QLatin1String(
"yyyy-MM-dd" ) )
330 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
331 else if ( fieldFormat == QLatin1String(
"HH:mm:ss" ) )
332 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
334 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
336 else if ( setup.
type() == QStringLiteral(
"Range" ) )
338 const QVariantMap config = setup.
config();
339 if ( config.contains( QStringLiteral(
"Precision" ) ) )
344 const int configPrec( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
347 if ( configPrec == 0 )
348 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
350 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
357 attElem.setAttribute( QStringLiteral(
"nillable" ), QStringLiteral(
"true" ) );
360 sequenceElem.appendChild( attElem );
363 if ( !alias.isEmpty() )
365 attElem.setAttribute( QStringLiteral(
"alias" ), alias );
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
Fields is 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...
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
QMap< QString, QString > Parameters
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
void setSchemaLayer(QDomElement &parentElement, QDomDocument &doc, const QgsVectorLayer *layer)
const QString GML_NAMESPACE
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\\.-]).")