qgis / QGIS-Enhancement-Proposals

QEP's (QGIS Enhancement Proposals) are used in the process of creating and discussing new enhancements for QGIS
117 stars 37 forks source link

Profile Tool Pt 1 - Layer/Project level elevation settings #246

Open nyalldawson opened 2 years ago

nyalldawson commented 2 years ago

QGIS Enhancement: Profile Tool Pt 1 - Layer/Project level elevation settings

Date 2022/02/09

Author Nyall Dawson (@nyalldawson )

Contact nyall dot dawson at gmail dot com

maintainer @nyalldawson

Version QGIS 3.26

Summary

(This is part 1 of the larger project to implement an inbuilt profile tool in QGIS, as part of https://www.lutraconsulting.co.uk/crowdfunding/elevation-pointcloud-enhancements-qgis/)

This proposal concerns a reworking of the way elevation data is handled in QGIS, with the goal of moving these properties from the renderer level up to the layer and project level.

Current Situation

Depending on the layer type, there are different ways in which elevation is handled in QGIS.

Vector layers:

Elevation is currently set as part of the layer's 3d renderer:

polygon

image

line

image

point

image

Point Cloud layers

Elevation properties are set on a layer level:

image

Raster layers

Limited support is available for setting elevation for ONE raster at a time in a 3d view, by assigning that raster as the terrain for a scene:

image

Mesh layers

Mesh layers have a mix of support -- a mesh layer can be assigned as a terrain for a scene (just like rasters), but there is also the capability to set some elevation properties on a 3d renderer level:

image

Scenes

In addition to layer specific elevation settings, QGIS also supports elevation properties on a per-scene basis. This is done through a 3D map's "Terrain" settings. Options include:

These scene level properties potentially affect how layer level elevation properties are handled, as features from vector layers can be set to take a relative elevation with respect to the scene's terrain.

Proposed Solution

While the current setup works sufficiently well for the sole purpose elevation data is currently used for in QGIS (3d map visualisation), in order to make a unified profile tool possible it is necessary to move the various elevation settings up to layer and project level settings and out of the 3d framework.

Additionally, in the case of vector layers, it is restrictive to mix the elevation related properties along with the 3d symbol properties for a layer. Elevation properties inherently apply to a particular layer, while other 3d symbol properties (e.g. the material settings) are generic and can be reused across different layers. By splitting the two concepts we will make it possible to create more generic, reusable 3d symbols (See more details regarding this below).

Project level settings

Some of the existing 3d terrain settings will be moved up to a project level. Specifically, the ability to select a "base terrain" type for the whole project. The project terrain settings will be moved to reside within a new tab in the Project Properties dialog, and will be accessible via a new QgsProjectElevationProperties class attached to a QgsProject object.

It is proposed that only the flat, raster and mesh terrain options will be available for project elevation (i.e. no Online terrain source, with this option only being available in 3d scenes).

While new 3d maps will automatically inherit the relevant terrain settings from the project elevation settings, these can still be modified manually on a 3d map by 3d map basis if desired.

Layer level settings

It is proposed that the approach used by point cloud layers be extended to cover vector, raster and mesh layers. Specifically, point clouds layers store elevation related properties in a QgsMapLayerElevationProperties subclass QgsPointCloudLayerElevationProperties, which is attached to each point cloud layer and accessible via layer->elevationProperties().

New subclasses of QgsMapLayerElevationProperties will be created for vector, raster and mesh layers, and will always be attached to their corresponding layer types. More details regarding these specific type are below:

QgsRasterLayerElevationProperties

This subclass will have properties available for:

Note that potentially MANY layers in a single project may have their raster layer elevation properties enabled! (Thus allowing all these layers to be visible on profile plots).

QgsVectorLayerElevationProperties

This subclass will contain the elevation related properties which are currently part of QgsAbstract3DSymbol:

QgsMeshLayerElevationProperties

This subclass will have properties available for:

Other considerations

Relationship to 3d maps and 3d symbols

Currently, NO changes will be made to the interface for 3d scene terrain settings or for the 3d symbol properties for layers. While it is possible (and ultimately desirable) that we could remove the elevation related properties from the 3d renderer settings for layers and ALWAYS use the layer level settings for these, such a change is not in scope for this project and will be deferred to a later body of work.

Instead, newly created 3d maps will automatically inherit the project level elevation settings for their terrain settings, and layers which are set to a new 3d renderer will also automatically inherit their 3d renderer's elevation related settings from the layer's general elevation properties.

The rationale behind this decision is:

Accordingly, these potential changes would be best made in breaking release such as QGIS 4.0, (if at all).

Migration of settings from existing projects

As noted above, no automatic migration of settings from 3d map -> project or layer level will be undertaken. Users will need to manually setup their project and layer level elevation settings prior to utilising these layers in the profile tool.

uclaros commented 2 years ago

Great analysis, +1 all the way! A minor note:

Currently, NO changes will be made to the interface for 3d scene terrain settings or for the 3d symbol properties for layers. While it is possible (and ultimately desirable) that we could remove the elevation related properties from the 3d renderer settings for layers and ALWAYS use the layer level settings for these, such a change is not in scope for this project and will be deferred to a later body of work.

Now that we have better control over a 3d view's lifetime using the 3d view manager, I don't think it is desirable to remove the elevation related properties from the 3d renderer settings. Your current proposed behavior looks perfect, since it will use a default terrain layer for new views (users will not have to select one for each view!!) but also allow to have different views with different terrain layers within the same project. That would make possible to have two 3d views open and compare for example the before-after of an excavation site!

wonder-sk commented 2 years ago

+1 to the proposal!

As for terrain setup in 3D views, I think we could probably also remove the "online" terrain type now that XYZ raster tiles can be interpreted as DEM as well (terrarium or maptiler). The "online" terrain type is half-baked anyway as e.g. altitude clamping does not work with it, so removing it should not hurt much...

nyalldawson commented 2 years ago

@wonder-sk

I think we could probably also remove the "online" terrain type now that XYZ raster tiles can be interpreted as DEM as well (terrarium or maptiler)

That's a good point! I'd suggest we just hide the option from the combobox, so that existing projects keep working without issue

nirvn commented 2 years ago

The online terrain type had one feature the DEM type doesn't have ATM: it respects the project extent. That'll need to be implemented for a XYZ raster tiles layer as DEM layer to fully match what we could do with online terrain type.

vcloarec commented 2 years ago

looks very good!

A detail, for mesh layer, I would suggest to set default to vertices elevation if provided. But for now, it is not easy to recognize if a dataset group represents this elevation, except during mesh editing where the only dataset group is a virtual one that link to the vertex Z values. I think it could be an opportunity to clarify elevation for mesh layer by introducing a virtual dataset group pointing to the vertices Z values if provided, even if not in editing mode. Indeed MDAL transforms these vertices Z value in dataset group but not in a very explicit way (only the name of the dataset group can be used to recognize it, and could depend on driver), and the same Z values are both on the dataset group and on the vertices (waste of memory). It might be beneficial to add a flag from the provider to specify if terrain elevation is provided in vertices, and in that case, QGIS could create a virtual dataset group pointing to Z value of vertices, and this dataset group would be the default one for QgsMeshLayerElevationProperties. Then MDAL would no need anymore to convert this Z values in dataset group.

Just ideas in mind...

nyalldawson commented 2 years ago

@nirvn

The online terrain type had one feature the DEM type doesn't have ATM: it respects the project extent. That'll need to be implemented for a XYZ raster tiles layer as DEM layer to fully match what we could do with online terrain type.

Is this to prevent the 3d scene extent becoming the global xyz layer extent?

If so, I'd propose that we introduce a QgsMapLayer::MapLayerProperty flag value for "basemap", which would be set for (automatically) for any layers which we can reasonably flag as a basemap style layer (i.e. global xyz or vector tile layers). If a layer has this flag present, then we ignore its reported extent when calculating the extent of a group of layers (such as when zooming a project to full extent or when calculating the extent of a 3d scene)

P-SLISSE commented 2 years ago

As you are renewing project elevation settings, I propose to add one useful setting. I work with huge databases (vector, raster) covering 340 km². Often, users need to see a small part of the territory in 3D, but with high accuracy. With the new setting, users are able to limit the 3D rendering to a bounding volume (Xmin, Xmax, Ymin, Ymax, Zmin, Zmax or Xcenter, Ycenter, length, width, heigth). Default setting can be 'data extent'.

nyalldawson commented 2 years ago

@P-SLISSE

With the new setting, users are able to limit the 3D rendering to a bounding volume

That's already possible (well, for a 2d bounding box). Check the Project Full Extent setting in Project Properties -> View Settings

P-SLISSE commented 2 years ago

@P-SLISSE

With the new setting, users are able to limit the 3D rendering to a bounding volume

That's already possible (well, for a 2d bounding box). Check the Project Full Extent setting in Project Properties -> View Settings

Thanks for the tip, I'm working with QGis 3.22 Unfortunately, setting the project Full Extent do not seem to work in the 3DView when 'extrusion' is enabled. My exemple : 1) I set the project full extent with coordinates to limit the view extent 2) I have my buildings in 2d with an attribute containing the building height. In the 2D view, the all data is visible, without clipping from my extent 3) I open a 3D view with flat terrain In the 3D view, only data inside my extent is visible : Great ! 4) I set 3DView to my building data so it is extruded using the value of height In this case, the extent doesnt work and I see all the data inside and outside the extent

Did I wrongly uses the extent settings ?

Please apologize for my poor frenchy english