Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsmeshlayer.h
3 : : --------------
4 : : begin : April 2018
5 : : copyright : (C) 2018 by Peter Petrik
6 : : email : zilolv at gmail dot com
7 : : ***************************************************************************/
8 : :
9 : : /***************************************************************************
10 : : * *
11 : : * This program is free software; you can redistribute it and/or modify *
12 : : * it under the terms of the GNU General Public License as published by *
13 : : * the Free Software Foundation; either version 2 of the License, or *
14 : : * (at your option) any later version. *
15 : : * *
16 : : ***************************************************************************/
17 : :
18 : : #ifndef QGSMESHLAYER_H
19 : : #define QGSMESHLAYER_H
20 : :
21 : : #include <memory>
22 : :
23 : : #include "qgis_core.h"
24 : : #include "qgsinterval.h"
25 : : #include "qgsmaplayer.h"
26 : : #include "qgsmeshdataprovider.h"
27 : : #include "qgsmeshrenderersettings.h"
28 : : #include "qgsmeshtimesettings.h"
29 : : #include "qgsmeshsimplificationsettings.h"
30 : :
31 : : class QgsMapLayerRenderer;
32 : : struct QgsMeshLayerRendererCache;
33 : : class QgsSymbol;
34 : : class QgsTriangularMesh;
35 : : class QgsRenderContext;
36 : : struct QgsMesh;
37 : : class QgsMesh3dAveragingMethod;
38 : : class QgsMeshLayerTemporalProperties;
39 : : class QgsMeshDatasetGroupStore;
40 : :
41 : : /**
42 : : * \ingroup core
43 : : *
44 : : * \brief Represents a mesh layer supporting display of data on structured or unstructured meshes
45 : : *
46 : : * The QgsMeshLayer is instantiated by specifying the name of a data provider,
47 : : * such as mdal, and url defining the specific data set to connect to.
48 : : * The vector layer constructor in turn instantiates a QgsMeshDataProvider subclass
49 : : * corresponding to the provider type, and passes it the url. The data provider
50 : : * connects to the data source.
51 : : *
52 : : * The QgsMeshLayer provides a common interface to the different data types. It does not
53 : : * yet support editing transactions.
54 : : *
55 : : * The main data providers supported by QGIS are listed below.
56 : : *
57 : : * \section mesh_providers Mesh data providers
58 : : *
59 : : * \subsection mesh_memory Memory data providerType (mesh_memory)
60 : : *
61 : : * The memory data provider is used to construct in memory data, for example scratch
62 : : * data. There is no inherent persistent storage of the data. The data source uri is constructed.
63 : : * Data can be populated by setMesh(const QString &vertices, const QString &faces), where
64 : : * vertices and faces is comma separated coordinates and connections for mesh.
65 : : * E.g. to create mesh with one quad and one triangle
66 : : *
67 : : * \code{py}
68 : : * uri = "1.0, 2.0 \n" \
69 : : * "2.0, 2.0 \n" \
70 : : * "3.0, 2.0 \n" \
71 : : * "2.0, 3.0 \n" \
72 : : * "1.0, 3.0 \n" \
73 : : * "---" \
74 : : * "0, 1, 3, 4 \n" \
75 : : * "1, 2, 3 \n"
76 : : *
77 : : * scratchLayer = QgsMeshLayer(uri, "My Scratch layer", "mesh_memory")
78 : : * \endcode
79 : : *
80 : : * \subsection mdal MDAL data provider (mdal)
81 : : *
82 : : * Accesses data using the MDAL drivers (https://github.com/lutraconsulting/MDAL). The url
83 : : * is the MDAL connection string. QGIS must be built with MDAL support to allow this provider.
84 : :
85 : : * \code{py}
86 : : * uri = "test/land.2dm"
87 : : * scratchLayer = QgsMeshLayer(uri, "My Scratch Layer", "mdal")
88 : : * \endcode
89 : : *
90 : : * \note The API is considered EXPERIMENTAL and can be changed without a notice
91 : : *
92 : : * \since QGIS 3.2
93 : : */
94 : : class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
95 : : {
96 : 0 : Q_OBJECT
97 : : public:
98 : :
99 : : /**
100 : : * Setting options for loading mesh layers.
101 : : */
102 : 0 : struct LayerOptions
103 : : {
104 : :
105 : : /**
106 : : * Constructor for LayerOptions with optional \a transformContext.
107 : : * \note transformContext argument was added in QGIS 3.8
108 : : */
109 : 0 : explicit LayerOptions( const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext( ) )
110 : 0 : : transformContext( transformContext )
111 : 0 : {}
112 : :
113 : : QgsCoordinateTransformContext transformContext;
114 : :
115 : : /**
116 : : * Controls whether the layer is allowed to have an invalid/unknown CRS.
117 : : *
118 : : * If TRUE, then no validation will be performed on the layer's CRS and the layer
119 : : * layer's crs() may be invalid() (i.e. the layer will have no georeferencing available
120 : : * and will be treated as having purely numerical coordinates).
121 : : *
122 : : * If FALSE (the default), the layer's CRS will be validated using QgsCoordinateReferenceSystem::validate(),
123 : : * which may cause a blocking, user-facing dialog asking users to manually select the correct CRS for the
124 : : * layer.
125 : : *
126 : : * \since QGIS 3.10
127 : : */
128 : 0 : bool skipCrsValidation = false;
129 : : };
130 : :
131 : : /**
132 : : * Constructor - creates a mesh layer
133 : : *
134 : : * The QgsMeshLayer is constructed by instantiating a data provider. The provider
135 : : * interprets the supplied path (url) of the data source to connect to and access the
136 : : * data.
137 : : *
138 : : * \param path The path or url of the parameter. Typically this encodes
139 : : * parameters used by the data provider as url query items.
140 : : * \param baseName The name used to represent the layer in the legend
141 : : * \param providerLib The name of the data provider, e.g., "mesh_memory", "mdal"
142 : : * \param options general mesh layer options
143 : : */
144 : 0 : explicit QgsMeshLayer( const QString &path = QString(), const QString &baseName = QString(), const QString &providerLib = QStringLiteral( "mesh_memory" ),
145 : : const QgsMeshLayer::LayerOptions &options = QgsMeshLayer::LayerOptions() );
146 : :
147 : : ~QgsMeshLayer() override;
148 : :
149 : : //! QgsMeshLayer cannot be copied.
150 : : QgsMeshLayer( const QgsMeshLayer &rhs ) = delete;
151 : : //! QgsMeshLayer cannot be copied.
152 : : QgsMeshLayer &operator=( QgsMeshLayer const &rhs ) = delete;
153 : :
154 : : #ifdef SIP_RUN
155 : : SIP_PYOBJECT __repr__();
156 : : % MethodCode
157 : : QString str = QStringLiteral( "<QgsMeshLayer: '%1' (%2)>" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QStringLiteral( "Invalid" ) );
158 : : sipRes = PyUnicode_FromString( str.toUtf8().constData() );
159 : : % End
160 : : #endif
161 : :
162 : : QgsMeshDataProvider *dataProvider() override;
163 : : const QgsMeshDataProvider *dataProvider() const override SIP_SKIP;
164 : : QgsMeshLayer *clone() const override SIP_FACTORY;
165 : : QgsRectangle extent() const override;
166 : : QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
167 : : bool readSymbology( const QDomNode &node, QString &errorMessage,
168 : : QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
169 : : bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
170 : : const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
171 : : bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) const override;
172 : : bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) override;
173 : : QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
174 : : QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;
175 : : bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;
176 : : bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
177 : : QgsMapLayerTemporalProperties *temporalProperties() override;
178 : : void reload() override;
179 : : QStringList subLayers() const override;
180 : : QString htmlMetadata() const override;
181 : :
182 : : //! Returns the provider type for this layer
183 : : QString providerType() const;
184 : :
185 : : /**
186 : : * Adds datasets to the mesh from file with \a path. Use the the time \a defaultReferenceTime as reference time is not provided in the file
187 : : *
188 : : * \param path the path to the atasets file
189 : : * \param defaultReferenceTime reference time used if not provided in the file
190 : : * \return whether the dataset is added
191 : : *
192 : : * \since QGIS 3.14
193 : : */
194 : : bool addDatasets( const QString &path, const QDateTime &defaultReferenceTime = QDateTime() );
195 : :
196 : : /**
197 : : * Adds extra datasets to the mesh. Take ownership.
198 : : *
199 : : * \param datasetGroup the extra dataset group
200 : : * \return whether the dataset is effectively added
201 : : *
202 : : * \since QGIS 3.16
203 : : */
204 : : bool addDatasets( QgsMeshDatasetGroup *datasetGroup SIP_TRANSFER );
205 : :
206 : : /**
207 : : * Saves datasets group on file with the specified \a driver
208 : : *
209 : : * \param path the path of the file
210 : : * \param datasetGroupIndex the index of the dataset group
211 : : * \param driver the driver to used for saving
212 : : * \return false if succeeds
213 : : *
214 : : * \since QGIS 3.16
215 : : */
216 : : bool saveDataset( const QString &path, int datasetGroupIndex, QString driver );
217 : :
218 : : /**
219 : : * Returns native mesh (NULLPTR before rendering or calling to updateMesh)
220 : : *
221 : : * \note Not available in Python bindings
222 : : */
223 : : QgsMesh *nativeMesh() SIP_SKIP;
224 : :
225 : : /**
226 : : * Returns native mesh (NULLPTR before rendering or calling to updateMesh)
227 : : *
228 : : * \note Not available in Python bindings
229 : : */
230 : : const QgsMesh *nativeMesh() const SIP_SKIP;
231 : :
232 : : /**
233 : : * Returns triangular mesh (NULLPTR before rendering or calling to updateMesh).
234 : : *
235 : : * If the parameter triangleSize is provided, among the base triangular mesh
236 : : * and the simplified triangular meshes, the one returned is which has the average triangle size just greater than triangleSize.
237 : : * The size of a triangle is the maximum between the height and the width of the triangle bounding box
238 : : * For default parameter (=0), it returns base triangular mesh.
239 : : * \param minimumTriangleSize is the average size criteria in canvas map units
240 : : * \returns triangular mesh, the layer keeps the ownership
241 : : * \note triangular size added in QGIS 3.14
242 : : * \note Not available in Python bindings
243 : : */
244 : : QgsTriangularMesh *triangularMesh( double minimumTriangleSize = 0 ) const SIP_SKIP;
245 : :
246 : : /**
247 : : * Returns the count of levels of detail of the mesh simplification
248 : : *
249 : : * \note Not available in Python bindings
250 : : * \since QGIS 3.18
251 : : */
252 : : int triangularMeshLevelOfDetailCount() const SIP_SKIP;
253 : :
254 : : /**
255 : : * Returns triangular corresponding to the index of level of details.
256 : : * If \a lodIndex is greater than the count of levels of detail, returns the last one (with lesser triangles)
257 : : * If \a lodIndex is lesser or equal to 0, returns the original triangular mesh
258 : : *
259 : : * \param lodIndex the level od detail index
260 : : *
261 : : * \note Not available in Python bindings
262 : : * \since QGIS 3.18
263 : : */
264 : : QgsTriangularMesh *triangularMeshByLodIndex( int lodIndex ) const SIP_SKIP;
265 : :
266 : : /**
267 : : * Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh
268 : : *
269 : : * \param transform Transformation from layer CRS to destination (e.g. map) CRS. With invalid transform, it keeps the native mesh CRS
270 : : *
271 : : * \since QGIS 3.14
272 : : */
273 : : void updateTriangularMesh( const QgsCoordinateTransform &transform = QgsCoordinateTransform() );
274 : :
275 : : /**
276 : : * Returns native mesh (NULLPTR before rendering)
277 : : *
278 : : * \note Not available in Python bindings
279 : : */
280 : : QgsMeshLayerRendererCache *rendererCache() SIP_SKIP;
281 : :
282 : : //! Returns renderer settings
283 : : QgsMeshRendererSettings rendererSettings() const;
284 : : //! Sets new renderer settings
285 : : void setRendererSettings( const QgsMeshRendererSettings &settings );
286 : :
287 : : /**
288 : : * Returns time format settings
289 : : *
290 : : * \since QGIS 3.8
291 : : */
292 : : QgsMeshTimeSettings timeSettings() const;
293 : :
294 : : /**
295 : : * Sets time format settings
296 : : *
297 : : * \since QGIS 3.8
298 : : */
299 : : void setTimeSettings( const QgsMeshTimeSettings &settings );
300 : :
301 : : /**
302 : : * Returns mesh simplification settings
303 : : *
304 : : * \since QGIS 3.14
305 : : */
306 : : QgsMeshSimplificationSettings meshSimplificationSettings() const SIP_SKIP;
307 : :
308 : : /**
309 : : * Sets mesh simplification settings
310 : : *
311 : : * \since QGIS 3.14
312 : : */
313 : : void setMeshSimplificationSettings( const QgsMeshSimplificationSettings &meshSimplificationSettings ) SIP_SKIP;
314 : :
315 : : /**
316 : : * Returns (date) time in hours formatted to human readable form
317 : : * \param hours time in double in hours
318 : : * \returns formatted time string
319 : : * \since QGIS 3.8
320 : : */
321 : : QString formatTime( double hours );
322 : :
323 : : /**
324 : : * Returns the dataset groups count handle by the layer
325 : : *
326 : : * \since QGIS 3.16
327 : : */
328 : : int datasetGroupCount() const;
329 : :
330 : : /**
331 : : * Returns the extra dataset groups count handle by the layer
332 : : *
333 : : * \since QGIS 3.16
334 : : */
335 : : int extraDatasetGroupCount() const;
336 : :
337 : : /**
338 : : * Returns the list of indexes of dataset groups handled by the layer
339 : : *
340 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
341 : : * In the layer scope, those indexes can be different from the data provider indexes.
342 : : *
343 : : * \since QGIS 3.16
344 : : */
345 : : QList<int> datasetGroupsIndexes() const;
346 : :
347 : : /**
348 : : * Returns the list of indexes of enables dataset groups handled by the layer
349 : : *
350 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
351 : : * In the layer scope, those indexes can be different from the data provider indexes.
352 : : *
353 : : * \since QGIS 3.16.3
354 : : */
355 : : QList<int> enabledDatasetGroupsIndexes() const;
356 : :
357 : : /**
358 : : * Returns the dataset groups metadata
359 : : *
360 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
361 : : * In the layer scope, those indexes can be different from the data provider indexes.
362 : : *
363 : : * \since QGIS 3.16
364 : : */
365 : : QgsMeshDatasetGroupMetadata datasetGroupMetadata( const QgsMeshDatasetIndex &index ) const;
366 : :
367 : : /**
368 : : * Returns the dataset count in the dataset groups
369 : : *
370 : : * \param index index of the dataset in the group
371 : : *
372 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
373 : : * In the layer scope, those indexes can be different from the data provider indexes.
374 : : *
375 : : * \since QGIS 3.16
376 : : */
377 : : int datasetCount( const QgsMeshDatasetIndex &index ) const;
378 : :
379 : : /**
380 : : * Returns the dataset metadata
381 : : *
382 : : * \param index index of the dataset
383 : : *
384 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
385 : : * In the layer scope, those indexes can be different from the data provider indexes.
386 : : *
387 : : * \since QGIS 3.16
388 : : */
389 : : QgsMeshDatasetMetadata datasetMetadata( const QgsMeshDatasetIndex &index ) const;
390 : :
391 : : /**
392 : : * Returns vector/scalar value associated with the index from the dataset
393 : : * To read multiple continuous values, use datasetValues()
394 : : *
395 : : * See QgsMeshDatasetMetadata::isVector() or QgsMeshDataBlock::type()
396 : : * to check if the returned value is vector or scalar
397 : : *
398 : : * Returns invalid value for DataOnVolumes
399 : : *
400 : : * \param index index of the dataset
401 : : * \param valueIndex index of the value
402 : : *
403 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
404 : : * In the layer scope, those indexes can be different from the data provider indexes.
405 : : *
406 : : * \since QGIS 3.16
407 : : */
408 : : QgsMeshDatasetValue datasetValue( const QgsMeshDatasetIndex &index, int valueIndex ) const;
409 : :
410 : : /**
411 : : * Returns N vector/scalar values from the index from the dataset
412 : : *
413 : : * See QgsMeshDatasetMetadata::isVector() or QgsMeshDataBlock::type()
414 : : * to check if the returned value is vector or scalar
415 : : *
416 : : * Returns invalid block for DataOnVolumes. Use QgsMeshLayerUtils::datasetValues() if you
417 : : * need block for any type of data type
418 : : *
419 : : * \param index index of the dataset
420 : : * \param valueIndex index of the value
421 : : * \param count number of values to return
422 : : *
423 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
424 : : * In the layer scope, those indexes can be different from the data provider indexes.
425 : : *
426 : : * \since QGIS 3.16
427 : : */
428 : : QgsMeshDataBlock datasetValues( const QgsMeshDatasetIndex &index, int valueIndex, int count ) const;
429 : :
430 : : /**
431 : : * Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes
432 : : *
433 : : * See QgsMeshDatasetMetadata::isVector() to check if the returned value is vector or scalar
434 : : *
435 : : * returns invalid block for DataOnFaces and DataOnVertices.
436 : : *
437 : : * \param index index of the dataset
438 : : * \param faceIndex index of the face
439 : : * \param count number of values to return
440 : : *
441 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
442 : : * In the layer scope, those indexes can be different from the data provider indexes.
443 : : *
444 : : * \since QGIS 3.16
445 : : */
446 : : QgsMesh3dDataBlock dataset3dValues( const QgsMeshDatasetIndex &index, int faceIndex, int count ) const;
447 : :
448 : : /**
449 : : * Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes
450 : : *
451 : : * See QgsMeshDatasetMetadata::isVector() to check if the returned value is vector or scalar
452 : : *
453 : : * returns invalid block for DataOnFaces and DataOnVertices.
454 : : */
455 : : bool isFaceActive( const QgsMeshDatasetIndex &index, int faceIndex ) const;
456 : :
457 : : /**
458 : : * Returns whether the faces are active for particular dataset
459 : : *
460 : : * \param index index of the dataset
461 : : * \param faceIndex index of the face
462 : : * \param count number of values to return
463 : : *
464 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
465 : : * In the layer scope, those indexes are different from the data provider indexes.
466 : : *
467 : : * \since QGIS 3.16
468 : : */
469 : : QgsMeshDataBlock areFacesActive( const QgsMeshDatasetIndex &index, int faceIndex, int count ) const;
470 : :
471 : : /**
472 : : * Interpolates the value on the given point from given dataset.
473 : : * For 3D datasets, it uses dataset3dValue(), \n
474 : : * For 1D datasets, it uses dataset1dValue() with \a searchRadius
475 : : *
476 : : * \note It uses previously cached and indexed triangular mesh
477 : : * and so if the layer has not been rendered previously
478 : : * (e.g. when used in a script) it returns NaN value
479 : : * \see updateTriangularMesh
480 : : *
481 : : * \param index dataset index specifying group and dataset to extract value from
482 : : * \param point point to query in map coordinates
483 : : * \param searchRadius the radius of the search area in map unit
484 : : * \returns interpolated value at the point. Returns NaN values for values
485 : : * outside the mesh layer, nodata values and in case triangular mesh was not
486 : : * previously used for rendering
487 : : *
488 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
489 : : * In the layer scope, those indexes are different from the data provider indexes.
490 : : *
491 : : * \since QGIS 3.4
492 : : */
493 : : QgsMeshDatasetValue datasetValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point, double searchRadius = 0 ) const;
494 : :
495 : : /**
496 : : * Returns the 3d values of stacked 3d mesh defined by the given point
497 : : *
498 : : * \note It uses previously cached and indexed triangular mesh
499 : : * and so if the layer has not been rendered previously
500 : : * (e.g. when used in a script) it returns NaN value
501 : : * \see updateTriangularMesh
502 : : *
503 : : * \param index dataset index specifying group and dataset to extract value from
504 : : * \param point point to query in map coordinates
505 : : * \returns all 3d stacked values that belong to face defined by given point. Returns invalid block
506 : : * for point outside the mesh layer or in case triangular mesh was not
507 : : * previously used for rendering or for datasets that do not have type DataOnVolumes
508 : : *
509 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
510 : : * In the layer scope, those indexes are different from the data provider indexes.
511 : : *
512 : : * \since QGIS 3.12
513 : : */
514 : : QgsMesh3dDataBlock dataset3dValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const;
515 : :
516 : : /**
517 : : * Returns the value of 1D mesh dataset defined on edge that are in the search area defined by point ans searchRadius
518 : : *
519 : : * \note It uses previously cached and indexed triangular mesh
520 : : * and so if the layer has not been rendered previously
521 : : * (e.g. when used in a script) it returns NaN value
522 : : * \see updateTriangularMesh
523 : : *
524 : : * \param index dataset index specifying group and dataset to extract value from
525 : : * \param point the center point of the search area
526 : : * \param searchRadius the radius of the searc area in map unit
527 : : * \returns interpolated value at the projected point. Returns NaN values for values
528 : : * outside the mesh layer and in case triangular mesh was not previously used for rendering
529 : : *
530 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
531 : : * In the layer scope, those indexes are different from the data provider indexes.
532 : : *
533 : : * \since QGIS 3.14
534 : : */
535 : : QgsMeshDatasetValue dataset1dValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point, double searchRadius ) const;
536 : :
537 : : /**
538 : : * Returns dataset index from datasets group depending on the time range.
539 : : * If the temporal properties is not active, returns invalid dataset index. This method is used for rendering mesh layer.
540 : : *
541 : : * \param timeRange the time range
542 : : * \param datasetGroupIndex the index of the dataset group
543 : : * \returns dataset index
544 : : *
545 : : * \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
546 : : *
547 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
548 : : * In the layer scope, those indexes are different from the data provider indexes.
549 : : *
550 : : * \since QGIS 3.14
551 : : */
552 : : QgsMeshDatasetIndex datasetIndexAtTime( const QgsDateTimeRange &timeRange, int datasetGroupIndex ) const;
553 : :
554 : : /**
555 : : * Returns dataset index from datasets group depending on the relative time from the layer reference time.
556 : : * Dataset index is valid even the temporal properties is inactive. This method is used for calculation on mesh layer.
557 : : *
558 : : * \param relativeTime the relative from the mesh layer reference time
559 : : * \param datasetGroupIndex the index of the dataset group
560 : : * \returns dataset index
561 : : *
562 : : * \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
563 : : *
564 : : * \note indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
565 : : * In the layer scope, those indexes are different from the data provider indexes.
566 : : *
567 : : * \since QGIS 3.16
568 : : */
569 : : QgsMeshDatasetIndex datasetIndexAtRelativeTime( const QgsInterval &relativeTime, int datasetGroupIndex ) const;
570 : :
571 : : /**
572 : : * Returns dataset index from active scalar group depending on the time range.
573 : : * If the temporal properties is not active, return the static dataset
574 : : *
575 : : * \param timeRange the time range
576 : : * \returns dataset index
577 : : *
578 : : * \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
579 : : *
580 : : * \since QGIS 3.14
581 : : */
582 : : QgsMeshDatasetIndex activeScalarDatasetAtTime( const QgsDateTimeRange &timeRange ) const;
583 : :
584 : : /**
585 : : * Returns dataset index from active vector group depending on the time range
586 : : * If the temporal properties is not active, return the static dataset
587 : : *
588 : : * \param timeRange the time range
589 : : * \returns dataset index
590 : : *
591 : : * \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
592 : : *
593 : : * \since QGIS 3.14
594 : : */
595 : : QgsMeshDatasetIndex activeVectorDatasetAtTime( const QgsDateTimeRange &timeRange ) const;
596 : :
597 : : /**
598 : : * Sets the static scalar dataset index that is rendered if the temporal properties is not active
599 : : *
600 : : * \param staticScalarDatasetIndex the scalar data set index
601 : : *
602 : : * \since QGIS 3.14
603 : : */
604 : : void setStaticScalarDatasetIndex( const QgsMeshDatasetIndex &staticScalarDatasetIndex ) SIP_SKIP;
605 : :
606 : : /**
607 : : * Sets the static vector dataset index that is rendered if the temporal properties is not active
608 : : *
609 : : * \param staticVectorDatasetIndex the vector data set index
610 : : *
611 : : * \since QGIS 3.14
612 : : */
613 : : void setStaticVectorDatasetIndex( const QgsMeshDatasetIndex &staticVectorDatasetIndex ) SIP_SKIP;
614 : :
615 : : /**
616 : : * Returns the static scalar dataset index that is rendered if the temporal properties is not active
617 : : *
618 : : * \since QGIS 3.14
619 : : */
620 : : QgsMeshDatasetIndex staticScalarDatasetIndex() const;
621 : :
622 : : /**
623 : : * Returns the static vector dataset index that is rendered if the temporal properties is not active
624 : : *
625 : : * \since QGIS 3.14
626 : : */
627 : : QgsMeshDatasetIndex staticVectorDatasetIndex() const;
628 : :
629 : : /**
630 : : * Sets the reference time of the layer
631 : : *
632 : : * \param referenceTime the reference time
633 : : *
634 : : * \since QGIS 3.14
635 : : */
636 : : void setReferenceTime( const QDateTime &referenceTime );
637 : :
638 : : /**
639 : : * Sets the method used to match the temporal dataset from a requested time, see activeVectorDatasetAtTime()
640 : : *
641 : : * \param matchingMethod the matching method
642 : : *
643 : : * \since QGIS 3.14
644 : : */
645 : : void setTemporalMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );
646 : :
647 : : /**
648 : : * Returns the position of the snapped point on the mesh element closest to \a point intersecting with
649 : : * the searching area defined by \a point and \a searchRadius
650 : : *
651 : : * For vertex, the snapped position is the vertex position
652 : : * For edge, the snapped position is the projected point on the edge, extremity of edge if outside the edge
653 : : * For face, the snapped position is the centroid of the face
654 : : * The returned position is in map coordinates.
655 : : *
656 : : * \note It uses previously cached and indexed triangular mesh
657 : : * and so if the layer has not been rendered previously
658 : : * (e.g. when used in a script) it returns empty QgsPointXY
659 : : * \see updateTriangularMesh
660 : : *
661 : : * \param elementType the type of element to snap
662 : : * \param point the center of the search area in map coordinates
663 : : * \param searchRadius the radius of the search area in map units
664 : : * \return the position of the snapped point on the closest element, empty QgsPointXY if no element of type \a elementType
665 : : *
666 : : * \since QGIS 3.14
667 : : */
668 : : QgsPointXY snapOnElement( QgsMesh::ElementType elementType, const QgsPointXY &point, double searchRadius );
669 : :
670 : : /**
671 : : * Returns the root items of the dataset group tree item
672 : : *
673 : : * \return the root item
674 : : *
675 : : * \since QGIS 3.14
676 : : */
677 : : QgsMeshDatasetGroupTreeItem *datasetGroupTreeRootItem() const;
678 : :
679 : : /**
680 : : * Sets the root items of the dataset group tree item.
681 : : * Changes active dataset groups if those one are not enabled anymore :
682 : : *
683 : : * - new active scalar dataset group is the first root item enabled child
684 : : * - new active vector dataset group is none
685 : : *
686 : : * Doesn't take ownership of the pointed item, the root item is cloned.
687 : : *
688 : : * \param rootItem the new root item
689 : : *
690 : : * \since QGIS 3.14
691 : : */
692 : : void setDatasetGroupTreeRootItem( QgsMeshDatasetGroupTreeItem *rootItem );
693 : :
694 : : /**
695 : : * Reset the dataset group tree item to default from provider
696 : : *
697 : : * \since QGIS 3.14
698 : : */
699 : : void resetDatasetGroupTreeItem();
700 : :
701 : : /**
702 : : * Returns the first valid time step of the dataset groups, invalid QgInterval if no time step is present
703 : : *
704 : : * \since QGIS 3.14
705 : : */
706 : : QgsInterval firstValidTimeStep() const;
707 : :
708 : : /**
709 : : * Returns the relative time of the dataset from the reference time of its group
710 : : *
711 : : * \since QGIS 3.16
712 : : */
713 : : QgsInterval datasetRelativeTime( const QgsMeshDatasetIndex &index );
714 : :
715 : : /**
716 : : * Returns the relative time (in milliseconds) of the dataset from the reference time of its group
717 : : *
718 : : * \since QGIS 3.16
719 : : */
720 : : qint64 datasetRelativeTimeInMilliseconds( const QgsMeshDatasetIndex &index );
721 : :
722 : : public slots:
723 : :
724 : : /**
725 : : * Sets the coordinate transform context to \a transformContext.
726 : : *
727 : : * \since QGIS 3.8
728 : : */
729 : : void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
730 : :
731 : : signals:
732 : :
733 : : /**
734 : : * Emitted when active scalar group dataset is changed
735 : : *
736 : : * \since QGIS 3.14
737 : : */
738 : : void activeScalarDatasetGroupChanged( int index );
739 : :
740 : : /**
741 : : * Emitted when active vector group dataset is changed
742 : : *
743 : : * \since QGIS 3.14
744 : : */
745 : : void activeVectorDatasetGroupChanged( int index );
746 : :
747 : : /**
748 : : * Emitted when time format is changed
749 : : *
750 : : * \since QGIS 3.8
751 : : */
752 : : void timeSettingsChanged( );
753 : :
754 : : private: // Private methods
755 : :
756 : : /**
757 : : * Returns TRUE if the provider is in read-only mode
758 : : */
759 : 0 : bool isReadOnly() const override {return true;}
760 : :
761 : : /**
762 : : * Binds layer to a specific data provider
763 : : * \param provider provider key string, must match a valid QgsMeshDataProvider key. E.g. "mesh_memory", etc.
764 : : * \param options generic provider options
765 : : * \param flags provider flags since QGIS 3.16
766 : : */
767 : : bool setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
768 : :
769 : : #ifdef SIP_RUN
770 : : QgsMeshLayer( const QgsMeshLayer &rhs );
771 : : #endif
772 : :
773 : : void fillNativeMesh();
774 : : void assignDefaultStyleToDatasetGroup( int groupIndex );
775 : : void setDefaultRendererSettings( const QList<int> &groupIndexes );
776 : : void createSimplifiedMeshes();
777 : : int levelsOfDetailsIndex( double partOfMeshInView ) const;
778 : :
779 : : bool hasSimplifiedMeshes() const;
780 : :
781 : : //! Changes scalar settings for classified scalar value (information about is in the metadata
782 : : void applyClassificationOnScalarSettings( const QgsMeshDatasetGroupMetadata &meta, QgsMeshRendererScalarSettings &scalarSettings ) const;
783 : :
784 : : private slots:
785 : : void onDatasetGroupsAdded( const QList<int> &datasetGroupIndexes );
786 : :
787 : : private:
788 : : //! Pointer to data provider derived from the abastract base class QgsMeshDataProvider
789 : : QgsMeshDataProvider *mDataProvider = nullptr;
790 : :
791 : : std::unique_ptr<QgsMeshDatasetGroupStore> mDatasetGroupStore;
792 : :
793 : : //! Pointer to native mesh structure, used as cache for rendering
794 : : std::unique_ptr<QgsMesh> mNativeMesh;
795 : :
796 : : //! Pointer to derived mesh structures (the first one is the base mesh, others are simplified meshes with decreasing level of detail)
797 : : std::vector<std::unique_ptr<QgsTriangularMesh>> mTriangularMeshes;
798 : :
799 : : //! Pointer to the cache with data used for last rendering
800 : : std::unique_ptr<QgsMeshLayerRendererCache> mRendererCache;
801 : :
802 : : //! Renderer configuration
803 : : QgsMeshRendererSettings mRendererSettings;
804 : :
805 : : //! Time format configuration
806 : : QgsMeshTimeSettings mTimeSettings;
807 : :
808 : : //! Simplify mesh configuration
809 : : QgsMeshSimplificationSettings mSimplificationSettings;
810 : :
811 : : QgsMeshLayerTemporalProperties *mTemporalProperties;
812 : :
813 : : int mStaticScalarDatasetIndex = 0;
814 : : int mStaticVectorDatasetIndex = 0;
815 : :
816 : : int closestEdge( const QgsPointXY &point, double searchRadius, QgsPointXY &projectedPoint ) const;
817 : :
818 : : //! Returns the exact position in map coordinates of the closest vertex in the search area
819 : : QgsPointXY snapOnVertex( const QgsPointXY &point, double searchRadius );
820 : :
821 : : //!Returns the position of the projected point on the closest edge in the search area
822 : : QgsPointXY snapOnEdge( const QgsPointXY &point, double searchRadius );
823 : :
824 : : //!Returns the position of the centroid point on the closest face in the search area
825 : : QgsPointXY snapOnFace( const QgsPointXY &point, double searchRadius );
826 : :
827 : : void updateActiveDatasetGroups();
828 : : };
829 : :
830 : : #endif //QGSMESHLAYER_H
|