Skip to content

Commit dc7e8e4

Browse files
committed
[Server][Feature][needs-docs] Update WMTS service : use config
Reuse the project configuration in the Server WMTS Service.
1 parent 71c7ce1 commit dc7e8e4

File tree

2 files changed

+237
-74
lines changed

2 files changed

+237
-74
lines changed

src/server/services/wmts/qgswmtsgetcapabilities.cpp

+224-74
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include "qgsexception.h"
2323
#include "qgsmapserviceexception.h"
2424
#include "qgscoordinatereferencesystem.h"
25+
#include "qgslayertree.h"
26+
#include "qgslayertreemodel.h"
27+
#include "qgslayertreemodellegendnode.h"
2528

2629
#include <QStringList>
2730

@@ -320,95 +323,243 @@ namespace QgsWmts
320323
QList< tileMatrixSet > tmsList = getTileMatrixSetList( project );
321324
if ( !tmsList.isEmpty() )
322325
{
323-
QDomElement layerParentElem = doc.createElement( QStringLiteral( "Layer" ) );
326+
QList< layerDef > wmtsLayers;
327+
QgsCoordinateReferenceSystem wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
328+
QList<tileMatrixSet>::iterator tmsIt = tmsList.begin();
324329

325-
// Root Layer name
326-
QString rootLayerName = QgsServerProjectUtils::wmsRootName( *project );
327-
if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
328-
{
329-
rootLayerName = project->title();
330-
}
330+
// WMTS Project configuration
331+
bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) );
331332

332-
if ( !rootLayerName.isEmpty() )
333+
if ( wmtsProject )
333334
{
334-
QDomElement layerParentNameElem = doc.createElement( QStringLiteral( "ows:Identifier" ) );
335-
QDomText layerParentNameText = doc.createTextNode( rootLayerName );
336-
layerParentNameElem.appendChild( layerParentNameText );
337-
layerParentElem.appendChild( layerParentNameElem );
338-
}
335+
layerDef pLayer;
339336

340-
if ( !project->title().isEmpty() )
341-
{
342-
// Root Layer title
343-
QDomElement layerParentTitleElem = doc.createElement( QStringLiteral( "ows:Title" ) );
344-
QDomText layerParentTitleText = doc.createTextNode( project->title() );
345-
layerParentTitleElem.appendChild( layerParentTitleText );
346-
layerParentElem.appendChild( layerParentTitleElem );
347-
348-
// Root Layer abstract
349-
QDomElement layerParentAbstElem = doc.createElement( QStringLiteral( "ows:Abstract" ) );
350-
QDomText layerParentAbstText = doc.createTextNode( project->title() );
351-
layerParentAbstElem.appendChild( layerParentAbstText );
352-
layerParentElem.appendChild( layerParentAbstElem );
337+
// Root Layer name
338+
QString rootLayerName = QgsServerProjectUtils::wmsRootName( *project );
339+
if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
340+
{
341+
rootLayerName = project->title();
342+
}
343+
pLayer.id = rootLayerName;
344+
345+
if ( !project->title().isEmpty() )
346+
{
347+
pLayer.title = project->title();
348+
pLayer.abstract = project->title();
349+
}
350+
351+
//transform the project native CRS into WGS84
352+
QgsRectangle projRect = QgsServerProjectUtils::wmsExtent( *project );
353+
QgsCoordinateReferenceSystem projCrs = project->crs();
354+
Q_NOWARN_DEPRECATED_PUSH
355+
QgsCoordinateTransform exGeoTransform( projCrs, wgs84 );
356+
Q_NOWARN_DEPRECATED_POP
357+
try
358+
{
359+
pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( projRect );
360+
}
361+
catch ( const QgsCsException & )
362+
{
363+
pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 );
364+
}
365+
366+
// Formats
367+
bool wmtsPngProject = project->readBoolEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Project" ) );
368+
if ( wmtsPngProject )
369+
pLayer.formats << QStringLiteral( "image/png" );
370+
bool wmtsJpegProject = project->readBoolEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Project" ) );
371+
if ( wmtsJpegProject )
372+
pLayer.formats << QStringLiteral( "image/jpeg" );
373+
374+
wmtsLayers.append( pLayer );
353375
}
354376

