37 #include <QStringList> 45 #ifdef HAVE_SERVER_PYTHON_PLUGINS 49 const QDomDocument *describeDocument =
nullptr;
51 #ifdef HAVE_SERVER_PYTHON_PLUGINS 53 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
55 describeDocument = &doc;
65 describeDocument = &doc;
69 describeDocument = &doc;
71 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
72 response.
write( describeDocument->toByteArray() );
88 if ( oFormat == QgsWfsParameters::Format::NONE )
90 QStringLiteral(
"OUTPUTFORMAT %1 is not supported" ).arg( wfsParameters.
outputFormatAsString() ) );
92 #ifdef HAVE_SERVER_PYTHON_PLUGINS 99 QDomElement schemaElement = doc.createElement( QStringLiteral(
"schema" ) );
100 schemaElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
101 schemaElement.setAttribute( QStringLiteral(
"xmlns:xsd" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
102 schemaElement.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
103 schemaElement.setAttribute( QStringLiteral(
"xmlns:gml" ),
GML_NAMESPACE );
104 schemaElement.setAttribute( QStringLiteral(
"xmlns:qgs" ),
QGS_NAMESPACE );
105 schemaElement.setAttribute( QStringLiteral(
"targetNamespace" ),
QGS_NAMESPACE );
106 schemaElement.setAttribute( QStringLiteral(
"elementFormDefault" ), QStringLiteral(
"qualified" ) );
107 schemaElement.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
108 doc.appendChild( schemaElement );
111 QDomElement importElement = doc.createElement( QStringLiteral(
"import" ) );
112 importElement.setAttribute( QStringLiteral(
"namespace" ),
GML_NAMESPACE );
113 if ( oFormat == QgsWfsParameters::Format::GML2 )
114 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
115 else if ( oFormat == QgsWfsParameters::Format::GML3 )
116 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
117 schemaElement.appendChild( importElement );
119 QStringList typeNameList;
120 QDomDocument queryDoc;
122 if ( queryDoc.setContent( parameters.value( QStringLiteral(
"REQUEST_BODY" ) ),
true, &errorMsg ) )
125 QDomElement queryDocElem = queryDoc.documentElement();
126 QDomNodeList docChildNodes = queryDocElem.childNodes();
127 if ( docChildNodes.size() )
129 for (
int i = 0; i < docChildNodes.size(); i++ )
131 QDomElement docChildElem = docChildNodes.at( i ).toElement();
132 if ( docChildElem.tagName() == QLatin1String(
"TypeName" ) )
134 QString
typeName = docChildElem.text().trimmed();
135 if ( typeName.contains(
':' ) )
136 typeNameList << typeName.section(
':', 1, 1 );
145 typeNameList = wfsParameters.
typeNames();
149 for (
int i = 0; i < wfsLayerIds.size(); ++i )
159 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
166 if ( !typeNameList.isEmpty() )
182 setSchemaLayer( schemaElement, doc, const_cast<QgsVectorLayer *>( vLayer ) );
198 QDomElement elementElem = doc.createElement( QStringLiteral(
"element" ) );
199 elementElem.setAttribute( QStringLiteral(
"name" ), typeName );
200 elementElem.setAttribute( QStringLiteral(
"type" ),
"qgs:" + typeName +
"Type" );
201 elementElem.setAttribute( QStringLiteral(
"substitutionGroup" ), QStringLiteral(
"gml:_Feature" ) );
202 parentElement.appendChild( elementElem );
205 QDomElement complexTypeElem = doc.createElement( QStringLiteral(
"complexType" ) );
206 complexTypeElem.setAttribute( QStringLiteral(
"name" ), typeName +
"Type" );
207 parentElement.appendChild( complexTypeElem );
210 QDomElement complexContentElem = doc.createElement( QStringLiteral(
"complexContent" ) );
211 complexTypeElem.appendChild( complexContentElem );
214 QDomElement extensionElem = doc.createElement( QStringLiteral(
"extension" ) );
215 extensionElem.setAttribute( QStringLiteral(
"base" ), QStringLiteral(
"gml:AbstractFeatureType" ) );
216 complexContentElem.appendChild( extensionElem );
219 QDomElement sequenceElem = doc.createElement( QStringLiteral(
"sequence" ) );
220 extensionElem.appendChild( sequenceElem );
225 QDomElement geomElem = doc.createElement( QStringLiteral(
"element" ) );
226 geomElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
233 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PointPropertyType" ) );
237 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:LineStringPropertyType" ) );
241 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PolygonPropertyType" ) );
245 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPointPropertyType" ) );
249 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiLineStringPropertyType" ) );
253 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPolygonPropertyType" ) );
256 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:GeometryPropertyType" ) );
259 geomElem.setAttribute( QStringLiteral(
"minOccurs" ), QStringLiteral(
"0" ) );
260 geomElem.setAttribute( QStringLiteral(
"maxOccurs" ), QStringLiteral(
"1" ) );
261 sequenceElem.appendChild( geomElem );
268 for (
int idx = 0; idx < fields.
count(); ++idx )
271 QString attributeName = field.
name();
273 if ( layerExcludedAttributes.contains( attributeName ) )
279 QDomElement attElem = doc.createElement( QStringLiteral(
"element" ) );
280 attElem.setAttribute( QStringLiteral(
"name" ), attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
281 QVariant::Type attributeType = field.
type();
282 if ( attributeType == QVariant::Int )
284 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
286 else if ( attributeType == QVariant::UInt )
288 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedInt" ) );
290 else if ( attributeType == QVariant::LongLong )
292 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"long" ) );
294 else if ( attributeType == QVariant::ULongLong )
296 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedLong" ) );
298 else if ( attributeType == QVariant::Double )
301 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
303 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
305 else if ( attributeType == QVariant::Bool )
307 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"boolean" ) );
309 else if ( attributeType == QVariant::Date )
311 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
313 else if ( attributeType == QVariant::Time )
315 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
317 else if ( attributeType == QVariant::DateTime )
319 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
323 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"string" ) );
327 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
330 const QVariantMap config = setup.
config();
331 const QString fieldFormat = config.value( QStringLiteral(
"field_format" ), fieldFormatter.
defaultFormat( field.
type() ) ).toString();
332 if ( fieldFormat == QStringLiteral(
"yyyy-MM-dd" ) )
333 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
334 else if ( fieldFormat == QStringLiteral(
"HH:mm:ss" ) )
335 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
337 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
339 else if ( setup.
type() == QStringLiteral(
"Range" ) )
341 const QVariantMap config = setup.
config();
342 if ( config.contains( QStringLiteral(
"Precision" ) ) )
347 int configPrec( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
348 if ( ok && configPrec != field.
precision() )
350 if ( configPrec == 0 )
351 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
353 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
360 attElem.setAttribute( QStringLiteral(
"nillable" ), QStringLiteral(
"true" ) );
363 sequenceElem.appendChild( attElem );
365 QString alias = field.
alias();
366 if ( !alias.isEmpty() )
368 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.
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.
QSet< QString > excludeAttributesWfs() const
A set of attributes that are not advertised in WFS requests with QGIS server.
Format outputFormat() const
Returns format.
bool setCachedDocument(const QDomDocument *doc, const QgsProject *project, const QgsServerRequest &request, QgsAccessControl *accessControl) const
Updates or inserts the document in cache like capabilities.
void setSchemaLayer(QDomElement &parentElement, QDomDocument &doc, const QgsVectorLayer *layer)
const QString QGS_NAMESPACE
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
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.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device...
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.
QStringList typeNames() const
Returns TYPENAME parameter as list.
QString outputFormatAsString() const
Returns OUTPUTFORMAT parameter as a string.
Type
The WKB type describes the number of dimensions a geometry has.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
const QString GML_NAMESPACE
A helper class that centralizes caches accesses given by all the server cache filter plugins...
Reads and writes project states.
int count() const
Returns number of items.
Format
Output format for the response.
Encapsulate a field in an attribute table or data source.
const QRegExp cleanTagNameRegExp("(?![\\w\\d\\.-]).")
const QString OGC_NAMESPACE
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
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.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
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...
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.
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
Provides an interface to retrieve and manipulate WFS parameters received from the client...
QMap< QString, QString > Parameters
bool layerReadPermission(const QgsMapLayer *layer) const
Returns the layer read right.