Skip to content

Commit

Permalink
Merge pull request #38225 from rldhont/project-read-flag-trust-layer-…
Browse files Browse the repository at this point in the history
…metadata

New project reading flag to trust layer metadata with server settings
  • Loading branch information
rldhont committed Aug 12, 2020
2 parents 4f6e638 + 22173e9 commit 0b3ec39
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 4 deletions.
4 changes: 3 additions & 1 deletion python/core/auto_additions/qgsproject.py
Expand Up @@ -4,7 +4,9 @@
QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ = "Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read time if the actual data from the layers is not required."
QgsProject.FlagDontLoadLayouts = QgsProject.ReadFlag.FlagDontLoadLayouts
QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ = "Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe)."
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__
QgsProject.FlagTrustLayerMetadata = QgsProject.ReadFlag.FlagTrustLayerMetadata
QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ = "Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server."
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ + '\n' + '* ``FlagTrustLayerMetadata``: ' + QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__
# --
# monkey patching scoped based enum
QgsProject.FileFormat.Qgz.__doc__ = "Archive file format, supports auxiliary data"
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsproject.sip.in
Expand Up @@ -38,6 +38,7 @@ open within the main QGIS application.
{
FlagDontResolveLayers,
FlagDontLoadLayouts,
FlagTrustLayerMetadata,
};
typedef QFlags<QgsProject::ReadFlag> ReadFlags;

Expand Down
10 changes: 10 additions & 0 deletions python/server/auto_generated/qgsserversettings.sip.in
Expand Up @@ -184,6 +184,16 @@ The default value is ``True``, this value can be changed by setting the environm
variable QGIS_SERVER_IGNORE_BAD_LAYERS.

.. versionadded:: 3.10.5
%End

bool trustLayerMetadata() const;
%Docstring
Returns ``True`` if the reading flag trust layer metadata is activated.

The default value is ``False``, this value can be changed by setting the environment
variable QGIS_SERVER_TRUST_LAYER_METADATA.

.. versionadded:: 3.16
%End

};
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsproject.cpp
Expand Up @@ -1121,7 +1121,7 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList<QDomNode> &broken
// apply specific settings to vector layer
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mapLayer.get() ) )
{
vl->setReadExtentFromXml( mTrustLayerMetadata );
vl->setReadExtentFromXml( mTrustLayerMetadata || ( flags & QgsProject::ReadFlag::FlagTrustLayerMetadata ) );
}
}
else if ( type == QLatin1String( "raster" ) )
Expand Down Expand Up @@ -1497,6 +1497,7 @@ bool QgsProject::readProjectFile( const QString &filename, QgsProject::ReadFlags
mEvaluateDefaultValues = true;
}

