Small cleanups in WMS renderer

This commit is contained in:
Blottiere Paul 2017-07-31 10:07:37 +01:00
parent 5c82a856bf
commit 3ebad9a119
4 changed files with 210 additions and 84 deletions

View File

@ -69,9 +69,7 @@ bool QgsProjectVersion::operator!=( const QgsProjectVersion &other ) const
bool QgsProjectVersion::operator>=( const QgsProjectVersion &other ) const
{
return ( ( mMajor >= other.mMajor ) ||
( ( mMajor == other.mMajor ) && ( mMinor >= other.mMinor ) ) ||
( ( mMajor == other.mMajor ) && ( mMinor == other.mMinor ) && ( mSub >= other.mSub ) ) );
return ( *this == other ) || ( *this > other );
}
bool QgsProjectVersion::operator>( const QgsProjectVersion &other ) const

View File

@ -23,6 +23,11 @@ namespace QgsWms
{
QgsWmsParameters::QgsWmsParameters()
{
// Available version number
mVersions.append( QgsProjectVersion( 1, 1, 1 ) );
mVersions.append( QgsProjectVersion( 1, 3, 0 ) );
// WMS parameters definition
const Parameter pBoxSpace = { ParameterName::BOXSPACE,
QVariant::Double,
QVariant( 2.0 ),
@ -184,6 +189,13 @@ namespace QgsWms
};
save( pCRS );
const Parameter pSRS = { ParameterName::SRS,
QVariant::String,
QVariant( "" ),
QVariant()
};
save( pSRS );
const Parameter pFormat = { ParameterName::FORMAT,
QVariant::String,
QVariant( "" ),
@ -393,6 +405,27 @@ namespace QgsWms
QVariant()
};
save( pWmsPrecision );
const Parameter pTransparent = { ParameterName::TRANSPARENT,
QVariant::Bool,
QVariant( false ),
QVariant()
};
save( pTransparent );
const Parameter pBgColor = { ParameterName::BGCOLOR,
QVariant::String,
QVariant( "white" ),
QVariant()
};
save( pBgColor );
const Parameter pDpi = { ParameterName::DPI,
QVariant::Int,
QVariant( -1 ),
QVariant()
};
save( pDpi );
}
QgsWmsParameters::QgsWmsParameters( const QgsServerRequest::Parameters &parameters )
@ -438,6 +471,9 @@ namespace QgsWms
log( " - " + name + " : " + value );
}
}
if ( !version().isEmpty() )
log( " - VERSION : " + version() );
}
void QgsWmsParameters::save( const Parameter &parameter )
@ -490,7 +526,25 @@ namespace QgsWms
QString QgsWmsParameters::crs() const
{
return value( ParameterName::CRS ).toString();
QString rs;
QString srs = value( ParameterName::SRS ).toString();
QString crs = value( ParameterName::CRS ).toString();
// both SRS/CRS are supported but there's a priority according to the
// specified version when both are defined in the request
if ( !srs.isEmpty() && crs.isEmpty() )
rs = srs;
else if ( srs.isEmpty() && !crs.isEmpty() )
rs = crs;
else if ( !srs.isEmpty() && !crs.isEmpty() )
{
if ( versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
rs = crs;
else
rs = srs;
}
return rs;
}
QString QgsWmsParameters::bbox() const
@ -552,6 +606,39 @@ namespace QgsWms
return toInt( ParameterName::WIDTH );
}
QString QgsWmsParameters::dpi() const
{
return value( ParameterName::DPI ).toString();
}
int QgsWmsParameters::dpiAsInt() const
{
return toInt( ParameterName::DPI );
}
QString QgsWmsParameters::version() const
{
// VERSION parameter is not managed with other parameters because
// there's a conflict with qgis VERSION defined in qgsconfig.h
if ( mRequestParameters.contains( "VERSION" ) )
return mRequestParameters["VERSION"];
else
return QString();
}
QgsProjectVersion QgsWmsParameters::versionAsNumber() const
{
QString vStr = version();
QgsProjectVersion version;
if ( vStr.isEmpty() )
version = QgsProjectVersion( 1, 3, 0 ); // default value
else if ( mVersions.contains( QgsProjectVersion( vStr ) ) )
version = QgsProjectVersion( vStr );
return version;
}
double QgsWmsParameters::toDouble( ParameterName p ) const
{
double val = defaultValue( p ).toDouble();
@ -605,6 +692,31 @@ namespace QgsWms
return val;
}
QColor QgsWmsParameters::toColor( ParameterName p ) const
{
QColor c = defaultValue( p ).value<QColor>();
if ( !value( p ).toString().isEmpty() )
{
// support hexadecimal notation to define colors
QString cStr = value( p ).toString();
if ( cStr.startsWith( "0x", Qt::CaseInsensitive ) )
cStr.replace( 0, 2, "#" );
c = QColor( cStr );
if ( !c.isValid() )
{
QString val = value( p ).toString();
QString n = name( p );
QString msg = n + " ('" + val + "') cannot be converted into a color";
raiseError( msg );
}
}
return c;
}
QStringList QgsWmsParameters::toStringList( ParameterName name, char delimiter ) const
{
return value( name ).toString().split( delimiter, QString::SkipEmptyParts );
@ -795,6 +907,16 @@ namespace QgsWms
return toBool( ParameterName::RULELABEL );
}
QString QgsWmsParameters::transparent() const
{
return value( ParameterName::TRANSPARENT ).toString();
}
bool QgsWmsParameters::transparentAsBool() const
{
return toBool( ParameterName::TRANSPARENT );
}
QString QgsWmsParameters::scale() const
{
return value( ParameterName::SCALE ).toString();
@ -962,23 +1084,7 @@ namespace QgsWms
QColor QgsWmsParameters::layerFontColorAsColor() const
{
ParameterName p = ParameterName::LAYERFONTCOLOR;
QColor c = defaultValue( p ).value<QColor>();
if ( !layerFontColor().isEmpty() )
{
c = QColor( layerFontColor() );
if ( !c.isValid() )
{
QString val = value( p ).toString();
QString n = name( p );
QString msg = n + " ('" + val + "') cannot be converted into a color";
raiseError( msg );
}
}
return c;
return toColor( ParameterName::LAYERFONTCOLOR );
}
QString QgsWmsParameters::itemFontSize() const
@ -1301,6 +1407,16 @@ namespace QgsWms
return params;
}
QString QgsWmsParameters::backgroundColor() const
{
return value( ParameterName::BGCOLOR ).toString();
}
QColor QgsWmsParameters::backgroundColorAsColor() const
{
return toColor( ParameterName::BGCOLOR );
}
QString QgsWmsParameters::name( ParameterName name ) const
{
const QMetaEnum metaEnum( QMetaEnum::fromType<ParameterName>() );

View File

@ -22,11 +22,13 @@
#include <QObject>
#include <QMetaEnum>
#include <QColor>
#include "qgsrectangle.h"
#include "qgswmsserviceexception.h"
#include "qgsserverrequest.h"
#include "qgslegendsettings.h"
#include "qgsgeometry.h"
#include "qgsprojectversion.h"
/** QgsWmsParameters provides an interface to retrieve and manipulate WMS
* parameters received from the client.
@ -66,7 +68,7 @@ namespace QgsWms
{
BOXSPACE,
CRS, // instead of SRS for WMS 1.3.0
// SRS, // for WMS 1.1.1
SRS, // for WMS 1.1.1
WIDTH,
HEIGHT,
BBOX,
@ -117,7 +119,10 @@ namespace QgsWms
HIGHLIGHT_LABELCOLOR,
HIGHLIGHT_LABELBUFFERCOLOR,
HIGHLIGHT_LABELBUFFERSIZE,
WMS_PRECISION
WMS_PRECISION,
TRANSPARENT,
BGCOLOR,
DPI
};
Q_ENUM( ParameterName )
@ -189,6 +194,17 @@ namespace QgsWms
*/
int heightAsInt() const;
/** Returns VERSION parameter as a string or an empty string if not
* defined.
* \returns version
*/
QString version() const;
/** Returns VERSION parameter if defined or its default value.
* \returns version
*/
QgsProjectVersion versionAsNumber() const;
/** Returns BBOX if defined or an empty string.
* \returns bbox parameter
*/
@ -712,6 +728,45 @@ namespace QgsWms
*/
int wmsPrecisionAsInt() const;
/** Returns TRANSPARENT parameter or an empty string if not defined.
* \returns TRANSPARENT parameter
*/
QString transparent() const;
/** Returns TRANSPARENT parameter as a bool or its default value if not
* defined. An exception is raised if TRANSPARENT is defined and cannot
* be converted.
* \returns transparent parameter
* \throws QgsBadRequestException
*/
bool transparentAsBool() const;
/** Returns BGCOLOR parameter or an empty string if not defined.
* \returns BGCOLOR parameter
*/
QString backgroundColor() const;
/** Returns BGCOLOR parameter as a QColor or its default value if not
* defined. An exception is raised if BGCOLOR is defined and cannot
* be converted.
* \returns background color parameter
* \throws QgsBadRequestException
*/
QColor backgroundColorAsColor() const;
/** Returns DPI parameter or an empty string if not defined.
* \returns DPI parameter
*/
QString dpi() const;
/** Returns DPI parameter as an int or its default value if not
* defined. An exception is raised if DPI is defined and cannot
* be converted.
* \returns dpi parameter
* \throws QgsBadRequestException
*/
int dpiAsInt() const;
private:
QString name( ParameterName name ) const;
void raiseError( ParameterName name ) const;
@ -724,6 +779,7 @@ namespace QgsWms
double toDouble( ParameterName name ) const;
bool toBool( ParameterName name ) const;
int toInt( ParameterName name ) const;
QColor toColor( ParameterName name ) const;
QStringList toStringList( ParameterName name, char delimiter = ',' ) const;
QList<int> toIntList( QStringList l, ParameterName name ) const;
QList<float> toFloatList( QStringList l, ParameterName name ) const;
@ -731,6 +787,7 @@ namespace QgsWms
QgsServerRequest::Parameters mRequestParameters;
QMap<ParameterName, Parameter> mParameters;
QList<QgsProjectVersion> mVersions;
};
}