355-
//transform the project native CRS into WGS84
356-
QgsRectangle wgs84BoundingRect;
357-
QgsRectangle projRect = QgsServerProjectUtils::wmsExtent( *project );
358-
QgsCoordinateReferenceSystem projCrs = project->crs();
359-
QgsCoordinateReferenceSystem wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
360-
Q_NOWARN_DEPRECATED_PUSH
361-
QgsCoordinateTransform exGeoTransform( projCrs, wgs84 );
362-
Q_NOWARN_DEPRECATED_POP
363-
try
377+
QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) );
378+
if ( !wmtsGroupNameList.isEmpty() )
364379
{
365-
wgs84BoundingRect = exGeoTransform.transformBoundingBox( projRect );
380+
QgsLayerTreeGroup *treeRoot = project->layerTreeRoot();
381+
382+
QStringList wmtsPngGroupNameList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Group" ) );
383+
QStringList wmtsJpegGroupNameList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Group" ) );
384+
385+
Q_FOREACH ( QString gName, wmtsGroupNameList )
386+
{
387+
QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName );
388+
if ( !treeGroup )
389+
{
390+
continue;
391+
}
392+
393+
layerDef pLayer;
394+
pLayer.id = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
395+
if ( pLayer.id.isEmpty() )
396+
pLayer.id = gName;
397+
398+
pLayer.title = treeGroup->customProperty( QStringLiteral( "wmsTitle" ) ).toString();
399+
if ( pLayer.title.isEmpty() )
400+
pLayer.title = gName;
401+
402+
pLayer.abstract = treeGroup->customProperty( QStringLiteral( "wmsAbstract" ) ).toString();
403+
404+
for ( QgsLayerTreeLayer *layer : treeGroup->findLayers() )
405+
{
406+
QgsMapLayer *l = layer->layer();
407+
//transform the layer native CRS into WGS84
408+
QgsRectangle wgs84BoundingRect;
409+
QgsCoordinateReferenceSystem layerCrs = l->crs();
410+
Q_NOWARN_DEPRECATED_PUSH
411+
QgsCoordinateTransform exGeoTransform( layerCrs, wgs84 );
412+
Q_NOWARN_DEPRECATED_POP
413+
try
414+
{
415+
wgs84BoundingRect.combineExtentWith( exGeoTransform.transformBoundingBox( l->extent() ) );
416+
}
417+
catch ( const QgsCsException & )
418+
{
419+
wgs84BoundingRect.combineExtentWith( QgsRectangle( -180, -90, 180, 90 ) );
420+
}
421+
}
422+
423+
// Formats
424+
if ( wmtsPngGroupNameList.contains( gName ) )
425+
pLayer.formats << QStringLiteral( "image/png" );
426+
if ( wmtsJpegGroupNameList.contains( gName ) )
427+
pLayer.formats << QStringLiteral( "image/jpeg" );
428+
429+
wmtsLayers.append( pLayer );
430+
}
366431
}
367-
catch ( const QgsCsException & )
432+
433+
QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) );
434+
QStringList wmtsPngLayerIdList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Layer" ) );
435+
QStringList wmtsJpegLayerIdList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Layer" ) );
436+
437+
Q_FOREACH ( QString lId, wmtsLayerIdList )
368438
{
369-
wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 );
439+
QgsMapLayer *l = project->mapLayer( lId );
440+
if ( !l )
441+
{
442+
continue;
443+
}
444+
#ifdef HAVE_SERVER_PYTHON_PLUGINS
445+
if ( !accessControl->layerReadPermission( l ) )
446+
{
447+
continue;
448+
}
449+
#endif
450+
451+
layerDef pLayer;
452+
pLayer.id = l->name();
453+
if ( !l->shortName().isEmpty() )
454+
pLayer.id = l->shortName();
455+
pLayer.id = pLayer.id.replace( ' ', '_' );
456+
457+
pLayer.title = l->title();
458+
pLayer.abstract = l->abstract();
459+
460+
//transform the layer native CRS into WGS84
461+
QgsCoordinateReferenceSystem layerCrs = l->crs();
462+
Q_NOWARN_DEPRECATED_PUSH
463+
QgsCoordinateTransform exGeoTransform( layerCrs, wgs84 );
464+
Q_NOWARN_DEPRECATED_POP
465+
try
466+
{
467+
pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( l->extent() );
468+
}
469+
catch ( const QgsCsException & )
470+
{
471+
pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 );
472+
}
473+
474+
// Formats
475+
if ( wmtsPngLayerIdList.contains( lId ) )
476+
pLayer.formats << QStringLiteral( "image/png" );
477+
if ( wmtsJpegLayerIdList.contains( lId ) )
478+
pLayer.formats << QStringLiteral( "image/jpeg" );
479+
480+
wmtsLayers.append( pLayer );
370481
}
371-
QDomElement wgs84BBoxElement = doc.createElement( QStringLiteral( "ows:WGS84BoundingBox" ) );
372-
QDomElement wgs84LowerCornerElement = doc.createElement( QStringLiteral( "LowerCorner" ) );
373-
QDomText wgs84LowerCornerText = doc.createTextNode( qgsDoubleToString( wgs84BoundingRect.xMinimum(), 6 ) + ' ' + qgsDoubleToString( wgs84BoundingRect.yMinimum(), 6 ) );
374-
wgs84LowerCornerElement.appendChild( wgs84LowerCornerText );
375-
wgs84BBoxElement.appendChild( wgs84LowerCornerElement );
376-
QDomElement wgs84UpperCornerElement = doc.createElement( QStringLiteral( "UpperCorner" ) );
377-
QDomText wgs84UpperCornerText = doc.createTextNode( qgsDoubleToString( wgs84BoundingRect.xMaximum(), 6 ) + ' ' + qgsDoubleToString( wgs84BoundingRect.yMaximum(), 6 ) );
378-
wgs84UpperCornerElement.appendChild( wgs84UpperCornerText );
379-
wgs84BBoxElement.appendChild( wgs84UpperCornerElement );
380-
layerParentElem.appendChild( wgs84BBoxElement );
381-
382-
// Root Layer Style
383-
QDomElement layerParentStyleElem = doc.createElement( QStringLiteral( "Style" ) );
384-
layerParentStyleElem.setAttribute( QStringLiteral( "isDefault" ), QStringLiteral( "true" ) );
385-
QDomElement layerParentStyleIdElem = doc.createElement( QStringLiteral( "ows:Identifier" ) );
386-
QDomText layerParentStyleIdText = doc.createTextNode( QStringLiteral( "default" ) );
387-
layerParentStyleIdElem.appendChild( layerParentStyleIdText );
388-
layerParentStyleElem.appendChild( layerParentStyleIdElem );
389-
QDomElement layerParentStyleTitleElem = doc.createElement( QStringLiteral( "ows:Title" ) );
390-
QDomText layerParentStyleTitleText = doc.createTextNode( QStringLiteral( "default" ) );
391-
layerParentStyleTitleElem.appendChild( layerParentStyleTitleText );
392-
layerParentStyleElem.appendChild( layerParentStyleTitleElem );
393-
layerParentElem.appendChild( layerParentStyleElem );
394482

