Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move postgres raster temporal settings out of QgsRasterLayerProperties
and to dedicated widget in postgres provider

Further cleanups to remove provider-specific logic from generic class
  • Loading branch information
nyalldawson committed Mar 24, 2021
1 parent 65c78aa commit 3a30e62
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 152 deletions.
78 changes: 0 additions & 78 deletions src/gui/raster/qgsrasterlayerproperties.cpp
Expand Up @@ -294,49 +294,6 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
temporalLayout->addWidget( mTemporalWidget );

// This group is used to define the temporal capabilities of the PG raster layer
if ( mRasterLayer->dataProvider() && mRasterLayer->providerType() == QLatin1String( "postgresraster" ) )
{
mPostgresRasterTemporalGroup->setEnabled( true );
mPostgresRasterTemporalGroup->setVisible( true );
mPostgresRasterTemporalGroup->setChecked( false );
const QgsFields fields { mRasterLayer->dataProvider()->fields() };
mPostgresRasterTemporalFieldComboBox->setFields( fields );
mPostgresRasterTemporalFieldComboBox->setFilters( QgsFieldProxyModel::Filter::Date |
QgsFieldProxyModel::Filter::DateTime |
QgsFieldProxyModel::Filter::String );
mPostgresRasterTemporalFieldComboBox->setAllowEmptyFieldName( true );
connect( mPostgresRasterTemporalFieldComboBox, &QgsFieldComboBox::fieldChanged, this, [ = ]( const QString & fieldName )
{
mPostgresRasterDefaultTime->setEnabled( ! fieldName.isEmpty() );
} );
mPostgresRasterDefaultTime->setAllowNull( true );
mPostgresRasterDefaultTime->setEmpty();
if ( mRasterLayer->dataProvider()->uri().hasParam( QStringLiteral( "temporalFieldIndex" ) ) )
{
bool ok;
const int fieldIdx { mRasterLayer->dataProvider()->uri().param( QStringLiteral( "temporalFieldIndex" ) ).toInt( &ok ) };
if ( ok && fields.exists( fieldIdx ) )
{
mPostgresRasterTemporalGroup->setChecked( true );
mPostgresRasterTemporalFieldComboBox->setField( fields.field( fieldIdx ).name() );
if ( mRasterLayer->dataProvider()->uri().hasParam( QStringLiteral( "temporalDefaultTime" ) ) )
{
const QDateTime defaultDateTime { QDateTime::fromString( mRasterLayer->dataProvider()->uri().param( QStringLiteral( "temporalDefaultTime" ) ), Qt::DateFormat::ISODate ) };
if ( defaultDateTime.isValid() )
{
mPostgresRasterDefaultTime->setDateTime( defaultDateTime );
}
}
}
}
}
else
{
mPostgresRasterTemporalGroup->setEnabled( false );
mPostgresRasterTemporalGroup->setVisible( false );
}

QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), 2 );
QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
mCrsSelector->setCrs( mRasterLayer->crs() );
Expand Down Expand Up @@ -1095,41 +1052,6 @@ void QgsRasterLayerProperties::apply()
//set the blend mode for the layer
mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );

