mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -04:00
Merge pull request #3987 from mhugo/servermultithread
[server] parallel map rendering
This commit is contained in:
commit
ef8a135f1b
89
python/server/qgsserversettings.sip
Normal file
89
python/server/qgsserversettings.sip
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsserversettings.sip
|
||||||
|
---------------------
|
||||||
|
begin : December 19, 2016
|
||||||
|
copyright : (C) 2016 by Paul Blottiere
|
||||||
|
email : paul dot blottiere at oslandia dot com
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup server
|
||||||
|
* QgsServerSettings provides a way to retrieve settings by prioritizing
|
||||||
|
* according to environment variables, ini file and default values.
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
class QgsServerSettings
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsserversettings.h"
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor.
|
||||||
|
*/
|
||||||
|
QgsServerSettings();
|
||||||
|
|
||||||
|
/** Load settings according to current environment variables.
|
||||||
|
*/
|
||||||
|
void load();
|
||||||
|
|
||||||
|
/** Log a summary of settings curently loaded.
|
||||||
|
*/
|
||||||
|
void logSummary() const;
|
||||||
|
|
||||||
|
/** Returns the ini file loaded by QSetting.
|
||||||
|
* @return the path of the ini file or an empty string if none is loaded.
|
||||||
|
*/
|
||||||
|
QString iniFile() const;
|
||||||
|
|
||||||
|
/** Returns the maximum number of threads to use.
|
||||||
|
* @return the number of threads.
|
||||||
|
*/
|
||||||
|
int maxThreads() const;
|
||||||
|
|
||||||
|
/** Returns parallel rendering setting.
|
||||||
|
* @return true if parallel rendering is activated, false otherwise.
|
||||||
|
*/
|
||||||
|
bool parallelRendering() const;
|
||||||
|
|
||||||
|
/** Returns the log level.
|
||||||
|
* @return the log level.
|
||||||
|
*/
|
||||||
|
QgsMessageLog::MessageLevel logLevel() const;
|
||||||
|
|
||||||
|
/** Returns the log file.
|
||||||
|
* @return the path of the log file or an empty string if none is defined.
|
||||||
|
*/
|
||||||
|
QString logFile() const;
|
||||||
|
|
||||||
|
/** Returns the QGS project file to use.
|
||||||
|
* @return the path of the QGS project or an empty string if none is defined.
|
||||||
|
*/
|
||||||
|
QString projectFile() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of cached layers.
|
||||||
|
* @return the number of cached layers.
|
||||||
|
*/
|
||||||
|
int maxCacheLayers() const;
|
||||||
|
|
||||||
|
/** Returns the cache size.
|
||||||
|
* @return the cache size.
|
||||||
|
*/
|
||||||
|
qint64 cacheSize() const;
|
||||||
|
|
||||||
|
/** Returns the cache directory.
|
||||||
|
* @return the directory.
|
||||||
|
*/
|
||||||
|
QString cacheDirectory() const;
|
||||||
|
};
|
@ -36,7 +36,7 @@ class QgsWCSServer: public QgsOWSServer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
|
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
|
||||||
QgsWCSServer( const QString& configFilePath, QMap<QString, QString>& parameters, QgsWCSProjectParser* pp,
|
QgsWCSServer( const QString& configFilePath, const QgsServerSettings& settings, QMap<QString, QString>& parameters, QgsWCSProjectParser* pp,
|
||||||
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
|
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
|
||||||
~QgsWCSServer();
|
~QgsWCSServer();
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ class QgsWfsServer: public QgsOWSServer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
|
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
|
||||||
QgsWfsServer( const QString& configFilePath, QMap<QString, QString>& parameters, QgsWfsProjectParser* cp,
|
QgsWfsServer( const QString& configFilePath, const QgsServerSettings& settings,
|
||||||
|
QMap<QString, QString>& parameters, QgsWfsProjectParser* cp,
|
||||||
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
|
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
|
||||||
~QgsWfsServer();
|
~QgsWfsServer();
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class QgsWmsServer: public QgsOWSServer
|
|||||||
public:
|
public:
|
||||||
/** Constructor. Does _NOT_ take ownership of
|
/** Constructor. Does _NOT_ take ownership of
|
||||||
QgsConfigParser, QgsCapabilitiesCache*/
|
QgsConfigParser, QgsCapabilitiesCache*/
|
||||||
QgsWmsServer( const QString& configFilePath, QMap<QString, QString> ¶meters, QgsWmsConfigParser* cp, QgsRequestHandler* rh, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
|
QgsWmsServer( const QString& configFilePath, const QgsServerSettings& settings, QMap<QString, QString> ¶meters, QgsWmsConfigParser* cp, QgsRequestHandler* rh, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
|
||||||
~QgsWmsServer();
|
~QgsWmsServer();
|
||||||
|
|
||||||
void executeRequest() override;
|
void executeRequest() override;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
%Include qgswmsprojectparser.sip
|
%Include qgswmsprojectparser.sip
|
||||||
%Include qgswfsprojectparser.sip
|
%Include qgswfsprojectparser.sip
|
||||||
%Include qgsconfigcache.sip
|
%Include qgsconfigcache.sip
|
||||||
|
%Include qgsserversettings.sip
|
||||||
%Include qgsserver.sip
|
%Include qgsserver.sip
|
||||||
|
|
||||||
%Include qgsserverrequest.sip
|
%Include qgsserverrequest.sip
|
||||||
|
@ -27,6 +27,7 @@ SET ( qgis_mapserv_SRCS
|
|||||||
qgsowsserver.cpp
|
qgsowsserver.cpp
|
||||||
qgswfsserver.cpp
|
qgswfsserver.cpp
|
||||||
qgswcsserver.cpp
|
qgswcsserver.cpp
|
||||||
|
qgsserversettings.cpp
|
||||||
qgsmapserviceexception.cpp
|
qgsmapserviceexception.cpp
|
||||||
qgsmslayercache.cpp
|
qgsmslayercache.cpp
|
||||||
qgsmslayerbuilder.cpp
|
qgsmslayerbuilder.cpp
|
||||||
@ -75,6 +76,7 @@ SET (qgis_mapserv_MOC_HDRS
|
|||||||
# qgshttptransaction.h
|
# qgshttptransaction.h
|
||||||
qgsmslayercache.h
|
qgsmslayercache.h
|
||||||
qgsserverlogger.h
|
qgsserverlogger.h
|
||||||
|
qgsserversettings.h
|
||||||
qgsserverstreamingdevice.h
|
qgsserverstreamingdevice.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,12 +22,25 @@
|
|||||||
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
|
void QgsAccessControl::resolveFilterFeatures( const QList<QgsMapLayer*> &layers )
|
||||||
|
{
|
||||||
|
Q_FOREACH ( QgsMapLayer* l, layers )
|
||||||
|
{
|
||||||
|
if ( l->type() == QgsMapLayer::LayerType::VectorLayer )
|
||||||
|
{
|
||||||
|
const QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( l );
|
||||||
|
mFilterFeaturesExpressions[vl->id()] = resolveFilterFeatures( vl );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Filter the features of the layer
|
mResolved = true;
|
||||||
void QgsAccessControl::filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const
|
}
|
||||||
|
|
||||||
|
QString QgsAccessControl::resolveFilterFeatures( const QgsVectorLayer* layer ) const
|
||||||
{
|
{
|
||||||
QStringList expressions = QStringList();
|
QStringList expressions = QStringList();
|
||||||
QgsAccessControlFilterMap::const_iterator acIterator;
|
QgsAccessControlFilterMap::const_iterator acIterator;
|
||||||
|
|
||||||
for ( acIterator = mPluginsAccessControls->constBegin(); acIterator != mPluginsAccessControls->constEnd(); ++acIterator )
|
for ( acIterator = mPluginsAccessControls->constBegin(); acIterator != mPluginsAccessControls->constEnd(); ++acIterator )
|
||||||
{
|
{
|
||||||
QString expression = acIterator.value()->layerFilterExpression( layer );
|
QString expression = acIterator.value()->layerFilterExpression( layer );
|
||||||
@ -36,9 +49,34 @@ void QgsAccessControl::filterFeatures( const QgsVectorLayer* layer, QgsFeatureRe
|
|||||||
expressions.append( expression );
|
expressions.append( expression );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString expression;
|
||||||
if ( !expressions.isEmpty() )
|
if ( !expressions.isEmpty() )
|
||||||
{
|
{
|
||||||
featureRequest.setFilterExpression( QStringLiteral( "((" ).append( expressions.join( QStringLiteral( ") AND (" ) ) ).append( "))" ) );
|
expression = QStringLiteral( "((" ).append( expressions.join( QStringLiteral( ") AND (" ) ) ).append( "))" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Filter the features of the layer
|
||||||
|
void QgsAccessControl::filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
QString expression;
|
||||||
|
|
||||||
|
if ( mResolved && mFilterFeaturesExpressions.keys().contains( layer->id() ) )
|
||||||
|
{
|
||||||
|
expression = mFilterFeaturesExpressions[layer->id()];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expression = resolveFilterFeatures( layer );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !expression.isEmpty() )
|
||||||
|
{
|
||||||
|
featureRequest.setFilterExpression( expression );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +40,15 @@ class SERVER_EXPORT QgsAccessControl : public QgsFeatureFilterProvider
|
|||||||
QgsAccessControl()
|
QgsAccessControl()
|
||||||
{
|
{
|
||||||
mPluginsAccessControls = new QgsAccessControlFilterMap();
|
mPluginsAccessControls = new QgsAccessControlFilterMap();
|
||||||
|
mResolved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
QgsAccessControl( const QgsAccessControl& copy )
|
QgsAccessControl( const QgsAccessControl& copy )
|
||||||
{
|
{
|
||||||
mPluginsAccessControls = new QgsAccessControlFilterMap( *copy.mPluginsAccessControls );
|
mPluginsAccessControls = new QgsAccessControlFilterMap( *copy.mPluginsAccessControls );
|
||||||
|
mFilterFeaturesExpressions = copy.mFilterFeaturesExpressions;
|
||||||
|
mResolved = copy.mResolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,6 +57,11 @@ class SERVER_EXPORT QgsAccessControl : public QgsFeatureFilterProvider
|
|||||||
delete mPluginsAccessControls;
|
delete mPluginsAccessControls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resolve features' filter of layers
|
||||||
|
* @param layers to filter
|
||||||
|
*/
|
||||||
|
void resolveFilterFeatures( const QList<QgsMapLayer*> &layers );
|
||||||
|
|
||||||
/** Filter the features of the layer
|
/** Filter the features of the layer
|
||||||
* @param layer the layer to control
|
* @param layer the layer to control
|
||||||
* @param filterFeatures the request to fill
|
* @param filterFeatures the request to fill
|
||||||
@ -122,8 +130,13 @@ class SERVER_EXPORT QgsAccessControl : public QgsFeatureFilterProvider
|
|||||||
void registerAccessControl( QgsAccessControlFilter* accessControl, int priority = 0 );
|
void registerAccessControl( QgsAccessControlFilter* accessControl, int priority = 0 );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString resolveFilterFeatures( const QgsVectorLayer* layer ) const;
|
||||||
|
|
||||||
//! The AccessControl plugins registry
|
//! The AccessControl plugins registry
|
||||||
QgsAccessControlFilterMap* mPluginsAccessControls;
|
QgsAccessControlFilterMap* mPluginsAccessControls;
|
||||||
|
|
||||||
|
QMap<QString, QString> mFilterFeaturesExpressions;
|
||||||
|
bool mResolved;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "qgsmaplayer.h"
|
#include "qgsmaplayer.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
|
#include "qgsserversettings.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
QgsMSLayerCache* QgsMSLayerCache::instance()
|
QgsMSLayerCache* QgsMSLayerCache::instance()
|
||||||
@ -32,20 +33,8 @@ QgsMSLayerCache* QgsMSLayerCache::instance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QgsMSLayerCache::QgsMSLayerCache()
|
QgsMSLayerCache::QgsMSLayerCache()
|
||||||
: mProjectMaxLayers( 0 )
|
: mProjectMaxLayers( 100 )
|
||||||
{
|
{
|
||||||
mDefaultMaxLayers = 100;
|
|
||||||
//max layer from environment variable overrides default
|
|
||||||
char* maxLayerEnv = getenv( "MAX_CACHE_LAYERS" );
|
|
||||||
if ( maxLayerEnv )
|
|
||||||
{
|
|
||||||
bool conversionOk = false;
|
|
||||||
int maxLayerInt = QString( maxLayerEnv ).toInt( &conversionOk );
|
|
||||||
if ( conversionOk )
|
|
||||||
{
|
|
||||||
mDefaultMaxLayers = maxLayerInt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QObject::connect( &mFileSystemWatcher, SIGNAL( fileChanged( const QString& ) ), this, SLOT( removeProjectFileLayers( const QString& ) ) );
|
QObject::connect( &mFileSystemWatcher, SIGNAL( fileChanged( const QString& ) ), this, SLOT( removeProjectFileLayers( const QString& ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +48,11 @@ QgsMSLayerCache::~QgsMSLayerCache()
|
|||||||
mEntries.clear();
|
mEntries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsMSLayerCache::setMaxCacheLayers( int maxCacheLayers )
|
||||||
|
{
|
||||||
|
mDefaultMaxLayers = maxCacheLayers;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QString& configFile, const QList<QString>& tempFiles )
|
void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QString& configFile, const QList<QString>& tempFiles )
|
||||||
{
|
{
|
||||||
QgsMessageLog::logMessage( "Layer cache: insert Layer '" + layerName + "' configFile: " + configFile, QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
QgsMessageLog::logMessage( "Layer cache: insert Layer '" + layerName + "' configFile: " + configFile, QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
||||||
|
@ -56,6 +56,13 @@ class QgsMSLayerCache: public QObject
|
|||||||
static QgsMSLayerCache* instance();
|
static QgsMSLayerCache* instance();
|
||||||
~QgsMSLayerCache();
|
~QgsMSLayerCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum number of layers in cache.
|
||||||
|
* @param maxCacheLayers the number of layers in cache
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
void setMaxCacheLayers( int maxCacheLayers );
|
||||||
|
|
||||||
/** Inserts a new layer into the cash
|
/** Inserts a new layer into the cash
|
||||||
@param url the layer datasource
|
@param url the layer datasource
|
||||||
@param layerName the layer name (to distinguish between different layers in a request using the same datasource
|
@param layerName the layer name (to distinguish between different layers in a request using the same datasource
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "qgsconfig.h"
|
#include "qgsconfig.h"
|
||||||
#include "qgsrequesthandler.h"
|
#include "qgsrequesthandler.h"
|
||||||
|
#include "qgsserversettings.h"
|
||||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
#include "qgsaccesscontrol.h"
|
#include "qgsaccesscontrol.h"
|
||||||
#else
|
#else
|
||||||
@ -35,11 +36,13 @@ class QgsOWSServer
|
|||||||
public:
|
public:
|
||||||
QgsOWSServer(
|
QgsOWSServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, const QMap<QString, QString>& parameters
|
, const QMap<QString, QString>& parameters
|
||||||
, QgsRequestHandler* rh
|
, QgsRequestHandler* rh
|
||||||
, const QgsAccessControl* ac
|
, QgsAccessControl* ac
|
||||||
)
|
)
|
||||||
: mParameters( parameters )
|
: mSettings( settings )
|
||||||
|
, mParameters( parameters )
|
||||||
, mRequestHandler( rh )
|
, mRequestHandler( rh )
|
||||||
, mConfigFilePath( configFilePath )
|
, mConfigFilePath( configFilePath )
|
||||||
, mAccessControl( ac )
|
, mAccessControl( ac )
|
||||||
@ -57,12 +60,13 @@ class QgsOWSServer
|
|||||||
QgsOWSServer() {}
|
QgsOWSServer() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QgsServerSettings mSettings;
|
||||||
QMap<QString, QString> mParameters;
|
QMap<QString, QString> mParameters;
|
||||||
QgsRequestHandler* mRequestHandler;
|
QgsRequestHandler* mRequestHandler;
|
||||||
QString mConfigFilePath;
|
QString mConfigFilePath;
|
||||||
|
|
||||||
//! The access control helper
|
//! The access control helper
|
||||||
const QgsAccessControl* mAccessControl;
|
QgsAccessControl* mAccessControl;
|
||||||
|
|
||||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
//for CMAKE_INSTALL_PREFIX
|
//for CMAKE_INSTALL_PREFIX
|
||||||
#include "qgsconfig.h"
|
#include "qgsconfig.h"
|
||||||
#include "qgsserver.h"
|
#include "qgsserver.h"
|
||||||
|
#include "qgsmslayercache.h"
|
||||||
|
|
||||||
#include "qgsmapsettings.h"
|
#include "qgsmapsettings.h"
|
||||||
#include "qgsauthmanager.h"
|
#include "qgsauthmanager.h"
|
||||||
@ -64,6 +65,7 @@ QgsCapabilitiesCache* QgsServer::sCapabilitiesCache = nullptr;
|
|||||||
QgsServerInterfaceImpl* QgsServer::sServerInterface = nullptr;
|
QgsServerInterfaceImpl* QgsServer::sServerInterface = nullptr;
|
||||||
// Initialization must run once for all servers
|
// Initialization must run once for all servers
|
||||||
bool QgsServer::sInitialised = false;
|
bool QgsServer::sInitialised = false;
|
||||||
|
QgsServerSettings QgsServer::sSettings;
|
||||||
|
|
||||||
QgsServiceRegistry QgsServer::sServiceRegistry;
|
QgsServiceRegistry QgsServer::sServiceRegistry;
|
||||||
|
|
||||||
@ -99,12 +101,8 @@ void QgsServer::setupNetworkAccessManager()
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
|
QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
|
||||||
QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
|
QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
|
||||||
QString cacheDirectory = settings.value( QStringLiteral( "cache/directory" ) ).toString();
|
qint64 cacheSize = sSettings.cacheSize();
|
||||||
if ( cacheDirectory.isEmpty() )
|
QString cacheDirectory = sSettings.cacheDirectory();
|
||||||
cacheDirectory = QgsApplication::qgisSettingsDirPath() + "cache";
|
|
||||||
qint64 cacheSize = settings.value( QStringLiteral( "cache/size" ), 50 * 1024 * 1024 ).toULongLong();
|
|
||||||
QgsMessageLog::logMessage( QStringLiteral( "setCacheDirectory: %1" ).arg( cacheDirectory ), QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
|
||||||
QgsMessageLog::logMessage( QStringLiteral( "setMaximumCacheSize: %1" ).arg( cacheSize ), QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
|
||||||
cache->setCacheDirectory( cacheDirectory );
|
cache->setCacheDirectory( cacheDirectory );
|
||||||
cache->setMaximumCacheSize( cacheSize );
|
cache->setMaximumCacheSize( cacheSize );
|
||||||
QgsMessageLog::logMessage( QStringLiteral( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ), QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
QgsMessageLog::logMessage( QStringLiteral( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ), QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
||||||
@ -214,7 +212,7 @@ void QgsServer::printRequestInfos()
|
|||||||
QString QgsServer::configPath( const QString& defaultConfigPath, const QMap<QString, QString>& parameters )
|
QString QgsServer::configPath( const QString& defaultConfigPath, const QMap<QString, QString>& parameters )
|
||||||
{
|
{
|
||||||
QString cfPath( defaultConfigPath );
|
QString cfPath( defaultConfigPath );
|
||||||
QString projectFile = getenv( "QGIS_PROJECT_FILE" );
|
QString projectFile = sSettings.projectFile();
|
||||||
if ( !projectFile.isEmpty() )
|
if ( !projectFile.isEmpty() )
|
||||||
{
|
{
|
||||||
cfPath = projectFile;
|
cfPath = projectFile;
|
||||||
@ -247,16 +245,6 @@ bool QgsServer::init( )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsServerLogger::instance();
|
|
||||||
|
|
||||||
QString optionsPath = getenv( "QGIS_OPTIONS_PATH" );
|
|
||||||
if ( !optionsPath.isEmpty() )
|
|
||||||
{
|
|
||||||
QgsMessageLog::logMessage( "Options PATH: " + optionsPath, QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
|
||||||
QSettings::setDefaultFormat( QSettings::IniFormat );
|
|
||||||
QSettings::setPath( QSettings::IniFormat, QSettings::UserScope, optionsPath );
|
|
||||||
}
|
|
||||||
|
|
||||||
QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
|
QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
|
||||||
QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
|
QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
|
||||||
QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );
|
QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );
|
||||||
@ -277,6 +265,22 @@ bool QgsServer::init( )
|
|||||||
QgsApplication::skipGdalDriver( "JP2ECW" );
|
QgsApplication::skipGdalDriver( "JP2ECW" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// reload settings to take into account QCoreApplication and QgsApplication
|
||||||
|
// configuration
|
||||||
|
sSettings.load();
|
||||||
|
|
||||||
|
// init and configure logger
|
||||||
|
QgsServerLogger::instance();
|
||||||
|
QgsServerLogger::instance()->setLogLevel( sSettings.logLevel() );
|
||||||
|
QgsServerLogger::instance()->setLogFile( sSettings.logFile() );
|
||||||
|
|
||||||
|
// init and configure cache
|
||||||
|
QgsMSLayerCache::instance();
|
||||||
|
QgsMSLayerCache::instance()->setMaxCacheLayers( sSettings.maxCacheLayers() );
|
||||||
|
|
||||||
|
// log settings currently used
|
||||||
|
sSettings.logSummary();
|
||||||
|
|
||||||
setupNetworkAccessManager();
|
setupNetworkAccessManager();
|
||||||
QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
|
QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
|
||||||
|
|
||||||
@ -324,7 +328,7 @@ bool QgsServer::init( )
|
|||||||
|
|
||||||
QgsEditorWidgetRegistry::initEditors();
|
QgsEditorWidgetRegistry::initEditors();
|
||||||
|
|
||||||
sServerInterface = new QgsServerInterfaceImpl( sCapabilitiesCache, &sServiceRegistry );
|
sServerInterface = new QgsServerInterfaceImpl( sCapabilitiesCache, &sServiceRegistry, &sSettings );
|
||||||
|
|
||||||
// Load service module
|
// Load service module
|
||||||
QString modulePath = QgsApplication::libexecPath() + "server";
|
QString modulePath = QgsApplication::libexecPath() + "server";
|
||||||
@ -345,6 +349,7 @@ void QgsServer::putenv( const QString &var, const QString &val )
|
|||||||
#else
|
#else
|
||||||
setenv( var.toStdString().c_str(), val.toStdString().c_str(), 1 );
|
setenv( var.toStdString().c_str(), val.toStdString().c_str(), 1 );
|
||||||
#endif
|
#endif
|
||||||
|
sSettings.load( var );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,7 +399,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
|||||||
QMap<QString, QString> parameterMap = request.parameters();
|
QMap<QString, QString> parameterMap = request.parameters();
|
||||||
printRequestParameters( parameterMap, logLevel );
|
printRequestParameters( parameterMap, logLevel );
|
||||||
|
|
||||||
const QgsAccessControl* accessControl = sServerInterface->accessControls();
|
QgsAccessControl* accessControl = sServerInterface->accessControls();
|
||||||
|
|
||||||
//Config file path
|
//Config file path
|
||||||
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
||||||
@ -447,6 +452,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
|||||||
{
|
{
|
||||||
QgsWCSServer wcsServer(
|
QgsWCSServer wcsServer(
|
||||||
configFilePath
|
configFilePath
|
||||||
|
, sSettings
|
||||||
, parameterMap
|
, parameterMap
|
||||||
, p
|
, p
|
||||||
, &theRequestHandler
|
, &theRequestHandler
|
||||||
@ -469,6 +475,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
|||||||
{
|
{
|
||||||
QgsWfsServer wfsServer(
|
QgsWfsServer wfsServer(
|
||||||
configFilePath
|
configFilePath
|
||||||
|
, sSettings
|
||||||
, parameterMap
|
, parameterMap
|
||||||
, p
|
, p
|
||||||
, &theRequestHandler
|
, &theRequestHandler
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "qgsmapsettings.h"
|
#include "qgsmapsettings.h"
|
||||||
#include "qgsmessagelog.h"
|
#include "qgsmessagelog.h"
|
||||||
#include "qgsserviceregistry.h"
|
#include "qgsserviceregistry.h"
|
||||||
|
#include "qgsserversettings.h"
|
||||||
#include "qgsserverplugins.h"
|
#include "qgsserverplugins.h"
|
||||||
#include "qgsserverfilter.h"
|
#include "qgsserverfilter.h"
|
||||||
#include "qgsserverinterfaceimpl.h"
|
#include "qgsserverinterfaceimpl.h"
|
||||||
@ -132,6 +133,7 @@ class SERVER_EXPORT QgsServer
|
|||||||
//! service registry
|
//! service registry
|
||||||
static QgsServiceRegistry sServiceRegistry;
|
static QgsServiceRegistry sServiceRegistry;
|
||||||
|
|
||||||
|
static QgsServerSettings sSettings;
|
||||||
};
|
};
|
||||||
#endif // QGSSERVER_H
|
#endif // QGSSERVER_H
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "qgscapabilitiescache.h"
|
#include "qgscapabilitiescache.h"
|
||||||
#include "qgsrequesthandler.h"
|
#include "qgsrequesthandler.h"
|
||||||
#include "qgsserverfilter.h"
|
#include "qgsserverfilter.h"
|
||||||
|
#include "qgsserversettings.h"
|
||||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
#include "qgsaccesscontrolfilter.h"
|
#include "qgsaccesscontrolfilter.h"
|
||||||
#include "qgsaccesscontrol.h"
|
#include "qgsaccesscontrol.h"
|
||||||
@ -111,7 +112,7 @@ class SERVER_EXPORT QgsServerInterface
|
|||||||
virtual void registerAccessControl( QgsAccessControlFilter* accessControl, int priority = 0 ) = 0;
|
virtual void registerAccessControl( QgsAccessControlFilter* accessControl, int priority = 0 ) = 0;
|
||||||
|
|
||||||
//! Gets the registred access control filters
|
//! Gets the registred access control filters
|
||||||
virtual const QgsAccessControl* accessControls() const = 0;
|
virtual QgsAccessControl* accessControls() const = 0;
|
||||||
|
|
||||||
//! Return an enrironment variable, used to pass environment variables to python
|
//! Return an enrironment variable, used to pass environment variables to python
|
||||||
virtual QString getEnv( const QString& name ) const = 0;
|
virtual QString getEnv( const QString& name ) const = 0;
|
||||||
@ -146,6 +147,14 @@ class SERVER_EXPORT QgsServerInterface
|
|||||||
*/
|
*/
|
||||||
virtual QgsServiceRegistry* serviceRegistry() = 0;
|
virtual QgsServiceRegistry* serviceRegistry() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the server settings
|
||||||
|
* @return QgsServerSettings
|
||||||
|
*
|
||||||
|
* @note not available in python bindings
|
||||||
|
*/
|
||||||
|
virtual QgsServerSettings* serverSettings() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString mConfigFilePath;
|
QString mConfigFilePath;
|
||||||
};
|
};
|
||||||
|
@ -22,9 +22,10 @@
|
|||||||
#include "qgsmslayercache.h"
|
#include "qgsmslayercache.h"
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
QgsServerInterfaceImpl::QgsServerInterfaceImpl( QgsCapabilitiesCache* capCache, QgsServiceRegistry* srvRegistry )
|
QgsServerInterfaceImpl::QgsServerInterfaceImpl( QgsCapabilitiesCache* capCache, QgsServiceRegistry* srvRegistry, QgsServerSettings* settings )
|
||||||
: mCapabilitiesCache( capCache )
|
: mCapabilitiesCache( capCache )
|
||||||
, mServiceRegistry( srvRegistry )
|
, mServiceRegistry( srvRegistry )
|
||||||
|
, mServerSettings( settings )
|
||||||
{
|
{
|
||||||
mRequestHandler = nullptr;
|
mRequestHandler = nullptr;
|
||||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
@ -100,3 +101,7 @@ QgsServiceRegistry* QgsServerInterfaceImpl::serviceRegistry()
|
|||||||
return mServiceRegistry;
|
return mServiceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsServerSettings* QgsServerInterfaceImpl::serverSettings()
|
||||||
|
{
|
||||||
|
return mServerSettings;
|
||||||
|
}
|
||||||
|
@ -36,7 +36,8 @@ class QgsServerInterfaceImpl : public QgsServerInterface
|
|||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
explicit QgsServerInterfaceImpl( QgsCapabilitiesCache *capCache,
|
explicit QgsServerInterfaceImpl( QgsCapabilitiesCache *capCache,
|
||||||
QgsServiceRegistry* srvRegistry );
|
QgsServiceRegistry* srvRegistry,
|
||||||
|
QgsServerSettings* serverSettings );
|
||||||
|
|
||||||
|
|
||||||
~QgsServerInterfaceImpl();
|
~QgsServerInterfaceImpl();
|
||||||
@ -55,7 +56,7 @@ class QgsServerInterfaceImpl : public QgsServerInterface
|
|||||||
/** Gets the helper over all the registered access control filters
|
/** Gets the helper over all the registered access control filters
|
||||||
* @return the access control helper
|
* @return the access control helper
|
||||||
*/
|
*/
|
||||||
const QgsAccessControl* accessControls() const override { return mAccessControls; }
|
QgsAccessControl* accessControls() const override { return mAccessControls; }
|
||||||
QString getEnv( const QString& name ) const override;
|
QString getEnv( const QString& name ) const override;
|
||||||
QString configFilePath() override { return mConfigFilePath; }
|
QString configFilePath() override { return mConfigFilePath; }
|
||||||
void setConfigFilePath( const QString& configFilePath ) override;
|
void setConfigFilePath( const QString& configFilePath ) override;
|
||||||
@ -65,6 +66,8 @@ class QgsServerInterfaceImpl : public QgsServerInterface
|
|||||||
|
|
||||||
QgsServiceRegistry* serviceRegistry() override;
|
QgsServiceRegistry* serviceRegistry() override;
|
||||||
|
|
||||||
|
QgsServerSettings* serverSettings() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString mConfigFilePath;
|
QString mConfigFilePath;
|
||||||
@ -73,6 +76,7 @@ class QgsServerInterfaceImpl : public QgsServerInterface
|
|||||||
QgsCapabilitiesCache* mCapabilitiesCache;
|
QgsCapabilitiesCache* mCapabilitiesCache;
|
||||||
QgsRequestHandler* mRequestHandler;
|
QgsRequestHandler* mRequestHandler;
|
||||||
QgsServiceRegistry* mServiceRegistry;
|
QgsServiceRegistry* mServiceRegistry;
|
||||||
|
QgsServerSettings* mServerSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSSERVERINTERFACEIMPL_H
|
#endif // QGSSERVERINTERFACEIMPL_H
|
||||||
|
@ -39,28 +39,33 @@ QgsServerLogger::QgsServerLogger()
|
|||||||
: mLogFile( nullptr )
|
: mLogFile( nullptr )
|
||||||
, mLogLevel( QgsMessageLog::NONE )
|
, mLogLevel( QgsMessageLog::NONE )
|
||||||
{
|
{
|
||||||
//logfile
|
|
||||||
QString filePath = getenv( "QGIS_SERVER_LOG_FILE" );
|
|
||||||
if ( filePath.isEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
mLogFile.setFileName( filePath );
|
|
||||||
if ( mLogFile.open( QIODevice::Append ) )
|
|
||||||
{
|
|
||||||
mTextStream.setDevice( &mLogFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
//log level
|
|
||||||
char* logLevelChar = getenv( "QGIS_SERVER_LOG_LEVEL" );
|
|
||||||
if ( logLevelChar )
|
|
||||||
{
|
|
||||||
mLogLevel = static_cast<QgsMessageLog::MessageLevel>( atoi( logLevelChar ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
connect( QgsApplication::messageLog(), SIGNAL( messageReceived( QString, QString, QgsMessageLog::MessageLevel ) ), this,
|
connect( QgsApplication::messageLog(), SIGNAL( messageReceived( QString, QString, QgsMessageLog::MessageLevel ) ), this,
|
||||||
SLOT( logMessage( QString, QString, QgsMessageLog::MessageLevel ) ) );
|
SLOT( logMessage( QString, QString, QgsMessageLog::MessageLevel ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsServerLogger::setLogLevel( QgsMessageLog::MessageLevel level )
|
||||||
|
{
|
||||||
|
mLogLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerLogger::setLogFile( const QString& f )
|
||||||
|
{
|
||||||
|
if ( ! f.isEmpty() )
|
||||||
|
{
|
||||||
|
if ( mLogFile.exists() )
|
||||||
|
{
|
||||||
|
mTextStream.flush();
|
||||||
|
mLogFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
mLogFile.setFileName( f );
|
||||||
|
if ( mLogFile.open( QIODevice::Append ) )
|
||||||
|
{
|
||||||
|
mTextStream.setDevice( &mLogFile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QgsServerLogger::logMessage( const QString& message, const QString& tag, QgsMessageLog::MessageLevel level )
|
void QgsServerLogger::logMessage( const QString& message, const QString& tag, QgsMessageLog::MessageLevel level )
|
||||||
{
|
{
|
||||||
Q_UNUSED( tag );
|
Q_UNUSED( tag );
|
||||||
|
@ -38,9 +38,23 @@ class QgsServerLogger: public QObject
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current log level
|
* Get the current log level
|
||||||
|
* @return the log level
|
||||||
|
* @note added in QGIS 3.0
|
||||||
*/
|
*/
|
||||||
QgsMessageLog::MessageLevel logLevel() const { return mLogLevel; }
|
QgsMessageLog::MessageLevel logLevel() const { return mLogLevel; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current log level
|
||||||
|
* @param level the log level
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
void setLogLevel( QgsMessageLog::MessageLevel level );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current log file
|
||||||
|
*/
|
||||||
|
void setLogFile( const QString& f );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
307
src/server/qgsserversettings.cpp
Normal file
307
src/server/qgsserversettings.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsserversettings.cpp
|
||||||
|
---------------------
|
||||||
|
begin : December 19, 2016
|
||||||
|
copyright : (C) 2016 by Paul Blottiere
|
||||||
|
email : paul dot blottiere at oslandia dot com
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsserversettings.h"
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
QgsServerSettings::QgsServerSettings()
|
||||||
|
{
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerSettings::initSettings()
|
||||||
|
{
|
||||||
|
mSettings.clear();
|
||||||
|
|
||||||
|
// options path
|
||||||
|
const Setting sOptPath = { QgsServerSettingsEnv::QGIS_OPTIONS_PATH,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Override the default path for user configuration",
|
||||||
|
"",
|
||||||
|
QVariant::String,
|
||||||
|
QVariant( "" ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sOptPath.envVar ] = sOptPath;
|
||||||
|
|
||||||
|
// parallel rendering
|
||||||
|
const Setting sParRend = { QgsServerSettingsEnv::QGIS_SERVER_PARALLEL_RENDERING,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Activate/Deactivate parallel rendering for WMS getMap request",
|
||||||
|
"/qgis/parallel_rendering",
|
||||||
|
QVariant::Bool,
|
||||||
|
QVariant( false ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sParRend.envVar ] = sParRend;
|
||||||
|
|
||||||
|
// max threads
|
||||||
|
const Setting sMaxThreads = { QgsServerSettingsEnv::QGIS_SERVER_MAX_THREADS,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Number of threads to use when parallel rendering is activated",
|
||||||
|
"/qgis/max_threads",
|
||||||
|
QVariant::Int,
|
||||||
|
QVariant( -1 ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sMaxThreads.envVar ] = sMaxThreads;
|
||||||
|
|
||||||
|
// log level
|
||||||
|
const Setting sLogLevel = { QgsServerSettingsEnv::QGIS_SERVER_LOG_LEVEL,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Log level",
|
||||||
|
"",
|
||||||
|
QVariant::Int,
|
||||||
|
QVariant( QgsMessageLog::NONE ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sLogLevel.envVar ] = sLogLevel;
|
||||||
|
|
||||||
|
// log file
|
||||||
|
const Setting sLogFile = { QgsServerSettingsEnv::QGIS_SERVER_LOG_FILE,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Log file",
|
||||||
|
"",
|
||||||
|
QVariant::String,
|
||||||
|
QVariant( "" ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sLogFile.envVar ] = sLogFile;
|
||||||
|
|
||||||
|
// project file
|
||||||
|
const Setting sProject = { QgsServerSettingsEnv::QGIS_PROJECT_FILE,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"QGIS project file",
|
||||||
|
"",
|
||||||
|
QVariant::String,
|
||||||
|
QVariant( "" ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sProject.envVar ] = sProject;
|
||||||
|
|
||||||
|
// max cache layers
|
||||||
|
const Setting sMaxCacheLayers = { QgsServerSettingsEnv::MAX_CACHE_LAYERS,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Specify the maximum number of cached layers",
|
||||||
|
"",
|
||||||
|
QVariant::Int,
|
||||||
|
QVariant( 100 ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sMaxCacheLayers.envVar ] = sMaxCacheLayers;
|
||||||
|
|
||||||
|
// cache directory
|
||||||
|
const Setting sCacheDir = { QgsServerSettingsEnv::QGIS_SERVER_CACHE_DIRECTORY,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Specify the cache directory",
|
||||||
|
"/cache/directory",
|
||||||
|
QVariant::String,
|
||||||
|
QVariant( QgsApplication::qgisSettingsDirPath() + "cache" ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sCacheDir.envVar ] = sCacheDir;
|
||||||
|
|
||||||
|
// cache size
|
||||||
|
const Setting sCacheSize = { QgsServerSettingsEnv::QGIS_SERVER_CACHE_SIZE,
|
||||||
|
QgsServerSettingsEnv::DEFAULT_VALUE,
|
||||||
|
"Specify the cache size",
|
||||||
|
"/cache/size",
|
||||||
|
QVariant::LongLong,
|
||||||
|
QVariant( 50*1024*1024 ),
|
||||||
|
QVariant()
|
||||||
|
};
|
||||||
|
mSettings[ sCacheSize.envVar ] = sCacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerSettings::load()
|
||||||
|
{
|
||||||
|
// init settings each time to take into account QgsApplication and
|
||||||
|
// QCoreApplication configuration for some default values
|
||||||
|
initSettings();
|
||||||
|
|
||||||
|
// store environment variables
|
||||||
|
QMap<QgsServerSettingsEnv::EnvVar, QString> env = getEnv();
|
||||||
|
|
||||||
|
// load QSettings if QGIS_OPTIONS_PATH is defined
|
||||||
|
loadQSettings( env[ QgsServerSettingsEnv::QGIS_OPTIONS_PATH ] );
|
||||||
|
|
||||||
|
// prioritize values: 'env var' -> 'ini file' -> 'default value'
|
||||||
|
prioritize( env );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsServerSettings::load( const QString& envVarName )
|
||||||
|
{
|
||||||
|
bool rc( false );
|
||||||
|
const QMetaEnum metaEnum( QMetaEnum::fromType<QgsServerSettingsEnv::EnvVar>() );
|
||||||
|
const int value = metaEnum.keyToValue( envVarName.toStdString().c_str() );
|
||||||
|
|
||||||
|
if ( value >= 0 )
|
||||||
|
{
|
||||||
|
const QString envValue( getenv( envVarName.toStdString().c_str() ) );
|
||||||
|
prioritize( QMap<QgsServerSettingsEnv::EnvVar, QString> { {( QgsServerSettingsEnv::EnvVar ) value, envValue } } );
|
||||||
|
rc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QgsServerSettingsEnv::EnvVar, QString> QgsServerSettings::getEnv() const
|
||||||
|
{
|
||||||
|
QMap<QgsServerSettingsEnv::EnvVar, QString> env;
|
||||||
|
|
||||||
|
const QMetaEnum metaEnum( QMetaEnum::fromType<QgsServerSettingsEnv::EnvVar>() );
|
||||||
|
for ( int i = 0; i < metaEnum.keyCount(); i++ )
|
||||||
|
{
|
||||||
|
env[( QgsServerSettingsEnv::EnvVar ) metaEnum.value( i )] = getenv( metaEnum.key( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QgsServerSettings::value( QgsServerSettingsEnv::EnvVar envVar ) const
|
||||||
|
{
|
||||||
|
if ( mSettings[ envVar ].src == QgsServerSettingsEnv::DEFAULT_VALUE )
|
||||||
|
{
|
||||||
|
return mSettings[ envVar ].defaultVal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mSettings[ envVar ].val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerSettings::loadQSettings( const QString& envOptPath ) const
|
||||||
|
{
|
||||||
|
if ( ! envOptPath.isEmpty() )
|
||||||
|
{
|
||||||
|
QSettings::setDefaultFormat( QSettings::IniFormat );
|
||||||
|
QSettings::setPath( QSettings::IniFormat, QSettings::UserScope, envOptPath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerSettings::prioritize( const QMap<QgsServerSettingsEnv::EnvVar, QString>& env )
|
||||||
|
{
|
||||||
|
for ( QgsServerSettingsEnv::EnvVar e : env.keys() )
|
||||||
|
{
|
||||||
|
Setting s = mSettings[ e ];
|
||||||
|
|
||||||
|
QVariant varValue;
|
||||||
|
if ( ! env.value( e ).isEmpty() )
|
||||||
|
{
|
||||||
|
varValue.setValue( env.value( e ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! varValue.isNull() && varValue.canConvert( s.type ) )
|
||||||
|
{
|
||||||
|
s.val = varValue;
|
||||||
|
s.src = QgsServerSettingsEnv::ENVIRONMENT_VARIABLE;
|
||||||
|
}
|
||||||
|
else if ( ! s.iniKey.isEmpty() && QSettings().contains( s.iniKey ) && QSettings().value( s.iniKey ).canConvert( s.type ) )
|
||||||
|
{
|
||||||
|
s.val = QSettings().value( s.iniKey );
|
||||||
|
s.src = QgsServerSettingsEnv::INI_FILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.val = QVariant();
|
||||||
|
s.src = QgsServerSettingsEnv::DEFAULT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// an empty string can be returned from QSettings. In this case, we want
|
||||||
|
// to use the default value
|
||||||
|
if ( s.type == QVariant::String && s.val.toString().isEmpty() )
|
||||||
|
{
|
||||||
|
s.val = QVariant();
|
||||||
|
s.src = QgsServerSettingsEnv::DEFAULT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSettings[ e ] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsServerSettings::logSummary() const
|
||||||
|
{
|
||||||
|
const QMetaEnum metaEnumSrc( QMetaEnum::fromType<QgsServerSettingsEnv::Source>() );
|
||||||
|
const QMetaEnum metaEnumEnv( QMetaEnum::fromType<QgsServerSettingsEnv::EnvVar>() );
|
||||||
|
|
||||||
|
QgsMessageLog::logMessage( "Qgis Server Settings: ", "Server", QgsMessageLog::INFO );
|
||||||
|
for ( Setting s : mSettings )
|
||||||
|
{
|
||||||
|
const QString src = metaEnumSrc.valueToKey( s.src );
|
||||||
|
const QString var = metaEnumEnv.valueToKey( s.envVar );
|
||||||
|
|
||||||
|
const QString msg = " - " + var + " / '" + s.iniKey + "' (" + s.descr + "): '" + value( s.envVar ).toString() + "' (read from " + src + ")";
|
||||||
|
QgsMessageLog::logMessage( msg, "Server", QgsMessageLog::INFO );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! iniFile().isEmpty() )
|
||||||
|
{
|
||||||
|
const QString msg = "Ini file used to initialize settings: " + iniFile();
|
||||||
|
QgsMessageLog::logMessage( msg, "Server", QgsMessageLog::INFO );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getter
|
||||||
|
QString QgsServerSettings::iniFile() const
|
||||||
|
{
|
||||||
|
return QSettings().fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsServerSettings::parallelRendering() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_SERVER_PARALLEL_RENDERING ).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsServerSettings::maxThreads() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_SERVER_MAX_THREADS ).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsServerSettings::logFile() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_SERVER_LOG_FILE ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMessageLog::MessageLevel QgsServerSettings::logLevel() const
|
||||||
|
{
|
||||||
|
return static_cast<QgsMessageLog::MessageLevel>( value( QgsServerSettingsEnv::QGIS_SERVER_LOG_LEVEL ).toInt() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsServerSettings::maxCacheLayers() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::MAX_CACHE_LAYERS ).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsServerSettings::projectFile() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_PROJECT_FILE ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QgsServerSettings::cacheSize() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_SERVER_CACHE_SIZE ).toLongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsServerSettings::cacheDirectory() const
|
||||||
|
{
|
||||||
|
return value( QgsServerSettingsEnv::QGIS_SERVER_CACHE_DIRECTORY ).toString();
|
||||||
|
}
|
154
src/server/qgsserversettings.h
Normal file
154
src/server/qgsserversettings.h
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsserversettings.h
|
||||||
|
-------------------
|
||||||
|
begin : December 19, 2016
|
||||||
|
copyright : (C) 2016 by Paul Blottiere
|
||||||
|
email : paul dot blottiere at oslandia dot com
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QGSSERVERSETTINGS_H
|
||||||
|
#define QGSSERVERSETTINGS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgis_server.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QgsServerSettingsEnv provides some enum describing the environment
|
||||||
|
* currently supported for configuration.
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
class QgsServerSettingsEnv : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Source
|
||||||
|
{
|
||||||
|
DEFAULT_VALUE,
|
||||||
|
ENVIRONMENT_VARIABLE,
|
||||||
|
INI_FILE
|
||||||
|
};
|
||||||
|
Q_ENUM( Source )
|
||||||
|
|
||||||
|
enum EnvVar
|
||||||
|
{
|
||||||
|
QGIS_OPTIONS_PATH,
|
||||||
|
QGIS_SERVER_PARALLEL_RENDERING,
|
||||||
|
QGIS_SERVER_MAX_THREADS,
|
||||||
|
QGIS_SERVER_LOG_LEVEL,
|
||||||
|
QGIS_SERVER_LOG_FILE,
|
||||||
|
QGIS_PROJECT_FILE,
|
||||||
|
MAX_CACHE_LAYERS,
|
||||||
|
QGIS_SERVER_CACHE_DIRECTORY,
|
||||||
|
QGIS_SERVER_CACHE_SIZE
|
||||||
|
};
|
||||||
|
Q_ENUM( EnvVar )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \ingroup server
|
||||||
|
* QgsServerSettings provides a way to retrieve settings by prioritizing
|
||||||
|
* according to environment variables, ini file and default values.
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
class SERVER_EXPORT QgsServerSettings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Setting
|
||||||
|
{
|
||||||
|
QgsServerSettingsEnv::EnvVar envVar;
|
||||||
|
QgsServerSettingsEnv::Source src;
|
||||||
|
QString descr;
|
||||||
|
QString iniKey;
|
||||||
|
QVariant::Type type;
|
||||||
|
QVariant defaultVal;
|
||||||
|
QVariant val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Constructor.
|
||||||
|
*/
|
||||||
|
QgsServerSettings();
|
||||||
|
|
||||||
|
/** Load settings according to current environment variables.
|
||||||
|
*/
|
||||||
|
void load();
|
||||||
|
|
||||||
|
/** Load setting for a specific environment variable name.
|
||||||
|
* @return true if loading is successful, false in case of an invalid name.
|
||||||
|
*/
|
||||||
|
bool load( const QString& envVarName );
|
||||||
|
|
||||||
|
/** Log a summary of settings curently loaded.
|
||||||
|
*/
|
||||||
|
void logSummary() const;
|
||||||
|
|
||||||
|
/** Returns the ini file loaded by QSetting.
|
||||||
|
* @return the path of the ini file or an empty string if none is loaded.
|
||||||
|
*/
|
||||||
|
QString iniFile() const;
|
||||||
|
|
||||||
|
/** Returns parallel rendering setting.
|
||||||
|
* @return true if parallel rendering is activated, false otherwise.
|
||||||
|
*/
|
||||||
|
bool parallelRendering() const;
|
||||||
|
|
||||||
|
/** Returns the maximum number of threads to use.
|
||||||
|
* @return the number of threads.
|
||||||
|
*/
|
||||||
|
int maxThreads() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of cached layers.
|
||||||
|
* @return the number of cached layers.
|
||||||
|
*/
|
||||||
|
int maxCacheLayers() const;
|
||||||
|
|
||||||
|
/** Returns the log level.
|
||||||
|
* @return the log level.
|
||||||
|
*/
|
||||||
|
QgsMessageLog::MessageLevel logLevel() const;
|
||||||
|
|
||||||
|
/** Returns the QGS project file to use.
|
||||||
|
* @return the path of the QGS project or an empty string if none is defined.
|
||||||
|
*/
|
||||||
|
QString projectFile() const;
|
||||||
|
|
||||||
|
/** Returns the log file.
|
||||||
|
* @return the path of the log file or an empty string if none is defined.
|
||||||
|
*/
|
||||||
|
QString logFile() const;
|
||||||
|
|
||||||
|
/** Returns the cache size.
|
||||||
|
* @return the cache size.
|
||||||
|
*/
|
||||||
|
qint64 cacheSize() const;
|
||||||
|
|
||||||
|
/** Returns the cache directory.
|
||||||
|
* @return the directory.
|
||||||
|
*/
|
||||||
|
QString cacheDirectory() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initSettings();
|
||||||
|
QVariant value( QgsServerSettingsEnv::EnvVar envVar ) const;
|
||||||
|
QMap<QgsServerSettingsEnv::EnvVar, QString> getEnv() const;
|
||||||
|
void loadQSettings( const QString& envOptPath ) const;
|
||||||
|
void prioritize( const QMap<QgsServerSettingsEnv::EnvVar, QString>& env );
|
||||||
|
|
||||||
|
QMap< QgsServerSettingsEnv::EnvVar, Setting > mSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -40,13 +40,15 @@ static const QString OGC_NAMESPACE = QStringLiteral( "http://www.opengis.net/ogc
|
|||||||
|
|
||||||
QgsWCSServer::QgsWCSServer(
|
QgsWCSServer::QgsWCSServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString> ¶meters
|
, QMap<QString, QString> ¶meters
|
||||||
, QgsWCSProjectParser* pp
|
, QgsWCSProjectParser* pp
|
||||||
, QgsRequestHandler* rh
|
, QgsRequestHandler* rh
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
)
|
)
|
||||||
: QgsOWSServer(
|
: QgsOWSServer(
|
||||||
configFilePath
|
configFilePath
|
||||||
|
, settings
|
||||||
, parameters
|
, parameters
|
||||||
, rh
|
, rh
|
||||||
, accessControl
|
, accessControl
|
||||||
@ -60,6 +62,7 @@ QgsWCSServer::QgsWCSServer(
|
|||||||
QgsWCSServer::QgsWCSServer()
|
QgsWCSServer::QgsWCSServer()
|
||||||
: QgsOWSServer(
|
: QgsOWSServer(
|
||||||
QString()
|
QString()
|
||||||
|
, QgsServerSettings()
|
||||||
, QMap<QString, QString>()
|
, QMap<QString, QString>()
|
||||||
, nullptr
|
, nullptr
|
||||||
, nullptr
|
, nullptr
|
||||||
|
@ -38,10 +38,11 @@ class QgsWCSServer: public QgsOWSServer
|
|||||||
//! Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)
|
//! Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)
|
||||||
QgsWCSServer(
|
QgsWCSServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString>& parameters
|
, QMap<QString, QString>& parameters
|
||||||
, QgsWCSProjectParser* pp
|
, QgsWCSProjectParser* pp
|
||||||
, QgsRequestHandler* rh
|
, QgsRequestHandler* rh
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
);
|
);
|
||||||
|
|
||||||
void executeRequest() override;
|
void executeRequest() override;
|
||||||
|
@ -64,13 +64,15 @@ static const QString QGS_NAMESPACE = QStringLiteral( "http://www.qgis.org/gml" )
|
|||||||
|
|
||||||
QgsWfsServer::QgsWfsServer(
|
QgsWfsServer::QgsWfsServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString> ¶meters
|
, QMap<QString, QString> ¶meters
|
||||||
, QgsWfsProjectParser* cp
|
, QgsWfsProjectParser* cp
|
||||||
, QgsRequestHandler* rh
|
, QgsRequestHandler* rh
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
)
|
)
|
||||||
: QgsOWSServer(
|
: QgsOWSServer(
|
||||||
configFilePath
|
configFilePath
|
||||||
|
, settings
|
||||||
, parameters
|
, parameters
|
||||||
, rh
|
, rh
|
||||||
, accessControl
|
, accessControl
|
||||||
@ -83,6 +85,7 @@ QgsWfsServer::QgsWfsServer(
|
|||||||
QgsWfsServer::QgsWfsServer()
|
QgsWfsServer::QgsWfsServer()
|
||||||
: QgsOWSServer(
|
: QgsOWSServer(
|
||||||
QString()
|
QString()
|
||||||
|
, QgsServerSettings()
|
||||||
, QMap<QString, QString>()
|
, QMap<QString, QString>()
|
||||||
, nullptr
|
, nullptr
|
||||||
, nullptr
|
, nullptr
|
||||||
|
@ -59,10 +59,11 @@ class QgsWfsServer: public QgsOWSServer
|
|||||||
//! Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)
|
//! Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)
|
||||||
QgsWfsServer(
|
QgsWfsServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString>& parameters
|
, QMap<QString, QString>& parameters
|
||||||
, QgsWfsProjectParser* cp
|
, QgsWfsProjectParser* cp
|
||||||
, QgsRequestHandler* rh
|
, QgsRequestHandler* rh
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
);
|
);
|
||||||
|
|
||||||
void executeRequest() override;
|
void executeRequest() override;
|
||||||
|
@ -17,6 +17,7 @@ SET (wms_SRCS
|
|||||||
qgswmsgetstyle.cpp
|
qgswmsgetstyle.cpp
|
||||||
qgswmsgetstyles.cpp
|
qgswmsgetstyles.cpp
|
||||||
qgswmsservertransitional.cpp
|
qgswmsservertransitional.cpp
|
||||||
|
qgsmaprendererjobproxy.cpp
|
||||||
qgsfilterrestorer.cpp
|
qgsfilterrestorer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,14 +41,14 @@ INCLUDE_DIRECTORIES(
|
|||||||
${CMAKE_BINARY_DIR}/src/analysis
|
${CMAKE_BINARY_DIR}/src/analysis
|
||||||
${CMAKE_BINARY_DIR}/src/server
|
${CMAKE_BINARY_DIR}/src/server
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
../../../core
|
../../../core
|
||||||
../../../core/dxf
|
../../../core/dxf
|
||||||
../../../core/geometry
|
../../../core/geometry
|
||||||
../../../core/raster
|
../../../core/raster
|
||||||
../../../core/symbology-ng
|
../../../core/symbology-ng
|
||||||
../../../core/composer
|
../../../core/composer
|
||||||
../../../core/layertree
|
../../../core/layertree
|
||||||
../../../gui
|
../../../gui
|
||||||
../../../gui/editorwidgets
|
../../../gui/editorwidgets
|
||||||
../../../gui/editorwidgets/core
|
../../../gui/editorwidgets/core
|
||||||
../..
|
../..
|
||||||
|
@ -122,7 +122,9 @@ namespace QgsWms
|
|||||||
|
|
||||||
QMap<QString, QString> formatOptionsMap = parseFormatOptions( params.value( QStringLiteral( "FORMAT_OPTIONS" ) ) );
|
QMap<QString, QString> formatOptionsMap = parseFormatOptions( params.value( QStringLiteral( "FORMAT_OPTIONS" ) ) );
|
||||||
|
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(),
|
||||||
|
params,
|
||||||
configParser,
|
configParser,
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
|
|
||||||
|
80
src/server/services/wms/qgsmaprendererjobproxy.cpp
Normal file
80
src/server/services/wms/qgsmaprendererjobproxy.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaprendererjobproxy.cpp
|
||||||
|
--------------------------
|
||||||
|
begin : January 2017
|
||||||
|
copyright : (C) 2017 by Paul Blottiere
|
||||||
|
email : paul dot blottiere at oslandia dot com
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsmaprendererjobproxy.h"
|
||||||
|
|
||||||
|
#include "qgsmessagelog.h"
|
||||||
|
#include "qgsmaprendererparalleljob.h"
|
||||||
|
#include "qgsmaprenderercustompainterjob.h"
|
||||||
|
|
||||||
|
namespace QgsWms
|
||||||
|
{
|
||||||
|
|
||||||
|
QgsMapRendererJobProxy::QgsMapRendererJobProxy(
|
||||||
|
bool parallelRendering
|
||||||
|
, int maxThreads
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
, QgsAccessControl* accessControl
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mParallelRendering( parallelRendering )
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
, mAccessControl( accessControl )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if ( mParallelRendering )
|
||||||
|
{
|
||||||
|
QgsApplication::setMaxThreads( maxThreads );
|
||||||
|
QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering activated with %1 threads" ).arg( maxThreads ), QStringLiteral( "server" ), QgsMessageLog::INFO );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering deactivated" ), QStringLiteral( "server" ), QgsMessageLog::INFO );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapRendererJobProxy::render( const QgsMapSettings& mapSettings, QImage* image )
|
||||||
|
{
|
||||||
|
if ( mParallelRendering )
|
||||||
|
{
|
||||||
|
QgsMapRendererParallelJob renderJob( mapSettings );
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
renderJob.setFeatureFilterProvider( mAccessControl );
|
||||||
|
#endif
|
||||||
|
renderJob.start();
|
||||||
|
renderJob.waitForFinished();
|
||||||
|
*image = renderJob.renderedImage();
|
||||||
|
mPainter.reset( new QPainter( image ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPainter.reset( new QPainter( image ) );
|
||||||
|
QgsMapRendererCustomPainterJob renderJob( mapSettings, mPainter.data() );
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
renderJob.setFeatureFilterProvider( mAccessControl );
|
||||||
|
#endif
|
||||||
|
renderJob.renderSynchronously();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter* QgsMapRendererJobProxy::takePainter()
|
||||||
|
{
|
||||||
|
return mPainter.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qgsws
|
68
src/server/services/wms/qgsmaprendererjobproxy.h
Normal file
68
src/server/services/wms/qgsmaprendererjobproxy.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaprendererjobproxy.h
|
||||||
|
------------------------
|
||||||
|
begin : January 2017
|
||||||
|
copyright : (C) 2017 by Paul Blottiere
|
||||||
|
email : paul dot blottiere at oslandia dot com
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSMAPRENDERERJOBPROXY_H
|
||||||
|
#define QGSMAPRENDERERJOBPROXY_H
|
||||||
|
|
||||||
|
#include "qgsmapsettings.h"
|
||||||
|
#include "qgsaccesscontrol.h"
|
||||||
|
|
||||||
|
namespace QgsWms
|
||||||
|
{
|
||||||
|
|
||||||
|
/** \ingroup server
|
||||||
|
* thiss class provides a proxy for sequential or parallel map render job by
|
||||||
|
* reading qsettings.
|
||||||
|
* @note added in QGIS 3.0
|
||||||
|
*/
|
||||||
|
class QgsMapRendererJobProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Constructor.
|
||||||
|
* @param accessControl Does not take ownership of QgsAccessControl
|
||||||
|
*/
|
||||||
|
QgsMapRendererJobProxy(
|
||||||
|
bool parallelRendering
|
||||||
|
, int maxThreads
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
, QgsAccessControl* accessControl
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Sequential or parallel map rendering according to qsettings.
|
||||||
|
* @param mapSettings passed to MapRendererJob
|
||||||
|
* @param the rendered image
|
||||||
|
*/
|
||||||
|
void render( const QgsMapSettings& mapSettings, QImage* image );
|
||||||
|
|
||||||
|
/** Take ownership of the painter used for rendering.
|
||||||
|
* @return painter
|
||||||
|
*/
|
||||||
|
QPainter* takePainter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mParallelRendering;
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
QgsAccessControl* mAccessControl;
|
||||||
|
#endif
|
||||||
|
QScopedPointer<QPainter> mPainter;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@ -32,7 +32,9 @@ namespace QgsWms
|
|||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(),
|
||||||
|
params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
QDomDocument doc = server.describeLayer();
|
QDomDocument doc = server.describeLayer();
|
||||||
|
@ -31,7 +31,8 @@ namespace QgsWms
|
|||||||
{
|
{
|
||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
QString configFilePath = serverIface->configFilePath();
|
QString configFilePath = serverIface->configFilePath();
|
||||||
const QgsAccessControl* accessControl = serverIface->accessControls();
|
QgsServerSettings* serverSettings = serverIface->serverSettings();
|
||||||
|
QgsAccessControl* accessControl = serverIface->accessControls();
|
||||||
QgsCapabilitiesCache* capabilitiesCache = serverIface->capabilitiesCache();
|
QgsCapabilitiesCache* capabilitiesCache = serverIface->capabilitiesCache();
|
||||||
|
|
||||||
QStringList cacheKeyList;
|
QStringList cacheKeyList;
|
||||||
@ -50,7 +51,9 @@ namespace QgsWms
|
|||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QgsWmsServer server( configFilePath, params,
|
QgsWmsServer server( configFilePath,
|
||||||
|
*serverSettings,
|
||||||
|
params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
accessControl );
|
accessControl );
|
||||||
doc = server.getCapabilities( version, projectSettings );
|
doc = server.getCapabilities( version, projectSettings );
|
||||||
|
@ -32,7 +32,9 @@ namespace QgsWms
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Q_UNUSED( version );
|
Q_UNUSED( version );
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(),
|
||||||
|
params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
QDomDocument doc = server.getContext();
|
QDomDocument doc = server.getContext();
|
||||||
|
@ -161,7 +161,8 @@ namespace QgsWms
|
|||||||
{
|
{
|
||||||
Q_UNUSED( version );
|
Q_UNUSED( version );
|
||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
try
|
try
|
||||||
|
@ -33,8 +33,8 @@ namespace QgsWms
|
|||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
QgsWmsConfigParser* parser = getConfigParser( serverIface );
|
QgsWmsConfigParser* parser = getConfigParser( serverIface );
|
||||||
|
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params, parser,
|
QgsWmsServer server( serverIface->configFilePath(), *serverIface->serverSettings(),
|
||||||
serverIface->accessControls() );
|
params, parser, serverIface->accessControls() );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QScopedPointer<QImage> result( server.getLegendGraphics() );
|
QScopedPointer<QImage> result( server.getLegendGraphics() );
|
||||||
|
@ -34,7 +34,8 @@ namespace QgsWms
|
|||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
QgsWmsConfigParser* parser = getConfigParser( serverIface );
|
QgsWmsConfigParser* parser = getConfigParser( serverIface );
|
||||||
|
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params, parser,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params, parser,
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,8 @@ namespace QgsWms
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Q_UNUSED( version );
|
Q_UNUSED( version );
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ namespace QgsWms
|
|||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
QDomDocument doc = server.getSchemaExtension();
|
QDomDocument doc = server.getSchemaExtension();
|
||||||
|
@ -33,7 +33,8 @@ namespace QgsWms
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Q_UNUSED( version );
|
Q_UNUSED( version );
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
QDomDocument doc = server.getStyle();
|
QDomDocument doc = server.getStyle();
|
||||||
|
@ -30,7 +30,8 @@ namespace QgsWms
|
|||||||
{
|
{
|
||||||
Q_UNUSED( version );
|
Q_UNUSED( version );
|
||||||
QgsServerRequest::Parameters params = request.parameters();
|
QgsServerRequest::Parameters params = request.parameters();
|
||||||
QgsWmsServer server( serverIface->configFilePath(), params,
|
QgsWmsServer server( serverIface->configFilePath(),
|
||||||
|
*serverIface->serverSettings(), params,
|
||||||
getConfigParser( serverIface ),
|
getConfigParser( serverIface ),
|
||||||
serverIface->accessControls() );
|
serverIface->accessControls() );
|
||||||
try
|
try
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
#include "qgseditorwidgetregistry.h"
|
#include "qgseditorwidgetregistry.h"
|
||||||
#include "qgsaccesscontrol.h"
|
#include "qgsaccesscontrol.h"
|
||||||
#include "qgsfeaturerequest.h"
|
#include "qgsfeaturerequest.h"
|
||||||
#include "qgsmaprenderercustompainterjob.h"
|
#include "qgsmaprendererjobproxy.h"
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
@ -74,9 +74,10 @@ namespace QgsWms
|
|||||||
|
|
||||||
QgsWmsServer::QgsWmsServer(
|
QgsWmsServer::QgsWmsServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString> ¶meters
|
, QMap<QString, QString> ¶meters
|
||||||
, QgsWmsConfigParser* cp
|
, QgsWmsConfigParser* cp
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
)
|
)
|
||||||
: mParameters( parameters )
|
: mParameters( parameters )
|
||||||
, mOwnsConfigParser( false )
|
, mOwnsConfigParser( false )
|
||||||
@ -85,6 +86,7 @@ namespace QgsWms
|
|||||||
, mConfigParser( cp )
|
, mConfigParser( cp )
|
||||||
, mConfigFilePath( configFilePath )
|
, mConfigFilePath( configFilePath )
|
||||||
, mAccessControl( accessControl )
|
, mAccessControl( accessControl )
|
||||||
|
, mSettings( settings )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,10 +687,9 @@ namespace QgsWms
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsWmsServer::runHitTest( const QgsMapSettings& mapSettings, QPainter* painter, HitTest& hitTest )
|
void QgsWmsServer::runHitTest( const QgsMapSettings& mapSettings, HitTest& hitTest )
|
||||||
{
|
{
|
||||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
||||||
context.setPainter( painter ); // we are not going to draw anything, but we still need a working painter
|
|
||||||
|
|
||||||
Q_FOREACH ( const QString& layerID, mapSettings.layerIds() )
|
Q_FOREACH ( const QString& layerID, mapSettings.layerIds() )
|
||||||
{
|
{
|
||||||
@ -1099,9 +1100,6 @@ namespace QgsWms
|
|||||||
QStringList layersList, stylesList, layerIdList;
|
QStringList layersList, stylesList, layerIdList;
|
||||||
QImage* theImage = initializeRendering( layersList, stylesList, layerIdList, mapSettings );
|
QImage* theImage = initializeRendering( layersList, stylesList, layerIdList, mapSettings );
|
||||||
|
|
||||||
QPainter thePainter( theImage );
|
|
||||||
thePainter.setRenderHint( QPainter::Antialiasing ); //make it look nicer
|
|
||||||
|
|
||||||
QStringList layerSetIds = mapSettings.layerIds();
|
QStringList layerSetIds = mapSettings.layerIds();
|
||||||
|
|
||||||
QStringList highlightLayersId = QgsWmsConfigParser::addHighlightLayers( mParameters, layerSetIds );
|
QStringList highlightLayersId = QgsWmsConfigParser::addHighlightLayers( mParameters, layerSetIds );
|
||||||
@ -1142,36 +1140,41 @@ namespace QgsWms
|
|||||||
|
|
||||||
applyOpacities( layersList, bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
applyOpacities( layersList, bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||||
|
|
||||||
|
QScopedPointer<QPainter> painter;
|
||||||
if ( hitTest )
|
if ( hitTest )
|
||||||
runHitTest( mapSettings, &thePainter, *hitTest );
|
{
|
||||||
|
runHitTest( mapSettings, *hitTest );
|
||||||
|
painter.reset( new QPainter() );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QgsMapRendererCustomPainterJob renderJob( mapSettings, &thePainter );
|
|
||||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
renderJob.setFeatureFilterProvider( mAccessControl );
|
mAccessControl->resolveFilterFeatures( mapSettings.layers() );
|
||||||
#endif
|
#endif
|
||||||
renderJob.renderSynchronously();
|
QgsMapRendererJobProxy renderJob( mSettings.parallelRendering(),
|
||||||
|
mSettings.maxThreads()
|
||||||
|
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||||
|
, mAccessControl
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
renderJob.render( mapSettings, theImage );
|
||||||
|
painter.reset( renderJob.takePainter() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mConfigParser )
|
if ( mConfigParser )
|
||||||
{
|
{
|
||||||
//draw configuration format specific overlay items
|
//draw configuration format specific overlay items
|
||||||
mConfigParser->drawOverlays( &thePainter, theImage->dotsPerMeterX() / 1000.0 * 25.4, theImage->width(), theImage->height() );
|
mConfigParser->drawOverlays( painter.data(), theImage->dotsPerMeterX() / 1000.0 * 25.4, theImage->width(), theImage->height() );
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||||
clearFeatureSelections( selectedLayerIdList );
|
clearFeatureSelections( selectedLayerIdList );
|
||||||
QgsWmsConfigParser::removeHighlightLayers( highlightLayersId );
|
QgsWmsConfigParser::removeHighlightLayers( highlightLayersId );
|
||||||
|
|
||||||
// QgsMessageLog::logMessage( "clearing filters" );
|
|
||||||
if ( !hitTest )
|
if ( !hitTest )
|
||||||
QgsProject::instance()->removeAllMapLayers();
|
QgsProject::instance()->removeAllMapLayers();
|
||||||
|
|
||||||
//#ifdef QGISDEBUG
|
painter->end();
|
||||||
// theImage->save( QDir::tempPath() + QDir::separator() + "lastrender.png" );
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
thePainter.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)
|
//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 widthParam = mParameters.value( "WIDTH", "0" ).toInt();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define QGSWMSSERVER_H
|
#define QGSWMSSERVER_H
|
||||||
|
|
||||||
#include "qgswmsconfigparser.h"
|
#include "qgswmsconfigparser.h"
|
||||||
|
#include "qgsserversettings.h"
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
@ -67,9 +68,10 @@ namespace QgsWms
|
|||||||
QgsConfigParser and QgsCapabilitiesCache*/
|
QgsConfigParser and QgsCapabilitiesCache*/
|
||||||
QgsWmsServer(
|
QgsWmsServer(
|
||||||
const QString& configFilePath
|
const QString& configFilePath
|
||||||
|
, const QgsServerSettings& settings
|
||||||
, QMap<QString, QString> ¶meters
|
, QMap<QString, QString> ¶meters
|
||||||
, QgsWmsConfigParser* cp
|
, QgsWmsConfigParser* cp
|
||||||
, const QgsAccessControl* accessControl
|
, QgsAccessControl* accessControl
|
||||||
);
|
);
|
||||||
~QgsWmsServer();
|
~QgsWmsServer();
|
||||||
|
|
||||||
@ -190,7 +192,7 @@ namespace QgsWms
|
|||||||
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
|
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 renderer. This is useful for content-based legend
|
//! 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 );
|
void runHitTest( const QgsMapSettings& mapSettings, HitTest& hitTest );
|
||||||
//! Record which symbols within one layer would be rendered with the given renderer context
|
//! Record which symbols within one layer would be rendered with the given renderer context
|
||||||
void runHitTestLayer( QgsVectorLayer* vl, SymbolSet& usedSymbols, QgsRenderContext& context );
|
void runHitTestLayer( QgsVectorLayer* vl, SymbolSet& usedSymbols, QgsRenderContext& context );
|
||||||
|
|
||||||
@ -272,7 +274,9 @@ namespace QgsWms
|
|||||||
QgsWmsConfigParser* mConfigParser;
|
QgsWmsConfigParser* mConfigParser;
|
||||||
QString mConfigFilePath;
|
QString mConfigFilePath;
|
||||||
//! The access control helper
|
//! The access control helper
|
||||||
const QgsAccessControl* mAccessControl;
|
QgsAccessControl* mAccessControl;
|
||||||
|
|
||||||
|
QgsServerSettings mSettings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QDomElement createFeatureGML(
|
QDomElement createFeatureGML(
|
||||||
|
@ -166,6 +166,7 @@ ENDIF (WITH_APIDOC)
|
|||||||
|
|
||||||
IF (WITH_SERVER)
|
IF (WITH_SERVER)
|
||||||
ADD_PYTHON_TEST(PyQgsServer test_qgsserver.py)
|
ADD_PYTHON_TEST(PyQgsServer test_qgsserver.py)
|
||||||
|
ADD_PYTHON_TEST(PyQgsServerSettings test_qgsserver_settings.py)
|
||||||
ADD_PYTHON_TEST(PyQgsServerAccessControl test_qgsserver_accesscontrol.py)
|
ADD_PYTHON_TEST(PyQgsServerAccessControl test_qgsserver_accesscontrol.py)
|
||||||
ADD_PYTHON_TEST(PyQgsServerWFST test_qgsserver_wfst.py)
|
ADD_PYTHON_TEST(PyQgsServerWFST test_qgsserver_wfst.py)
|
||||||
ADD_PYTHON_TEST(PyQgsOfflineEditingWFS test_offline_editing_wfs.py)
|
ADD_PYTHON_TEST(PyQgsOfflineEditingWFS test_offline_editing_wfs.py)
|
||||||
|
214
tests/src/python/test_qgsserver_settings.py
Normal file
214
tests/src/python/test_qgsserver_settings.py
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""QGIS Unit tests for QgsServerSettings.
|
||||||
|
|
||||||
|
.. note:: This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
"""
|
||||||
|
__author__ = 'Paul Blottiere'
|
||||||
|
__date__ = '20/12/2016'
|
||||||
|
__copyright__ = 'Copyright 2016, The QGIS Project'
|
||||||
|
# This will get replaced with a git SHA1 when you do a git archive
|
||||||
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from qgis.PyQt.QtCore import QCoreApplication
|
||||||
|
|
||||||
|
from utilities import unitTestDataPath
|
||||||
|
from qgis.testing import unittest
|
||||||
|
from qgis.core import QgsApplication
|
||||||
|
from qgis.server import QgsServerSettings
|
||||||
|
|
||||||
|
|
||||||
|
class TestQgsServerSettings(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.settings = QgsServerSettings()
|
||||||
|
self.testdata_path = unitTestDataPath("qgis_server_settings")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_env_parallel_rendering(self):
|
||||||
|
env = "QGIS_SERVER_PARALLEL_RENDERING"
|
||||||
|
|
||||||
|
# test parallel rendering value from environment variable
|
||||||
|
os.environ[env] = "1"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertTrue(self.settings.parallelRendering())
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "0"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertFalse(self.settings.parallelRendering())
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_log_level(self):
|
||||||
|
env = "QGIS_SERVER_LOG_LEVEL"
|
||||||
|
|
||||||
|
# test log level value from environment variable
|
||||||
|
os.environ[env] = "3"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.logLevel(), 3)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "1"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.logLevel(), 1)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_log_file(self):
|
||||||
|
env = "QGIS_SERVER_LOG_FILE"
|
||||||
|
|
||||||
|
# test parallel rendering value from environment variable
|
||||||
|
os.environ[env] = "/tmp/qgisserv.log"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.logFile(), "/tmp/qgisserv.log")
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "/tmp/qserv.log"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.logFile(), "/tmp/qserv.log")
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_project_file(self):
|
||||||
|
env = "QGIS_PROJECT_FILE"
|
||||||
|
|
||||||
|
# test parallel rendering value from environment variable
|
||||||
|
os.environ[env] = "/tmp/myproject.qgs"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.projectFile(), "/tmp/myproject.qgs")
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "/tmp/myproject2.qgs"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.projectFile(), "/tmp/myproject2.qgs")
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_max_cache_layers(self):
|
||||||
|
env = "MAX_CACHE_LAYERS"
|
||||||
|
|
||||||
|
# test parallel rendering value from environment variable
|
||||||
|
os.environ[env] = "3"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.maxCacheLayers(), 3)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "100"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.maxCacheLayers(), 100)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_max_threads(self):
|
||||||
|
env = "QGIS_SERVER_MAX_THREADS"
|
||||||
|
|
||||||
|
# test parallel rendering value from environment variable
|
||||||
|
os.environ[env] = "3"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 3)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
os.environ[env] = "5"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 5)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_cache_size(self):
|
||||||
|
env = "QGIS_SERVER_CACHE_SIZE"
|
||||||
|
|
||||||
|
self.assertEqual(self.settings.cacheSize(), 50 * 1024 * 1024)
|
||||||
|
|
||||||
|
os.environ[env] = "1024"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.cacheSize(), 1024)
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_env_cache_directory(self):
|
||||||
|
env = "QGIS_SERVER_CACHE_DIRECTORY"
|
||||||
|
|
||||||
|
os.environ[env] = "/tmp/fake"
|
||||||
|
self.settings.load()
|
||||||
|
self.assertEqual(self.settings.cacheDirectory(), "/tmp/fake")
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_priority(self):
|
||||||
|
env = "QGIS_OPTIONS_PATH"
|
||||||
|
dpath = "conf0"
|
||||||
|
ini = "{0}.ini".format(os.path.join(self.testdata_path, dpath))
|
||||||
|
QCoreApplication.setOrganizationName(dpath)
|
||||||
|
|
||||||
|
# load settings
|
||||||
|
os.environ[env] = self.testdata_path
|
||||||
|
self.settings.load()
|
||||||
|
|
||||||
|
# test conf
|
||||||
|
self.assertTrue(self.settings.parallelRendering())
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 3)
|
||||||
|
|
||||||
|
# set environment variables and test priority
|
||||||
|
env_pr = "QGIS_SERVER_PARALLEL_RENDERING"
|
||||||
|
os.environ[env_pr] = "0"
|
||||||
|
|
||||||
|
env_mt = "QGIS_SERVER_MAX_THREADS"
|
||||||
|
os.environ[env_mt] = "5"
|
||||||
|
|
||||||
|
self.settings.load()
|
||||||
|
self.assertFalse(self.settings.parallelRendering())
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 5)
|
||||||
|
|
||||||
|
# clear environment
|
||||||
|
os.environ.pop(env)
|
||||||
|
os.environ.pop(env_pr)
|
||||||
|
os.environ.pop(env_mt)
|
||||||
|
|
||||||
|
def test_options_path_conf0(self):
|
||||||
|
env = "QGIS_OPTIONS_PATH"
|
||||||
|
dpath = "conf0"
|
||||||
|
ini = "{0}.ini".format(os.path.join(self.testdata_path, dpath))
|
||||||
|
QCoreApplication.setOrganizationName(dpath)
|
||||||
|
|
||||||
|
# load settings
|
||||||
|
os.environ[env] = self.testdata_path
|
||||||
|
self.settings.load()
|
||||||
|
|
||||||
|
# test ini file
|
||||||
|
self.assertEqual(ini, self.settings.iniFile())
|
||||||
|
|
||||||
|
# test conf
|
||||||
|
self.assertTrue(self.settings.parallelRendering())
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 3)
|
||||||
|
self.assertEqual(self.settings.cacheSize(), 52428800)
|
||||||
|
|
||||||
|
# default value when an empty string is indicated in ini file
|
||||||
|
self.assertEqual(self.settings.cacheDirectory(), "cache")
|
||||||
|
|
||||||
|
# clear environment
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
def test_options_path_conf1(self):
|
||||||
|
env = "QGIS_OPTIONS_PATH"
|
||||||
|
dpath = "conf1"
|
||||||
|
ini = "{0}.ini".format(os.path.join(self.testdata_path, dpath))
|
||||||
|
QCoreApplication.setOrganizationName(dpath)
|
||||||
|
|
||||||
|
# load settings
|
||||||
|
os.environ[env] = self.testdata_path
|
||||||
|
self.settings.load()
|
||||||
|
|
||||||
|
# test ini file
|
||||||
|
self.assertEqual(ini, self.settings.iniFile())
|
||||||
|
|
||||||
|
# test conf
|
||||||
|
self.assertFalse(self.settings.parallelRendering())
|
||||||
|
self.assertEqual(self.settings.maxThreads(), 5)
|
||||||
|
self.assertEqual(self.settings.cacheSize(), 52428800)
|
||||||
|
self.assertEqual(self.settings.cacheDirectory(), "/tmp/mycache")
|
||||||
|
|
||||||
|
# clear environment
|
||||||
|
os.environ.pop(env)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
7
tests/testdata/qgis_server_settings/conf0.ini
vendored
Normal file
7
tests/testdata/qgis_server_settings/conf0.ini
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[cache]
|
||||||
|
directory=
|
||||||
|
size=@Variant(\0\0\0\x81\0\0\0\0\x3 \0\0)
|
||||||
|
|
||||||
|
[qgis]
|
||||||
|
parallel_rendering=true
|
||||||
|
max_threads=3
|
7
tests/testdata/qgis_server_settings/conf1.ini
vendored
Normal file
7
tests/testdata/qgis_server_settings/conf1.ini
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[cache]
|
||||||
|
directory=/tmp/mycache
|
||||||
|
size=@Variant(\0\0\0\x81\0\0\0\0\x3 \0\0)
|
||||||
|
|
||||||
|
[qgis]
|
||||||
|
parallel_rendering=false
|
||||||
|
max_threads=5
|
Loading…
x
Reference in New Issue
Block a user