395-
QList<tileMatrixSet>::iterator tmsIt = tmsList.begin();
396-
for ( ; tmsIt != tmsList.end(); ++tmsIt )
483+
Q_FOREACH ( layerDef wmtsLayer, wmtsLayers )
397484
{
398-
tileMatrixSet &tms = *tmsIt;
485+
if ( wmtsLayer.id.isEmpty() )
486+
continue;
399487

400-
//wmts:TileMatrixSetLink
401-
QDomElement tmslElement = doc.createElement( QStringLiteral( "TileMatrixSetLink" )/*wmts:TileMatrixSetLink*/ );
488+
QDomElement layerElem = doc.createElement( QStringLiteral( "Layer" ) );
402489

403-
QDomElement identifierElem = doc.createElement( QStringLiteral( "TileMatrixSet" ) );
404-
QDomText identifierText = doc.createTextNode( tms.ref );
405-
identifierElem.appendChild( identifierText );
406-
tmslElement.appendChild( identifierElem );
490+
QDomElement layerIdElem = doc.createElement( QStringLiteral( "ows:Identifier" ) );
491+
QDomText layerIdText = doc.createTextNode( wmtsLayer.id );
492+
layerIdElem.appendChild( layerIdText );
493+
layerElem.appendChild( layerIdElem );
407494

408-
layerParentElem.appendChild( tmslElement );
409-
}
495+
if ( !wmtsLayer.title.isEmpty() )
496+
{
497+
// Layer title
498+
QDomElement layerTitleElem = doc.createElement( QStringLiteral( "ows:Title" ) );
499+
QDomText layerTitleText = doc.createTextNode( wmtsLayer.title );
500+
layerTitleElem.appendChild( layerTitleText );
501+
layerElem.appendChild( layerTitleElem );
502+
}
410503