// Update temporal field
if ( mRasterLayer->dataProvider() )
{
QgsDataSourceUri uri { mRasterLayer->dataProvider()->uri() };
if ( mPostgresRasterTemporalGroup->isEnabled() &&
mPostgresRasterTemporalGroup->isChecked() &&
! mPostgresRasterTemporalFieldComboBox->currentField().isEmpty() )
{
const QString originaUri { uri.uri() };
const int fieldIdx { mRasterLayer->dataProvider()->fields().lookupField( mPostgresRasterTemporalFieldComboBox->currentField() ) };
uri.removeParam( QStringLiteral( "temporalFieldIndex" ) );
uri.removeParam( QStringLiteral( "temporalDefaultTime" ) );
if ( fieldIdx >= 0 )
{
uri.setParam( QStringLiteral( "temporalFieldIndex" ), QString::number( fieldIdx ) );
if ( mPostgresRasterDefaultTime->dateTime().isValid() )
{
QDateTime defaultDateTime { mPostgresRasterDefaultTime->dateTime() };
const QTime defaultTime { defaultDateTime.time() };
// Set secs to 0
defaultDateTime.setTime( { defaultTime.hour(), defaultTime.minute(), 0 } );
uri.setParam( QStringLiteral( "temporalDefaultTime" ), defaultDateTime.toString( Qt::DateFormat::ISODate ) );
}
if ( uri.uri( ) != originaUri )
mRasterLayer->setDataSource( uri.uri(), mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
}
}
else if ( uri.hasParam( QStringLiteral( "temporalFieldIndex" ) ) )
{
uri.removeParam( QStringLiteral( "temporalFieldIndex" ) );
uri.removeParam( QStringLiteral( "temporalDefaultTime" ) );
mRasterLayer->setDataSource( uri.uri(), mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
}
}

// Update temporal properties
mTemporalWidget->saveTemporalProperties();

Expand Down
14 changes: 13 additions & 1 deletion src/providers/postgres/CMakeLists.txt
Expand Up @@ -23,7 +23,10 @@ if (WITH_GUI)
qgspgsourceselect.cpp
qgspgnewconnection.cpp
qgspostgresprojectstoragedialog.cpp
raster/qgspostgresrastertemporalsettingswidget.cpp
)

set(PG_UIS raster/qgspostgresrastertemporalsettingswidgetbase.ui)
endif()

set(PG_HDRS
Expand Down Expand Up @@ -52,6 +55,9 @@ if (WITH_GUI)
include_directories(SYSTEM
${QSCINTILLA_INCLUDE_DIR}
)
include_directories (
${CMAKE_BINARY_DIR}/src/providers/postgres/raster
)
endif()

# static library
Expand All @@ -72,7 +78,13 @@ target_link_libraries (postgresprovider_a
)

if (WITH_GUI)
add_library(postgresprovider_gui_a STATIC ${PG_GUI_SRCS})
include_directories (
${CMAKE_BINARY_DIR}/src/providers/postgres
)

QT5_WRAP_UI(PG_UIS_H ${PG_UIS})

add_library(postgresprovider_gui_a STATIC ${PG_GUI_SRCS} ${PG_UIS_H})

# require c++17
target_compile_features(postgresprovider_gui_a PRIVATE cxx_std_17)
Expand Down
8 changes: 7 additions & 1 deletion src/providers/postgres/qgspostgresprovidergui.cpp
Expand Up @@ -23,7 +23,7 @@
#include "qgsprojectstorageguiprovider.h"
#include "qgspostgresprojectstoragedialog.h"
#include "qgspostgresdataitemguiprovider.h"

#include "raster/qgspostgresrastertemporalsettingswidget.h"

//! Provider for postgres source select
class QgsPostgresSourceSelectProvider : public QgsSourceSelectProvider //#spellok
Expand Down Expand Up @@ -74,6 +74,7 @@ class QgsPostgresProjectStorageGuiProvider : public QgsProjectStorageGuiProvider
QgsPostgresProviderGuiMetadata::QgsPostgresProviderGuiMetadata():
QgsProviderGuiMetadata( QgsPostgresProvider::POSTGRES_KEY )
{
mRasterTemporalWidgetFactory = std::make_unique< QgsPostgresRasterTemporalSettingsConfigWidgetFactory>();
}

QList<QgsSourceSelectProvider *> QgsPostgresProviderGuiMetadata::sourceSelectProviders()
Expand All @@ -96,6 +97,11 @@ QList<QgsProjectStorageGuiProvider *> QgsPostgresProviderGuiMetadata::projectSto
return providers;
}

QList<const QgsMapLayerConfigWidgetFactory *> QgsPostgresProviderGuiMetadata::mapLayerConfigWidgetFactories()
{
return { mRasterTemporalWidgetFactory.get() };
}

#ifndef HAVE_STATIC_PROVIDERS
QGISEXTERN QgsProviderGuiMetadata *providerGuiMetadataFactory()
{
Expand Down
6 changes: 6 additions & 0 deletions src/providers/postgres/qgspostgresprovidergui.h
Expand Up @@ -29,6 +29,12 @@ class QgsPostgresProviderGuiMetadata: public QgsProviderGuiMetadata
QList<QgsSourceSelectProvider *> sourceSelectProviders() override;
QList<QgsDataItemGuiProvider *> dataItemGuiProviders() override;
QList<QgsProjectStorageGuiProvider *> projectStorageGuiProviders() override;
QList<const QgsMapLayerConfigWidgetFactory *> mapLayerConfigWidgetFactories() override;

private:

std::unique_ptr< QgsMapLayerConfigWidgetFactory > mRasterTemporalWidgetFactory;

};

#endif // QGSPOSTGRESPROVIDERGUI_H
@@ -0,0 +1,138 @@
/***************************************************************************
qgspostgresrastertemporalsettingswidget.cpp
------------------
begin : March 2021
copyright : (C) 2021 by Nyall Dawson
email : nyall dot dawson at gmail 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. *
* *
***************************************************************************/

#include "qgspostgresrastertemporalsettingswidget.h"
#include "qgsmaplayer.h"
#include "qgsproject.h"
#include "qgsrasterlayer.h"
#include "qgsprojecttimesettings.h"
#include "qgsrasterlayertemporalproperties.h"
#include "qgsproviderregistry.h"
#include "qgsprovidermetadata.h"

QgsPostgresRasterTemporalSettingsWidget::QgsPostgresRasterTemporalSettingsWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
: QgsMapLayerConfigWidget( layer, canvas, parent )
, mRasterLayer( qobject_cast< QgsRasterLayer* >( layer ) )
{
Q_ASSERT( mRasterLayer );
Q_ASSERT( mRasterLayer->dataProvider() );
Q_ASSERT( mRasterLayer->providerType() == QLatin1String( "postgresraster" ) );

setupUi( this );

mPostgresRasterTemporalGroup->setEnabled( true );
mPostgresRasterTemporalGroup->setVisible( true );
mPostgresRasterTemporalGroup->setChecked( false );

mPostgresRasterTemporalFieldComboBox->setFilters( QgsFieldProxyModel::Filter::Date |
QgsFieldProxyModel::Filter::DateTime |
QgsFieldProxyModel::Filter::String );
mPostgresRasterTemporalFieldComboBox->setAllowEmptyFieldName( true );
connect( mPostgresRasterTemporalFieldComboBox, &QgsFieldComboBox::fieldChanged, this, [ = ]( const QString & fieldName )
{
mPostgresRasterDefaultTime->setEnabled( ! fieldName.isEmpty() );
} );
mPostgresRasterDefaultTime->setAllowNull( true );
mPostgresRasterDefaultTime->setEmpty();

syncToLayer( mRasterLayer );
}

void QgsPostgresRasterTemporalSettingsWidget::syncToLayer( QgsMapLayer *layer )
{
mRasterLayer = qobject_cast< QgsRasterLayer * >( layer );
const QgsFields fields { mRasterLayer->dataProvider()->fields() };
mPostgresRasterTemporalFieldComboBox->setFields( fields );

if ( mRasterLayer->dataProvider()->uri().hasParam( QStringLiteral( "temporalFieldIndex" ) ) )
{
bool ok;
const int fieldIdx { mRasterLayer->dataProvider()->uri().param( QStringLiteral( "temporalFieldIndex" ) ).toInt( &ok ) };
if ( ok && fields.exists( fieldIdx ) )
{
mPostgresRasterTemporalGroup->setChecked( true );
mPostgresRasterTemporalFieldComboBox->setField( fields.field( fieldIdx ).name() );
if ( mRasterLayer->dataProvider()->uri().hasParam( QStringLiteral( "temporalDefaultTime" ) ) )
{
const QDateTime defaultDateTime { QDateTime::fromString( mRasterLayer->dataProvider()->uri().param( QStringLiteral( "temporalDefaultTime" ) ), Qt::DateFormat::ISODate ) };
if ( defaultDateTime.isValid() )
{
mPostgresRasterDefaultTime->setDateTime( defaultDateTime );
}
}
}
}
}

void QgsPostgresRasterTemporalSettingsWidget::apply()
{
QgsDataSourceUri uri { mRasterLayer->dataProvider()->uri() };
if ( mPostgresRasterTemporalGroup->isEnabled() &&
mPostgresRasterTemporalGroup->isChecked() &&
! mPostgresRasterTemporalFieldComboBox->currentField().isEmpty() )
{
const QString originaUri { uri.uri() };
const int fieldIdx { mRasterLayer->dataProvider()->fields().lookupField( mPostgresRasterTemporalFieldComboBox->currentField() ) };
uri.removeParam( QStringLiteral( "temporalFieldIndex" ) );
uri.removeParam( QStringLiteral( "temporalDefaultTime" ) );
if ( fieldIdx >= 0 )
{
uri.setParam( QStringLiteral( "temporalFieldIndex" ), QString::number( fieldIdx ) );
if ( mPostgresRasterDefaultTime->dateTime().isValid() )
{
QDateTime defaultDateTime { mPostgresRasterDefaultTime->dateTime() };
const QTime defaultTime { defaultDateTime.time() };
// Set secs to 0
defaultDateTime.setTime( { defaultTime.hour(), defaultTime.minute(), 0 } );
uri.setParam( QStringLiteral( "temporalDefaultTime" ), defaultDateTime.toString( Qt::DateFormat::ISODate ) );
}
if ( uri.uri( ) != originaUri )
mRasterLayer->setDataSource( uri.uri(), mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
}
}
else if ( uri.hasParam( QStringLiteral( "temporalFieldIndex" ) ) )
{
uri.removeParam( QStringLiteral( "temporalFieldIndex" ) );
uri.removeParam( QStringLiteral( "temporalDefaultTime" ) );
mRasterLayer->setDataSource( uri.uri(), mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
}
}


//
// QgsPostgresRasterTemporalSettingsConfigWidgetFactory
//

bool QgsPostgresRasterTemporalSettingsConfigWidgetFactory::supportLayerPropertiesDialog() const
{
return true;
}

bool QgsPostgresRasterTemporalSettingsConfigWidgetFactory::supportsLayer( QgsMapLayer *layer ) const
{
return layer && layer->isValid() && layer->providerType() == QLatin1String( "postgresraster" );
}

QgsMapLayerConfigWidgetFactory::ParentPage QgsPostgresRasterTemporalSettingsConfigWidgetFactory::parentPage() const
{
return ParentPage::Temporal;
}

QgsMapLayerConfigWidget *QgsPostgresRasterTemporalSettingsConfigWidgetFactory::createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool, QWidget *parent ) const
{
return new QgsPostgresRasterTemporalSettingsWidget( layer, canvas, parent );
}
@@ -0,0 +1,54 @@
/***************************************************************************
qgspostgresrastertemporalsettingswidget.h
------------------
begin : March 2021
copyright : (C) 2021 by Nyall Dawson
email : nyall dot dawson at gmail 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. *
* *
***************************************************************************/

#ifndef QGSPOSTGRESRASTERTEMPORALSETTINGSWIDGET_H
#define QGSPOSTGRESRASTERTEMPORALSETTINGSWIDGET_H

#include "ui_qgspostgresrastertemporalsettingswidgetbase.h"
#include "qgsmaplayerconfigwidget.h"
#include "qgsmaplayerconfigwidgetfactory.h"

class QgsRasterLayer;

class QgsPostgresRasterTemporalSettingsWidget : public QgsMapLayerConfigWidget, private Ui::QgsPostgresRasterTemporalSettingsWidgetBase
{
Q_OBJECT

public:
QgsPostgresRasterTemporalSettingsWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );

void syncToLayer( QgsMapLayer *layer ) override;
void apply() override;
private slots:

private:

QgsRasterLayer *mRasterLayer = nullptr;

};

class QgsPostgresRasterTemporalSettingsConfigWidgetFactory : public QgsMapLayerConfigWidgetFactory
{
public:
bool supportLayerPropertiesDialog() const override;
bool supportsLayer( QgsMapLayer *layer ) const override;
ParentPage parentPage() const override;
QgsMapLayerConfigWidget *createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget = true, QWidget *parent = nullptr ) const override;

};

#endif // QGSPOSTGRESRASTERTEMPORALSETTINGSWIDGET_H

0 comments on commit 3a30e62

Please sign in to comment.