Skip to content
Permalink
Browse files

[server] parallel map rendering

  • Loading branch information
pblottiere authored and Hugo Mercier committed Jan 13, 2017
1 parent 563de37 commit 932d9fb5d3a7d95124614860bfc042a4291823fd
Showing with 1,166 additions and 102 deletions.
  1. +89 −0 python/server/qgsserversettings.sip
  2. +1 −1 python/server/qgswcserver.sip
  3. +2 −1 python/server/qgswfserver.sip
  4. +1 −1 python/server/qgswmserver.sip
  5. +1 −0 python/server/server.sip
  6. +2 −0 src/server/CMakeLists.txt
  7. +41 −3 src/server/qgsaccesscontrol.cpp
  8. +13 −0 src/server/qgsaccesscontrol.h
  9. +7 −13 src/server/qgsmslayercache.cpp
  10. +7 −0 src/server/qgsmslayercache.h
  11. +7 −3 src/server/qgsowsserver.h
  12. +26 −19 src/server/qgsserver.cpp
  13. +2 −0 src/server/qgsserver.h
  14. +10 −1 src/server/qgsserverinterface.h
  15. +6 −1 src/server/qgsserverinterfaceimpl.cpp
  16. +6 −2 src/server/qgsserverinterfaceimpl.h
  17. +21 −16 src/server/qgsserverlogger.cpp
  18. +14 −0 src/server/qgsserverlogger.h
  19. +307 −0 src/server/qgsserversettings.cpp
  20. +154 −0 src/server/qgsserversettings.h
  21. +4 −1 src/server/qgswcsserver.cpp
  22. +2 −1 src/server/qgswcsserver.h
  23. +4 −1 src/server/qgswfsserver.cpp
  24. +2 −1 src/server/qgswfsserver.h
  25. +4 −3 src/server/services/wms/CMakeLists.txt
  26. +3 −1 src/server/services/wms/qgsdxfwriter.cpp
  27. +80 −0 src/server/services/wms/qgsmaprendererjobproxy.cpp
  28. +68 −0 src/server/services/wms/qgsmaprendererjobproxy.h
  29. +3 −1 src/server/services/wms/qgswmsdescribelayer.cpp
  30. +5 −2 src/server/services/wms/qgswmsgetcapabilities.cpp
  31. +3 −1 src/server/services/wms/qgswmsgetcontext.cpp
  32. +2 −1 src/server/services/wms/qgswmsgetfeatureinfo.cpp
  33. +2 −2 src/server/services/wms/qgswmsgetlegendgraphics.cpp
  34. +2 −1 src/server/services/wms/qgswmsgetmap.cpp
  35. +2 −1 src/server/services/wms/qgswmsgetprint.cpp
  36. +2 −1 src/server/services/wms/qgswmsgetschemaextension.cpp
  37. +2 −1 src/server/services/wms/qgswmsgetstyle.cpp
  38. +2 −1 src/server/services/wms/qgswmsgetstyles.cpp
  39. +21 −18 src/server/services/wms/qgswmsservertransitional.cpp
  40. +7 −3 src/server/services/wms/qgswmsservertransitional.h
  41. +1 −0 tests/src/python/CMakeLists.txt
  42. +214 −0 tests/src/python/test_qgsserver_settings.py
  43. +7 −0 tests/testdata/qgis_server_settings/conf0.ini
  44. +7 −0 tests/testdata/qgis_server_settings/conf1.ini
