Skip to content

Commit

Permalink
Add explicit settings for ellipsoid, distance and area units to QgsPr…
Browse files Browse the repository at this point in the history
…ocessingContext

to avoid having to always retrieve these via the context's project (which may
not be available in some circumstances)

Refs #37988
  • Loading branch information
nyalldawson committed Jul 29, 2020
1 parent 0f7a946 commit 03854a4
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 4 deletions.
72 changes: 70 additions & 2 deletions python/core/auto_generated/processing/qgsprocessingcontext.sip.in
Expand Up @@ -73,8 +73,8 @@ Returns the project in which the algorithm is being executed.
%Docstring
Sets the ``project`` in which the algorithm will be executed.

This also automatically sets the :py:func:`~QgsProcessingContext.transformContext` to match
the project's transform context.
This also automatically sets the :py:func:`~QgsProcessingContext.transformContext`, :py:func:`~QgsProcessingContext.ellipsoid`, :py:func:`~QgsProcessingContext.distanceUnit` and
:py:func:`~QgsProcessingContext.areaUnit` to match the project's settings.

.. seealso:: :py:func:`project`
%End
Expand Down Expand Up @@ -105,6 +105,74 @@ Note that setting a project for the context will automatically set the coordinat
context.

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

QString ellipsoid() const;
%Docstring
Returns the ellipsoid to use for distance and area calculations.

.. seealso:: :py:func:`setEllipsoid`

.. versionadded:: 3.16
%End

void setEllipsoid( const QString &ellipsoid );
%Docstring
Sets a specified ``ellipsoid`` to use for distance and area calculations.

If not explicitly set, the ellipsoid will default to the :py:func:`~QgsProcessingContext.project`'s ellipsoid setting.

.. seealso:: :py:func:`ellipsoid`

.. versionadded:: 3.16
%End

QgsUnitTypes::DistanceUnit distanceUnit() const;
%Docstring
Returns the distance unit to use for distance calculations.

.. seealso:: :py:func:`setDistanceUnit`

.. seealso:: :py:func:`areaUnit`

.. versionadded:: 3.16
%End

void setDistanceUnit( QgsUnitTypes::DistanceUnit unit );
%Docstring
Sets the ``unit`` to use for distance calculations.

If not explicitly set, the unit will default to the :py:func:`~QgsProcessingContext.project`'s distance unit setting.

.. seealso:: :py:func:`distanceUnit`

.. seealso:: :py:func:`setAreaUnit`

.. versionadded:: 3.16
%End

QgsUnitTypes::AreaUnit areaUnit() const;
%Docstring
Returns the area unit to use for area calculations.

.. seealso:: :py:func:`setAreaUnit`

.. seealso:: :py:func:`distanceUnit`

.. versionadded:: 3.16
%End

void setAreaUnit( QgsUnitTypes::AreaUnit areaUnit );
%Docstring
Sets the ``unit`` to use for area calculations.

If not explicitly set, the unit will default to the :py:func:`~QgsProcessingContext.project`'s area unit setting.

.. seealso:: :py:func:`areaUnit`

.. seealso:: :py:func:`setDistanceUnit`

.. versionadded:: 3.16
%End

QgsMapLayerStore *temporaryLayerStore();
Expand Down
28 changes: 28 additions & 0 deletions src/core/processing/qgsprocessingcontext.cpp
Expand Up @@ -110,7 +110,35 @@ QgsMapLayer *QgsProcessingContext::takeResultLayer( const QString &id )
return tempLayerStore.takeMapLayer( tempLayerStore.mapLayer( id ) );
}

QString QgsProcessingContext::ellipsoid() const
{
return mEllipsoid;
}

void QgsProcessingContext::setEllipsoid( const QString &ellipsoid )
{
mEllipsoid = ellipsoid;
}

QgsUnitTypes::DistanceUnit QgsProcessingContext::distanceUnit() const
{
return mDistanceUnit;
}

void QgsProcessingContext::setDistanceUnit( QgsUnitTypes::DistanceUnit unit )
{
mDistanceUnit = unit;
}

QgsUnitTypes::AreaUnit QgsProcessingContext::areaUnit() const
{
return mAreaUnit;
}

void QgsProcessingContext::setAreaUnit( QgsUnitTypes::AreaUnit areaUnit )
{
mAreaUnit = areaUnit;
}

QgsProcessingLayerPostProcessorInterface *QgsProcessingContext::LayerDetails::postProcessor() const
{
Expand Down
80 changes: 78 additions & 2 deletions src/core/processing/qgsprocessingcontext.h
Expand Up @@ -78,6 +78,11 @@ class CORE_EXPORT QgsProcessingContext
mTransformErrorCallback = other.mTransformErrorCallback;
mDefaultEncoding = other.mDefaultEncoding;
mFeedback = other.mFeedback;
mPreferredVectorFormat = other.mPreferredVectorFormat;
mPreferredRasterFormat = other.mPreferredRasterFormat;
mEllipsoid = other.mEllipsoid;
mDistanceUnit = other.mDistanceUnit;
mAreaUnit = other.mAreaUnit;
}

