class: center, top  # 29 OCTOBER 2026 ## INBO coding club Herman Teirlinck
01.19 Paul Van Ostaijen --- class: left, top # Reminders 1. Did we confirm the room reservation on the _roomie_? 2. Did we start the recording? --- class: left, top # Do you know that? Thanks to Sebastiaan for the new INBO tutorial: ["Exploring the potential of aerial LiDAR: introduction to lidR"](https://tutorials.inbo.be/tutorials/r_lidr/)! And by extension, a huge thanks đ to all contributors of our [INBO tutorial](https://tutorials.inbo.be/) website. .center[] --- class: center, middle  --- class: center, top ### How to get started? Check the [Each session setup](https://inbo.github.io/coding-club/gettingstarted.html#each-session-setup) to get started. ### First time coding club? Check the [First time setup](https://inbo.github.io/coding-club/gettingstarted.html#first-time-setup) section to setup. --- class: left, top 
Especially for people online: open the hackmd (see next slide) and place your name under Participants: stars (`*`) will be your yellow stickers. Basic principle doesn't change. --- class: center, top ### Share your code during the coding session! Go to https://hackmd.io/gIGB6eFUQxW55_W-SYXaxA?both
--- class: left, top # QGIS - [QGIS](https://qgis.org/en/site/) is a free and open source geographic information system application. - Typically described as the open source version of [ArcGIS](https://www.arcgis.com/index.html). - QGIS allows to create, edit, visualise, analyse and publish geospatial information. - The most recent version at the moment of writing (2026-10-26) is 4.2.3 'Belém do Parå'. It was released on 2026-09-25. The most recent long term version* is 3.44 (that's what I have installed on my laptop).
\* The long term version is a **stable** release, maintained for a longer period of time than the standard edition. The term is typically reserved for open-source software, where it describes a software edition that is supported for months or years longer than the software's standard edition. Source: Wikipedia contributors. (2026, August 10). Long-term support. In Wikipedia, The Free Encyclopedia. Retrieved 14:09, October 28, 2026, from https://en.wikipedia.org/w/index.php?title=Long-term_support&oldid=1368613073
--- class: left, top # What is qgisprocess? - [qgisprocess](https://r-spatial.github.io/qgisprocess/index.html) is an R package - it wraps the standalone [qgis_process command-line utility](https://docs.qgis.org/3.44/en/docs/user_manual/processing/standalone.html) - it allows you to run processing algorithms and models (built-in or provided by plugins) directly from R without you starting the qgis_process command-line utility or the QGIS Desktop. --- class: left, top # Why should I use it? - Expand geospatial processing abilities in R - Still have all other processing capabilities of R - Reproducibility - No QGIS project needed - Unified interface to QGIS natice algorithms and external processing providers/plugins, e.g. GRASS GIS, SAGA, GDAL
Source: [Floris' presentation](https://florisvdh.github.io/foss4g-2023-qgisprocess/#17) at FOSS4G 2023
--- class: center, top  Download cheatsheet in [English](https://github.com/inbo/coding-club/blob/master/cheat_sheets/20231214_cheat_sheet_qgisprocess_en.pdf) or in [Spanish](https://github.com/inbo/coding-club/blob/master/cheat_sheets/20231214__cheat_sheet_qgisprocess_es.pdf) --- class: left, top # Data and scripts description - `water`: [20261029_watersurfaces_hab.gpkg](https://github.com/inbo/coding-club/tree/master/data/20261029/20261029_watersurfaces_hab.gpkg). Standing water Natura 2000 habitat types (2190_a and 31xx) and regionally important biotopes (rbbah) in Flanders
\*
- `hab_springs`: [20261029_habitatsprings_flanders.geojson](https://github.com/inbo/coding-club/tree/master/data/20261029/20261029_habitatsprings_flanders.geojson). A geospatial collection of points that corresponds with the presence of the Natura 2000 habitat type 7220 (Petrifying springs with tufa formation (Cratoneurion)) in springs and streaming water segments in Flanders.
\*\*
- `hydrocotyle_ranunculoides`: [20261029_hydrocotyle_ranunculoides.geojson](https://github.com/inbo/coding-club/blob/master/data/20261029/20261029_hydrocotyle_ranunculoides.geojson). Dataset with GBIF observations of floating pennywort (EN) - grote waternavel (NL) (_Hydrocotyle_ranunculoides_) in Flanders in 2025.
\*\*\*
\* Westra, T., Vanderhaeghe, F., & Herr, C. (2021). Map of standing water habitat types and regionally important biotopes in Flanders (watersurfaces_hab_v4) [Data set]. Zenodo. https://doi.org/10.5281/zenodo.4915849.
\*\* Derived from "Oosterlynck, P. (2020). Distribution of the Natura 2000 habitat type 7220 (Cratoneurion) in Flanders and Brussels Capital Region, Belgium (version 2020) (habitatsprings_2020v2) [Dataset]. Zenodo. https://doi.org/10.5281/zenodo.3784149".
\*\*\* Source: GBIF.org (26 October 2026) GBIF Occurrence Download https://doi.org/10.15468/dl.t2z7c6
--- class: left, top # Data and scripts description - `land_use`: [20261029_land_use_nara_2016_100m.tif](https://github.com/inbo/coding-club/blob/main/data/20261029/20261029_land_use_nara_2016_100m.tif). A categorical raster of land use of Flanders with 9 land use categories. Thanks, NARA team! - `prot_areas`: [20261029_natura2000_protected_areas.gpkg](https://github.com/inbo/coding-club/blob/main/data/20261029/20261029_natura2000_protected_areas.gpkg). A geopackage with NATURA2000 protected areas - [20261029_challenges.R](https://github.com/inbo/coding-club/blob/master/src/20261029/20261029_challenges.R): a R script to start with. --- class: left, top # Load packages Before installing and loading qgisprocess, we load some other packages (if needed, install them) we will use today: ```r library(tidyverse) library(sf) # to deal with spatial vector data library(terra) # to deal with raster data ``` Optional: for visualization purposes, you could use the `mapview()` function from [mapview](https://r-spatial.github.io/mapview/index.html) R package. Install it, if needed, and load it: ```r library(mapview) ``` --- class: left, top # Challenge 0 - Install the package: install.packages("qgisprocess") - Load the package: ```r > library(qgisprocess) Attempting to load the package cache ... Success! QGIS version: 3.30.3-'s-Hertogenbosch Having access to 349 algorithms from 4 QGIS processing providers. Run `qgis_configure(use_cached_data = TRUE)` to reload cache and get more details. Warning message: package âqgisprocessâ was built under R version 4.3.1 ``` - Algorithms come from different processing providers*. Which ones? ```r > qgis_providers() # A tibble: 4 Ă 3 provider provider_title algorithm_count
1 gdal GDAL 56 2 qgis QGIS 50 3 3d QGIS (3D) 1 4 native QGIS (native c++) 242 ```
* The list of providers and the number of algorithms they provide can be different than what shown in this slide. However, you should have the QGIS `native` and `qgis` providers, for sure.
--- class: left, top # Challenge 0 Let's run the [example](https://r-spatial.github.io/qgisprocess/index.html#example) on qgisprocess homepage. Use the buffer algorithm on the New York City shapefile to create a buffer area around the city. ```r input <- sf::read_sf(system.file("shape/nc.shp", package = "sf")) plot(sf::st_geometry(input)) # Not present in example online result <- qgis_run_algorithm( "native:buffer", INPUT = input, DISTANCE = 1, DISSOLVE = TRUE ) result #>
#> List of 1 #> $ OUTPUT: 'qgis_outputVector' chr "...\\Temp\\Rtmpcx8CAj\\file2fa446803f36\\file2fa47e4039a3.gpkg" output_sf <- sf::st_as_sf(result) plot(sf::st_geometry(output_sf)) # Use mapview if you want to visualize spatial data on a map library(mapview) mapview(output_sf) + mapview(input) ``` --- background-image: url(/assets/images/background_challenge_1.png) class: left, top # Challenge 1 1. In challenge 0 we specified (a little blindly) some arguments, e.g. `DISSOLVE = TRUE`. What does this argument do? What happens if you set `DISSOLVE = FALSE`? How can you get a description of the chosen algorithm? How can you retrieve information about all the arguments allowed by the algorithm? Or about the generated output? Hint: use the cheat sheet! 2. Calculate the âshortestâ path (lines) between the `hab_springs` points and the nearest watersurface `water`. 3. Calculate the âshortestâ paths (lines) between the polygons `water` and the `hab_springs` points. 4. We are all pipe (`%>%` or `|>`)* lovers, aren't we? Can you use `qgis_run_algorithm()` in a pipe? No. How to combine qgisprocess and pipes? Hint: check the cheat sheet. For challenge 2, 3 and 4: you can check the output by transforming it to an sf object, e.g. `sf::st_as_sf(output2)`, and then visualizing it, e.g. `mapview(output2) + mapview(hab_springs) + mapview(water)`.
\* The new R pipe `|>` is available with R 4.0 or higher and is embedded in R itself, no need to load any package.
--- class: left, top # INTERMEZZO 1 - qgisprocess vs sf/terra The [sf](https://r-spatial.github.io/sf/) package is widely used in geospatial R community. We use it often, see e.g. the INBO coding club ["Spatial data in R"](https://inbo.github.io/coding-club/sessions/20260126_spatial_data_in_r.html#1), 2026-01-26. The same goes for the [terra](https://rspatial.github.io/terra/index.html) package, the mainstream package to work with rasters. See e.g. the INBO coding club ["rasters in R"](https://inbo.github.io/coding-club/sessions/20260528_rasters_in_r.html#1), 2026-05-28. When should I use qgisprocess instead of native sf/terra functions? - Not all QGIS algorithms have a sf/terra counterpart - Work with big spatial files: QGIS algorithms are typically faster - You are a QGIS pro and don't want to/have time to learn sf/terra or other packages --- class: left, top # INTERMEZZO 1 - qgisprocess vs sf/terra Example: calculate buffers at high resolution ``` library(tictoc) > tic("buffer via sf") > buffer_via_sf <- sf::st_buffer(water, nQuadSegs = 5000, dist = 100) > toc() > buffer via sf: 64.93 sec elapsed tic("buffer via qgisprocess") buffer_via_qgisprocess <- qgis_run_algorithm( + INPUT = water, + algorithm = "native:buffer", + SEGMENTS = 5000, + DISTANCE = 100 + ) > toc() buffer via qgisprocess: 48.03 sec elapsed ``` On the other hand, sf is faster for buffers at low resolution. --- background-image: url(/assets/images/background_challenge_2.png) class: left, top # Challenge 2 Use `qgis_search_algorithms()` to find the right algorithm to use. 1. **Count** the number of occurrences of floating pennyworth (`hydrocotyle_ranunculoides`) in each of the water polygons. 2. Create a buffer around `hab_springs` points with a dynamic radius expressed as the square root of `area_m2` divided by `3.14` (constant pi seems not interpreted by QGIS
\*\*
). Hint: check this [example](https://r-spatial.github.io/qgisprocess/articles/qgis_expressions.html#example-applying-a-data-defined-override) in the article "How to use QGIS expressions in qgisprocess?". 3. Typically, before making any spatial analysis, a check of **validity**\* is performed. Please, confirm that `water` and `prot_areas` are valid vector spatial data. Which algorithm do you use? Which output do you need to check? 4. The spatial vector dataset `invalid` contains some invalid polygons. **Fix** it using qgisprocess.
* There are several reasons why a set of "geometries" are invalid. Check the blogpost ["Invalid OGC Geometry Examples"](https://support.safe.com/hc/en-us/articles/25407709561741-Invalid-OGC-Geometry-Examples) for some examples.
\*\* Post-session **correction**: QGIS has supported pi for a very long time, but you need to call it as a function: `pi()`.
--- class: left, top # INTERMEZZO 2 - the qgis package Using functions with explicit arguments is really user friendly. You will then probably love the [qgis](https://jancaha.github.io/r_package_qgis/index.html) package. It aims to provide calls and simple documentation for each QGIS function available in the QGIS core and the most important algorithm providers like GRASS GIS and SAGA. It requires the qgisprocess package. An example. Instead of: ```r input <- sf::read_sf(system.file("shape/nc.shp", package = "sf")) input %>% qgisprocess::qgis_run_algorithm_p( algorithm = "native:buffer", DISTANCE = 0.2, DISSOLVE = TRUE, END_CAP_STYLE = "Flat") %>% sf::st_as_sf() %>% plot() ``` ```r input %>% qgis::qgis_buffer( DISTANCE = 0.2, DISSOLVE = TRUE, END_CAP_STYLE = "Flat") %>% st_as_sf() %>% plot() ``` --- background-image: url(/assets/images/background_challenge_3.png) class: left, top # CHALLENGE 3A 1. Which parts of the water bodies (`water`) are inside the Natura 2000 protected areas (`prot_areas`)? 2. Which parts of the water bodies (`water`) are outside the Natura 2000 protected areas (`prot_areas`)? --- class: left, top # CHALLENGE 3B - rasters "A raster is a spatial (geographic) data structure that divides a region into rectangles called **cells** (or pixels) that can store one or more values for each of these cells."* 2. Let's do some [zonal statistics](https://up42.com/blog/an-introduction-to-zonal-statistics#what-are-zonal-statistics): calculate the most and the least occurring land use category in each of the Natura2000 protected areas.
\*\*
3. **Clip** the raster based on the first NATURA 2000 protected area (`prot_areas[1, ]`). Keep the resolution of the input raster. You can use `qgis_as_terra()` at the end to convert the output to a `SpatRaster` object (something terra or mapview packages can understand). 4. Let's do some **sampling**! Sample `land_use` values at the `hab_spring` locations. You can use `sf::st_as_sf()` at the end to convert the output to a `sf` object. The final output is like `hab_spring` but with an additional column with the land use category at each point. 5. How to convert the `land_use` raster to polygons? Be careful when visualizing the ouptut with mapview as you have just generated a lot of polygons! You can use `mapview::mapview(land_use_polygons[1:50000,], zcol = "class")` to show the land use category of the first 50 thousands squares.
\* Source: https://rspatial.org/raster/pkg/1-introduction.html
\*\* Notice that if you want to do the same purely in R, you need to use the R package [extractr](https://isciences.gitlab.io/exactextractr/index.html). See the last exercise in [slide 14](https://inbo.github.io/coding-club/sessions/20221124_coding_club_rasters.html#14) (Nov 24, 2022) or the last exercise of [slide 13](https://inbo.github.io/coding-club/sessions/20211125_rasters_in_r.html#13) (Nov 25, 2021).
--- class: left, top # How to get help with qgisprocess? Do you have a generic question about the use of qgisprocess? Or do you not find the algorithm fitting your problem? Check the [FAQs](https://github.com/r-spatial/qgisprocess/issues/new/choose) on the "Issues" page of the qgisprocess GitHub repository. For INBO people: you can eventually use our standard mailing list (`dg_useR`).  --- class: left, top # The power of open science & software You can be helped, but you can also help! Software is not perfect. If it's open, you can report issues and even contribute to the solution. For example, thanks to the INBO coding club we found in Dec 2023 an issue (deprecation) with qgisprocess and a QGIS algorithm (see [#193](https://github.com/r-spatial/qgisprocess/issues/193)). We helped improving qgisprocess! How cool is that?!?  --- class: left, top # The R package of the month: lidr We close the session as we started it :-) The package lidr is a R package to process and visualize LiDAR data. Check the [lidR book](https://r-lidar.github.io/lidRbook/) and the [INBO tutorial](https://tutorials.inbo.be/tutorials/r_lidr/) of Sebastiaan.  --- class: left, top # Resources - Comprehensive [solutions](https://github.com/inbo/coding-club/blob/main/src/20261029/20261029_challenges_solutions.R) are available on GitHub. You can opt to download the solutions automatically by using `inborutils::setup_codingclub_session("20261029")`. - Edited [video recording](https://youtu.be/JEb-POve5O0) is available on YouTube. From September 2026 we have switched to YouTube. Check the [INBO Coding Club playlist](https://www.youtube.com/playlist?list=PLe0S6mqrTKNE). All previous recordings will continue to be available on [our vimeo channel](https://vimeo.com/user/8605285/folder/1978815). - [qgisprocess](https://r-spatial.github.io/qgisprocess/index.html) R package documentation. - [Interfacing QGIS processing from R](https://florisvdh.github.io/foss4g-2023-qgisprocess/#1): Floris' presentation at FOSS4G 2023. Floris rocks: watch the [video](https://www.youtube.com/watch?v=Qt5DzWThWqI) of his talk. - [qgis](https://jancaha.github.io/r_package_qgis/index.html) R package documentation. - [QGIS](https://qgis.org/en/site/) website. - Blogpost explaining the (in)validity of spatial objects: [What Makes a Geometry Valid? The OGC Rules Explained](https://www.spatialworkflow.io/geometry-validity-explained). See some examples in the section [The rules, in one picture](https://www.spatialworkflow.io/geometry-validity-explained/#the-rules-in-one-picture). - [sf](https://r-spatial.github.io/sf/) R package documentation. - [terra](https://rspatial.github.io/terra/index.html) R package documentation. - How to get help: use our internal INBO R mailing list (DG_useR) and also check the [FAQs](https://github.com/r-spatial/qgisprocess/issues/new/choose) on the "Issues" page of the qgisprocess GitHub repository. - Our [INBO tutorial](https://tutorials.inbo.be/) website. --- class: left, top ``` cowsay::say( what = "Hope your Halloween is a total scream!", by = "pumpkin", what_color = "purple", by_color = "black", width = 40 ) ``` .center[] --- class: center, middle  Topic: to be decided
Room: HT - 00.48 - Keldermans
Date: **24/11/2026** (Tuesday), van **10:00** tot **12:30**
Help needed with the technical setup? You are welcome from 9:45am