1 /***************************************************************************
2   qgsrulebasedchunkloader_p.h
3   --------------------------------------
4   Date                 : November 2019
5   Copyright            : (C) 2019 by Martin Dobias
6   Email                : wonder dot sk at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #ifndef QGSRULEBASEDCHUNKLOADER_H
17 #define QGSRULEBASEDCHUNKLOADER_H
18 
19 ///@cond PRIVATE
20 
21 //
22 //  W A R N I N G
23 //  -------------
24 //
25 // This file is not part of the QGIS API.  It exists purely as an
26 // implementation detail.  This header file may change from version to
27 // version without notice, or even be removed.
28 //
29 
30 #include "qgschunkloader_p.h"
31 #include "qgsfeature3dhandler_p.h"
32 #include "qgschunkedentity_p.h"
33 #include "qgsrulebased3drenderer.h"
34 
35 #define SIP_NO_FILE
36 
37 class Qgs3DMapSettings;
38 class QgsVectorLayer;
39 class QgsVectorLayerFeatureSource;
40 class QgsAbstract3DSymbol;
41 class QgsFeature3DHandler;
42 
43 
44 /**
45  * \ingroup 3d
46  * \brief This loader factory is responsible for creation of loaders for individual tiles
47  * of QgsRuleBasedChunkedEntity whenever a new tile is requested by the entity.
48  *
49  * \since QGIS 3.12
50  */
51 class QgsRuleBasedChunkLoaderFactory : public QgsChunkLoaderFactory
52 {
53   public:
54     //! Constructs the factory (vl and rootRule must not be null)
55     QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettings &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel );
56     ~QgsRuleBasedChunkLoaderFactory() override;
57 
58     //! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
59     virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
60 
61     const Qgs3DMapSettings &mMap;
62     QgsVectorLayer *mLayer;
63     std::unique_ptr<QgsRuleBased3DRenderer::Rule> mRootRule;
64     int mLeafLevel;
65 };
66 
67 
68 /**
69  * \ingroup 3d
70  * \brief This loader class is responsible for async loading of data for a single tile
71  * of QgsRuleBasedChunkedEntity and creation of final 3D entity from the data
72  * previously prepared in a worker thread.
73  *
74  * \since QGIS 3.12
75  */
76 class QgsRuleBasedChunkLoader : public QgsChunkLoader
77 {
78   public:
79     //! Constructs the loader (factory and node must not be null)
80     QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderFactory *factory, QgsChunkNode *node );
81     ~QgsRuleBasedChunkLoader() override;
82 
83     virtual void cancel() override;
84     virtual Qt3DCore::QEntity *createEntity( Qt3DCore::QEntity *parent ) override;
85 
86   private:
87     const QgsRuleBasedChunkLoaderFactory *mFactory;
88     QgsRuleBased3DRenderer::RuleToHandlerMap mHandlers;
89     Qgs3DRenderContext mContext;
90     std::unique_ptr<QgsVectorLayerFeatureSource> mSource;
91     bool mCanceled = false;
92     QFutureWatcher<void> *mFutureWatcher = nullptr;
93     std::unique_ptr<QgsRuleBased3DRenderer::Rule> mRootRule;
94 };
95 
96 
97 /**
98  * \ingroup 3d
99  * \brief 3D entity used for rendering of vector layers using a hierarchy of rules (just like
100  * in case of 2D rule-based rendering or labeling).
101  *
102  * It is implemented using tiling approach with QgsChunkedEntity. Internally it uses
103  * QgsRuleBasedChunkLoaderFactory and QgsRuleBasedChunkLoader to do the actual work
104  * of loading and creating 3D sub-entities for each tile.
105  *
106  * \since QGIS 3.12
107  */
108 class QgsRuleBasedChunkedEntity : public QgsChunkedEntity
109 {
110     Q_OBJECT
111   public:
112     //! Constructs the entity. The argument maxLevel determines how deep the tree of tiles will be
113     explicit QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, double zMin, double zMax, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map );
114 
115     ~QgsRuleBasedChunkedEntity();
116 };
117 
118 /// @endcond
119 
120 #endif // QGSRULEBASEDCHUNKLOADER_H
121