mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-07 00:15:48 -04:00
Setup core infrastructure for tiled scene 2d renderers
This commit is contained in:
parent
fb3c25e1a5
commit
c8658efde4
@ -745,6 +745,13 @@ Returns the application's renderer registry, used for managing vector layer rend
|
||||
Returns the application's point cloud renderer registry, used for managing point cloud layer 2D renderers.
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
static QgsTiledSceneRendererRegistry *tiledSceneRendererRegistry() /KeepReference/;
|
||||
%Docstring
|
||||
Returns the application's tiled scene renderer registry, used for managing tiled scene layer 2D renderers.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
static QgsDataItemProviderRegistry *dataItemProviderRegistry() /KeepReference/;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsTiledSceneLayer : QgsMapLayer
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
@ -89,6 +90,23 @@ QgsTiledSceneLayer cannot be copied.
|
||||
virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;
|
||||
|
||||
|
||||
QgsTiledSceneRenderer *renderer();
|
||||
%Docstring
|
||||
Returns the 2D renderer for the tiled scene.
|
||||
|
||||
.. seealso:: :py:func:`setRenderer`
|
||||
%End
|
||||
|
||||
|
||||
void setRenderer( QgsTiledSceneRenderer *renderer /Transfer/ );
|
||||
%Docstring
|
||||
Sets the 2D ``renderer`` for the tiled scene.
|
||||
|
||||
Ownership of ``renderer`` is transferred to the layer.
|
||||
|
||||
.. seealso:: :py:func:`renderer`
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsTiledSceneLayer( const QgsTiledSceneLayer &rhs );
|
||||
};
|
||||
|
@ -0,0 +1,222 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/tiledscene/qgstiledscenerenderer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsTiledSceneRenderContext
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
|
||||
Encapsulates the render context for a 2D tiled scene rendering operation.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstiledscenerenderer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsTiledSceneRenderContext( QgsRenderContext &context, QgsFeedback *feedback = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsTiledSceneRenderContext.
|
||||
%End
|
||||
|
||||
|
||||
|
||||
QgsRenderContext &renderContext();
|
||||
%Docstring
|
||||
Returns a reference to the context's render context.
|
||||
%End
|
||||
|
||||
|
||||
QgsFeedback *feedback() const;
|
||||
%Docstring
|
||||
Returns the feedback object used to cancel rendering
|
||||
|
||||
.. versionadded:: 3.20
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsTiledSceneRenderContext( const QgsTiledSceneRenderContext &rh );
|
||||
};
|
||||
|
||||
class QgsTiledSceneRenderer
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
|
||||
Abstract base class for 2d tiled scene renderers.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstiledscenerenderer.h"
|
||||
%End
|
||||
%ConvertToSubClassCode
|
||||
|
||||
const QString type = sipCpp->type();
|
||||
|
||||
sipType = 0;
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsTiledSceneRenderer();
|
||||
%Docstring
|
||||
Constructor for QgsTiledSceneRenderer.
|
||||
%End
|
||||
|
||||
virtual ~QgsTiledSceneRenderer();
|
||||
|
||||
virtual QString type() const = 0;
|
||||
%Docstring
|
||||
Returns the identifier of the renderer type.
|
||||
%End
|
||||
|
||||
virtual QgsTiledSceneRenderer *clone() const = 0 /Factory/;
|
||||
%Docstring
|
||||
Create a deep copy of this renderer. Should be implemented by all subclasses
|
||||
and generate a proper subclass.
|
||||
%End
|
||||
|
||||
|
||||
|
||||
static QgsTiledSceneRenderer *load( QDomElement &element, const QgsReadWriteContext &context ) /Factory/;
|
||||
%Docstring
|
||||
Creates a renderer from an XML ``element``.
|
||||
|
||||
Caller takes ownership of the returned renderer.
|
||||
|
||||
.. seealso:: :py:func:`save`
|
||||
%End
|
||||
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const = 0;
|
||||
%Docstring
|
||||
Saves the renderer configuration to an XML element.
|
||||
|
||||
.. seealso:: :py:func:`load`
|
||||
%End
|
||||
|
||||
double maximumScreenError() const;
|
||||
%Docstring
|
||||
Returns the maximum screen error allowed when rendering the tiled scene.
|
||||
|
||||
Larger values result in a faster render with less detailed features rendered.
|
||||
|
||||
Units are retrieved via :py:func:`~QgsTiledSceneRenderer.maximumScreenErrorUnit`.
|
||||
|
||||
.. seealso:: :py:func:`setMaximumScreenError`
|
||||
|
||||
.. seealso:: :py:func:`maximumScreenErrorUnit`
|
||||
%End
|
||||
|
||||
void setMaximumScreenError( double error );
|
||||
%Docstring
|
||||
Sets the maximum screen ``error`` allowed when rendering the tiled scene.
|
||||
|
||||
Larger values result in a faster render with less detailed features rendered.
|
||||
|
||||
Units are set via :py:func:`~QgsTiledSceneRenderer.setMaximumScreenErrorUnit`.
|
||||
|
||||
.. seealso:: :py:func:`maximumScreenError`
|
||||
|
||||
.. seealso:: :py:func:`setMaximumScreenErrorUnit`
|
||||
%End
|
||||
|
||||
Qgis::RenderUnit maximumScreenErrorUnit() const;
|
||||
%Docstring
|
||||
Returns the unit for the maximum screen error allowed when rendering the tiled scene.
|
||||
|
||||
.. seealso:: :py:func:`maximumScreenError`
|
||||
|
||||
.. seealso:: :py:func:`setMaximumScreenErrorUnit`
|
||||
%End
|
||||
|
||||
void setMaximumScreenErrorUnit( Qgis::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the ``unit`` for the maximum screen error allowed when rendering the tiled scene.
|
||||
|
||||
.. seealso:: :py:func:`setMaximumScreenError`
|
||||
|
||||
.. seealso:: :py:func:`maximumScreenErrorUnit`
|
||||
%End
|
||||
|
||||
virtual void startRender( QgsTiledSceneRenderContext &context );
|
||||
%Docstring
|
||||
Must be called when a new render cycle is started. A call to :py:func:`~QgsTiledSceneRenderer.startRender` must always
|
||||
be followed by a corresponding call to :py:func:`~QgsTiledSceneRenderer.stopRender` after all features have been rendered.
|
||||
|
||||
.. seealso:: :py:func:`stopRender`
|
||||
|
||||
.. warning::
|
||||
|
||||
This method is not thread safe. Before calling :py:func:`~QgsTiledSceneRenderer.startRender` in a non-main thread,
|
||||
the renderer should instead be cloned and :py:func:`~QgsTiledSceneRenderer.startRender`/:py:func:`~QgsTiledSceneRenderer.stopRender` called on the clone.
|
||||
%End
|
||||
|
||||
virtual void stopRender( QgsTiledSceneRenderContext &context );
|
||||
%Docstring
|
||||
Must be called when a render cycle has finished, to allow the renderer to clean up.
|
||||
|
||||
Calls to :py:func:`~QgsTiledSceneRenderer.stopRender` must always be preceded by a call to :py:func:`~QgsTiledSceneRenderer.startRender`.
|
||||
|
||||
.. warning::
|
||||
|
||||
This method is not thread safe. Before calling :py:func:`~QgsTiledSceneRenderer.startRender` in a non-main thread,
|
||||
the renderer should instead be cloned and :py:func:`~QgsTiledSceneRenderer.startRender`/:py:func:`~QgsTiledSceneRenderer.stopRender` called on the clone.
|
||||
|
||||
.. seealso:: :py:func:`startRender`
|
||||
%End
|
||||
|
||||
virtual QList<QgsLayerTreeModelLegendNode *> createLegendNodes( QgsLayerTreeLayer *nodeLayer ) /Factory/;
|
||||
%Docstring
|
||||
Creates a set of legend nodes representing the renderer.
|
||||
%End
|
||||
|
||||
virtual QStringList legendRuleKeys() const;
|
||||
%Docstring
|
||||
Returns a list of all rule keys for legend nodes created by the renderer.
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
void copyCommonProperties( QgsTiledSceneRenderer *destination ) const;
|
||||
%Docstring
|
||||
Copies common tiled scene renderer properties (such as screen error) to the ``destination`` renderer.
|
||||
%End
|
||||
|
||||
void restoreCommonProperties( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Restores common renderer properties (such as screen error) from the
|
||||
specified DOM ``element``.
|
||||
|
||||
.. seealso:: :py:func:`saveCommonProperties`
|
||||
%End
|
||||
|
||||
void saveCommonProperties( QDomElement &element, const QgsReadWriteContext &context ) const;
|
||||
%Docstring
|
||||
Saves common renderer properties (such as point size and screen error) to the
|
||||
specified DOM ``element``.
|
||||
|
||||
.. seealso:: :py:func:`restoreCommonProperties`
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsTiledSceneRenderer( const QgsTiledSceneRenderer &other );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/tiledscene/qgstiledscenerenderer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -0,0 +1,173 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/tiledscene/qgstiledscenerendererregistry.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsTiledSceneRendererAbstractMetadata
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Stores metadata about one tiled scene renderer class.
|
||||
|
||||
.. note::
|
||||
|
||||
It's necessary to implement :py:func:`~createRenderer` function.
|
||||
In C++ you can use :py:class:`QgsTiledSceneRendererMetadata` convenience class.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsTiledSceneRendererAbstractMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon() );
|
||||
%Docstring
|
||||
Constructor for QgsTiledSceneRendererAbstractMetadata, with the specified ``name``.
|
||||
|
||||
The ``visibleName`` argument gives a translated, user friendly string identifying the renderer type.
|
||||
|
||||
The ``icon`` argument can be used to specify an icon representing the renderer.
|
||||
%End
|
||||
virtual ~QgsTiledSceneRendererAbstractMetadata();
|
||||
|
||||
QString name() const;
|
||||
%Docstring
|
||||
Returns the unique name of the renderer. This value is not translated.
|
||||
|
||||
.. seealso:: :py:func:`visibleName`
|
||||
%End
|
||||
|
||||
QString visibleName() const;
|
||||
%Docstring
|
||||
Returns a friendly display name of the renderer. This value is translated.
|
||||
|
||||
.. seealso:: :py:func:`name`
|
||||
%End
|
||||
|
||||
QIcon icon() const;
|
||||
%Docstring
|
||||
Returns an icon representing the renderer.
|
||||
|
||||
.. seealso:: :py:func:`setIcon`
|
||||
%End
|
||||
|
||||
void setIcon( const QIcon &icon );
|
||||
%Docstring
|
||||
Sets an ``icon`` representing the renderer.
|
||||
|
||||
.. seealso:: :py:func:`icon`
|
||||
%End
|
||||
|
||||
virtual QgsTiledSceneRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) = 0 /Factory/;
|
||||
%Docstring
|
||||
Returns new instance of the renderer given the DOM element. Returns ``None`` on error.
|
||||
Pure virtual function: must be implemented in derived classes.
|
||||
%End
|
||||
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
class QgsTiledSceneRendererMetadata : QgsTiledSceneRendererAbstractMetadata
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Convenience metadata class that uses static functions to create tiled scene renderer and its widget.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
|
||||
virtual QgsTiledSceneRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) /Factory/;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
QgsTiledSceneRendererMetadata();
|
||||
};
|
||||
|
||||
|
||||
class QgsTiledSceneRendererRegistry
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Registry of 2D renderers for tiled scenes.
|
||||
|
||||
:py:class:`QgsTiledSceneRendererRegistry` is not usually directly created, but rather accessed through
|
||||
:py:func:`QgsApplication.tiledSceneRendererRegistry()`.
|
||||
|
||||
.. versionadded:: 3.34
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsTiledSceneRendererRegistry();
|
||||
~QgsTiledSceneRendererRegistry();
|
||||
|
||||
|
||||
bool addRenderer( QgsTiledSceneRendererAbstractMetadata *metadata /Transfer/ );
|
||||
%Docstring
|
||||
Adds a renderer to the registry. Takes ownership of the metadata object.
|
||||
|
||||
:param metadata: renderer metadata
|
||||
|
||||
:return: ``True`` if renderer was added successfully, or ``False`` if renderer could not
|
||||
be added (e.g., a renderer with a duplicate name already exists)
|
||||
%End
|
||||
|
||||
bool removeRenderer( const QString &rendererName );
|
||||
%Docstring
|
||||
Removes a renderer from registry.
|
||||
|
||||
:param rendererName: name of renderer to remove from registry
|
||||
|
||||
:return: ``True`` if renderer was successfully removed, or ``False`` if matching
|
||||
renderer could not be found
|
||||
%End
|
||||
|
||||
QgsTiledSceneRendererAbstractMetadata *rendererMetadata( const QString &rendererName );
|
||||
%Docstring
|
||||
Returns the metadata for a specified renderer. Returns ``None`` if a matching
|
||||
renderer was not found in the registry.
|
||||
%End
|
||||
|
||||
QStringList renderersList() const;
|
||||
%Docstring
|
||||
Returns a list of available renderers.
|
||||
%End
|
||||
|
||||
static QgsTiledSceneRenderer *defaultRenderer( const QgsTiledSceneLayer *layer ) /Factory/;
|
||||
%Docstring
|
||||
Returns a new default tiled scene renderer for a specified ``layer``.
|
||||
|
||||
Caller takes ownership of the returned renderer.
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsTiledSceneRendererRegistry( const QgsTiledSceneRendererRegistry &rh );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/tiledscene/qgstiledscenerendererregistry.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -717,6 +717,8 @@
|
||||
%Include auto_generated/tiledscene/qgstiledscenedataprovider.sip
|
||||
%Include auto_generated/tiledscene/qgstiledsceneindex.sip
|
||||
%Include auto_generated/tiledscene/qgstiledscenelayer.sip
|
||||
%Include auto_generated/tiledscene/qgstiledscenerenderer.sip
|
||||
%Include auto_generated/tiledscene/qgstiledscenerendererregistry.sip
|
||||
%Include auto_generated/tiledscene/qgstiledscenerequest.sip
|
||||
%Include auto_generated/tiledscene/qgstiledscenetile.sip
|
||||
%Include auto_generated/sensor/qgssensormodel.sip
|
||||
|
@ -347,6 +347,8 @@ set(QGIS_CORE_SRCS
|
||||
tiledscene/qgstiledscenelayerrenderer.cpp
|
||||
tiledscene/qgstiledscenenode.cpp
|
||||
tiledscene/qgstiledsceneprovidermetadata.cpp
|
||||
tiledscene/qgstiledscenerenderer.cpp
|
||||
tiledscene/qgstiledscenerendererregistry.cpp
|
||||
tiledscene/qgstiledscenerequest.cpp
|
||||
tiledscene/qgstiledscenetile.cpp
|
||||
|
||||
@ -1921,6 +1923,8 @@ set(QGIS_CORE_HDRS
|
||||
tiledscene/qgstiledscenelayerrenderer.h
|
||||
tiledscene/qgstiledscenenode.h
|
||||
tiledscene/qgstiledsceneprovidermetadata.h
|
||||
tiledscene/qgstiledscenerenderer.h
|
||||
tiledscene/qgstiledscenerendererregistry.h
|
||||
tiledscene/qgstiledscenerequest.h
|
||||
tiledscene/qgstiledscenetile.h
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "qgssettings.h"
|
||||
#include "qgssettingsregistrycore.h"
|
||||
#include "qgstiledownloadmanager.h"
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsuserprofile.h"
|
||||
#include "qgsuserprofilemanager.h"
|
||||
@ -2428,6 +2429,11 @@ QgsPointCloudRendererRegistry *QgsApplication::pointCloudRendererRegistry()
|
||||
return members()->mPointCloudRendererRegistry;
|
||||
}
|
||||
|
||||
QgsTiledSceneRendererRegistry *QgsApplication::tiledSceneRendererRegistry()
|
||||
{
|
||||
return members()->mTiledSceneRendererRegistry;
|
||||
}
|
||||
|
||||
QgsDataItemProviderRegistry *QgsApplication::dataItemProviderRegistry()
|
||||
{
|
||||
if ( auto *lInstance = instance() )
|
||||
@ -2737,6 +2743,11 @@ QgsApplication::ApplicationMembers::ApplicationMembers()
|
||||
mPointCloudRendererRegistry = new QgsPointCloudRendererRegistry();
|
||||
profiler->end();
|
||||
}
|
||||
{
|
||||
profiler->start( tr( "Setup tiled scene renderer registry" ) );
|
||||
mTiledSceneRendererRegistry = new QgsTiledSceneRendererRegistry();
|
||||
profiler->end();
|
||||
}
|
||||
{
|
||||
profiler->start( tr( "Setup GPS registry" ) );
|
||||
mGpsConnectionRegistry = new QgsGpsConnectionRegistry();
|
||||
@ -2851,6 +2862,7 @@ QgsApplication::ApplicationMembers::~ApplicationMembers()
|
||||
delete mSensorRegistry;
|
||||
delete mLayoutItemRegistry;
|
||||
delete mPointCloudRendererRegistry;
|
||||
delete mTiledSceneRendererRegistry;
|
||||
delete mRasterRendererRegistry;
|
||||
delete mRendererRegistry;
|
||||
delete mSvgCache;
|
||||
|
@ -70,6 +70,7 @@ class QgsConnectionRegistry;
|
||||
class QgsScaleBarRendererRegistry;
|
||||
class Qgs3DSymbolRegistry;
|
||||
class QgsPointCloudRendererRegistry;
|
||||
class QgsTiledSceneRendererRegistry;
|
||||
class QgsTileDownloadManager;
|
||||
class QgsCoordinateReferenceSystemRegistry;
|
||||
class QgsRecentStyleHandler;
|
||||
@ -721,6 +722,12 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
*/
|
||||
static QgsPointCloudRendererRegistry *pointCloudRendererRegistry() SIP_KEEPREFERENCE;
|
||||
|
||||
/**
|
||||
* Returns the application's tiled scene renderer registry, used for managing tiled scene layer 2D renderers.
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
static QgsTiledSceneRendererRegistry *tiledSceneRendererRegistry() SIP_KEEPREFERENCE;
|
||||
|
||||
/**
|
||||
* Returns the application's data item provider registry, which keeps a list of data item
|
||||
* providers that may add items to the browser tree.
|
||||
@ -1170,6 +1177,7 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
QgsRasterRendererRegistry *mRasterRendererRegistry = nullptr;
|
||||
QgsRendererRegistry *mRendererRegistry = nullptr;
|
||||
QgsPointCloudRendererRegistry *mPointCloudRendererRegistry = nullptr;
|
||||
QgsTiledSceneRendererRegistry *mTiledSceneRendererRegistry = nullptr;
|
||||
QgsSvgCache *mSvgCache = nullptr;
|
||||
QgsImageCache *mImageCache = nullptr;
|
||||
QgsSourceCache *mSourceCache = nullptr;
|
||||
|
@ -21,10 +21,12 @@
|
||||
#include "qgspainting.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgslayermetadataformatter.h"
|
||||
#include "qgstiledscenerenderer.h"
|
||||
#include "qgsxmlutils.h"
|
||||
#include "qgsruntimeprofiler.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgstiledscenelayerrenderer.h"
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
|
||||
QgsTiledSceneLayer::QgsTiledSceneLayer( const QString &uri,
|
||||
const QString &baseName,
|
||||
@ -62,6 +64,9 @@ QgsTiledSceneLayer *QgsTiledSceneLayer::clone() const
|
||||
QgsTiledSceneLayer *layer = new QgsTiledSceneLayer( source(), name(), mProviderKey, mLayerOptions );
|
||||
QgsMapLayer::clone( layer );
|
||||
|
||||
if ( mRenderer )
|
||||
layer->setRenderer( mRenderer->clone() );
|
||||
|
||||
layer->mLayerOptions = mLayerOptions;
|
||||
|
||||
return layer;
|
||||
@ -84,6 +89,32 @@ QgsMapLayerRenderer *QgsTiledSceneLayer::createMapRenderer( QgsRenderContext &co
|
||||
return new QgsTiledSceneLayerRenderer( this, context );
|
||||
}
|
||||
|
||||
QgsTiledSceneRenderer *QgsTiledSceneLayer::renderer()
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
|
||||
return mRenderer.get();
|
||||
}
|
||||
|
||||
const QgsTiledSceneRenderer *QgsTiledSceneLayer::renderer() const
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
|
||||
return mRenderer.get();
|
||||
}
|
||||
|
||||
void QgsTiledSceneLayer::setRenderer( QgsTiledSceneRenderer *renderer )
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
|
||||
if ( renderer == mRenderer.get() )
|
||||
return;
|
||||
|
||||
mRenderer.reset( renderer );
|
||||
emit rendererChanged();
|
||||
emitStyleChanged();
|
||||
}
|
||||
|
||||
QgsTiledSceneDataProvider *QgsTiledSceneLayer::dataProvider()
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
@ -172,7 +203,7 @@ bool QgsTiledSceneLayer::readSymbology( const QDomNode &node, QString &errorMess
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsTiledSceneLayer::readStyle( const QDomNode &node, QString &, QgsReadWriteContext &, QgsMapLayer::StyleCategories categories )
|
||||
bool QgsTiledSceneLayer::readStyle( const QDomNode &node, QString &, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories )
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
|
||||
@ -187,6 +218,25 @@ bool QgsTiledSceneLayer::readStyle( const QDomNode &node, QString &, QgsReadWrit
|
||||
const QDomElement e = blendModeNode.toElement();
|
||||
setBlendMode( QgsPainting::getCompositionMode( static_cast< Qgis::BlendMode >( e.text().toInt() ) ) );
|
||||
}
|
||||
|
||||
QDomElement rendererElement = node.firstChildElement( QStringLiteral( "renderer" ) );
|
||||
if ( !rendererElement.isNull() )
|
||||
{
|
||||
std::unique_ptr< QgsTiledSceneRenderer > r( QgsTiledSceneRenderer::load( rendererElement, context ) );
|
||||
if ( r )
|
||||
{
|
||||
setRenderer( r.release() );
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
// make sure layer has a renderer - if none exists, fallback to a default renderer
|
||||
if ( !mRenderer )
|
||||
{
|
||||
setRenderer( QgsTiledSceneRendererRegistry::defaultRenderer( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
// get and set the layer transparency and scale visibility if they exists
|
||||
@ -231,7 +281,7 @@ bool QgsTiledSceneLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QStr
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsTiledSceneLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &, QgsMapLayer::StyleCategories categories ) const
|
||||
bool QgsTiledSceneLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const
|
||||
{
|
||||
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
|
||||
|
||||
@ -250,6 +300,12 @@ bool QgsTiledSceneLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString
|
||||
const QDomText blendModeText = doc.createTextNode( QString::number( static_cast< int >( QgsPainting::getBlendModeEnum( blendMode() ) ) ) );
|
||||
blendModeElem.appendChild( blendModeText );
|
||||
node.appendChild( blendModeElem );
|
||||
|
||||
if ( mRenderer )
|
||||
{
|
||||
const QDomElement rendererElement = mRenderer->save( doc, context );
|
||||
node.appendChild( rendererElement );
|
||||
}
|
||||
}
|
||||
|
||||
// add the layer opacity and scale visibility
|
||||
@ -321,6 +377,32 @@ void QgsTiledSceneLayer::setDataSourcePrivate( const QString &dataSource, const
|
||||
{
|
||||
setExtent( mDataProvider->extent() );
|
||||
}
|
||||
|
||||
bool loadDefaultStyleFlag = false;
|
||||
if ( flags & QgsDataProvider::FlagLoadDefaultStyle )
|
||||
{
|
||||
loadDefaultStyleFlag = true;
|
||||
}
|
||||
|
||||
if ( !mRenderer || loadDefaultStyleFlag )
|
||||
{
|
||||
std::unique_ptr< QgsScopedRuntimeProfile > profile;
|
||||
if ( QgsApplication::profiler()->groupIsActive( QStringLiteral( "projectload" ) ) )
|
||||
profile = std::make_unique< QgsScopedRuntimeProfile >( tr( "Load layer style" ), QStringLiteral( "projectload" ) );
|
||||
|
||||
bool defaultLoadedFlag = false;
|
||||
|
||||
if ( !defaultLoadedFlag && loadDefaultStyleFlag )
|
||||
{
|
||||
loadDefaultStyle( defaultLoadedFlag );
|
||||
}
|
||||
|
||||
if ( !defaultLoadedFlag )
|
||||
{
|
||||
// all else failed, create default renderer
|
||||
setRenderer( QgsTiledSceneRendererRegistry::defaultRenderer( this ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsTiledSceneLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgstiledscenedataprovider.h"
|
||||
|
||||
class QgsTiledSceneRenderer;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
*
|
||||
@ -112,6 +114,30 @@ class CORE_EXPORT QgsTiledSceneLayer : public QgsMapLayer
|
||||
QString htmlMetadata() const override;
|
||||
QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Returns the 2D renderer for the tiled scene.
|
||||
*
|
||||
* \see setRenderer()
|
||||
*/
|
||||
QgsTiledSceneRenderer *renderer();
|
||||
|
||||
/**
|
||||
* Returns the 2D renderer for the tiled scene.
|
||||
* \note not available in Python bindings
|
||||
*
|
||||
* \see setRenderer()
|
||||
*/
|
||||
const QgsTiledSceneRenderer *renderer() const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Sets the 2D \a renderer for the tiled scene.
|
||||
*
|
||||
* Ownership of \a renderer is transferred to the layer.
|
||||
*
|
||||
* \see renderer()
|
||||
*/
|
||||
void setRenderer( QgsTiledSceneRenderer *renderer SIP_TRANSFER );
|
||||
|
||||
private slots:
|
||||
void setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags ) override;
|
||||
|
||||
@ -124,6 +150,7 @@ class CORE_EXPORT QgsTiledSceneLayer : public QgsMapLayer
|
||||
#endif
|
||||
|
||||
std::unique_ptr<QgsTiledSceneDataProvider> mDataProvider;
|
||||
std::unique_ptr<QgsTiledSceneRenderer> mRenderer;
|
||||
|
||||
LayerOptions mLayerOptions;
|
||||
};
|
||||
|
124
src/core/tiledscene/qgstiledscenerenderer.cpp
Normal file
124
src/core/tiledscene/qgstiledscenerenderer.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/***************************************************************************
|
||||
qgstiledscenerenderer.cpp
|
||||
--------------------
|
||||
begin : August 2023
|
||||
copyright : (C) 2023 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 "qgstiledscenerenderer.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgstiledscenerendererregistry.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
//
|
||||
// QgsTiledSceneRenderContext
|
||||
//
|
||||
|
||||
QgsTiledSceneRenderContext::QgsTiledSceneRenderContext( QgsRenderContext &context, QgsFeedback *feedback )
|
||||
: mRenderContext( context )
|
||||
, mFeedback( feedback )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// QgsTiledSceneRenderer
|
||||
//
|
||||
|
||||
QgsTiledSceneRenderer *QgsTiledSceneRenderer::load( QDomElement &element, const QgsReadWriteContext &context )
|
||||
{
|
||||
if ( element.isNull() )
|
||||
return nullptr;
|
||||
|
||||
// load renderer
|
||||
const QString rendererType = element.attribute( QStringLiteral( "type" ) );
|
||||
|
||||
QgsTiledSceneRendererAbstractMetadata *m = QgsApplication::tiledSceneRendererRegistry()->rendererMetadata( rendererType );
|
||||
if ( !m )
|
||||
return nullptr;
|
||||
|
||||
std::unique_ptr< QgsTiledSceneRenderer > r( m->createRenderer( element, context ) );
|
||||
return r.release();
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::startRender( QgsTiledSceneRenderContext & )
|
||||
{
|
||||
#ifdef QGISDEBUG
|
||||
if ( !mThread )
|
||||
{
|
||||
mThread = QThread::currentThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_ASSERT_X( mThread == QThread::currentThread(), "QgsTiledSceneRenderer::startRender", "startRender called in a different thread - use a cloned renderer instead" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::stopRender( QgsTiledSceneRenderContext & )
|
||||
{
|
||||
#ifdef QGISDEBUG
|
||||
Q_ASSERT_X( mThread == QThread::currentThread(), "QgsTiledSceneRenderer::stopRender", "stopRender called in a different thread - use a cloned renderer instead" );
|
||||
#endif
|
||||
}
|
||||
|
||||
double QgsTiledSceneRenderer::maximumScreenError() const
|
||||
{
|
||||
return mMaximumScreenError;
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::setMaximumScreenError( double error )
|
||||
{
|
||||
mMaximumScreenError = error;
|
||||
}
|
||||
|
||||
Qgis::RenderUnit QgsTiledSceneRenderer::maximumScreenErrorUnit() const
|
||||
{
|
||||
return mMaximumScreenErrorUnit;
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::setMaximumScreenErrorUnit( Qgis::RenderUnit unit )
|
||||
{
|
||||
mMaximumScreenErrorUnit = unit;
|
||||
}
|
||||
|
||||
QList<QgsLayerTreeModelLegendNode *> QgsTiledSceneRenderer::createLegendNodes( QgsLayerTreeLayer * )
|
||||
{
|
||||
return QList<QgsLayerTreeModelLegendNode *>();
|
||||
}
|
||||
|
||||
QStringList QgsTiledSceneRenderer::legendRuleKeys() const
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::copyCommonProperties( QgsTiledSceneRenderer *destination ) const
|
||||
{
|
||||
destination->setMaximumScreenError( mMaximumScreenError );
|
||||
destination->setMaximumScreenErrorUnit( mMaximumScreenErrorUnit );
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::restoreCommonProperties( const QDomElement &element, const QgsReadWriteContext & )
|
||||
{
|
||||
mMaximumScreenError = element.attribute( QStringLiteral( "maximumScreenError" ), QStringLiteral( "0.3" ) ).toDouble();
|
||||
mMaximumScreenErrorUnit = QgsUnitTypes::decodeRenderUnit( element.attribute( QStringLiteral( "maximumScreenErrorUnit" ), QStringLiteral( "MM" ) ) );
|
||||
}
|
||||
|
||||
void QgsTiledSceneRenderer::saveCommonProperties( QDomElement &element, const QgsReadWriteContext & ) const
|
||||
{
|
||||
|
||||
element.setAttribute( QStringLiteral( "maximumScreenError" ), qgsDoubleToString( mMaximumScreenError ) );
|
||||
element.setAttribute( QStringLiteral( "maximumScreenErrorUnit" ), QgsUnitTypes::encodeUnit( mMaximumScreenErrorUnit ) );
|
||||
}
|
251
src/core/tiledscene/qgstiledscenerenderer.h
Normal file
251
src/core/tiledscene/qgstiledscenerenderer.h
Normal file
@ -0,0 +1,251 @@
|
||||
/***************************************************************************
|
||||
qgstiledscenerenderer.h
|
||||
--------------------
|
||||
begin : August 2023
|
||||
copyright : (C) 2023 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 QGSTILEDSCENERENDERER_H
|
||||
#define QGSTILEDSCENERENDERER_H
|
||||
|
||||
#include "qgsrendercontext.h"
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
|
||||
class QgsLayerTreeLayer;
|
||||
class QgsLayerTreeModelLegendNode;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsTiledSceneRenderContext
|
||||
*
|
||||
* \brief Encapsulates the render context for a 2D tiled scene rendering operation.
|
||||
*
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
class CORE_EXPORT QgsTiledSceneRenderContext
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsTiledSceneRenderContext.
|
||||
*/
|
||||
QgsTiledSceneRenderContext( QgsRenderContext &context, QgsFeedback *feedback = nullptr );
|
||||
|
||||
//! QgsTiledSceneRenderContext cannot be copied.
|
||||
QgsTiledSceneRenderContext( const QgsTiledSceneRenderContext &rh ) = delete;
|
||||
|
||||
//! QgsTiledSceneRenderContext cannot be copied.
|
||||
QgsTiledSceneRenderContext &operator=( const QgsTiledSceneRenderContext & ) = delete;
|
||||
|
||||
/**
|
||||
* Returns a reference to the context's render context.
|
||||
*/
|
||||
QgsRenderContext &renderContext() { return mRenderContext; }
|
||||
|
||||
/**
|
||||
* Returns a reference to the context's render context.
|
||||
* \note Not available in Python bindings.
|
||||
*/
|
||||
const QgsRenderContext &renderContext() const { return mRenderContext; } SIP_SKIP
|
||||
|
||||
/**
|
||||
* Returns the feedback object used to cancel rendering
|
||||
*
|
||||
* \since QGIS 3.20
|
||||
*/
|
||||
QgsFeedback *feedback() const { return mFeedback; }
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
QgsTiledSceneRenderContext( const QgsTiledSceneRenderContext &rh );
|
||||
#endif
|
||||
|
||||
QgsRenderContext &mRenderContext;
|
||||
QgsFeedback *mFeedback = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsTiledSceneRenderer
|
||||
*
|
||||
* \brief Abstract base class for 2d tiled scene renderers.
|
||||
*
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
class CORE_EXPORT QgsTiledSceneRenderer
|
||||
{
|
||||
|
||||
#ifdef SIP_RUN
|
||||
SIP_CONVERT_TO_SUBCLASS_CODE
|
||||
|
||||
const QString type = sipCpp->type();
|
||||
|
||||
sipType = 0;
|
||||
SIP_END
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsTiledSceneRenderer.
|
||||
*/
|
||||
QgsTiledSceneRenderer() = default;
|
||||
|
||||
virtual ~QgsTiledSceneRenderer() = default;
|
||||
|
||||
/**
|
||||
* Returns the identifier of the renderer type.
|
||||
*/
|
||||
virtual QString type() const = 0;
|
||||
|
||||
/**
|
||||
* Create a deep copy of this renderer. Should be implemented by all subclasses
|
||||
* and generate a proper subclass.
|
||||
*/
|
||||
virtual QgsTiledSceneRenderer *clone() const = 0 SIP_FACTORY;
|
||||
|
||||
//! QgsTiledSceneRenderer cannot be copied -- use clone() instead
|
||||
QgsTiledSceneRenderer( const QgsTiledSceneRenderer &other ) = delete;
|
||||
|
||||
//! QgsTiledSceneRenderer cannot be copied -- use clone() instead
|
||||
QgsTiledSceneRenderer &operator=( const QgsTiledSceneRenderer &other ) = delete;
|
||||
|
||||
/**
|
||||
* Creates a renderer from an XML \a element.
|
||||
*
|
||||
* Caller takes ownership of the returned renderer.
|
||||
*
|
||||
* \see save()
|
||||
*/
|
||||
static QgsTiledSceneRenderer *load( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Saves the renderer configuration to an XML element.
|
||||
* \see load()
|
||||
*/
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const = 0;
|
||||
|
||||
/**
|
||||
* Returns the maximum screen error allowed when rendering the tiled scene.
|
||||
*
|
||||
* Larger values result in a faster render with less detailed features rendered.
|
||||
*
|
||||
* Units are retrieved via maximumScreenErrorUnit().
|
||||
*
|
||||
* \see setMaximumScreenError()
|
||||
* \see maximumScreenErrorUnit()
|
||||
*/
|
||||
double maximumScreenError() const;
|
||||
|
||||
/**
|
||||
* Sets the maximum screen \a error allowed when rendering the tiled scene.
|
||||
*
|
||||
* Larger values result in a faster render with less detailed features rendered.
|
||||
*
|
||||
* Units are set via setMaximumScreenErrorUnit().
|
||||
*
|
||||
* \see maximumScreenError()
|
||||
* \see setMaximumScreenErrorUnit()
|
||||
*/
|
||||
void setMaximumScreenError( double error );
|
||||
|
||||
/**
|
||||
* Returns the unit for the maximum screen error allowed when rendering the tiled scene.
|
||||
*
|
||||
* \see maximumScreenError()
|
||||
* \see setMaximumScreenErrorUnit()
|
||||
*/
|
||||
Qgis::RenderUnit maximumScreenErrorUnit() const;
|
||||
|
||||
/**
|
||||
* Sets the \a unit for the maximum screen error allowed when rendering the tiled scene.
|
||||
*
|
||||
* \see setMaximumScreenError()
|
||||
* \see maximumScreenErrorUnit()
|
||||
*/
|
||||
void setMaximumScreenErrorUnit( Qgis::RenderUnit unit );
|
||||
|
||||
/**
|
||||
* Must be called when a new render cycle is started. A call to startRender() must always
|
||||
* be followed by a corresponding call to stopRender() after all features have been rendered.
|
||||
*
|
||||
* \see stopRender()
|
||||
*
|
||||
* \warning This method is not thread safe. Before calling startRender() in a non-main thread,
|
||||
* the renderer should instead be cloned and startRender()/stopRender() called on the clone.
|
||||
*/
|
||||
virtual void startRender( QgsTiledSceneRenderContext &context );
|
||||
|
||||
/**
|
||||
* Must be called when a render cycle has finished, to allow the renderer to clean up.
|
||||
*
|
||||
* Calls to stopRender() must always be preceded by a call to startRender().
|
||||
*
|
||||
* \warning This method is not thread safe. Before calling startRender() in a non-main thread,
|
||||
* the renderer should instead be cloned and startRender()/stopRender() called on the clone.
|
||||
*
|
||||
* \see startRender()
|
||||
*/
|
||||
virtual void stopRender( QgsTiledSceneRenderContext &context );
|
||||
|
||||
/**
|
||||
* Creates a set of legend nodes representing the renderer.
|
||||
*/
|
||||
virtual QList<QgsLayerTreeModelLegendNode *> createLegendNodes( QgsLayerTreeLayer *nodeLayer ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Returns a list of all rule keys for legend nodes created by the renderer.
|
||||
*/
|
||||
virtual QStringList legendRuleKeys() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Copies common tiled scene renderer properties (such as screen error) to the \a destination renderer.
|
||||
*/
|
||||
void copyCommonProperties( QgsTiledSceneRenderer *destination ) const;
|
||||
|
||||
/**
|
||||
* Restores common renderer properties (such as screen error) from the
|
||||
* specified DOM \a element.
|
||||
*
|
||||
* \see saveCommonProperties()
|
||||
*/
|
||||
void restoreCommonProperties( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
|
||||
/**
|
||||
* Saves common renderer properties (such as point size and screen error) to the
|
||||
* specified DOM \a element.
|
||||
*
|
||||
* \see restoreCommonProperties()
|
||||
*/
|
||||
void saveCommonProperties( QDomElement &element, const QgsReadWriteContext &context ) const;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
QgsTiledSceneRenderer( const QgsTiledSceneRenderer &other );
|
||||
#endif
|
||||
|
||||
#ifdef QGISDEBUG
|
||||
//! Pointer to thread in which startRender was first called
|
||||
QThread *mThread = nullptr;
|
||||
#endif
|
||||
|
||||
double mMaximumScreenError = 0.3;
|
||||
Qgis::RenderUnit mMaximumScreenErrorUnit = Qgis::RenderUnit::Millimeters;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSTILEDSCENERENDERER_H
|
70
src/core/tiledscene/qgstiledscenerendererregistry.cpp
Normal file
70
src/core/tiledscene/qgstiledscenerendererregistry.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
qgstiledscenerendererregistry.cpp
|
||||
---------------------
|
||||
begin : August 2023
|
||||
copyright : (C) 2023 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 "qgstiledscenerendererregistry.h"
|
||||
#include "qgstiledscenerenderer.h"
|
||||
|
||||
QgsTiledSceneRendererRegistry::QgsTiledSceneRendererRegistry()
|
||||
{
|
||||
// add default renderers
|
||||
}
|
||||
|
||||
QgsTiledSceneRendererRegistry::~QgsTiledSceneRendererRegistry()
|
||||
{
|
||||
qDeleteAll( mRenderers );
|
||||
}
|
||||
|
||||
bool QgsTiledSceneRendererRegistry::addRenderer( QgsTiledSceneRendererAbstractMetadata *metadata )
|
||||
{
|
||||
if ( !metadata || mRenderers.contains( metadata->name() ) )
|
||||
return false;
|
||||
|
||||
mRenderers[metadata->name()] = metadata;
|
||||
mRenderersOrder << metadata->name();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsTiledSceneRendererRegistry::removeRenderer( const QString &rendererName )
|
||||
{
|
||||
if ( !mRenderers.contains( rendererName ) )
|
||||
return false;
|
||||
|
||||
delete mRenderers[rendererName];
|
||||
mRenderers.remove( rendererName );
|
||||
mRenderersOrder.removeAll( rendererName );
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsTiledSceneRendererAbstractMetadata *QgsTiledSceneRendererRegistry::rendererMetadata( const QString &rendererName )
|
||||
{
|
||||
return mRenderers.value( rendererName );
|
||||
}
|
||||
|
||||
QStringList QgsTiledSceneRendererRegistry::renderersList() const
|
||||
{
|
||||
QStringList renderers;
|
||||
for ( const QString &renderer : mRenderersOrder )
|
||||
{
|
||||
QgsTiledSceneRendererAbstractMetadata *r = mRenderers.value( renderer );
|
||||
if ( r )
|
||||
renderers << renderer;
|
||||
}
|
||||
return renderers;
|
||||
}
|
||||
|
||||
QgsTiledSceneRenderer *QgsTiledSceneRendererRegistry::defaultRenderer( const QgsTiledSceneLayer * )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
239
src/core/tiledscene/qgstiledscenerendererregistry.h
Normal file
239
src/core/tiledscene/qgstiledscenerendererregistry.h
Normal file
@ -0,0 +1,239 @@
|
||||
/***************************************************************************
|
||||
qgstiledscenerendererregistry.h
|
||||
---------------------
|
||||
begin : August 2023
|
||||
copyright : (C) 2023 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 QGSTILEDSCENERENDERERREGISTRY_H
|
||||
#define QGSTILEDSCENERENDERERREGISTRY_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
#include <QIcon>
|
||||
#include <QMap>
|
||||
#include <QStringList>
|
||||
#include <QDomElement>
|
||||
|
||||
class QgsTiledSceneRenderer;
|
||||
class QgsReadWriteContext;
|
||||
class QgsTiledSceneLayer;
|
||||
class QgsStyle;
|
||||
#ifndef SIP_RUN
|
||||
class QgsTiledSceneRendererWidget SIP_EXTERNAL;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \brief Stores metadata about one tiled scene renderer class.
|
||||
*
|
||||
* \note It's necessary to implement createRenderer() function.
|
||||
* In C++ you can use QgsTiledSceneRendererMetadata convenience class.
|
||||
*
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
class CORE_EXPORT QgsTiledSceneRendererAbstractMetadata
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsTiledSceneRendererAbstractMetadata, with the specified \a name.
|
||||
*
|
||||
* The \a visibleName argument gives a translated, user friendly string identifying the renderer type.
|
||||
*
|
||||
* The \a icon argument can be used to specify an icon representing the renderer.
|
||||
*/
|
||||
QgsTiledSceneRendererAbstractMetadata( const QString &name, const QString &visibleName, const QIcon &icon = QIcon() )
|
||||
: mName( name )
|
||||
, mVisibleName( visibleName )
|
||||
, mIcon( icon )
|
||||
{}
|
||||
virtual ~QgsTiledSceneRendererAbstractMetadata() = default;
|
||||
|
||||
/**
|
||||
* Returns the unique name of the renderer. This value is not translated.
|
||||
* \see visibleName()
|
||||
*/
|
||||
QString name() const { return mName; }
|
||||
|
||||
/**
|
||||
* Returns a friendly display name of the renderer. This value is translated.
|
||||
* \see name()
|
||||
*/
|
||||
QString visibleName() const { return mVisibleName; }
|
||||
|
||||
/**
|
||||
* Returns an icon representing the renderer.
|
||||
* \see setIcon()
|
||||
*/
|
||||
QIcon icon() const { return mIcon; }
|
||||
|
||||
/**
|
||||
* Sets an \a icon representing the renderer.
|
||||
* \see icon()
|
||||
*/
|
||||
void setIcon( const QIcon &icon ) { mIcon = icon; }
|
||||
|
||||
/**
|
||||
* Returns new instance of the renderer given the DOM element. Returns NULLPTR on error.
|
||||
* Pure virtual function: must be implemented in derived classes.
|
||||
*/
|
||||
virtual QgsTiledSceneRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) = 0 SIP_FACTORY;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
* Returns new instance of settings widget for the renderer. Returns NULLPTR on error.
|
||||
*
|
||||
* The \a oldRenderer argument may refer to previously used renderer (or it is NULLPTR).
|
||||
* If not NULLPTR, it may be used to initialize GUI of the widget from the previous settings.
|
||||
* The old renderer does not have to be of the same type as returned by createRenderer().
|
||||
*
|
||||
* \note Not available in Python bindings
|
||||
*/
|
||||
virtual QgsTiledSceneRendererWidget *createRendererWidget( QgsTiledSceneLayer *layer, QgsStyle *style, QgsTiledSceneRenderer *oldRenderer ) SIP_FACTORY
|
||||
{ Q_UNUSED( layer ) Q_UNUSED( style ); Q_UNUSED( oldRenderer ); return nullptr; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
//! name used within QGIS for identification (the same what renderer's type() returns)
|
||||
QString mName;
|
||||
//! name visible for users (translatable)
|
||||
QString mVisibleName;
|
||||
//! icon to be shown in the renderer properties dialog
|
||||
QIcon mIcon;
|
||||
};
|
||||
|
||||
typedef QgsTiledSceneRenderer *( *QgsTiledSceneRendererCreateFunc )( QDomElement &, const QgsReadWriteContext & ) SIP_SKIP;
|
||||
typedef QgsTiledSceneRendererWidget *( *QgsTiledSceneRendererWidgetFunc )( QgsTiledSceneLayer *, QgsStyle *, QgsTiledSceneRenderer * ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \brief Convenience metadata class that uses static functions to create tiled scene renderer and its widget.
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
class CORE_EXPORT QgsTiledSceneRendererMetadata : public QgsTiledSceneRendererAbstractMetadata
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct metadata
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
QgsTiledSceneRendererMetadata( const QString &name,
|
||||
const QString &visibleName,
|
||||
QgsTiledSceneRendererCreateFunc pfCreate,
|
||||
const QIcon &icon = QIcon(),
|
||||
QgsTiledSceneRendererWidgetFunc pfWidget = nullptr ) SIP_SKIP
|
||||
: QgsTiledSceneRendererAbstractMetadata( name, visibleName, icon )
|
||||
, mCreateFunc( pfCreate )
|
||||
, mWidgetFunc( pfWidget )
|
||||
{}
|
||||
|
||||
QgsTiledSceneRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) override SIP_FACTORY
|
||||
{ return mCreateFunc ? mCreateFunc( elem, context ) : nullptr; }
|
||||
|
||||
#ifndef SIP_RUN
|
||||
QgsTiledSceneRendererWidget *createRendererWidget( QgsTiledSceneLayer *layer, QgsStyle *style, QgsTiledSceneRenderer *renderer ) override SIP_FACTORY
|
||||
{ return mWidgetFunc ? mWidgetFunc( layer, style, renderer ) : nullptr; }
|
||||
#endif
|
||||
|
||||
//! \note not available in Python bindings
|
||||
QgsTiledSceneRendererCreateFunc createFunction() const { return mCreateFunc; } SIP_SKIP
|
||||
//! \note not available in Python bindings
|
||||
QgsTiledSceneRendererWidgetFunc widgetFunction() const { return mWidgetFunc; } SIP_SKIP
|
||||
|
||||
//! \note not available in Python bindings
|
||||
void setWidgetFunction( QgsTiledSceneRendererWidgetFunc f ) { mWidgetFunc = f; } SIP_SKIP
|
||||
|
||||
protected:
|
||||
//! pointer to function that creates an instance of the renderer when loading project / style
|
||||
QgsTiledSceneRendererCreateFunc mCreateFunc;
|
||||
//! pointer to function that creates a widget for configuration of renderer's params
|
||||
QgsTiledSceneRendererWidgetFunc mWidgetFunc;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
QgsTiledSceneRendererMetadata();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsTiledSceneRendererRegistry
|
||||
* \brief Registry of 2D renderers for tiled scenes.
|
||||
*
|
||||
* QgsTiledSceneRendererRegistry is not usually directly created, but rather accessed through
|
||||
* QgsApplication::tiledSceneRendererRegistry().
|
||||
*
|
||||
* \since QGIS 3.34
|
||||
*/
|
||||
class CORE_EXPORT QgsTiledSceneRendererRegistry
|
||||
{
|
||||
public:
|
||||
|
||||
QgsTiledSceneRendererRegistry();
|
||||
~QgsTiledSceneRendererRegistry();
|
||||
|
||||
//! QgsTiledSceneRendererRegistry cannot be copied.
|
||||
QgsTiledSceneRendererRegistry( const QgsTiledSceneRendererRegistry &rh ) = delete;
|
||||
//! QgsTiledSceneRendererRegistry cannot be copied.
|
||||
QgsTiledSceneRendererRegistry &operator=( const QgsTiledSceneRendererRegistry &rh ) = delete;
|
||||
|
||||
/**
|
||||
* Adds a renderer to the registry. Takes ownership of the metadata object.
|
||||
* \param metadata renderer metadata
|
||||
* \returns TRUE if renderer was added successfully, or FALSE if renderer could not
|
||||
* be added (e.g., a renderer with a duplicate name already exists)
|
||||
*/
|
||||
bool addRenderer( QgsTiledSceneRendererAbstractMetadata *metadata SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Removes a renderer from registry.
|
||||
* \param rendererName name of renderer to remove from registry
|
||||
* \returns TRUE if renderer was successfully removed, or FALSE if matching
|
||||
* renderer could not be found
|
||||
*/
|
||||
bool removeRenderer( const QString &rendererName );
|
||||
|
||||
/**
|
||||
* Returns the metadata for a specified renderer. Returns NULLPTR if a matching
|
||||
* renderer was not found in the registry.
|
||||
*/
|
||||
QgsTiledSceneRendererAbstractMetadata *rendererMetadata( const QString &rendererName );
|
||||
|
||||
/**
|
||||
* Returns a list of available renderers.
|
||||
*/
|
||||
QStringList renderersList() const;
|
||||
|
||||
/**
|
||||
* Returns a new default tiled scene renderer for a specified \a layer.
|
||||
*
|
||||
* Caller takes ownership of the returned renderer.
|
||||
*/
|
||||
static QgsTiledSceneRenderer *defaultRenderer( const QgsTiledSceneLayer *layer ) SIP_FACTORY;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
QgsTiledSceneRendererRegistry( const QgsTiledSceneRendererRegistry &rh );
|
||||
#endif
|
||||
|
||||
//! Map of name to renderer
|
||||
QMap<QString, QgsTiledSceneRendererAbstractMetadata *> mRenderers;
|
||||
|
||||
//! List of renderers, maintained in the order that they have been added
|
||||
QStringList mRenderersOrder;
|
||||
};
|
||||
|
||||
#endif // QGSTILEDSCENERENDERERREGISTRY_H
|
@ -194,6 +194,7 @@ set(TESTS
|
||||
testqgstemporalproperty.cpp
|
||||
testqgstemporalrangeobject.cpp
|
||||
testqgstiledsceneconnection.cpp
|
||||
testqgstiledscenerendererregistry.cpp
|
||||
testqgstiledownloadmanager.cpp
|
||||
testqgstracer.cpp
|
||||
testqgstranslateproject.cpp
|
||||
|
139
tests/src/core/testqgstiledscenerendererregistry.cpp
Normal file
139
tests/src/core/testqgstiledscenerendererregistry.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/***************************************************************************
|
||||
testqgstiledscenerendererregistry.cpp
|
||||
-----------------------
|
||||
begin : August 2023
|
||||
copyright : (C) 2023 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 "qgstiledscenerendererregistry.h"
|
||||
#include "qgstiledscenerenderer.h"
|
||||
#include "qgsreadwritecontext.h"
|
||||
|
||||
#include <QObject>
|
||||
#include "qgstest.h"
|
||||
|
||||
//dummy renderer for testing
|
||||
class DummyRenderer : public QgsTiledSceneRenderer
|
||||
{
|
||||
public:
|
||||
DummyRenderer() = default;
|
||||
QString type() const override { return QStringLiteral( "dummy" ); }
|
||||
QgsTiledSceneRenderer *clone() const override { return new DummyRenderer(); }
|
||||
static QgsTiledSceneRenderer *create( QDomElement &, const QgsReadWriteContext & ) { return new DummyRenderer(); }
|
||||
QDomElement save( QDomDocument &doc, const QgsReadWriteContext & ) const override { return doc.createElement( QStringLiteral( "test" ) ); }
|
||||
|
||||
};
|
||||
|
||||
class TestQgsTiledSceneRendererRegistry : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
void metadata();
|
||||
void createInstance();
|
||||
void instanceHasDefaultRenderers();
|
||||
void addRenderer();
|
||||
void fetchTypes();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::initTestCase()
|
||||
{
|
||||
QgsApplication::init(); // init paths for CRS lookup
|
||||
QgsApplication::initQgis();
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::cleanupTestCase()
|
||||
{
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::metadata()
|
||||
{
|
||||
QgsTiledSceneRendererMetadata metadata = QgsTiledSceneRendererMetadata( QStringLiteral( "name" ), QStringLiteral( "display name" ), DummyRenderer::create, QIcon() );
|
||||
QCOMPARE( metadata.name(), QString( "name" ) );
|
||||
QCOMPARE( metadata.visibleName(), QString( "display name" ) );
|
||||
|
||||
//test creating renderer from metadata
|
||||
QDomElement elem;
|
||||
const std::unique_ptr< QgsTiledSceneRenderer > renderer( metadata.createRenderer( elem, QgsReadWriteContext() ) );
|
||||
QVERIFY( renderer );
|
||||
DummyRenderer *dummyRenderer = dynamic_cast<DummyRenderer *>( renderer.get() );
|
||||
QVERIFY( dummyRenderer );
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::createInstance()
|
||||
{
|
||||
QgsTiledSceneRendererRegistry *registry = QgsApplication::tiledSceneRendererRegistry();
|
||||
QVERIFY( registry );
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::instanceHasDefaultRenderers()
|
||||
{
|
||||
//check that callout registry is initially populated with some renderers
|
||||
//(assumes that there is some default renderers)
|
||||
QgsTiledSceneRendererRegistry *registry = QgsApplication::tiledSceneRendererRegistry();
|
||||
QVERIFY( registry->renderersList().length() > 0 );
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::addRenderer()
|
||||
{
|
||||
QgsTiledSceneRendererRegistry *registry = QgsApplication::tiledSceneRendererRegistry();
|
||||
const int previousCount = registry->renderersList().length();
|
||||
|
||||
registry->addRenderer( new QgsTiledSceneRendererMetadata( QStringLiteral( "Dummy" ), QStringLiteral( "Dummy renderer" ), DummyRenderer::create, QIcon() ) );
|
||||
QCOMPARE( registry->renderersList().length(), previousCount + 1 );
|
||||
//try adding again, should have no effect
|
||||
QgsTiledSceneRendererMetadata *dupe = new QgsTiledSceneRendererMetadata( QStringLiteral( "Dummy" ), QStringLiteral( "Dummy callout" ), DummyRenderer::create, QIcon() );
|
||||
QVERIFY( ! registry->addRenderer( dupe ) );
|
||||
QCOMPARE( registry->renderersList().length(), previousCount + 1 );
|
||||
delete dupe;
|
||||
|
||||
//try adding empty metadata
|
||||
registry->addRenderer( nullptr );
|
||||
QCOMPARE( registry->renderersList().length(), previousCount + 1 );
|
||||
}
|
||||
|
||||
void TestQgsTiledSceneRendererRegistry::fetchTypes()
|
||||
{
|
||||
QgsTiledSceneRendererRegistry *registry = QgsApplication::tiledSceneRendererRegistry();
|
||||
const QStringList types = registry->renderersList();
|
||||
|
||||
QVERIFY( types.contains( "Dummy" ) );
|
||||
|
||||
QgsTiledSceneRendererAbstractMetadata *metadata = registry->rendererMetadata( QStringLiteral( "Dummy" ) );
|
||||
QCOMPARE( metadata->name(), QString( "Dummy" ) );
|
||||
|
||||
//metadata for bad renderer
|
||||
metadata = registry->rendererMetadata( QStringLiteral( "bad renderer" ) );
|
||||
QVERIFY( !metadata );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsTiledSceneRendererRegistry )
|
||||
#include "testqgstiledscenerendererregistry.moc"
|
Loading…
x
Reference in New Issue
Block a user