Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't reset mesh layer styling when changing data source for layer #45392

Merged
merged 5 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshlayer.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ Constructor for LayerOptions with optional ``transformContext``.

QgsCoordinateTransformContext transformContext;

bool loadDefaultStyle;

bool skipCrsValidation;
};

Expand Down Expand Up @@ -161,6 +163,8 @@ QgsMeshLayer cannot be copied.

virtual bool supportsEditing() const;

virtual QString loadDefaultStyle( bool &resultFlag /Out/ ) ${SIP_FINAL};


QString providerType() const;
%Docstring
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,22 @@ Returns the method used to match dataset from temporal capabilities
Sets the method used to match dataset from temporal capabilities

:param matchingMethod: the matching method
%End

bool isValid() const;
%Docstring
Returns whether the instance is valid

.. versionadded:: 3.22
%End

void setIsValid( bool isValid );
%Docstring
Sets whether the instance is valid

:param isValid: whether the instance is valid

.. versionadded:: 3.22
%End

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,13 @@ Returns the active vector dataset group
Sets the active vector dataset group

.. versionadded:: 3.14
%End

bool hasSettings( int datasetGroupIndex ) const;
%Docstring
Returns whether the group with ``index`` has render settings (scalar or vector)

.. versionadded:: 3.22
%End

};
Expand Down
6 changes: 4 additions & 2 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "qgsvectorlayer.h"
#include "qgsvectorlayerlabeling.h"
#include "qgsxmlutils.h"
#include "qgsmeshlayer.h"


QgsAppLayerTreeViewMenuProvider::QgsAppLayerTreeViewMenuProvider( QgsLayerTreeView *view, QgsMapCanvas *canvas )
Expand Down Expand Up @@ -153,6 +154,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
QgsPointCloudLayer *pcLayer = qobject_cast<QgsPointCloudLayer * >( layer );
QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer * >( layer );

if ( layer && layer->isSpatial() )
{
Expand Down Expand Up @@ -363,8 +365,8 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
menu->addAction( tr( "&Filter…" ), QgisApp::instance(), qOverload<>( &QgisApp::layerSubsetString ) );
}

