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;
62 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
63 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( parameters.value( QStringLiteral(
"REQUEST_BODY" ) ),
true, &errorMsg ) )
116 QDomElement queryDocElem = queryDoc.documentElement();
117 QDomNodeList docChildNodes = queryDocElem.childNodes();
118 if ( docChildNodes.size() )
120 for (
int i = 0; i < docChildNodes.size(); i++ )
122 QDomElement docChildElem = docChildNodes.at( i ).toElement();
123 if ( docChildElem.tagName() == QLatin1String(
"TypeName" ) )
125 QString
typeName = docChildElem.text().trimmed();
126 if ( typeName.contains(
':' ) )
127 typeNameList << typeName.section(
':', 1, 1 );
136 typeNameList = wfsParameters.
typeNames();
140 for (
int i = 0; i < wfsLayerIds.size(); ++i )
154 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
158 #ifdef HAVE_SERVER_PYTHON_PLUGINS 161 if ( !typeNameList.isEmpty() )
177 setSchemaLayer( schemaElement, doc, const_cast<QgsVectorLayer *>( vLayer ) );
193 QDomElement elementElem = doc.createElement( QStringLiteral(
"element" ) );
194 elementElem.setAttribute( QStringLiteral(
"name" ), typeName );
195 elementElem.setAttribute( QStringLiteral(
"type" ),
"qgs:" + typeName +
"Type" );
196 elementElem.setAttribute( QStringLiteral(
"substitutionGroup" ), QStringLiteral(
"gml:_Feature" ) );
197 parentElement.appendChild( elementElem );
200 QDomElement complexTypeElem = doc.createElement( QStringLiteral(
"complexType" ) );
201 complexTypeElem.setAttribute( QStringLiteral(
"name" ), typeName +
"Type" );
202 parentElement.appendChild( complexTypeElem );
205 QDomElement complexContentElem = doc.createElement( QStringLiteral(
"complexContent" ) );
206 complexTypeElem.appendChild( complexContentElem );
209 QDomElement extensionElem = doc.createElement( QStringLiteral(
"extension" ) );
210 extensionElem.setAttribute( QStringLiteral(
"base" ), QStringLiteral(
"gml:AbstractFeatureType" ) );
211 complexContentElem.appendChild( extensionElem );
214 QDomElement sequenceElem = doc.createElement( QStringLiteral(
"sequence" ) );
215 extensionElem.appendChild( sequenceElem );
220 QDomElement geomElem = doc.createElement( QStringLiteral(
"element" ) );
221 geomElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
228 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PointPropertyType" ) );
232 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:LineStringPropertyType" ) );
236 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PolygonPropertyType" ) );
240 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPointPropertyType" ) );
244 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiLineStringPropertyType" ) );
248 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPolygonPropertyType" ) );
251 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:GeometryPropertyType" ) );
254 geomElem.setAttribute( QStringLiteral(
"minOccurs" ), QStringLiteral(
"0" ) );
255 geomElem.setAttribute( QStringLiteral(
"maxOccurs" ), QStringLiteral(
"1" ) );
256 sequenceElem.appendChild( geomElem );
262 for (
int idx = 0; idx < fields.
count(); ++idx )
265 QString attributeName = field.
name();
267 if ( layerExcludedAttributes.contains( attributeName ) )
273 QDomElement attElem = doc.createElement( QStringLiteral(
"element" ) );
274 attElem.setAttribute( QStringLiteral(
"name" ), attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
275 QVariant::Type attributeType = field.
type();
276 if ( attributeType == QVariant::Int )
278 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
280 else if ( attributeType == QVariant::UInt )
282 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedInt" ) );
284 else if ( attributeType == QVariant::LongLong )
286 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"long" ) );
288 else if ( attributeType == QVariant::ULongLong )
290 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedLong" ) );
292 else if ( attributeType == QVariant::Double )
295 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
297 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
299 else if ( attributeType == QVariant::Bool )
301 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"boolean" ) );
303 else if ( attributeType == QVariant::Date )
305 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
307 else if ( attributeType == QVariant::Time )
309 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
311 else if ( attributeType == QVariant::DateTime )
313 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
317 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"string" ) );
321 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
324 const QVariantMap config = setup.
config();
325 const QString fieldFormat = config.value( QStringLiteral(
"field_format" ), fieldFormatter.
defaultFormat( field.
type() ) ).toString();
326 if ( fieldFormat == QStringLiteral(
"yyyy-MM-dd" ) )
327 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
328 else if ( fieldFormat == QStringLiteral(
"HH:mm:ss" ) )
329 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
331 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
333 else if ( setup.
type() == QStringLiteral(
"Range" ) )
335 const QVariantMap config = setup.
config();
336 if ( config.contains( QStringLiteral(
"Precision" ) ) )
341 int configPrec( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
342 if ( ok && configPrec != field.
precision() )
344 if ( configPrec == 0 )
345 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
347 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
354 attElem.setAttribute( QStringLiteral(
"nillable" ), QStringLiteral(
"true" ) );
357 sequenceElem.appendChild( attElem );
359 QString alias = field.
alias();
360 if ( !alias.isEmpty() )
362 attElem.setAttribute( QStringLiteral(
"alias" ), alias );
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...
Base class for all map layer types.
QgsMapLayerType type() const
Returns the type of the layer.
void setSchemaLayer(QDomElement &parentElement, QDomDocument &doc, const QgsVectorLayer *layer)
const QString QGS_NAMESPACE
QSet< QString > excludeAttributesWfs() const
A set of attributes that are not advertised in WFS requests with QGIS server.
Format outputFormat() const
Returns format.
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QString outputFormatAsString() const
Returns OUTPUTFORMAT parameter as a string.
void writeDescribeFeatureType(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS GetCapabilities response.
Container of fields for a vector layer.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device...
int count() const
Returns number of items.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Type
The WKB type describes the number of dimensions a geometry has.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
const QString GML_NAMESPACE
A helper class that centralizes caches accesses given by all the server cache filter plugins...
Reads and writes project states.
Format
Output format for the response.
Encapsulate a field in an attribute table or data source.
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.
const QString OGC_NAMESPACE
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
const QRegExp cleanTagNameRegExp("(?![\\\-]).")
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins...
QgsFieldConstraints constraints
QDomDocument createDescribeFeatureTypeDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create get capabilities document.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
Exception thrown in case of malformed request.
A helper class that centralizes restrictions given by all the access control filter plugins...
QStringList typeNames() const
Returns TYPENAME parameter as list.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Exception thrown when data access violates access controls.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
Provides an interface to retrieve and manipulate WFS parameters received from the client...
QMap< QString, QString > Parameters