QDomElement getContentMetadataElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project ) { #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsAccessControl *accessControl = serverIface->accessControls(); #endif /* * Adding layer list in ContentMetadata */ QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ ); QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project ); for ( int i = 0; i < wcsLayersId.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) ); if ( layer->type() != QgsMapLayer::LayerType::RasterLayer ) { continue; } #ifdef HAVE_SERVER_PYTHON_PLUGINS if ( !accessControl->layerReadPermission( layer ) ) { continue; } #endif QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer ); QDomElement layerElem = getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), true ); contentMetadataElement.appendChild( layerElem ); } //End return contentMetadataElement; }
QDomElement getFeatureTypeListElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project ) { QgsAccessControl *accessControl = serverIface->accessControls(); //wfs:FeatureTypeList element QDomElement featureTypeListElement = doc.createElement( QStringLiteral( "FeatureTypeList" )/*wfs:FeatureTypeList*/ ); //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 ); QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project ); QStringList wfstUpdateLayersId = QgsServerProjectUtils::wfstUpdateLayerIds( *project ); QStringList wfstInsertLayersId = QgsServerProjectUtils::wfstInsertLayerIds( *project ); QStringList wfstDeleteLayersId = QgsServerProjectUtils::wfstDeleteLayerIds( *project ); for ( int i = 0; i < wfsLayerIds.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) ); if ( layer->type() != QgsMapLayer::LayerType::VectorLayer ) { continue; } if ( accessControl && !accessControl->layerReadPermission( layer ) ) { continue; } QDomElement layerElem = doc.createElement( QStringLiteral( "FeatureType" ) ); //create Name QDomElement nameElem = doc.createElement( QStringLiteral( "Name" ) ); QString typeName = layer->name(); if ( !layer->shortName().isEmpty() ) typeName = layer->shortName(); typeName = typeName.replace( QLatin1String( " " ), QLatin1String( "_" ) ); QDomText nameText = doc.createTextNode( typeName ); nameElem.appendChild( nameText ); layerElem.appendChild( nameElem ); //create Title QDomElement titleElem = doc.createElement( QStringLiteral( "Title" ) ); QString title = layer->title(); if ( title.isEmpty() ) { title = layer->name(); } QDomText titleText = doc.createTextNode( title ); titleElem.appendChild( titleText ); layerElem.appendChild( titleElem ); //create Abstract QString abstract = layer->abstract(); if ( !abstract.isEmpty() ) { QDomElement abstractElem = doc.createElement( QStringLiteral( "Abstract" ) ); QDomText abstractText = doc.createTextNode( abstract ); abstractElem.appendChild( abstractText ); layerElem.appendChild( abstractElem ); } //create keywords QString keywords = layer->keywordList(); if ( !keywords.isEmpty() ) { QDomElement keywordsElem = doc.createElement( QStringLiteral( "Keywords" ) ); QDomText keywordsText = doc.createTextNode( keywords ); keywordsElem.appendChild( keywordsText ); layerElem.appendChild( keywordsElem ); } //create SRS QDomElement srsElem = doc.createElement( QStringLiteral( "SRS" ) ); QDomText srsText = doc.createTextNode( layer->crs().authid() ); srsElem.appendChild( srsText ); layerElem.appendChild( srsElem ); //create LatLongBoundingBox QgsRectangle layerExtent = layer->extent(); QDomElement bBoxElement = doc.createElement( QStringLiteral( "LatLongBoundingBox" ) ); bBoxElement.setAttribute( QStringLiteral( "minx" ), QString::number( layerExtent.xMinimum() ) ); bBoxElement.setAttribute( QStringLiteral( "miny" ), QString::number( layerExtent.yMinimum() ) ); bBoxElement.setAttribute( QStringLiteral( "maxx" ), QString::number( layerExtent.xMaximum() ) ); bBoxElement.setAttribute( QStringLiteral( "maxy" ), QString::number( layerExtent.yMaximum() ) ); layerElem.appendChild( bBoxElement ); // layer metadata URL QString metadataUrl = layer->metadataUrl(); if ( !metadataUrl.isEmpty() ) { QDomElement metaUrlElem = doc.createElement( QStringLiteral( "MetadataURL" ) ); QString metadataUrlType = layer->metadataUrlType(); metaUrlElem.setAttribute( QStringLiteral( "type" ), metadataUrlType ); QString metadataUrlFormat = layer->metadataUrlFormat(); if ( metadataUrlFormat == QLatin1String( "text/xml" ) ) { metaUrlElem.setAttribute( QStringLiteral( "format" ), QStringLiteral( "XML" ) ); } else { metaUrlElem.setAttribute( QStringLiteral( "format" ), QStringLiteral( "TXT" ) ); } QDomText metaUrlText = doc.createTextNode( metadataUrl ); metaUrlElem.appendChild( metaUrlText ); layerElem.appendChild( metaUrlElem ); } //wfs:Operations element QDomElement operationsElement = doc.createElement( QStringLiteral( "Operations" )/*wfs:Operations*/ ); //wfs:Query element QDomElement queryElement = doc.createElement( QStringLiteral( "Query" )/*wfs:Query*/ ); operationsElement.appendChild( queryElement ); if ( wfstUpdateLayersId.contains( layer->id() ) || wfstInsertLayersId.contains( layer->id() ) || wfstDeleteLayersId.contains( layer->id() ) ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ); QgsVectorDataProvider *provider = vlayer->dataProvider(); if ( ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) && wfstInsertLayersId.contains( layer->id() ) ) { //wfs:Insert element QDomElement insertElement = doc.createElement( QStringLiteral( "Insert" )/*wfs:Insert*/ ); operationsElement.appendChild( insertElement ); } if ( ( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) && ( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) && wfstUpdateLayersId.contains( layer->id() ) ) { //wfs:Update element QDomElement updateElement = doc.createElement( QStringLiteral( "Update" )/*wfs:Update*/ ); operationsElement.appendChild( updateElement ); } if ( ( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) && wfstDeleteLayersId.contains( layer->id() ) ) { //wfs:Delete element QDomElement deleteElement = doc.createElement( QStringLiteral( "Delete" )/*wfs:Delete*/ ); operationsElement.appendChild( deleteElement ); } } layerElem.appendChild( operationsElement ); featureTypeListElement.appendChild( layerElem ); } return featureTypeListElement; }
QDomDocument createDescribeCoverageDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request ) { Q_UNUSED( version ); QDomDocument doc; QgsServerRequest::Parameters parameters = request.parameters(); #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsAccessControl *accessControl = serverIface->accessControls(); #endif //wcs:WCS_Capabilities element QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ ); coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE ); coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) ); coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" ); coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE ); coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) ); coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) ); coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) ); doc.appendChild( coveDescElement ); //defining coverage name QString coveNames; //read COVERAGE QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) ); if ( cove_name_it != parameters.constEnd() ) { coveNames = cove_name_it.value(); } if ( coveNames.isEmpty() ) { QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) ); if ( cove_name_it != parameters.constEnd() ) { coveNames = cove_name_it.value(); } } QStringList coveNameList; if ( !coveNames.isEmpty() ) { coveNameList = coveNames.split( ',' ); for ( int i = 0; i < coveNameList.size(); ++i ) { coveNameList.replace( i, coveNameList.at( i ).trimmed() ); } } QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project ); for ( int i = 0; i < wcsLayersId.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) ); if ( !layer ) { continue; } if ( layer->type() != QgsMapLayer::LayerType::RasterLayer ) { continue; } #ifdef HAVE_SERVER_PYTHON_PLUGINS if ( !accessControl->layerReadPermission( layer ) ) { continue; } #endif QString name = layer->name(); if ( !layer->shortName().isEmpty() ) name = layer->shortName(); name = name.replace( ' ', '_' ); if ( coveNameList.size() == 0 || coveNameList.contains( name ) ) { QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer ); coveDescElement.appendChild( getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project ) ); } } return doc; }
QDomDocument createDescribeFeatureTypeDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request ) { Q_UNUSED( version ); QDomDocument doc; QgsServerRequest::Parameters parameters = request.parameters(); QgsWfsParameters wfsParameters( parameters ); QgsWfsParameters::Format oFormat = wfsParameters.outputFormat(); // test oFormat if ( oFormat == QgsWfsParameters::Format::NONE ) throw QgsBadRequestException( QStringLiteral( "Invalid WFS Parameter" ), "OUTPUTFORMAT " + wfsParameters.outputFormatAsString() + "is not supported" ); QgsAccessControl *accessControl = serverIface->accessControls(); //xsd:schema QDomElement schemaElement = doc.createElement( QStringLiteral( "schema" )/*xsd:schema*/ ); schemaElement.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) ); schemaElement.setAttribute( QStringLiteral( "xmlns:xsd" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) ); schemaElement.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE ); schemaElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE ); schemaElement.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE ); schemaElement.setAttribute( QStringLiteral( "targetNamespace" ), QGS_NAMESPACE ); schemaElement.setAttribute( QStringLiteral( "elementFormDefault" ), QStringLiteral( "qualified" ) ); schemaElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) ); doc.appendChild( schemaElement ); //xsd:import QDomElement importElement = doc.createElement( QStringLiteral( "import" )/*xsd:import*/ ); importElement.setAttribute( QStringLiteral( "namespace" ), GML_NAMESPACE ); if ( oFormat == QgsWfsParameters::Format::GML2 ) importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) ); else if ( oFormat == QgsWfsParameters::Format::GML3 ) importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) ); schemaElement.appendChild( importElement ); QStringList typeNameList; QDomDocument queryDoc; QString errorMsg; if ( queryDoc.setContent( parameters.value( QStringLiteral( "REQUEST_BODY" ) ), true, &errorMsg ) ) { //read doc QDomElement queryDocElem = queryDoc.documentElement(); QDomNodeList docChildNodes = queryDocElem.childNodes(); if ( docChildNodes.size() ) { for ( int i = 0; i < docChildNodes.size(); i++ ) { QDomElement docChildElem = docChildNodes.at( i ).toElement(); if ( docChildElem.tagName() == QLatin1String( "TypeName" ) ) { QString typeName = docChildElem.text().trimmed(); if ( typeName.contains( ':' ) ) typeNameList << typeName.section( ':', 1, 1 ); else typeNameList << typeName; } } } } else { QString typeNames = request.parameter( QStringLiteral( "TYPENAME" ) ); if ( !typeNames.isEmpty() ) { QStringList typeNameSplit = typeNames.split( ',' ); for ( int i = 0; i < typeNameSplit.size(); ++i ) { QString typeName = typeNameSplit.at( i ).trimmed(); if ( typeName.contains( ':' ) ) typeNameList << typeName.section( ':', 1, 1 ); else typeNameList << typeName; } } } QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project ); for ( int i = 0; i < wfsLayerIds.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) ); if ( layer->type() != QgsMapLayer::LayerType::VectorLayer ) { continue; } QString name = layer->name(); if ( !layer->shortName().isEmpty() ) name = layer->shortName(); name = name.replace( ' ', '_' ); if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) ) { continue; } if ( accessControl && !accessControl->layerReadPermission( layer ) ) { if ( !typeNameList.isEmpty() ) { throw QgsSecurityAccessException( QStringLiteral( "Feature access permission denied" ) ); } else { continue; } } QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer ); QgsVectorDataProvider *provider = vLayer->dataProvider(); if ( !provider ) { continue; } setSchemaLayer( schemaElement, doc, const_cast<QgsVectorLayer *>( vLayer ) ); } return doc; }
QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsWmtsParameters ¶ms, const QgsProject *project, QgsServerInterface *serverIface ) { #ifndef HAVE_SERVER_PYTHON_PLUGINS ( void )serverIface; #endif //defining Layer QString layer = params.layer(); //read Layer if ( layer.isEmpty() ) { throw QgsRequestNotWellFormedException( QStringLiteral( "Layer is mandatory" ) ); } //check layer value bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) ); QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) ); QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) ); QStringList wmtsLayerIds; if ( wmtsProject ) { // Root Layer name QString rootLayerId = QgsServerProjectUtils::wmsRootName( *project ); if ( rootLayerId.isEmpty() ) { rootLayerId = project->title(); } if ( !rootLayerId.isEmpty() ) { wmtsLayerIds << rootLayerId; } } if ( !wmtsGroupNameList.isEmpty() ) { QgsLayerTreeGroup *treeRoot = project->layerTreeRoot(); for ( const QString &gName : wmtsGroupNameList ) { QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName ); if ( !treeGroup ) { continue; } QString groupLayerId = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString(); if ( groupLayerId.isEmpty() ) { groupLayerId = gName; } wmtsLayerIds << groupLayerId; } } if ( !wmtsLayerIdList.isEmpty() ) { #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsAccessControl *accessControl = serverIface->accessControls(); #endif for ( const QString &lId : wmtsLayerIdList ) { QgsMapLayer *l = project->mapLayer( lId ); if ( !l ) { continue; } #ifdef HAVE_SERVER_PYTHON_PLUGINS if ( !accessControl->layerReadPermission( l ) ) { continue; } #endif QString layerLayerId = l->shortName(); if ( layerLayerId.isEmpty() ) { layerLayerId = l->name(); } wmtsLayerIds << layerLayerId; } } if ( !wmtsLayerIds.contains( layer ) ) { QString msg = QObject::tr( "Layer '%1' not found" ).arg( layer ); throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ), msg ); } //defining Format QString format = params.formatAsString(); //read Format if ( format.isEmpty() ) { throw QgsRequestNotWellFormedException( QStringLiteral( "Format is mandatory" ) ); } //defining TileMatrixSet ref QString tms_ref = params.tileMatrixSet(); //read TileMatrixSet if ( tms_ref.isEmpty() ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is mandatory" ) ); } // verifying TileMatrixSet value QList< tileMatrixSetDef > tmsList = getTileMatrixSetList( project, tms_ref ); if ( tmsList.isEmpty() ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) ); } tileMatrixSetDef tms = tmsList[0]; if ( tms.ref != tms_ref ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) ); } //defining TileMatrix idx int tm_idx = params.tileMatrixAsInt(); //read TileMatrix if ( tm_idx < 0 || tms.tileMatrixList.count() < tm_idx ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is unknown" ) ); } tileMatrixDef tm = tms.tileMatrixList.at( tm_idx ); //defining TileRow int tr = params.tileRowAsInt(); //read TileRow if ( tr < 0 || tm.row <= tr ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileRow is unknown" ) ); } //defining TileCol int tc = params.tileColAsInt(); //read TileCol if ( tc < 0 || tm.col <= tc ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileCol is unknown" ) ); } double res = tm.resolution; double minx = tm.left + tc * ( tileSize * res ); double miny = tm.top - ( tr + 1 ) * ( tileSize * res ); double maxx = tm.left + ( tc + 1 ) * ( tileSize * res ); double maxy = tm.top - tr * ( tileSize * res ); QString bbox; if ( tms.hasAxisInverted ) { bbox = qgsDoubleToString( miny, 6 ) + ',' + qgsDoubleToString( minx, 6 ) + ',' + qgsDoubleToString( maxy, 6 ) + ',' + qgsDoubleToString( maxx, 6 ); } else { bbox = qgsDoubleToString( minx, 6 ) + ',' + qgsDoubleToString( miny, 6 ) + ',' + qgsDoubleToString( maxx, 6 ) + ',' + qgsDoubleToString( maxy, 6 ); } QUrlQuery query; if ( !params.value( QStringLiteral( "MAP" ) ).isEmpty() ) { query.addQueryItem( QgsServerParameter::name( QgsServerParameter::MAP ), params.value( QStringLiteral( "MAP" ) ) ); } query.addQueryItem( QgsServerParameter::name( QgsServerParameter::SERVICE ), QStringLiteral( "WMS" ) ); query.addQueryItem( QgsServerParameter::name( QgsServerParameter::VERSION_SERVICE ), QStringLiteral( "1.3.0" ) ); query.addQueryItem( QgsServerParameter::name( QgsServerParameter::REQUEST ), request ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::LAYERS ), layer ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::STYLES ), QString() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::CRS ), tms.ref ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::BBOX ), bbox ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::WIDTH ), QStringLiteral( "256" ) ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::HEIGHT ), QStringLiteral( "256" ) ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::FORMAT ), format ); if ( params.format() == QgsWmtsParameters::Format::PNG ) { query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::TRANSPARENT ), QStringLiteral( "true" ) ); } query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::DPI ), QStringLiteral( "96" ) ); return query; }
QList< layerDef > getWmtsLayerList( QgsServerInterface *serverIface, const QgsProject *project ) { QList< layerDef > wmtsLayers; #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsAccessControl *accessControl = serverIface->accessControls(); #else ( void )serverIface; #endif // WMTS Project configuration bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) ); // Root Layer name QString rootLayerName = QgsServerProjectUtils::wmsRootName( *project ); if ( rootLayerName.isEmpty() && !project->title().isEmpty() ) { rootLayerName = project->title(); } if ( wmtsProject && !rootLayerName.isEmpty() ) { layerDef pLayer; pLayer.id = rootLayerName; if ( !project->title().isEmpty() ) { pLayer.title = project->title(); pLayer.abstract = project->title(); } //transform the project native CRS into WGS84 QgsRectangle projRect = QgsServerProjectUtils::wmsExtent( *project ); QgsCoordinateReferenceSystem projCrs = project->crs(); QgsCoordinateTransform exGeoTransform( projCrs, wgs84, project ); try { pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( projRect ); } catch ( const QgsCsException & ) { pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 ); } // Formats bool wmtsPngProject = project->readBoolEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Project" ) ); if ( wmtsPngProject ) pLayer.formats << QStringLiteral( "image/png" ); bool wmtsJpegProject = project->readBoolEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Project" ) ); if ( wmtsJpegProject ) pLayer.formats << QStringLiteral( "image/jpeg" ); // Project is not queryable in WMS //pLayer.queryable = ( nonIdentifiableLayers.count() != project->count() ); pLayer.queryable = false; wmtsLayers.append( pLayer ); } QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) ); if ( !wmtsGroupNameList.isEmpty() ) { QgsLayerTreeGroup *treeRoot = project->layerTreeRoot(); QStringList wmtsPngGroupNameList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Group" ) ); QStringList wmtsJpegGroupNameList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Group" ) ); for ( const QString &gName : wmtsGroupNameList ) { QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName ); if ( !treeGroup ) { continue; } layerDef pLayer; pLayer.id = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString(); if ( pLayer.id.isEmpty() ) pLayer.id = gName; pLayer.title = treeGroup->customProperty( QStringLiteral( "wmsTitle" ) ).toString(); if ( pLayer.title.isEmpty() ) pLayer.title = gName; pLayer.abstract = treeGroup->customProperty( QStringLiteral( "wmsAbstract" ) ).toString(); QgsRectangle wgs84BoundingRect; bool queryable = false; double maxScale = 0.0; double minScale = 0.0; for ( QgsLayerTreeLayer *layer : treeGroup->findLayers() ) { QgsMapLayer *l = layer->layer(); if ( !l ) { continue; } //transform the layer native CRS into WGS84 QgsCoordinateReferenceSystem layerCrs = l->crs(); QgsCoordinateTransform exGeoTransform( layerCrs, wgs84, project ); try { wgs84BoundingRect.combineExtentWith( exGeoTransform.transformBoundingBox( l->extent() ) ); } catch ( const QgsCsException & ) { wgs84BoundingRect.combineExtentWith( QgsRectangle( -180, -90, 180, 90 ) ); } if ( !queryable && l->flags().testFlag( QgsMapLayer::Identifiable ) ) { queryable = true; } if ( l->hasScaleBasedVisibility() ) { double lMaxScale = l->maximumScale(); if ( lMaxScale > 0.0 && lMaxScale > maxScale ) { maxScale = lMaxScale; } double lMinScale = l->minimumScale(); if ( lMinScale > 0.0 && ( minScale == 0.0 || lMinScale < minScale ) ) { minScale = lMinScale; } } } pLayer.wgs84BoundingRect = wgs84BoundingRect; pLayer.queryable = queryable; pLayer.maxScale = maxScale; pLayer.minScale = minScale; // Formats if ( wmtsPngGroupNameList.contains( gName ) ) pLayer.formats << QStringLiteral( "image/png" ); if ( wmtsJpegGroupNameList.contains( gName ) ) pLayer.formats << QStringLiteral( "image/jpeg" ); wmtsLayers.append( pLayer ); } } QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) ); QStringList wmtsPngLayerIdList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Layer" ) ); QStringList wmtsJpegLayerIdList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Layer" ) ); for ( const QString &lId : wmtsLayerIdList ) { QgsMapLayer *l = project->mapLayer( lId ); if ( !l ) { continue; } #ifdef HAVE_SERVER_PYTHON_PLUGINS if ( !accessControl->layerReadPermission( l ) ) { continue; } #endif layerDef pLayer; pLayer.id = l->name(); if ( !l->shortName().isEmpty() ) pLayer.id = l->shortName(); pLayer.id = pLayer.id.replace( ' ', '_' ); pLayer.title = l->title(); pLayer.abstract = l->abstract(); //transform the layer native CRS into WGS84 QgsCoordinateReferenceSystem layerCrs = l->crs(); QgsCoordinateTransform exGeoTransform( layerCrs, wgs84, project ); try { pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( l->extent() ); } catch ( const QgsCsException & ) { pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 ); } // Formats if ( wmtsPngLayerIdList.contains( lId ) ) pLayer.formats << QStringLiteral( "image/png" ); if ( wmtsJpegLayerIdList.contains( lId ) ) pLayer.formats << QStringLiteral( "image/jpeg" ); pLayer.queryable = ( l->flags().testFlag( QgsMapLayer::Identifiable ) ); if ( l->hasScaleBasedVisibility() ) { pLayer.maxScale = l->maximumScale(); pLayer.minScale = l->minimumScale(); } else { pLayer.maxScale = 0.0; pLayer.minScale = 0.0; } wmtsLayers.append( pLayer ); } return wmtsLayers; }
// 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; }