Example #1
0
  QDomElement getCapabilityElement( QDomDocument &doc, const QgsProject *project, const QgsServerRequest &request )
  {
    //wfs:Capability element
    QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wfs:Capability*/ );

    //wfs:Request element
    QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wfs:Request*/ );
    capabilityElement.appendChild( requestElement );
    //wfs:GetCapabilities
    QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wfs:GetCapabilities*/ );
    requestElement.appendChild( getCapabilitiesElement );

    QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wfs:DCPType*/ );
    getCapabilitiesElement.appendChild( dcpTypeElement );
    QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wfs:HTTP*/ );
    dcpTypeElement.appendChild( httpElement );

    //Prepare url
    QString hrefString = serviceUrl( request, project );

    //only Get supported for the moment
    QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wfs:Get*/ );
    httpElement.appendChild( getElement );
    getElement.setAttribute( QStringLiteral( "onlineResource" ), hrefString );
    QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );

    //wfs:DescribeFeatureType
    QDomElement describeFeatureTypeElement = doc.createElement( QStringLiteral( "DescribeFeatureType" )/*wfs:DescribeFeatureType*/ );
    requestElement.appendChild( describeFeatureTypeElement );
    QDomElement schemaDescriptionLanguageElement = doc.createElement( QStringLiteral( "SchemaDescriptionLanguage" )/*wfs:SchemaDescriptionLanguage*/ );
    describeFeatureTypeElement.appendChild( schemaDescriptionLanguageElement );
    QDomElement xmlSchemaElement = doc.createElement( QStringLiteral( "XMLSCHEMA" )/*wfs:XMLSCHEMA*/ );
    schemaDescriptionLanguageElement.appendChild( xmlSchemaElement );
    QDomElement describeFeatureTypeDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypeElement );
    QDomElement describeFeatureTypeDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    describeFeatureTypeDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypePostElement );

    //wfs:GetFeature
    QDomElement getFeatureElement = doc.createElement( QStringLiteral( "GetFeature" )/*wfs:GetFeature*/ );
    requestElement.appendChild( getFeatureElement );
    QDomElement getFeatureFormatElement = doc.createElement( QStringLiteral( "ResultFormat" ) );/*wfs:ResultFormat*/
    getFeatureElement.appendChild( getFeatureFormatElement );
    QDomElement gmlFormatElement = doc.createElement( QStringLiteral( "GML2" ) );/*wfs:GML2*/
    getFeatureFormatElement.appendChild( gmlFormatElement );
    QDomElement gml3FormatElement = doc.createElement( QStringLiteral( "GML3" ) );/*wfs:GML3*/
    getFeatureFormatElement.appendChild( gml3FormatElement );
    QDomElement geojsonFormatElement = doc.createElement( QStringLiteral( "GeoJSON" ) );/*wfs:GeoJSON*/
    getFeatureFormatElement.appendChild( geojsonFormatElement );
    QDomElement getFeatureDhcTypeGetElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getFeatureElement.appendChild( getFeatureDhcTypeGetElement );
    QDomElement getFeatureDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getFeatureDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    getFeatureElement.appendChild( getFeatureDhcTypePostElement );

    //wfs:Transaction
    QDomElement transactionElement = doc.createElement( QStringLiteral( "Transaction" )/*wfs:Transaction*/ );
    requestElement.appendChild( transactionElement );
    QDomElement transactionDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    transactionDhcTypeElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    transactionElement.appendChild( transactionDhcTypeElement );

    return capabilityElement;
  }
