Skip to content
Permalink
Browse files

QGIS Project temporal settings

Adds the ability to set a temporal range for a project
  • Loading branch information
Samweli committed Mar 6, 2020
1 parent 36e773f commit 0facf5450d58fe42ab6d422dcd4b637b0be68a6b
@@ -815,6 +815,7 @@
<file>themes/default/mIconHtml.svg</file>
<file>themes/default/mIconHamburgerMenu.svg</file>
<file>themes/default/mActionAddManualTable.svg</file>
<file>themes/default/propertyicons/temporal.svg</file>
<file>themes/default/mIconModelerCollapse.svg</file>
<file>themes/default/mIconModelerExpand.svg</file>
<file>themes/default/mActionDeleteModelComponent.svg</file>
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
version="1.1"
viewBox="0 0 8.4667 8.4667"
id="svg39"
sodipodi:docname="temporal.svg"
inkscape:version="0.92.4 (unknown)">
<defs
id="defs43" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1299"
inkscape:window-height="713"
id="namedview41"
showgrid="false"
inkscape:zoom="1.6010084"
inkscape:cx="46.187762"
inkscape:cy="-25.179072"
inkscape:window-x="67"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g37"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="false"
inkscape:snap-bbox="false" />
<metadata
id="metadata29">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0 -288.53)"
stroke="#000"
id="g37">
<ellipse
cx="4.2354093"
cy="292.87"
rx="3.7774999"
ry="3.6596999"
id="ellipse31"
style="fill:#ffffff;stroke-width:0.48207274;stroke-miterlimit:4;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
style="fill:#888a85;stroke:#000000;stroke-width:0.41460372;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.0893299,292.96408 v -2.33574 m 1.3699151,3.27284 -1.3682693,-0.93364"
id="path4" />
</g>
</svg>
@@ -601,6 +601,15 @@ relating to how a QgsProject should be viewed and behave inside a map canvas
%End


QgsProjectTimeSettings *timeSettings();
%Docstring
Returns the project's time settings, contains temporal range, which can
be used in constraining temporal properties from temporal layers in the project.

.. versionadded:: 3.14
%End


QgsProjectDisplaySettings *displaySettings();
%Docstring
Returns the project's display settings, which settings and properties relating
@@ -0,0 +1,84 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsprojecttimesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsProjectTimeSettings : QObject
{
%Docstring
Contains temporal settings and properties for the project,
this will be used in animating/showing temporal layers.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsprojecttimesettings.h"
%End
public:

QgsProjectTimeSettings( QObject *parent = 0 );
%Docstring
Constructor for QgsProjectTimeSettings with the specified ``parent`` object.
%End

void reset();
%Docstring
Resets the settings to a default state.
%End

QgsDateTimeRange temporalRange() const;
%Docstring
Returns the project temporal range.

.. seealso:: :py:func:`setTemporalRange`
%End

void setTemporalRange( const QgsDateTimeRange &extent );
%Docstring
Sets the project temporal range

.. seealso:: :py:func:`temporalRange`
%End

bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
%Docstring
Reads the settings's state from a DOM element.

.. seealso:: :py:func:`writeXml`
%End

QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
%Docstring
Returns a DOM element representing the settings.

.. seealso:: :py:func:`readXml`
%End


signals:

void temporalRangeChanged();
%Docstring
Emitted when temporal range changes.

.. seealso:: :py:func:`temporalRange`

.. seealso:: :py:func:`setTemporalRange`
%End
};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsprojecttimesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -152,6 +152,7 @@
%Include auto_generated/qgsprojectproperty.sip
%Include auto_generated/qgsprojectstorage.sip
%Include auto_generated/qgsprojectstorageregistry.sip
%Include auto_generated/qgsprojecttimesettings.sip
%Include auto_generated/qgsprojecttranslator.sip
%Include auto_generated/qgsprojectversion.sip
%Include auto_generated/qgsprojectviewsettings.sip
@@ -11373,6 +11373,7 @@ QMap< QString, QString > QgisApp::projectPropertiesPagesMap()
sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Variables" ), QStringLiteral( "mTab_Variables" ) );
sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Macros" ), QStringLiteral( "mProjOptsMacros" ) );
sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "QGIS Server" ), QStringLiteral( "mProjOptsOWS" ) );
sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Temporal" ), QStringLiteral( "mTemporalOptions" ) );
} );

