diff --git a/python/core/auto_generated/elevation/qgsabstractprofilegenerator.sip.in b/python/core/auto_generated/elevation/qgsabstractprofilegenerator.sip.in new file mode 100644 index 00000000000..4eb182e1473 --- /dev/null +++ b/python/core/auto_generated/elevation/qgsabstractprofilegenerator.sip.in @@ -0,0 +1,80 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/elevation/qgsabstractprofilegenerator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsAbstractProfileGenerator +{ +%Docstring(signature="appended") +Abstract base class for objects which generate elevation profiles. + +The generation is typically done in a background +thread, so it is necessary to keep all structures required for generating the +profile away from the original profile source because it may change at any time. + +Because the data needs to be copied (to avoid the need for locking), +it is highly desirable to use copy-on-write where possible. This way, +the overhead of copying (both memory and CPU) will be kept low. +Qt containers and various Qt classes use implicit sharing. + +The scenario will be: + +# elevation profile job (doing preparation in the GUI thread) calls + :py:func:`QgsAbstractProfileSource.createProfileGenerator()` and gets an instance of this class. + The instance is initialized at that point and should not need + additional calls to the source. +# profile job (still in GUI thread) stores the generator for later use. +# profile job (in worker thread) calls :py:func:`QgsAbstractProfileGenerator.generateProfile()` +# profile job (again in GUI thread) will check :py:func:`~errors` and report them + +.. versionadded:: 3.26 +%End + +%TypeHeaderCode +#include "qgsabstractprofilegenerator.h" +%End + public: + + virtual ~QgsAbstractProfileGenerator(); + + virtual bool generateProfile() = 0; +%Docstring +Generate the profile (based on data stored in the class). + +Returns ``True`` if the profile was generated successfully (i.e. the generation +was not canceled early). +%End + + struct Result + { + double distance; + double height; + }; + + QList< QgsAbstractProfileGenerator::Result > results() const; +%Docstring +Temporary method to return results. +%End + + QList< QgsPoint > rawPoints() const; +%Docstring +Temporary method to return results. +%End + + protected: + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/elevation/qgsabstractprofilegenerator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/elevation/qgsabstractprofilesource.sip.in b/python/core/auto_generated/elevation/qgsabstractprofilesource.sip.in new file mode 100644 index 00000000000..099570ddc58 --- /dev/null +++ b/python/core/auto_generated/elevation/qgsabstractprofilesource.sip.in @@ -0,0 +1,46 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/elevation/qgsabstractprofilesource.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + +class QgsAbstractProfileSource +{ +%Docstring(signature="appended") +Interface for classes which can generate elevation profiles. + +.. versionadded:: 3.26 +%End + +%TypeHeaderCode +#include "qgsabstractprofilesource.h" +%End + public: + + virtual ~QgsAbstractProfileSource(); + + virtual QgsAbstractProfileGenerator *createProfileGenerator( const QgsProfileRequest &request ) = 0 /Factory/; +%Docstring +Given a profile ``request``, returns a new profile generator ready for generating +elevation profiles. + +The caller takes ownership of the returned generator. + +May return ``None`` if the source cannot generate a profile at this time. +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/elevation/qgsabstractprofilesource.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/elevation/qgsprofilerequest.sip.in b/python/core/auto_generated/elevation/qgsprofilerequest.sip.in index 0153eee749f..666a6a7c658 100644 --- a/python/core/auto_generated/elevation/qgsprofilerequest.sip.in +++ b/python/core/auto_generated/elevation/qgsprofilerequest.sip.in @@ -53,7 +53,7 @@ The coordinate reference system of the ``curve`` is set via :py:func:`~QgsProfil .. seealso:: :py:func:`profileCurve` %End - QgsCurve *profileCurve(); + QgsCurve *profileCurve() const; %Docstring Returns the cross section profile curve, which represents the line along which the profile should be generated. @@ -129,7 +129,7 @@ Ownership of ``provider`` is transferred to the request. .. seealso:: :py:func:`terrainProvider` %End - QgsAbstractTerrainProvider *terrainProvider(); + QgsAbstractTerrainProvider *terrainProvider() const; %Docstring Returns the terrain provider. diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index a678a76aa9e..1c2768e89f7 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -268,6 +268,8 @@ %Include auto_generated/editform/qgsattributeeditorrelation.sip %Include auto_generated/editform/qgsattributeeditorhtmlelement.sip %Include auto_generated/editform/qgsattributeeditorqmlelement.sip +%Include auto_generated/elevation/qgsabstractprofilegenerator.sip +%Include auto_generated/elevation/qgsabstractprofilesource.sip %Include auto_generated/elevation/qgsprofilerequest.sip %Include auto_generated/elevation/qgsterrainprovider.sip %Include auto_generated/externalstorage/qgsexternalstorage.sip diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ed7a533404a..459eba5361d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -44,6 +44,8 @@ set(QGIS_CORE_SRCS classification/qgsclassificationstandarddeviation.cpp classification/qgsclassificationlogarithmic.cpp + elevation/qgsabstractprofilegenerator.cpp + elevation/qgsabstractprofilesource.cpp elevation/qgsprofilerequest.cpp elevation/qgsterrainprovider.cpp @@ -1261,6 +1263,8 @@ set(QGIS_CORE_HDRS editform/qgsattributeeditorhtmlelement.h editform/qgsattributeeditorqmlelement.h + elevation/qgsabstractprofilegenerator.h + elevation/qgsabstractprofilesource.h elevation/qgsprofilerequest.h elevation/qgsterrainprovider.h diff --git a/src/core/elevation/qgsabstractprofilegenerator.cpp b/src/core/elevation/qgsabstractprofilegenerator.cpp new file mode 100644 index 00000000000..d7bd8e4b866 --- /dev/null +++ b/src/core/elevation/qgsabstractprofilegenerator.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + qgsabstractprofilegenerator.cpp + --------------- + begin : March 2022 + copyright : (C) 2022 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 "qgsabstractprofilegenerator.h" + +QgsAbstractProfileGenerator::~QgsAbstractProfileGenerator() = default; diff --git a/src/core/elevation/qgsabstractprofilegenerator.h b/src/core/elevation/qgsabstractprofilegenerator.h new file mode 100644 index 00000000000..b4034e67510 --- /dev/null +++ b/src/core/elevation/qgsabstractprofilegenerator.h @@ -0,0 +1,89 @@ +/*************************************************************************** + qgsabstractprofilegenerator.h + --------------- + begin : March 2022 + copyright : (C) 2022 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 QGSABSTRACTPROFILEGENERATOR_H +#define QGSABSTRACTPROFILEGENERATOR_H + +#include "qgis_core.h" +#include "qgis_sip.h" +#include + +#include "qgspoint.h" + +/** + * \brief Abstract base class for objects which generate elevation profiles. + * + * The generation is typically done in a background + * thread, so it is necessary to keep all structures required for generating the + * profile away from the original profile source because it may change at any time. + * + * Because the data needs to be copied (to avoid the need for locking), + * it is highly desirable to use copy-on-write where possible. This way, + * the overhead of copying (both memory and CPU) will be kept low. + * Qt containers and various Qt classes use implicit sharing. + * + * The scenario will be: + * + * # elevation profile job (doing preparation in the GUI thread) calls + * QgsAbstractProfileSource::createProfileGenerator() and gets an instance of this class. + * The instance is initialized at that point and should not need + * additional calls to the source. + * # profile job (still in GUI thread) stores the generator for later use. + * # profile job (in worker thread) calls QgsAbstractProfileGenerator::generateProfile() + * # profile job (again in GUI thread) will check errors() and report them + * + * \ingroup core + * \since QGIS 3.26 + */ +class CORE_EXPORT QgsAbstractProfileGenerator +{ + + public: + + virtual ~QgsAbstractProfileGenerator(); + + /** + * Generate the profile (based on data stored in the class). + * + * Returns TRUE if the profile was generated successfully (i.e. the generation + * was not canceled early). + */ + virtual bool generateProfile() = 0; + + // Temporary class only! + struct CORE_EXPORT Result + { + double distance; + double height; + }; + + /** + * Temporary method to return results. + */ + QList< QgsAbstractProfileGenerator::Result > results() const { return mResults; } + + /** + * Temporary method to return results. + */ + QList< QgsPoint > rawPoints() const { return mRawPoints; } + + protected: + QList< QgsPoint > mRawPoints; + QList< Result > mResults; + +}; + +#endif // QGSABSTRACTPROFILEGENERATOR_H diff --git a/src/core/elevation/qgsabstractprofilesource.cpp b/src/core/elevation/qgsabstractprofilesource.cpp new file mode 100644 index 00000000000..b63ef024637 --- /dev/null +++ b/src/core/elevation/qgsabstractprofilesource.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + qgsabstractprofilesource.cpp + --------------- + begin : March 2022 + copyright : (C) 2022 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 "qgsabstractprofilesource.h" + +QgsAbstractProfileSource::~QgsAbstractProfileSource() = default; diff --git a/src/core/elevation/qgsabstractprofilesource.h b/src/core/elevation/qgsabstractprofilesource.h new file mode 100644 index 00000000000..d9b29130f50 --- /dev/null +++ b/src/core/elevation/qgsabstractprofilesource.h @@ -0,0 +1,52 @@ +/*************************************************************************** + qgsabstractprofilesource.h + --------------- + begin : March 2022 + copyright : (C) 2022 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 QGSABSTRACTPROFILESOURCE_H +#define QGSABSTRACTPROFILESOURCE_H + +#include "qgis_core.h" +#include "qgis_sip.h" + +class QgsProfileRequest; +class QgsAbstractProfileGenerator; + + +/** + * \brief Interface for classes which can generate elevation profiles. + * + * \ingroup core + * \since QGIS 3.26 + */ +class CORE_EXPORT QgsAbstractProfileSource +{ + + public: + + virtual ~QgsAbstractProfileSource(); + + /** + * Given a profile \a request, returns a new profile generator ready for generating + * elevation profiles. + * + * The caller takes ownership of the returned generator. + * + * May return NULLPTR if the source cannot generate a profile at this time. + */ + virtual QgsAbstractProfileGenerator *createProfileGenerator( const QgsProfileRequest &request ) = 0 SIP_FACTORY; + +}; + +#endif // QGSABSTRACTPROFILESOURCE_H diff --git a/src/core/elevation/qgsprofilerequest.cpp b/src/core/elevation/qgsprofilerequest.cpp index d8b7dd680cd..d0817856f26 100644 --- a/src/core/elevation/qgsprofilerequest.cpp +++ b/src/core/elevation/qgsprofilerequest.cpp @@ -89,7 +89,7 @@ QgsProfileRequest &QgsProfileRequest::setProfileCurve( QgsCurve *curve ) return *this; } -QgsCurve *QgsProfileRequest::profileCurve() +QgsCurve *QgsProfileRequest::profileCurve() const { return mCurve.get(); } @@ -128,7 +128,7 @@ QgsProfileRequest &QgsProfileRequest::setTerrainProvider( QgsAbstractTerrainProv return *this; } -QgsAbstractTerrainProvider *QgsProfileRequest::terrainProvider() +QgsAbstractTerrainProvider *QgsProfileRequest::terrainProvider() const { return mTerrainProvider.get(); } diff --git a/src/core/elevation/qgsprofilerequest.h b/src/core/elevation/qgsprofilerequest.h index 0cac8dde10f..92cab7d1a8b 100644 --- a/src/core/elevation/qgsprofilerequest.h +++ b/src/core/elevation/qgsprofilerequest.h @@ -78,7 +78,7 @@ class CORE_EXPORT QgsProfileRequest * * \see setProfileCurve() */ - QgsCurve *profileCurve(); + QgsCurve *profileCurve() const; /** * Sets the desired Coordinate Reference System (\a crs) for the profile. @@ -152,7 +152,7 @@ class CORE_EXPORT QgsProfileRequest * * \see setTerrainProvider() */ - QgsAbstractTerrainProvider *terrainProvider(); + QgsAbstractTerrainProvider *terrainProvider() const; private: