Merge pull request #4699 from pblottiere/getlegendgraphic
[Server] WMS GetLegendGraphics refactoring
@ -21,24 +21,15 @@
|
||||
#include "qgsrasterrenderer.h"
|
||||
#include "qgsmaplayerstylemanager.h"
|
||||
|
||||
const QString DEFAULT_NAMED_STYLE = "server_default_style";
|
||||
|
||||
QgsLayerRestorer::QgsLayerRestorer( const QList<QgsMapLayer *> &layers )
|
||||
{
|
||||
Q_FOREACH ( QgsMapLayer *layer, layers )
|
||||
{
|
||||
QgsLayerSettings settings;
|
||||
settings.name = layer->name();
|
||||
|
||||
QString style = layer->styleManager()->currentStyle();
|
||||
if ( style.isEmpty() )
|
||||
{
|
||||
layer->styleManager()->addStyleFromLayer( DEFAULT_NAMED_STYLE );
|
||||
settings.mNamedStyle = DEFAULT_NAMED_STYLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.mNamedStyle = style;
|
||||
}
|
||||
settings.mNamedStyle = layer->styleManager()->currentStyle();
|
||||
|
||||
// set a custom property allowing to keep in memory if a SLD file has
|
||||
// been loaded for rendering
|
||||
@ -80,6 +71,7 @@ QgsLayerRestorer::~QgsLayerRestorer()
|
||||
{
|
||||
QgsLayerSettings settings = mLayerSettings[layer];
|
||||
layer->styleManager()->setCurrentStyle( settings.mNamedStyle );
|
||||
layer->setName( mLayerSettings[layer].name );
|
||||
|
||||
// if a SLD file has been loaded for rendering, we restore the previous one
|
||||
QString errMsg;
|
||||
|
@ -30,6 +30,7 @@ class QgsLayerRestorer
|
||||
{
|
||||
struct QgsLayerSettings
|
||||
{
|
||||
QString name;
|
||||
double mOpacity;
|
||||
QString mNamedStyle;
|
||||
QDomDocument mSldStyle;
|
||||
|
@ -23,6 +23,90 @@ namespace QgsWms
|
||||
{
|
||||
QgsWmsParameters::QgsWmsParameters()
|
||||
{
|
||||
const Parameter pBoxSpace = { ParameterName::BOXSPACE,
|
||||
QVariant::Double,
|
||||
QVariant( 2.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pBoxSpace );
|
||||
|
||||
const Parameter pSymbSpace = { ParameterName::SYMBOLSPACE,
|
||||
QVariant::Double,
|
||||
QVariant( 2.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pSymbSpace );
|
||||
|
||||
const Parameter pLayerSpace = { ParameterName::LAYERSPACE,
|
||||
QVariant::Double,
|
||||
QVariant( 3.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerSpace );
|
||||
|
||||
const Parameter pTitleSpace = { ParameterName::LAYERTITLESPACE,
|
||||
QVariant::Double,
|
||||
QVariant( 3.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pTitleSpace );
|
||||
|
||||
const Parameter pSymbHeight = { ParameterName::SYMBOLHEIGHT,
|
||||
QVariant::Double,
|
||||
QVariant( 4.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pSymbHeight );
|
||||
|
||||
const Parameter pSymbWidth = { ParameterName::SYMBOLWIDTH,
|
||||
QVariant::Double,
|
||||
QVariant( 7.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pSymbWidth );
|
||||
|
||||
const Parameter pIcLabelSpace = { ParameterName::ICONLABELSPACE,
|
||||
QVariant::Double,
|
||||
QVariant( 2.0 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pIcLabelSpace );
|
||||
|
||||
const Parameter pItFontFamily = { ParameterName::ITEMFONTFAMILY,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pItFontFamily );
|
||||
|
||||
const Parameter pItFontBold = { ParameterName::ITEMFONTBOLD,
|
||||
QVariant::Bool,
|
||||
QVariant( false ),
|
||||
QVariant()
|
||||
};
|
||||
save( pItFontBold );
|
||||
|
||||
const Parameter pItFontItalic = { ParameterName::ITEMFONTITALIC,
|
||||
QVariant::Bool,
|
||||
QVariant( false ),
|
||||
QVariant()
|
||||
};
|
||||
save( pItFontItalic );
|
||||
|
||||
const Parameter pItFontSize = { ParameterName::ITEMFONTSIZE,
|
||||
QVariant::Double,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pItFontSize );
|
||||
|
||||
const Parameter pItFontColor = { ParameterName::ITEMFONTCOLOR,
|
||||
QVariant::String,
|
||||
QVariant( "black" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pItFontColor );
|
||||
|
||||
const Parameter pHighlightGeom = { ParameterName::HIGHLIGHT_GEOM,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
@ -30,6 +114,13 @@ namespace QgsWms
|
||||
};
|
||||
save( pHighlightGeom );
|
||||
|
||||
const Parameter pShowFeatureCount = { ParameterName::SHOWFEATURECOUNT,
|
||||
QVariant::Bool,
|
||||
QVariant( false ),
|
||||
QVariant()
|
||||
};
|
||||
save( pShowFeatureCount );
|
||||
|
||||
const Parameter pHighlightSymbol = { ParameterName::HIGHLIGHT_SYMBOL,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
@ -46,7 +137,7 @@ namespace QgsWms
|
||||
|
||||
const Parameter pHighlightColor = { ParameterName::HIGHLIGHT_LABELCOLOR,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant( "black" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pHighlightColor );
|
||||
@ -74,7 +165,7 @@ namespace QgsWms
|
||||
|
||||
const Parameter pHighlightBufferColor = { ParameterName::HIGHLIGHT_LABELBUFFERCOLOR,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant( "black" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pHighlightBufferColor );
|
||||
@ -93,6 +184,34 @@ namespace QgsWms
|
||||
};
|
||||
save( pCRS );
|
||||
|
||||
const Parameter pFormat = { ParameterName::FORMAT,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pFormat );
|
||||
|
||||
const Parameter pRule = { ParameterName::RULE,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pRule );
|
||||
|
||||
const Parameter pRuleLabel = { ParameterName::RULELABEL,
|
||||
QVariant::Bool,
|
||||
QVariant( true ),
|
||||
QVariant()
|
||||
};
|
||||
save( pRuleLabel );
|
||||
|
||||
const Parameter pScale = { ParameterName::SCALE,
|
||||
QVariant::Double,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pScale );
|
||||
|
||||
const Parameter pHeight = { ParameterName::HEIGHT,
|
||||
QVariant::Int,
|
||||
QVariant( 0 ),
|
||||
@ -135,6 +254,48 @@ namespace QgsWms
|
||||
};
|
||||
save( pLayers );
|
||||
|
||||
const Parameter pLayerTitle = { ParameterName::LAYERTITLE,
|
||||
QVariant::Bool,
|
||||
QVariant( true ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerTitle );
|
||||
|
||||
const Parameter pLayerFtFamily = { ParameterName::LAYERFONTFAMILY,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerFtFamily );
|
||||
|
||||
const Parameter pLayerFtBold = { ParameterName::LAYERFONTBOLD,
|
||||
QVariant::Bool,
|
||||
QVariant( false ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerFtBold );
|
||||
|
||||
const Parameter pLayerFtItalic = { ParameterName::LAYERFONTITALIC,
|
||||
QVariant::Bool,
|
||||
QVariant( false ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerFtItalic );
|
||||
|
||||
const Parameter pLayerFtSize = { ParameterName::LAYERFONTSIZE,
|
||||
QVariant::Double,
|
||||
QVariant( -1 ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerFtSize );
|
||||
|
||||
const Parameter pLayerFtColor = { ParameterName::LAYERFONTCOLOR,
|
||||
QVariant::String,
|
||||
QVariant( "black" ),
|
||||
QVariant()
|
||||
};
|
||||
save( pLayerFtColor );
|
||||
|
||||
const Parameter pStyle = { ParameterName::STYLE,
|
||||
QVariant::String,
|
||||
QVariant( "" ),
|
||||
@ -226,6 +387,11 @@ namespace QgsWms
|
||||
return mParameters[name].mValue;
|
||||
}
|
||||
|
||||
QVariant QgsWmsParameters::defaultValue( ParameterName name ) const
|
||||
{
|
||||
return mParameters[name].mDefaultValue;
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::highlightGeom() const
|
||||
{
|
||||
return toStringList( ParameterName::HIGHLIGHT_GEOM, ';' );
|
||||
@ -303,26 +469,77 @@ namespace QgsWms
|
||||
return extent;
|
||||
}
|
||||
|
||||
int QgsWmsParameters::height() const
|
||||
QString QgsWmsParameters::height() const
|
||||
{
|
||||
bool ok = false;
|
||||
int height = value( ParameterName::HEIGHT ).toInt( &ok );
|
||||
|
||||
if ( ! ok )
|
||||
raiseError( ParameterName::HEIGHT );
|
||||
|
||||
return height;
|
||||
return value( ParameterName::HEIGHT ).toString();
|
||||
}
|
||||
|
||||
int QgsWmsParameters::width() const
|
||||
QString QgsWmsParameters::width() const
|
||||
{
|
||||
bool ok = false;
|
||||
int width = value( ParameterName::WIDTH ).toInt( &ok );
|
||||
return value( ParameterName::WIDTH ).toString();
|
||||
}
|
||||
|
||||
if ( ! ok )
|
||||
raiseError( ParameterName::WIDTH );
|
||||
int QgsWmsParameters::heightAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::HEIGHT );
|
||||
}
|
||||
|
||||
return width;
|
||||
int QgsWmsParameters::widthAsInt() const
|
||||
{
|
||||
return toInt( ParameterName::WIDTH );
|
||||
}
|
||||
|
||||
double QgsWmsParameters::toDouble( ParameterName p ) const
|
||||
{
|
||||
double val = defaultValue( p ).toDouble();
|
||||
QString valStr = value( p ).toString();
|
||||
|
||||
if ( ! valStr.isEmpty() )
|
||||
{
|
||||
bool ok;
|
||||
val = value( p ).toDouble( &ok );
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
QString n = name( p );
|
||||
QString msg = n + " ('" + valStr + "') cannot be converted into a double";
|
||||
raiseError( msg );
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::toBool( ParameterName p ) const
|
||||
{
|
||||
bool val = defaultValue( p ).toBool();
|
||||
QString valStr = value( p ).toString();
|
||||
|
||||
if ( ! valStr.isEmpty() )
|
||||
val = value( p ).toBool();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int QgsWmsParameters::toInt( ParameterName p ) const
|
||||
{
|
||||
int val = defaultValue( p ).toInt();
|
||||
QString valStr = value( p ).toString();
|
||||
|
||||
if ( ! valStr.isEmpty() )
|
||||
{
|
||||
bool ok;
|
||||
val = value( p ).toInt( &ok );
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
QString n = name( p );
|
||||
QString msg = n + " ('" + valStr + "') cannot be converted into int";
|
||||
raiseError( msg );
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::toStringList( ParameterName name, char delimiter ) const
|
||||
@ -404,6 +621,285 @@ namespace QgsWms
|
||||
return elements;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::formatAsString() const
|
||||
{
|
||||
return value( ParameterName::FORMAT ).toString();
|
||||
}
|
||||
|
||||
QgsWmsParameters::Format QgsWmsParameters::format() const
|
||||
{
|
||||
Format f = Format::PNG;
|
||||
QString fStr = formatAsString();
|
||||
|
||||
if ( fStr.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0
|
||||
|| fStr.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0
|
||||
|| fStr.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 )
|
||||
f = Format::JPG;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::rule() const
|
||||
{
|
||||
return value( ParameterName::RULE ).toString();
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::ruleLabel() const
|
||||
{
|
||||
return value( ParameterName::RULELABEL ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::ruleLabelAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::RULELABEL );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::scale() const
|
||||
{
|
||||
return value( ParameterName::SCALE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::scaleAsDouble() const
|
||||
{
|
||||
return toDouble( ParameterName::SCALE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::showFeatureCount() const
|
||||
{
|
||||
return value( ParameterName::SHOWFEATURECOUNT ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::showFeatureCountAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::SHOWFEATURECOUNT );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::boxSpace() const
|
||||
{
|
||||
return value( ParameterName::BOXSPACE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::boxSpaceAsDouble() const
|
||||
{
|
||||
return toDouble( ParameterName::BOXSPACE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerSpace() const
|
||||
{
|
||||
return value( ParameterName::LAYERSPACE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::layerSpaceAsDouble() const
|
||||
{
|
||||
return toDouble( ParameterName::LAYERSPACE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerTitleSpace() const
|
||||
{
|
||||
return value( ParameterName::LAYERTITLESPACE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::layerTitleSpaceAsDouble() const
|
||||
{
|
||||
return toDouble( ParameterName::LAYERTITLESPACE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::symbolSpace() const
|
||||
{
|
||||
return value( ParameterName::SYMBOLSPACE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::symbolSpaceAsDouble() const
|
||||
{
|
||||
return toDouble( ParameterName::SYMBOLSPACE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::symbolHeight() const
|
||||
{
|
||||
return value( ParameterName::SYMBOLHEIGHT ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::symbolHeightAsDouble() const
|
||||
{
|
||||
return toDouble( SYMBOLHEIGHT );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::symbolWidth() const
|
||||
{
|
||||
return value( ParameterName::SYMBOLWIDTH ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::symbolWidthAsDouble() const
|
||||
{
|
||||
return toDouble( SYMBOLWIDTH );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::iconLabelSpace() const
|
||||
{
|
||||
return value( ParameterName::ICONLABELSPACE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::iconLabelSpaceAsDouble() const
|
||||
{
|
||||
return toDouble( ICONLABELSPACE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerFontFamily() const
|
||||
{
|
||||
return value( ParameterName::LAYERFONTFAMILY ).toString();
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::itemFontFamily() const
|
||||
{
|
||||
return value( ParameterName::ITEMFONTFAMILY ).toString();
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerFontBold() const
|
||||
{
|
||||
return value( ParameterName::LAYERFONTBOLD ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::layerFontBoldAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::LAYERFONTBOLD );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::itemFontBold() const
|
||||
{
|
||||
return value( ParameterName::ITEMFONTBOLD ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::itemFontBoldAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::ITEMFONTBOLD );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerFontItalic() const
|
||||
{
|
||||
return value( ParameterName::LAYERFONTITALIC ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::layerFontItalicAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::LAYERFONTITALIC );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::itemFontItalic() const
|
||||
{
|
||||
return value( ParameterName::ITEMFONTITALIC ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::itemFontItalicAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::ITEMFONTITALIC );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerFontSize() const
|
||||
{
|
||||
return value( ParameterName::LAYERFONTSIZE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::layerFontSizeAsDouble() const
|
||||
{
|
||||
return toDouble( LAYERFONTSIZE );
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerFontColor() const
|
||||
{
|
||||
return value( ParameterName::LAYERFONTCOLOR ).toString();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::itemFontSize() const
|
||||
{
|
||||
return value( ParameterName::ITEMFONTSIZE ).toString();
|
||||
}
|
||||
|
||||
double QgsWmsParameters::itemFontSizeAsDouble() const
|
||||
{
|
||||
return toDouble( ITEMFONTSIZE );
|
||||
}
|
||||
|
||||
QFont QgsWmsParameters::layerFont() const
|
||||
{
|
||||
QFont font;
|
||||
font.fromString( "" );
|
||||
font.setBold( layerFontBoldAsBool() );
|
||||
font.setItalic( layerFontItalicAsBool() );
|
||||
|
||||
if ( ! layerFontSize().isEmpty() )
|
||||
font.setPointSizeF( layerFontSizeAsDouble() );
|
||||
|
||||
if ( !layerFontFamily().isEmpty() )
|
||||
font.setFamily( layerFontFamily() );
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
QFont QgsWmsParameters::itemFont() const
|
||||
{
|
||||
QFont font;
|
||||
font.fromString( "" );
|
||||
|
||||
font.setBold( itemFontBoldAsBool() );
|
||||
font.setItalic( itemFontItalicAsBool() );
|
||||
|
||||
if ( ! itemFontSize().isEmpty() )
|
||||
font.setPointSizeF( itemFontSizeAsDouble() );
|
||||
|
||||
if ( !itemFontFamily().isEmpty() )
|
||||
font.setFamily( itemFontFamily() );
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
QString QgsWmsParameters::layerTitle() const
|
||||
{
|
||||
return value( ParameterName::LAYERTITLE ).toString();
|
||||
}
|
||||
|
||||
bool QgsWmsParameters::layerTitleAsBool() const
|
||||
{
|
||||
return toBool( ParameterName::LAYERTITLE );
|
||||
}
|
||||
|
||||
QgsLegendSettings QgsWmsParameters::legendSettings() const
|
||||
{
|
||||
QgsLegendSettings settings;
|
||||
settings.setTitle( QString() );
|
||||
settings.setBoxSpace( boxSpaceAsDouble() );
|
||||
settings.setSymbolSize( QSizeF( symbolWidthAsDouble(), symbolHeightAsDouble() ) );
|
||||
|
||||
settings.rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, layerSpaceAsDouble() );
|
||||
settings.rstyle( QgsLegendStyle::Subgroup ).setFont( layerFont() );
|
||||
|
||||
settings.rstyle( QgsLegendStyle::SymbolLabel ).setFont( itemFont() );
|
||||
settings.rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, symbolSpaceAsDouble() );
|
||||
settings.rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Left, iconLabelSpaceAsDouble() );
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
QStringList QgsWmsParameters::highlightLabelString() const
|
||||
{
|
||||
return toStringList( ParameterName::HIGHLIGHT_LABELSTRING, ';' );
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgswmsserviceexception.h"
|
||||
#include "qgsserverrequest.h"
|
||||
#include "qgslegendsettings.h"
|
||||
#include "qgsgeometry.h"
|
||||
|
||||
/** QgsWmsParameters provides an interface to retrieve and manipulate WMS
|
||||
@ -63,18 +64,41 @@ namespace QgsWms
|
||||
public:
|
||||
enum ParameterName
|
||||
{
|
||||
BOXSPACE,
|
||||
CRS, // instead of SRS for WMS 1.3.0
|
||||
// SRS, // for WMS 1.1.1
|
||||
WIDTH,
|
||||
HEIGHT,
|
||||
BBOX,
|
||||
ICONLABELSPACE,
|
||||
ITEMFONTFAMILY,
|
||||
ITEMFONTBOLD,
|
||||
ITEMFONTITALIC,
|
||||
ITEMFONTSIZE,
|
||||
ITEMFONTCOLOR,
|
||||
LAYER,
|
||||
LAYERFONTFAMILY,
|
||||
LAYERFONTBOLD,
|
||||
LAYERFONTITALIC,
|
||||
LAYERFONTSIZE,
|
||||
LAYERFONTCOLOR,
|
||||
LAYERTITLE,
|
||||
LAYERS,
|
||||
LAYERSPACE,
|
||||
LAYERTITLESPACE,
|
||||
SHOWFEATURECOUNT,
|
||||
STYLE,
|
||||
STYLES,
|
||||
SYMBOLSPACE,
|
||||
SYMBOLHEIGHT,
|
||||
SYMBOLWIDTH,
|
||||
OPACITIES,
|
||||
SLD,
|
||||
FILTER,
|
||||
FORMAT,
|
||||
RULE,
|
||||
RULELABEL,
|
||||
SCALE,
|
||||
SELECTION,
|
||||
HIGHLIGHT_GEOM,
|
||||
HIGHLIGHT_SYMBOL,
|
||||
@ -88,6 +112,13 @@ namespace QgsWms
|
||||
};
|
||||
Q_ENUM( ParameterName )
|
||||
|
||||
enum Format
|
||||
{
|
||||
NONE,
|
||||
JPG,
|
||||
PNG
|
||||
};
|
||||
|
||||
struct Parameter
|
||||
{
|
||||
ParameterName mName;
|
||||
@ -119,19 +150,31 @@ namespace QgsWms
|
||||
*/
|
||||
QString crs() const;
|
||||
|
||||
/** Returns WIDTH parameter as an int (0 if not defined). An exception is
|
||||
* raised if it cannot be converted.
|
||||
/** Returns WIDTH parameter or an empty string if not defined.
|
||||
* \returns width parameter
|
||||
*/
|
||||
QString width() const;
|
||||
|
||||
/** Returns WIDTH parameter as an int or its default value if not
|
||||
* defined. An exception is raised if WIDTH is defined and cannot be
|
||||
* converted.
|
||||
* \returns width parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int width() const;
|
||||
int widthAsInt() const;
|
||||
|
||||
/** Returns HEIGHT parameter as an int (0 if not defined). An exception
|
||||
* is raised if it cannot be converted.
|
||||
/** Returns HEIGHT parameter or an empty string if not defined.
|
||||
* \returns height parameter
|
||||
*/
|
||||
QString height() const;
|
||||
|
||||
/** Returns HEIGHT parameter as an int or its default value if not
|
||||
* defined. An exception is raised if HEIGHT is defined and cannot be
|
||||
* converted.
|
||||
* \returns height parameter
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
int height() const;
|
||||
int heightAsInt() const;
|
||||
|
||||
/** Returns BBOX if defined or an empty string.
|
||||
* \returns bbox parameter
|
||||
@ -188,6 +231,278 @@ namespace QgsWms
|
||||
*/
|
||||
QList<QgsWmsParametersLayer> layersParameters() const;
|
||||
|
||||
/** Returns FORMAT parameter as a string.
|
||||
* \returns FORMAT parameter as string
|
||||
*/
|
||||
QString formatAsString() const;
|
||||
|
||||
/** Returns format. If the FORMAT parameter is not used, then the
|
||||
* default value is PNG.
|
||||
* \returns format
|
||||
*/
|
||||
Format format() const;
|
||||
|
||||
/** Returns RULE parameter or an empty string if none is defined
|
||||
* \returns RULE parameter or an empty string if none is defined
|
||||
*/
|
||||
QString rule() const;
|
||||
|
||||
/** Returns RULELABEL parameter or an empty string if none is defined
|
||||
* \returns RULELABEL parameter or an empty string if none is defined
|
||||
*/
|
||||
QString ruleLabel() const;
|
||||
|
||||
/** Returns RULELABEL as a bool. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns ruleLabel
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool ruleLabelAsBool() const;
|
||||
|
||||
/** Returns SHOWFEATURECOUNT parameter or an empty string if none is defined
|
||||
* \returns SHOWFEATURECOUNT parameter or an empty string if none is defined
|
||||
*/
|
||||
QString showFeatureCount() const;
|
||||
|
||||
/** Returns SHOWFEATURECOUNT as a bool. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns showFeatureCount
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool showFeatureCountAsBool() const;
|
||||
|
||||
/** Returns SCALE parameter or an empty string if none is defined
|
||||
* \returns SCALE parameter or an empty string if none is defined
|
||||
*/
|
||||
QString scale() const;
|
||||
|
||||
/** Returns SCALE as a double. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns scale
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double scaleAsDouble() const;
|
||||
|
||||
/** Returns BOXSPACE parameter or an empty string if not defined.
|
||||
* \returns BOXSPACE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString boxSpace() const;
|
||||
|
||||
/** Returns BOXSPACE as a double or its default value if not defined.
|
||||
* An exception is raised if an invalid parameter is found.
|
||||
* \returns boxSpace
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double boxSpaceAsDouble() const;
|
||||
|
||||
/** Returns LAYERSPACE parameter or an empty string if not defined.
|
||||
* \returns LAYERSPACE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerSpace() const;
|
||||
|
||||
/** Returns LAYERSPACE as a double or its default value if not defined.
|
||||
* An exception is raised if an invalid parameter is found.
|
||||
* \returns layerSpace
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double layerSpaceAsDouble() const;
|
||||
|
||||
/** Returns LAYERTITLESPACE parameter or an empty string if not defined.
|
||||
* \returns LAYERTITLESPACE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerTitleSpace() const;
|
||||
|
||||
/** Returns LAYERTITLESPACE as a double. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns layerTitleSpace
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double layerTitleSpaceAsDouble() const;
|
||||
|
||||
/** Returns SYMBOLSPACE parameter or an empty string if not defined.
|
||||
* \returns SYMBOLSPACE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString symbolSpace() const;
|
||||
|
||||
/** Returns SYMBOLSPACE as a double or its default value if not defined.
|
||||
* An exception is raised if an invalid parameter is found.
|
||||
* \returns symbolSpace
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double symbolSpaceAsDouble() const;
|
||||
|
||||
/** Returns ICONLABELSPACE parameter or an empty string if not defined.
|
||||
* \returns ICONLABELSPACE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString iconLabelSpace() const;
|
||||
|
||||
/** Returns ICONLABELSPACE as a double or its default value if not
|
||||
* defined. An exception is raised if an invalid parameter is found.
|
||||
* \returns iconLabelSpace
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double iconLabelSpaceAsDouble() const;
|
||||
|
||||
/** Returns SYMBOLWIDTH parameter or an empty string if not defined.
|
||||
* \returns SYMBOLWIDTH parameter or an empty string if not defined.
|
||||
*/
|
||||
QString symbolWidth() const;
|
||||
|
||||
/** Returns SYMBOLWIDTH as a double or its default value if not defined.
|
||||
* An exception is raised if an invalid parameter is found.
|
||||
* \returns symbolWidth
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double symbolWidthAsDouble() const;
|
||||
|
||||
/** Returns SYMBOLHEIGHT parameter or an empty string if not defined.
|
||||
* \returns SYMBOLHEIGHT parameter or an empty string if not defined.
|
||||
*/
|
||||
QString symbolHeight() const;
|
||||
|
||||
/** Returns SYMBOLHEIGHT as a double or its default value if not defined.
|
||||
* An exception is raised if an invalid parameter is found.
|
||||
* \returns symbolHeight
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double symbolHeightAsDouble() const;
|
||||
|
||||
/** Returns the layer font (built thanks to the LAYERFONTFAMILY,
|
||||
* LAYERFONTSIZE, LAYERFONTBOLD, ... parameters).
|
||||
* \returns layerFont
|
||||
*/
|
||||
QFont layerFont() const;
|
||||
|
||||
/** Returns LAYERFONTFAMILY parameter or an empty string if not defined.
|
||||
* \returns LAYERFONTFAMILY parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerFontFamily() const;
|
||||
|
||||
/** Returns LAYERFONTBOLD parameter or an empty string if not defined.
|
||||
* \returns LAYERFONTBOLD parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerFontBold() const;
|
||||
|
||||
/** Returns LAYERFONTBOLD as a boolean or its default value if not
|
||||
* defined. An exception is raised if an
|
||||
* invalid parameter is found.
|
||||
* \returns layerFontBold
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool layerFontBoldAsBool() const;
|
||||
|
||||
/** Returns LAYERFONTITALIC parameter or an empty string if not defined.
|
||||
* \returns LAYERFONTITALIC parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerFontItalic() const;
|
||||
|
||||
/** Returns LAYERFONTITALIC as a boolean or its default value if not
|
||||
* defined. An exception is raised if an invalid parameter is found.
|
||||
* \returns layerFontItalic
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool layerFontItalicAsBool() const;
|
||||
|
||||
/** Returns LAYERFONTSIZE parameter or an empty string if not defined.
|
||||
* \returns LAYERFONTSIZE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerFontSize() const;
|
||||
|
||||
/** Returns LAYERFONTSIZE as a double. An exception is raised if an invalid
|
||||
* parameter is found.
|
||||
* \returns layerFontSize
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double layerFontSizeAsDouble() const;
|
||||
|
||||
/** Returns LAYERFONTCOLOR parameter or an empty string if not defined.
|
||||
* \returns LAYERFONTCOLOR parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerFontColor() const;
|
||||
|
||||
/** Returns LAYERFONTCOLOR as a color or its defined value if not
|
||||
* defined. An exception is raised if an invalid parameter is found.
|
||||
* \returns layerFontColor
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
QColor layerFontColorAsColor() const;
|
||||
|
||||
/** Returns the item font (built thanks to the ITEMFONTFAMILY,
|
||||
* ITEMFONTSIZE, ITEMFONTBOLD, ... parameters).
|
||||
* \returns itemFont
|
||||
*/
|
||||
QFont itemFont() const;
|
||||
|
||||
/** Returns ITEMFONTFAMILY parameter or an empty string if not defined.
|
||||
* \returns ITEMFONTFAMILY parameter or an empty string if not defined.
|
||||
*/
|
||||
QString itemFontFamily() const;
|
||||
|
||||
/** Returns ITEMFONTBOLD parameter or an empty string if not defined.
|
||||
* \returns ITEMFONTBOLD parameter or an empty string if not defined.
|
||||
*/
|
||||
QString itemFontBold() const;
|
||||
|
||||
/** Returns ITEMFONTBOLD as a boolean or its default value if not
|
||||
* defined. An exception is raised if an invalid parameter is found.
|
||||
* \returns itemFontBold
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool itemFontBoldAsBool() const;
|
||||
|
||||
/** Returns ITEMFONTITALIC parameter or an empty string if not defined.
|
||||
* \returns ITEMFONTITALIC parameter or an empty string if not defined.
|
||||
*/
|
||||
QString itemFontItalic() const;
|
||||
|
||||
/** Returns ITEMFONTITALIC as a boolean or its default value if not
|
||||
* defined. An exception is raised if an invalid parameter is found.
|
||||
* \returns itemFontItalic
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool itemFontItalicAsBool() const;
|
||||
|
||||
/** Returns ITEMFONTSIZE parameter or an empty string if not defined.
|
||||
* \returns ITEMFONTSIZE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString itemFontSize() const;
|
||||
|
||||
/** Returns ITEMFONTSIZE as a double. An exception is raised if an
|
||||
* invalid parameter is found.
|
||||
* \returns itemFontSize
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
double itemFontSizeAsDouble() const;
|
||||
|
||||
/** Returns ITEMFONTCOLOR parameter or an empty string if not defined.
|
||||
* \returns ITEMFONTCOLOR parameter or an empty string if not defined.
|
||||
*/
|
||||
QString itemFontColor() const;
|
||||
|
||||
/** Returns ITEMFONTCOLOR as a color. An exception is raised if an
|
||||
* invalid parameter is found.
|
||||
* \returns itemFontColor
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
QColor itemFontColorAsColor() const;
|
||||
|
||||
/** Returns LAYERTITLE parameter or an empty string if not defined.
|
||||
* \returns LAYERTITLE parameter or an empty string if not defined.
|
||||
*/
|
||||
QString layerTitle() const;
|
||||
|
||||
/** Returns LAYERTITLE as a bool or its default value if not defined. An
|
||||
* exception is raised if an invalid parameter is found.
|
||||
* \returns layerTitle
|
||||
* \throws QgsBadRequestException
|
||||
*/
|
||||
bool layerTitleAsBool() const;
|
||||
|
||||
/** Returns legend settings
|
||||
* \returns legend settings
|
||||
*/
|
||||
QgsLegendSettings legendSettings() const;
|
||||
|
||||
/** Returns parameters for each highlight layer.
|
||||
* \returns parameters for each highlight layer
|
||||
*/
|
||||
@ -286,8 +601,12 @@ namespace QgsWms
|
||||
void raiseError( const QString &msg ) const;
|
||||
void initParameters();
|
||||
QVariant value( ParameterName name ) const;
|
||||
QVariant defaultValue( ParameterName name ) const;
|
||||
void log( const QString &msg ) const;
|
||||
void save( const Parameter ¶meter );
|
||||
double toDouble( ParameterName name ) const;
|
||||
bool toBool( ParameterName name ) const;
|
||||
int toInt( 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;
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgslayerrestorer.h"
|
||||
#include "qgsdxfexport.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
@ -111,8 +112,6 @@ namespace QgsWms
|
||||
QgsWmsConfigParser *parser )
|
||||
: mParameters( parameters )
|
||||
, mOwnsConfigParser( false )
|
||||
, mDrawLegendLayerLabel( true )
|
||||
, mDrawLegendItemLabel( true )
|
||||
, mConfigParser( parser )
|
||||
, mAccessControl( serverIface->accessControls() )
|
||||
, mSettings( *serverIface->serverSettings() )
|
||||
@ -138,290 +137,100 @@ namespace QgsWms
|
||||
|
||||
QImage *QgsRenderer::getLegendGraphics()
|
||||
{
|
||||
if ( !mConfigParser )
|
||||
{
|
||||
throw QgsException( QStringLiteral( "No config parser" ) );
|
||||
}
|
||||
if ( !mParameters.contains( QStringLiteral( "LAYER" ) ) && !mParameters.contains( QStringLiteral( "LAYERS" ) ) )
|
||||
{
|
||||
// check parameters
|
||||
if ( mWmsParameters.allLayersNickname().isEmpty() )
|
||||
throw QgsBadRequestException( QStringLiteral( "LayerNotSpecified" ),
|
||||
QStringLiteral( "LAYER is mandatory for GetLegendGraphic operation" ) );
|
||||
}
|
||||
if ( !mParameters.contains( QStringLiteral( "FORMAT" ) ) )
|
||||
{
|
||||
|
||||
if ( mWmsParameters.format() == QgsWmsParameters::Format::NONE )
|
||||
throw QgsBadRequestException( QStringLiteral( "FormatNotSpecified" ),
|
||||
QStringLiteral( "FORMAT is mandatory for GetLegendGraphic operation" ) );
|
||||
}
|
||||
|
||||
bool contentBasedLegend = false;
|
||||
QgsRectangle contentBasedLegendExtent;
|
||||
|
||||
if ( mParameters.contains( QStringLiteral( "BBOX" ) ) )
|
||||
{
|
||||
contentBasedLegend = true;
|
||||
|
||||
contentBasedLegendExtent = parseBbox( mParameters.value( QStringLiteral( "BBOX" ) ) );
|
||||
if ( contentBasedLegendExtent.isEmpty() )
|
||||
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ),
|
||||
QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
|
||||
if ( mParameters.contains( QStringLiteral( "RULE" ) ) )
|
||||
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ),
|
||||
QStringLiteral( "BBOX parameter cannot be combined with RULE" ) );
|
||||
}
|
||||
|
||||
QStringList layersList, stylesList;
|
||||
|
||||
readLayersAndStyles( mParameters, layersList, stylesList );
|
||||
|
||||
if ( layersList.isEmpty() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//scale
|
||||
double scaleDenominator = -1;
|
||||
QMap<QString, QString>::const_iterator scaleIt = mParameters.constFind( QStringLiteral( "SCALE" ) );
|
||||
if ( scaleIt != mParameters.constEnd() )
|
||||
{
|
||||
bool conversionSuccess;
|
||||
double scaleValue = scaleIt.value().toDouble( &conversionSuccess );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
scaleDenominator = scaleValue;
|
||||
}
|
||||
}
|
||||
if ( ! mWmsParameters.scale().isEmpty() )
|
||||
scaleDenominator = mWmsParameters.scaleAsDouble();
|
||||
|
||||
QgsCoordinateReferenceSystem dummyCRS;
|
||||
QStringList layerIds = layerSet( layersList, stylesList, dummyCRS, scaleDenominator );
|
||||
if ( layerIds.isEmpty() )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
QgsLegendSettings legendSettings = mWmsParameters.legendSettings();
|
||||
|
||||
//get icon size, spaces between legend items and font from config parser
|
||||
double boxSpace, layerSpace, layerTitleSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight;
|
||||
QFont layerFont, itemFont;
|
||||
QColor layerFontColor, itemFontColor;
|
||||
legendParameters( boxSpace, layerSpace, layerTitleSpace, symbolSpace,
|
||||
iconLabelSpace, symbolWidth, symbolHeight, layerFont, itemFont, layerFontColor, itemFontColor );
|
||||
// get layers
|
||||
std::unique_ptr<QgsLayerRestorer> restorer;
|
||||
restorer.reset( new QgsLayerRestorer( mNicknameLayers.values() ) );
|
||||
|
||||
QString rule;
|
||||
int ruleSymbolWidth = 0, ruleSymbolHeight = 0;
|
||||
QMap<QString, QString>::const_iterator ruleIt = mParameters.constFind( QStringLiteral( "RULE" ) );
|
||||
if ( ruleIt != mParameters.constEnd() )
|
||||
{
|
||||
rule = ruleIt.value();
|
||||
QList<QgsMapLayer *> layers;
|
||||
QList<QgsWmsParametersLayer> params = mWmsParameters.layersParameters();
|
||||
|
||||
QMap<QString, QString>::const_iterator widthIt = mParameters.constFind( QStringLiteral( "WIDTH" ) );
|
||||
if ( widthIt != mParameters.constEnd() )
|
||||
{
|
||||
bool conversionSuccess;
|
||||
double width = widthIt.value().toDouble( &conversionSuccess );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
ruleSymbolWidth = width;
|
||||
}
|
||||
}
|
||||
QString sld = mWmsParameters.sld();
|
||||
if ( !sld.isEmpty() )
|
||||
layers = sldStylizedLayers( sld );
|
||||
else
|
||||
layers = stylizedLayers( params );
|
||||
|
||||
QMap<QString, QString>::const_iterator heightIt = mParameters.constFind( QStringLiteral( "HEIGHT" ) );
|
||||
if ( heightIt != mParameters.constEnd() )
|
||||
{
|
||||
bool conversionSuccess;
|
||||
double width = heightIt.value().toDouble( &conversionSuccess );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
ruleSymbolHeight = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
removeUnwantedLayers( layers, scaleDenominator );
|
||||
std::reverse( layers.begin(), layers.end() );
|
||||
|
||||
// Checks showFeatureCount parameter
|
||||
bool showFeatureCount = false;
|
||||
if ( mParameters.contains( QStringLiteral( "SHOWFEATURECOUNT" ) ) )
|
||||
showFeatureCount = QVariant( mParameters[ QStringLiteral( "SHOWFEATURECOUNT" )] ).toBool();
|
||||
// check permissions
|
||||
Q_FOREACH ( QgsMapLayer *ml, layers )
|
||||
checkLayerReadPermissions( ml );
|
||||
|
||||
// Create the layer tree root
|
||||
// build layer tree model for legend
|
||||
QgsLayerTree rootGroup;
|
||||
// Store layers' name to reset them
|
||||
QMap<QString, QString> layerNameMap;
|
||||
// Create tree layer node for each layer
|
||||
Q_FOREACH ( const QString &layerId, layerIds )
|
||||
std::unique_ptr<QgsLayerTreeModel> legendModel;
|
||||
legendModel.reset( buildLegendTreeModel( layers, scaleDenominator, rootGroup ) );
|
||||
|
||||
// rendering step
|
||||
qreal dpmm = dotsPerMm();
|
||||
std::unique_ptr<QImage> image;
|
||||
std::unique_ptr<QPainter> painter;
|
||||
|
||||
if ( !mWmsParameters.rule().isEmpty() )
|
||||
{
|
||||
// get layer
|
||||
QgsMapLayer *ml = QgsProject::instance()->mapLayer( layerId );
|
||||
// create tree layer node
|
||||
QgsLayerTreeLayer *layer = rootGroup.addLayer( ml );
|
||||
// store the layer's name
|
||||
layerNameMap.insert( layerId, ml->name() );
|
||||
// set layer name with layer's title to have it in legend
|
||||
if ( !ml->title().isEmpty() )
|
||||
layer->setName( ml->title() );
|
||||
// set show feature count
|
||||
if ( showFeatureCount )
|
||||
layer->setCustomProperty( QStringLiteral( "showFeatureCount" ), showFeatureCount );
|
||||
}
|
||||
QgsLayerTreeModel legendModel( &rootGroup );
|
||||
QString rule = mWmsParameters.rule();
|
||||
int width = mWmsParameters.widthAsInt();
|
||||
int height = mWmsParameters.heightAsInt();
|
||||
|
||||
if ( scaleDenominator > 0 )
|
||||
legendModel.setLegendFilterByScale( scaleDenominator );
|
||||
image.reset( createImage( width, height, false ) );
|
||||
painter.reset( new QPainter( image.get() ) );
|
||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
||||
painter->scale( dpmm, dpmm );
|
||||
|
||||
QgsMapSettings contentBasedMapSettings;
|
||||
if ( contentBasedLegend )
|
||||
{
|
||||
HitTest hitTest;
|
||||
getMapOld( contentBasedMapSettings, &hitTest );
|
||||
|
||||
Q_FOREACH ( QgsLayerTreeNode *node, rootGroup.children() )
|
||||
{
|
||||
Q_ASSERT( QgsLayerTree::isLayer( node ) );
|
||||
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( nodeLayer->layer() );
|
||||
if ( !vl || !vl->renderer() )
|
||||
continue;
|
||||
|
||||
const SymbolSet &usedSymbols = hitTest[vl];
|
||||
QList<int> order;
|
||||
int i = 0;
|
||||
Q_FOREACH ( const QgsLegendSymbolItem &legendItem, vl->renderer()->legendSymbolItemsV2() )
|
||||
{
|
||||
if ( usedSymbols.contains( legendItem.legacyRuleKey() ) )
|
||||
order.append( i );
|
||||
++i;
|
||||
}
|
||||
|
||||
// either remove the whole layer or just filter out some items
|
||||
if ( order.isEmpty() )
|
||||
rootGroup.removeChildNode( nodeLayer );
|
||||
else
|
||||
{
|
||||
QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order );
|
||||
legendModel.refreshLayerLegend( nodeLayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find out DPI
|
||||
QImage *tmpImage = createImage( 1, 1, false );
|
||||
if ( !tmpImage )
|
||||
return nullptr;
|
||||
qreal dpmm = tmpImage->dotsPerMeterX() / 1000.0;
|
||||
delete tmpImage;
|
||||
|
||||
// setup legend configuration
|
||||
QgsLegendSettings legendSettings;
|
||||
legendSettings.setTitle( QString() );
|
||||
legendSettings.setBoxSpace( boxSpace );
|
||||
legendSettings.rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, layerSpace );
|
||||
// TODO: not available: layer title space
|
||||
legendSettings.rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, symbolSpace );
|
||||
legendSettings.rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Left, iconLabelSpace );
|
||||
legendSettings.setSymbolSize( QSizeF( symbolWidth, symbolHeight ) );
|
||||
legendSettings.rstyle( QgsLegendStyle::Subgroup ).setFont( layerFont );
|
||||
legendSettings.rstyle( QgsLegendStyle::SymbolLabel ).setFont( itemFont );
|
||||
// TODO: not available: layer font color
|
||||
legendSettings.setFontColor( itemFontColor );
|
||||
|
||||
if ( contentBasedLegend )
|
||||
{
|
||||
legendSettings.setMapScale( contentBasedMapSettings.scale() );
|
||||
}
|
||||
|
||||
if ( !rule.isEmpty() )
|
||||
{
|
||||
//create second image with the right dimensions
|
||||
QImage *paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight, false );
|
||||
|
||||
//go through the items a second time for painting
|
||||
QPainter p( paintImage );
|
||||
p.setRenderHint( QPainter::Antialiasing, true );
|
||||
p.scale( dpmm, dpmm );
|
||||
|
||||
QgsLayerTreeModelLegendNode *legendNode = _findLegendNodeForRule( &legendModel, rule );
|
||||
QgsLayerTreeModelLegendNode *legendNode = _findLegendNodeForRule( legendModel.get(), rule );
|
||||
if ( legendNode )
|
||||
{
|
||||
QgsLayerTreeModelLegendNode::ItemContext ctx;
|
||||
ctx.painter = &p;
|
||||
ctx.painter = painter.get();
|
||||
ctx.labelXOffset = 0;
|
||||
ctx.point = QPointF();
|
||||
double itemHeight = ruleSymbolHeight / dpmm;
|
||||
double itemHeight = height / dpmm;
|
||||
legendNode->drawSymbol( legendSettings, &ctx, itemHeight );
|
||||
}
|
||||
|
||||
QgsProject::instance()->removeAllMapLayers();
|
||||
return paintImage;
|
||||
}
|
||||
|
||||
QList<QgsLayerTreeNode *> rootChildren = rootGroup.children();
|
||||
Q_FOREACH ( QgsLayerTreeNode *node, rootChildren )
|
||||
{
|
||||
if ( QgsLayerTree::isLayer( node ) )
|
||||
{
|
||||
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !mAccessControl->layerReadPermission( nodeLayer->layer() ) )
|
||||
{
|
||||
throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: " ).arg( nodeLayer->layer()->name() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// layer titles - hidden or not
|
||||
QgsLegendRenderer::setNodeLegendStyle( nodeLayer, mDrawLegendLayerLabel ? QgsLegendStyle::Subgroup : QgsLegendStyle::Hidden );
|
||||
|
||||
// rule item titles
|
||||
if ( !mDrawLegendItemLabel )
|
||||
{
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel.layerLegendNodes( nodeLayer ) )
|
||||
{
|
||||
legendNode->setUserLabel( QStringLiteral( " " ) ); // empty string = no override, so let's use one space
|
||||
}
|
||||
}
|
||||
else if ( !mDrawLegendLayerLabel )
|
||||
{
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel.layerLegendNodes( nodeLayer ) )
|
||||
{
|
||||
if ( legendNode->isEmbeddedInParent() )
|
||||
legendNode->setEmbeddedInParent( false );
|
||||
}
|
||||
}
|
||||
painter->end();
|
||||
}
|
||||
}
|
||||
|
||||
QgsLegendRenderer legendRenderer( &legendModel, legendSettings );
|
||||
QSizeF minSize = legendRenderer.minimumSize();
|
||||
QSize s( minSize.width() * dpmm, minSize.height() * dpmm );
|
||||
|
||||
QImage *paintImage = createImage( s.width(), s.height(), false );
|
||||
|
||||
QPainter p( paintImage );
|
||||
p.setRenderHint( QPainter::Antialiasing, true );
|
||||
p.scale( dpmm, dpmm );
|
||||
|
||||
legendRenderer.drawLegend( &p );
|
||||
|
||||
p.end();
|
||||
|
||||
// reset layers' name
|
||||
Q_FOREACH ( const QString &layerId, layerIds )
|
||||
else
|
||||
{
|
||||
QgsMapLayer *ml = QgsProject::instance()->mapLayer( layerId );
|
||||
ml->setName( layerNameMap[ layerId ] );
|
||||
QgsLegendRenderer legendRendererNew( legendModel.get(), legendSettings );
|
||||
|
||||
QSizeF minSize = legendRendererNew.minimumSize();
|
||||
QSize s( minSize.width() * dpmm, minSize.height() * dpmm );
|
||||
|
||||
image.reset( createImage( s.width(), s.height(), false ) );
|
||||
painter.reset( new QPainter( image.get() ) );
|
||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
||||
painter->scale( dpmm, dpmm );
|
||||
|
||||
legendRendererNew.drawLegend( painter.get() );
|
||||
painter->end();
|
||||
}
|
||||
// clear map layer registry
|
||||
QgsProject::instance()->removeAllMapLayers();
|
||||
return paintImage;
|
||||
|
||||
return image.release();
|
||||
}
|
||||
|
||||
|
||||
void QgsRenderer::runHitTest( const QgsMapSettings &mapSettings, HitTest &hitTest ) const
|
||||
{
|
||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
||||
|
||||
Q_FOREACH ( const QString &layerID, mapSettings.layerIds() )
|
||||
Q_FOREACH ( const QString &id, mapSettings.layerIds() )
|
||||
{
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( layerID ) );
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mProject->mapLayer( id ) );
|
||||
if ( !vl || !vl->renderer() )
|
||||
continue;
|
||||
|
||||
@ -455,113 +264,15 @@ namespace QgsWms
|
||||
if ( moreSymbolsPerFeature )
|
||||
{
|
||||
Q_FOREACH ( QgsSymbol *s, r->originalSymbolsForFeature( f, context ) )
|
||||
usedSymbols.insert( s );
|
||||
usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( s ) );
|
||||
}
|
||||
else
|
||||
usedSymbols.insert( r->originalSymbolForFeature( f, context ) );
|
||||
usedSymbols.insert( QgsSymbolLayerUtils::symbolProperties( r->originalSymbolForFeature( f, context ) ) );
|
||||
}
|
||||
r->stopRender( context );
|
||||
}
|
||||
|
||||
|
||||
void QgsRenderer::legendParameters( double &boxSpace, double &layerSpace, double &layerTitleSpace,
|
||||
double &symbolSpace, double &iconLabelSpace, double &symbolWidth, double &symbolHeight,
|
||||
QFont &layerFont, QFont &itemFont, QColor &layerFontColor, QColor &itemFontColor )
|
||||
{
|
||||
//spaces between legend elements
|
||||
QMap<QString, QString>::const_iterator boxSpaceIt = mParameters.constFind( QStringLiteral( "BOXSPACE" ) );
|
||||
boxSpace = ( boxSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendBoxSpace() : boxSpaceIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator layerSpaceIt = mParameters.constFind( QStringLiteral( "LAYERSPACE" ) );
|
||||
layerSpace = ( layerSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendLayerSpace() : layerSpaceIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator layerTitleSpaceIt = mParameters.constFind( QStringLiteral( "LAYERTITLESPACE" ) );
|
||||
layerTitleSpace = ( layerTitleSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendLayerTitleSpace() : layerTitleSpaceIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator symbolSpaceIt = mParameters.constFind( QStringLiteral( "SYMBOLSPACE" ) );
|
||||
symbolSpace = ( symbolSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolSpace() : symbolSpaceIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator iconLabelSpaceIt = mParameters.constFind( QStringLiteral( "ICONLABELSPACE" ) );
|
||||
iconLabelSpace = ( iconLabelSpaceIt == mParameters.constEnd() ) ? mConfigParser->legendIconLabelSpace() : iconLabelSpaceIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator symbolWidthIt = mParameters.constFind( QStringLiteral( "SYMBOLWIDTH" ) );
|
||||
symbolWidth = ( symbolWidthIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolWidth() : symbolWidthIt.value().toDouble();
|
||||
QMap<QString, QString>::const_iterator symbolHeightIt = mParameters.constFind( QStringLiteral( "SYMBOLHEIGHT" ) );
|
||||
symbolHeight = ( symbolHeightIt == mParameters.constEnd() ) ? mConfigParser->legendSymbolHeight() : symbolHeightIt.value().toDouble();
|
||||
|
||||
//font properties
|
||||
layerFont = mConfigParser->legendLayerFont();
|
||||
QMap<QString, QString>::const_iterator layerFontFamilyIt = mParameters.constFind( QStringLiteral( "LAYERFONTFAMILY" ) );
|
||||
if ( layerFontFamilyIt != mParameters.constEnd() )
|
||||
{
|
||||
layerFont.setFamily( layerFontFamilyIt.value() );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator layerFontBoldIt = mParameters.constFind( QStringLiteral( "LAYERFONTBOLD" ) );
|
||||
if ( layerFontBoldIt != mParameters.constEnd() )
|
||||
{
|
||||
layerFont.setBold( layerFontBoldIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator layerFontItalicIt = mParameters.constFind( QStringLiteral( "LAYERFONTITALIC" ) );
|
||||
if ( layerFontItalicIt != mParameters.constEnd() )
|
||||
{
|
||||
layerFont.setItalic( layerFontItalicIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator layerFontSizeIt = mParameters.constFind( QStringLiteral( "LAYERFONTSIZE" ) );
|
||||
layerFont.setPointSizeF( layerFontSizeIt != mParameters.constEnd() ? layerFontSizeIt.value().toDouble() : layerFont.pointSizeF() );
|
||||
QMap<QString, QString>::const_iterator layerFontColorIt = mParameters.constFind( QStringLiteral( "LAYERFONTCOLOR" ) );
|
||||
if ( layerFontColorIt != mParameters.constEnd() )
|
||||
{
|
||||
layerFontColor.setNamedColor( layerFontColorIt.value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
layerFontColor = QColor( 0, 0, 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator layerTitleIt = mParameters.constFind( QStringLiteral( "LAYERTITLE" ) );
|
||||
if ( layerTitleIt != mParameters.constEnd() )
|
||||
{
|
||||
mDrawLegendLayerLabel = ( layerTitleIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mDrawLegendLayerLabel = true;
|
||||
}
|
||||
|
||||
|
||||
itemFont = mConfigParser->legendItemFont();
|
||||
QMap<QString, QString>::const_iterator itemFontFamilyIt = mParameters.constFind( QStringLiteral( "ITEMFONTFAMILY" ) );
|
||||
if ( itemFontFamilyIt != mParameters.constEnd() )
|
||||
{
|
||||
itemFont.setFamily( itemFontFamilyIt.value() );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator itemFontBoldIt = mParameters.constFind( QStringLiteral( "ITEMFONTBOLD" ) );
|
||||
if ( itemFontBoldIt != mParameters.constEnd() )
|
||||
{
|
||||
itemFont.setBold( itemFontBoldIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator itemFontItalicIt = mParameters.constFind( QStringLiteral( "ITEMFONTITALIC" ) );
|
||||
if ( itemFontItalicIt != mParameters.constEnd() )
|
||||
{
|
||||
itemFont.setItalic( itemFontItalicIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator itemFontSizeIt = mParameters.constFind( QStringLiteral( "ITEMFONTSIZE" ) );
|
||||
itemFont.setPointSizeF( itemFontSizeIt != mParameters.constEnd() ? itemFontSizeIt.value().toDouble() : itemFont.pointSizeF() );
|
||||
QMap<QString, QString>::const_iterator itemFontColorIt = mParameters.constFind( QStringLiteral( "ITEMFONTCOLOR" ) );
|
||||
if ( itemFontColorIt != mParameters.constEnd() )
|
||||
{
|
||||
itemFontColor.setNamedColor( itemFontColorIt.value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemFontColor = QColor( 0, 0, 0 );
|
||||
}
|
||||
QMap<QString, QString>::const_iterator itemLabelIt = mParameters.constFind( QStringLiteral( "RULELABEL" ) );
|
||||
if ( itemLabelIt != mParameters.constEnd() )
|
||||
{
|
||||
mDrawLegendItemLabel = ( itemLabelIt.value().compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mDrawLegendItemLabel = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QByteArray *QgsRenderer::getPrint( const QString &formatString )
|
||||
{
|
||||
QStringList layersList, stylesList, layerIdList;
|
||||
@ -707,105 +418,6 @@ namespace QgsWms
|
||||
}
|
||||
#endif
|
||||
|
||||
QImage *QgsRenderer::getMapOld( HitTest *hitTest )
|
||||
{
|
||||
QgsMapSettings mapSettings;
|
||||
return getMapOld( mapSettings, hitTest );
|
||||
}
|
||||
|
||||
QImage *QgsRenderer::getMapOld( QgsMapSettings &mapSettings, HitTest *hitTest )
|
||||
{
|
||||
if ( !checkMaximumWidthHeight() )
|
||||
{
|
||||
throw QgsBadRequestException( QStringLiteral( "Size error" ),
|
||||
QStringLiteral( "The requested map size is too large" ) );
|
||||
}
|
||||
QStringList layersList, stylesList, layerIdList;
|
||||
QImage *image = initializeRendering( layersList, stylesList, layerIdList, mapSettings );
|
||||
|
||||
QStringList layerSetIds = mapSettings.layerIds();
|
||||
|
||||
QStringList highlightLayersId = QgsWmsConfigParser::addHighlightLayers( mParameters, layerSetIds );
|
||||
|
||||
QList<QgsMapLayer *> layerSet;
|
||||
Q_FOREACH ( QString layerSetId, layerSetIds )
|
||||
{
|
||||
layerSet.append( QgsProject::instance()->mapLayer( layerSetId ) );
|
||||
}
|
||||
mapSettings.setLayers( layerSet );
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers() )
|
||||
{
|
||||
if ( !mAccessControl->layerReadPermission( layer ) )
|
||||
{
|
||||
throw QgsSecurityException( QStringLiteral( "You are not allowed to access to the layer: %1" ).arg( layer->name() ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//scoped pointer to restore all original layer filters (subsetStrings) when pointer goes out of scope
|
||||
//there's LOTS of potential exit paths here, so we avoid having to restore the filters manually
|
||||
std::unique_ptr< QgsOWSServerFilterRestorer > filterRestorer( new QgsOWSServerFilterRestorer( mAccessControl ) );
|
||||
|
||||
applyRequestedLayerFilters( layersList, mapSettings, filterRestorer->originalFilters() );
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
applyAccessControlLayersFilters( layersList, filterRestorer->originalFilters() );
|
||||
#endif
|
||||
|
||||
QStringList selectedLayerIdList = applyFeatureSelections( layersList );
|
||||
|
||||
QList< QPair< QgsVectorLayer *, QgsFeatureRenderer *> > bkVectorRenderers;
|
||||
QList< QPair< QgsRasterLayer *, QgsRasterRenderer * > > bkRasterRenderers;
|
||||
QList< QPair< QgsVectorLayer *, double > > labelTransparencies;
|
||||
QList< QPair< QgsVectorLayer *, double > > labelBufferTransparencies;
|
||||
|
||||
applyOpacities( layersList, bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||
|
||||
std::unique_ptr<QPainter> painter;
|
||||
if ( hitTest )
|
||||
{
|
||||
runHitTest( mapSettings, *hitTest );
|
||||
painter.reset( new QPainter() );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
mAccessControl->resolveFilterFeatures( mapSettings.layers() );
|
||||
#endif
|
||||
QgsMapRendererJobProxy renderJob( mSettings.parallelRendering(), mSettings.maxThreads(), mAccessControl );
|
||||
renderJob.render( mapSettings, image );
|
||||
painter.reset( renderJob.takePainter() );
|
||||
}
|
||||
|
||||
if ( mConfigParser )
|
||||
{
|
||||
//draw configuration format specific overlay items
|
||||
mConfigParser->drawOverlays( painter.get(), image->dotsPerMeterX() / 1000.0 * 25.4, image->width(), image->height() );
|
||||
}
|
||||
|
||||
restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||
clearFeatureSelections( selectedLayerIdList );
|
||||
QgsWmsConfigParser::removeHighlightLayers( highlightLayersId );
|
||||
|
||||
if ( !hitTest )
|
||||
QgsProject::instance()->removeAllMapLayers();
|
||||
|
||||
painter->end();
|
||||
|
||||
//test if width / height ratio of image is the same as the ratio of WIDTH / HEIGHT parameters. If not, the image has to be scaled (required by WMS spec)
|
||||
int widthParam = mParameters.value( "WIDTH", "0" ).toInt();
|
||||
int heightParam = mParameters.value( "HEIGHT", "0" ).toInt();
|
||||
if ( widthParam != image->width() || heightParam != image->height() )
|
||||
{
|
||||
//scale image
|
||||
*image = image->scaled( widthParam, heightParam, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage *QgsRenderer::getMap( HitTest *hitTest )
|
||||
{
|
||||
QgsMapSettings mapSettings;
|
||||
@ -1405,20 +1017,10 @@ namespace QgsWms
|
||||
bool conversionSuccess;
|
||||
|
||||
if ( width < 0 )
|
||||
{
|
||||
width = mParameters.value( QStringLiteral( "WIDTH" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
width = 0;
|
||||
}
|
||||
width = mWmsParameters.widthAsInt();
|
||||
|
||||
if ( height < 0 )
|
||||
{
|
||||
height = mParameters.value( QStringLiteral( "HEIGHT" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
height = 0;
|
||||
}
|
||||
}
|
||||
height = mWmsParameters.heightAsInt();
|
||||
|
||||
//Adapt width / height if the aspect ratio does not correspond with the BBOX.
|
||||
//Required by WMS spec. 1.3.
|
||||
@ -2463,15 +2065,15 @@ namespace QgsWms
|
||||
{
|
||||
//test if maxWidth / maxHeight set and WIDTH / HEIGHT parameter is in the range
|
||||
int wmsMaxWidth = QgsServerProjectUtils::wmsMaxWidth( *mProject );
|
||||
int width = mWmsParameters.width();
|
||||
if ( wmsMaxWidth != -1 && width != -1 && width > wmsMaxWidth )
|
||||
int width = mWmsParameters.widthAsInt();
|
||||
if ( wmsMaxWidth != -1 && width > wmsMaxWidth )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int wmsMaxHeight = QgsServerProjectUtils::wmsMaxHeight( *mProject );
|
||||
int height = mWmsParameters.height();
|
||||
if ( wmsMaxHeight != -1 && height != -1 && height > wmsMaxHeight )
|
||||
int height = mWmsParameters.heightAsInt();
|
||||
if ( wmsMaxHeight != -1 && height > wmsMaxHeight )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3272,8 +2874,8 @@ namespace QgsWms
|
||||
// WIDTH / HEIGHT parameters. If not, the image has to be scaled (required
|
||||
// by WMS spec)
|
||||
QImage *scaledImage = nullptr;
|
||||
int width = mWmsParameters.width();
|
||||
int height = mWmsParameters.height();
|
||||
int width = mWmsParameters.widthAsInt();
|
||||
int height = mWmsParameters.heightAsInt();
|
||||
if ( width != image->width() || height != image->height() )
|
||||
{
|
||||
scaledImage = new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
|
||||
@ -3311,4 +2913,125 @@ namespace QgsWms
|
||||
|
||||
layers = wantedLayers;
|
||||
}
|
||||
|
||||
QgsLayerTreeModel *QgsRenderer::buildLegendTreeModel( const QList<QgsMapLayer *> &layers, double scaleDenominator, QgsLayerTree &rootGroup )
|
||||
{
|
||||
// get params
|
||||
bool showFeatureCount = mWmsParameters.showFeatureCountAsBool();
|
||||
bool drawLegendLayerLabel = mWmsParameters.layerTitleAsBool();
|
||||
bool drawLegendItemLabel = mWmsParameters.ruleLabelAsBool();
|
||||
|
||||
bool ruleDefined = false;
|
||||
if ( !mWmsParameters.rule().isEmpty() )
|
||||
ruleDefined = true;
|
||||
|
||||
bool contentBasedLegend = false;
|
||||
QgsRectangle contentBasedLegendExtent;
|
||||
if ( ! mWmsParameters.bbox().isEmpty() )
|
||||
{
|
||||
contentBasedLegend = true;
|
||||
contentBasedLegendExtent = mWmsParameters.bboxAsRectangle();
|
||||
if ( contentBasedLegendExtent.isEmpty() )
|
||||
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ),
|
||||
QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
|
||||
if ( !mWmsParameters.rule().isEmpty() )
|
||||
throw QgsBadRequestException( QStringLiteral( "InvalidParameterValue" ),
|
||||
QStringLiteral( "BBOX parameter cannot be combined with RULE" ) );
|
||||
}
|
||||
|
||||
// build layer tree
|
||||
rootGroup.clear();
|
||||
Q_FOREACH ( QgsMapLayer *ml, layers )
|
||||
{
|
||||
QgsLayerTreeLayer *lt = rootGroup.addLayer( ml );
|
||||
lt->setCustomProperty( QStringLiteral( "showFeatureCount" ), showFeatureCount );
|
||||
|
||||
if ( !ml->title().isEmpty() )
|
||||
lt->setName( ml->title() );
|
||||
}
|
||||
|
||||
// build legend model
|
||||
QgsLayerTreeModel *legendModel = new QgsLayerTreeModel( &rootGroup );
|
||||
if ( scaleDenominator > 0 )
|
||||
legendModel->setLegendFilterByScale( scaleDenominator );
|
||||
|
||||
QgsMapSettings contentBasedMapSettings;
|
||||
if ( contentBasedLegend )
|
||||
{
|
||||
HitTest hitTest;
|
||||
getMap( contentBasedMapSettings, &hitTest );
|
||||
|
||||
Q_FOREACH ( QgsLayerTreeNode *node, rootGroup.children() )
|
||||
{
|
||||
Q_ASSERT( QgsLayerTree::isLayer( node ) );
|
||||
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( nodeLayer->layer() );
|
||||
if ( !vl || !vl->renderer() )
|
||||
continue;
|
||||
|
||||
const SymbolSet &usedSymbols = hitTest[vl];
|
||||
QList<int> order;
|
||||
int i = 0;
|
||||
Q_FOREACH ( const QgsLegendSymbolItem &legendItem, vl->renderer()->legendSymbolItemsV2() )
|
||||
{
|
||||
QString sProp = QgsSymbolLayerUtils::symbolProperties( legendItem.legacyRuleKey() );
|
||||
if ( usedSymbols.contains( sProp ) )
|
||||
order.append( i );
|
||||
++i;
|
||||
}
|
||||
|
||||
// either remove the whole layer or just filter out some items
|
||||
if ( order.isEmpty() )
|
||||
rootGroup.removeChildNode( nodeLayer );
|
||||
else
|
||||
{
|
||||
QgsMapLayerLegendUtils::setLegendNodeOrder( nodeLayer, order );
|
||||
legendModel->refreshLayerLegend( nodeLayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if legend is not based on rendering rules
|
||||
if ( ! ruleDefined )
|
||||
{
|
||||
QList<QgsLayerTreeNode *> rootChildren = rootGroup.children();
|
||||
Q_FOREACH ( QgsLayerTreeNode *node, rootChildren )
|
||||
{
|
||||
if ( QgsLayerTree::isLayer( node ) )
|
||||
{
|
||||
QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
|
||||
|
||||
// layer titles - hidden or not
|
||||
QgsLegendRenderer::setNodeLegendStyle( nodeLayer, drawLegendLayerLabel ? QgsLegendStyle::Subgroup : QgsLegendStyle::Hidden );
|
||||
|
||||
// rule item titles
|
||||
if ( !drawLegendItemLabel )
|
||||
{
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel->layerLegendNodes( nodeLayer ) )
|
||||
{
|
||||
legendNode->setUserLabel( QStringLiteral( " " ) ); // empty string = no override, so let's use one space
|
||||
}
|
||||
}
|
||||
else if ( !drawLegendLayerLabel )
|
||||
{
|
||||
Q_FOREACH ( QgsLayerTreeModelLegendNode *legendNode, legendModel->layerLegendNodes( nodeLayer ) )
|
||||
{
|
||||
if ( legendNode->isEmbeddedInParent() )
|
||||
legendNode->setEmbeddedInParent( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return legendModel;
|
||||
}
|
||||
|
||||
qreal QgsRenderer::dotsPerMm() const
|
||||
{
|
||||
std::unique_ptr<QImage> tmpImage( createImage( 1, 1, false ) );
|
||||
return tmpImage->dotsPerMeterX() / 1000.0;
|
||||
}
|
||||
} // namespace QgsWms
|
||||
|
@ -47,6 +47,8 @@ class QgsSymbol;
|
||||
class QgsSymbol;
|
||||
class QgsAccessControl;
|
||||
class QgsDxfExport;
|
||||
class QgsLayerTreeModel;
|
||||
class QgsLayerTree;
|
||||
|
||||
class QColor;
|
||||
class QFile;
|
||||
@ -88,19 +90,17 @@ namespace QgsWms
|
||||
of the image object*/
|
||||
QImage *getLegendGraphics();
|
||||
|
||||
typedef QSet<QgsSymbol *> SymbolSet;
|
||||
typedef QSet<QString> SymbolSet;
|
||||
typedef QHash<QgsVectorLayer *, SymbolSet> HitTest;
|
||||
|
||||
/** Returns the map as an image (or a null pointer in case of error). The caller takes ownership
|
||||
of the image object). If an instance to existing hit test structure is passed, instead of rendering
|
||||
it will fill the structure with symbols that would be used for rendering */
|
||||
QImage *getMap( HitTest *hitTest = nullptr );
|
||||
QImage *getMapOld( HitTest *hitTest = nullptr );
|
||||
|
||||
/** Identical to getMap( HitTest* hitTest ) and updates the map settings actually used.
|
||||
\since QGIS 3.0 */
|
||||
QImage *getMap( QgsMapSettings &mapSettings, HitTest *hitTest = nullptr );
|
||||
QImage *getMapOld( QgsMapSettings &mapSettings, HitTest *hitTest = nullptr );
|
||||
|
||||
/** Returns the map as DXF data
|
||||
\param options: extracted from the FORMAT_OPTIONS parameter
|
||||
@ -173,6 +173,12 @@ namespace QgsWms
|
||||
// Check layer read permissions
|
||||
void checkLayerReadPermissions( QgsMapLayer *layer ) const;
|
||||
|
||||
// Build a layer tree model for legend
|
||||
QgsLayerTreeModel *buildLegendTreeModel( const QList<QgsMapLayer *> &layers, double scaleDenominator, QgsLayerTree &rootGroup );
|
||||
|
||||
// Returns default dots per mm
|
||||
qreal dotsPerMm() const;
|
||||
|
||||
/** Initializes WMS layers and configures rendering.
|
||||
* \param layersList out: list with WMS layer names
|
||||
* \param stylesList out: list with WMS style names
|
||||
@ -236,10 +242,6 @@ namespace QgsWms
|
||||
//! Record which symbols within one layer would be rendered with the given renderer context
|
||||
void runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context ) const;
|
||||
|
||||
//! Read legend parameter from the request or from the first print composer in the project
|
||||
void legendParameters( double &boxSpace, double &layerSpace, double &layerTitleSpace,
|
||||
double &symbolSpace, double &iconLabelSpace, double &symbolWidth, double &symbolHeight, QFont &layerFont, QFont &itemFont, QColor &layerFontColor, QColor &itemFontColor );
|
||||
|
||||
/** Apply filter (subset) strings from the request to the layers. Example: '&FILTER=<layer1>:"AND property > 100",<layer2>:"AND bla = 'hallo!'" '
|
||||
* \param layerList list of layer IDs to filter
|
||||
* \param originalFilters hash of layer ID to original filter string
|
||||
@ -313,10 +315,6 @@ namespace QgsWms
|
||||
|
||||
bool mOwnsConfigParser; //delete config parser after request (e.g. sent SLD)
|
||||
|
||||
// specify if layer or rule item labels should be drawn in the legend graphic with GetLegendGraphics
|
||||
bool mDrawLegendLayerLabel;
|
||||
bool mDrawLegendItemLabel;
|
||||
|
||||
//! Map containing the WMS parameters
|
||||
QgsWmsConfigParser *mConfigParser = nullptr;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import email
|
||||
|
||||
from io import StringIO
|
||||
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
|
||||
from qgis.core import QgsRenderChecker, QgsApplication
|
||||
from qgis.core import QgsRenderChecker, QgsApplication, QgsFontUtils
|
||||
from qgis.testing import unittest
|
||||
from qgis.PyQt.QtCore import QSize
|
||||
from utilities import unitTestDataPath
|
||||
@ -94,6 +94,9 @@ class QgsServerTestBase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Create the server instance"""
|
||||
self.fontFamily = QgsFontUtils.standardTestFontFamily()
|
||||
QgsFontUtils.loadStandardTestFonts(['All'])
|
||||
|
||||
self.testdata_path = unitTestDataPath('qgis_server') + '/'
|
||||
|
||||
d = unitTestDataPath('qgis_server_accesscontrol') + '/'
|
||||
|
@ -1026,8 +1026,80 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
self.assertEqual(-1, h.find(b'Content-Type: text/xml; charset=utf-8'), "Header: %s\nResponse:\n%s" % (h, r))
|
||||
self.assertNotEqual(-1, h.find(b'Content-Type: image/png'), "Header: %s\nResponse:\n%s" % (h, r))
|
||||
|
||||
def test_getLegendGraphics_invalid_parameters(self):
|
||||
"""Test that does return an exception"""
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetLegendGraphic",
|
||||
"LAYER": "Country,Hello,db_point",
|
||||
"LAYERTITLE": "FALSE",
|
||||
"FORMAT": "image/png",
|
||||
"HEIGHT": "500",
|
||||
"WIDTH": "500",
|
||||
"RULE": "1",
|
||||
"BBOX": "-151.7,-38.9,51.0,78.0",
|
||||
"CRS": "EPSG:4326"
|
||||
}.items())])
|
||||
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
err = b"BBOX parameter cannot be combined with RULE" in r
|
||||
self.assertTrue(err)
|
||||
|
||||
def test_wms_GetLegendGraphic_LayerSpace(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetLegendGraphic",
|
||||
"LAYER": "Country,Hello",
|
||||
"FORMAT": "image/png",
|
||||
# "HEIGHT": "500",
|
||||
# "WIDTH": "500",
|
||||
"LAYERSPACE": "50.0",
|
||||
"LAYERFONTBOLD": "TRUE",
|
||||
"LAYERFONTSIZE": "30",
|
||||
"ITEMFONTBOLD": "TRUE",
|
||||
"ITEMFONTSIZE": "20",
|
||||
"LAYERFONTFAMILY": self.fontFamily,
|
||||
"ITEMFONTFAMILY": self.fontFamily,
|
||||
"LAYERTITLE": "TRUE",
|
||||
"CRS": "EPSG:3857"
|
||||
}.items())])
|
||||
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerSpace")
|
||||
|
||||
def test_wms_GetLegendGraphic_ShowFeatureCount(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetLegendGraphic",
|
||||
"LAYER": "Country,Hello",
|
||||
"FORMAT": "image/png",
|
||||
# "HEIGHT": "500",
|
||||
# "WIDTH": "500",
|
||||
"LAYERTITLE": "TRUE",
|
||||
"LAYERFONTBOLD": "TRUE",
|
||||
"LAYERFONTSIZE": "30",
|
||||
"LAYERFONTFAMILY": self.fontFamily,
|
||||
"ITEMFONTFAMILY": self.fontFamily,
|
||||
"ITEMFONTBOLD": "TRUE",
|
||||
"ITEMFONTSIZE": "20",
|
||||
"SHOWFEATURECOUNT": "TRUE",
|
||||
"CRS": "EPSG:3857"
|
||||
}.items())])
|
||||
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount", max_size_diff=QSize(1, 1))
|
||||
|
||||
def test_getLegendGraphics_layertitle(self):
|
||||
"""Test that does not return an exception but an image"""
|
||||
|
||||
print("TEST FONT FAMILY: ", self.fontFamily)
|
||||
|
||||
parms = {
|
||||
'MAP': self.testdata_path + "test_project.qgs",
|
||||
'SERVICE': 'WMS',
|
||||
@ -1037,6 +1109,12 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
# 'WIDTH': '20', # optional
|
||||
# 'HEIGHT': '20', # optional
|
||||
'LAYER': u'testlayer%20èé',
|
||||
'LAYERFONTBOLD': 'TRUE',
|
||||
'LAYERFONTSIZE': '30',
|
||||
'ITEMFONTBOLD': 'TRUE',
|
||||
'LAYERFONTFAMILY': self.fontFamily,
|
||||
'ITEMFONTFAMILY': self.fontFamily,
|
||||
'ITEMFONTSIZE': '20',
|
||||
'LAYERTITLE': 'TRUE',
|
||||
}
|
||||
qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
|
||||
@ -1058,6 +1136,78 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(15, 15))
|
||||
|
||||
def test_getLegendGraphics_rulelabel(self):
|
||||
"""Test that does not return an exception but an image"""
|
||||
parms = {
|
||||
'MAP': self.testdata_path + "test_project.qgs",
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': '1.3.0',
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': u'testlayer%20èé',
|
||||
'LAYERFONTBOLD': 'TRUE',
|
||||
'LAYERFONTSIZE': '30',
|
||||
'LAYERFONTFAMILY': self.fontFamily,
|
||||
'ITEMFONTFAMILY': self.fontFamily,
|
||||
'ITEMFONTBOLD': 'TRUE',
|
||||
'ITEMFONTSIZE': '20',
|
||||
'RULELABEL': 'TRUE',
|
||||
}
|
||||
qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_test", 250, QSize(15, 15))
|
||||
|
||||
parms = {
|
||||
'MAP': self.testdata_path + "test_project.qgs",
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': '1.3.0',
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': u'testlayer%20èé',
|
||||
'LAYERFONTBOLD': 'TRUE',
|
||||
'LAYERFONTSIZE': '30',
|
||||
'ITEMFONTBOLD': 'TRUE',
|
||||
'ITEMFONTSIZE': '20',
|
||||
'LAYERFONTFAMILY': self.fontFamily,
|
||||
'ITEMFONTFAMILY': self.fontFamily,
|
||||
'RULELABEL': 'FALSE',
|
||||
}
|
||||
qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_rulelabel_false", 250, QSize(15, 15))
|
||||
|
||||
def test_getLegendGraphics_rule(self):
|
||||
"""Test that does not return an exception but an image"""
|
||||
parms = {
|
||||
'MAP': self.testdata_path + "test_project_legend_rule.qgs",
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': '1.3.0',
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': u'testlayer%20èé',
|
||||
'WIDTH': '20',
|
||||
'HEIGHT': '20',
|
||||
'RULE': 'rule0',
|
||||
}
|
||||
qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_rule0", 250, QSize(15, 15))
|
||||
|
||||
parms = {
|
||||
'MAP': self.testdata_path + "test_project_legend_rule.qgs",
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': '1.3.0',
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': u'testlayer%20èé',
|
||||
'WIDTH': '20',
|
||||
'HEIGHT': '20',
|
||||
'RULE': 'rule1',
|
||||
}
|
||||
qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_rule1", 250, QSize(15, 15))
|
||||
|
||||
def test_wms_GetLegendGraphic_Basic(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
@ -1201,6 +1351,54 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSize")
|
||||
|
||||
def test_wms_GetLegendGraphic_LayerFont(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetLegendGraphic",
|
||||
"LAYER": "Country,Hello",
|
||||
"LAYERTITLE": "TRUE",
|
||||
"LAYERFONTBOLD": "TRUE",
|
||||
"LAYERFONTITALIC": "TRUE",
|
||||
"LAYERFONTSIZE": "30",
|
||||
"ITEMFONTBOLD": "TRUE",
|
||||
"ITEMFONTSIZE": "20",
|
||||
"LAYERFONTFAMILY": self.fontFamily,
|
||||
"ITEMFONTFAMILY": self.fontFamily,
|
||||
"FORMAT": "image/png",
|
||||
"HEIGHT": "500",
|
||||
"WIDTH": "500",
|
||||
"CRS": "EPSG:3857"
|
||||
}.items())])
|
||||
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerFont", max_size_diff=QSize(1, 1))
|
||||
|
||||
def test_wms_GetLegendGraphic_ItemFont(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
"SERVICE": "WMS",
|
||||
"VERSION": "1.1.1",
|
||||
"REQUEST": "GetLegendGraphic",
|
||||
"LAYER": "Country,Hello",
|
||||
"LAYERTITLE": "TRUE",
|
||||
"LAYERFONTBOLD": "TRUE",
|
||||
"LAYERFONTSIZE": "30",
|
||||
"ITEMFONTBOLD": "TRUE",
|
||||
"ITEMFONTITALIC": "TRUE",
|
||||
"ITEMFONTSIZE": "20",
|
||||
"LAYERFONTFAMILY": self.fontFamily,
|
||||
"ITEMFONTFAMILY": self.fontFamily,
|
||||
"FORMAT": "image/png",
|
||||
"HEIGHT": "500",
|
||||
"WIDTH": "500",
|
||||
"CRS": "EPSG:3857"
|
||||
}.items())])
|
||||
|
||||
r, h = self._result(self._execute_request(qs))
|
||||
self._img_diff_error(r, h, "WMS_GetLegendGraphic_ItemFont", max_size_diff=QSize(1, 1))
|
||||
|
||||
def test_wms_GetLegendGraphic_BBox(self):
|
||||
qs = "?" + "&".join(["%s=%s" % i for i in list({
|
||||
"MAP": urllib.parse.quote(self.projectPath),
|
||||
|
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 176 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 13 KiB |
BIN
tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule0/WMS_GetLegendGraphic_rule0.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_rule1/WMS_GetLegendGraphic_rule1.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 259 B |
445
tests/testdata/qgis_server/test_project_legend_rule.qgs
vendored
Normal file
@ -0,0 +1,445 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis projectname="QGIS Test Project" version="2.99.0-Master">
|
||||
<title>QGIS Test Project</title>
|
||||
<autotransaction active="0"/>
|
||||
<evaluateDefaultValues active="0"/>
|
||||
<layer-tree-group>
|
||||
<customproperties/>
|
||||
<layer-tree-layer expanded="1" providerKey="ogr" checked="Qt::Checked" source="/home/blottiere/devel/packages/QGIS_pbl_getlegendgraphic/tests/testdata/qgis_server/testlayer.shp" id="testlayer20150528120452665" name="testlayer èé">
|
||||
<customproperties/>
|
||||
</layer-tree-layer>
|
||||
<custom-order enabled="0">
|
||||
<item>testlayer20150528120452665</item>
|
||||
</custom-order>
|
||||
</layer-tree-group>
|
||||
<snapping-settings type="1" mode="1" unit="2" intersection-snapping="0" tolerance="0" enabled="0">
|
||||
<individual-layer-settings/>
|
||||
</snapping-settings>
|
||||
<relations/>
|
||||
<mapcanvas annotationsVisible="1" name="theMapCanvas">
|
||||
<units>degrees</units>
|
||||
<extent>
|
||||
<xmin>8.20202108826836884</xmin>
|
||||
<ymin>44.9009031607650968</ymin>
|
||||
<xmax>8.20606418507941449</xmax>
|
||||
<ymax>44.90195628381741244</ymax>
|
||||
</extent>
|
||||
<rotation>0</rotation>
|
||||
<destinationsrs>
|
||||
<spatialrefsys>
|
||||
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
|
||||
<srsid>3452</srsid>
|
||||
<srid>4326</srid>
|
||||
<authid>EPSG:4326</authid>
|
||||
<description>WGS 84</description>
|
||||
<projectionacronym>longlat</projectionacronym>
|
||||
<ellipsoidacronym>WGS84</ellipsoidacronym>
|
||||
<geographicflag>true</geographicflag>
|
||||
</spatialrefsys>
|
||||
</destinationsrs>
|
||||
<rendermaptile>0</rendermaptile>
|
||||
<layer_coordinate_transform_info>
|
||||
<layer_coordinate_transform srcAuthId="EPSG:4326" layerid="testlayer20150528120452665" destDatumTransform="-1" destAuthId="EPSG:4326" srcDatumTransform="-1"/>
|
||||
</layer_coordinate_transform_info>
|
||||
</mapcanvas>
|
||||
<legend updateDrawingOrder="true">
|
||||
<legendlayer showFeatureCount="0" open="true" checked="Qt::Checked" drawingOrder="-1" name="testlayer èé">
|
||||
<filegroup open="true" hidden="false">
|
||||
<legendlayerfile layerid="testlayer20150528120452665" visible="1" isInOverview="0"/>
|
||||
</filegroup>
|
||||
</legendlayer>
|
||||
</legend>
|
||||
<mapViewDocks/>
|
||||
<projectlayers>
|
||||
<maplayer simplifyDrawingTol="1" type="vector" readOnly="0" simplifyDrawingHints="0" simplifyMaxScale="1" autoRefreshEnabled="0" autoRefreshTime="0" simplifyAlgorithm="0" hasScaleBasedVisibilityFlag="0" geometry="Point" simplifyLocal="1" minimumScale="0" maximumScale="1e+8">
|
||||
<extent>
|
||||
<xmin>8.20345930703634352</xmin>
|
||||
<ymin>44.90139483904469131</ymin>
|
||||
<xmax>8.20354699399348775</xmax>
|
||||
<ymax>44.90148252600183554</ymax>
|
||||
</extent>
|
||||
<id>testlayer20150528120452665</id>
|
||||
<datasource>./testlayer.shp</datasource>
|
||||
<title>A test vector layer</title>
|
||||
<abstract>A test vector layer with unicode òà</abstract>
|
||||
<keywordList>
|
||||
<value></value>
|
||||
</keywordList>
|
||||
<layername>testlayer èé</layername>
|
||||
<srs>
|
||||
<spatialrefsys>
|
||||
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
|
||||
<srsid>3452</srsid>
|
||||
<srid>4326</srid>
|
||||
<authid>EPSG:4326</authid>
|
||||
<description>WGS 84</description>
|
||||
<projectionacronym>longlat</projectionacronym>
|
||||
<ellipsoidacronym>WGS84</ellipsoidacronym>
|
||||
<geographicflag>true</geographicflag>
|
||||
</spatialrefsys>
|
||||
</srs>
|
||||
<provider encoding="UTF-8">ogr</provider>
|
||||
<vectorjoins/>
|
||||
<layerDependencies/>
|
||||
<dataDependencies/>
|
||||
<expressionfields/>
|
||||
<map-layer-style-manager current="">
|
||||
<map-layer-style name=""/>
|
||||
</map-layer-style-manager>
|
||||
<renderer-v2 type="RuleRenderer" forceraster="0" symbollevels="0" enableorderby="0">
|
||||
<rules key="{9968c7d6-186c-4e91-80fd-b3c1e5541edf}">
|
||||
<rule symbol="0" label="rule0" key="{42912a46-cc74-4e39-a409-3a5ad6b9f59e}"/>
|
||||
<rule symbol="1" label="rule1" key="{c4d8fca3-46ba-4eeb-92e1-4efd5a19da74}"/>
|
||||
</rules>
|
||||
<symbols>
|
||||
<symbol alpha="1" clip_to_extent="1" type="marker" name="0">
|
||||
<layer pass="0" class="SimpleMarker" locked="0" enabled="1">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="102,164,67,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="circle"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="area"/>
|
||||
<prop k="size" v="2"/>
|
||||
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
<effect type="effectStack" enabled="0">
|
||||
<effect type="drawSource">
|
||||
<prop k="blend_mode" v="0"/>
|
||||
<prop k="draw_mode" v="2"/>
|
||||
<prop k="enabled" v="1"/>
|
||||
<prop k="transparency" v="0"/>
|
||||
</effect>
|
||||
</effect>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" type="QString" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" type="QString" name="type"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
<symbol alpha="1" clip_to_extent="1" type="marker" name="1">
|
||||
<layer pass="0" class="SimpleMarker" locked="0" enabled="1">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="159,114,97,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="star"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="diameter"/>
|
||||
<prop k="size" v="4"/>
|
||||
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" type="QString" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" type="QString" name="type"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<effect type="effectStack" enabled="0">
|
||||
<effect type="drawSource">
|
||||
<prop k="blend_mode" v="0"/>
|
||||
<prop k="draw_mode" v="2"/>
|
||||
<prop k="enabled" v="1"/>
|
||||
<prop k="transparency" v="0"/>
|
||||
</effect>
|
||||
</effect>
|
||||
</renderer-v2>
|
||||
<customproperties>
|
||||
<property value="0" key="embeddedWidgets/count"/>
|
||||
<property key="variableNames"/>
|
||||
<property key="variableValues"/>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerTransparency>0</layerTransparency>
|
||||
<SingleCategoryDiagramRenderer diagramType="Pie" attributeLegend="1" sizeLegend="0">
|
||||
<DiagramCategory penWidth="0" angleOffset="1440" maxScaleDenominator="1e+8" scaleDependency="Area" sizeScale="0,0,0,0,0,0" width="15" transparency="0" backgroundColor="#ffffff" minScaleDenominator="0" diagramOrientation="Up" barWidth="5" backgroundAlpha="255" scaleBasedVisibility="0" labelPlacementMethod="XHeight" penAlpha="255" lineSizeScale="0,0,0,0,0,0" sizeType="MM" minimumSize="0" height="15" enabled="0" lineSizeType="MM" penColor="#000000">
|
||||
<fontProperties style="" description="Ubuntu,9,-1,5,50,0,0,0,0,0"/>
|
||||
<attribute label="" color="#000000" field=""/>
|
||||
</DiagramCategory>
|
||||
<symbol alpha="1" clip_to_extent="1" type="marker" name="sizeSymbol">
|
||||
<layer pass="0" class="SimpleMarker" locked="0" enabled="1">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="255,0,0,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="circle"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="diameter"/>
|
||||
<prop k="size" v="2"/>
|
||||
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" type="QString" name="name"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" type="QString" name="type"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</SingleCategoryDiagramRenderer>
|
||||
<DiagramLayerSettings priority="0" obstacle="0" showAll="1" dist="0" placement="0" linePlacementFlags="2" zIndex="0">
|
||||
<properties>
|
||||
<Option type="Map">
|
||||
<Option value="" type="QString" name="name"/>
|
||||
<Option type="Map" name="properties">
|
||||
<Option type="Map" name="show">
|
||||
<Option value="true" type="bool" name="active"/>
|
||||
<Option value="id" type="QString" name="field"/>
|
||||
<Option value="2" type="int" name="type"/>
|
||||
</Option>
|
||||
</Option>
|
||||
<Option value="collection" type="QString" name="type"/>
|
||||
</Option>
|
||||
</properties>
|
||||
</DiagramLayerSettings>
|
||||
<fieldConfiguration>
|
||||
<field name="id">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option type="Map">
|
||||
<Option value="0" type="QString" name="IsMultiline"/>
|
||||
<Option value="0" type="QString" name="UseHtml"/>
|
||||
</Option>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option type="Map">
|
||||
<Option value="0" type="QString" name="IsMultiline"/>
|
||||
<Option value="0" type="QString" name="UseHtml"/>
|
||||
</Option>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="utf8nameè">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option type="Map">
|
||||
<Option value="0" type="QString" name="IsMultiline"/>
|
||||
<Option value="0" type="QString" name="UseHtml"/>
|
||||
</Option>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias index="0" field="id" name=""/>
|
||||
<alias index="1" field="name" name=""/>
|
||||
<alias index="2" field="utf8nameè" name=""/>
|
||||
</aliases>
|
||||
<excludeAttributesWMS/>
|
||||
<excludeAttributesWFS/>
|
||||
<defaults>
|
||||
<default field="id" expression=""/>
|
||||
<default field="name" expression=""/>
|
||||
<default field="utf8nameè" expression=""/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint notnull_strength="0" exp_strength="0" field="id" unique_strength="0" constraints="0"/>
|
||||
<constraint notnull_strength="0" exp_strength="0" field="name" unique_strength="0" constraints="0"/>
|
||||
<constraint notnull_strength="0" exp_strength="0" field="utf8nameè" unique_strength="0" constraints="0"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint desc="" exp="" field="id"/>
|
||||
<constraint desc="" exp="" field="name"/>
|
||||
<constraint desc="" exp="" field="utf8nameè"/>
|
||||
</constraintExpressions>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
|
||||
<columns>
|
||||
<column type="field" hidden="0" name="id" width="-1"/>
|
||||
<column type="field" hidden="0" name="name" width="-1"/>
|
||||
<column type="field" hidden="0" name="utf8nameè" width="-1"/>
|
||||
<column type="actions" hidden="1" width="-1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<editform>../../../../../..</editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath>../../../../../..</editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS forms can have a Python function that is called when the form is
|
||||
opened.
|
||||
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
Enter the name of the function in the "Python Init function"
|
||||
field.
|
||||
An example follows:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<widgets/>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<expressionfields/>
|
||||
<previewExpression>name</previewExpression>
|
||||
<mapTip></mapTip>
|
||||
</maplayer>
|
||||
</projectlayers>
|
||||
<layerorder>
|
||||
<layer id="testlayer20150528120452665"/>
|
||||
</layerorder>
|
||||
<properties>
|
||||
<WMSRestrictedLayers type="QStringList"/>
|
||||
<Variables>
|
||||
<variableNames type="QStringList"/>
|
||||
<variableValues type="QStringList"/>
|
||||
</Variables>
|
||||
<WMSServiceTitle type="QString">QGIS TestProject</WMSServiceTitle>
|
||||
<WMSPrecision type="QString">4</WMSPrecision>
|
||||
<WFSLayersPrecision>
|
||||
<testlayer20150528120452665 type="int">8</testlayer20150528120452665>
|
||||
</WFSLayersPrecision>
|
||||
<Measurement>
|
||||
<DistanceUnits type="QString">meters</DistanceUnits>
|
||||
<AreaUnits type="QString">m2</AreaUnits>
|
||||
</Measurement>
|
||||
<PositionPrecision>
|
||||
<Automatic type="bool">true</Automatic>
|
||||
<DegreeFormat type="QString">D</DegreeFormat>
|
||||
<DecimalPlaces type="int">2</DecimalPlaces>
|
||||
</PositionPrecision>
|
||||
<DefaultStyles>
|
||||
<AlphaInt type="int">255</AlphaInt>
|
||||
<Marker type="QString"></Marker>
|
||||
<Fill type="QString"></Fill>
|
||||
<ColorRamp type="QString"></ColorRamp>
|
||||
<Line type="QString"></Line>
|
||||
<RandomColors type="bool">true</RandomColors>
|
||||
</DefaultStyles>
|
||||
<SpatialRefSys>
|
||||
<ProjectCRSID type="int">3452</ProjectCRSID>
|
||||
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
|
||||
<ProjectCRSProj4String type="QString">+proj=longlat +datum=WGS84 +no_defs</ProjectCRSProj4String>
|
||||
<ProjectCrs type="QString">EPSG:4326</ProjectCrs>
|
||||
</SpatialRefSys>
|
||||
<WMSOnlineResource type="QString"></WMSOnlineResource>
|
||||
<WMSContactPosition type="QString"></WMSContactPosition>
|
||||
<WMSContactOrganization type="QString">QGIS dev team</WMSContactOrganization>
|
||||
<WMSKeywordList type="QStringList">
|
||||
<value></value>
|
||||
</WMSKeywordList>
|
||||
<Measure>
|
||||
<Ellipsoid type="QString">WGS84</Ellipsoid>
|
||||
</Measure>
|
||||
<WMSAddWktGeometry type="bool">true</WMSAddWktGeometry>
|
||||
<WMSContactMail type="QString">elpaso@itopen.it</WMSContactMail>
|
||||
<WMSContactPhone type="QString"></WMSContactPhone>
|
||||
<Gui>
|
||||
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
|
||||
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
|
||||
<CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
|
||||
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
|
||||
<CanvasColorRedPart type="int">255</CanvasColorRedPart>
|
||||
<CanvasColorBluePart type="int">255</CanvasColorBluePart>
|
||||
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
|
||||
</Gui>
|
||||
<WMSImageQuality type="int">90</WMSImageQuality>
|
||||
<WCSLayers type="QStringList"/>
|
||||
<WMSAccessConstraints type="QString">None</WMSAccessConstraints>
|
||||
<WMSServiceAbstract type="QString">Some UTF8 text èòù</WMSServiceAbstract>
|
||||
<WFSLayers type="QStringList">
|
||||
<value>testlayer20150528120452665</value>
|
||||
</WFSLayers>
|
||||
<Identify>
|
||||
<disabledLayers type="QStringList"/>
|
||||
</Identify>
|
||||
<WMSExtent type="QStringList">
|
||||
<value>8.20315414376310059</value>
|
||||
<value>44.901236559338642</value>
|
||||
<value>8.204164917965862</value>
|
||||
<value>44.90159838674664172</value>
|
||||
</WMSExtent>
|
||||
<WFSTLayers>
|
||||
<Insert type="QStringList">
|
||||
<value>testlayer20150528120452665</value>
|
||||
</Insert>
|
||||
<Update type="QStringList">
|
||||
<value>testlayer20150528120452665</value>
|
||||
</Update>
|
||||
<Delete type="QStringList">
|
||||
<value>testlayer20150528120452665</value>
|
||||
</Delete>
|
||||
</WFSTLayers>
|
||||
<WCSUrl type="QString"></WCSUrl>
|
||||
<Digitizing>
|
||||
<DefaultSnapType type="QString">off</DefaultSnapType>
|
||||
<LayerSnapToList type="QStringList"/>
|
||||
<AvoidIntersectionsList type="QStringList"/>
|
||||
<DefaultSnapTolerance type="double">0</DefaultSnapTolerance>
|
||||
<DefaultSnapToleranceUnit type="int">2</DefaultSnapToleranceUnit>
|
||||
<LayerSnappingList type="QStringList"/>
|
||||
<LayerSnappingToleranceUnitList type="QStringList"/>
|
||||
<LayerSnappingToleranceList type="QStringList"/>
|
||||
<SnappingMode type="QString">current_layer</SnappingMode>
|
||||
<LayerSnappingEnabledList type="QStringList"/>
|
||||
</Digitizing>
|
||||
<Macros>
|
||||
<pythonCode type="QString"></pythonCode>
|
||||
</Macros>
|
||||
<WMSRestrictedComposers type="QStringList"/>
|
||||
<Legend>
|
||||
<filterByMap type="bool">false</filterByMap>
|
||||
</Legend>
|
||||
<Paths>
|
||||
<Absolute type="bool">false</Absolute>
|
||||
</Paths>
|
||||
<WMSContactPerson type="QString">Alessandro Pasotti</WMSContactPerson>
|
||||
<WMSUrl type="QString"></WMSUrl>
|
||||
<WMSUseLayerIDs type="bool">false</WMSUseLayerIDs>
|
||||
<WMSFees type="QString">conditions unknown</WMSFees>
|
||||
<WMSServiceCapabilities type="bool">true</WMSServiceCapabilities>
|
||||
<WFSUrl type="QString"></WFSUrl>
|
||||
</properties>
|
||||
<visibility-presets/>
|
||||
<Annotations/>
|
||||
<Layouts/>
|
||||
</qgis>
|