// Read trust layer metadata config in the project
nl = doc->elementsByTagName( QStringLiteral( "trust" ) );
if ( nl.count() )
{
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsproject.h
Expand Up @@ -118,6 +118,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
{
FlagDontResolveLayers = 1 << 0, //!< Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read time if the actual data from the layers is not required.
FlagDontLoadLayouts = 1 << 1, //!< Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe).
FlagTrustLayerMetadata = 1 << 2, //!< Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server.
};
Q_DECLARE_FLAGS( ReadFlags, ReadFlag )

Expand Down
10 changes: 9 additions & 1 deletion src/server/qgsconfigcache.cpp
Expand Up @@ -44,9 +44,17 @@ const QgsProject *QgsConfigCache::project( const QString &path, QgsServerSetting
if ( ! mProjectCache[ path ] )
{
std::unique_ptr<QgsProject> prj( new QgsProject() );

QgsStoreBadLayerInfo *badLayerHandler = new QgsStoreBadLayerInfo();
prj->setBadLayerHandler( badLayerHandler );
if ( prj->read( path ) )

QgsProject::ReadFlags readFlags = QgsProject::ReadFlag();
if ( ! settings || ! settings->trustLayerMetadata() )
{
readFlags |= QgsProject::ReadFlag::FlagTrustLayerMetadata;
}

if ( prj->read( path, readFlags ) )
{
if ( !badLayerHandler->badLayers().isEmpty() )
{
Expand Down
16 changes: 16 additions & 0 deletions src/server/qgsserversettings.cpp
Expand Up @@ -163,6 +163,17 @@ void QgsServerSettings::initSettings()
};
mSettings[ sIgnoreBadLayers.envVar ] = sIgnoreBadLayers;

// trust layer metadata
const Setting sTrustLayerMetadata = { QgsServerSettingsEnv::QGIS_SERVER_TRUST_LAYER_METADATA,
QgsServerSettingsEnv::DEFAULT_VALUE,
QStringLiteral( "Trust layer metadata" ),
QString(),
QVariant::Bool,
QVariant( false ),
QVariant()
};
mSettings[ sTrustLayerMetadata.envVar ] = sTrustLayerMetadata;

// show group separator
const Setting sShowGroupSeparator = { QgsServerSettingsEnv::QGIS_SERVER_SHOW_GROUP_SEPARATOR,
QgsServerSettingsEnv::DEFAULT_VALUE,
Expand Down Expand Up @@ -434,3 +445,8 @@ bool QgsServerSettings::ignoreBadLayers() const
{
return value( QgsServerSettingsEnv::QGIS_SERVER_IGNORE_BAD_LAYERS ).toBool();
}

bool QgsServerSettings::trustLayerMetadata() const
{
return value( QgsServerSettingsEnv::QGIS_SERVER_TRUST_LAYER_METADATA ).toBool();
}
13 changes: 12 additions & 1 deletion src/server/qgsserversettings.h
Expand Up @@ -67,7 +67,8 @@ class SERVER_EXPORT QgsServerSettingsEnv : public QObject
QGIS_SERVER_WMS_MAX_HEIGHT, //!< Maximum height for a WMS request. The most conservative between this and the project one is used (since QGIS 3.6.2)
QGIS_SERVER_WMS_MAX_WIDTH, //!< Maximum width for a WMS request. The most conservative between this and the project one is used (since QGIS 3.6.2)
QGIS_SERVER_API_RESOURCES_DIRECTORY, //!< Base directory where HTML templates and static assets (e.g. images, js and css files) are searched for (since QGIS 3.10).
QGIS_SERVER_API_WFS3_MAX_LIMIT //!< Maximum value for "limit" in a features request, defaults to 10000 (since QGIS 3.10).
QGIS_SERVER_API_WFS3_MAX_LIMIT, //!< Maximum value for "limit" in a features request, defaults to 10000 (since QGIS 3.10).
QGIS_SERVER_TRUST_LAYER_METADATA //!< Trust layer metadata (since QGIS 3.16).
};
Q_ENUM( EnvVar )
};
Expand Down Expand Up @@ -234,6 +235,16 @@ class SERVER_EXPORT QgsServerSettings
*/
bool ignoreBadLayers() const;

/**
* Returns TRUE if the reading flag trust layer metadata is activated.
*
* The default value is FALSE, this value can be changed by setting the environment
* variable QGIS_SERVER_TRUST_LAYER_METADATA.
*
* \since QGIS 3.16
*/
bool trustLayerMetadata() const;

private:
void initSettings();
QVariant value( QgsServerSettingsEnv::EnvVar envVar ) const;
Expand Down
15 changes: 15 additions & 0 deletions tests/src/python/test_qgsserver_settings.py
Expand Up @@ -131,6 +131,21 @@ def test_env_cache_directory(self):
self.assertEqual(self.settings.cacheDirectory(), "/tmp/fake")
os.environ.pop(env)

def test_env_trust_layer_metadata(self):
env = "QGIS_SERVER_TRUST_LAYER_METADATA"

self.assertFalse(self.settings.trustLayerMetadata())

os.environ[env] = "1"
self.settings.load()
self.assertTrue(self.settings.trustLayerMetadata())
os.environ.pop(env)

os.environ[env] = "0"
self.settings.load()
self.assertFalse(self.settings.trustLayerMetadata())
os.environ.pop(env)

def test_priority(self):
env = "QGIS_OPTIONS_PATH"
dpath = "conf0"
Expand Down

0 comments on commit 0b3ec39

Please sign in to comment.