@@ -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:
/** 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 );
~QgsWCSServer();

@@ -59,7 +59,8 @@ class QgsWfsServer: public QgsOWSServer
{
public:
/** 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 );
~QgsWfsServer();

@@ -60,7 +60,7 @@ class QgsWmsServer: public QgsOWSServer
public:
/** Constructor. Does _NOT_ take ownership of
QgsConfigParser, QgsCapabilitiesCache*/
QgsWmsServer( const QString& configFilePath, QMap<QString, QString> &parameters, QgsWmsConfigParser* cp, QgsRequestHandler* rh, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
QgsWmsServer( const QString& configFilePath, const QgsServerSettings& settings, QMap<QString, QString> &parameters, QgsWmsConfigParser* cp, QgsRequestHandler* rh, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
~QgsWmsServer();

void executeRequest() override;
@@ -27,6 +27,7 @@
%Include qgswmsprojectparser.sip
%Include qgswfsprojectparser.sip
%Include qgsconfigcache.sip
%Include qgsserversettings.sip
%Include qgsserver.sip

%Include qgsserverrequest.sip
@@ -27,6 +27,7 @@ SET ( qgis_mapserv_SRCS
qgsowsserver.cpp
qgswfsserver.cpp
qgswcsserver.cpp
qgsserversettings.cpp
qgsmapserviceexception.cpp
qgsmslayercache.cpp
qgsmslayerbuilder.cpp
@@ -75,6 +76,7 @@ SET (qgis_mapserv_MOC_HDRS
# qgshttptransaction.h
qgsmslayercache.h
qgsserverlogger.h
qgsserversettings.h
qgsserverstreamingdevice.h
)

@@ -22,12 +22,25 @@

#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
void QgsAccessControl::filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const
mResolved = true;
}

QString QgsAccessControl::resolveFilterFeatures( const QgsVectorLayer* layer ) const
{
QStringList expressions = QStringList();
QgsAccessControlFilterMap::const_iterator acIterator;

for ( acIterator = mPluginsAccessControls->constBegin(); acIterator != mPluginsAccessControls->constEnd(); ++acIterator )
{
QString expression = acIterator.value()->layerFilterExpression( layer );
@@ -36,9 +49,34 @@ void QgsAccessControl::filterFeatures( const QgsVectorLayer* layer, QgsFeatureRe
expressions.append( expression );
}
}

QString expression;
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()
{
mPluginsAccessControls = new QgsAccessControlFilterMap();
mResolved = false;
}

//! Constructor
QgsAccessControl( const QgsAccessControl& copy )
{
mPluginsAccessControls = new QgsAccessControlFilterMap( *copy.mPluginsAccessControls );
mFilterFeaturesExpressions = copy.mFilterFeaturesExpressions;
mResolved = copy.mResolved;
}


@@ -54,6 +57,11 @@ class SERVER_EXPORT QgsAccessControl : public QgsFeatureFilterProvider
delete mPluginsAccessControls;
}

/** Resolve features' filter of layers
* @param layers to filter
*/
void resolveFilterFeatures( const QList<QgsMapLayer*> &layers );

/** Filter the features of the layer
* @param layer the layer to control
* @param filterFeatures the request to fill
@@ -122,8 +130,13 @@ class SERVER_EXPORT QgsAccessControl : public QgsFeatureFilterProvider
void registerAccessControl( QgsAccessControlFilter* accessControl, int priority = 0 );

private:
QString resolveFilterFeatures( const QgsVectorLayer* layer ) const;

//! The AccessControl plugins registry
QgsAccessControlFilterMap* mPluginsAccessControls;

QMap<QString, QString> mFilterFeaturesExpressions;
bool mResolved;
};

#endif
@@ -21,6 +21,7 @@
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgsserversettings.h"
#include <QFile>

QgsMSLayerCache* QgsMSLayerCache::instance()
@@ -32,20 +33,8 @@ QgsMSLayerCache* QgsMSLayerCache::instance()
}

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& ) ) );
}

@@ -59,6 +48,11 @@ QgsMSLayerCache::~QgsMSLayerCache()
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 )
{
QgsMessageLog::logMessage( "Layer cache: insert Layer '" + layerName + "' configFile: " + configFile, QStringLiteral( "Server" ), QgsMessageLog::INFO );
@@ -56,6 +56,13 @@ class QgsMSLayerCache: public QObject
static QgsMSLayerCache* instance();
~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
@param url the layer 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 "qgsrequesthandler.h"
#include "qgsserversettings.h"
#ifdef HAVE_SERVER_PYTHON_PLUGINS
#include "qgsaccesscontrol.h"
#else
@@ -35,11 +36,13 @@ class QgsOWSServer
public:
QgsOWSServer(
const QString& configFilePath
, const QgsServerSettings& settings
, const QMap<QString, QString>& parameters
, QgsRequestHandler* rh
, const QgsAccessControl* ac
, QgsAccessControl* ac
)
: mParameters( parameters )
: mSettings( settings )
, mParameters( parameters )
, mRequestHandler( rh )
, mConfigFilePath( configFilePath )
, mAccessControl( ac )
@@ -57,12 +60,13 @@ class QgsOWSServer
QgsOWSServer() {}

protected:
QgsServerSettings mSettings;
QMap<QString, QString> mParameters;
QgsRequestHandler* mRequestHandler;
QString mConfigFilePath;

//! The access control helper
const QgsAccessControl* mAccessControl;
QgsAccessControl* mAccessControl;

#ifdef HAVE_SERVER_PYTHON_PLUGINS

0 comments on commit 932d9fb

Please sign in to comment.
You can’t perform that action at this time.