Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[server] parallel map rendering
  • Loading branch information
pblottiere authored and Hugo Mercier committed Jan 13, 2017
1 parent 563de37 commit 932d9fb
Show file tree
Hide file tree
Showing 44 changed files with 1,166 additions and 102 deletions.
89 changes: 89 additions & 0 deletions python/server/qgsserversettings.sip
@@ -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;
};
2 changes: 1 addition & 1 deletion python/server/qgswcserver.sip
Expand Up @@ -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();

Expand Down
3 changes: 2 additions & 1 deletion python/server/qgswfserver.sip
Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswmserver.sip
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions python/server/server.sip
Expand Up @@ -27,6 +27,7 @@
%Include qgswmsprojectparser.sip
%Include qgswfsprojectparser.sip
%Include qgsconfigcache.sip
%Include qgsserversettings.sip
%Include qgsserver.sip

%Include qgsserverrequest.sip
Expand Down
2 changes: 2 additions & 0 deletions src/server/CMakeLists.txt
Expand Up @@ -27,6 +27,7 @@ SET ( qgis_mapserv_SRCS
qgsowsserver.cpp
qgswfsserver.cpp
qgswcsserver.cpp
qgsserversettings.cpp
qgsmapserviceexception.cpp
qgsmslayercache.cpp
qgsmslayerbuilder.cpp
Expand Down Expand Up @@ -75,6 +76,7 @@ SET (qgis_mapserv_MOC_HDRS
# qgshttptransaction.h
qgsmslayercache.h
qgsserverlogger.h
qgsserversettings.h
qgsserverstreamingdevice.h
)

Expand Down
44 changes: 41 additions & 3 deletions src/server/qgsaccesscontrol.cpp
Expand Up @@ -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 );
Expand All @@ -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 );
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/server/qgsaccesscontrol.h
Expand Up @@ -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;
}


Expand All @@ -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
Expand Down Expand Up @@ -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
20 changes: 7 additions & 13 deletions src/server/qgsmslayercache.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgsserversettings.h"
#include <QFile>

QgsMSLayerCache* QgsMSLayerCache::instance()
Expand All @@ -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& ) ) );
}

Expand All @@ -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 );
Expand Down
7 changes: 7 additions & 0 deletions src/server/qgsmslayercache.h
Expand Up @@ -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
Expand Down
10 changes: 7 additions & 3 deletions src/server/qgsowsserver.h
Expand Up @@ -20,6 +20,7 @@

#include "qgsconfig.h"
#include "qgsrequesthandler.h"
#include "qgsserversettings.h"
#ifdef HAVE_SERVER_PYTHON_PLUGINS
#include "qgsaccesscontrol.h"
#else
Expand All @@ -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 )
Expand All @@ -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

Expand Down

0 comments on commit 932d9fb

Please sign in to comment.