void writeGetTile( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response ) { Q_UNUSED( version ); const QgsWmtsParameters params( QUrlQuery( request.url() ) ); // WMS query QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetMap" ), params, project, serverIface ); // Get cached image QgsAccessControl *accessControl = serverIface->accessControls(); QgsServerCacheManager *cacheManager = serverIface->cacheManager(); if ( cacheManager ) { QgsWmtsParameters::Format f = params.format(); QString contentType; QString saveFormat; std::unique_ptr<QImage> image; if ( f == QgsWmtsParameters::Format::JPG ) { contentType = QStringLiteral( "image/jpeg" ); saveFormat = QStringLiteral( "JPEG" ); image = qgis::make_unique<QImage>( 256, 256, QImage::Format_RGB32 ); } else { contentType = QStringLiteral( "image/png" ); saveFormat = QStringLiteral( "PNG" ); image = qgis::make_unique<QImage>( 256, 256, QImage::Format_ARGB32_Premultiplied ); } QByteArray content = cacheManager->getCachedImage( project, request, accessControl ); if ( !content.isEmpty() && image->loadFromData( content ) ) { response.setHeader( QStringLiteral( "Content-Type" ), contentType ); image->save( response.io(), qPrintable( saveFormat ) ); return; } } QgsServerParameters wmsParams( query ); QgsServerRequest wmsRequest( "?" + query.query( QUrl::FullyDecoded ) ); QgsService *service = serverIface->serviceRegistry()->getService( wmsParams.service(), wmsParams.version() ); service->executeRequest( wmsRequest, response, project ); if ( cacheManager ) { QByteArray content = response.data(); if ( !content.isEmpty() ) cacheManager->setCachedImage( &content, project, request, accessControl ); } }
void executeRequest( const QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project ) override { Q_UNUSED( project ); const QgsWmtsParameters params( QUrlQuery( request.url() ) ); // Set the default version QString versionString = params.version(); if ( versionString.isEmpty() ) { versionString = version(); // defined in qgswfsutils.h } // Get the request QString req = params.value( QgsServerParameter::name( QgsServerParameter::REQUEST ) ); if ( req.isEmpty() ) { throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), QStringLiteral( "Please check the value of the REQUEST parameter" ), 501 ); } if ( QSTR_COMPARE( req, "GetCapabilities" ) ) { writeGetCapabilities( mServerIface, project, versionString, request, response ); } else if ( QSTR_COMPARE( req, "GetTile" ) ) { writeGetTile( mServerIface, project, versionString, request, response ); } else if ( QSTR_COMPARE( req, "GetFeatureInfo" ) ) { writeGetFeatureInfo( mServerIface, project, versionString, request, response ); } else { // Operation not supported throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), QStringLiteral( "Request %1 is not supported" ).arg( req ), 501 ); } }
void writeGetFeatureInfo( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response ) { Q_UNUSED( version ); const QgsWmtsParameters params( QUrlQuery( request.url() ) ); // WMS query QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetFeatureInfo" ), params, project, serverIface ); // GetFeatureInfo query items query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::QUERY_LAYERS ), params.layer() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::I ), params.i() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::J ), params.j() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::INFO_FORMAT ), params.infoFormatAsString() ); QgsServerParameters wmsParams( query ); QgsServerRequest wmsRequest( "?" + query.query( QUrl::FullyDecoded ) ); QgsService *service = serverIface->serviceRegistry()->getService( wmsParams.service(), wmsParams.version() ); service->executeRequest( wmsRequest, response, project ); }
QString serviceUrl( const QgsServerRequest &request, const QgsProject *project ) { QString href; if ( project ) { href = QgsServerProjectUtils::wmtsServiceUrl( *project ); } // Build default url if ( href.isEmpty() ) { QUrl url = request.originalUrl(); QgsWmtsParameters params; params.load( QUrlQuery( url ) ); params.remove( QgsServerParameter::REQUEST ); params.remove( QgsServerParameter::VERSION_SERVICE ); params.remove( QgsServerParameter::SERVICE ); url.setQuery( params.urlQuery() ); href = url.toString(); } return href; }
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; }