return sProjectPropertiesPagesMap;
@@ -69,6 +69,7 @@
#include "qgsnumericformatwidget.h"
#include "qgsbearingnumericformat.h"
#include "qgsprojectdisplaysettings.h"
#include "qgsprojecttimesettings.h"

//qt includes
#include <QInputDialog>
@@ -77,6 +78,8 @@
#include <QMessageBox>
#include <QDesktopServices>
#include <QAbstractListModel>
#include <QList>
#include <QtCore>

const char *QgsProjectProperties::GEO_NONE_DESC = QT_TRANSLATE_NOOP( "QgsOptions", "None / Planimetric" );

@@ -119,6 +122,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
connect( mButtonAddColor, &QToolButton::clicked, this, &QgsProjectProperties::mButtonAddColor_clicked );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsProjectProperties::showHelp );
connect( mCustomizeBearingFormatButton, &QPushButton::clicked, this, &QgsProjectProperties::customizeBearingFormat );
connect( mCalculateFromLayerButton, &QPushButton::clicked, this, &QgsProjectProperties::calculateFromLayersButton_clicked );

// QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
// switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
@@ -229,6 +233,18 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
}
}

// Set time settings input
QgsDateTimeRange range = QgsProject::instance()->timeSettings()->temporalRange();
if ( range.begin().isValid() && range.end().isValid() )
{
mStartDateTimeEdit->setDateTime( range.begin() );
mEndDateTimeEdit->setDateTime( range.end() );
}

mCurrentRangeLabel->setText( tr( "Current range: %1 to %2" ).arg(
mStartDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ),
mEndDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ) ) );

mAutoTransaction->setChecked( QgsProject::instance()->autoTransaction() );
title( QgsProject::instance()->title() );
mProjectFileLineEdit->setText( QDir::toNativeSeparators( QgsProject::instance()->fileName() ) );
@@ -1017,6 +1033,12 @@ void QgsProjectProperties::apply()
QgsProject::instance()->setEvaluateDefaultValues( mEvaluateDefaultValues->isChecked() );
QgsProject::instance()->setTrustLayerMetadata( mTrustProjectCheckBox->isChecked() );

// Time settings
QDateTime start = mStartDateTimeEdit->dateTime();
QDateTime end = mEndDateTimeEdit->dateTime();

QgsProject::instance()->timeSettings()->setTemporalRange( QgsDateTimeRange( start, end ) );

// set the mouse display precision method and the
// number of decimal places for the manual option
// Note. Qt 3.2.3 and greater have a function selectedId() that
@@ -2475,6 +2497,45 @@ void QgsProjectProperties::mButtonAddColor_clicked()
mTreeProjectColors->addColor( newColor, QgsSymbolLayerUtils::colorToName( newColor ) );
}

void QgsProjectProperties::calculateFromLayersButton_clicked()
{
const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers();
QgsMapLayer *currentLayer = nullptr;

QDateTime minDate;
QDateTime maxDate;

for ( QMap<QString, QgsMapLayer *>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); ++it )
{
currentLayer = it.value();

if ( !currentLayer->temporalProperties() || !currentLayer->temporalProperties()->isActive() )
continue;

if ( currentLayer->type() == QgsMapLayerType::RasterLayer )
{
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( currentLayer );

QgsDateTimeRange layerRange = rasterLayer->temporalProperties()->temporalRange();

if ( !minDate.isValid() || layerRange.begin() < minDate )
minDate = layerRange.begin();
if ( !maxDate.isValid() || layerRange.end() > maxDate )
maxDate = layerRange.end();
}
}

if ( !minDate.isValid() || !maxDate.isValid() )
return;