Example #2
0
  QDomDocument createGetCapabilitiesDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    //wcs:WCS_Capabilities element
    QDomElement wcsCapabilitiesElement = doc.createElement( QStringLiteral( "WCS_Capabilities" )/*wcs:WCS_Capabilities*/ );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), implementationVersion() );
    wcsCapabilitiesElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
    doc.appendChild( wcsCapabilitiesElement );

    //INSERT Service
    wcsCapabilitiesElement.appendChild( getServiceElement( doc, project ) );

    //wcs:Capability element
    QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wcs:Capability*/ );
    wcsCapabilitiesElement.appendChild( capabilityElement );

    //wcs:Request element
    QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wcs:Request*/ );
    capabilityElement.appendChild( requestElement );

    //wcs:GetCapabilities
    QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wcs:GetCapabilities*/ );
    requestElement.appendChild( getCapabilitiesElement );

    QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wcs:DCPType*/ );
    getCapabilitiesElement.appendChild( dcpTypeElement );
    QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wcs:HTTP*/ );
    dcpTypeElement.appendChild( httpElement );

    //Prepare url
    QString hrefString = serviceUrl( request, project );

    QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wcs:Get*/ );
    httpElement.appendChild( getElement );
    QDomElement onlineResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wcs:OnlineResource*/ );
    onlineResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
    onlineResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
    getElement.appendChild( onlineResourceElement );

    QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );

    QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
    describeCoverageElement.setTagName( QStringLiteral( "DescribeCoverage" ) );
    requestElement.appendChild( describeCoverageElement );

    QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
    getCoverageElement.setTagName( QStringLiteral( "GetCoverage" ) );
    requestElement.appendChild( getCoverageElement );

    //INSERT ContentMetadata
    wcsCapabilitiesElement.appendChild( getContentMetadataElement( doc, serverIface, project ) );

    return doc;

  }
