33using namespace Qt::StringLiterals;
45#ifdef HAVE_SERVER_PYTHON_PLUGINS
49 const QDomDocument *capabilitiesDocument =
nullptr;
51#ifdef HAVE_SERVER_PYTHON_PLUGINS
53 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
55 capabilitiesDocument = &doc;
65 capabilitiesDocument = &doc;
69 capabilitiesDocument = &doc;
71 response.
setHeader( u
"Content-Type"_s, u
"text/xml; charset=utf-8"_s );
72 response.
write( capabilitiesDocument->toByteArray() );
83 QDomElement wfsCapabilitiesElement = doc.createElement( u
"WFS_Capabilities"_s );
84 wfsCapabilitiesElement.setAttribute( u
"xmlns"_s,
WFS_NAMESPACE );
85 wfsCapabilitiesElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
86 wfsCapabilitiesElement.setAttribute( u
"xsi:schemaLocation"_s,
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd" );
87 wfsCapabilitiesElement.setAttribute( u
"xmlns:ogc"_s,
OGC_NAMESPACE );
88 wfsCapabilitiesElement.setAttribute( u
"xmlns:gml"_s,
GML_NAMESPACE );
89 wfsCapabilitiesElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
90 wfsCapabilitiesElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
91 wfsCapabilitiesElement.setAttribute( u
"version"_s, u
"1.0.0"_s );
92 wfsCapabilitiesElement.setAttribute( u
"updateSequence"_s, u
"0"_s );
93 doc.appendChild( wfsCapabilitiesElement );
108 QDomElement filterCapabilitiesElement = doc.createElement( u
"ogc:Filter_Capabilities"_s );
109 wfsCapabilitiesElement.appendChild( filterCapabilitiesElement );
110 QDomElement spatialCapabilitiesElement = doc.createElement( u
"ogc:Spatial_Capabilities"_s );
111 filterCapabilitiesElement.appendChild( spatialCapabilitiesElement );
112 QDomElement spatialOperatorsElement = doc.createElement( u
"ogc:Spatial_Operators"_s );
113 spatialCapabilitiesElement.appendChild( spatialOperatorsElement );
114 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:BBOX"_s ) );
115 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Disjoint"_s ) );
116 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Intersect"_s ) );
117 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Touches"_s ) );
118 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Crosses"_s ) );
119 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Contains"_s ) );
120 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Overlaps"_s ) );
121 spatialOperatorsElement.appendChild( doc.createElement( u
"ogc:Within"_s ) );
122 QDomElement scalarCapabilitiesElement = doc.createElement( u
"ogc:Scalar_Capabilities"_s );
123 filterCapabilitiesElement.appendChild( scalarCapabilitiesElement );
124 QDomElement comparisonOperatorsElement = doc.createElement( u
"ogc:Comparison_Operators"_s );
125 scalarCapabilitiesElement.appendChild( comparisonOperatorsElement );
126 comparisonOperatorsElement.appendChild( doc.createElement( u
"ogc:Simple_Comparisons"_s ) );
127 comparisonOperatorsElement.appendChild( doc.createElement( u
"ogc:Between"_s ) );
128 comparisonOperatorsElement.appendChild( doc.createElement( u
"ogc:Like"_s ) );
136 QDomElement serviceElem = doc.createElement( u
"Service"_s );
139 QDomElement nameElem = doc.createElement( u
"Name"_s );
140 const QDomText nameText = doc.createTextNode(
"WFS" );
141 nameElem.appendChild( nameText );
142 serviceElem.appendChild( nameElem );
145 QDomElement titleElem = doc.createElement( u
"Title"_s );
146 const QDomText titleText = doc.createTextNode( title );
147 titleElem.appendChild( titleText );
148 serviceElem.appendChild( titleElem );
151 if ( !abstract.isEmpty() )
153 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
154 const QDomText abstractText = doc.createCDATASection( abstract );
155 abstractElem.appendChild( abstractText );
156 serviceElem.appendChild( abstractElem );
160 if ( !keywords.isEmpty() && !keywords.join(
", "_L1 ).isEmpty() )
162 QDomElement keywordsElem = doc.createElement( u
"Keywords"_s );
163 const QDomText keywordsText = doc.createTextNode( keywords.join(
", "_L1 ) );
164 keywordsElem.appendChild( keywordsText );
165 serviceElem.appendChild( keywordsElem );
168 QDomElement onlineResourceElem = doc.createElement( u
"OnlineResource"_s );
170 if ( !onlineResource.isEmpty() )
172 const QDomText onlineResourceText = doc.createTextNode( onlineResource );
173 onlineResourceElem.appendChild( onlineResourceText );
175 serviceElem.appendChild( onlineResourceElem );
178 if ( !fees.isEmpty() )
180 QDomElement feesElem = doc.createElement( u
"Fees"_s );
181 const QDomText feesText = doc.createTextNode( fees );
182 feesElem.appendChild( feesText );
183 serviceElem.appendChild( feesElem );
187 if ( !accessConstraints.isEmpty() )
189 QDomElement accessConstraintsElem = doc.createElement( u
"AccessConstraints"_s );
190 const QDomText accessConstraintsText = doc.createTextNode( accessConstraints );
191 accessConstraintsElem.appendChild( accessConstraintsText );
192 serviceElem.appendChild( accessConstraintsElem );
201 QDomElement capabilityElement = doc.createElement( u
"Capability"_s );
204 QDomElement requestElement = doc.createElement( u
"Request"_s );
205 capabilityElement.appendChild( requestElement );
207 QDomElement getCapabilitiesElement = doc.createElement( u
"GetCapabilities"_s );
208 requestElement.appendChild( getCapabilitiesElement );
210 QDomElement dcpTypeElement = doc.createElement( u
"DCPType"_s );
211 getCapabilitiesElement.appendChild( dcpTypeElement );
212 QDomElement httpElement = doc.createElement( u
"HTTP"_s );
213 dcpTypeElement.appendChild( httpElement );
216 const QString hrefString =
serviceUrl( request, project, *settings );
219 QDomElement getElement = doc.createElement( u
"Get"_s );
220 httpElement.appendChild( getElement );
221 getElement.setAttribute( u
"onlineResource"_s, hrefString );
222 const QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();
223 getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( u
"Post"_s );
224 getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
227 QDomElement describeFeatureTypeElement = doc.createElement( u
"DescribeFeatureType"_s );
228 requestElement.appendChild( describeFeatureTypeElement );
229 QDomElement schemaDescriptionLanguageElement = doc.createElement( u
"SchemaDescriptionLanguage"_s );
230 describeFeatureTypeElement.appendChild( schemaDescriptionLanguageElement );
231 const QDomElement xmlSchemaElement = doc.createElement( u
"XMLSCHEMA"_s );
232 schemaDescriptionLanguageElement.appendChild( xmlSchemaElement );
233 const QDomElement describeFeatureTypeDhcTypeElement = dcpTypeElement.cloneNode().toElement();
234 describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypeElement );
235 const QDomElement describeFeatureTypeDhcTypePostElement = dcpTypeElement.cloneNode().toElement();
236 describeFeatureTypeDhcTypePostElement.firstChild().firstChild().toElement().setTagName( u
"Post"_s );
237 describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypePostElement );
240 QDomElement getFeatureElement = doc.createElement( u
"GetFeature"_s );
241 requestElement.appendChild( getFeatureElement );
242 QDomElement getFeatureFormatElement = doc.createElement( u
"ResultFormat"_s );
243 getFeatureElement.appendChild( getFeatureFormatElement );
244 const QDomElement gmlFormatElement = doc.createElement( u
"GML2"_s );
245 getFeatureFormatElement.appendChild( gmlFormatElement );
246 const QDomElement gml3FormatElement = doc.createElement( u
"GML3"_s );
247 getFeatureFormatElement.appendChild( gml3FormatElement );
248 const QDomElement geojsonFormatElement = doc.createElement( u
"GeoJSON"_s );
249 getFeatureFormatElement.appendChild( geojsonFormatElement );
250 const QDomElement getFeatureDhcTypeGetElement = dcpTypeElement.cloneNode().toElement();
251 getFeatureElement.appendChild( getFeatureDhcTypeGetElement );
252 const QDomElement getFeatureDhcTypePostElement = dcpTypeElement.cloneNode().toElement();
253 getFeatureDhcTypePostElement.firstChild().firstChild().toElement().setTagName( u
"Post"_s );
254 getFeatureElement.appendChild( getFeatureDhcTypePostElement );
257 QDomElement transactionElement = doc.createElement( u
"Transaction"_s );
258 requestElement.appendChild( transactionElement );
259 const QDomElement transactionDhcTypeElement = dcpTypeElement.cloneNode().toElement();
260 transactionDhcTypeElement.firstChild().firstChild().toElement().setTagName( u
"Post"_s );
261 transactionElement.appendChild( transactionDhcTypeElement );
263 return capabilityElement;
268#ifdef HAVE_SERVER_PYTHON_PLUGINS
271 ( void ) serverIface;
275 QDomElement featureTypeListElement = doc.createElement( u
"FeatureTypeList"_s );
277 QDomElement operationsElement = doc.createElement( u
"Operations"_s );
278 featureTypeListElement.appendChild( operationsElement );
280 const QDomElement queryElement = doc.createElement( u
"Query"_s );
281 operationsElement.appendChild( queryElement );
287 for (
const QString &wfsLayerId : wfsLayerIds )
298#ifdef HAVE_SERVER_PYTHON_PLUGINS
304 QDomElement layerElem = doc.createElement( u
"FeatureType"_s );
307 QDomElement nameElem = doc.createElement( u
"Name"_s );
308 QString typeName = layer->
name();
311 typeName = typeName.replace(
" "_L1,
"_"_L1 );
312 const QDomText nameText = doc.createTextNode( typeName );
313 nameElem.appendChild( nameText );
314 layerElem.appendChild( nameElem );
317 QDomElement titleElem = doc.createElement( u
"Title"_s );
319 if ( title.isEmpty() )
321 title = layer->
name();
323 const QDomText titleText = doc.createTextNode( title );
324 titleElem.appendChild( titleText );
325 layerElem.appendChild( titleElem );
329 if ( !abstract.isEmpty() )
331 QDomElement abstractElem = doc.createElement( u
"Abstract"_s );
332 const QDomText abstractText = doc.createTextNode( abstract );
333 abstractElem.appendChild( abstractText );
334 layerElem.appendChild( abstractElem );
339 if ( !keywords.isEmpty() )
341 QDomElement keywordsElem = doc.createElement( u
"Keywords"_s );
342 const QDomText keywordsText = doc.createTextNode( keywords );
343 keywordsElem.appendChild( keywordsText );
344 layerElem.appendChild( keywordsElem );
348 QDomElement srsElem = doc.createElement( u
"SRS"_s );
349 const QDomText srsText = doc.createTextNode( layer->
crs().
authid() );
350 srsElem.appendChild( srsText );
351 layerElem.appendChild( srsElem );
362 QDomElement bBoxElement = doc.createElement( u
"LatLongBoundingBox"_s );
367 layerElem.appendChild( bBoxElement );
373 QDomElement metaUrlElem = doc.createElement( u
"MetadataURL"_s );
374 const QString metadataUrlType = url.type;
375 metaUrlElem.setAttribute( u
"type"_s, metadataUrlType );
376 const QString metadataUrlFormat = url.format;
377 if ( metadataUrlFormat ==
"text/xml"_L1 )
379 metaUrlElem.setAttribute( u
"format"_s, u
"XML"_s );
383 metaUrlElem.setAttribute( u
"format"_s, u
"TXT"_s );
385 const QDomText metaUrlText = doc.createTextNode( url.url );
386 metaUrlElem.appendChild( metaUrlText );
387 layerElem.appendChild( metaUrlElem );
391 QDomElement operationsElement = doc.createElement( u
"Operations"_s );
393 const QDomElement queryElement = doc.createElement( u
"Query"_s );
394 operationsElement.appendChild( queryElement );
395 if ( wfstUpdateLayersId.contains( layer->
id() ) || wfstInsertLayersId.contains( layer->
id() ) || wfstDeleteLayersId.contains( layer->
id() ) )
402 const QDomElement insertElement = doc.createElement( u
"Insert"_s );
403 operationsElement.appendChild( insertElement );
408 const QDomElement updateElement = doc.createElement( u
"Update"_s );
409 operationsElement.appendChild( updateElement );
414 const QDomElement deleteElement = doc.createElement( u
"Delete"_s );
415 operationsElement.appendChild( deleteElement );
419 layerElem.appendChild( operationsElement );
421 featureTypeListElement.appendChild( layerElem );
424 return featureTypeListElement;
@ AddFeatures
Allows adding features.
@ ChangeGeometries
Allows modifications of geometries.
@ DeleteFeatures
Allows deletion of features.
@ ChangeAttributeValues
Allows modification of attribute values.
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.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
QString keywordList() const
Returns the keyword list of the layerused by QGIS Server in GetCapabilities request.
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
QString abstract() const
Returns the abstract of the layerused by QGIS Server in GetCapabilities request.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
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 rectangle specified with double values.
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.
Defines interfaces exposed by QGIS Server and made available to plugins.
virtual QgsServerCacheManager * cacheManager() const =0
Gets the registered server cache filters.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
virtual QgsServerSettings * serverSettings()=0
Returns the server settings.
static double ceilWithPrecision(double number, int places)
Returns a double greater than number to the specified number of places.
static QString owsServiceAccessConstraints(const QgsProject &project)
Returns the owsService access constraints defined in project.
static QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
static QString owsServiceOnlineResource(const QgsProject &project)
Returns the owsService online resource defined in project.
static QString owsServiceFees(const QgsProject &project)
Returns the owsService fees defined in project.
static QStringList owsServiceKeywords(const QgsProject &project)
Returns the owsService keywords defined in project.
static QStringList wfstUpdateLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with update capabilities.
static QStringList wfstInsertLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with insert capabilities.
static QString owsServiceTitle(const QgsProject &project)
Returns the owsService title defined in project.
static QString owsServiceAbstract(const QgsProject &project)
Returns the owsService abstract defined in project.
static double floorWithPrecision(double number, int places)
Returns a double less than number to the specified number of places.
static QStringList wfstDeleteLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with delete capabilities.
Defines requests passed to QgsService classes.
Defines the response interface passed to QgsService.
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...
Provides a way to retrieve settings by prioritizing according to environment variables,...
Base class for vector data providers.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
Represents a vector layer which manages a vector based dataset.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
void writeGetCapabilities(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS GetCapabilities response.
QDomElement getFeatureTypeListElement(QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project)
Create FeatureTypeList element for get capabilities document.
QDomDocument createGetCapabilitiesDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create get capabilities document.
QDomElement getCapabilityElement(QDomDocument &doc, const QgsProject *project, const QgsServerRequest &request, const QgsServerSettings *settings)
Create Capability element for get capabilities document.
QDomElement getServiceElement(QDomDocument &doc, const QgsProject *project)
Create Service element for get capabilities document.
QString serviceUrl(const QgsServerRequest &request, const QgsProject *project, const QgsServerSettings &settings)
Service URL string.
const QString OGC_NAMESPACE
const QString GML_NAMESPACE
const QString WFS_NAMESPACE
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.