41 #ifdef HAVE_SERVER_PYTHON_PLUGINS
45 const QDomDocument *capabilitiesDocument =
nullptr;
47 #ifdef HAVE_SERVER_PYTHON_PLUGINS
49 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
51 capabilitiesDocument = &doc;
61 capabilitiesDocument = &doc;
65 capabilitiesDocument = &doc;
67 response.
setHeader( QStringLiteral(
"Content-Type" ), QStringLiteral(
"text/xml; charset=utf-8" ) );
68 response.
write( capabilitiesDocument->toByteArray() );
80 QDomElement wfsCapabilitiesElement = doc.createElement( QStringLiteral(
"WFS_Capabilities" ) );
81 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns" ),
WFS_NAMESPACE );
82 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
83 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ),
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd" );
84 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
85 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:gml" ),
GML_NAMESPACE );
86 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:ows" ), QStringLiteral(
"http://www.opengis.net/ows" ) );
87 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
89 wfsCapabilitiesElement.setAttribute( QStringLiteral(
"updateSequence" ), QStringLiteral(
"0" ) );
90 doc.appendChild( wfsCapabilitiesElement );
108 QDomElement filterCapabilitiesElement = doc.createElement( QStringLiteral(
"ogc:Filter_Capabilities" ) );
109 wfsCapabilitiesElement.appendChild( filterCapabilitiesElement );
110 QDomElement spatialCapabilitiesElement = doc.createElement( QStringLiteral(
"ogc:Spatial_Capabilities" ) );
111 filterCapabilitiesElement.appendChild( spatialCapabilitiesElement );
113 QStringList geometryOperands;
114 geometryOperands << QStringLiteral(
"gml:Point" ) << QStringLiteral(
"gml:LineString" ) << QStringLiteral(
"gml:Polygon" )
115 << QStringLiteral(
"gml:Envelope" );
116 QDomElement geometryOperandsElem = doc.createElement( QStringLiteral(
"ogc:GeometryOperands" ) );
117 for (
const QString &geometryOperand : geometryOperands )
119 QDomElement geometryOperandElem = doc.createElement( QStringLiteral(
"ogc:GeometryOperand" ) );
120 QDomText geometryOperandText = doc.createTextNode( geometryOperand );
121 geometryOperandElem.appendChild( geometryOperandText );
122 geometryOperandsElem.appendChild( geometryOperandElem );
124 spatialCapabilitiesElement.appendChild( geometryOperandsElem );
126 QStringList spatialOperators;
127 spatialOperators << QStringLiteral(
"Equals" ) << QStringLiteral(
"Disjoint" ) << QStringLiteral(
"Touches" )
128 << QStringLiteral(
"Within" ) << QStringLiteral(
"Overlaps" ) << QStringLiteral(
"Crosses" )
129 << QStringLiteral(
"Intersects" ) << QStringLiteral(
"Contains" ) << QStringLiteral(
"BBOX" );
130 QDomElement spatialOperatorsElem = doc.createElement( QStringLiteral(
"ogc:SpatialOperators" ) );
131 for (
const QString &spatialOperator : spatialOperators )
133 QDomElement spatialOperatorElem = doc.createElement( QStringLiteral(
"ogc:SpatialOperator" ) );
134 spatialOperatorElem.setAttribute( QStringLiteral(
"name" ), spatialOperator );
135 spatialOperatorsElem.appendChild( spatialOperatorElem );
137 spatialCapabilitiesElement.appendChild( spatialOperatorsElem );
138 QDomElement scalarCapabilitiesElement = doc.createElement( QStringLiteral(
"ogc:Scalar_Capabilities" ) );
139 filterCapabilitiesElement.appendChild( scalarCapabilitiesElement );
140 QDomElement logicalOperatorsElement = doc.createElement( QStringLiteral(
"ogc:LogicalOperators" ) );
141 scalarCapabilitiesElement.appendChild( logicalOperatorsElement );
143 QStringList comparisonOperators;
144 comparisonOperators << QStringLiteral(
"LessThan" ) << QStringLiteral(
"GreaterThan" )
145 << QStringLiteral(
"LessThanEqualTo" ) << QStringLiteral(
"GreaterThanEqualTo" )
146 << QStringLiteral(
"EqualTo" ) << QStringLiteral(
"Like" ) << QStringLiteral(
"Between" );
147 QDomElement comparisonOperatorsElem = doc.createElement( QStringLiteral(
"ogc:ComparisonOperators" ) );
148 for (
const QString &comparisonOperator : comparisonOperators )
150 QDomElement comparisonOperatorElem = doc.createElement( QStringLiteral(
"ogc:ComparisonOperator" ) );
151 QDomText comparisonOperatorText = doc.createTextNode( comparisonOperator );
152 comparisonOperatorElem.appendChild( comparisonOperatorText );
153 comparisonOperatorsElem.appendChild( comparisonOperatorElem );
155 scalarCapabilitiesElement.appendChild( comparisonOperatorsElem );
157 QDomElement idCapabilitiesElement = doc.createElement( QStringLiteral(
"ogc:Id_Capabilities" ) );
158 QDomElement fidElem = doc.createElement( QStringLiteral(
"ogc:FID" ) );
159 idCapabilitiesElement.appendChild( fidElem );
160 filterCapabilitiesElement.appendChild( idCapabilitiesElement );
169 QDomElement serviceElem = doc.createElement( QStringLiteral(
"ows:ServiceIdentification" ) );
172 if ( !title.isEmpty() )
174 QDomElement titleElem = doc.createElement( QStringLiteral(
"ows:Title" ) );
175 QDomText titleText = doc.createTextNode( title );
176 titleElem.appendChild( titleText );
177 serviceElem.appendChild( titleElem );
181 if ( !
abstract.isEmpty() )
183 QDomElement abstractElem = doc.createElement( QStringLiteral(
"ows:Abstract" ) );
184 QDomText abstractText = doc.createCDATASection(
abstract );
185 abstractElem.appendChild( abstractText );
186 serviceElem.appendChild( abstractElem );
190 if ( !keywords.isEmpty() && !keywords.join( QStringLiteral(
", " ) ).isEmpty() )
192 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"ows:Keywords" ) );
193 for (
const QString &keyword : keywords )
195 if ( !keyword.isEmpty() )
197 QDomElement keywordElem = doc.createElement( QStringLiteral(
"ows:Keyword" ) );
198 QDomText keywordText = doc.createTextNode( keyword );
199 keywordElem.appendChild( keywordText );
200 keywordsElem.appendChild( keywordElem );
203 serviceElem.appendChild( keywordsElem );
207 QDomElement serviceTypeElem = doc.createElement( QStringLiteral(
"ows:ServiceType" ) );
208 QDomText serviceTypeText = doc.createTextNode(
"WFS" );
209 serviceTypeElem.appendChild( serviceTypeText );
210 serviceElem.appendChild( serviceTypeElem );
213 QDomElement serviceTypeVersionElem = doc.createElement( QStringLiteral(
"ows:ServiceTypeVersion" ) );
214 QDomText serviceTypeVersionText = doc.createTextNode(
"1.1.0" );
215 serviceTypeVersionElem.appendChild( serviceTypeVersionText );
216 serviceElem.appendChild( serviceTypeVersionElem );
218 QDomElement feesElem = doc.createElement( QStringLiteral(
"ows:Fees" ) );
219 QDomText feesText = doc.createTextNode(
"None" );
221 if ( !fees.isEmpty() )
223 feesText = doc.createTextNode( fees );
225 feesElem.appendChild( feesText );
226 serviceElem.appendChild( feesElem );
228 QDomElement accessConstraintsElem = doc.createElement( QStringLiteral(
"ows:AccessConstraints" ) );
230 QDomText accessConstraintsText = doc.createTextNode(
"None" );
231 if ( !accessConstraints.isEmpty() )
233 accessConstraintsText = doc.createTextNode( accessConstraints );
235 accessConstraintsElem.appendChild( accessConstraintsText );
236 serviceElem.appendChild( accessConstraintsElem );
245 QDomElement serviceElem = doc.createElement( QStringLiteral(
"ows:ServiceProvider" ) );
249 if ( !contactOrganization.isEmpty() )
251 QDomElement providerNameElem = doc.createElement( QStringLiteral(
"ows:ProviderName" ) );
252 QDomText providerNameText = doc.createTextNode( contactOrganization );
253 providerNameElem.appendChild( providerNameText );
254 serviceElem.appendChild( providerNameElem );
259 if ( !contactPerson.isEmpty() ||
260 !contactPosition.isEmpty() )
263 QDomElement serviceContactElem = doc.createElement( QStringLiteral(
"ows:ServiceContact" ) );
265 if ( !contactPerson.isEmpty() )
267 QDomElement individualNameElem = doc.createElement( QStringLiteral(
"ows:IndividualName" ) );
268 QDomText individualNameText = doc.createTextNode( contactPerson );
269 individualNameElem.appendChild( individualNameText );
270 serviceContactElem.appendChild( individualNameElem );
273 if ( !contactPosition.isEmpty() )
275 QDomElement positionNameElem = doc.createElement( QStringLiteral(
"ows:PositionName" ) );
276 QDomText positionNameText = doc.createTextNode( contactPosition );
277 positionNameElem.appendChild( positionNameText );
278 serviceContactElem.appendChild( positionNameElem );
284 if ( !contactMail.isEmpty() ||
285 !contactPhone.isEmpty() ||
286 !onlineResource.isEmpty() )
289 QDomElement contactInfoElem = doc.createElement( QStringLiteral(
"ows:ContactInfo" ) );
291 if ( !contactPhone.isEmpty() )
293 QDomElement phoneElem = doc.createElement( QStringLiteral(
"ows:Phone" ) );
294 QDomElement voiceElem = doc.createElement( QStringLiteral(
"ows:Voice" ) );
295 QDomText voiceText = doc.createTextNode( contactPhone );
296 voiceElem.appendChild( voiceText );
297 phoneElem.appendChild( voiceElem );
298 contactInfoElem.appendChild( phoneElem );
301 if ( !contactMail.isEmpty() )
303 QDomElement addressElem = doc.createElement( QStringLiteral(
"ows:Address" ) );
304 QDomElement mailElem = doc.createElement( QStringLiteral(
"ows:ElectronicMailAddress" ) );
305 QDomText mailText = doc.createTextNode( contactMail );
306 mailElem.appendChild( mailText );
307 addressElem.appendChild( mailElem );
308 contactInfoElem.appendChild( addressElem );
311 if ( !onlineResource.isEmpty() )
313 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"ows:OnlineResource" ) );
314 onlineResourceElem.setAttribute(
"xlink:href", onlineResource );
315 contactInfoElem.appendChild( onlineResourceElem );
319 QDomElement roleElem = doc.createElement( QStringLiteral(
"ows:Role" ) );
320 QDomText roleText = doc.createTextNode(
"PointOfContact" );
321 roleElem.appendChild( roleText );
322 serviceContactElem.appendChild( roleElem );
324 serviceElem.appendChild( serviceContactElem );
331 QDomElement
getParameterElement( QDomDocument &doc,
const QString &name,
const QStringList &values )
333 QDomElement parameterElement = doc.createElement( QStringLiteral(
"ows:Parameter" ) );
334 parameterElement.setAttribute( QStringLiteral(
"name" ), name );
336 for (
const QString &v : values )
338 QDomElement valueElement = doc.createElement( QStringLiteral(
"ows:Value" ) );
339 QDomText valueText = doc.createTextNode( v );
340 valueElement.appendChild( valueText );
341 parameterElement.appendChild( valueElement );
344 return parameterElement;
349 QDomElement oprationsElement = doc.createElement( QStringLiteral(
"ows:OperationsMetadata" ) );
352 QString hrefString =
serviceUrl( request, project );
354 QDomElement operationElement = doc.createElement( QStringLiteral(
"ows:Operation" ) );
355 QDomElement dcpElement = doc.createElement( QStringLiteral(
"ows:DCP" ) );
356 QDomElement httpElement = doc.createElement( QStringLiteral(
"ows:HTTP" ) );
357 QDomElement getElement = doc.createElement( QStringLiteral(
"ows:Get" ) );
358 getElement.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
359 httpElement.appendChild( getElement );
361 QDomElement postElement = doc.createElement( QStringLiteral(
"ows:Post" ) );
362 postElement.setAttribute( QStringLiteral(
"xlink:href" ), hrefString );
363 httpElement.appendChild( postElement );
365 dcpElement.appendChild( httpElement );
366 operationElement.appendChild( dcpElement );
369 QDomElement getCapabilitiesElement = operationElement.cloneNode().toElement();
370 getCapabilitiesElement.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"GetCapabilities" ) );
372 QDomElement serviceParameterElement =
getParameterElement( doc, QStringLiteral(
"service" ),
373 QStringList() << QStringLiteral(
"WFS" ) );
374 getCapabilitiesElement.appendChild( serviceParameterElement );
376 QDomElement acceptVersionsParameterElement =
getParameterElement( doc, QStringLiteral(
"AcceptVersions" ),
377 QStringList() << QStringLiteral(
"1.1.0" ) << QStringLiteral(
"1.0.0" ) );
378 getCapabilitiesElement.appendChild( acceptVersionsParameterElement );
380 QDomElement acceptFormatsParameterElement =
getParameterElement( doc, QStringLiteral(
"AcceptFormats" ),
381 QStringList() << QStringLiteral(
"text/xml" ) );
382 getCapabilitiesElement.appendChild( acceptFormatsParameterElement );
384 oprationsElement.appendChild( getCapabilitiesElement );
387 QDomElement describeFeatureTypeElement = operationElement.cloneNode().toElement();
388 describeFeatureTypeElement.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"DescribeFeatureType" ) );
390 QDomElement dftOutputFormatParameterElement =
getParameterElement( doc, QStringLiteral(
"outputFormat" ),
391 QStringList() << QStringLiteral(
"XMLSCHEMA" )
392 << QStringLiteral(
"text/xml; subtype=gml/2.1.2" )
393 << QStringLiteral(
"text/xml; subtype=gml/3.1.1" ) );
394 describeFeatureTypeElement.appendChild( dftOutputFormatParameterElement );
396 oprationsElement.appendChild( describeFeatureTypeElement );
399 QDomElement getFeatureElement = operationElement.cloneNode().toElement();
400 getFeatureElement.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"GetFeature" ) );
402 QDomElement gfOutputFormatParameterElement =
getParameterElement( doc, QStringLiteral(
"outputFormat" ),
403 QStringList() << QStringLiteral(
"text/xml; subtype=gml/2.1.2" )
404 << QStringLiteral(
"text/xml; subtype=gml/3.1.1" )
405 << QStringLiteral(
"application/vnd.geo+json" ) );
406 getFeatureElement.appendChild( gfOutputFormatParameterElement );
408 QDomElement resultTypeParameterElement =
getParameterElement( doc, QStringLiteral(
"resultType" ),
409 QStringList() << QStringLiteral(
"results" ) << QStringLiteral(
"hits" ) );
410 getFeatureElement.appendChild( resultTypeParameterElement );
412 oprationsElement.appendChild( getFeatureElement );
415 QDomElement transactionElement = operationElement.cloneNode().toElement();
416 transactionElement.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"Transaction" ) );
418 QDomElement inputFormatParameterElement =
getParameterElement( doc, QStringLiteral(
"inputFormat" ),
419 QStringList() << QStringLiteral(
"text/xml; subtype=gml/2.1.2" )
420 << QStringLiteral(
"text/xml; subtype=gml/3.1.1" )
421 << QStringLiteral(
"application/vnd.geo+json" ) );
422 transactionElement.appendChild( inputFormatParameterElement );
424 oprationsElement.appendChild( transactionElement );
426 return oprationsElement;
432 #ifdef HAVE_SERVER_PYTHON_PLUGINS
439 QDomElement featureTypeListElement = doc.createElement( QStringLiteral(
"FeatureTypeList" ) );
441 QDomElement operationsElement = doc.createElement( QStringLiteral(
"Operations" ) );
442 featureTypeListElement.appendChild( operationsElement );
444 QDomElement operationElement = doc.createElement( QStringLiteral(
"Operation" ) );
445 QDomText queryText = doc.createTextNode(
"Query" );
446 operationElement.appendChild( queryText );
447 operationsElement.appendChild( operationElement );
464 #ifdef HAVE_SERVER_PYTHON_PLUGINS
470 QDomElement layerElem = doc.createElement( QStringLiteral(
"FeatureType" ) );
473 QDomElement nameElem = doc.createElement( QStringLiteral(
"Name" ) );
474 QDomText nameText = doc.createTextNode(
layerTypeName( layer ) );
475 nameElem.appendChild( nameText );
476 layerElem.appendChild( nameElem );
479 QDomElement titleElem = doc.createElement( QStringLiteral(
"Title" ) );
480 QString title = layer->
title();
481 if ( title.isEmpty() )
483 title = layer->
name();
485 QDomText titleText = doc.createTextNode( title );
486 titleElem.appendChild( titleText );
487 layerElem.appendChild( titleElem );
490 QString
abstract = layer->
abstract();
491 if ( !
abstract.isEmpty() )
493 QDomElement abstractElem = doc.createElement( QStringLiteral(
"Abstract" ) );
494 QDomText abstractText = doc.createTextNode(
abstract );
495 abstractElem.appendChild( abstractText );
496 layerElem.appendChild( abstractElem );
501 if ( !keywords.isEmpty() )
503 QDomElement keywordsElem = doc.createElement( QStringLiteral(
"ows:Keywords" ) );
504 for (
const QString &keyword : keywords.split(
',' ) )
506 if ( !keyword.trimmed().isEmpty() )
508 QDomElement keywordElem = doc.createElement( QStringLiteral(
"ows:Keyword" ) );
509 QDomText keywordText = doc.createTextNode( keyword.trimmed() );
510 keywordElem.appendChild( keywordText );
511 keywordsElem.appendChild( keywordElem );
514 layerElem.appendChild( keywordsElem );
518 const QString defaultSrs = layer->
crs().
authid();
519 QDomElement srsElem = doc.createElement( QStringLiteral(
"DefaultSRS" ) );
520 QDomText srsText = doc.createTextNode( defaultSrs );
521 srsElem.appendChild( srsText );
522 layerElem.appendChild( srsElem );
526 for (
const QString &
crs : outputCrsList )
528 if (
crs == defaultSrs )
530 QDomElement otherSrsElem = doc.createElement( QStringLiteral(
"OtherSRS" ) );
531 QDomText otherSrsText = doc.createTextNode(
crs );
532 otherSrsElem.appendChild( otherSrsText );
533 layerElem.appendChild( otherSrsElem );
537 QDomElement operationsElement = doc.createElement( QStringLiteral(
"Operations" ) );
539 QDomElement operationElement = doc.createElement( QStringLiteral(
"Operation" ) );
540 QDomText queryText = doc.createTextNode( QStringLiteral(
"Query" ) );
541 operationElement.appendChild( queryText );
542 operationsElement.appendChild( operationElement );
544 if ( wfstUpdateLayersId.contains( layer->
id() ) ||
545 wfstInsertLayersId.contains( layer->
id() ) ||
546 wfstDeleteLayersId.contains( layer->
id() ) )
553 QDomElement operationElement = doc.createElement( QStringLiteral(
"Operation" ) );
554 QDomText insertText = doc.createTextNode( QStringLiteral(
"Insert" ) );
555 operationElement.appendChild( insertText );
556 operationsElement.appendChild( operationElement );
561 wfstUpdateLayersId.contains( layer->
id() ) )
564 QDomElement operationElement = doc.createElement( QStringLiteral(
"Operation" ) );
565 QDomText updateText = doc.createTextNode( QStringLiteral(
"Update" ) );
566 operationElement.appendChild( updateText );
567 operationsElement.appendChild( operationElement );
573 QDomElement operationElement = doc.createElement( QStringLiteral(
"Operation" ) );
574 QDomText deleteText = doc.createTextNode( QStringLiteral(
"Delete" ) );
575 operationElement.appendChild( deleteText );
576 operationsElement.appendChild( operationElement );
580 layerElem.appendChild( operationsElement );
586 int wgs84precision = 6;
588 if ( !layerExtent.
isNull() )
593 wgs84BoundingRect = exGeoTransform.transformBoundingBox( layerExtent );
602 QDomElement bBoxElement = doc.createElement( QStringLiteral(
"ows:WGS84BoundingBox" ) );
603 bBoxElement.setAttribute( QStringLiteral(
"dimensions" ), QStringLiteral(
"2" ) );
604 QDomElement lCornerElement = doc.createElement( QStringLiteral(
"ows:LowerCorner" ) );
606 lCornerElement.appendChild( lCornerText );
607 bBoxElement.appendChild( lCornerElement );
608 QDomElement uCornerElement = doc.createElement( QStringLiteral(
"ows:UpperCorner" ) );
610 uCornerElement.appendChild( uCornerText );
611 bBoxElement.appendChild( uCornerElement );
612 layerElem.appendChild( bBoxElement );
616 if ( !metadataUrl.isEmpty() )
618 QDomElement metaUrlElem = doc.createElement( QStringLiteral(
"MetadataURL" ) );
620 metaUrlElem.setAttribute( QStringLiteral(
"type" ), metadataUrlType );
622 metaUrlElem.setAttribute( QStringLiteral(
"format" ), metadataUrlFormat );
623 QDomText metaUrlText = doc.createTextNode( metadataUrl );
624 metaUrlElem.appendChild( metaUrlText );
625 layerElem.appendChild( metaUrlElem );
628 featureTypeListElement.appendChild( layerElem );
631 return featureTypeListElement;