Example #3
0
QDomDocument QgsWCSServer::getCapabilities()
{
  QgsDebugMsg( "Entering." );
  QDomDocument doc;

  //wcs:WCS_Capabilities element
  QDomElement wcsCapabilitiesElement = doc.createElement( "WCS_Capabilities"/*wcs:WCS_Capabilities*/ );
  wcsCapabilitiesElement.setAttribute( "xmlns", WCS_NAMESPACE );
  wcsCapabilitiesElement.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
  wcsCapabilitiesElement.setAttribute( "xsi:schemaLocation", WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
  wcsCapabilitiesElement.setAttribute( "xmlns:gml", GML_NAMESPACE );
  wcsCapabilitiesElement.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
  wcsCapabilitiesElement.setAttribute( "version", "1.0.0" );
  wcsCapabilitiesElement.setAttribute( "updateSequence", "0" );
  doc.appendChild( wcsCapabilitiesElement );

  if ( mConfigParser )
  {
    mConfigParser->serviceCapabilities( wcsCapabilitiesElement, doc );
  }

  //INSERT Service

  //wcs:Capability element
  QDomElement capabilityElement = doc.createElement( "Capability"/*wcs:Capability*/ );
  wcsCapabilitiesElement.appendChild( capabilityElement );

  //wcs:Request element
  QDomElement requestElement = doc.createElement( "Request"/*wcs:Request*/ );
  capabilityElement.appendChild( requestElement );

  //wcs:GetCapabilities
  QDomElement getCapabilitiesElement = doc.createElement( "GetCapabilities"/*wcs:GetCapabilities*/ );
  requestElement.appendChild( getCapabilitiesElement );

  QDomElement dcpTypeElement = doc.createElement( "DCPType"/*wcs:DCPType*/ );
  getCapabilitiesElement.appendChild( dcpTypeElement );
  QDomElement httpElement = doc.createElement( "HTTP"/*wcs:HTTP*/ );
  dcpTypeElement.appendChild( httpElement );

  //Prepare url
  QString hrefString = mConfigParser->wcsServiceUrl();
  if ( hrefString.isEmpty() )
  {
    hrefString = mConfigParser->serviceUrl();
  }
  if ( hrefString.isEmpty() )
  {
    hrefString = serviceUrl();
  }

  QDomElement getElement = doc.createElement( "Get"/*wcs:Get*/ );
  httpElement.appendChild( getElement );
  QDomElement onlineResourceElement = doc.createElement( "OnlineResource"/*wcs:OnlineResource*/ );
  onlineResourceElement.setAttribute( "xlink:type", "simple" );
  onlineResourceElement.setAttribute( "xlink:href", hrefString );
  getElement.appendChild( onlineResourceElement );

  QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
  getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( "Post" );
  getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );

  QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
  describeCoverageElement.setTagName( "DescribeCoverage" );
  requestElement.appendChild( describeCoverageElement );

  QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
  getCoverageElement.setTagName( "GetCoverage" );
  requestElement.appendChild( getCoverageElement );

  /*
   * Adding layer list in ContentMetadata
   */
  QDomElement contentMetadataElement = doc.createElement( "ContentMetadata"/*wcs:ContentMetadata*/ );
  wcsCapabilitiesElement.appendChild( contentMetadataElement );
  /*
   * Adding layer liste in contentMetadataElement
   */
  if ( mConfigParser )
  {
    mConfigParser->wcsContentMetadata( contentMetadataElement, doc );
  }

  return doc;
}
  QDomDocument createGetCapabilitiesDocument( QgsServerInterface* serverIface, const QgsProject* project, const QString& version,
      const QgsServerRequest& request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsWfsProjectParser* configParser = getConfigParser( serverIface );

    //wfs:WFS_Capabilities element
    QDomElement wfsCapabilitiesElement = doc.createElement( QStringLiteral( "WFS_Capabilities" )/*wms:WFS_Capabilities*/ );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), WFS_NAMESPACE );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WFS_NAMESPACE + " http://schemas.opengis.net/wfs/1.0.0/WFS-capabilities.xsd" );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), implementationVersion() );
    wfsCapabilitiesElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
    doc.appendChild( wfsCapabilitiesElement );

    configParser->serviceCapabilities( wfsCapabilitiesElement, doc );

    //wfs:Capability element
    QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wfs:Capability*/ );
    wfsCapabilitiesElement.appendChild( capabilityElement );

    //wfs:Request element
    QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wfs:Request*/ );
    capabilityElement.appendChild( requestElement );
    //wfs:GetCapabilities
    QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wfs:GetCapabilities*/ );
    requestElement.appendChild( getCapabilitiesElement );

    QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wfs:DCPType*/ );
    getCapabilitiesElement.appendChild( dcpTypeElement );
    QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wfs:HTTP*/ );
    dcpTypeElement.appendChild( httpElement );

    //Prepare url
    QString hrefString = serviceUrl( request, project );

    //only Get supported for the moment
    QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wfs:Get*/ );
    httpElement.appendChild( getElement );
    getElement.setAttribute( QStringLiteral( "onlineResource" ), hrefString );
    QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );

    //wfs:DescribeFeatureType
    QDomElement describeFeatureTypeElement = doc.createElement( QStringLiteral( "DescribeFeatureType" )/*wfs:DescribeFeatureType*/ );
    requestElement.appendChild( describeFeatureTypeElement );
    QDomElement schemaDescriptionLanguageElement = doc.createElement( QStringLiteral( "SchemaDescriptionLanguage" )/*wfs:SchemaDescriptionLanguage*/ );
    describeFeatureTypeElement.appendChild( schemaDescriptionLanguageElement );
    QDomElement xmlSchemaElement = doc.createElement( QStringLiteral( "XMLSCHEMA" )/*wfs:XMLSCHEMA*/ );
    schemaDescriptionLanguageElement.appendChild( xmlSchemaElement );
    QDomElement describeFeatureTypeDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypeElement );
    QDomElement describeFeatureTypeDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    describeFeatureTypeDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypePostElement );

    //wfs:GetFeature
    QDomElement getFeatureElement = doc.createElement( QStringLiteral( "GetFeature" )/*wfs:GetFeature*/ );
    requestElement.appendChild( getFeatureElement );
    QDomElement getFeatureFormatElement = doc.createElement( QStringLiteral( "ResultFormat" ) );/*wfs:ResultFormat*/
    getFeatureElement.appendChild( getFeatureFormatElement );
    QDomElement gmlFormatElement = doc.createElement( QStringLiteral( "GML2" ) );/*wfs:GML2*/
    getFeatureFormatElement.appendChild( gmlFormatElement );
    QDomElement gml3FormatElement = doc.createElement( QStringLiteral( "GML3" ) );/*wfs:GML3*/
    getFeatureFormatElement.appendChild( gml3FormatElement );
    QDomElement geojsonFormatElement = doc.createElement( QStringLiteral( "GeoJSON" ) );/*wfs:GeoJSON*/
    getFeatureFormatElement.appendChild( geojsonFormatElement );
    QDomElement getFeatureDhcTypeGetElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getFeatureElement.appendChild( getFeatureDhcTypeGetElement );
    QDomElement getFeatureDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    getFeatureDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    getFeatureElement.appendChild( getFeatureDhcTypePostElement );

    //wfs:Transaction
    QDomElement transactionElement = doc.createElement( QStringLiteral( "Transaction" )/*wfs:Transaction*/ );
    requestElement.appendChild( transactionElement );
    QDomElement transactionDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
    transactionDhcTypeElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
    transactionElement.appendChild( transactionDhcTypeElement );

    //wfs:FeatureTypeList element
    QDomElement featureTypeListElement = doc.createElement( QStringLiteral( "FeatureTypeList" )/*wfs:FeatureTypeList*/ );
    wfsCapabilitiesElement.appendChild( featureTypeListElement );
    //wfs:Operations element
    QDomElement operationsElement = doc.createElement( QStringLiteral( "Operations" )/*wfs:Operations*/ );
    featureTypeListElement.appendChild( operationsElement );
    //wfs:Query element
    QDomElement queryElement = doc.createElement( QStringLiteral( "Query" )/*wfs:Query*/ );
    operationsElement.appendChild( queryElement );
    /*
     * Adding layer liste in featureTypeListElement
     */
    configParser->featureTypeList( featureTypeListElement, doc );

    /*
     * Adding ogc:Filter_Capabilities in capabilityElement
     */
    //ogc:Filter_Capabilities element
    QDomElement filterCapabilitiesElement = doc.createElement( QStringLiteral( "ogc:Filter_Capabilities" )/*ogc:Filter_Capabilities*/ );
    wfsCapabilitiesElement.appendChild( filterCapabilitiesElement );
    QDomElement spatialCapabilitiesElement = doc.createElement( QStringLiteral( "ogc:Spatial_Capabilities" )/*ogc:Spatial_Capabilities*/ );
    filterCapabilitiesElement.appendChild( spatialCapabilitiesElement );
    QDomElement spatialOperatorsElement = doc.createElement( QStringLiteral( "ogc:Spatial_Operators" )/*ogc:Spatial_Operators*/ );
    spatialCapabilitiesElement.appendChild( spatialOperatorsElement );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:BBOX" )/*ogc:BBOX*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Disjoint" )/*ogc:Disjoint*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Intersect" )/*ogc:Intersects*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Touches" )/*ogc:Touches*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Crosses" )/*ogc:Crosses*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Contains" )/*ogc:Contains*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Overlaps" )/*ogc:Overlaps*/ ) );
    spatialOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Within" )/*ogc:Within*/ ) );
    QDomElement scalarCapabilitiesElement = doc.createElement( QStringLiteral( "ogc:Scalar_Capabilities" )/*ogc:Scalar_Capabilities*/ );
    filterCapabilitiesElement.appendChild( scalarCapabilitiesElement );
    QDomElement comparisonOperatorsElement = doc.createElement( QStringLiteral( "ogc:Comparison_Operators" )/*ogc:Comparison_Operators*/ );
    scalarCapabilitiesElement.appendChild( comparisonOperatorsElement );
    comparisonOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Simple_Comparisons" )/*ogc:Simple_Comparisons*/ ) );
    comparisonOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Between" )/*ogc:Between*/ ) );
    comparisonOperatorsElement.appendChild( doc.createElement( QStringLiteral( "ogc:Like" )/*ogc:Like*/ ) );

    return doc;

  }