// change data source is only supported for vectors and rasters, point clouds
if ( vlayer || rlayer || pcLayer )
// change data source is only supported for vectors, rasters, point clouds, mesh
if ( vlayer || rlayer || pcLayer || meshLayer )
{

QAction *a = new QAction( layer->isValid() ? tr( "C&hange Data Source…" ) : tr( "Repair Data Source…" ), menu );
Expand Down
10 changes: 10 additions & 0 deletions src/core/mesh/qgsmeshdatasetgroupstore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,16 @@ void QgsMeshDatasetGroupStore::readXml( const QDomElement &storeElem, const QgsR
setDatasetGroupTreeItem( new QgsMeshDatasetGroupTreeItem( rootTreeItemElem, context ) );
}

int QgsMeshDatasetGroupStore::globalDatasetGroupIndexInSource( QgsMeshDatasetSourceInterface *source, int nativeGroupIndex ) const
{
for ( QMap<int, DatasetGroup>::const_iterator it = mRegistery.cbegin(); it != mRegistery.cend(); ++it )
{
if ( it.value().first == source && it.value().second == nativeGroupIndex )
return it.key();
}

return -1;
}

bool QgsMeshDatasetGroupStore::saveDatasetGroup( QString filePath, int groupIndex, QString driver )
{
Expand Down
8 changes: 8 additions & 0 deletions src/core/mesh/qgsmeshdatasetgroupstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ class QgsMeshDatasetGroupStore: public QObject
//! Reads the store's information from a DOM document
void readXml( const QDomElement &storeElem, const QgsReadWriteContext &context );

/**
* Returns the global dataset group index of the dataset group with native index \a globalGroupIndex in the \a source
* Returns -1 if the group or the source is not registered
*
* Since QGIS 3.22
*/
int globalDatasetGroupIndexInSource( QgsMeshDatasetSourceInterface *source, int nativeGroupIndex ) const;

signals:
//! Emitted after dataset groups are added
void datasetGroupsAdded( QList<int> indexes );
Expand Down
52 changes: 39 additions & 13 deletions src/core/mesh/qgsmeshlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ QgsMeshLayer::QgsMeshLayer( const QString &meshLayerPath,
: QgsMapLayer( QgsMapLayerType::MeshLayer, baseName, meshLayerPath ),
mDatasetGroupStore( new QgsMeshDatasetGroupStore( this ) ),
mTemporalProperties( new QgsMeshLayerTemporalProperties( this ) )

{
mShouldValidateCrs = !options.skipCrsValidation;

const QgsDataProvider::ProviderOptions providerOptions { options.transformContext };
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( options.loadDefaultStyle )
{
flags |= QgsDataProvider::FlagLoadDefaultStyle;
}
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
Expand All @@ -65,7 +68,7 @@ QgsMeshLayer::QgsMeshLayer( const QString &meshLayerPath,
resetDatasetGroupTreeItem();
setLegend( QgsMapLayerLegend::defaultMeshLegend( this ) );

if ( isValid() )
if ( isValid() && options.loadDefaultStyle )
setDefaultRendererSettings( mDatasetGroupStore->datasetGroupIndexes() );

connect( mDatasetGroupStore.get(), &QgsMeshDatasetGroupStore::datasetGroupsAdded, this, &QgsMeshLayer::onDatasetGroupsAdded );
Expand Down Expand Up @@ -201,6 +204,22 @@ bool QgsMeshLayer::supportsEditing() const
return driverMetadata.capabilities() & QgsMeshDriverMetadata::CanWriteMeshData;
}

QString QgsMeshLayer::loadDefaultStyle( bool &resultFlag )
{
const QList<int> groupsList = datasetGroupsIndexes();

for ( const int index : groupsList )
assignDefaultStyleToDatasetGroup( index );

if ( !groupsList.isEmpty() )
{
emit rendererChanged();
emitStyleChanged();
}

return QgsMapLayer::loadDefaultStyle( resultFlag );
}

bool QgsMeshLayer::addDatasets( const QString &path, const QDateTime &defaultReferenceTime )
{
const bool isTemporalBefore = dataProvider()->temporalCapabilities()->hasTemporalCapabilities();
Expand Down Expand Up @@ -1138,17 +1157,8 @@ void QgsMeshLayer::setDataSourcePrivate( const QString &dataSource, const QStrin
mLayerName = baseName;
setProviderType( provider );

// if we’re given a provider type, try to create and bind one to this layer
bool ok = false;
if ( !mDataSource.isEmpty() && !provider.isEmpty() )
{
ok = setDataProvider( provider, options, flags );
}

if ( ok )
{
mTemporalProperties->setDefaultsFromDataProviderTemporalCapabilities( mDataProvider->temporalCapabilities() );
}
setDataProvider( provider, options, flags );
}

QgsPointXY QgsMeshLayer::snapOnElement( QgsMesh::ElementType elementType, const QgsPointXY &point, double searchRadius )
Expand Down Expand Up @@ -1693,8 +1703,15 @@ bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvid
return false;
}

if ( !mTemporalProperties->isValid() )
{
mTemporalProperties->setDefaultsFromDataProviderTemporalCapabilities( dataProvider()->temporalCapabilities() );
}

mDataProvider->setTemporalUnit( mTemporalUnit );

mDatasetGroupStore->setPersistentProvider( mDataProvider, mExtraDatasetUri );

setCrs( mDataProvider->crs() );

if ( provider == QLatin1String( "mesh_memory" ) )
Expand All @@ -1703,8 +1720,17 @@ bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvid
mDataSource = mDataSource + QStringLiteral( "&uid=%1" ).arg( QUuid::createUuid().toString() );
}

// set default style if required by flags or if the dataset group does not has a style yet
for ( int i = 0; i < mDataProvider->datasetGroupCount(); ++i )
assignDefaultStyleToDatasetGroup( i );
{
int globalIndex = mDatasetGroupStore->globalDatasetGroupIndexInSource( mDataProvider, i );
if ( globalIndex != -1 &&
( !mRendererSettings.hasSettings( globalIndex ) || ( flags & QgsDataProvider::FlagLoadDefaultStyle ) ) )
assignDefaultStyleToDatasetGroup( globalIndex );
}

emit rendererChanged();
emitStyleChanged();

connect( mDataProvider, &QgsMeshDataProvider::dataChanged, this, &QgsMeshLayer::dataChanged );

Expand Down
10 changes: 10 additions & 0 deletions src/core/mesh/qgsmeshlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,17 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
: transformContext( transformContext )
{}

/**
* Coordinate transform context
*/
QgsCoordinateTransformContext transformContext;

/**
* Set to TRUE if the default layer style should be loaded.
* \since QGIS 3.22
*/
bool loadDefaultStyle = true;

/**
* Controls whether the layer is allowed to have an invalid/unknown CRS.
*
Expand Down Expand Up @@ -182,6 +191,7 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
QString htmlMetadata() const override;
bool isEditable() const override;
bool supportsEditing() const override;
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) FINAL;

//! Returns the provider type for this layer
QString providerType() const;
Expand Down
13 changes: 13 additions & 0 deletions src/core/mesh/qgsmeshlayertemporalproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ bool QgsMeshLayerTemporalProperties::readXml( const QDomElement &element, const
mMatchingMethod = static_cast<QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod>(
temporalElement.attribute( QStringLiteral( "matching-method" ) ).toInt() );

mIsValid = true;
return true;
}

Expand All @@ -74,6 +75,8 @@ void QgsMeshLayerTemporalProperties::setDefaultsFromDataProviderTemporalCapabili

if ( mReferenceTime.isValid() )
mTimeExtent = temporalCapabilities->timeExtent();

mIsValid = true;
}

QgsDateTimeRange QgsMeshLayerTemporalProperties::calculateTemporalExtent( QgsMapLayer * ) const
Expand Down Expand Up @@ -112,3 +115,13 @@ void QgsMeshLayerTemporalProperties::setMatchingMethod( const QgsMeshDataProvide
{
mMatchingMethod = matchingMethod;
}

bool QgsMeshLayerTemporalProperties::isValid() const
{
return mIsValid;
}

void QgsMeshLayerTemporalProperties::setIsValid( bool isValid )
{
mIsValid = isValid;
}
17 changes: 17 additions & 0 deletions src/core/mesh/qgsmeshlayertemporalproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,28 @@ class CORE_EXPORT QgsMeshLayerTemporalProperties : public QgsMapLayerTemporalPro
*/
void setMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );

/**
* Returns whether the instance is valid
*
* \since QGIS 3.22
*/
bool isValid() const;

/**
* Sets whether the instance is valid
*
* \param isValid whether the instance is valid
*
* \since QGIS 3.22
*/
void setIsValid( bool isValid );

private:
QDateTime mReferenceTime;
QgsDateTimeRange mTimeExtent;
QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod mMatchingMethod =
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetBeforeStartRangeTime;
bool mIsValid = false;
};

#endif // QGSMESHLAYERTEMPORALPROPERTIES_H
4 changes: 4 additions & 0 deletions src/core/mesh/qgsmeshrenderersettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,3 +740,7 @@ void QgsMeshRendererVectorTracesSettings::setParticlesCount( int value )
mParticlesCount = value;
}

bool QgsMeshRendererSettings::hasSettings( int datasetGroupIndex ) const
{
return mRendererScalarSettings.contains( datasetGroupIndex ) || mRendererVectorSettings.contains( datasetGroupIndex );
}
7 changes: 7 additions & 0 deletions src/core/mesh/qgsmeshrenderersettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,13 @@ class CORE_EXPORT QgsMeshRendererSettings
*/
void setActiveVectorDatasetGroup( int activeVectorDatasetGroup );

/**
* Returns whether the group with \a index has render settings (scalar or vector)
*
* \since QGIS 3.22
*/
bool hasSettings( int datasetGroupIndex ) const;

private:
QgsMeshRendererMeshSettings mRendererNativeMeshSettings;
QgsMeshRendererMeshSettings mRendererTriangularMeshSettings;
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsmaplayerfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ QgsMapLayer *QgsMapLayerFactory::createLayer( const QString &uri, const QString
{
QgsMeshLayer::LayerOptions meshOptions;
meshOptions.transformContext = options.transformContext;
meshOptions.loadDefaultStyle = options.loadDefaultStyle;
return new QgsMeshLayer( uri, name, provider, meshOptions );
}

Expand Down