/**
Expand All @@ -101,16 +106,24 @@ class CORE_EXPORT QgsProcessingContext
/**
* Sets the \a project in which the algorithm will be executed.
*
* This also automatically sets the transformContext() to match
* the project's transform context.
* This also automatically sets the transformContext(), ellipsoid(), distanceUnit() and
* areaUnit() to match the project's settings.
*
* \see project()
*/
void setProject( QgsProject *project )
{
mProject = project;
if ( mProject )
{
mTransformContext = mProject->transformContext();
if ( mEllipsoid.isEmpty() )
mEllipsoid = mProject->ellipsoid();
if ( mDistanceUnit == QgsUnitTypes::DistanceUnknownUnit )
mDistanceUnit = mProject->distanceUnits();
if ( mAreaUnit == QgsUnitTypes::AreaUnknownUnit )
mAreaUnit = mProject->areaUnits();
}
}

/**
Expand Down Expand Up @@ -144,6 +157,64 @@ class CORE_EXPORT QgsProcessingContext
*/
void setTransformContext( const QgsCoordinateTransformContext &context ) { mTransformContext = context; }

/**
* Returns the ellipsoid to use for distance and area calculations.
*
* \see setEllipsoid()
* \since QGIS 3.16
*/
QString ellipsoid() const;

/**
* Sets a specified \a ellipsoid to use for distance and area calculations.
*
* If not explicitly set, the ellipsoid will default to the project()'s ellipsoid setting.
*
* \see ellipsoid()
* \since QGIS 3.16
*/
void setEllipsoid( const QString &ellipsoid );

/**
* Returns the distance unit to use for distance calculations.
*
* \see setDistanceUnit()
* \see areaUnit()
* \since QGIS 3.16
*/
QgsUnitTypes::DistanceUnit distanceUnit() const;

/**
* Sets the \a unit to use for distance calculations.
*
* If not explicitly set, the unit will default to the project()'s distance unit setting.
*
* \see distanceUnit()
* \see setAreaUnit()
* \since QGIS 3.16
*/
void setDistanceUnit( QgsUnitTypes::DistanceUnit unit );

/**
* Returns the area unit to use for area calculations.
*
* \see setAreaUnit()
* \see distanceUnit()
* \since QGIS 3.16
*/
QgsUnitTypes::AreaUnit areaUnit() const;

/**
* Sets the \a unit to use for area calculations.
*
* If not explicitly set, the unit will default to the project()'s area unit setting.
*
* \see areaUnit()
* \see setDistanceUnit()
* \since QGIS 3.16
*/
void setAreaUnit( QgsUnitTypes::AreaUnit areaUnit );

/**
* Returns a reference to the layer store used for storing temporary layers during
* algorithm execution.
Expand Down Expand Up @@ -535,6 +606,11 @@ class CORE_EXPORT QgsProcessingContext
QgsProcessingContext::Flags mFlags = QgsProcessingContext::Flags();
QPointer< QgsProject > mProject;
QgsCoordinateTransformContext mTransformContext;

QString mEllipsoid;
QgsUnitTypes::DistanceUnit mDistanceUnit = QgsUnitTypes::DistanceUnknownUnit;
QgsUnitTypes::AreaUnit mAreaUnit = QgsUnitTypes::AreaUnknownUnit;

//! Temporary project owned by the context, used for storing temporarily loaded map layers
QgsMapLayerStore tempLayerStore;
QgsExpressionContext mExpressionContext;
Expand Down
19 changes: 19 additions & 0 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -956,9 +956,28 @@ void TestQgsProcessing::context()
context.setFlags( QgsProcessingContext::Flags( nullptr ) );
QCOMPARE( context.flags(), QgsProcessingContext::Flags( nullptr ) );

QCOMPARE( context.ellipsoid(), QString() );
QCOMPARE( context.distanceUnit(), QgsUnitTypes::DistanceUnknownUnit );
QCOMPARE( context.areaUnit(), QgsUnitTypes::AreaUnknownUnit );

QgsProject p;
p.setEllipsoid( QStringLiteral( "WGS84" ) );
p.setDistanceUnits( QgsUnitTypes::DistanceFeet );
p.setAreaUnits( QgsUnitTypes::AreaHectares );
context.setProject( &p );
QCOMPARE( context.project(), &p );
QCOMPARE( context.ellipsoid(), QStringLiteral( "WGS84" ) );
QCOMPARE( context.distanceUnit(), QgsUnitTypes::DistanceFeet );
QCOMPARE( context.areaUnit(), QgsUnitTypes::AreaHectares );

// if context ellipsoid/units are already set then setting the project shouldn't overwrite them
p.setEllipsoid( QStringLiteral( "WGS84v2" ) );
p.setDistanceUnits( QgsUnitTypes::DistanceMiles );
p.setAreaUnits( QgsUnitTypes::AreaAcres );
context.setProject( &p );
QCOMPARE( context.ellipsoid(), QStringLiteral( "WGS84" ) );
QCOMPARE( context.distanceUnit(), QgsUnitTypes::DistanceFeet );
QCOMPARE( context.areaUnit(), QgsUnitTypes::AreaHectares );

context.setInvalidGeometryCheck( QgsFeatureRequest::GeometrySkipInvalid );
QCOMPARE( context.invalidGeometryCheck(), QgsFeatureRequest::GeometrySkipInvalid );
Expand Down

0 comments on commit 03854a4

Please sign in to comment.