New point clouds and mesh features in QGIS 3.36

FEBRUARY 05, 2024 3d mesh point cloud qgis

QGIS 3.36 is round the corner and as usual, there will be several new exciting features with the new release. Below is the list of features our team has added to the new release. This was made possible by generous funding from clients.

Render point clouds as a surface in 2D map views

Point clouds are rendered as individual points by default. Depending on the zoom level and density of the points, you might not be able to get a full picture of the map.

Rendering points as surface enables you to have a better understanding of the data before trying to do any analysis or processing. This has been possible in 3D map views for a couple of QGIS releases, now we have added the functionality also in 2D map views.

The feature generates a surface using triangulation on-the-fly from the points using the same symbology. Below you can see the difference between a point cloud rendered as individual points and rendered as a surface:

Point clouds as surface

Point clouds as individual points vs. as a TIN surface

The good news is that rendering as a surface also works well with global map shading, allowing users to get a nice hillshade:

Point clouds as surface with hillshade with hillshade

Point clouds as surface with hillshade

To enable this feature, you need to check the option for Render as a Surface (Triangulate) under the Layer Styling panel.

Point clouds styling panel

Settings to display point clouds as surface

Pro-tip: if the on-the-fly rendering as a surface takes too long to render, try increasing the Maximum error: for example 0.6 mm instead of the default 0.3 mm.

Flexible styling of classes

Previously, point cloud data visualisation in QGIS was limited to rendering all points with a uniform size and opacity. This made it difficult to differentiate between different point classes and highlight specific features of interest. To address this issue, we have introduced a new feature that allows users to customise the point size and opacity for each point cloud data class. This provides a flexible way for visualising point cloud data, allowing users to highlight specific point classes, e.g. by increasing the point size.

Assigning size and opacity to each point cloud class

Assigning size and opacity to each point cloud class

Point clouds with different sizes and opacity levels

Point clouds with different sizes and opacity levels

Set 3D map view extent in 2D map

Effectively navigating and visualising large-scale 3D datasets can be challenging on PCs with limited resources. To address this issue, we introduced a new feature that allows users to interactively limit the 3D scene, enabling them to focus on specific areas of interest. This new feature, conveniently accessible from the toolbar, eliminates the need for tedious manual entry of coordinates for bounding boxes. Instead, users can simply drag and draw a box around the desired area, instantly restricting the 3D scene to that specific extent. This interactive approach significantly enhances the user experience and streamlines the process of exploring and analysing 3D data:

Interactive selection of 3D map scene from 2D map

Interactive selection of 3D map scene from 2D map

Python API for 3D views

Creating and viewing 3D maps in QGIS with the correct camera location and angle, scene tilt, light, and other parameters can be a time-consuming and error-prone process. This is because it requires users to manually adjust these settings, often through trial and error. However, with the introduction of the new 3D map view API in QGIS, Python plugins can now automate this process, making it much easier, consistent and more efficient to create high-quality 3D maps that are visually appealing and informative.

# List all open 3D map canvases
iface.mapCanvases3D()
# [<qgis._3d.Qgs3DMapCanvas object at 0x7f23491b5e10>]
canvas = iface.mapCanvases3D()[0]

Now let’s try something more complicated:

# Let's change some settings!
ms = canvas.mapSettings()
ms.setEyeDomeLightingEnabled(True)
ms.setBackgroundColor(QColor('beige'))
ms.setTerrainMapTheme('dtm')
ms.setFieldOfView(110)

# Move the camera to look at specific map coordinates in layer's CRS
cam = canvas.cameraController()
mapPoint = QgsVector3D(-498175.92, -1205400.58, 210)
worldPoint = ms.mapToWorldCoordinates(mapPoint)
cam.setLookingAtPoint(worldPoint, 60, 45, 100)

# Create four new 3D map views
c1 = iface.createNewMapCanvas3D('South View')
c2 = iface.createNewMapCanvas3D('West View')
c3 = iface.createNewMapCanvas3D('North View')
c4 = iface.createNewMapCanvas3D('East View')

# Apply settings to all open 3D map views
for canvas in iface.mapCanvases3D():
	canvas.mapSettings().setEyeDomeLightingEnabled(True)

# Define a camera pose to update the views' cameras
pose = QgsCameraPose()
pose.setCenterPoint(QgsVector3D(0, 210, 0))  # This is in 3D world coordinates
pose.setDistanceFromCenterPoint(100)
pose.setPitchAngle(75)  # Tilt the camera by 75 degrees
pose.setHeadingAngle(0)  # Looking towards North
c1.cameraController().setCameraPose(pose)
pose.setHeadingAngle(90)  # Towards East
c2.cameraController().setCameraPose(pose)
pose.setHeadingAngle(180)  # Towards South
c3.cameraController().setCameraPose(pose)
pose.setHeadingAngle(270)  # Towards West
c4.cameraController().setCameraPose(pose)

# We can set the 3D map views 2D extent to always match the main 2D canvas one
# Our 3D views get updated while zooming/panning the main 2D canvas
canvas = iface.mapCanvas()
canvas.extentsChanged.connect(lambda :c1.mapSettings().setExtent(canvas.extent()))
canvas.extentsChanged.connect(lambda :c2.mapSettings().setExtent(canvas.extent()))
canvas.extentsChanged.connect(lambda :c3.mapSettings().setExtent(canvas.extent()))
canvas.extentsChanged.connect(lambda :c4.mapSettings().setExtent(canvas.extent()))

Changing 3D view settings through Python

Changing 3D view settings through Python

More point clouds attributes

LAS/LAZ/COPC point clouds have a classificationFlags attribute that stores four types of information (Synthetic, Keypoint, Withheld, and Overlap) in a single value. This saves space, but it makes it difficult to use the information for styling or filtering, as you need to write complex expressions.

To make it easier to use, we are following the approach introduced in PDAL 2.6: the classificationFlags attribute gets replaced with four separate attributes: Synthetic, Keypoint, Withheld, and Overlap. This will make it easier to include these attributes in styling and filtering expressions.

Performance enhancement for rendering

To improve the performance of point cloud rendering in QGIS, we introduced a new caching system to minimise the need for repeated decompression of LAS node data while panning or zooming. This caching mechanism efficiently stores decompressed points for each unique combination of layer URI, node, requested attributes, filter extent, and filter expression. This enables rapid rendering of previously cached nodes, significantly enhancing the overall rendering performance in 2D and 3D maps.

Performance can vary depending on actual data, but on a local sample COPC file, it renders 7 times faster with this change.

Labels for mesh layer

Viewing mesh data has been possible through styling, plotting or using the Identify tool. But now you can also create labels on mesh surfaces or vertices similar to vector layers.

To display labels for your mesh data, simply open the styling panel and enable labels for:

  • Labels on Vertices
  • Labels on Surfaces

Label settings for mesh layers

Label settings for mesh layers

Below is an example of mesh Z values at vertices (yellow) and mesh areas at cell centre (purple):

Example of labels on a mesh layer

Example of labels on a mesh layer

Want more changes in QGIS?

Do you want to see more improvements and new features in QGIS? Do not hesitate to contact us to discuss your requiremnets.


Posted by Martin Dobias, Stefanos Natsis, Saber Razmjooei