9 changes: 5 additions & 4 deletions python/server/qgswmserver.sip
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class QgsConfigParser;
class QgsFeature;
class QgsFeatureRenderer;
class QgsMapLayer;
class QgsMapRenderer;
class QgsMapSettings;
class QgsPoint;
class QgsRasterLayer;
class QgsRasterRenderer;
Expand All @@ -41,6 +41,8 @@ class QgsRenderContext;
class QgsVectorLayer;
class QgsSymbol;
class QgsSymbol;
class QgsAccessControl;

class QColor;
class QFile;
class QFont;
Expand All @@ -57,9 +59,8 @@ class QgsWmsServer: public QgsOWSServer
{
public:
/** Constructor. Does _NOT_ take ownership of
QgsConfigParser, QgsCapabilitiesCache and QgsMapRenderer*/
QgsWmsServer( const QString& configFilePath, QMap<QString, QString> &parameters, QgsWmsConfigParser* cp, QgsRequestHandler* rh,
QgsMapRenderer* renderer, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
QgsConfigParser, QgsCapabilitiesCache*/
QgsWmsServer( const QString& configFilePath, QMap<QString, QString> &parameters, QgsWmsConfigParser* cp, QgsRequestHandler* rh, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
~QgsWmsServer();

void executeRequest() override;
Expand Down
10 changes: 5 additions & 5 deletions python/server/qgswmsprojectparser.sip
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ class QgsWmsProjectParser : public QgsWmsConfigParser
int wmsPrecision() const /*override*/ ;

//printing
//QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap* >& mapList, //QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const /*override*/ ;
//QgsComposition* initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap* >& mapList, //QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const /*override*/ ;

void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const /*override*/ ;

//todo: fixme
void setScaleDenominator( double ) /*override*/;
void addExternalGMLData( const QString&, QDomDocument* ) /*override*/ ;

QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const /*override*/ ;
QList< QPair< QString, QgsDatumTransformStore::Entry > > layerCoordinateTransforms() const /*override*/ ;

/** Fills a layer and a style list. The two list have the same number of entries and the style and the layer at a position belong together (similar to the HTTP parameters 'Layers' and 'Styles'. Returns 0 in case of success*/
int layersAndStyles( QStringList& layers, QStringList& styles ) const /*override*/ ;
Expand All @@ -78,7 +78,7 @@ class QgsWmsProjectParser : public QgsWmsConfigParser
QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const /*override*/ ;

/** Returns if output are MM or PIXEL*/
QgsMapRenderer::OutputUnits outputUnits() const /*override*/ ;
QgsUnitTypes::RenderUnit outputUnits() const /*override*/ ;

/** True if the feature info response should contain the wkt geometry for vector features*/
bool featureInfoWithWktGeometry() const /*override*/ ;
Expand All @@ -102,8 +102,8 @@ class QgsWmsProjectParser : public QgsWmsConfigParser
/** Draw text annotation items from the QGIS projectfile*/
void drawOverlays( QPainter* p, int dpi, int width, int height ) const /*override*/ ;

/** Load PAL engine settings from projectfile*/
void loadLabelSettings( QgsLabelingEngineInterface* lbl ) const /*override*/ ;
/** Load PAL engine settings into global project instance*/
void loadLabelSettings() const /*override*/ ;

int nLayers() const /*override*/ ;

Expand Down
1 change: 0 additions & 1 deletion python/server/server.sip
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
%Include qgsaccesscontrol.sip
%End

%Include qgsmaprenderer.sip
%Include qgsmapserviceexception.sip
%Include qgscapabilitiescache.sip
%Include qgsrequesthandler.sip
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsmaprendererjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ QgsMapRendererJob::QgsMapRendererJob( const QgsMapSettings& settings )
: mSettings( settings )
, mCache( nullptr )
, mRenderingTime( 0 )
, mFeatureFilterProvider( nullptr )
{
}

Expand Down Expand Up @@ -249,6 +250,9 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsLabelingEn
job.context.setCoordinateTransform( ct );
job.context.setExtent( r1 );

if ( mFeatureFilterProvider )
job.context.setFeatureFilterProvider( mFeatureFilterProvider );

// if we can use the cache, let's do it and avoid rendering!
if ( mCache && !mCache->cacheImage( ml->id() ).isNull() )
{
Expand Down
16 changes: 15 additions & 1 deletion src/core/qgsmaprendererjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class QgsLabelingResults;
class QgsMapLayerRenderer;
class QgsMapRendererCache;
class QgsPalLabeling;
class QgsFeatureFilterProvider;


/** \ingroup core
Expand Down Expand Up @@ -105,6 +106,18 @@ class CORE_EXPORT QgsMapRendererJob : public QObject
//! Get pointer to internal labeling engine (in order to get access to the results)
virtual QgsLabelingResults* takeLabelingResults() = 0;

//! @note Added in QGIS 3.0
//! Set the feature filter provider used by the QgsRenderContext of
//! each LayerRenderJob.
//! Ownership is not transferred and the provider must not be deleted
//! before the render job.
void setFeatureFilterProvider( const QgsFeatureFilterProvider *f ) { mFeatureFilterProvider = f; };

//! @note Added in QGIS 3.0
//! Returns the feature filter provider used by the QgsRenderContext of
//! each LayerRenderJob.
const QgsFeatureFilterProvider* featureFilterProvider() const { return mFeatureFilterProvider; };

struct Error
{
Error( const QString& lid, const QString& msg )
Expand Down Expand Up @@ -182,7 +195,6 @@ class CORE_EXPORT QgsMapRendererJob : public QObject

//! called when rendering has finished to update all layers' geometry caches
void updateLayerGeometryCaches();

QgsMapSettings mSettings;
Errors mErrors;

Expand All @@ -195,6 +207,8 @@ class CORE_EXPORT QgsMapRendererJob : public QObject

QTime mRenderingStart;
int mRenderingTime;

const QgsFeatureFilterProvider *mFeatureFilterProvider;
};


Expand Down
4 changes: 1 addition & 3 deletions src/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ SET ( qgis_mapserv_SRCS
qgswfsserver.cpp
qgswcsserver.cpp
qgsmapserviceexception.cpp
qgsmaprenderer.cpp
qgsmslayercache.cpp
qgsmslayerbuilder.cpp
qgshostedvdsbuilder.cpp
Expand All @@ -41,7 +40,7 @@ SET ( qgis_mapserv_SRCS
qgsremotedatasourcebuilder.cpp
qgssentdatasourcebuilder.cpp
qgsserverlogger.cpp
qgsmsutils.cpp
qgsmapserverutils.cpp
qgswcsprojectparser.cpp
qgswfsprojectparser.cpp
qgswmsconfigparser.cpp
Expand All @@ -67,7 +66,6 @@ SET (qgis_mapserv_MOC_HDRS
qgscapabilitiescache.h
qgsconfigcache.h
# qgshttptransaction.h
qgsmaprenderer.h
qgsmslayercache.h
qgsserverlogger.h
qgsserverstreamingdevice.h
Expand Down
1,154 changes: 0 additions & 1,154 deletions src/server/qgsmaprenderer.cpp

This file was deleted.

395 changes: 0 additions & 395 deletions src/server/qgsmaprenderer.h

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
qgsmsutils.cpp
qgsmapserverutils.cpp
---------------------
begin : August 2010
copyright : (C) 2010 by Marco Hugentobler
Expand All @@ -12,15 +12,15 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsmsutils.h"
#include "qgsmapserverutils.h"
#include "qgslogger.h"
#include <stdlib.h>
#include <time.h>
#include <QDir>
#include <QFileInfo>
#include <QTextStream>

QString QgsMSUtils::createTempFilePath()
QString QgsMapServerUtils::createTempFilePath()
{


Expand Down Expand Up @@ -67,7 +67,7 @@ QString QgsMSUtils::createTempFilePath()
return tempFilePath;
}

int QgsMSUtils::createTextFile( const QString& filePath, const QString& text )
int QgsMapServerUtils::createTextFile( const QString& filePath, const QString& text )
{
QFile file( filePath );
if ( file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
qgsmsutils.h
qgsmapserverutils.h
---------------------
begin : August 2010
copyright : (C) 2010 by Marco Hugentobler
Expand All @@ -12,13 +12,13 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSMSUTILS_H
#define QGSMSUTILS_H
#ifndef QGSMAPSERVERUTILS_H
#define QGSMAPSERVERUTILS_H

#include <QString>

//! Some utility functions that may be included from everywhere in the code
namespace QgsMSUtils
namespace QgsMapServerUtils
{

/** Creates a ramdom filename for a temporary file. This function also creates the directory to store
Expand Down
11 changes: 1 addition & 10 deletions src/server/qgsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "qgsconfig.h"
#include "qgsserver.h"

#include "qgsmapsettings.h"
#include "qgsauthmanager.h"
#include "qgscapabilitiescache.h"
#include "qgsfontutils.h"
Expand Down Expand Up @@ -61,7 +62,6 @@

QString* QgsServer::sConfigFilePath = nullptr;
QgsCapabilitiesCache* QgsServer::sCapabilitiesCache = nullptr;
QgsMapRenderer* QgsServer::sMapRenderer = nullptr;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
QgsServerInterfaceImpl*QgsServer::sServerInterface = nullptr;
#endif
Expand Down Expand Up @@ -386,8 +386,6 @@ bool QgsServer::init( )

//create cache for capabilities XML
sCapabilitiesCache = new QgsCapabilitiesCache();
sMapRenderer = new QgsMapRenderer;
sMapRenderer->setLabelingEngine( new QgsPalLabeling() );

#ifdef ENABLE_MS_TESTS
QgsFontUtils::loadStandardTestFonts( QStringList() << QStringLiteral( "Roman" ) << QStringLiteral( "Bold" ) );
Expand Down Expand Up @@ -440,12 +438,6 @@ QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString& queryStri
QTime time; //used for measuring request time if loglevel < 1
QgsProject::instance()->removeAllMapLayers();

// Clean up Expression Context
// because each call to QgsMapLayer::draw add items to QgsExpressionContext scope
// list. This prevent the scope list to grow indefinitely and seriously deteriorate
// performances and memory in the long run
sMapRenderer->rendererContext()->setExpressionContext( QgsExpressionContext() );

qApp->processEvents();

if ( logLevel < 1 )
Expand Down Expand Up @@ -594,7 +586,6 @@ QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString& queryStri
, parameterMap
, p
, theRequestHandler.data()
, sMapRenderer
, sCapabilitiesCache
#ifdef HAVE_SERVER_PYTHON_PLUGINS
, accessControl
Expand Down
3 changes: 1 addition & 2 deletions src/server/qgsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include <QFileInfo>
#include "qgsrequesthandler.h"
#include "qgsapplication.h"
#include "qgsmaprenderer.h"
#include "qgsconfigcache.h"
#include "qgscapabilitiescache.h"
#include "qgsmapsettings.h"

#ifdef HAVE_SERVER_PYTHON_PLUGINS
#include "qgsserverplugins.h"
Expand Down Expand Up @@ -121,7 +121,6 @@ class SERVER_EXPORT QgsServer
// Status
static QString* sConfigFilePath;
static QgsCapabilitiesCache* sCapabilitiesCache;
static QgsMapRenderer* sMapRenderer;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
static QgsServerInterfaceImpl* sServerInterface;
#endif
Expand Down
1 change: 0 additions & 1 deletion src/server/qgsserverinterfaceimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "qgsgetrequesthandler.h"
#include "qgspostrequesthandler.h"
#include "qgssoaprequesthandler.h"
#include "qgsmaprenderer.h"

/**
* QgsServerInterface
Expand Down
2 changes: 1 addition & 1 deletion src/server/qgsserverplugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "qgslogger.h"
#include "qgspythonutils.h"
#include "qgsserverlogger.h"
#include "qgsmsutils.h"
#include "qgsmapserverutils.h"

#include <QLibrary>

Expand Down
8 changes: 4 additions & 4 deletions src/server/qgsserverprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1463,9 +1463,9 @@ QList<QDomElement> QgsServerProjectParser::publishedComposerElements() const
return composerElemList;
}

QList< QPair< QString, QgsLayerCoordinateTransform > > QgsServerProjectParser::layerCoordinateTransforms() const
QList< QPair< QString, QgsDatumTransformStore::Entry > > QgsServerProjectParser::layerCoordinateTransforms() const
{
QList< QPair< QString, QgsLayerCoordinateTransform > > layerTransformList;
QList< QPair< QString, QgsDatumTransformStore::Entry > > layerTransformList;

QDomElement coordTransformInfoElem = mXMLDoc->documentElement().firstChildElement( QStringLiteral( "mapcanvas" ) ).firstChildElement( QStringLiteral( "layer_coordinate_transform_info" ) );
if ( coordTransformInfoElem.isNull() )
Expand All @@ -1477,10 +1477,10 @@ QList< QPair< QString, QgsLayerCoordinateTransform > > QgsServerProjectParser::l
layerTransformList.reserve( layerTransformNodeList.size() );
for ( int i = 0; i < layerTransformNodeList.size(); ++i )
{
QPair< QString, QgsLayerCoordinateTransform > layerEntry;
QPair< QString, QgsDatumTransformStore::Entry > layerEntry;
QDomElement layerTransformElem = layerTransformNodeList.at( i ).toElement();
layerEntry.first = layerTransformElem.attribute( QStringLiteral( "layerid" ) );
QgsLayerCoordinateTransform t;
QgsDatumTransformStore::Entry t;
t.srcAuthId = layerTransformElem.attribute( QStringLiteral( "srcAuthId" ) );
t.destAuthId = layerTransformElem.attribute( QStringLiteral( "destAuthId" ) );
t.srcDatumTransform = layerTransformElem.attribute( QStringLiteral( "srcDatumTransform" ), QStringLiteral( "-1" ) ).toInt();
Expand Down
4 changes: 2 additions & 2 deletions src/server/qgsserverprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "qgsconfig.h"
#include "qgsvectorlayer.h"
#include "qgsmaprenderer.h"
#include "qgsdatumtransformstore.h"

#include <QDomElement>
#include <QHash>
Expand Down Expand Up @@ -99,7 +99,7 @@ class SERVER_EXPORT QgsServerProjectParser

QList<QDomElement> publishedComposerElements() const;

QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const;
QList< QPair< QString, QgsDatumTransformStore::Entry > > layerCoordinateTransforms() const;

/** Returns the text of the <layername> element for a layer element
@return name or a null string in case of error*/
Expand Down
29 changes: 10 additions & 19 deletions src/server/qgssldconfigparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ QgsSLDConfigParser::QgsSLDConfigParser( QDomDocument* doc, const QMap<QString, Q
, mXMLDoc( doc )
, mParameterMap( parameters )
, mSLDNamespace( QStringLiteral( "http://www.opengis.net/sld" ) )
, mOutputUnits( QgsMapRenderer::Pixels )
, mOutputUnits( QgsUnitTypes::RenderUnit::RenderPixels )
, mFallbackParser( nullptr )
{

Expand All @@ -76,11 +76,11 @@ QgsSLDConfigParser::QgsSLDConfigParser( QDomDocument* doc, const QMap<QString, Q
{
if ( unitString == QLatin1String( "mm" ) )
{
mOutputUnits = QgsMapRenderer::Millimeters;
mOutputUnits = QgsUnitTypes::RenderUnit::RenderMillimeters;
}
else if ( unitString == QLatin1String( "pixel" ) )
{
mOutputUnits = QgsMapRenderer::Pixels;
mOutputUnits = QgsUnitTypes::RenderUnit::RenderPixels;
}
}
}
Expand Down Expand Up @@ -490,7 +490,7 @@ QDomDocument QgsSLDConfigParser::describeLayer( QStringList& layerList, const QS
return QDomDocument();
}

QgsMapRenderer::OutputUnits QgsSLDConfigParser::outputUnits() const
QgsUnitTypes::RenderUnit QgsSLDConfigParser::outputUnits() const
{
return mOutputUnits;
}
Expand Down Expand Up @@ -564,11 +564,11 @@ void QgsSLDConfigParser::drawOverlays( QPainter* p, int dpi, int width, int heig
}
}

void QgsSLDConfigParser::loadLabelSettings( QgsLabelingEngineInterface * lbl ) const
void QgsSLDConfigParser::loadLabelSettings() const
{
if ( mFallbackParser )
{
mFallbackParser->loadLabelSettings( lbl );
mFallbackParser->loadLabelSettings();
}
}

Expand Down Expand Up @@ -724,20 +724,11 @@ bool QgsSLDConfigParser::wmsInspireActivated() const
return false;
}

QgsComposition* QgsSLDConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const
QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
{
if ( mFallbackParser )
{
return mFallbackParser->createPrintComposition( composerTemplate, mapRenderer, parameterMap, highlightLayers );
}
return nullptr;
}

QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
{
if ( mFallbackParser )
{
return mFallbackParser->initComposition( composerTemplate, mapRenderer, mapList, legendList, labelList, htmlFrameList );
return mFallbackParser->initComposition( composerTemplate, mapSettings, mapList, legendList, labelList, htmlFrameList );
}
return nullptr;
}
Expand Down Expand Up @@ -768,9 +759,9 @@ void QgsSLDConfigParser::addExternalGMLData( const QString &, QDomDocument * )
//soon...
}

QList< QPair< QString, QgsLayerCoordinateTransform > > QgsSLDConfigParser::layerCoordinateTransforms() const
QList< QPair< QString, QgsDatumTransformStore::Entry > > QgsSLDConfigParser::layerCoordinateTransforms() const
{
return QList< QPair< QString, QgsLayerCoordinateTransform > >();
return QList< QPair< QString, QgsDatumTransformStore::Entry > >();
}

int QgsSLDConfigParser::nLayers() const
Expand Down
14 changes: 7 additions & 7 deletions src/server/qgssldconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class QgsSLDConfigParser : public QgsWmsConfigParser
QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const override;

//! Returns if output are MM or PIXEL
QgsMapRenderer::OutputUnits outputUnits() const override;
QgsUnitTypes::RenderUnit outputUnits() const override;

//! Returns an ID-list of layers which are not queryable (comes from <properties> -> <Identify> -> <disabledLayers in the project file
QStringList identifyDisabledLayers() const override;
Expand All @@ -83,8 +83,8 @@ class QgsSLDConfigParser : public QgsWmsConfigParser
//! Draw text annotation items from the QGIS projectfile
void drawOverlays( QPainter* p, int dpi, int width, int height ) const override;

//! Load PAL engine settings from projectfile
void loadLabelSettings( QgsLabelingEngineInterface* lbl ) const override;
//! Load PAL engine settings into global project instance
void loadLabelSettings() const override;

QString serviceUrl() const override;

Expand Down Expand Up @@ -116,18 +116,18 @@ class QgsSLDConfigParser : public QgsWmsConfigParser
//printing

//! Creates a print composition, usually for a GetPrint request. Replaces map and label parameters
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const;
QgsComposition* createPrintComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const;

//! Creates a composition from the project file (probably delegated to the fallback parser)
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const override;
QgsComposition* initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const override;

//! Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element
void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const override;

void setScaleDenominator( double denom ) override;
void addExternalGMLData( const QString& layerName, QDomDocument* gmlDoc ) override;

QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const override;
QList< QPair< QString, QgsDatumTransformStore::Entry > > layerCoordinateTransforms() const override;

int nLayers() const override;

Expand All @@ -146,7 +146,7 @@ class QgsSLDConfigParser : public QgsWmsConfigParser
QString mSLDNamespace;

//! Output units (pixel or mm)
QgsMapRenderer::OutputUnits mOutputUnits;
QgsUnitTypes::RenderUnit mOutputUnits;

QgsWmsConfigParser *mFallbackParser;

Expand Down
1 change: 0 additions & 1 deletion src/server/qgswfsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "qgsfeatureiterator.h"
#include "qgsgeometry.h"
#include "qgsmaplayer.h"
#include "qgsmaprenderer.h"
#include "qgsmaptopixel.h"
#include "qgsmessagelog.h"
#include "qgspallabeling.h"
Expand Down
1 change: 0 additions & 1 deletion src/server/qgswfsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class QgsCoordinateReferenceSystem;
class QgsComposition;
class QgsFields;
class QgsMapLayer;
class QgsMapRenderer;
class QgsPoint;
class QgsRasterLayer;
class QgsConfigParser;
Expand Down
13 changes: 4 additions & 9 deletions src/server/qgswmsconfigparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "qgscomposerhtml.h"
#include "qgscomposerframe.h"
#include "qgscomposition.h"
#include "qgsmapsettings.h"

#include "qgslayertreegroup.h"
#include "qgslayertreelayer.h"
Expand All @@ -45,20 +46,14 @@ QgsWmsConfigParser::~QgsWmsConfigParser()

}

QgsComposition* QgsWmsConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
QStringList highlightLayers;
return createPrintComposition( composerTemplate, mapRenderer, parameterMap, highlightLayers );
}

QgsComposition* QgsWmsConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const
QgsComposition* QgsWmsConfigParser::createPrintComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const
{
QList<QgsComposerMap*> composerMaps;
QList<QgsComposerLegend*> composerLegends;
QList<QgsComposerLabel*> composerLabels;
QList<const QgsComposerHtml*> composerHtmls;

QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLegends, composerLabels, composerHtmls );
QgsComposition* c = initComposition( composerTemplate, mapSettings, composerMaps, composerLegends, composerLabels, composerHtmls );
if ( !c )
{
return nullptr;
Expand Down Expand Up @@ -113,7 +108,7 @@ QgsComposition* QgsWmsConfigParser::createPrintComposition( const QString& compo

//Change x- and y- of extent for WMS 1.3.0 if axis inverted
QString version = parameterMap.value( QStringLiteral( "VERSION" ) );
if ( version == QLatin1String( "1.3.0" ) && mapRenderer && mapRenderer->destinationCrs().hasAxisInverted() )
if ( version == QLatin1String( "1.3.0" ) && mapSettings.destinationCrs().hasAxisInverted() )
{
r.invert();
}
Expand Down
24 changes: 12 additions & 12 deletions src/server/qgswmsconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@
#ifndef QGSWMSCONFIGPARSER_H
#define QGSWMSCONFIGPARSER_H

#include "qgsmaprenderer.h"
#include "qgsunittypes.h"
#include "qgspallabeling.h"
#include "qgsdatumtransformstore.h"

class QPainter;
class QDomDocument;
class QgsComposerHtml;
class QgsComposerLabel;
class QgsComposerLegend;
class QgsComposerMap;
class QgsComposition;
class QgsMapLayer;
class QgsLegendModel;
class QgsMapSettings;


class SERVER_EXPORT QgsWmsConfigParser
Expand Down Expand Up @@ -56,7 +61,7 @@ class SERVER_EXPORT QgsWmsConfigParser
virtual QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const = 0;

//! Returns if output are MM or PIXEL
virtual QgsMapRenderer::OutputUnits outputUnits() const = 0;
virtual QgsUnitTypes::RenderUnit outputUnits() const = 0;

//! Returns an ID-list of layers which are not queryable (comes from <properties> -> <Identify> -> <disabledLayers in the project file
virtual QStringList identifyDisabledLayers() const = 0;
Expand All @@ -82,8 +87,8 @@ class SERVER_EXPORT QgsWmsConfigParser
//! Draw text annotation items from the QGIS projectfile
virtual void drawOverlays( QPainter* p, int dpi, int width, int height ) const = 0;

//! Load PAL engine settings from the QGIS projectfile
virtual void loadLabelSettings( QgsLabelingEngineInterface* lbl ) const = 0;
//! Load PAL engine settings into global project instance
virtual void loadLabelSettings() const = 0;

virtual QString serviceUrl() const = 0;

Expand Down Expand Up @@ -115,23 +120,18 @@ class SERVER_EXPORT QgsWmsConfigParser
virtual void inspireCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;

//printing

//! Creates a print composition, usually for a GetPrint request. Replaces map and label parameters
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;

//! Creates a print composition, usually for a GetPrint request. Replaces map and label parameters
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const;
QgsComposition* createPrintComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, const QMap< QString, QString >& parameterMap, QStringList& highlightLayers ) const;

//! Creates a composition from the project file (probably delegated to the fallback parser)
virtual QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const = 0;
virtual QgsComposition* initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const = 0;

//! Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element
virtual void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;

virtual void setScaleDenominator( double denom ) = 0;
virtual void addExternalGMLData( const QString& layerName, QDomDocument* gmlDoc ) = 0;

virtual QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const = 0;
virtual QList< QPair< QString, QgsDatumTransformStore::Entry > > layerCoordinateTransforms() const = 0;

virtual int nLayers() const = 0;

Expand Down
147 changes: 80 additions & 67 deletions src/server/qgswmsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "qgsmaplayerstylemanager.h"
#include "qgsmapserviceexception.h"
#include "qgspallabeling.h"
#include "qgsproject.h"
#include "qgsrenderer.h"
#include "qgsvectorlayer.h"

Expand Down Expand Up @@ -468,7 +469,7 @@ bool QgsWmsProjectParser::wmsInspireActivated() const
return inspireActivated;
}

QgsComposition* QgsWmsProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlList ) const
QgsComposition* QgsWmsProjectParser::initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlList ) const
{
//Create composition from xml
QDomElement composerElem = composerByName( composerTemplate );
Expand All @@ -483,7 +484,7 @@ QgsComposition* QgsWmsProjectParser::initComposition( const QString& composerTem
return nullptr;
}

QgsComposition* composition = new QgsComposition( mapRenderer->mapSettings() ); //set resolution, paper size from composer element attributes
QgsComposition* composition = new QgsComposition( mapSettings ); //set resolution, paper size from composer element attributes
if ( !composition->readXml( compositionElem, *( mProjectParser->xmlDocument() ) ) )
{
delete composition;
Expand Down Expand Up @@ -799,7 +800,7 @@ void QgsWmsProjectParser::inspireCapabilities( QDomElement& parentElement, QDomD
parentElement.appendChild( inspireCapabilitiesElem );
}

QList< QPair< QString, QgsLayerCoordinateTransform > > QgsWmsProjectParser::layerCoordinateTransforms() const
QList< QPair< QString, QgsDatumTransformStore::Entry > > QgsWmsProjectParser::layerCoordinateTransforms() const
{
return mProjectParser->layerCoordinateTransforms();
}
Expand Down Expand Up @@ -1992,9 +1993,9 @@ QDomDocument QgsWmsProjectParser::describeLayer( QStringList& layerList, const Q
return myDocument;
}

QgsMapRenderer::OutputUnits QgsWmsProjectParser::outputUnits() const
QgsUnitTypes::RenderUnit QgsWmsProjectParser::outputUnits() const
{
return QgsMapRenderer::Millimeters;
return QgsUnitTypes::RenderUnit::RenderMillimeters;
}

bool QgsWmsProjectParser::featureInfoWithWktGeometry() const
Expand Down Expand Up @@ -2233,77 +2234,89 @@ void QgsWmsProjectParser::drawOverlays( QPainter* p, int dpi, int width, int hei
}
}

void QgsWmsProjectParser::loadLabelSettings( QgsLabelingEngineInterface* lbl ) const
void QgsWmsProjectParser::loadLabelSettings() const
{
QgsPalLabeling* pal = dynamic_cast<QgsPalLabeling*>( lbl );
if ( pal )
{
QDomElement propertiesElem = mProjectParser->propertiesElem();
if ( propertiesElem.isNull() )
{
return;
}

QDomElement palElem = propertiesElem.firstChildElement( QStringLiteral( "PAL" ) );
if ( palElem.isNull() )
{
return;
}

//pal::Pal default positions for candidates;
int candPoint, candLine, candPoly;
pal->numCandidatePositions( candPoint, candLine, candPoly );

//mCandPoint
QDomElement candPointElem = palElem.firstChildElement( QStringLiteral( "CandidatesPoint" ) );
if ( !candPointElem.isNull() )
{
candPoint = candPointElem.text().toInt();
}
int searchMethod, nCandPoint, nCandLine, nCandPoly;
bool showingCandidates, drawRectOnly, showingShadowRects, showingAllLabels, showingPartialsLabels, drawOutlineLabels;

readLabelSettings( searchMethod, nCandPoint, nCandLine, nCandPoly, showingCandidates, drawRectOnly, showingShadowRects, showingAllLabels, showingPartialsLabels, drawOutlineLabels );

QgsProject::instance()->writeEntry( "PAL", "/SearchMethod", searchMethod );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPoint", nCandPoint );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesLine", nCandLine );
QgsProject::instance()->writeEntry( "PAL", "/CandidatesPolygon", nCandPoly );

QgsProject::instance()->writeEntry( "PAL", "/ShowingCandidates", showingCandidates );
QgsProject::instance()->writeEntry( "PAL", "/DrawRectOnly", drawRectOnly );
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", showingShadowRects );
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", showingAllLabels );
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", showingPartialsLabels );
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", drawOutlineLabels );
}

//mCandLine
QDomElement candLineElem = palElem.firstChildElement( QStringLiteral( "CandidatesLine" ) );
if ( !candLineElem.isNull() )
{
candLine = candLineElem.text().toInt();
}
void QgsWmsProjectParser::readLabelSettings( int& searchMethod, int& nCandPoint, int& nCandLine, int& nCandPoly, bool& showingCandidates, bool& drawRectOnly, bool& showingShadowRects, bool& showingAllLabels, bool& showingPartialsLabels, bool& drawOutlineLabels ) const
{
searchMethod = static_cast< int >( QgsPalLabeling::Chain );
nCandPoint = 8;
nCandLine = 8;
nCandPoly = 8;
showingCandidates = false;
drawRectOnly = false;
showingShadowRects = false;
showingAllLabels = false;
showingPartialsLabels = true;
drawOutlineLabels = true;

//mCandPolygon
QDomElement candPolyElem = palElem.firstChildElement( QStringLiteral( "CandidatesPolygon" ) );
if ( !candPolyElem.isNull() )
{
candPoly = candPolyElem.text().toInt();
}
QDomElement propertiesElem = mProjectParser->propertiesElem();
if ( propertiesElem.isNull() )
{
return;
}

pal->setNumCandidatePositions( candPoint, candLine, candPoly );
QDomElement palElem = propertiesElem.firstChildElement( "PAL" );
if ( palElem.isNull() )
{
return;
}

//mShowingCandidates
QDomElement showCandElem = palElem.firstChildElement( QStringLiteral( "ShowingCandidates" ) );
if ( !showCandElem.isNull() )
{
pal->setShowingCandidates( showCandElem.text().compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
}
QDomElement candPointElem = palElem.firstChildElement( "CandidatesPoint" );
if ( !candPointElem.isNull() )
{
nCandPoint = candPointElem.text().toInt();
}
QDomElement candLineElem = palElem.firstChildElement( "CandidatesLine" );
if ( !candLineElem.isNull() )
{
nCandLine = candLineElem.text().toInt();
}
QDomElement candPolyElem = palElem.firstChildElement( "CandidatesPolygon" );
if ( !candPolyElem.isNull() )
{
nCandPoly = candPolyElem.text().toInt();
}

//mShowingAllLabels
QDomElement showAllLabelsElem = palElem.firstChildElement( QStringLiteral( "ShowingAllLabels" ) );
if ( !showAllLabelsElem.isNull() )
{
pal->setShowingAllLabels( showAllLabelsElem.text().compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
}
QDomElement showCandElem = palElem.firstChildElement( "ShowingCandidates" );
if ( !showCandElem.isNull() )
{
showingCandidates = showCandElem.text().compare( "true", Qt::CaseInsensitive ) == 0;
}

//mShowingPartialsLabels
QDomElement showPartialsLabelsElem = palElem.firstChildElement( QStringLiteral( "ShowingPartialsLabels" ) );
if ( !showPartialsLabelsElem.isNull() )
{
pal->setShowingPartialsLabels( showPartialsLabelsElem.text().compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
}
QDomElement showAllLabelsElem = palElem.firstChildElement( "ShowingAllLabels" );
if ( !showAllLabelsElem.isNull() )
{
showingAllLabels = showAllLabelsElem.text().compare( "true", Qt::CaseInsensitive ) == 0;
}

//mDrawOutlineLabels
// TODO: This should probably always be true (already default) for WMS, regardless of any project setting.
// Not much sense to output text-as-text, when text-as-outlines gives better results.
QDomElement showPartialsLabelsElem = palElem.firstChildElement( "ShowingPartialsLabels" );
if ( !showPartialsLabelsElem.isNull() )
{
showingPartialsLabels = showPartialsLabelsElem.text().compare( "true", Qt::CaseInsensitive ) == 0;
}

//save settings into global project instance (QgsMapRendererCustomPainterJob reads label settings from there)
pal->saveEngineSettings();
QDomElement drawOutlineLabelsElem = palElem.firstChildElement( "DrawOutlineLabels" );
if ( !drawOutlineLabelsElem.isNull() )
{
drawOutlineLabels = drawOutlineLabelsElem.text().compare( "true", Qt::CaseInsensitive ) == 0;
}
}

Expand Down
13 changes: 8 additions & 5 deletions src/server/qgswmsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class QgsAccessControl;

class QTextDocument;
class QSvgRenderer;
class QgsMapSettings;

class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
{
Expand Down Expand Up @@ -73,14 +74,14 @@ class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
void inspireCapabilities( QDomElement& parentElement, QDomDocument& doc ) const override;

//printing
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const override;
QgsComposition* initComposition( const QString& composerTemplate, const QgsMapSettings& mapSettings, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const override;
void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const override;

//todo: fixme
void setScaleDenominator( double ) override {}
void addExternalGMLData( const QString&, QDomDocument* ) override {}

QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const override;
QList< QPair< QString, QgsDatumTransformStore::Entry > > layerCoordinateTransforms() const override;

//! Fills a layer and a style list. The two list have the same number of entries and the style and the layer at a position belong together (similar to the HTTP parameters 'Layers' and 'Styles'. Returns 0 in case of success
int layersAndStyles( QStringList& layers, QStringList& styles ) const override;
Expand All @@ -95,7 +96,7 @@ class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const override;

//! Returns if output are MM or PIXEL
QgsMapRenderer::OutputUnits outputUnits() const override;
QgsUnitTypes::RenderUnit outputUnits() const override;

//! True if the feature info response should contain the wkt geometry for vector features
bool featureInfoWithWktGeometry() const override;
Expand All @@ -118,8 +119,8 @@ class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
//! Draw text annotation items from the QGIS projectfile
void drawOverlays( QPainter* p, int dpi, int width, int height ) const override;

//! Load PAL engine settings from projectfile
void loadLabelSettings( QgsLabelingEngineInterface* lbl ) const override;
//! Load PAL engine settings into global project instance
void loadLabelSettings() const override;

int nLayers() const override;

Expand Down Expand Up @@ -182,6 +183,8 @@ class SERVER_EXPORT QgsWmsProjectParser : public QgsWmsConfigParser
void cleanupTextAnnotationItems();

QString getCapaServiceUrl( QDomDocument& doc ) const;

void readLabelSettings( int& searchMethod, int& nCandPoint, int& nCandLine, int& nCandPoly, bool& showingCandidates, bool& drawRectOnly, bool& showingShadowRects, bool& showingAllLabels, bool& showingPartialsLabels, bool& drawOutlineLabels ) const;
};

#endif // QGSWMSPROJECTPARSER_H
262 changes: 117 additions & 145 deletions src/server/qgswmsserver.cpp

Large diffs are not rendered by default.

37 changes: 20 additions & 17 deletions src/server/qgswmsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class QgsConfigParser;
class QgsFeature;
class QgsFeatureRenderer;
class QgsMapLayer;
class QgsMapRenderer;
class QgsMapSettings;
class QgsPoint;
class QgsRasterLayer;
class QgsRasterRenderer;
Expand Down Expand Up @@ -61,13 +61,12 @@ class QgsWmsServer: public QgsOWSServer
public:

/** Constructor. Does _NOT_ take ownership of
QgsConfigParser, QgsCapabilitiesCache and QgsMapRenderer*/
QgsConfigParser and QgsCapabilitiesCache*/
QgsWmsServer(
const QString& configFilePath
, QMap<QString, QString> &parameters
, QgsWmsConfigParser* cp
, QgsRequestHandler* rh
, QgsMapRenderer* renderer
, QgsCapabilitiesCache* capCache
#ifdef HAVE_SERVER_PYTHON_PLUGINS
, const QgsAccessControl* accessControl
Expand Down Expand Up @@ -95,6 +94,10 @@ class QgsWmsServer: public QgsOWSServer
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 );

/** Identical to getMap( HitTest* hitTest ) and updates the map settings actually used.
@note added in QGIS 3.0 */
QImage* getMap( QgsMapSettings &mapSettings, HitTest* hitTest = nullptr );
//! GetMap request with vector format output. This output is usually symbolized (difference to WFS GetFeature)
void getMapAsDxf();
//! Returns an SLD file with the style of the requested layer. Exception is raised in case of troubles :-)
Expand Down Expand Up @@ -123,24 +126,24 @@ class QgsWmsServer: public QgsOWSServer
//! Don't use the default constructor
QgsWmsServer();

/** Initializes WMS layers and configures mMapRendering.
/** Initializes WMS layers and configures rendering.
@param layersList out: list with WMS layer names
@param stylesList out: list with WMS style names
@param layerIdList out: list with QGIS layer ids
@return image configured together with mMapRenderer (or 0 in case of error). The calling function takes ownership of the image*/
QImage* initializeRendering( QStringList& layersList, QStringList& stylesList, QStringList& layerIdList );
@return image configured (or 0 in case of error). The calling function takes ownership of the image*/
QImage* initializeRendering( QStringList& layersList, QStringList& stylesList, QStringList& layerIdList, QgsMapSettings& mapSettings );

/** Creates a QImage from the HEIGHT and WIDTH parameters
@param width image width (or -1 if width should be taken from WIDTH wms parameter)
@param height image height (or -1 if height should be taken from HEIGHT wms parameter)
@return 0 in case of error*/
QImage* createImage( int width = -1, int height = -1 ) const;

/** Configures mMapRenderer to the parameters
/** Configures mapSettings to the parameters
HEIGHT, WIDTH, BBOX, CRS.
@param paintDevice the device that is used for painting (for dpi)
@return 0 in case of success*/
int configureMapRender( const QPaintDevice* paintDevice ) const;
int configureMapSettings( const QPaintDevice* paintDevice, QgsMapSettings& mapSettings ) const;

/** Reads the layers and style lists from the parameters LAYERS and STYLES
@return 0 in case of success*/
Expand All @@ -150,7 +153,7 @@ class QgsWmsServer: public QgsOWSServer
set to the layer and style names according to the SLD
@return 0 in case of success*/
int initializeSLDParser( QStringList& layersList, QStringList& stylesList );
static bool infoPointToMapCoordinates( int i, int j, QgsPoint* infoPoint, QgsMapRenderer* mapRenderer );
static bool infoPointToMapCoordinates( int i, int j, QgsPoint* infoPoint, const QgsMapSettings& mapSettings );

/** Appends feature info xml for the layer to the layer element of the feature info dom document
@param featureBBox the bounding box of the selected features in output CRS
Expand All @@ -160,25 +163,26 @@ class QgsWmsServer: public QgsOWSServer
int nFeatures,
QDomDocument& infoDocument,
QDomElement& layerElement,
QgsMapRenderer* mapRender,
const QgsMapSettings& mapSettings,
QgsRenderContext& renderContext,
const QString& version,
const QString& infoFormat,
QgsRectangle* featureBBox = nullptr ) const;
//! Appends feature info xml for the layer to the layer element of the dom document
int featureInfoFromRasterLayer( QgsRasterLayer* layer,
const QgsMapSettings& mapSettings,
const QgsPoint* infoPoint,
QDomDocument& infoDocument,
QDomElement& layerElement,
const QString& version,
const QString& infoFormat ) const;

/** Creates a layer set and returns a stringlist with layer ids that can be passed to a QgsMapRenderer. Usually used in conjunction with readLayersAndStyles
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a renderer. Usually used in conjunction with readLayersAndStyles
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;

//! Record which symbols would be used if the map was in the current configuration of mMapRenderer. This is useful for content-based legend
void runHitTest( QPainter* painter, HitTest& hitTest );
//! Record which symbols would be used if the map was in the current configuration of renderer. This is useful for content-based legend
void runHitTest( const QgsMapSettings& mapSettings, QPainter* painter, HitTest& hitTest );
//! Record which symbols within one layer would be rendered with the given renderer context
void runHitTestLayer( QgsVectorLayer* vl, SymbolSet& usedSymbols, QgsRenderContext& context );

Expand All @@ -197,7 +201,7 @@ class QgsWmsServer: public QgsOWSServer
* to ensure that the original filters are always correctly restored, regardless of whether exceptions
* are thrown or functions are terminated early.
*/
void applyRequestedLayerFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalFilters ) const;
void applyRequestedLayerFilters( const QStringList& layerList, QgsMapSettings& mapSettings, QHash<QgsMapLayer*, QString>& originalFilters ) const;

#ifdef HAVE_SERVER_PYTHON_PLUGINS

Expand Down Expand Up @@ -252,8 +256,6 @@ class QgsWmsServer: public QgsOWSServer
void cleanupAfterRequest();

//! Map containing the WMS parameters
QgsMapRenderer* mMapRenderer;

QgsCapabilitiesCache* mCapabilitiesCache;

QgsWmsConfigParser* mConfigParser;
Expand All @@ -269,6 +271,7 @@ class QgsWmsServer: public QgsOWSServer
QgsVectorLayer* layer,
QDomDocument& doc,
QgsCoordinateReferenceSystem& crs,
const QgsMapSettings& mapSettings,
const QString& typeName,
bool withGeom,
int version,
Expand All @@ -284,7 +287,7 @@ class QgsWmsServer: public QgsOWSServer
int getWMSPrecision( int defaultValue ) const;

//! Gets layer search rectangle (depending on request parameter, layer type, map and layer crs)
QgsRectangle featureInfoSearchRect( QgsVectorLayer* ml, QgsMapRenderer* mr, const QgsRenderContext& rct, const QgsPoint& infoPoint ) const;
QgsRectangle featureInfoSearchRect( QgsVectorLayer* ml, const QgsMapSettings& ms, const QgsRenderContext& rct, const QgsPoint& infoPoint ) const;

//! Reads and extracts the different options in the FORMAT_OPTIONS parameter
void readFormatOptions( QMap<QString, QString>& formatOptions ) const;
Expand Down
360 changes: 355 additions & 5 deletions tests/src/python/test_qgsserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ def assertXMLEqual(self, response, expected, msg=''):
#print("---->%s\t%s == %s" % (line_no, expected_line, response_line))
# Compare attributes
if re.match(RE_ATTRIBUTES, expected_line): # has attrs
expected_attrs = re.findall(RE_ATTRIBUTES, expected_line)
expected_attrs.sort()
response_attrs = re.findall(RE_ATTRIBUTES, response_line)
response_attrs.sort()
expected_attrs = sorted(re.findall(RE_ATTRIBUTES, expected_line))
response_attrs = sorted(re.findall(RE_ATTRIBUTES, response_line))
self.assertEqual(expected_attrs, response_attrs, msg=msg + "\nXML attributes differ at line {0}: {1} != {2}".format(line_no, expected_attrs, response_attrs))
line_no += 1

Expand All @@ -71,6 +69,10 @@ def tearDownClass(cls):
def setUp(self):
"""Create the server instance"""
self.testdata_path = unitTestDataPath('qgis_server') + '/'

d = unitTestDataPath('qgis_server_accesscontrol') + '/'
self.projectPath = os.path.join(d, "project.qgs")

# Clean env just to be sure
env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE']
for ev in env_vars:
Expand Down Expand Up @@ -416,6 +418,230 @@ def test_getfeature_post(self):
for id, req in tests:
self.wfs_getfeature_post_compare(id, req)

def test_wms_getmap_order(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Hello,Country",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_LayerOrder")

def test_wms_getmap_srs(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country,Hello",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-151.7,-38.9,51.0,78.0",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:4326"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_SRS")

def test_wms_getmap_style(self):
# default style
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country_Labels",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_StyleDefault")

# custom style
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country_Labels",
"STYLES": "custom",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_StyleCustom")

def test_wms_getmap_filter(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country,Hello",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857",
"FILTER": "Country:\"name\" = 'eurasia'"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_Filter")

def test_wms_getmap_selection(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country,Hello",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
"SELECTION": "Country_Labels: 4"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_Selection")

def test_wms_getmap_opacities(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"LAYERS": "Country,Hello",
"STYLES": "",
"FORMAT": "image/png",
"BBOX": "-16817707,-4710778,5696513,14587125",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857",
"OPACITIES": "125, 50"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetMap_Opacities")

def test_wms_getprint_basic(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"map0:LAYERS": "Country,Hello",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Basic")

def test_wms_getprint_srs(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-309.015,-133.011,312.179,133.949",
"map0:LAYERS": "Country,Hello",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:4326"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetPrint_SRS")

def test_wms_getprint_scale(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"map0:LAYERS": "Country,Hello",
"map0:SCALE": "36293562",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Scale")

def test_wms_getprint_grid(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"map0:LAYERS": "Country,Hello",
"map0:GRID_INTERVAL_X": "1000000",
"map0:GRID_INTERVAL_Y": "2000000",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Grid")

def test_wms_getprint_rotation(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"map0:LAYERS": "Country,Hello",
"map0:ROTATION": "45",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Rotation")

def test_getLegendGraphics(self):
"""Test that does not return an exception but an image"""
parms = {
Expand All @@ -429,7 +655,6 @@ def test_getLegendGraphics(self):
'LAYER': 'testlayer%20èé',
}
qs = '&'.join(["%s=%s" % (k, v) for k, v in parms.items()])
print(qs)
h, r = self.server.handleRequest(qs)
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))
Expand Down Expand Up @@ -466,6 +691,131 @@ def test_getLegendGraphics_layertitle(self):
r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(10, 10))

def test_wms_GetLegendGraphic_Basic(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": "FALSE",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_Basic")

def test_wms_GetLegendGraphic_BoxSpace(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": "FALSE",
"BOXSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_BoxSpace")

def test_wms_GetLegendGraphic_SymbolSpace(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": "FALSE",
"SYMBOLSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSpace")

def test_wms_GetLegendGraphic_IconLabelSpace(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": "FALSE",
"ICONLABELSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_IconLabelSpace")

def test_wms_GetLegendGraphic_SymbolSize(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": "FALSE",
"SYMBOLWIDTH": "50",
"SYMBOLHEIGHT": "30",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSize")

#def test_wms_GetLegendGraphic_BBox(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,db_point",
# "LAYERTITLE": "FALSE",
# "FORMAT": "image/png",
# "HEIGHT": "500",
# "WIDTH": "500",
# "BBOX": "-151.7,-38.9,51.0,78.0",
# "CRS": "EPSG:4326"
# }.items())])
# r, h = self._result(self.server.handleRequest(qs))
# self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox")

#def test_wms_GetLegendGraphic_BBox2(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,db_point",
# "LAYERTITLE": "FALSE",
# "FORMAT": "image/png",
# "HEIGHT": "500",
# "WIDTH": "500",
# #"BBOX": "-76.08,38.04,109.95,-6.4",
# "SRS": "EPSG:4326"
# }.items())])

# r, h = self._result(self.server.handleRequest(qs))
# self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox2")

def _result(self, data):
headers = {}
for line in data[0].decode('UTF-8').split("\n"):
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4,698 changes: 2,734 additions & 1,964 deletions tests/testdata/qgis_server_accesscontrol/project.qgs

Large diffs are not rendered by default.