411-
contentsElement.appendChild( layerParentElem );
504+
if ( !wmtsLayer.abstract.isEmpty() )
505+
{
506+
// Layer abstract
507+
QDomElement layerAbstElem = doc.createElement( QStringLiteral( "ows:Abstract" ) );
508+
QDomText layerAbstText = doc.createTextNode( project->title() );
509+
layerAbstElem.appendChild( layerAbstText );
510+
layerElem.appendChild( layerAbstElem );
511+
}
512+
513+
QDomElement wgs84BBoxElement = doc.createElement( QStringLiteral( "ows:WGS84BoundingBox" ) );
514+
QDomElement wgs84LowerCornerElement = doc.createElement( QStringLiteral( "LowerCorner" ) );
515+
QDomText wgs84LowerCornerText = doc.createTextNode( qgsDoubleToString( wmtsLayer.wgs84BoundingRect.xMinimum(), 6 ) + ' ' + qgsDoubleToString( wmtsLayer.wgs84BoundingRect.yMinimum(), 6 ) );
516+
wgs84LowerCornerElement.appendChild( wgs84LowerCornerText );
517+
wgs84BBoxElement.appendChild( wgs84LowerCornerElement );
518+
QDomElement wgs84UpperCornerElement = doc.createElement( QStringLiteral( "UpperCorner" ) );
519+
QDomText wgs84UpperCornerText = doc.createTextNode( qgsDoubleToString( wmtsLayer.wgs84BoundingRect.xMaximum(), 6 ) + ' ' + qgsDoubleToString( wmtsLayer.wgs84BoundingRect.yMaximum(), 6 ) );
520+
wgs84UpperCornerElement.appendChild( wgs84UpperCornerText );
521+
wgs84BBoxElement.appendChild( wgs84UpperCornerElement );
522+
layerElem.appendChild( wgs84BBoxElement );
523+
524+
// Layer Style
525+
QDomElement layerStyleElem = doc.createElement( QStringLiteral( "Style" ) );
526+
layerStyleElem.setAttribute( QStringLiteral( "isDefault" ), QStringLiteral( "true" ) );
527+
QDomElement layerStyleIdElem = doc.createElement( QStringLiteral( "ows:Identifier" ) );
528+
QDomText layerStyleIdText = doc.createTextNode( QStringLiteral( "default" ) );
529+
layerStyleIdElem.appendChild( layerStyleIdText );
530+
layerStyleElem.appendChild( layerStyleIdElem );
531+
QDomElement layerStyleTitleElem = doc.createElement( QStringLiteral( "ows:Title" ) );
532+
QDomText layerStyleTitleText = doc.createTextNode( QStringLiteral( "default" ) );
533+
layerStyleTitleElem.appendChild( layerStyleTitleText );
534+
layerStyleElem.appendChild( layerStyleTitleElem );
535+
layerElem.appendChild( layerStyleElem );
536+
537+
Q_FOREACH ( QString format, wmtsLayer.formats )
538+
{
539+
QDomElement layerFormatElem = doc.createElement( QStringLiteral( "Format" ) );
540+
QDomText layerFormatText = doc.createTextNode( format );
541+
layerFormatElem.appendChild( layerFormatText );
542+
layerElem.appendChild( layerFormatElem );
543+
}
544+
545+
tmsIt = tmsList.begin();
546+
for ( ; tmsIt != tmsList.end(); ++tmsIt )
547+
{
548+
tileMatrixSet &tms = *tmsIt;
549+
550+
//wmts:TileMatrixSetLink
551+
QDomElement tmslElement = doc.createElement( QStringLiteral( "TileMatrixSetLink" )/*wmts:TileMatrixSetLink*/ );
552+
553+
QDomElement identifierElem = doc.createElement( QStringLiteral( "TileMatrixSet" ) );
554+
QDomText identifierText = doc.createTextNode( tms.ref );
555+
identifierElem.appendChild( identifierText );
556+
tmslElement.appendChild( identifierElem );
557+
558+
layerElem.appendChild( tmslElement );
559+
}
560+
561+
contentsElement.appendChild( layerElem );
562+
}
412563

413564
tmsIt = tmsList.begin();
414565
for ( ; tmsIt != tmsList.end(); ++tmsIt )
@@ -480,7 +631,6 @@ namespace QgsWmts
480631
}
481632
}
482633

483-
484634
//End
485635
return contentsElement;
486636
}

src/server/services/wmts/qgswmtsutils.h

+13
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ namespace QgsWmts
7070
QList< tileMatrix > tileMatrixList;
7171
};
7272

73+
struct layerDef
74+
{
75+
QString id;
76+
77+
QString title;
78+
79+
QString abstract;
80+
81+
QgsRectangle wgs84BoundingRect;
82+
83+
QStringList formats;
84+
};
85+
7386
/**
7487
* Returns the highest version supported by this implementation
7588
*/

0 commit comments

Comments
 (0)