Skip to content
Permalink
Browse files

Merge pull request #3886 from pblottiere/servermultithread

[server] parallel map rendering
  • Loading branch information
rldhont committed Jan 9, 2017
2 parents 590a981 + f7729b3 commit 350a2b513446462120946241cf7fb1bb67ca828b
@@ -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;
};
@@ -27,4 +27,5 @@
%Include qgswmsprojectparser.sip
%Include qgswfsprojectparser.sip
%Include qgsconfigcache.sip
%Include qgsserversettings.sip
%Include qgsserver.sip
@@ -29,6 +29,7 @@ SET ( qgis_mapserv_SRCS
qgswmsserver.cpp
qgswfsserver.cpp
qgswcsserver.cpp
qgsserversettings.cpp
qgsmapserviceexception.cpp
qgsmslayercache.cpp
qgsmslayerbuilder.cpp
@@ -67,6 +68,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
@@ -19,6 +19,7 @@
#define QGSOWSSERVER_H

#include "qgsrequesthandler.h"
#include "qgsserversettings.h"
#ifdef HAVE_SERVER_PYTHON_PLUGINS
#include "qgsaccesscontrol.h"
#endif
@@ -32,13 +33,15 @@ class QgsOWSServer
public:
QgsOWSServer(
const QString& configFilePath
, const QgsServerSettings& settings
, const QMap<QString, QString>& parameters
, QgsRequestHandler* rh
#ifdef HAVE_SERVER_PYTHON_PLUGINS
, const QgsAccessControl* ac
, QgsAccessControl* ac
#endif
)
: mParameters( parameters )
: mSettings( settings )
, mParameters( parameters )
, mRequestHandler( rh )
, mConfigFilePath( configFilePath )
#ifdef HAVE_SERVER_PYTHON_PLUGINS
@@ -58,12 +61,13 @@ class QgsOWSServer
QgsOWSServer() {}

protected:
QgsServerSettings mSettings;
QMap<QString, QString> mParameters;
QgsRequestHandler* mRequestHandler;
QString mConfigFilePath;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
//! The access control helper
const QgsAccessControl* mAccessControl;
QgsAccessControl* mAccessControl;

/** Apply filter strings from the access control to the layers.
* @param layer the concerned layer

0 comments on commit 350a2b5

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