1 /***************************************************************************
2                               qgswmsparameters.cpp
3                               --------------------
4   begin                : March 17, 2017
5   copyright            : (C) 2017 by Paul Blottiere
6   email                : paul dot blottiere at oslandia 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 "qgswmsparameters.h"
19 #include "qgsdatasourceuri.h"
20 #include "qgsmaplayerserverproperties.h"
21 #include "qgsmessagelog.h"
22 #include "qgswmsserviceexception.h"
23 
24 const QString EXTERNAL_LAYER_PREFIX = QStringLiteral( "EXTERNAL_WMS:" );
25 
26 namespace QgsWms
27 {
28   //
29   // QgsWmsParameter
30   //
QgsWmsParameter(const QgsWmsParameter::Name name,const QVariant::Type type,const QVariant defaultValue)31   QgsWmsParameter::QgsWmsParameter( const QgsWmsParameter::Name name,
32                                     const QVariant::Type type,
33                                     const QVariant defaultValue )
34     : QgsServerParameterDefinition( type, defaultValue )
35     , mName( name )
36   {
37   }
38 
isValid() const39   bool QgsWmsParameter::isValid() const
40   {
41     return ( mName != QgsWmsParameter::UNKNOWN ) && QgsServerParameterDefinition::isValid();
42   }
43 
raiseError() const44   void QgsWmsParameter::raiseError() const
45   {
46     const QString msg = QString( "%1 ('%2') cannot be converted into %3" ).arg( name( mName ), toString(), typeName() );
47     QgsServerParameterDefinition::raiseError( msg );
48   }
49 
toStyleList(const char delimiter) const50   QStringList QgsWmsParameter::toStyleList( const char delimiter ) const
51   {
52     return QgsServerParameterDefinition::toStringList( delimiter, false );
53   }
54 
toGeomList(const char delimiter) const55   QList<QgsGeometry> QgsWmsParameter::toGeomList( const char delimiter ) const
56   {
57     bool ok = true;
58     const QList<QgsGeometry> geoms = QgsServerParameterDefinition::toGeomList( ok, delimiter );
59 
60     if ( !ok )
61     {
62       const QString msg = QString( "%1 ('%2') cannot be converted into a list of geometries" ).arg( name( mName ), toString() );
63       QgsServerParameterDefinition::raiseError( msg );
64     }
65 
66     return geoms;
67   }
68 
toRectangle() const69   QgsRectangle QgsWmsParameter::toRectangle() const
70   {
71     bool ok = true;
72     const QgsRectangle rect = QgsServerParameterDefinition::toRectangle( ok );
73 
74     if ( !ok )
75     {
76       const QString msg = QString( "%1 ('%2') cannot be converted into a rectangle" ).arg( name( mName ), toString() );
77       QgsServerParameterDefinition::raiseError( msg );
78     }
79 
80     return rect;
81   }
82 
toInt() const83   int QgsWmsParameter::toInt() const
84   {
85     bool ok = false;
86     const int val = QgsServerParameterDefinition::toInt( ok );
87 
88     if ( !ok )
89     {
90       raiseError();
91     }
92 
93     return val;
94   }
95 
loadUrl() const96   QString QgsWmsParameter::loadUrl() const
97   {
98     // Check URL -- it will be used in error messages
99     const QUrl url = toUrl();
100 
101     bool ok = false;
102     const QString content = QgsServerParameterDefinition::loadUrl( ok );
103 
104     if ( !ok )
105     {
106       const QString msg = QString( "%1 request error for %2" ).arg( name( mName ), url.toString() );
107       QgsServerParameterDefinition::raiseError( msg );
108     }
109 
110     return content;
111   }
112 
toUrl() const113   QUrl QgsWmsParameter::toUrl() const
114   {
115     bool ok = false;
116     const QUrl url = QgsServerParameterDefinition::toUrl( ok );
117 
118     if ( !ok )
119     {
120       raiseError();
121     }
122 
123     return url;
124   }
125 
toColor() const126   QColor QgsWmsParameter::toColor() const
127   {
128     bool ok = false;
129     const QColor col = QgsServerParameterDefinition::toColor( ok );
130 
131     if ( !ok )
132     {
133       raiseError();
134     }
135 
136     return col;
137   }
138 
toColorList(const char delimiter) const139   QList<QColor> QgsWmsParameter::toColorList( const char delimiter ) const
140   {
141     bool ok = false;
142     const QList<QColor> vals = QgsServerParameterDefinition::toColorList( ok, delimiter );
143 
144     if ( !ok )
145     {
146       const QString msg = QString( "%1 ('%2') cannot be converted into a list of colors" ).arg( name( mName ), toString() );
147       QgsServerParameterDefinition::raiseError( msg );
148     }
149 
150     return vals;
151   }
152 
toIntList(const char delimiter) const153   QList<int> QgsWmsParameter::toIntList( const char delimiter ) const
154   {
155     bool ok = false;
156     const QList<int> vals = QgsServerParameterDefinition::toIntList( ok, delimiter );
157 
158     if ( !ok )
159     {
160       const QString msg = QString( "%1 ('%2') cannot be converted into a list of int" ).arg( name( mName ), toString() );
161       QgsServerParameterDefinition::raiseError( msg );
162     }
163 
164     return vals;
165   }
166 
toDoubleList(const char delimiter) const167   QList<double> QgsWmsParameter::toDoubleList( const char delimiter ) const
168   {
169     bool ok = false;
170     const QList<double> vals = QgsServerParameterDefinition::toDoubleList( ok, delimiter );
171 
172     if ( !ok )
173     {
174       const QString msg = QString( "%1 ('%2') cannot be converted into a list of float" ).arg( name( mName ), toString() );
175       QgsServerParameterDefinition::raiseError( msg );
176     }
177 
178     return vals;
179   }
180 
toDouble() const181   double QgsWmsParameter::toDouble() const
182   {
183     bool ok = false;
184     const double val = QgsServerParameterDefinition::toDouble( ok );
185 
186     if ( !ok )
187     {
188       raiseError();
189     }
190 
191     return val;
192   }
193 
name() const194   QString QgsWmsParameter::name() const
195   {
196     return QgsWmsParameter::name( mName );
197   }
198 
name(const QgsWmsParameter::Name name)199   QString QgsWmsParameter::name( const QgsWmsParameter::Name name )
200   {
201     const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmsParameter::Name>() );
202     return metaEnum.valueToKey( name );
203   }
204 
name(const QString & name)205   QgsWmsParameter::Name QgsWmsParameter::name( const QString &name )
206   {
207     const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmsParameter::Name>() );
208     return ( QgsWmsParameter::Name ) metaEnum.keyToValue( name.toUpper().toStdString().c_str() );
209   }
210 
211   //
212   // QgsWmsParameters
213   //
QgsWmsParameters()214   QgsWmsParameters::QgsWmsParameters()
215     : QgsServerParameters()
216   {
217     // Available version number
218     mVersions.append( QgsProjectVersion( 1, 1, 1 ) );
219     mVersions.append( QgsProjectVersion( 1, 3, 0 ) );
220 
221     // WMS parameters definition
222     const QgsWmsParameter pQuality( QgsWmsParameter::IMAGE_QUALITY,
223                                     QVariant::Int,
224                                     QVariant( 0 ) );
225     save( pQuality );
226 
227     const QgsWmsParameter pTiled( QgsWmsParameter::TILED,
228                                   QVariant::Bool,
229                                   QVariant( false ) );
230     save( pTiled );
231 
232     const QgsWmsParameter pBoxSpace( QgsWmsParameter::BOXSPACE,
233                                      QVariant::Double,
234                                      QVariant( 2.0 ) );
235     save( pBoxSpace );
236 
237     const QgsWmsParameter pSymbSpace( QgsWmsParameter::SYMBOLSPACE,
238                                       QVariant::Double,
239                                       QVariant( 2.0 ) );
240     save( pSymbSpace );
241 
242     const QgsWmsParameter pLayerSpace( QgsWmsParameter::LAYERSPACE,
243                                        QVariant::Double,
244                                        QVariant( 3.0 ) );
245     save( pLayerSpace );
246 
247     const QgsWmsParameter pTitleSpace( QgsWmsParameter::LAYERTITLESPACE,
248                                        QVariant::Double,
249                                        QVariant( 3.0 ) );
250     save( pTitleSpace );
251 
252     const QgsWmsParameter pSymbHeight( QgsWmsParameter::SYMBOLHEIGHT,
253                                        QVariant::Double,
254                                        QVariant( 4.0 ) );
255     save( pSymbHeight );
256 
257     const QgsWmsParameter pSymbWidth( QgsWmsParameter::SYMBOLWIDTH,
258                                       QVariant::Double,
259                                       QVariant( 7.0 ) );
260     save( pSymbWidth );
261 
262     const QgsWmsParameter pIcLabelSpace( QgsWmsParameter::ICONLABELSPACE,
263                                          QVariant::Double,
264                                          QVariant( 2.0 ) );
265     save( pIcLabelSpace );
266 
267     const QgsWmsParameter pItFontFamily( QgsWmsParameter::ITEMFONTFAMILY );
268     save( pItFontFamily );
269 
270     const QgsWmsParameter pItFontBold( QgsWmsParameter::ITEMFONTBOLD,
271                                        QVariant::Bool,
272                                        QVariant( false ) );
273     save( pItFontBold );
274 
275     const QgsWmsParameter pItFontItalic( QgsWmsParameter::ITEMFONTITALIC,
276                                          QVariant::Bool,
277                                          QVariant( false ) );
278     save( pItFontItalic );
279 
280     const QgsWmsParameter pItFontSize( QgsWmsParameter::ITEMFONTSIZE,
281                                        QVariant::Double,
282                                        QVariant( -1 ) );
283     save( pItFontSize );
284 
285     const QgsWmsParameter pItFontColor( QgsWmsParameter::ITEMFONTCOLOR,
286                                         QVariant::String,
287                                         QVariant( "black" ) );
288     save( pItFontColor );
289 
290     const QgsWmsParameter pHighlightGeom( QgsWmsParameter::HIGHLIGHT_GEOM );
291     save( pHighlightGeom );
292 
293     const QgsWmsParameter pShowFeatureCount( QgsWmsParameter::SHOWFEATURECOUNT,
294         QVariant::Bool,
295         QVariant( false ) );
296     save( pShowFeatureCount );
297 
298     const QgsWmsParameter pHighlightSymbol( QgsWmsParameter::HIGHLIGHT_SYMBOL );
299     save( pHighlightSymbol );
300 
301     const QgsWmsParameter pHighlightLabel( QgsWmsParameter::HIGHLIGHT_LABELSTRING );
302     save( pHighlightLabel );
303 
304     const QgsWmsParameter pHighlightColor( QgsWmsParameter::HIGHLIGHT_LABELCOLOR,
305                                            QVariant::String,
306                                            QVariant( "black" ) );
307     save( pHighlightColor );
308 
309     const QgsWmsParameter pHighlightFontSize( QgsWmsParameter::HIGHLIGHT_LABELSIZE );
310     save( pHighlightFontSize );
311 
312     const QgsWmsParameter pHighlightFontWeight( QgsWmsParameter::HIGHLIGHT_LABELWEIGHT );
313     save( pHighlightFontWeight );
314 
315     const QgsWmsParameter pHighlightFont( QgsWmsParameter::HIGHLIGHT_LABELFONT );
316     save( pHighlightFont );
317 
318     const QgsWmsParameter pHighlightBufferColor( QgsWmsParameter::HIGHLIGHT_LABELBUFFERCOLOR,
319         QVariant::String,
320         QVariant( "black" ) );
321     save( pHighlightBufferColor );
322 
323     const QgsWmsParameter pHighlightBufferSize( QgsWmsParameter::HIGHLIGHT_LABELBUFFERSIZE );
324     save( pHighlightBufferSize );
325 
326     const QgsWmsParameter pCRS( QgsWmsParameter::CRS );
327     save( pCRS );
328 
329     const QgsWmsParameter pSRS( QgsWmsParameter::SRS );
330     save( pSRS );
331 
332     const QgsWmsParameter pFormat( QgsWmsParameter::FORMAT,
333                                    QVariant::String,
334                                    QVariant( "png" ) );
335     save( pFormat );
336 
337     const QgsWmsParameter pInfoFormat( QgsWmsParameter::INFO_FORMAT );
338     save( pInfoFormat );
339 
340     const QgsWmsParameter pI( QgsWmsParameter::I,
341                               QVariant::Int,
342                               QVariant( -1 ) );
343     save( pI );
344 
345     const QgsWmsParameter pJ( QgsWmsParameter::J,
346                               QVariant::Int,
347                               QVariant( -1 ) );
348     save( pJ );
349 
350     const QgsWmsParameter pX( QgsWmsParameter::X,
351                               QVariant::Int,
352                               QVariant( -1 ) );
353     save( pX );
354 
355     const QgsWmsParameter pY( QgsWmsParameter::Y,
356                               QVariant::Int,
357                               QVariant( -1 ) );
358     save( pY );
359 
360     const QgsWmsParameter pRule( QgsWmsParameter::RULE );
361     save( pRule );
362 
363     const QgsWmsParameter pRuleLabel( QgsWmsParameter::RULELABEL,
364                                       QVariant::Bool,
365                                       QVariant( true ) );
366     save( pRuleLabel );
367 
368     const QgsWmsParameter pScale( QgsWmsParameter::SCALE,
369                                   QVariant::Double,
370                                   QVariant( -1 ) );
371     save( pScale );
372 
373     const QgsWmsParameter pHeight( QgsWmsParameter::HEIGHT,
374                                    QVariant::Int,
375                                    QVariant( 0 ) );
376     save( pHeight );
377 
378     const QgsWmsParameter pWidth( QgsWmsParameter::WIDTH,
379                                   QVariant::Int,
380                                   QVariant( 0 ) );
381     save( pWidth );
382 
383     const QgsWmsParameter pSrcHeight( QgsWmsParameter::SRCHEIGHT,
384                                       QVariant::Int,
385                                       QVariant( 0 ) );
386     save( pSrcHeight );
387 
388     const QgsWmsParameter pSrcWidth( QgsWmsParameter::SRCWIDTH,
389                                      QVariant::Int,
390                                      QVariant( 0 ) );
391     save( pSrcWidth );
392 
393     const QgsWmsParameter pBbox( QgsWmsParameter::BBOX );
394     save( pBbox );
395 
396     const QgsWmsParameter pSld( QgsWmsParameter::SLD );
397     save( pSld );
398 
399     const QgsWmsParameter pSldBody( QgsWmsParameter::SLD_BODY );
400     save( pSldBody );
401 
402     const QgsWmsParameter pLayer( QgsWmsParameter::LAYER );
403     save( pLayer );
404 
405     const QgsWmsParameter pLayers( QgsWmsParameter::LAYERS );
406     save( pLayers );
407 
408     const QgsWmsParameter pQueryLayers( QgsWmsParameter::QUERY_LAYERS );
409     save( pQueryLayers );
410 
411     const QgsWmsParameter pFeatureCount( QgsWmsParameter::FEATURE_COUNT,
412                                          QVariant::Int,
413                                          QVariant( 1 ) );
414     save( pFeatureCount );
415 
416     const QgsWmsParameter pLayerTitle( QgsWmsParameter::LAYERTITLE,
417                                        QVariant::Bool,
418                                        QVariant( true ) );
419     save( pLayerTitle );
420 
421     const QgsWmsParameter pLayerFtFamily( QgsWmsParameter::LAYERFONTFAMILY );
422     save( pLayerFtFamily );
423 
424     const QgsWmsParameter pLayerFtBold( QgsWmsParameter::LAYERFONTBOLD,
425                                         QVariant::Bool,
426                                         QVariant( false ) );
427     save( pLayerFtBold );
428 
429     const QgsWmsParameter pLayerFtItalic( QgsWmsParameter::LAYERFONTITALIC,
430                                           QVariant::Bool,
431                                           QVariant( false ) );
432     save( pLayerFtItalic );
433 
434     const QgsWmsParameter pLayerFtSize( QgsWmsParameter::LAYERFONTSIZE,
435                                         QVariant::Double,
436                                         QVariant( -1 ) );
437     save( pLayerFtSize );
438 
439     const QgsWmsParameter pLayerFtColor( QgsWmsParameter::LAYERFONTCOLOR,
440                                          QVariant::String,
441                                          QVariant( "black" ) );
442     save( pLayerFtColor );
443 
444     const QgsWmsParameter pStyle( QgsWmsParameter::STYLE );
445     save( pStyle );
446 
447     const QgsWmsParameter pStyles( QgsWmsParameter::STYLES );
448     save( pStyles );
449 
450     const QgsWmsParameter pOpacities( QgsWmsParameter::OPACITIES );
451     save( pOpacities );
452 
453     const QgsWmsParameter pFilter( QgsWmsParameter::FILTER );
454     save( pFilter );
455 
456     const QgsWmsParameter pFilterGeom( QgsWmsParameter::FILTER_GEOM );
457     save( pFilterGeom );
458 
459     const QgsWmsParameter pPolygTol( QgsWmsParameter::FI_POLYGON_TOLERANCE,
460                                      QVariant::Double,
461                                      QVariant( 0.0 ) );
462     save( pPolygTol );
463 
464     const QgsWmsParameter pLineTol( QgsWmsParameter::FI_LINE_TOLERANCE,
465                                     QVariant::Double,
466                                     QVariant( 0.0 ) );
467     save( pLineTol );
468 
469     const QgsWmsParameter pPointTol( QgsWmsParameter::FI_POINT_TOLERANCE,
470                                      QVariant::Double,
471                                      QVariant( 0.0 ) );
472     save( pPointTol );
473 
474     const QgsWmsParameter pSelection( QgsWmsParameter::SELECTION );
475     save( pSelection );
476 
477     const QgsWmsParameter pWmsPrecision( QgsWmsParameter::WMS_PRECISION,
478                                          QVariant::Int,
479                                          QVariant( -1 ) );
480     save( pWmsPrecision );
481 
482     const QgsWmsParameter pTransparent( QgsWmsParameter::TRANSPARENT,
483                                         QVariant::Bool,
484                                         QVariant( false ) );
485     save( pTransparent );
486 
487     const QgsWmsParameter pBgColor( QgsWmsParameter::BGCOLOR,
488                                     QVariant::String,
489                                     QVariant( "white" ) );
490     save( pBgColor );
491 
492     const QgsWmsParameter pDpi( QgsWmsParameter::DPI,
493                                 QVariant::Int,
494                                 QVariant( -1 ) );
495     save( pDpi );
496 
497     const QgsWmsParameter pTemplate( QgsWmsParameter::TEMPLATE );
498     save( pTemplate );
499 
500     const QgsWmsParameter pExtent( QgsWmsParameter::EXTENT );
501     save( pExtent );
502 
503     const QgsWmsParameter pRotation( QgsWmsParameter::ROTATION,
504                                      QVariant::Double,
505                                      QVariant( 0.0 ) );
506     save( pRotation );
507 
508     const QgsWmsParameter pGridX( QgsWmsParameter::GRID_INTERVAL_X,
509                                   QVariant::Double,
510                                   QVariant( 0.0 ) );
511     save( pGridX );
512 
513     const QgsWmsParameter pGridY( QgsWmsParameter::GRID_INTERVAL_Y,
514                                   QVariant::Double,
515                                   QVariant( 0.0 ) );
516     save( pGridY );
517 
518     const QgsWmsParameter pWithGeometry( QgsWmsParameter::WITH_GEOMETRY,
519                                          QVariant::Bool,
520                                          QVariant( false ) );
521     save( pWithGeometry );
522 
523     const QgsWmsParameter pWithMapTip( QgsWmsParameter::WITH_MAPTIP,
524                                        QVariant::Bool,
525                                        QVariant( false ) );
526     save( pWithMapTip );
527 
528     const QgsWmsParameter pWmtver( QgsWmsParameter::WMTVER );
529     save( pWmtver );
530 
531     const QgsWmsParameter pAtlasPk( QgsWmsParameter::ATLAS_PK,
532                                     QVariant::StringList );
533     save( pAtlasPk );
534 
535     const QgsWmsParameter pFormatOpts( QgsWmsParameter::FORMAT_OPTIONS,
536                                        QVariant::String );
537     save( pFormatOpts );
538   }
539 
QgsWmsParameters(const QgsServerParameters & parameters)540   QgsWmsParameters::QgsWmsParameters( const QgsServerParameters &parameters )
541     : QgsWmsParameters()
542   {
543     load( parameters.urlQuery() );
544 
545     const QString sld = mWmsParameters[ QgsWmsParameter::SLD ].toString();
546     if ( !sld.isEmpty() )
547     {
548       const QString sldBody = mWmsParameters[ QgsWmsParameter::SLD ].loadUrl();
549       if ( !sldBody.isEmpty() )
550       {
551         loadParameter( QgsWmsParameter::name( QgsWmsParameter::SLD_BODY ), sldBody );
552       }
553     }
554   }
555 
operator [](QgsWmsParameter::Name name) const556   QgsWmsParameter QgsWmsParameters::operator[]( QgsWmsParameter::Name name ) const
557   {
558     return mWmsParameters[name];
559   }
560 
set(QgsWmsParameter::Name name,const QVariant & value)561   void QgsWmsParameters::set( QgsWmsParameter::Name name, const QVariant &value )
562   {
563     mWmsParameters[name].mValue = value;
564   }
565 
loadParameter(const QString & key,const QString & value)566   bool QgsWmsParameters::loadParameter( const QString &key, const QString &value )
567   {
568     bool loaded = false;
569 
570     const QRegExp composerParamRegExp( QStringLiteral( "^MAP\\d+:" ), Qt::CaseInsensitive );
571     if ( key.contains( composerParamRegExp ) )
572     {
573 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
574       const int mapId = key.midRef( 3, key.indexOf( ':' ) - 3 ).toInt();
575 #else
576       const int mapId = QStringView {key}.mid( 3, key.indexOf( ':' ) - 3 ).toInt();
577 #endif
578       const QString theKey = key.mid( key.indexOf( ':' ) + 1 );
579       const QgsWmsParameter::Name name = QgsWmsParameter::name( theKey );
580 
581       if ( name >= 0 )
582       {
583         QgsWmsParameter param = mWmsParameters[name];
584         param.mValue = value;
585         param.mId = mapId;
586 
587         if ( ! param.isValid() )
588         {
589           param.raiseError();
590         }
591 
592         save( param, true ); // multi MAP parameters for composer
593         loaded = true;
594       }
595     }
596     else
597     {
598       const QgsWmsParameter::Name name = QgsWmsParameter::name( key );
599       if ( name >= 0 )
600       {
601         mWmsParameters[name].mValue = value;
602         if ( ! mWmsParameters[name].isValid() )
603         {
604           mWmsParameters[name].raiseError();
605         }
606 
607         loaded = true;
608       }
609       else //maybe an external wms parameter?
610       {
611         int separator = key.indexOf( QLatin1Char( ':' ) );
612         if ( separator >= 1 )
613         {
614           QString id = key.left( separator );
615           QString param = key.right( key.length() - separator - 1 );
616           mExternalWMSParameters[id].insert( param, value );
617 
618           loaded = true;
619         }
620       }
621     }
622 
623     return loaded;
624   }
625 
dump() const626   void QgsWmsParameters::dump() const
627   {
628     log( QStringLiteral( "WMS Request parameters:" ) );
629     for ( auto parameter : mWmsParameters.toStdMap() )
630     {
631       const QString value = parameter.second.toString();
632 
633       if ( ! value.isEmpty() )
634       {
635         QString name = QgsWmsParameter::name( parameter.first );
636 
637         if ( parameter.second.mId >= 0 )
638         {
639           name = QStringLiteral( "%1:%2" ).arg( QString::number( parameter.second.mId ), name );
640         }
641 
642         log( QStringLiteral( " - %1 : %2" ).arg( name, value ) );
643       }
644     }
645 
646     if ( !version().isEmpty() )
647       log( QStringLiteral( " - VERSION : %1" ).arg( version() ) );
648   }
649 
save(const QgsWmsParameter & parameter,bool multi)650   void QgsWmsParameters::save( const QgsWmsParameter &parameter, bool multi )
651   {
652     if ( multi )
653     {
654       mWmsParameters.insertMulti( parameter.mName, parameter );
655     }
656     else
657     {
658       mWmsParameters[ parameter.mName ] = parameter;
659     }
660   }
661 
highlightGeom() const662   QStringList QgsWmsParameters::highlightGeom() const
663   {
664     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_GEOM ].toStringList( ';' );
665   }
666 
highlightGeomAsGeom() const667   QList<QgsGeometry> QgsWmsParameters::highlightGeomAsGeom() const
668   {
669     return mWmsParameters[QgsWmsParameter::HIGHLIGHT_GEOM].toGeomList( ';' );
670   }
671 
highlightSymbol() const672   QStringList QgsWmsParameters::highlightSymbol() const
673   {
674     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_SYMBOL ].toStringList( ';' );
675   }
676 
crs() const677   QString QgsWmsParameters::crs() const
678   {
679     QString rs;
680     const QString srs = mWmsParameters[ QgsWmsParameter::SRS ].toString();
681     const QString crs = mWmsParameters[ QgsWmsParameter::CRS ].toString();
682 
683     // both SRS/CRS are supported but there's a priority according to the
684     // specified version when both are defined in the request
685     if ( !srs.isEmpty() && crs.isEmpty() )
686       rs = srs;
687     else if ( srs.isEmpty() && !crs.isEmpty() )
688       rs = crs;
689     else if ( !srs.isEmpty() && !crs.isEmpty() )
690     {
691       if ( versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
692         rs = crs;
693       else
694         rs = srs;
695     }
696 
697     return rs;
698   }
699 
bbox() const700   QString QgsWmsParameters::bbox() const
701   {
702     return mWmsParameters[ QgsWmsParameter::BBOX ].toString();
703   }
704 
bboxAsRectangle() const705   QgsRectangle QgsWmsParameters::bboxAsRectangle() const
706   {
707     return mWmsParameters[ QgsWmsParameter::BBOX ].toRectangle();
708   }
709 
height() const710   QString QgsWmsParameters::height() const
711   {
712     return mWmsParameters[ QgsWmsParameter::HEIGHT ].toString();
713   }
714 
width() const715   QString QgsWmsParameters::width() const
716   {
717     return mWmsParameters[ QgsWmsParameter::WIDTH ].toString();
718   }
719 
heightAsInt() const720   int QgsWmsParameters::heightAsInt() const
721   {
722     return mWmsParameters[ QgsWmsParameter::HEIGHT ].toInt();
723   }
724 
widthAsInt() const725   int QgsWmsParameters::widthAsInt() const
726   {
727     return mWmsParameters[ QgsWmsParameter::WIDTH ].toInt();
728   }
729 
srcHeight() const730   QString QgsWmsParameters::srcHeight() const
731   {
732     return mWmsParameters[ QgsWmsParameter::SRCHEIGHT ].toString();
733   }
734 
srcWidth() const735   QString QgsWmsParameters::srcWidth() const
736   {
737     return mWmsParameters[ QgsWmsParameter::SRCWIDTH ].toString();
738   }
739 
srcHeightAsInt() const740   int QgsWmsParameters::srcHeightAsInt() const
741   {
742     return mWmsParameters[ QgsWmsParameter::SRCHEIGHT ].toInt();
743   }
744 
srcWidthAsInt() const745   int QgsWmsParameters::srcWidthAsInt() const
746   {
747     return mWmsParameters[ QgsWmsParameter::SRCWIDTH ].toInt();
748   }
749 
dpi() const750   QString QgsWmsParameters::dpi() const
751   {
752     return mWmsParameters[ QgsWmsParameter::DPI ].toString();
753   }
754 
dpiAsDouble() const755   double QgsWmsParameters::dpiAsDouble() const
756   {
757     return mWmsParameters[ QgsWmsParameter::DPI ].toDouble();
758   }
759 
version() const760   QString QgsWmsParameters::version() const
761   {
762     QString version = QgsServerParameters::version();
763 
764     if ( QgsServerParameters::request().compare( QLatin1String( "GetProjectSettings" ), Qt::CaseInsensitive ) == 0 )
765     {
766       version = QStringLiteral( "1.3.0" );
767     }
768     else if ( version.isEmpty() )
769     {
770       if ( ! wmtver().isEmpty() )
771       {
772         version = wmtver();
773       }
774       else
775       {
776         version = QStringLiteral( "1.3.0" );
777       }
778     }
779     else if ( !mVersions.contains( QgsProjectVersion( version ) ) )
780     {
781       // WMS 1.3.0 specification: If a version lower than any of those
782       // known to the server is requested, then the server shall send the
783       // lowest version it supports.
784       if ( QgsProjectVersion( 1, 1, 1 ) > QgsProjectVersion( version ) )
785       {
786         version = QStringLiteral( "1.1.1" );
787       }
788       else
789       {
790         version = QStringLiteral( "1.3.0" );
791       }
792     }
793 
794     return version;
795   }
796 
request() const797   QString QgsWmsParameters::request() const
798   {
799     QString req = QgsServerParameters::request();
800 
801     if ( version().compare( QLatin1String( "1.1.1" ) ) == 0
802          && req.compare( QLatin1String( "capabilities" ), Qt::CaseInsensitive ) == 0 )
803     {
804       req = QStringLiteral( "GetCapabilities" );
805     }
806 
807     return req;
808   }
809 
versionAsNumber() const810   QgsProjectVersion QgsWmsParameters::versionAsNumber() const
811   {
812     return QgsProjectVersion( version() );
813   }
814 
versionIsValid(const QString version) const815   bool QgsWmsParameters::versionIsValid( const QString version ) const
816   {
817     return mVersions.contains( QgsProjectVersion( version ) );
818   }
819 
formatAsString() const820   QString QgsWmsParameters::formatAsString() const
821   {
822     return mWmsParameters[ QgsWmsParameter::FORMAT ].toString( true );
823   }
824 
formatAsString(const QgsWmsParameters::Format format)825   QString QgsWmsParameters::formatAsString( const QgsWmsParameters::Format format )
826   {
827     const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmsParameters::Format>() );
828     return metaEnum.valueToKey( format );
829   }
830 
format() const831   QgsWmsParameters::Format QgsWmsParameters::format() const
832   {
833     const QString fStr = formatAsString();
834 
835     Format f = Format::NONE;
836     if ( fStr.compare( QLatin1String( "image/png" ), Qt::CaseInsensitive ) == 0 ||
837          fStr.compare( QLatin1String( "png" ), Qt::CaseInsensitive ) == 0 )
838     {
839       f = Format::PNG;
840     }
841     else if ( fStr.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
842               || fStr.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
843               || fStr.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 )
844     {
845       f = Format::JPG;
846     }
847     else if ( fStr.compare( QLatin1String( "image/svg" ), Qt::CaseInsensitive ) == 0 ||
848               fStr.compare( QLatin1String( "image/svg+xml" ), Qt::CaseInsensitive ) == 0 ||
849               fStr.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
850     {
851       f = Format::SVG;
852     }
853     else if ( fStr.compare( QLatin1String( "application/pdf" ), Qt::CaseInsensitive ) == 0 ||
854               fStr.compare( QLatin1String( "pdf" ), Qt::CaseInsensitive ) == 0 )
855     {
856       f = Format::PDF;
857     }
858     else if ( fStr.compare( QLatin1String( "application/json" ), Qt::CaseInsensitive ) == 0 ||
859               fStr.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 )
860     {
861       f = Format::JSON;
862     }
863     return f;
864   }
865 
infoFormatAsString() const866   QString QgsWmsParameters::infoFormatAsString() const
867   {
868     return mWmsParameters[ QgsWmsParameter::INFO_FORMAT ].toString();
869   }
870 
infoFormatIsImage() const871   bool QgsWmsParameters::infoFormatIsImage() const
872   {
873     return infoFormat() == Format::PNG || infoFormat() == Format::JPG;
874   }
875 
infoFormat() const876   QgsWmsParameters::Format QgsWmsParameters::infoFormat() const
877   {
878     QString fStr = infoFormatAsString();
879 
880     Format f = Format::TEXT;
881     if ( fStr.isEmpty() )
882       return f;
883 
884     if ( fStr.startsWith( QLatin1String( "text/xml" ), Qt::CaseInsensitive ) )
885       f = Format::XML;
886     else if ( fStr.startsWith( QLatin1String( "text/html" ), Qt::CaseInsensitive ) )
887       f = Format::HTML;
888     else if ( fStr.startsWith( QLatin1String( "text/plain" ), Qt::CaseInsensitive ) )
889       f = Format::TEXT;
890     else if ( fStr.startsWith( QLatin1String( "application/vnd.ogc.gml" ), Qt::CaseInsensitive ) )
891       f = Format::GML;
892     else if ( fStr.startsWith( QLatin1String( "application/json" ), Qt::CaseInsensitive )
893               || fStr.startsWith( QLatin1String( "application/geo+json" ), Qt::CaseInsensitive ) )
894       f = Format::JSON;
895     else
896       f = Format::NONE;
897 
898     return f;
899   }
900 
infoFormatVersion() const901   int QgsWmsParameters::infoFormatVersion() const
902   {
903     if ( infoFormat() != Format::GML )
904       return -1;
905 
906     QString fStr = infoFormatAsString();
907     if ( fStr.startsWith( QLatin1String( "application/vnd.ogc.gml/3" ), Qt::CaseInsensitive ) )
908       return 3;
909     else
910       return 2;
911   }
912 
i() const913   QString QgsWmsParameters::i() const
914   {
915     return mWmsParameters[ QgsWmsParameter::I ].toString();
916   }
917 
j() const918   QString QgsWmsParameters::j() const
919   {
920     return mWmsParameters[ QgsWmsParameter::J ].toString();
921   }
922 
iAsInt() const923   int QgsWmsParameters::iAsInt() const
924   {
925     return mWmsParameters[ QgsWmsParameter::I ].toInt();
926   }
927 
jAsInt() const928   int QgsWmsParameters::jAsInt() const
929   {
930     return mWmsParameters[ QgsWmsParameter::J ].toInt();
931   }
932 
x() const933   QString QgsWmsParameters::x() const
934   {
935     return mWmsParameters[ QgsWmsParameter::X ].toString();
936   }
937 
y() const938   QString QgsWmsParameters::y() const
939   {
940     return mWmsParameters[ QgsWmsParameter::Y ].toString();
941   }
942 
xAsInt() const943   int QgsWmsParameters::xAsInt() const
944   {
945     return mWmsParameters[ QgsWmsParameter::X ].toInt();
946   }
947 
yAsInt() const948   int QgsWmsParameters::yAsInt() const
949   {
950     return mWmsParameters[ QgsWmsParameter::Y ].toInt();
951   }
952 
rule() const953   QString QgsWmsParameters::rule() const
954   {
955     return mWmsParameters[ QgsWmsParameter::RULE ].toString();
956   }
957 
ruleLabel() const958   QString QgsWmsParameters::ruleLabel() const
959   {
960     return mWmsParameters[ QgsWmsParameter::RULELABEL ].toString();
961   }
962 
ruleLabelAsBool() const963   bool QgsWmsParameters::ruleLabelAsBool() const
964   {
965     return mWmsParameters[ QgsWmsParameter::RULELABEL ].toBool();
966   }
967 
transparent() const968   QString QgsWmsParameters::transparent() const
969   {
970     return mWmsParameters[ QgsWmsParameter::TRANSPARENT ].toString();
971   }
972 
transparentAsBool() const973   bool QgsWmsParameters::transparentAsBool() const
974   {
975     return mWmsParameters[ QgsWmsParameter::TRANSPARENT ].toBool();
976   }
977 
scale() const978   QString QgsWmsParameters::scale() const
979   {
980     return mWmsParameters[ QgsWmsParameter::SCALE ].toString();
981   }
982 
scaleAsDouble() const983   double QgsWmsParameters::scaleAsDouble() const
984   {
985     return mWmsParameters[ QgsWmsParameter::SCALE ].toDouble();
986   }
987 
imageQuality() const988   QString QgsWmsParameters::imageQuality() const
989   {
990     return mWmsParameters[ QgsWmsParameter::IMAGE_QUALITY ].toString();
991   }
992 
imageQualityAsInt() const993   int QgsWmsParameters::imageQualityAsInt() const
994   {
995     return mWmsParameters[ QgsWmsParameter::IMAGE_QUALITY ].toInt();
996   }
997 
tiled() const998   QString QgsWmsParameters::tiled() const
999   {
1000     return mWmsParameters[ QgsWmsParameter::TILED ].toString();
1001   }
1002 
tiledAsBool() const1003   bool QgsWmsParameters::tiledAsBool() const
1004   {
1005     return mWmsParameters[ QgsWmsParameter::TILED ].toBool();
1006   }
1007 
showFeatureCount() const1008   QString QgsWmsParameters::showFeatureCount() const
1009   {
1010     return mWmsParameters[ QgsWmsParameter::SHOWFEATURECOUNT ].toString();
1011   }
1012 
showFeatureCountAsBool() const1013   bool QgsWmsParameters::showFeatureCountAsBool() const
1014   {
1015     return mWmsParameters[ QgsWmsParameter::SHOWFEATURECOUNT ].toBool();
1016   }
1017 
featureCount() const1018   QString QgsWmsParameters::featureCount() const
1019   {
1020     return mWmsParameters[ QgsWmsParameter::FEATURE_COUNT ].toString();
1021   }
1022 
featureCountAsInt() const1023   int QgsWmsParameters::featureCountAsInt() const
1024   {
1025     return mWmsParameters[ QgsWmsParameter::FEATURE_COUNT ].toInt();
1026   }
1027 
boxSpace() const1028   QString QgsWmsParameters::boxSpace() const
1029   {
1030     return mWmsParameters[ QgsWmsParameter::BOXSPACE ].toString();
1031   }
1032 
boxSpaceAsDouble() const1033   double QgsWmsParameters::boxSpaceAsDouble() const
1034   {
1035     return mWmsParameters[ QgsWmsParameter::BOXSPACE ].toDouble();
1036   }
1037 
layerSpace() const1038   QString QgsWmsParameters::layerSpace() const
1039   {
1040     return mWmsParameters[ QgsWmsParameter::LAYERSPACE ].toString();
1041   }
1042 
layerSpaceAsDouble() const1043   double QgsWmsParameters::layerSpaceAsDouble() const
1044   {
1045     return mWmsParameters[ QgsWmsParameter::LAYERSPACE ].toDouble();
1046   }
1047 
layerTitleSpace() const1048   QString QgsWmsParameters::layerTitleSpace() const
1049   {
1050     return mWmsParameters[ QgsWmsParameter::LAYERTITLESPACE ].toString();
1051   }
1052 
layerTitleSpaceAsDouble() const1053   double QgsWmsParameters::layerTitleSpaceAsDouble() const
1054   {
1055     return mWmsParameters[ QgsWmsParameter::LAYERTITLESPACE ].toDouble();
1056   }
1057 
symbolSpace() const1058   QString QgsWmsParameters::symbolSpace() const
1059   {
1060     return mWmsParameters[ QgsWmsParameter::SYMBOLSPACE ].toString();
1061   }
1062 
symbolSpaceAsDouble() const1063   double QgsWmsParameters::symbolSpaceAsDouble() const
1064   {
1065     return mWmsParameters[ QgsWmsParameter::SYMBOLSPACE ].toDouble();
1066   }
1067 
symbolHeight() const1068   QString QgsWmsParameters::symbolHeight() const
1069   {
1070     return mWmsParameters[ QgsWmsParameter::SYMBOLHEIGHT ].toString();
1071   }
1072 
symbolHeightAsDouble() const1073   double QgsWmsParameters::symbolHeightAsDouble() const
1074   {
1075     return mWmsParameters[ QgsWmsParameter::SYMBOLHEIGHT ].toDouble();
1076   }
1077 
symbolWidth() const1078   QString QgsWmsParameters::symbolWidth() const
1079   {
1080     return mWmsParameters[ QgsWmsParameter::SYMBOLWIDTH ].toString();
1081   }
1082 
symbolWidthAsDouble() const1083   double QgsWmsParameters::symbolWidthAsDouble() const
1084   {
1085     return mWmsParameters[ QgsWmsParameter::SYMBOLWIDTH ].toDouble();
1086   }
1087 
iconLabelSpace() const1088   QString QgsWmsParameters::iconLabelSpace() const
1089   {
1090     return mWmsParameters[ QgsWmsParameter::ICONLABELSPACE ].toString();
1091   }
1092 
iconLabelSpaceAsDouble() const1093   double QgsWmsParameters::iconLabelSpaceAsDouble() const
1094   {
1095     return mWmsParameters[ QgsWmsParameter::ICONLABELSPACE ].toDouble();
1096   }
1097 
layerFontFamily() const1098   QString QgsWmsParameters::layerFontFamily() const
1099   {
1100     return mWmsParameters[ QgsWmsParameter::LAYERFONTFAMILY ].toString();
1101   }
1102 
itemFontFamily() const1103   QString QgsWmsParameters::itemFontFamily() const
1104   {
1105     return mWmsParameters[ QgsWmsParameter::ITEMFONTFAMILY ].toString();
1106   }
1107 
layerFontBold() const1108   QString QgsWmsParameters::layerFontBold() const
1109   {
1110     return mWmsParameters[ QgsWmsParameter::LAYERFONTBOLD ].toString();
1111   }
1112 
layerFontBoldAsBool() const1113   bool QgsWmsParameters::layerFontBoldAsBool() const
1114   {
1115     return mWmsParameters[ QgsWmsParameter::LAYERFONTBOLD ].toBool();
1116   }
1117 
itemFontBold() const1118   QString QgsWmsParameters::itemFontBold() const
1119   {
1120     return mWmsParameters[ QgsWmsParameter::ITEMFONTBOLD ].toString();
1121   }
1122 
polygonTolerance() const1123   QString QgsWmsParameters::polygonTolerance() const
1124   {
1125     return mWmsParameters[ QgsWmsParameter::FI_POLYGON_TOLERANCE ].toString();
1126   }
1127 
lineTolerance() const1128   QString QgsWmsParameters::lineTolerance() const
1129   {
1130     return mWmsParameters[ QgsWmsParameter::FI_LINE_TOLERANCE ].toString();
1131   }
1132 
pointTolerance() const1133   QString QgsWmsParameters::pointTolerance() const
1134   {
1135     return mWmsParameters[ QgsWmsParameter::FI_POINT_TOLERANCE ].toString();
1136   }
1137 
polygonToleranceAsInt() const1138   int QgsWmsParameters::polygonToleranceAsInt() const
1139   {
1140     return mWmsParameters[ QgsWmsParameter::FI_POLYGON_TOLERANCE ].toInt();
1141   }
1142 
lineToleranceAsInt() const1143   int QgsWmsParameters::lineToleranceAsInt() const
1144   {
1145     return mWmsParameters[ QgsWmsParameter::FI_LINE_TOLERANCE ].toInt();
1146   }
1147 
pointToleranceAsInt() const1148   int QgsWmsParameters::pointToleranceAsInt() const
1149   {
1150     return mWmsParameters[ QgsWmsParameter::FI_POINT_TOLERANCE ].toInt();
1151   }
1152 
itemFontBoldAsBool() const1153   bool QgsWmsParameters::itemFontBoldAsBool() const
1154   {
1155     return mWmsParameters[ QgsWmsParameter::ITEMFONTBOLD ].toBool();
1156   }
1157 
layerFontItalic() const1158   QString QgsWmsParameters::layerFontItalic() const
1159   {
1160     return mWmsParameters[ QgsWmsParameter::LAYERFONTITALIC ].toString();
1161   }
1162 
layerFontItalicAsBool() const1163   bool QgsWmsParameters::layerFontItalicAsBool() const
1164   {
1165     return mWmsParameters[ QgsWmsParameter::LAYERFONTITALIC ].toBool();
1166   }
1167 
itemFontItalic() const1168   QString QgsWmsParameters::itemFontItalic() const
1169   {
1170     return mWmsParameters[ QgsWmsParameter::ITEMFONTITALIC ].toString();
1171   }
1172 
itemFontItalicAsBool() const1173   bool QgsWmsParameters::itemFontItalicAsBool() const
1174   {
1175     return mWmsParameters[ QgsWmsParameter::ITEMFONTITALIC ].toBool();
1176   }
1177 
layerFontSize() const1178   QString QgsWmsParameters::layerFontSize() const
1179   {
1180     return mWmsParameters[ QgsWmsParameter::LAYERFONTSIZE ].toString();
1181   }
1182 
layerFontSizeAsDouble() const1183   double QgsWmsParameters::layerFontSizeAsDouble() const
1184   {
1185     return mWmsParameters[ QgsWmsParameter::LAYERFONTSIZE ].toDouble();
1186   }
1187 
layerFontColor() const1188   QString QgsWmsParameters::layerFontColor() const
1189   {
1190     return mWmsParameters[ QgsWmsParameter::LAYERFONTCOLOR ].toString();
1191   }
1192 
layerFontColorAsColor() const1193   QColor QgsWmsParameters::layerFontColorAsColor() const
1194   {
1195     return mWmsParameters[ QgsWmsParameter::LAYERFONTCOLOR ].toColor();
1196   }
1197 
itemFontSize() const1198   QString QgsWmsParameters::itemFontSize() const
1199   {
1200     return mWmsParameters[ QgsWmsParameter::ITEMFONTSIZE ].toString();
1201   }
1202 
itemFontSizeAsDouble() const1203   double QgsWmsParameters::itemFontSizeAsDouble() const
1204   {
1205     return mWmsParameters[ QgsWmsParameter::ITEMFONTSIZE ].toDouble();
1206   }
1207 
itemFontColor() const1208   QString QgsWmsParameters::itemFontColor() const
1209   {
1210     return mWmsParameters[ QgsWmsParameter::ITEMFONTCOLOR ].toString();
1211   }
1212 
itemFontColorAsColor() const1213   QColor QgsWmsParameters::itemFontColorAsColor() const
1214   {
1215     return mWmsParameters[ QgsWmsParameter::ITEMFONTCOLOR ].toColor();
1216   }
1217 
layerFont() const1218   QFont QgsWmsParameters::layerFont() const
1219   {
1220     QFont font;
1221     font.fromString( "" );
1222     font.setBold( layerFontBoldAsBool() );
1223     font.setItalic( layerFontItalicAsBool() );
1224 
1225     if ( ! layerFontSize().isEmpty() )
1226       font.setPointSizeF( layerFontSizeAsDouble() );
1227 
1228     if ( !layerFontFamily().isEmpty() )
1229       font.setFamily( layerFontFamily() );
1230 
1231     return font;
1232   }
1233 
itemFont() const1234   QFont QgsWmsParameters::itemFont() const
1235   {
1236     QFont font;
1237     font.fromString( "" );
1238 
1239     font.setBold( itemFontBoldAsBool() );
1240     font.setItalic( itemFontItalicAsBool() );
1241 
1242     if ( ! itemFontSize().isEmpty() )
1243       font.setPointSizeF( itemFontSizeAsDouble() );
1244 
1245     if ( !itemFontFamily().isEmpty() )
1246       font.setFamily( itemFontFamily() );
1247 
1248     return font;
1249   }
1250 
layerTitle() const1251   QString QgsWmsParameters::layerTitle() const
1252   {
1253     return mWmsParameters[ QgsWmsParameter::LAYERTITLE ].toString();
1254   }
1255 
layerTitleAsBool() const1256   bool QgsWmsParameters::layerTitleAsBool() const
1257   {
1258     return mWmsParameters[ QgsWmsParameter::LAYERTITLE ].toBool();
1259   }
1260 
legendSettings() const1261   QgsLegendSettings QgsWmsParameters::legendSettings() const
1262   {
1263     QgsLegendSettings settings;
1264     settings.setTitle( QString() );
1265     settings.setBoxSpace( boxSpaceAsDouble() );
1266     settings.setSymbolSize( QSizeF( symbolWidthAsDouble(), symbolHeightAsDouble() ) );
1267 
1268     settings.rstyle( QgsLegendStyle::Style::Subgroup ).setMargin( QgsLegendStyle::Side::Top, layerSpaceAsDouble() );
1269     settings.rstyle( QgsLegendStyle::Style::Subgroup ).setMargin( QgsLegendStyle::Side::Bottom, layerTitleSpaceAsDouble() );
1270     settings.rstyle( QgsLegendStyle::Style::Subgroup ).setFont( layerFont() );
1271 
1272     if ( !itemFontColor().isEmpty() )
1273     {
1274       settings.setFontColor( itemFontColorAsColor() );
1275     }
1276 
1277     // Ok, this is tricky: because QgsLegendSettings's layerFontColor was added to the API after
1278     // fontColor, to fix regressions #21871 and #21870 and the previous behavior was to use fontColor
1279     // for the whole legend we need to preserve that behavior.
1280     // But, the 2.18 server parameters ITEMFONTCOLOR did not have effect on the layer titles too, so
1281     // we set explicitly layerFontColor to black if it's not overridden by LAYERFONTCOLOR argument.
1282     settings.setLayerFontColor( layerFontColor().isEmpty() ? QColor( Qt::black ) : layerFontColorAsColor() );
1283 
1284     settings.rstyle( QgsLegendStyle::Style::SymbolLabel ).setFont( itemFont() );
1285     settings.rstyle( QgsLegendStyle::Style::Symbol ).setMargin( QgsLegendStyle::Side::Top, symbolSpaceAsDouble() );
1286     settings.rstyle( QgsLegendStyle::Style::SymbolLabel ).setMargin( QgsLegendStyle::Side::Left, iconLabelSpaceAsDouble() );
1287 
1288     return settings;
1289   }
1290 
layoutParameter(const QString & id,bool & ok) const1291   QString QgsWmsParameters::layoutParameter( const QString &id, bool &ok ) const
1292   {
1293     QString label;
1294     ok = false;
1295 
1296     if ( mUnmanagedParameters.contains( id.toUpper() ) )
1297     {
1298       label = mUnmanagedParameters[id.toUpper()];
1299       ok = true;
1300     }
1301 
1302     return label;
1303   }
1304 
atlasPk() const1305   QStringList QgsWmsParameters::atlasPk() const
1306   {
1307     return mWmsParameters[ QgsWmsParameter::ATLAS_PK ].toStringList();
1308   }
1309 
highlightLabelString() const1310   QStringList QgsWmsParameters::highlightLabelString() const
1311   {
1312     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELSTRING ].toStringList( ';' );
1313   }
1314 
highlightLabelSize() const1315   QStringList QgsWmsParameters::highlightLabelSize() const
1316   {
1317     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELSIZE ].toStringList( ';' );
1318   }
1319 
highlightLabelSizeAsInt() const1320   QList<int> QgsWmsParameters::highlightLabelSizeAsInt() const
1321   {
1322     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELSIZE ].toIntList( ';' );
1323   }
1324 
highlightLabelColor() const1325   QStringList QgsWmsParameters::highlightLabelColor() const
1326   {
1327     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELCOLOR ].toStringList( ';' );
1328   }
1329 
highlightLabelColorAsColor() const1330   QList<QColor> QgsWmsParameters::highlightLabelColorAsColor() const
1331   {
1332     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELCOLOR ].toColorList( ';' );
1333   }
1334 
highlightLabelWeight() const1335   QStringList QgsWmsParameters::highlightLabelWeight() const
1336   {
1337     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELWEIGHT ].toStringList( ';' );
1338   }
1339 
highlightLabelWeightAsInt() const1340   QList<int> QgsWmsParameters::highlightLabelWeightAsInt() const
1341   {
1342     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELWEIGHT ].toIntList( ';' );
1343   }
1344 
highlightLabelFont() const1345   QStringList QgsWmsParameters::highlightLabelFont() const
1346   {
1347     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELFONT ].toStringList( ';' );
1348   }
1349 
highlightLabelBufferColor() const1350   QStringList QgsWmsParameters::highlightLabelBufferColor() const
1351   {
1352     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELBUFFERCOLOR ].toStringList( ';' );
1353   }
1354 
highlightLabelBufferColorAsColor() const1355   QList<QColor> QgsWmsParameters::highlightLabelBufferColorAsColor() const
1356   {
1357     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELBUFFERCOLOR ].toColorList( ';' );
1358   }
1359 
highlightLabelBufferSize() const1360   QStringList QgsWmsParameters::highlightLabelBufferSize() const
1361   {
1362     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELBUFFERSIZE ].toStringList( ';' );
1363   }
1364 
highlightLabelBufferSizeAsFloat() const1365   QList<double> QgsWmsParameters::highlightLabelBufferSizeAsFloat() const
1366   {
1367     return mWmsParameters[ QgsWmsParameter::HIGHLIGHT_LABELBUFFERSIZE ].toDoubleList( ';' );
1368   }
1369 
wmsPrecision() const1370   QString QgsWmsParameters::wmsPrecision() const
1371   {
1372     return mWmsParameters[ QgsWmsParameter::WMS_PRECISION ].toString();
1373   }
1374 
wmsPrecisionAsInt() const1375   int QgsWmsParameters::wmsPrecisionAsInt() const
1376   {
1377     return mWmsParameters[ QgsWmsParameter::WMS_PRECISION ].toInt();
1378   }
1379 
sldBody() const1380   QString QgsWmsParameters::sldBody() const
1381   {
1382     return mWmsParameters[ QgsWmsParameter::SLD_BODY ].toString();
1383   }
1384 
filters() const1385   QStringList QgsWmsParameters::filters() const
1386   {
1387     const QString filter = mWmsParameters[ QgsWmsParameter::FILTER ].toString();
1388     QStringList results;
1389     int pos = 0;
1390     while ( pos < filter.size() )
1391     {
1392       if ( pos + 1 < filter.size() && filter[pos] == '(' && filter[pos + 1] == '<' )
1393       {
1394         // OGC filter on multiple layers
1395         int posEnd = filter.indexOf( "Filter>)", pos );
1396         if ( posEnd < 0 )
1397         {
1398           posEnd = filter.size();
1399         }
1400         results.append( filter.mid( pos + 1, posEnd - pos + 6 ) );
1401         pos = posEnd + 8;
1402       }
1403       else if ( pos + 1 < filter.size() && filter[pos] == '(' && filter[pos + 1] == ')' )
1404       {
1405         // empty OGC filter
1406         results.append( "" );
1407         pos += 2;
1408       }
1409       else if ( filter[pos] == '<' )
1410       {
1411         // Single OGC filter
1412         results.append( filter.mid( pos ) );
1413         break;
1414       }
1415       else
1416       {
1417         // QGIS specific filter
1418         int posEnd = filter.indexOf( ';', pos + 1 );
1419         if ( posEnd < 0 )
1420         {
1421           posEnd = filter.size();
1422         }
1423         results.append( filter.mid( pos, posEnd - pos ) );
1424         pos = posEnd + 1;
1425       }
1426     }
1427     return results;
1428   }
1429 
filterGeom() const1430   QString QgsWmsParameters::filterGeom() const
1431   {
1432     return mWmsParameters[ QgsWmsParameter::FILTER_GEOM ].toString();
1433   }
1434 
selections() const1435   QStringList QgsWmsParameters::selections() const
1436   {
1437     return mWmsParameters[ QgsWmsParameter::SELECTION ].toStringList( ';' );
1438   }
1439 
opacities() const1440   QStringList QgsWmsParameters::opacities() const
1441   {
1442     return mWmsParameters[ QgsWmsParameter::OPACITIES ].toStringList();
1443   }
1444 
opacitiesAsInt() const1445   QList<int> QgsWmsParameters::opacitiesAsInt() const
1446   {
1447     return mWmsParameters[ QgsWmsParameter::OPACITIES ].toIntList();
1448   }
1449 
allLayersNickname() const1450   QStringList QgsWmsParameters::allLayersNickname() const
1451   {
1452     QStringList layer = mWmsParameters[ QgsWmsParameter::LAYER ].toStringList();
1453     const QStringList layers = mWmsParameters[ QgsWmsParameter::LAYERS ].toStringList();
1454     return layer << layers;
1455   }
1456 
queryLayersNickname() const1457   QStringList QgsWmsParameters::queryLayersNickname() const
1458   {
1459     return mWmsParameters[ QgsWmsParameter::QUERY_LAYERS ].toStringList();
1460   }
1461 
allStyles() const1462   QStringList QgsWmsParameters::allStyles() const
1463   {
1464     QStringList style = mWmsParameters[ QgsWmsParameter::STYLE ].toStyleList();
1465     const QStringList styles = mWmsParameters[ QgsWmsParameter::STYLES ].toStyleList();
1466     return style << styles;
1467   }
1468 
layerFilters(const QStringList & layers) const1469   QMultiMap<QString, QgsWmsParametersFilter> QgsWmsParameters::layerFilters( const QStringList &layers ) const
1470   {
1471     const QString nsWfs2 = QStringLiteral( "http://www.opengis.net/fes/2.0" );
1472     const QString prefixWfs2 = QStringLiteral( "<fes:" );
1473 
1474     const QStringList rawFilters = filters();
1475     QMultiMap<QString, QgsWmsParametersFilter> filters;
1476     for ( int i = 0; i < rawFilters.size(); i++ )
1477     {
1478       const QString f = rawFilters[i];
1479       if ( f.startsWith( QLatin1Char( '<' ) ) \
1480            && f.endsWith( QLatin1String( "Filter>" ) ) \
1481            &&  i < layers.size() )
1482       {
1483         QgsWmsParametersFilter filter;
1484         filter.mFilter = f;
1485         filter.mType = QgsWmsParametersFilter::OGC_FE;
1486         filter.mVersion = QgsOgcUtils::FILTER_OGC_1_0;
1487 
1488         if ( filter.mFilter.contains( nsWfs2 ) \
1489              || filter.mFilter.contains( prefixWfs2 ) )
1490         {
1491           filter.mVersion = QgsOgcUtils::FILTER_FES_2_0;
1492         }
1493 
1494         filters.insert( layers[i], filter );
1495       }
1496       else if ( !f.isEmpty() )
1497       {
1498         // filter format: "LayerName,LayerName2:filterString;LayerName3:filterString2;..."
1499         // several filters can be defined for one layer
1500         const int colonIndex = f.indexOf( ':' );
1501         if ( colonIndex != -1 )
1502         {
1503           const QString layers = f.section( ':', 0, 0 );
1504           const QString filter = f.section( ':', 1 );
1505           const QStringList layersList = layers.split( ',' );
1506           for ( const QString &layer : layersList )
1507           {
1508             QgsWmsParametersFilter parametersFilter;
1509             parametersFilter.mFilter = filter;
1510             parametersFilter.mType = QgsWmsParametersFilter::SQL;
1511             filters.insert( layer, parametersFilter );
1512           }
1513         }
1514         else
1515         {
1516           QString filterStr = mWmsParameters[ QgsWmsParameter::FILTER ].toString();
1517           raiseError( QStringLiteral( "FILTER ('" ) + filterStr + QStringLiteral( "') is not properly formatted" ) );
1518         }
1519       }
1520     }
1521     return filters;
1522   }
1523 
isForce2D() const1524   bool QgsWmsParameters::isForce2D() const
1525   {
1526     bool force2D = false;
1527     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
1528 
1529     if ( options.contains( DxfFormatOption::FORCE_2D ) )
1530     {
1531       force2D = QVariant( options[ DxfFormatOption::FORCE_2D ] ).toBool();
1532     }
1533 
1534     return force2D;
1535   }
1536 
noMText() const1537   bool QgsWmsParameters::noMText() const
1538   {
1539     bool noMText = false;
1540     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
1541 
1542     if ( options.contains( DxfFormatOption::NO_MTEXT ) )
1543     {
1544       noMText = QVariant( options[ DxfFormatOption::NO_MTEXT ] ).toBool();
1545     }
1546 
1547     return noMText;
1548   }
1549 
layersParameters() const1550   QList<QgsWmsParametersLayer> QgsWmsParameters::layersParameters() const
1551   {
1552     const QStringList layers = allLayersNickname();
1553     const QStringList styles = allStyles();
1554     const QStringList selection = selections();
1555     const QList<int> opacities = opacitiesAsInt();
1556     const QMultiMap<QString, QgsWmsParametersFilter> filters = layerFilters( layers );
1557 
1558     // selection format: "LayerName:id0,id1;LayerName2:id0,id1;..."
1559     // several filters can be defined for one layer
1560     QMultiMap<QString, QString> layerSelections;
1561     for ( const QString &s : selection )
1562     {
1563       const QStringList splits = s.split( ':' );
1564       if ( splits.size() == 2 )
1565       {
1566         layerSelections.insert( splits[0], splits[1] );
1567       }
1568       else
1569       {
1570         QString selStr = mWmsParameters[ QgsWmsParameter::SELECTION ].toString();
1571         raiseError( QStringLiteral( "SELECTION ('" ) + selStr + QStringLiteral( "') is not properly formatted" ) );
1572       }
1573     }
1574 
1575     QList<QgsWmsParametersLayer> parameters;
1576     for ( int i = 0; i < layers.size(); i++ )
1577     {
1578       QString layer = layers[i];
1579 
1580       QgsWmsParametersLayer param;
1581       param.mNickname = layer;
1582 
1583       if ( i < opacities.count() )
1584         param.mOpacity = opacities[i];
1585 
1586       if ( isExternalLayer( layer ) )
1587       {
1588         const QgsWmsParametersExternalLayer extParam = externalLayerParameter( layer );
1589         param.mNickname = extParam.mName;
1590         param.mExternalUri = extParam.mUri;
1591       }
1592       else
1593       {
1594         if ( i < styles.count() )
1595           param.mStyle = styles[i];
1596 
1597         if ( filters.contains( layer ) )
1598         {
1599           auto it = filters.find( layer );
1600           while ( it != filters.end() && it.key() == layer )
1601           {
1602             param.mFilter.append( it.value() );
1603             ++it;
1604           }
1605         }
1606 
1607         if ( layerSelections.contains( layer ) )
1608         {
1609           QMultiMap<QString, QString>::const_iterator it;
1610           it = layerSelections.constFind( layer );
1611           while ( it != layerSelections.constEnd() && it.key() == layer )
1612           {
1613             param.mSelection << it.value().split( ',' );
1614             ++it;
1615           }
1616         }
1617       }
1618 
1619       parameters.append( param );
1620     }
1621 
1622     return parameters;
1623   }
1624 
highlightLayersParameters() const1625   QList<QgsWmsParametersHighlightLayer> QgsWmsParameters::highlightLayersParameters() const
1626   {
1627     QList<QgsWmsParametersHighlightLayer> params;
1628     QList<QgsGeometry> geoms = highlightGeomAsGeom();
1629     QStringList slds = highlightSymbol();
1630     QStringList labels = highlightLabelString();
1631     QList<QColor> colors = highlightLabelColorAsColor();
1632     QList<int> sizes = highlightLabelSizeAsInt();
1633     QList<int> weights = highlightLabelWeightAsInt();
1634     QStringList fonts = highlightLabelFont();
1635     QList<QColor> bufferColors = highlightLabelBufferColorAsColor();
1636     QList<double> bufferSizes = highlightLabelBufferSizeAsFloat();
1637 
1638     int nLayers = std::min( geoms.size(), slds.size() );
1639     for ( int i = 0; i < nLayers; i++ )
1640     {
1641       QgsWmsParametersHighlightLayer param;
1642       param.mName = QStringLiteral( "highlight_" ) + QString::number( i );
1643       param.mGeom = geoms[i];
1644       param.mSld = slds[i];
1645 
1646       if ( i < labels.count() )
1647         param.mLabel = labels[i];
1648 
1649       if ( i < colors.count() )
1650         param.mColor = colors[i];
1651 
1652       if ( i < sizes.count() )
1653         param.mSize = sizes[i];
1654 
1655       if ( i < weights.count() )
1656         param.mWeight = weights[i];
1657 
1658       if ( i < fonts.count() )
1659         param.mFont = fonts[ i ];
1660 
1661       if ( i < bufferColors.count() )
1662         param.mBufferColor = bufferColors[i];
1663 
1664       if ( i < bufferSizes.count() )
1665         param.mBufferSize = bufferSizes[i];
1666 
1667       params.append( param );
1668     }
1669 
1670     return params;
1671   }
1672 
externalLayersParameters() const1673   QList<QgsWmsParametersExternalLayer> QgsWmsParameters::externalLayersParameters() const
1674   {
1675     auto notExternalLayer = []( const QString & name ) { return ! QgsWmsParameters::isExternalLayer( name ); };
1676 
1677     QList<QgsWmsParametersExternalLayer> externalLayers;
1678 
1679     QStringList layers = allLayersNickname();
1680     QStringList::iterator rit = std::remove_if( layers.begin(), layers.end(), notExternalLayer );
1681 
1682     for ( QStringList::iterator it = layers.begin(); it != rit; ++it )
1683     {
1684       externalLayers << externalLayerParameter( *it );
1685     }
1686 
1687     return externalLayers;
1688   }
1689 
backgroundColor() const1690   QString QgsWmsParameters::backgroundColor() const
1691   {
1692     return mWmsParameters[ QgsWmsParameter::BGCOLOR ].toString();
1693   }
1694 
backgroundColorAsColor() const1695   QColor QgsWmsParameters::backgroundColorAsColor() const
1696   {
1697     return mWmsParameters[ QgsWmsParameter::BGCOLOR ].toColor();
1698   }
1699 
composerTemplate() const1700   QString QgsWmsParameters::composerTemplate() const
1701   {
1702     return mWmsParameters[ QgsWmsParameter::TEMPLATE ].toString();
1703   }
1704 
composerMapParameters(const int mapId) const1705   QgsWmsParametersComposerMap QgsWmsParameters::composerMapParameters( const int mapId ) const
1706   {
1707     QgsWmsParameter wmsParam;
1708     QgsWmsParametersComposerMap param;
1709     param.mId = mapId;
1710 
1711     //map extent is mandatory
1712     QString extentStr;
1713     wmsParam = idParameter( QgsWmsParameter::EXTENT, mapId );
1714     if ( wmsParam.isValid() )
1715     {
1716       extentStr = wmsParam.toString();
1717     }
1718 
1719     if ( extentStr.isEmpty() )
1720     {
1721       return param;
1722     }
1723 
1724     QString pMapId = QStringLiteral( "MAP" ) + QString::number( mapId );
1725 
1726     wmsParam = idParameter( QgsWmsParameter::EXTENT, mapId );
1727     QgsRectangle extent;
1728     if ( wmsParam.isValid() )
1729     {
1730       extent = wmsParam.toRectangle();
1731     }
1732 
1733     if ( extent.isEmpty() )
1734       return param;
1735 
1736     param.mHasExtent = !extent.isEmpty();
1737     param.mExtent = extent;
1738 
1739     // scale
1740     wmsParam = idParameter( QgsWmsParameter::SCALE, mapId );
1741     if ( wmsParam.isValid() && !wmsParam.toString().isEmpty() )
1742     {
1743       param.mScale = wmsParam.toDouble();
1744     }
1745 
1746     // rotation
1747     wmsParam = idParameter( QgsWmsParameter::ROTATION, mapId );
1748     if ( wmsParam.isValid() && !wmsParam.toString().isEmpty() )
1749     {
1750       param.mRotation = wmsParam.toDouble();
1751     }
1752 
1753     //grid space x / y
1754     double gridx( -1 ), gridy( -1 );
1755 
1756     wmsParam = idParameter( QgsWmsParameter::GRID_INTERVAL_X, mapId );
1757     if ( wmsParam.isValid() && !wmsParam.toString().isEmpty() )
1758     {
1759       gridx = wmsParam.toDouble();
1760     }
1761 
1762     wmsParam = idParameter( QgsWmsParameter::GRID_INTERVAL_Y, mapId );
1763     if ( wmsParam.isValid() && !wmsParam.toString().isEmpty() )
1764     {
1765       gridy = wmsParam.toDouble();
1766     }
1767 
1768     if ( gridx != -1 && gridy != -1 )
1769     {
1770       param.mGridX = gridx;
1771       param.mGridY = gridy;
1772     }
1773 
1774     //layers
1775     QStringList allLayers;
1776     wmsParam = idParameter( QgsWmsParameter::LAYERS, mapId );
1777     if ( wmsParam.isValid() )
1778     {
1779       allLayers = wmsParam.toStringList();
1780     }
1781 
1782     // external layers
1783     QStringList layers;
1784     QList<QgsWmsParametersExternalLayer> eParams;
1785 
1786     for ( const auto &layer : std::as_const( allLayers ) )
1787     {
1788       if ( isExternalLayer( layer ) )
1789       {
1790         const QgsWmsParametersExternalLayer extParam = externalLayerParameter( layer );
1791         layers << extParam.mName;
1792       }
1793       else
1794       {
1795         layers << layer;
1796       }
1797     }
1798 
1799     QStringList styles;
1800     wmsParam = idParameter( QgsWmsParameter::STYLES, mapId );
1801     if ( wmsParam.isValid() )
1802     {
1803       styles = wmsParam.toStyleList();
1804     }
1805 
1806     QList<QgsWmsParametersLayer> lParams;
1807     for ( int i = 0; i < layers.size(); i++ )
1808     {
1809       QString layer = layers[i];
1810       QgsWmsParametersLayer lParam;
1811       lParam.mNickname = layer;
1812 
1813       if ( i < styles.count() )
1814         lParam.mStyle = styles[i];
1815 
1816       lParams.append( lParam );
1817     }
1818     param.mLayers = lParams;
1819 
1820     //highlight layers
1821     QList<QgsWmsParametersHighlightLayer> hParams;
1822 
1823     QList<QgsGeometry> geoms;
1824     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_GEOM, mapId );
1825     if ( wmsParam.isValid() )
1826     {
1827       geoms = wmsParam.toGeomList( ';' );
1828     }
1829 
1830     QStringList slds;
1831     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_SYMBOL, mapId );
1832     if ( wmsParam.isValid() )
1833     {
1834       slds = wmsParam.toStringList( ';' );
1835     }
1836 
1837     QStringList labels;
1838     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELSTRING, mapId );
1839     if ( wmsParam.isValid() )
1840     {
1841       labels = wmsParam.toStringList( ';' );
1842     }
1843 
1844     QStringList fonts;
1845     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELFONT, mapId );
1846     if ( wmsParam.isValid() )
1847     {
1848       fonts = wmsParam.toStringList( ';' );
1849     }
1850 
1851     QList<QColor> colors;
1852     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELCOLOR, mapId );
1853     if ( wmsParam.isValid() )
1854     {
1855       colors = wmsParam.toColorList( ';' );
1856     }
1857 
1858     QList<int> sizes;
1859     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELSIZE, mapId );
1860     if ( wmsParam.isValid() )
1861     {
1862       sizes = wmsParam.toIntList( ';' );
1863     }
1864 
1865     QList<int> weights;
1866     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELWEIGHT, mapId );
1867     if ( wmsParam.isValid() )
1868     {
1869       weights = wmsParam.toIntList( ';' );
1870     }
1871 
1872     QList<QColor> bufferColors;
1873     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELBUFFERCOLOR, mapId );
1874     if ( wmsParam.isValid() )
1875     {
1876       bufferColors = wmsParam.toColorList( ';' );
1877     }
1878 
1879     QList<double> bufferSizes;
1880     wmsParam = idParameter( QgsWmsParameter::HIGHLIGHT_LABELBUFFERSIZE, mapId );
1881     if ( wmsParam.isValid() )
1882     {
1883       bufferSizes = wmsParam.toDoubleList( ';' );
1884     }
1885 
1886     int nHLayers = std::min( geoms.size(), slds.size() );
1887     for ( int i = 0; i < nHLayers; i++ )
1888     {
1889       QgsWmsParametersHighlightLayer hParam;
1890       hParam.mName = pMapId + QStringLiteral( "_highlight_" ) + QString::number( i );
1891       hParam.mGeom = geoms[i];
1892       hParam.mSld = slds[i];
1893 
1894       if ( i < labels.count() )
1895         hParam.mLabel = labels[i];
1896 
1897       if ( i < colors.count() )
1898         hParam.mColor = colors[i];
1899 
1900       if ( i < sizes.count() )
1901         hParam.mSize = sizes[i];
1902 
1903       if ( i < weights.count() )
1904         hParam.mWeight = weights[i];
1905 
1906       if ( i < fonts.count() )
1907         hParam.mFont = fonts[ i ];
1908 
1909       if ( i < bufferColors.count() )
1910         hParam.mBufferColor = bufferColors[i];
1911 
1912       if ( i < bufferSizes.count() )
1913         hParam.mBufferSize = bufferSizes[i];
1914 
1915       hParams.append( hParam );
1916     }
1917     param.mHighlightLayers = hParams;
1918 
1919     return param;
1920   }
1921 
externalWMSUri(const QString & id) const1922   QString QgsWmsParameters::externalWMSUri( const QString &id ) const
1923   {
1924     if ( !mExternalWMSParameters.contains( id ) )
1925     {
1926       return QString();
1927     }
1928 
1929     QgsDataSourceUri wmsUri;
1930     const QMap<QString, QString> &paramMap = mExternalWMSParameters[ id ];
1931     QMap<QString, QString>::const_iterator paramIt = paramMap.constBegin();
1932     for ( ; paramIt != paramMap.constEnd(); ++paramIt )
1933     {
1934       QString paramName = paramIt.key().toLower();
1935       if ( paramName == QLatin1String( "layers" ) || paramName == QLatin1String( "styles" ) || paramName == QLatin1String( "opacities" ) )
1936       {
1937         const QStringList values = paramIt.value().split( ',' );
1938         for ( const QString &value : values )
1939           wmsUri.setParam( paramName, value );
1940       }
1941       else
1942       {
1943         wmsUri.setParam( paramName, paramIt.value() );
1944       }
1945     }
1946     return wmsUri.encodedUri();
1947   }
1948 
withGeometry() const1949   bool QgsWmsParameters::withGeometry() const
1950   {
1951     return mWmsParameters[ QgsWmsParameter::WITH_GEOMETRY ].toBool();
1952   }
1953 
withMapTip() const1954   bool QgsWmsParameters::withMapTip() const
1955   {
1956     return mWmsParameters[ QgsWmsParameter::WITH_MAPTIP ].toBool();
1957   }
1958 
wmtver() const1959   QString QgsWmsParameters::wmtver() const
1960   {
1961     return mWmsParameters[ QgsWmsParameter::WMTVER ].toString();
1962   }
1963 
log(const QString & msg) const1964   void QgsWmsParameters::log( const QString &msg ) const
1965   {
1966     QgsMessageLog::logMessage( msg, QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
1967   }
1968 
raiseError(const QString & msg) const1969   void QgsWmsParameters::raiseError( const QString &msg ) const
1970   {
1971     throw QgsBadRequestException( QgsServiceException::QGIS_InvalidParameterValue, msg );
1972   }
1973 
idParameter(const QgsWmsParameter::Name name,const int id) const1974   QgsWmsParameter QgsWmsParameters::idParameter( const QgsWmsParameter::Name name, const int id ) const
1975   {
1976     QgsWmsParameter p;
1977 
1978     for ( const auto &param : mWmsParameters.values( name ) )
1979     {
1980       if ( param.mId == id )
1981       {
1982         p = param;
1983       }
1984     }
1985 
1986     return p;
1987   }
1988 
externalLayerParameter(const QString & name) const1989   QgsWmsParametersExternalLayer QgsWmsParameters::externalLayerParameter( const QString &name ) const
1990   {
1991     QgsWmsParametersExternalLayer param;
1992 
1993     param.mName = name;
1994     param.mName.remove( 0, EXTERNAL_LAYER_PREFIX.size() );
1995     param.mUri = externalWMSUri( param.mName );
1996 
1997     return param;
1998   }
1999 
isExternalLayer(const QString & name)2000   bool QgsWmsParameters::isExternalLayer( const QString &name )
2001   {
2002     return name.startsWith( EXTERNAL_LAYER_PREFIX );
2003   }
2004 
dxfLayerAttributes() const2005   QStringList QgsWmsParameters::dxfLayerAttributes() const
2006   {
2007     QStringList attributes;
2008     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
2009 
2010     if ( options.contains( DxfFormatOption::LAYERATTRIBUTES ) )
2011     {
2012       attributes = options[ DxfFormatOption::LAYERATTRIBUTES ].split( ',' );
2013     }
2014 
2015     return attributes;
2016   }
2017 
dxfUseLayerTitleAsName() const2018   bool QgsWmsParameters::dxfUseLayerTitleAsName() const
2019   {
2020     bool use = false;
2021     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
2022 
2023     if ( options.contains( DxfFormatOption::USE_TITLE_AS_LAYERNAME ) )
2024     {
2025       use = QVariant( options[ DxfFormatOption::USE_TITLE_AS_LAYERNAME ] ).toBool();
2026     }
2027 
2028     return use;
2029   }
2030 
dxfScale() const2031   double QgsWmsParameters::dxfScale() const
2032   {
2033     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
2034 
2035     double scale = -1;
2036     if ( options.contains( DxfFormatOption::SCALE ) )
2037     {
2038       scale = options[ DxfFormatOption::SCALE ].toDouble();
2039     }
2040 
2041     return scale;
2042   }
2043 
dxfMode() const2044   QgsDxfExport::SymbologyExport QgsWmsParameters::dxfMode() const
2045   {
2046     const QMap<DxfFormatOption, QString> options = dxfFormatOptions();
2047 
2048     QgsDxfExport::SymbologyExport symbol = QgsDxfExport::NoSymbology;
2049 
2050     if ( ! options.contains( DxfFormatOption::MODE ) )
2051     {
2052       return symbol;
2053     }
2054 
2055     const QString mode = options[ DxfFormatOption::MODE ];
2056     if ( mode.compare( QLatin1String( "SymbolLayerSymbology" ), Qt::CaseInsensitive ) == 0 )
2057     {
2058       symbol = QgsDxfExport::SymbolLayerSymbology;
2059     }
2060     else if ( mode.compare( QLatin1String( "FeatureSymbology" ), Qt::CaseInsensitive ) == 0 )
2061     {
2062       symbol = QgsDxfExport::FeatureSymbology;
2063     }
2064 
2065     return symbol;
2066   }
2067 
dxfCodec() const2068   QString QgsWmsParameters::dxfCodec() const
2069   {
2070     QString codec = QStringLiteral( "ISO-8859-1" );
2071 
2072     if ( dxfFormatOptions().contains( DxfFormatOption::CODEC ) )
2073     {
2074       codec = dxfFormatOptions()[ DxfFormatOption::CODEC ];
2075     }
2076 
2077     return codec;
2078   }
2079 
dxfFormatOptions() const2080   QMap<QgsWmsParameters::DxfFormatOption, QString> QgsWmsParameters::dxfFormatOptions() const
2081   {
2082     QMap<QgsWmsParameters::DxfFormatOption, QString> options;
2083 
2084     const QMetaEnum metaEnum( QMetaEnum::fromType<QgsWmsParameters::DxfFormatOption>() );
2085     const QStringList opts = mWmsParameters[ QgsWmsParameter::FORMAT_OPTIONS ].toStringList( ';' );
2086 
2087     for ( auto it = opts.constBegin(); it != opts.constEnd(); ++it )
2088     {
2089       const int equalIdx = it->indexOf( ':' );
2090       if ( equalIdx > 0 && equalIdx < ( it->length() - 1 ) )
2091       {
2092         const QString name = it->left( equalIdx ).toUpper();
2093         const QgsWmsParameters::DxfFormatOption option =
2094           ( QgsWmsParameters::DxfFormatOption ) metaEnum.keyToValue( name.toStdString().c_str() );
2095         const QString value = it->right( it->length() - equalIdx - 1 );
2096         options.insert( option, value );
2097       }
2098     }
2099 
2100     return options;
2101   }
2102 
dimensionValues() const2103   QMap<QString, QString> QgsWmsParameters::dimensionValues() const
2104   {
2105     QMap<QString, QString> dimValues;
2106     const QMetaEnum pnMetaEnum( QMetaEnum::fromType<QgsMapLayerServerProperties::PredefinedWmsDimensionName>() );
2107     const QStringList unmanagedNames = mUnmanagedParameters.keys();
2108     for ( const QString &key : unmanagedNames )
2109     {
2110       if ( key.startsWith( QLatin1String( "DIM_" ) ) )
2111       {
2112         dimValues[key.mid( 4 )] = mUnmanagedParameters[key];
2113       }
2114       else if ( pnMetaEnum.keyToValue( key.toUpper().toStdString().c_str() ) != -1 )
2115       {
2116         dimValues[key] = mUnmanagedParameters[key];
2117       }
2118     }
2119     return dimValues;
2120   }
2121 }
2122