View File

@ -809,8 +809,6 @@ namespace QgsWms
QImage *QgsRenderer::createImage( int width, int height, bool useBbox ) const
{
bool conversionSuccess;
if ( width < 0 )
width = mWmsParameters.widthAsInt();
@ -819,8 +817,7 @@ namespace QgsWms
//Adapt width / height if the aspect ratio does not correspond with the BBOX.
//Required by WMS spec. 1.3.
QString version = mParameters.value( QStringLiteral( "VERSION" ), QStringLiteral( "1.3.0" ) );
if ( useBbox && version != QLatin1String( "1.1.1" ) )
if ( useBbox && mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
{
QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
if ( !mWmsParameters.bbox().isEmpty() && mapExtent.isEmpty() )
@ -829,7 +826,7 @@ namespace QgsWms
QStringLiteral( "Invalid BBOX parameter" ) );
}
QString crs = mParameters.value( QStringLiteral( "CRS" ), mParameters.value( QStringLiteral( "SRS" ) ) );
QString crs = mWmsParameters.crs();
if ( crs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
{
crs = QString( "EPSG:4326" );
@ -861,31 +858,11 @@ namespace QgsWms
QImage *image = nullptr;
//Define the image background color in case of map settings is not used
//is format jpeg?
QString format = mParameters.value( QStringLiteral( "FORMAT" ) );
bool jpeg = format.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
|| format.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
|| format.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0;
// use alpha channel only if necessary because it slows down performance
QgsWmsParameters::Format format = mWmsParameters.format();
bool transparent = mWmsParameters.transparentAsBool();
//transparent parameter
bool transparent = mParameters.value( QStringLiteral( "TRANSPARENT" ) ).compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
//background color
QString bgColorString = mParameters.value( "BGCOLOR" );
if ( bgColorString.startsWith( "0x", Qt::CaseInsensitive ) )
{
bgColorString.replace( 0, 2, "#" );
}
QColor backgroundColor;
backgroundColor.setNamedColor( bgColorString );
if ( !backgroundColor.isValid() )
{
backgroundColor = QColor( Qt::white );
}
//use alpha channel only if necessary because it slows down performance
if ( transparent && !jpeg )
if ( transparent && format != QgsWmsParameters::JPG )
{
image = new QImage( width, height, QImage::Format_ARGB32_Premultiplied );
image->fill( 0 );
@ -893,21 +870,16 @@ namespace QgsWms
else
{
image = new QImage( width, height, QImage::Format_RGB32 );
image->fill( backgroundColor );
image->fill( mWmsParameters.backgroundColorAsColor() );
}
//apply DPI parameter if present. This is an extension of Qgis Mapserver compared to WMS 1.3.
//Because of backwards compatibility, this parameter is optional
double OGC_PX_M = 0.00028; // OGC reference pixel size in meter, also used by qgis
int dpm = 1 / OGC_PX_M;
if ( mParameters.contains( QStringLiteral( "DPI" ) ) )
{
int dpi = mParameters[ QStringLiteral( "DPI" )].toInt( &conversionSuccess );
if ( conversionSuccess )
{
dpm = dpi / 0.0254;
}
}
if ( !mWmsParameters.dpi().isEmpty() )
dpm = mWmsParameters.dpiAsInt() / 0.0254;
image->setDotsPerMeterX( dpm );
image->setDotsPerMeterY( dpm );
return image;
@ -931,7 +903,7 @@ namespace QgsWms
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Invalid BBOX parameter" ) );
}
QString crs = mParameters.value( QStringLiteral( "CRS" ), mParameters.value( QStringLiteral( "SRS" ) ) );
QString crs = mWmsParameters.crs();
if ( crs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
{
crs = QString( "EPSG:4326" );
@ -941,8 +913,6 @@ namespace QgsWms
QgsCoordinateReferenceSystem outputCRS;
//wms spec says that CRS parameter is mandatory.
//destination SRS
outputCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
if ( !outputCRS.isValid() )
{
@ -954,8 +924,7 @@ namespace QgsWms
mapSettings.setDestinationCrs( outputCRS );
// Change x- and y- of BBOX for WMS 1.3.0 if axis inverted
QString version = mParameters.value( QStringLiteral( "VERSION" ), QStringLiteral( "1.3.0" ) );
if ( version != QLatin1String( "1.1.1" ) && outputCRS.hasAxisInverted() )
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.hasAxisInverted() )
{
mapExtent.invert();
}
@ -965,26 +934,12 @@ namespace QgsWms
/* Define the background color
* Transparent or colored
*/
//is format jpeg?
QString format = mParameters.value( QStringLiteral( "FORMAT" ) );
bool jpeg = format.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
|| format.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
|| format.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0;
//transparent parameter
bool transparent = mParameters.value( QStringLiteral( "TRANSPARENT" ) ).compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
//background color
QString bgColorString = mParameters.value( "BGCOLOR" );
if ( bgColorString.startsWith( "0x", Qt::CaseInsensitive ) )
{
bgColorString.replace( 0, 2, "#" );
}
QColor backgroundColor;
backgroundColor.setNamedColor( bgColorString );
QgsWmsParameters::Format format = mWmsParameters.format();
bool transparent = mWmsParameters.transparentAsBool();
QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
//set background color
if ( transparent && !jpeg )
if ( transparent && format != QgsWmsParameters::JPG )
{
mapSettings.setBackgroundColor( QColor( 0, 0, 0, 0 ) );
}