mStartDateTimeEdit->setDateTime( minDate );
mEndDateTimeEdit->setDateTime( maxDate );

mCurrentRangeLabel->setText( tr( "Current range: %1 to %2" ).arg(
mStartDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ),
mEndDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ) ) );
}

QListWidgetItem *QgsProjectProperties::addScaleToScaleList( const QString &newScale )
{
// TODO QGIS3: Rework the scale list widget to be a reusable piece of code, see PR #2558
@@ -184,6 +184,18 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:

void customizeBearingFormat();

/**
* Sets the start and end dates input values from the project
* temporal layers.
*
* Looks for the smallest date and the greatest date from the
* project layers and set them for start and end dates
* input respectively.
*
* \since QGIS 3.14
*/
void calculateFromLayersButton_clicked();

private:

/**
@@ -341,6 +341,7 @@ SET(QGIS_CORE_SRCS
qgsprojectproperty.cpp
qgsprojectstorage.cpp
qgsprojectstorageregistry.cpp
qgsprojecttimesettings.cpp
qgsprojectversion.cpp
qgsprojectviewsettings.cpp
qgsprojutils.cpp
@@ -853,6 +854,7 @@ SET(QGIS_CORE_HDRS
qgsprojectproperty.h
qgsprojectstorage.h
qgsprojectstorageregistry.h
qgsprojecttimesettings.h
qgsprojecttranslator.h
qgsprojectversion.h
qgsprojectviewsettings.h
@@ -59,6 +59,7 @@
#include "qgsstyleentityvisitor.h"
#include "qgsprojectviewsettings.h"
#include "qgsprojectdisplaysettings.h"
#include "qgsprojecttimesettings.h"

#include <algorithm>
#include <QApplication>
@@ -364,6 +365,7 @@ QgsProject::QgsProject( QObject *parent )
, mLayoutManager( new QgsLayoutManager( this ) )
, mBookmarkManager( QgsBookmarkManager::createProjectBasedManager( this ) )
, mViewSettings( new QgsProjectViewSettings( this ) )
, mTimeSettings( new QgsProjectTimeSettings( this ) )
, mDisplaySettings( new QgsProjectDisplaySettings( this ) )
, mRootGroup( new QgsLayerTree )
, mLabelingEngineSettings( new QgsLabelingEngineSettings )
@@ -762,6 +764,7 @@ void QgsProject::clear()
mLayoutManager->clear();
mBookmarkManager->clear();
mViewSettings->reset();
mTimeSettings->reset();
mDisplaySettings->reset();
mSnappingConfig.reset();
emit snappingConfigChanged( mSnappingConfig );
@@ -1539,6 +1542,11 @@ bool QgsProject::readProjectFile( const QString &filename, QgsProject::ReadFlags
if ( !viewSettingsElement.isNull() )
mViewSettings->readXml( viewSettingsElement, context );

// restore time settings
QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral( "ProjectTimeSettings" ) );
if ( !timeSettingsElement.isNull() )
mTimeSettings->readXml( timeSettingsElement, context );

QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral( "ProjectDisplaySettings" ) );
if ( !displaySettingsElement.isNull() )
mDisplaySettings->readXml( displaySettingsElement, context );
@@ -2166,6 +2174,9 @@ bool QgsProject::writeProjectFile( const QString &filename )
QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
qgisNode.appendChild( viewSettingsElem );

QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
qgisNode.appendChild( timeSettingsElement );

QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
qgisNode.appendChild( displaySettingsElem );

@@ -2873,6 +2884,16 @@ QgsProjectViewSettings *QgsProject::viewSettings()
return mViewSettings;
}

const QgsProjectTimeSettings *QgsProject::timeSettings() const
{
return mTimeSettings;
}

QgsProjectTimeSettings *QgsProject::timeSettings()
{
return mTimeSettings;
}

const QgsProjectDisplaySettings *QgsProject::displaySettings() const
{
return mDisplaySettings;

0 comments on commit 0facf54

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