Skip to content

Commit 408484d

Browse files
committedAug 21, 2018
[Server][Feature][needs-docs] Add QgsWmtsParameters to WMTS service
1 parent 6895926 commit 408484d

10 files changed

+652
-132
lines changed
 

‎src/server/services/wmts/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ SET (wmts_SRCS
88
qgswmtsgetcapabilities.cpp
99
qgswmtsgettile.cpp
1010
qgswmtsgetfeatureinfo.cpp
11+
qgswmtsparameters.cpp
12+
)
13+
14+
SET (wmts_MOC_HDRS
15+
qgswmtsparameters.h
1116
)
1217

1318
########################################################
1419
# Build
1520

16-
ADD_LIBRARY (wmts MODULE ${wmts_SRCS})
21+
QT5_WRAP_CPP(wmts_MOC_SRCS ${wmts_MOC_HDRS})
22+
23+
ADD_LIBRARY (wmts MODULE ${wmts_SRCS} ${wmts_MOC_SRCS} ${wmts_MOC_HDRS})
1724

1825

1926
INCLUDE_DIRECTORIES(SYSTEM

‎src/server/services/wmts/qgswmts.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ namespace QgsWmts
5858
{
5959
Q_UNUSED( project );
6060

61-
QgsServerRequest::Parameters params = request.parameters();
62-
QString versionString = params.value( QStringLiteral( "VERSION" ) );
61+
const QgsWmtsParameters params( QUrlQuery( request.url() ) );
6362

6463
// Set the default version
64+
QString versionString = params.version();
6565
if ( versionString.isEmpty() )
6666
{
67-
versionString = version();
67+
versionString = version(); // defined in qgswfsutils.h
6868
}
6969

7070
// Get the request

‎src/server/services/wmts/qgswmtsgetcapabilities.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,12 @@ namespace QgsWmts
320320
*/
321321
QDomElement contentsElement = doc.createElement( QStringLiteral( "Contents" )/*wmts:Contents*/ );
322322

323-
QList< tileMatrixSet > tmsList = getTileMatrixSetList( project );
323+
QList< tileMatrixSetDef > tmsList = getTileMatrixSetList( project );
324324
if ( !tmsList.isEmpty() )
325325
{
326326
QList< layerDef > wmtsLayers;
327327
QgsCoordinateReferenceSystem wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
328-
QList<tileMatrixSet>::iterator tmsIt = tmsList.begin();
328+
QList<tileMatrixSetDef>::iterator tmsIt = tmsList.begin();
329329

330330
QStringList nonIdentifiableLayers = project->nonIdentifiableLayers();
331331

@@ -547,7 +547,7 @@ namespace QgsWmts
547547
tmsIt = tmsList.begin();
548548
for ( ; tmsIt != tmsList.end(); ++tmsIt )
549549
{
550-
tileMatrixSet &tms = *tmsIt;
550+
tileMatrixSetDef &tms = *tmsIt;
551551
if ( tms.ref == QLatin1String( "EPSG:4326" ) )
552552
continue;
553553

@@ -609,7 +609,7 @@ namespace QgsWmts
609609
tmsIt = tmsList.begin();
610610
for ( ; tmsIt != tmsList.end(); ++tmsIt )
611611
{
612-
tileMatrixSet &tms = *tmsIt;
612+
tileMatrixSetDef &tms = *tmsIt;
613613
if ( tms.ref != QLatin1String( "EPSG:4326" ) )
614614
{
615615
QgsRectangle rect;
@@ -636,10 +636,10 @@ namespace QgsWmts
636636
//wmts:TileMatrixSetLimits
637637
QDomElement tmsLimitsElement = doc.createElement( QStringLiteral( "TileMatrixSetLimits" )/*wmts:TileMatrixSetLimits*/ );
638638
int tmIdx = 0;
639-
QList<tileMatrix>::iterator tmIt = tms.tileMatrixList.begin();
639+
QList<tileMatrixDef>::iterator tmIt = tms.tileMatrixList.begin();
640640
for ( ; tmIt != tms.tileMatrixList.end(); ++tmIt )
641641
{
642-
tileMatrix &tm = *tmIt;
642+
tileMatrixDef &tm = *tmIt;
643643

644644
QDomElement tmLimitsElement = doc.createElement( QStringLiteral( "TileMatrixLimits" )/*wmts:TileMatrixLimits*/ );
645645

@@ -683,7 +683,7 @@ namespace QgsWmts
683683
tmsIt = tmsList.begin();
684684
for ( ; tmsIt != tmsList.end(); ++tmsIt )
685685
{
686-
tileMatrixSet &tms = *tmsIt;
686+
tileMatrixSetDef &tms = *tmsIt;
687687

688688
//wmts:TileMatrixSet
689689
QDomElement tmsElement = doc.createElement( QStringLiteral( "TileMatrixSet" )/*wmts:TileMatrixSet*/ );
@@ -700,10 +700,10 @@ namespace QgsWmts
700700

701701
//wmts:TileMatrix
702702
int tmIdx = 0;
703-
QList<tileMatrix>::iterator tmIt = tms.tileMatrixList.begin();
703+
QList<tileMatrixDef>::iterator tmIt = tms.tileMatrixList.begin();
704704
for ( ; tmIt != tms.tileMatrixList.end(); ++tmIt )
705705
{
706-
tileMatrix &tm = *tmIt;
706+
tileMatrixDef &tm = *tmIt;
707707

708708
QDomElement tmElement = doc.createElement( QStringLiteral( "TileMatrix" )/*wmts:TileMatrix*/ );
709709

‎src/server/services/wmts/qgswmtsgetfeatureinfo.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***************************************************************************
2-
qgswmsgetfeatureinfo.cpp
2+
qgswmtsgetfeatureinfo.cpp
33
-------------------------
44
begin : July 23 , 2017
55
copyright : (C) 2018 by René-Luc D'Hont
@@ -15,6 +15,7 @@
1515
* *
1616
***************************************************************************/
1717
#include "qgswmtsutils.h"
18+
#include "qgswmtsparameters.h"
1819
#include "qgswmtsgetfeatureinfo.h"
1920

2021
#include <QImage>
@@ -27,17 +28,16 @@ namespace QgsWmts
2728
QgsServerResponse &response )
2829
{
2930
Q_UNUSED( version );
30-
31-
QgsServerRequest::Parameters params = request.parameters();
31+
const QgsWmtsParameters params( QUrlQuery( request.url() ) );
3232

3333
// WMS query
3434
QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetFeatureInfo" ), params, project, serverIface );
3535

3636
// GetFeatureInfo query items
37-
query.addQueryItem( QStringLiteral( "query_layers" ), query.queryItemValue( QStringLiteral( "layers" ) ) );
38-
query.addQueryItem( QStringLiteral( "i" ), params.value( QStringLiteral( "I" ) ) );
39-
query.addQueryItem( QStringLiteral( "j" ), params.value( QStringLiteral( "J" ) ) );
40-
query.addQueryItem( QStringLiteral( "info_format" ), params.value( QStringLiteral( "INFOFORMAT" ) ) );
37+
query.addQueryItem( QStringLiteral( "query_layers" ), params.layer() );
38+
query.addQueryItem( QgsWmtsParameter::name( QgsWmtsParameter::I ), params.i() );
39+
query.addQueryItem( QgsWmtsParameter::name( QgsWmtsParameter::J ), params.j() );
40+
query.addQueryItem( QStringLiteral( "info_format" ), params.infoFormatAsString() );
4141

4242
QgsServerParameters wmsParams( query );
4343
QgsServerRequest wmsRequest( "?" + query.query( QUrl::FullyDecoded ) );

‎src/server/services/wmts/qgswmtsgetfeatureinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***************************************************************************
2-
qgswmsgetfeatureinfo.h
2+
qgswmtsgetfeatureinfo.h
33
-------------------------
44
begin : July 23 , 2017
55
copyright : (C) 2018 by René-Luc D'Hont

‎src/server/services/wmts/qgswmtsgettile.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* *
1616
***************************************************************************/
1717
#include "qgswmtsutils.h"
18+
#include "qgswmtsparameters.h"
1819
#include "qgswmtsgettile.h"
1920

2021
#include <QImage>
@@ -27,7 +28,8 @@ namespace QgsWmts
2728
QgsServerResponse &response )
2829
{
2930
Q_UNUSED( version );
30-
QgsServerRequest::Parameters params = request.parameters();
31+
//QgsServerRequest::Parameters params = request.parameters();
32+
const QgsWmtsParameters params( QUrlQuery( request.url() ) );
3133

3234
// WMS query
3335
QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetMap" ), params, project, serverIface );
@@ -44,16 +46,19 @@ namespace QgsWmts
4446
QgsServerCacheManager *cacheManager = serverIface->cacheManager();
4547
if ( cacheManager && cache )
4648
{
47-
QString contentType = params.value( QStringLiteral( "FORMAT" ) );
49+
QgsWmtsParameters::Format f = params.format();
50+
QString contentType;
4851
QString saveFormat;
4952
std::unique_ptr<QImage> image;
50-
if ( contentType == QLatin1String( "image/jpeg" ) )
53+
if ( f == QgsWmtsParameters::Format::JPG )
5154
{
55+
contentType = QStringLiteral( "image/jpeg" );
5256
saveFormat = QStringLiteral( "JPEG" );
5357
image = qgis::make_unique<QImage>( 256, 256, QImage::Format_RGB32 );
5458
}
5559
else
5660
{
61+
contentType = QStringLiteral( "image/png" );
5762
saveFormat = QStringLiteral( "PNG" );
5863
image = qgis::make_unique<QImage>( 256, 256, QImage::Format_ARGB32_Premultiplied );
5964
}
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/***************************************************************************
2+
qgswmtsparameters.cpp
3+
--------------------
4+
begin : Aug 10, 2018
5+
copyright : (C) 2018 by René-Luc Dhont
6+
email : rldhont at 3liz dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgswmtsparameters.h"
19+
#include "qgsmessagelog.h"
20+
#include <iostream>
21+
22+
namespace QgsWmts
23+
{
24+
//
25+
// QgsWmtsParameter
26+
//
27+
QgsWmtsParameter::QgsWmtsParameter( const QgsWmtsParameter::Name name,
28+
const QVariant::Type type,
29+
const QVariant defaultValue )
30+
: QgsServerParameterDefinition( type, defaultValue )
31+
, mName( name )
32+
{
33+
}
34+
35+
int QgsWmtsParameter::toInt() const
36+
{
37+
bool ok = false;
38+
const int val = QgsServerParameterDefinition::toInt( ok );
39+
40+
if ( !ok )
41+
{
42+
raiseError();
43+
}
44+
45+
return val;
46+
}
47+
48+
void QgsWmtsParameter::raiseError() const
49+
{
50+
const QString msg = QString( "%1 ('%2') cannot be converted into %3" ).arg( name( mName ), toString(), typeName() );
51+
QgsServerParameterDefinition::raiseError( msg );
52+
}
53+
54+
QString QgsWmtsParameter::name( const QgsWmtsParameter::Name name )
55+
{
56+
const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmtsParameter::Name>() );
57+
return metaEnum.valueToKey( name );
58+
}
59+
60+
QgsWmtsParameter::Name QgsWmtsParameter::name( const QString &name )
61+
{
62+
const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmtsParameter::Name>() );
63+
return ( QgsWmtsParameter::Name ) metaEnum.keyToValue( name.toUpper().toStdString().c_str() );
64+
}
65+
66+
//
67+
// QgsWmtsParameters
68+
//
69+
QgsWmtsParameters::QgsWmtsParameters()
70+
: QgsServerParameters()
71+
{
72+
// Available version number
73+
mVersions.append( QgsProjectVersion( 1, 0, 0 ) );
74+
75+
const QgsWmtsParameter pLayer = QgsWmtsParameter( QgsWmtsParameter::LAYER );
76+
save( pLayer );
77+
78+
const QgsWmtsParameter pFormat = QgsWmtsParameter( QgsWmtsParameter::FORMAT );
79+
save( pFormat );
80+
81+
const QgsWmtsParameter pTileMatrix = QgsWmtsParameter( QgsWmtsParameter::TILEMATRIX,
82+
QVariant::Int,
83+
QVariant( -1 ) );
84+
save( pTileMatrix );
85+
86+
const QgsWmtsParameter pTileRow = QgsWmtsParameter( QgsWmtsParameter::TILEROW,
87+
QVariant::Int,
88+
QVariant( -1 ) );
89+
save( pTileRow );
90+
91+
const QgsWmtsParameter pTileCol = QgsWmtsParameter( QgsWmtsParameter::TILECOL,
92+
QVariant::Int,
93+
QVariant( -1 ) );
94+
save( pTileCol );
95+
96+
const QgsWmtsParameter pInfoFormat( QgsWmtsParameter::INFOFORMAT );
97+
save( pInfoFormat );
98+
99+
const QgsWmtsParameter pI( QgsWmtsParameter::I,
100+
QVariant::Int,
101+
QVariant( -1 ) );
102+
save( pI );
103+
104+
const QgsWmtsParameter pJ( QgsWmtsParameter::J,
105+
QVariant::Int,
106+
QVariant( -1 ) );
107+
save( pJ );
108+
}
109+
110+
QgsWmtsParameters::QgsWmtsParameters( const QgsServerParameters &parameters )
111+
: QgsWmtsParameters()
112+
{
113+
load( parameters.urlQuery() );
114+
}
115+
116+
bool QgsWmtsParameters::loadParameter( const QString &key, const QString &value )
117+
{
118+
bool loaded = false;
119+
120+
const QgsWmtsParameter::Name name = QgsWmtsParameter::name( key );
121+
if ( name >= 0 )
122+
{
123+
mWmtsParameters[name].mValue = value;
124+
if ( ! mWmtsParameters[name].isValid() )
125+
{
126+
mWmtsParameters[name].raiseError();
127+
}
128+
129+
loaded = true;
130+
}
131+
132+
return loaded;
133+
}
134+
135+
void QgsWmtsParameters::save( const QgsWmtsParameter &parameter )
136+
{
137+
mWmtsParameters[ parameter.mName ] = parameter;
138+
}
139+
140+
void QgsWmtsParameters::dump() const
141+
{
142+
log( "WMTS Request parameters:" );
143+
for ( auto parameter : mWmtsParameters.toStdMap() )
144+
{
145+
const QString value = parameter.second.toString();
146+
147+
if ( ! value.isEmpty() )
148+
{
149+
const QString name = QgsWmtsParameter::name( parameter.first );
150+
log( QStringLiteral( " - %1 : %2" ).arg( name, value ) );
151+
}
152+
}
153+
154+
if ( !version().isEmpty() )
155+
log( QStringLiteral( " - VERSION : %1" ).arg( version() ) );
156+
}
157+
158+
QString QgsWmtsParameters::layer() const
159+
{
160+
return mWmtsParameters[ QgsWmtsParameter::LAYER ].toString();
161+
}
162+
163+
QString QgsWmtsParameters::formatAsString() const
164+
{
165+
return mWmtsParameters[ QgsWmtsParameter::FORMAT ].toString();
166+
}
167+
168+
QgsWmtsParameters::Format QgsWmtsParameters::format() const
169+
{
170+
QString fStr = formatAsString();
171+
172+
if ( fStr.isEmpty() )
173+
return Format::NONE;
174+
175+
Format f = Format::PNG;
176+
if ( fStr.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
177+
|| fStr.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
178+
|| fStr.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 )
179+
f = Format::JPG;
180+
181+
return f;
182+
}
183+
184+
QString QgsWmtsParameters::tileMatrixSet() const
185+
{
186+
return mWmtsParameters[ QgsWmtsParameter::TILEMATRIXSET ].toString();
187+
}
188+
189+
QString QgsWmtsParameters::tileMatrix() const
190+
{
191+
return mWmtsParameters[ QgsWmtsParameter::TILEMATRIX ].toString();
192+
}
193+
194+
int QgsWmtsParameters::tileMatrixAsInt() const
195+
{
196+
return mWmtsParameters[ QgsWmtsParameter::TILEMATRIX ].toInt();
197+
}
198+
199+
QString QgsWmtsParameters::tileRow() const
200+
{
201+
return mWmtsParameters[ QgsWmtsParameter::TILEROW ].toString();
202+
}
203+
204+
int QgsWmtsParameters::tileRowAsInt() const
205+
{
206+
return mWmtsParameters[ QgsWmtsParameter::TILEROW ].toInt();
207+
}
208+
209+
QString QgsWmtsParameters::tileCol() const
210+
{
211+
return mWmtsParameters[ QgsWmtsParameter::TILECOL ].toString();
212+
}
213+
214+
int QgsWmtsParameters::tileColAsInt() const
215+
{
216+
return mWmtsParameters[ QgsWmtsParameter::TILECOL ].toInt();
217+
}
218+
219+
QString QgsWmtsParameters::infoFormatAsString() const
220+
{
221+
return mWmtsParameters[ QgsWmtsParameter::INFOFORMAT ].toString();
222+
}
223+
224+
QgsWmtsParameters::Format QgsWmtsParameters::infoFormat() const
225+
{
226+
QString fStr = infoFormatAsString();
227+
228+
Format f = Format::TEXT;
229+
if ( fStr.isEmpty() )
230+
return f;
231+
232+
if ( fStr.startsWith( QLatin1String( "text/xml" ), Qt::CaseInsensitive ) )
233+
f = Format::XML;
234+
else if ( fStr.startsWith( QLatin1String( "text/html" ), Qt::CaseInsensitive ) )
235+
f = Format::HTML;
236+
else if ( fStr.startsWith( QLatin1String( "text/plain" ), Qt::CaseInsensitive ) )
237+
f = Format::TEXT;
238+
else if ( fStr.startsWith( QLatin1String( "application/vnd.ogc.gml" ), Qt::CaseInsensitive ) )
239+
f = Format::GML;
240+
else
241+
f = Format::NONE;
242+
243+
return f;
244+
}
245+
246+
int QgsWmtsParameters::infoFormatVersion() const
247+
{
248+
if ( infoFormat() != Format::GML )
249+
return -1;
250+
251+
QString fStr = infoFormatAsString();
252+
if ( fStr.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ), Qt::CaseInsensitive ) )
253+
return 3;
254+
else
255+
return 2;
256+
}
257+
258+
QString QgsWmtsParameters::i() const
259+
{
260+
return mWmtsParameters[ QgsWmtsParameter::I ].toString();
261+
}
262+
263+
QString QgsWmtsParameters::j() const
264+
{
265+
return mWmtsParameters[ QgsWmtsParameter::J ].toString();
266+
}
267+
268+
int QgsWmtsParameters::iAsInt() const
269+
{
270+
return mWmtsParameters[ QgsWmtsParameter::I ].toInt();
271+
}
272+
273+
int QgsWmtsParameters::jAsInt() const
274+
{
275+
return mWmtsParameters[ QgsWmtsParameter::J ].toInt();
276+
}
277+
278+
QgsProjectVersion QgsWmtsParameters::versionAsNumber() const
279+
{
280+
QString vStr = version();
281+
QgsProjectVersion version;
282+
283+
if ( vStr.isEmpty() )
284+
version = QgsProjectVersion( 1, 0, 0 ); // default value
285+
else if ( mVersions.contains( QgsProjectVersion( vStr ) ) )
286+
version = QgsProjectVersion( vStr );
287+
288+
return version;
289+
}
290+
291+
void QgsWmtsParameters::log( const QString &msg ) const
292+
{
293+
QgsMessageLog::logMessage( msg, "Server", Qgis::Info );
294+
}
295+
}
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/***************************************************************************
2+
qgswmtsparameters.h
3+
-------------------
4+
begin : Aug 10, 2018
5+
copyright : (C) 2018 by René-Luc Dhont
6+
email : rldhont at 3liz dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSWMTSPARAMETERS_H
19+
#define QGSWMTSPARAMETERS_H
20+
21+
#include <QMap>
22+
#include <QObject>
23+
#include <QMetaEnum>
24+
25+
#include "qgswmtsserviceexception.h"
26+
#include "qgsserverrequest.h"
27+
#include "qgsprojectversion.h"
28+
#include "qgsserverparameters.h"
29+
30+
namespace QgsWmts
31+
{
32+
33+
/**
34+
* \ingroup server
35+
* \class QgsWmts::QgsWmtsParameter
36+
* \brief WMTS parameter received from the client.
37+
* \since QGIS 3.4
38+
*/
39+
class QgsWmtsParameter : public QgsServerParameterDefinition
40+
{
41+
Q_GADGET
42+
43+
public:
44+
//! Available parameters for WMTS requests
45+
enum Name
46+
{
47+
UNKNOWN,
48+
LAYER,
49+
FORMAT,
50+
TILEMATRIXSET,
51+
TILEMATRIX,
52+
TILEROW,
53+
TILECOL,
54+
INFOFORMAT,
55+
I,
56+
J
57+
};
58+
Q_ENUM( Name )
59+
60+
/**
61+
* Constructor for QgsWmtsParameter.
62+
* \param name Name of the WMS parameter
63+
* \param type Type of the parameter
64+
* \param defaultValue Default value of the parameter
65+
*/
66+
QgsWmtsParameter( const QgsWmtsParameter::Name name = QgsWmtsParameter::UNKNOWN,
67+
const QVariant::Type type = QVariant::String,
68+
const QVariant defaultValue = QVariant( "" ) );
69+
70+
/**
71+
* Default destructor for QgsWmtsParameter.
72+
*/
73+
virtual ~QgsWmtsParameter() = default;
74+
75+
/**
76+
* Converts the parameter into an integer.
77+
* \returns An integer
78+
* \throws QgsBadRequestException Invalid parameter exception
79+
*/
80+
int toInt() const;
81+
82+
/**
83+
* Raises an error in case of an invalid conversion.
84+
* \throws QgsBadRequestException Invalid parameter exception
85+
*/
86+
void raiseError() const;
87+
88+
/**
89+
* Converts a parameter's name into its string representation.
90+
*/
91+
static QString name( const QgsWmtsParameter::Name );
92+
93+
/**
94+
* Converts a string into a parameter's name (UNKNOWN in case of an
95+
* invalid string).
96+
*/
97+
static QgsWmtsParameter::Name name( const QString &name );
98+
99+
QgsWmtsParameter::Name mName;
100+
};
101+
102+
103+
/**
104+
* \ingroup server
105+
* \class QgsWmts::QgsWmtsParameters
106+
* \brief Provides an interface to retrieve and manipulate WMTS parameters received from the client.
107+
* \since QGIS 3.4
108+
*/
109+
class QgsWmtsParameters : public QgsServerParameters
110+
{
111+
Q_GADGET
112+
113+
public:
114+
115+
//! Output format for the response
116+
enum Format
117+
{
118+
NONE,
119+
JPG,
120+
PNG,
121+
TEXT,
122+
XML,
123+
HTML,
124+
GML
125+
};
126+
127+
/**
128+
* Constructor for WMTS parameters with specific values.
129+
* \param parameters Map of parameters where keys are parameters' names.
130+
*/
131+
QgsWmtsParameters( const QgsServerParameters &parameters );
132+
133+
/**
134+
* Constructor for WMTS parameters with default values only.
135+
*/
136+
QgsWmtsParameters();
137+
138+
/**
139+
* Default destructor for QgsWmtsParameters.
140+
*/
141+
virtual ~QgsWmtsParameters() = default;
142+
143+
/**
144+
* Dumps parameters.
145+
*/
146+
void dump() const;
147+
148+
/**
149+
* Returns VERSION parameter if defined or its default value.
150+
* \returns version
151+
*/
152+
QgsProjectVersion versionAsNumber() const;
153+
154+
/**
155+
* Returns LAYER parameter as a string.
156+
* \returns layer parameter as string
157+
*/
158+
QString layer() const;
159+
160+
/**
161+
* Returns FORMAT parameter as a string.
162+
* \returns Format parameter as string
163+
*/
164+
QString formatAsString() const;
165+
166+
/**
167+
* Returns format. If the FORMAT parameter is not used, then the
168+
* default value is NONE.
169+
* \returns format
170+
*/
171+
Format format() const;
172+
173+
/**
174+
* Returns TILEMATRIXSET parameter as a string.
175+
* \returns tileMatrixSet parameter as string
176+
*/
177+
QString tileMatrixSet() const;
178+
179+
/**
180+
* Returns TILEMATRIX parameter as a string.
181+
* \returns tileMatrix parameter as string
182+
*/
183+
QString tileMatrix() const;
184+
185+
/**
186+
* Returns TILEMATRIX parameter as an int or its default value if not
187+
* defined. An exception is raised if TILEMATRIX is defined and cannot be
188+
* converted.
189+
* \returns tileMatrix parameter
190+
* \throws QgsBadRequestException
191+
*/
192+
int tileMatrixAsInt() const;
193+
194+
/**
195+
* Returns TILEROW parameter as a string.
196+
* \returns tileRow parameter as string
197+
*/
198+
QString tileRow() const;
199+
200+
/**
201+
* Returns TILEROW parameter as an int or its default value if not
202+
* defined. An exception is raised if TILEROW is defined and cannot be
203+
* converted.
204+
* \returns tileRow parameter
205+
* \throws QgsBadRequestException
206+
*/
207+
int tileRowAsInt() const;
208+
209+
/**
210+
* Returns TILECOL parameter as a string.
211+
* \returns tileCol parameter as string
212+
*/
213+
QString tileCol() const;
214+
215+
/**
216+
* Returns TILECOL parameter as an int or its default value if not
217+
* defined. An exception is raised if TILECOL is defined and cannot be
218+
* converted.
219+
* \returns tileCol parameter
220+
* \throws QgsBadRequestException
221+
*/
222+
int tileColAsInt() const;
223+
224+
/**
225+
* Returns INFO_FORMAT parameter as a string.
226+
* \returns INFO_FORMAT parameter as string
227+
*/
228+
QString infoFormatAsString() const;
229+
230+
/**
231+
* Returns infoFormat. If the INFO_FORMAT parameter is not used, then the
232+
* default value is text/plain.
233+
* \returns infoFormat
234+
*/
235+
Format infoFormat() const;
236+
237+
/**
238+
* Returns the infoFormat version for GML. If the INFO_FORMAT is not GML,
239+
* then the default value is -1.
240+
* \returns infoFormat version
241+
*/
242+
int infoFormatVersion() const;
243+
244+
/**
245+
* Returns I parameter or an empty string if not defined.
246+
* \returns i parameter
247+
*/
248+
QString i() const;
249+
250+
/**
251+
* Returns I parameter as an int or its default value if not
252+
* defined. An exception is raised if I is defined and cannot be
253+
* converted.
254+
* \returns i parameter
255+
* \throws QgsBadRequestException
256+
*/
257+
int iAsInt() const;
258+
259+
/**
260+
* Returns J parameter or an empty string if not defined.
261+
* \returns j parameter
262+
*/
263+
QString j() const;
264+
265+
/**
266+
* Returns J parameter as an int or its default value if not
267+
* defined. An exception is raised if J is defined and cannot be
268+
* converted.
269+
* \returns j parameter
270+
* \throws QgsBadRequestException
271+
*/
272+
int jAsInt() const;
273+
274+
private:
275+
bool loadParameter( const QString &name, const QString &key ) override;
276+
void save( const QgsWmtsParameter &parameter );
277+
278+
void log( const QString &msg ) const;
279+
280+
QList<QgsProjectVersion> mVersions;
281+
QMap<QgsWmtsParameter::Name, QgsWmtsParameter> mWmtsParameters;
282+
};
283+
}
284+
285+
#endif

‎src/server/services/wmts/qgswmtsutils.cpp

Lines changed: 29 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
***************************************************************************/
1717

1818
#include "qgswmtsutils.h"
19+
#include "qgswmtsparameters.h"
1920
#include "qgsconfigcache.h"
2021
#include "qgsserverprojectutils.h"
2122

@@ -65,39 +66,20 @@ namespace QgsWmts
6566
if ( href.isEmpty() )
6667
{
6768
QUrl url = request.url();
68-
QUrlQuery q( url );
6969

70-
q.removeAllQueryItems( QStringLiteral( "REQUEST" ) );
71-
q.removeAllQueryItems( QStringLiteral( "VERSION" ) );
72-
q.removeAllQueryItems( QStringLiteral( "SERVICE" ) );
73-
q.removeAllQueryItems( QStringLiteral( "_DC" ) );
70+
QgsWmtsParameters params;
71+
params.load( QUrlQuery( url ) );
72+
params.remove( QgsServerParameter::REQUEST );
73+
params.remove( QgsServerParameter::VERSION_SERVICE );
74+
params.remove( QgsServerParameter::SERVICE );
7475

75-
url.setQuery( q );
76+
url.setQuery( params.urlQuery() );
7677
href = url.toString( QUrl::FullyDecoded );
77-
7878
}
7979

8080
return href;
8181
}
8282

83-
QgsRectangle parseBbox( const QString &bboxStr )
84-
{
85-
QStringList lst = bboxStr.split( ',' );
86-
if ( lst.count() != 4 )
87-
return QgsRectangle();
88-
89-
double d[4];
90-
bool ok;
91-
for ( int i = 0; i < 4; i++ )
92-
{
93-
lst[i].replace( ' ', '+' );
94-
d[i] = lst[i].toDouble( &ok );
95-
if ( !ok )
96-
return QgsRectangle();
97-
}
98-
return QgsRectangle( d[0], d[1], d[2], d[3] );
99-
}
100-
10183
tileMatrixInfo getTileMatrixInfo( const QString &crsStr, const QgsProject *project )
10284
{
10385
if ( tileMatrixInfoMap.contains( crsStr ) )
@@ -133,9 +115,9 @@ namespace QgsWmts
133115
return tmi;
134116
}
135117

136-
tileMatrixSet getTileMatrixSet( tileMatrixInfo tmi, double minScale )
118+
tileMatrixSetDef getTileMatrixSet( tileMatrixInfo tmi, double minScale )
137119
{
138-
QList< tileMatrix > tileMatrixList;
120+
QList< tileMatrixDef > tileMatrixList;
139121
double scaleDenominator = tmi.scaleDenominator;
140122
QgsRectangle extent = tmi.extent;
141123
QgsUnitTypes::DistanceUnit unit = tmi.unit;
@@ -149,7 +131,7 @@ namespace QgsWmts
149131
double left = ( extent.xMinimum() + ( extent.xMaximum() - extent.xMinimum() ) / 2.0 ) - ( col / 2.0 ) * ( tileWidth * res );
150132
double top = ( extent.yMinimum() + ( extent.yMaximum() - extent.yMinimum() ) / 2.0 ) + ( row / 2.0 ) * ( tileHeight * res );
151133

152-
tileMatrix tm;
134+
tileMatrixDef tm;
153135
tm.resolution = res;
154136
tm.scaleDenominator = scale;
155137
tm.col = col;
@@ -161,7 +143,7 @@ namespace QgsWmts
161143
scaleDenominator = scale / 2;
162144
}
163145

164-
tileMatrixSet tms;
146+
tileMatrixSetDef tms;
165147
tms.ref = tmi.ref;
166148
tms.extent = extent;
167149
tms.unit = unit;
@@ -206,9 +188,9 @@ namespace QgsWmts
206188
return scale;
207189
}
208190

209-
QList< tileMatrixSet > getTileMatrixSetList( const QgsProject *project )
191+
QList< tileMatrixSetDef > getTileMatrixSetList( const QgsProject *project )
210192
{
211-
QList< tileMatrixSet > tmsList;
193+
QList< tileMatrixSetDef > tmsList;
212194

213195
double minScale = getProjectMinScale( project );
214196

@@ -225,18 +207,13 @@ namespace QgsWmts
225207
return tmsList;
226208
}
227209

228-
QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsServerRequest::Parameters &params,
210+
QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsWmtsParameters &params,
229211
const QgsProject *project, QgsServerInterface *serverIface )
230212
{
231213
//defining Layer
232-
QString layer;
214+
QString layer = params.layer();
233215
//read Layer
234-
QMap<QString, QString>::const_iterator layer_it = params.constFind( QStringLiteral( "LAYER" ) );
235-
if ( layer_it != params.constEnd() )
236-
{
237-
layer = layer_it.value();
238-
}
239-
else
216+
if ( layer.isEmpty() )
240217
{
241218
throw QgsRequestNotWellFormedException( QStringLiteral( "Layer is mandatory" ) );
242219
}
@@ -309,27 +286,17 @@ namespace QgsWmts
309286
}
310287

311288
//defining Format
312-
QString format;
289+
QString format = params.formatAsString();
313290
//read Format
314-
QMap<QString, QString>::const_iterator format_it = params.constFind( QStringLiteral( "FORMAT" ) );
315-
if ( format_it != params.constEnd() )
316-
{
317-
format = format_it.value();
318-
}
319-
else
291+
if ( format.isEmpty() )
320292
{
321293
throw QgsRequestNotWellFormedException( QStringLiteral( "Format is mandatory" ) );
322294
}
323295

324296
//defining TileMatrixSet ref
325-
QString tms_ref;
297+
QString tms_ref = params.tileMatrixSet();
326298
//read TileMatrixSet
327-
QMap<QString, QString>::const_iterator tms_ref_it = params.constFind( QStringLiteral( "TILEMATRIXSET" ) );
328-
if ( tms_ref_it != params.constEnd() )
329-
{
330-
tms_ref = tms_ref_it.value();
331-
}
332-
else
299+
if ( tms_ref.isEmpty() )
333300
{
334301
throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is mandatory" ) );
335302
}
@@ -346,48 +313,25 @@ namespace QgsWmts
346313
{
347314
throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
348315
}
349-
tileMatrixSet tms = getTileMatrixSet( tmi, getProjectMinScale( project ) );
350-
351-
bool conversionSuccess = false;
316+
tileMatrixSetDef tms = getTileMatrixSet( tmi, getProjectMinScale( project ) );
352317

353318
//difining TileMatrix idx
354-
int tm_idx;
319+
int tm_idx = params.tileMatrixAsInt();
355320
//read TileMatrix
356-
QMap<QString, QString>::const_iterator tm_ref_it = params.constFind( QStringLiteral( "TILEMATRIX" ) );
357-
if ( tm_ref_it != params.constEnd() )
358-
{
359-
QString tm_ref = tm_ref_it.value();
360-
tm_idx = tm_ref.toInt( &conversionSuccess );
361-
if ( !conversionSuccess )
362-
{
363-
throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is unknown" ) );
364-
}
365-
}
366-
else
321+
if ( tm_idx == -1 )
367322
{
368323
throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is mandatory" ) );
369324
}
370325
if ( tms.tileMatrixList.count() < tm_idx )
371326
{
372327
throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is unknown" ) );
373328
}
374-
tileMatrix tm = tms.tileMatrixList.at( tm_idx );
329+
tileMatrixDef tm = tms.tileMatrixList.at( tm_idx );
375330

376331
//defining TileRow
377-
int tr;
332+
int tr = params.tileRowAsInt();
378333
//read TileRow
379-
QMap<QString, QString>::const_iterator tr_it = params.constFind( QStringLiteral( "TILEROW" ) );
380-
if ( tr_it != params.constEnd() )
381-
{
382-
QString tr_str = tr_it.value();
383-
conversionSuccess = false;
384-
tr = tr_str.toInt( &conversionSuccess );
385-
if ( !conversionSuccess )
386-
{
387-
throw QgsRequestNotWellFormedException( QStringLiteral( "TileRow is unknown" ) );
388-
}
389-
}
390-
else
334+
if ( tr == -1 )
391335
{
392336
throw QgsRequestNotWellFormedException( QStringLiteral( "TileRow is mandatory" ) );
393337
}
@@ -397,20 +341,9 @@ namespace QgsWmts
397341
}
398342

399343
//defining TileCol
400-
int tc;
344+
int tc = params.tileColAsInt();
401345
//read TileCol
402-
QMap<QString, QString>::const_iterator tc_it = params.constFind( QStringLiteral( "TILECOL" ) );
403-
if ( tc_it != params.constEnd() )
404-
{
405-
QString tc_str = tc_it.value();
406-
conversionSuccess = false;
407-
tc = tc_str.toInt( &conversionSuccess );
408-
if ( !conversionSuccess )
409-
{
410-
throw QgsRequestNotWellFormedException( QStringLiteral( "TileCol is unknown" ) );
411-
}
412-
}
413-
else
346+
if ( tc == -1 )
414347
{
415348
throw QgsRequestNotWellFormedException( QStringLiteral( "TileCol is mandatory" ) );
416349
}
@@ -457,7 +390,7 @@ namespace QgsWmts
457390
query.addQueryItem( QStringLiteral( "width" ), QStringLiteral( "256" ) );
458391
query.addQueryItem( QStringLiteral( "height" ), QStringLiteral( "256" ) );
459392
query.addQueryItem( QStringLiteral( "format" ), format );
460-
if ( format.startsWith( QStringLiteral( "image/png" ) ) )
393+
if ( params.format() == QgsWmtsParameters::Format::PNG )
461394
{
462395
query.addQueryItem( QStringLiteral( "transparent" ), QStringLiteral( "true" ) );
463396
}

‎src/server/services/wmts/qgswmtsutils.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define QGSWMTSUTILS_H
2121

2222
#include "qgsmodule.h"
23+
#include "qgswmtsparameters.h"
2324
#include "qgswmtsserviceexception.h"
2425

2526
#include <QDomDocument>
@@ -45,7 +46,7 @@ namespace QgsWmts
4546
QgsUnitTypes::DistanceUnit unit;
4647
};
4748

48-
struct tileMatrix
49+
struct tileMatrixDef
4950
{
5051
double resolution = 0.0;
5152

@@ -60,15 +61,15 @@ namespace QgsWmts
6061
double top = 0.0;
6162
};
6263

63-
struct tileMatrixSet
64+
struct tileMatrixSetDef
6465
{
6566
QString ref;
6667

6768
QgsRectangle extent;
6869

6970
QgsUnitTypes::DistanceUnit unit;
7071

71-
QList< tileMatrix > tileMatrixList;
72+
QList< tileMatrixDef > tileMatrixList;
7273
};
7374

7475
struct layerDef
@@ -96,26 +97,20 @@ namespace QgsWmts
9697
*/
9798
QString serviceUrl( const QgsServerRequest &request, const QgsProject *project );
9899

99-
/**
100-
* Parse bounding box
101-
*/
102-
//XXX At some point, should be moved to common library
103-
QgsRectangle parseBbox( const QString &bboxStr );
104-
105100
// Define namespaces used in WMTS documents
106101
const QString WMTS_NAMESPACE = QStringLiteral( "http://www.opengis.net/wmts/1.0" );
107102
const QString GML_NAMESPACE = QStringLiteral( "http://www.opengis.net/gml" );
108103
const QString OWS_NAMESPACE = QStringLiteral( "http://www.opengis.net/ows/1.1" );
109104

110105
tileMatrixInfo getTileMatrixInfo( const QString &crsStr, const QgsProject *project );
111-
tileMatrixSet getTileMatrixSet( tileMatrixInfo tmi, double minScale );
106+
tileMatrixSetDef getTileMatrixSet( tileMatrixInfo tmi, double minScale );
112107
double getProjectMinScale( const QgsProject *project );
113-
QList< tileMatrixSet > getTileMatrixSetList( const QgsProject *project );
108+
QList< tileMatrixSetDef > getTileMatrixSetList( const QgsProject *project );
114109

115110
/**
116111
* Translate WMTS parameters to WMS query item
117112
*/
118-
QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsServerRequest::Parameters &params,
113+
QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsWmtsParameters &params,
119114
const QgsProject *project, QgsServerInterface *serverIface );
120115

121116
} // namespace QgsWmts

0 commit comments

Comments
 (0)
Please sign in to comment.