Example #5
0
QDomDocument getCapabilities( QgsServerInterface* serverIface, const QString& version,
                              const QgsServerRequest& request, bool projectSettings )
{
    QDomDocument doc;
    QDomElement wmsCapabilitiesElement;

    QgsWmsConfigParser* configParser = getConfigParser( serverIface );

    QgsServerRequest::Parameters parameters = request.parameters();

    // Get service URL
    QUrl href = serviceUrl( request, configParser );

    //href needs to be a prefix
    QString hrefString = href.toString( QUrl::FullyDecoded );
    hrefString.append( href.hasQuery() ? "&" : "?" );

    // XML declaration
    QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral( "xml" ),
            QStringLiteral( "version=\"1.0\" encoding=\"utf-8\"" ) );

    // Append format helper
    std::function < void ( QDomElement&, const QString& ) > appendFormat = [&doc]( QDomElement & elem, const QString & format )
    {
        QDomElement formatElem = doc.createElement( QStringLiteral( "Format" )/*wms:Format*/ );
        formatElem.appendChild( doc.createTextNode( format ) );
        elem.appendChild( formatElem );
    };

    if ( version == QLatin1String( "1.1.1" ) )
    {
        doc = QDomDocument( QStringLiteral( "WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );  //WMS 1.1.1 needs DOCTYPE  "SYSTEM http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd"
        doc.appendChild( xmlDeclaration );
        wmsCapabilitiesElement = doc.createElement( QStringLiteral( "WMT_MS_Capabilities" )/*wms:WMS_Capabilities*/ );
    }
    else // 1.3.0 as default
    {
        doc.appendChild( xmlDeclaration );
        wmsCapabilitiesElement = doc.createElement( QStringLiteral( "WMS_Capabilities" )/*wms:WMS_Capabilities*/ );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.opengis.net/wms" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:sld" ), QStringLiteral( "http://www.opengis.net/sld" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:qgs" ), QStringLiteral( "http://www.qgis.org/wms" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
        QString schemaLocation = QStringLiteral( "http://www.opengis.net/wms" );
        schemaLocation += QLatin1String( " http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
        schemaLocation += QLatin1String( " http://www.opengis.net/sld" );
        schemaLocation += QLatin1String( " http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
        schemaLocation += QLatin1String( " http://www.qgis.org/wms" );
        if ( configParser && configParser->wmsInspireActivated() )
        {
            wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:inspire_common" ), QStringLiteral( "http://inspire.ec.europa.eu/schemas/common/1.0" ) );
            wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:inspire_vs" ), QStringLiteral( "http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
            schemaLocation += QLatin1String( " http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
            schemaLocation += QLatin1String( " http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
        }

        schemaLocation += " " + hrefString + "SERVICE=WMS&REQUEST=GetSchemaExtension";
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), schemaLocation );
    }
    wmsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), version );
    doc.appendChild( wmsCapabilitiesElement );

    configParser->serviceCapabilities( wmsCapabilitiesElement, doc );

    //wms:Capability element
    QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wms:Capability*/ );
    wmsCapabilitiesElement.appendChild( capabilityElement );
    //wms:Request element
    QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wms:Request*/ );
    capabilityElement.appendChild( requestElement );

    QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wms:DCPType*/ );
    QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wms:HTTP*/ );
    dcpTypeElement.appendChild( httpElement );

    QDomElement elem;

    //wms:GetCapabilities
    elem = doc.createElement( QStringLiteral( "GetCapabilities" )/*wms:GetCapabilities*/ );
    appendFormat( elem, ( version == QLatin1String( "1.1.1" ) ? "application/vnd.ogc.wms_xml" : "text/xml" ) );
    elem.appendChild( dcpTypeElement );
    requestElement.appendChild( elem );

    // SOAP platform
    //only give this information if it is not a WMS request to be in sync with the WMS capabilities schema
    // XXX Not even sure that cam be ever true
    if ( parameters.value( QStringLiteral( "SERVICE" ) ).compare( QLatin1String( "WMS" ), Qt::CaseInsensitive ) != 0 )
    {
        QDomElement soapElement = doc.createElement( QStringLiteral( "SOAP" )/*wms:SOAP*/ );
        httpElement.appendChild( soapElement );
        QDomElement soapResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wms:OnlineResource*/ );
        soapResourceElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
        soapResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
        soapResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
        soapElement.appendChild( soapResourceElement );
    }

    //only Get supported for the moment
    QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wms:Get*/ );
    httpElement.appendChild( getElement );
    QDomElement olResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wms:OnlineResource*/ );
    olResourceElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    olResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
    olResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
    getElement.appendChild( olResourceElement );

    //wms:GetMap
    elem = doc.createElement( QStringLiteral( "GetMap" )/*wms:GetMap*/ );
    appendFormat( elem, QStringLiteral( "image/jpeg" ) );
    appendFormat( elem, QStringLiteral( "image/png" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=16bit" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=8bit" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=1bit" ) );
    appendFormat( elem, QStringLiteral( "application/dxf" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetFeatureInfo
    elem = doc.createElement( QStringLiteral( "GetFeatureInfo" ) );
    appendFormat( elem, QStringLiteral( "text/plain" ) );
    appendFormat( elem, QStringLiteral( "text/html" ) );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    appendFormat( elem, QStringLiteral( "application/vnd.ogc.gml" ) );
    appendFormat( elem, QStringLiteral( "application/vnd.ogc.gml/3.1.1" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetLegendGraphic
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "GetLegendGraphic" : "sld:GetLegendGraphic" )/*wms:GetLegendGraphic*/ );
    appendFormat( elem, QStringLiteral( "image/jpeg" ) );
    appendFormat( elem, QStringLiteral( "image/png" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); // this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:DescribeLayer
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "DescribeLayer" : "sld:DescribeLayer" )/*wms:GetLegendGraphic*/ );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); // this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetStyles
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "GetStyles" : "qgs:GetStyles" )/*wms:GetStyles*/ );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    if ( projectSettings ) //remove composer templates from GetCapabilities in the long term
    {
        //wms:GetPrint
        elem = doc.createElement( QStringLiteral( "GetPrint" ) /*wms:GetPrint*/ );
        appendFormat( elem, QStringLiteral( "svg" ) );
        appendFormat( elem, QStringLiteral( "png" ) );
        appendFormat( elem, QStringLiteral( "pdf" ) );
        elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
        requestElement.appendChild( elem );
    }

    //Exception element is mandatory
    elem = doc.createElement( QStringLiteral( "Exception" ) );
    appendFormat( elem, ( version == QLatin1String( "1.1.1" ) ? "application/vnd.ogc.se_xml" : "XML" ) );
    capabilityElement.appendChild( elem );

    //UserDefinedSymbolization element
    if ( version == QLatin1String( "1.3.0" ) )
    {
        elem = doc.createElement( QStringLiteral( "sld:UserDefinedSymbolization" ) );
        elem.setAttribute( QStringLiteral( "SupportSLD" ), QStringLiteral( "1" ) );
        elem.setAttribute( QStringLiteral( "UserLayer" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "UserStyle" ), QStringLiteral( "1" ) );
        elem.setAttribute( QStringLiteral( "RemoteWFS" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "InlineFeature" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "RemoteWCS" ), QStringLiteral( "0" ) );
        capabilityElement.appendChild( elem );

        if ( configParser->wmsInspireActivated() )
        {
            configParser->inspireCapabilities( capabilityElement, doc );
        }
    }

    if ( projectSettings )
    {
        //Insert <ComposerTemplate> elements derived from wms:_ExtendedCapabilities
        configParser->printCapabilities( capabilityElement, doc );

        //WFS layers
        QStringList wfsLayers = configParser->wfsLayerNames();
        if ( !wfsLayers.isEmpty() )
        {
            QDomElement wfsLayersElem = doc.createElement( QStringLiteral( "WFSLayers" ) );
            for ( auto wfsIt = wfsLayers.constBegin() ; wfsIt != wfsLayers.constEnd(); ++wfsIt )
            {
                QDomElement wfsLayerElem = doc.createElement( QStringLiteral( "WFSLayer" ) );
                wfsLayerElem.setAttribute( QStringLiteral( "name" ), *wfsIt );
                wfsLayersElem.appendChild( wfsLayerElem );
            }
            capabilityElement.appendChild( wfsLayersElem );
        }
    }

    //add the xml content for the individual layers/styles
    configParser->layersAndStylesCapabilities( capabilityElement, doc, version, projectSettings );

    return doc;
}
  // DescribeLayer is defined for WMS1.1.1/SLD1.0 and in WMS 1.3.0 SLD Extension
  QDomDocument describeLayer( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                              const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters parameters = request.parameters();

    if ( !parameters.contains( QStringLiteral( "SLD_VERSION" ) ) )
    {
      throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
                                 QStringLiteral( "SLD_VERSION is mandatory for DescribeLayer operation" ), 400 );
    }
    if ( parameters[ QStringLiteral( "SLD_VERSION" )] != QLatin1String( "1.1.0" ) )
    {
      throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ),
                                 QStringLiteral( "SLD_VERSION = %1 is not supported" ).arg( parameters[ QStringLiteral( "SLD_VERSION" )] ), 400 );
    }

    if ( !parameters.contains( QStringLiteral( "LAYERS" ) ) )
    {
      throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
                                 QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ), 400 );
    }

    QStringList layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', QString::SkipEmptyParts );
    if ( layersList.isEmpty() )
    {
      throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 );
    }
    QDomDocument myDocument = QDomDocument();

    QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
    myDocument.appendChild( header );

    // Create the root element
    QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) );
    root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) );
    root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
    root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
    root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    myDocument.appendChild( root );

    // store the Version element
    QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) );
    versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) );
    root.appendChild( versionNode );

    // get the wms service url defined in project or keep the one from the
    // request url
    QString wmsHrefString = serviceUrl( request, project ).toString();

    // get the wfs service url defined in project or take the same as the
    // wms service url
    QString wfsHrefString = QgsServerProjectUtils::wfsServiceUrl( *project );
    if ( wfsHrefString.isEmpty() )
    {
      wfsHrefString = wmsHrefString;
    }

    // get the wcs service url defined in project or take the same as the
    // wms service url
    QString wcsHrefString = QgsServerProjectUtils::wcsServiceUrl( *project );
    if ( wcsHrefString.isEmpty() )
    {
      wcsHrefString = wmsHrefString;
    }

    // access control
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif
    // Use layer ids
    bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
    // WMS restricted layers
    QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
    // WFS layers
    QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
    // WCS layers
    QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );

    for ( QgsMapLayer *layer : project->mapLayers() )
    {
      QString name = layer->name();
      if ( useLayerIds )
        name = layer->id();
      else if ( !layer->shortName().isEmpty() )
        name = layer->shortName();

      if ( !layersList.contains( name ) )
      {
        continue;
      }

      //unpublished layer
      if ( restrictedLayers.contains( layer->name() ) )
      {
        throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
      }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( accessControl && !accessControl->layerReadPermission( layer ) )
      {
        throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
      }
#endif

      // Create the NamedLayer element
      QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
      root.appendChild( layerNode );

      // store the owsType element
      QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
      // store the se:OnlineResource element
      QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
      oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
      // store the TypeName element
      QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
      switch ( layer->type() )
      {
        case QgsMapLayer::VectorLayer:
        {
          typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );

          if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
          {
            oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
          }

          // store the se:FeatureTypeName element
          QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
          typeNameNode.appendChild( myDocument.createTextNode( name ) );
          nameNode.appendChild( typeNameNode );
          break;
        }
        case QgsMapLayer::RasterLayer:
        {
          typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );

          if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
          {
            oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
          }

          // store the se:CoverageTypeName element
          QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
          typeNameNode.appendChild( myDocument.createTextNode( name ) );
          nameNode.appendChild( typeNameNode );
          break;
        }

        case QgsMapLayer::MeshLayer:
        case QgsMapLayer::PluginLayer:
          break;
      }
      layerNode.appendChild( typeNode );
      layerNode.appendChild( oResNode );
      layerNode.appendChild( nameNode );
    }

    return myDocument;
  }