QGIS Planethttp://plugins.qgis.org/planet2024-03-18T20:16:40Zanitagraser.com: Getting started with pygeoapi processes2024-03-18T20:16:40Zunderdarknospam@nospam.comhttps://anitagraser.com/2024/03/18/getting-started-with-pygeoapi-processes/<p>Today’s post is a quick introduction to <a href="https://pygeoapi.io">pygeoapi</a>, a Python server implementation of the <a href="https://ogcapi.ogc.org/">OGC API suite of standards</a>. OGC API provides many different standards but I’m particularly interested in <a href="https://ogcapi.ogc.org/processes">OGC API – Processes</a> which standardizes geospatial data processing functionality. pygeoapi implements this standard by providing a plugin architecture, thereby allowing developers to implement custom processing workflows in Python.</p>
<p>I’ll provide instructions for setting up and running pygeoapi on Windows using Powershell. The <a href="https://docs.pygeoapi.io/en/stable/installation.html">official docs</a> show how to do this on Linux systems. The <a href="https://pygeoapi.io">pygeoapi</a> homepage prominently features instructions for installing the dev version. For first experiments, however, I’d recommend using a release version instead. So that’s what we’ll do here. </p>
<p>As a first step, lets install the latest release (0.16.1 at the time of writing) from <a href="https://github.com/geopython/pygeoapi/releases">conda-forge</a>:</p>
<pre class="wp-block-code"><code>conda create -n pygeoapi python=3.10<br>conda activate pygeoapi<br>mamba install -c conda-forge pygeoapi</code></pre>
<p>Next, we’ll clone <a href="https://github.com/geopython/pygeoapi">the GitHub repo</a> to get the example config and datasets:</p>
<pre class="wp-block-code"><code>cd C:\Users\anita\Documents\GitHub\<br>git clone https://github.com/geopython/pygeoapi.git<br>cd pygeoapi\</code></pre>
<p>To finish the setup, we need some configurations:</p>
<pre class="wp-block-code"><code>cp pygeoapi-config.yml example-config.yml <br># There is a known issue in pygeoapi 0.16.1: https://github.com/geopython/pygeoapi/issues/1597<br># To fix it, edit the example-config.yml: uncomment the TinyDB option in the server settings (lines 51-54)<br><br>$Env:PYGEOAPI_CONFIG = "F:/Documents/GitHub/pygeoapi/example-config.yml"<br>$Env:PYGEOAPI_OPENAPI = "F:/Documents/GitHub/pygeoapi/example-openapi.yml"<br>pygeoapi openapi generate $Env:PYGEOAPI_CONFIG --output-file $Env:PYGEOAPI_OPENAPI</code></pre>
<p>Now we can start the server:</p>
<pre class="wp-block-code"><code>pygeoapi serve</code></pre>
<p>And once the server is running, we can send requests, e.g. the list of processes:</p>
<pre class="wp-block-code"><code>curl.exe http://localhost:5000/processes</code></pre>
<p>And, of course, execute the example “hello-world” process:</p>
<pre class="wp-block-code"><code>curl.exe --% -X POST http://localhost:5000/processes/hello-world/execution -H "Content-Type: application/json" -d "{\"inputs\":{\"name\": \"hi there\"}}"</code></pre>
<p>As you can see, writing JSON content for curl is a pain. Luckily, pyopenapi comes with a nice web GUI, including Swagger UI for playing with all the functionality, including the hello-world process: </p>
<figure class="wp-block-image size-large"><img width="584" height="455" data-attachment-id="8840" data-permalink="https://anitagraser.com/2024/03/18/getting-started-with-pygeoapi-processes/image-45/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/03/image.png" data-orig-size="584,455" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/03/image.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/03/image.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/03/image.png?w=584" alt="" class="wp-image-8840" srcset="https://anitagraser.com/wp-content/uploads/2024/03/image.png 584w, https://anitagraser.com/wp-content/uploads/2024/03/image.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/03/image.png?w=300 300w" sizes="(max-width: 584px) 100vw, 584px" /></figure>
<figure class="wp-block-image size-large"><img width="584" height="634" data-attachment-id="8841" data-permalink="https://anitagraser.com/2024/03/18/getting-started-with-pygeoapi-processes/image-1-14/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/03/image-1.png" data-orig-size="584,634" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-1" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/03/image-1.png?w=276" data-large-file="https://anitagraser.com/wp-content/uploads/2024/03/image-1.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/03/image-1.png?w=584" alt="" class="wp-image-8841" srcset="https://anitagraser.com/wp-content/uploads/2024/03/image-1.png 584w, https://anitagraser.com/wp-content/uploads/2024/03/image-1.png?w=138 138w, https://anitagraser.com/wp-content/uploads/2024/03/image-1.png?w=276 276w" sizes="(max-width: 584px) 100vw, 584px" /></figure>
<p>It’s not really a geospatial hello-world example, but it’s a first step. </p>
<p>Finally, I wan’t to leave you with a teaser since there are more interesting things going on in this space, including work on OGC API – Moving Features as <a href="https://noc.social/@pygeoapi/112013706668052981">shared by the pygeoapi team recently</a>:</p>
<figure class="wp-block-image size-large"><img width="311" height="325" data-attachment-id="8847" data-permalink="https://anitagraser.com/2024/03/18/getting-started-with-pygeoapi-processes/image-3-12/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/03/image-3.png" data-orig-size="311,325" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-3" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/03/image-3.png?w=287" data-large-file="https://anitagraser.com/wp-content/uploads/2024/03/image-3.png?w=311" src="https://anitagraser.com/wp-content/uploads/2024/03/image-3.png?w=311" alt="" class="wp-image-8847" srcset="https://anitagraser.com/wp-content/uploads/2024/03/image-3.png 311w, https://anitagraser.com/wp-content/uploads/2024/03/image-3.png?w=144 144w, https://anitagraser.com/wp-content/uploads/2024/03/image-3.png?w=287 287w" sizes="(max-width: 311px) 100vw, 311px" /></figure>
<p>So, stay tuned. </p>Mergin Maps: [Case Study] Innovating road research and construction2024-03-13T01:00:00Znospam@nospam.comhttps://merginmaps.com/case-studies/innovating-road-research-and-construction?utm_source=qgisDiscover how BRRC revolutionized their field survey workflows with Mergin Maps, enhancing productivity and data accuracy. Learn how their partnership with Lutra Consulting enabled tailored solutions for seamless integration, transforming road research and construction projects.QField releases: 3.2.0 - Congo2024-03-08T09:47:49Znirvnnospam@nospam.comhttps://github.com/opengisch/QField/releases/tag/v3.2.0<h2>Changes</h2>
<p><a target="_blank" rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/1728657/310742115-bedae1db-c12e-498c-92f0-d29033ed688d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTA4Mzc5MjQsIm5iZiI6MTcxMDgzNzYyNCwicGF0aCI6Ii8xNzI4NjU3LzMxMDc0MjExNS1iZWRhZTFkYi1jMTJlLTQ5OGMtOTJmMC1kMjkwMzNlZDY4OGQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDMxOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAzMTlUMDg0MDI0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MTAzMTI2Y2M3NDI0NmI2ZDNjYTAyOGRhY2QxMTI2ZDM4MTVkMGFiODNlMGRhMTRjNTYyNWRlMGMwZTMxODAwYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.5EL33LqgR7jH3Z_F_xbiWajf_KYzJq0WEDLs4F5Uf34"><img src="https://private-user-images.githubusercontent.com/1728657/310742115-bedae1db-c12e-498c-92f0-d29033ed688d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTA4Mzc5MjQsIm5iZiI6MTcxMDgzNzYyNCwicGF0aCI6Ii8xNzI4NjU3LzMxMDc0MjExNS1iZWRhZTFkYi1jMTJlLTQ5OGMtOTJmMC1kMjkwMzNlZDY4OGQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDMxOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAzMTlUMDg0MDI0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MTAzMTI2Y2M3NDI0NmI2ZDNjYTAyOGRhY2QxMTI2ZDM4MTVkMGFiODNlMGRhMTRjNTYyNWRlMGMwZTMxODAwYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.5EL33LqgR7jH3Z_F_xbiWajf_KYzJq0WEDLs4F5Uf34" alt="qfield32" content-type-secured-asset="image/png" style="max-width: 100%;"></a></p>
<h3>🚀 Features</h3>
<ul>
<li>Project-defined tracking sessions activated on project load</li>
<li>Background push and synchronization for cloud projects</li>
<li>Automatically push pending changes to the cloud on a regular interval</li>
<li>New undo/redo functionality allowing you to reverse undesired digitizing and feature editing</li>
<li>Title and copyright decoration overlay on top of the map canvas</li>
</ul>
<h3>✨ Improvements</h3>
<ul>
<li>Better progress feedback when downloading and synchronizing cloud projects</li>
<li>Visual indicators of ‘newer’ cloud project available on the server in QField</li>
<li>Relationship’s children can now be created <em>prior to</em> saving their parent feature</li>
<li>Insure positioning precise view (i.e. stake-out) works on compass-less devices</li>
<li>User interface polishing, including a brand new main menu layout</li>
<li>Support for gpsd-served NMEA streams over TCP/UDP</li>
<li>Updated several underlying libraries, including QGIS (v3.36) and Qt (v6.6.2)</li>
</ul>
<h3>🤖 Android improvements</h3>
<ul>
<li>Massive re-work of native camera, gallery, and file opening activities unlocking proper OS activity overlay</li>
</ul>Mergin Maps: [Case Study] Designing surveys for fibre optics rollout2024-02-26T00:00:00Znospam@nospam.comhttps://merginmaps.com/case-studies/designing-surveys-for-fibre-optics-rollout?utm_source=qgisJacops was starting a new project for the fiber rollout and needed the tools to organise a national survey. Previously they had used tools provided by a partner and needed to find a solution that allowed them to manage the full scope of the project.anitagraser.com: Trajectools 2.0 released 🎉2024-02-24T19:27:25Zunderdarknospam@nospam.comhttps://anitagraser.com/2024/02/24/trajectools-2-0-released/<p>It’s my pleasure to share with you that Trajectools 2.0 just landed in <a href="https://plugins.qgis.org/plugins/processing_trajectory/#plugin-versions">the official QGIS Plugin Repository</a>.</p>
<p>This is the first version without the “experimental” flag. If you look at the plugin release history, you will see that the previous release was from 2020. That’s quite a while ago and a lot has happened since, including the development of <a href="https://movingpandas.org">MovingPandas</a>.</p>
<h2 class="wp-block-heading">Let’s have a look what’s new!</h2>
<figure class="wp-block-image size-large"><img loading="lazy" width="624" height="325" data-attachment-id="8812" data-permalink="https://anitagraser.com/2024/02/24/trajectools-2-0-released/trajectools-1-2/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png" data-orig-size="624,325" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="trajectools-1-2" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png?w=624" alt="" class="wp-image-8812" srcset="https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png 624w, https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/02/trajectools-1-2.png?w=300 300w" sizes="(max-width: 624px) 100vw, 624px" /></figure>
<p>The old “Trajectories from point layer”, “Add heading to points”, and “Add speed (m/s) to points” algorithms have been superseded by the new <strong>“Create trajectories”</strong> algorithm which automatically computes speeds and headings when creating the trajectory outputs. </p>
<p>“Day trajectories from point layer” is covered by the new <strong>“Split trajectories at time intervals” </strong>which supports splitting by hour, day, month, and year.</p>
<p><strong>“Clip trajectories by extent”</strong> still exists but, additionally, we can now also <strong>“Clip trajectories by polygon layer”</strong></p>
<p>There are two new event extraction algorithms to <strong>“Extract OD points”</strong> and <strong>“Extract OD points”</strong>, as well as the related <strong>“Split trajectories at stops”</strong>. Additionally, we can also <strong>“Split trajectories at observation gaps”</strong>.</p>
<p>Trajectory outputs, by default, come as a pair of a point layer and a line layer. Depending on your use case, you can use both or pick just one of them. By default, the line layer is styled with a gradient line that makes it easy to see the movement direction:</p>
<figure class="wp-block-image size-large"><img loading="lazy" width="624" height="191" data-attachment-id="8817" data-permalink="https://anitagraser.com/2024/02/24/trajectools-2-0-released/image-7-9/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/02/image-7.png" data-orig-size="624,191" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-7" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/02/image-7.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/02/image-7.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/02/image-7.png?w=624" alt="" class="wp-image-8817" srcset="https://anitagraser.com/wp-content/uploads/2024/02/image-7.png 624w, https://anitagraser.com/wp-content/uploads/2024/02/image-7.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/02/image-7.png?w=300 300w" sizes="(max-width: 624px) 100vw, 624px" /></figure>
<p>while the default point layer style shows the movement speed: </p>
<figure class="wp-block-image size-large"><img loading="lazy" width="612" height="207" data-attachment-id="8824" data-permalink="https://anitagraser.com/2024/02/24/trajectools-2-0-released/image-12-6/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/02/image-12.png" data-orig-size="612,207" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-12" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/02/image-12.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/02/image-12.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/02/image-12.png?w=612" alt="" class="wp-image-8824" srcset="https://anitagraser.com/wp-content/uploads/2024/02/image-12.png 612w, https://anitagraser.com/wp-content/uploads/2024/02/image-12.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/02/image-12.png?w=300 300w" sizes="(max-width: 612px) 100vw, 612px" /></figure>
<h2 class="wp-block-heading">How to use Trajectools</h2>
<p>Trajectools 2.0 is powered by MovingPandas. You will need to install MovingPandas in your QGIS Python environment. I recommend installing both QGIS and MovingPandas from conda-forge:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
(base) conda create -n qgis -c conda-forge python=3.9
(base) conda activate qgis
(qgis) mamba install -c conda-forge qgis movingpandas
</pre></div>
<p>The plugin download includes small trajectory sample datasets so you can get started immediately. </p>
<h2 class="wp-block-heading">Outlook</h2>
<p>There is still some work to do to reach feature parity with MovingPandas. Stay tuned for more trajectory algorithms, including but not limited to down-sampling, smoothing, and outlier cleaning. </p>
<p>I’m also reviewing other existing QGIS plugins to see how they can complement each other. If you know a plugin I should look into, please leave a note in the comments. </p>QGIS Project blog: Save the date & call for contributions: QGIS user conference and contributor meeting in Bratislava2024-02-20T19:19:35Zunderdarknospam@nospam.comhttps://blog.qgis.org/2024/02/20/save-the-date-call-for-contributions-qgis-user-conference-and-contributor-meeting-in-bratislava/<p>We are happy to announce that QGIS User Conference will take place on 9-10 September 2024 in Bratislava, Slovakia.</p>
<figure class="wp-block-image size-large"><img width="535" height="213" data-attachment-id="2831" data-permalink="https://blog.qgis.org/2024/02/20/save-the-date-call-for-contributions-qgis-user-conference-and-contributor-meeting-in-bratislava/logotype_qgis_uc_20247850032873421006461/" data-orig-file="https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png" data-orig-size="535,213" data-comments-opened="0" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="logotype_qgis_uc_20247850032873421006461" data-image-description="" data-image-caption="" data-medium-file="https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png?w=300" data-large-file="https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png?w=535" src="https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png?w=535" alt="" class="wp-image-2831" srcset="https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png 535w, https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png?w=150 150w, https://qgisblog.files.wordpress.com/2024/02/logotype_qgis_uc_20247850032873421006461.png?w=300 300w" sizes="(max-width: 535px) 100vw, 535px" /></figure>
<p><br>The traditional Contributor Meeting will be held right after the conference on 11-13 September 2024 at the same venue.<br><br>Learn more about the user conference and the contributor meeting at the event’s web site: <a href="https://uc2024.qgis.sk/" rel="nofollow">https://uc2024.qgis.sk/</a><br><br>The call for papers for the user conference is now open – you can <strong>submit</strong> <strong>proposals for talks and workshops by 31 March 2024:</strong><br><a href="https://uc2024.qgis.sk/call-for-papers/" rel="nofollow">https://uc2024.qgis.sk/call-for-papers/</a><br><br>We have also started call for sponsors, with <strong>sponsorship opportunities</strong> at various levels. More details here:<br><a href="https://uc2024.qgis.sk/sponsors/" rel="nofollow">https://uc2024.qgis.sk/sponsors/</a><br><br><strong>User Conference</strong><br><br>The QGIS User Conference is an annual event that brings together users and developers of QGIS. The conference provides an opportunity for attendees to learn about the latest developments in QGIS, share their experiences with others, and network with other QGIS users and<br>developers.<br><br><strong>Contributor Meeting</strong><br><br>QGIS Contributor Meetings are volunteer-driven events where contributors to the QGIS project from around the world get together in a common space – usually a university campus. During these events, contributors to the QGIS project take the opportunity to plan their work, hold face-to-face discussions and present new improvements to the QGIS project that they have been working on. Everybody attending the event donates their time to the project for the days of the event.<br>As a project that is built primarily through online collaboration, these meetings provide a crucial ingredient to the future development of the QGIS project. The event is planned largely as an ‘unconference’ with minimal structured programme planning.</p>
<p>For more details and to sign up, please visit the corresponding wiki page <a href="https://github.com/qgis/QGIS/wiki/27th%E2%80%90Contributor%E2%80%90Meeting%E2%80%90in%E2%80%90Bratislava" rel="nofollow">https://github.com/qgis/QGIS/wiki/27th%E2%80%90Contributor%E2%80%90Meeting%E2%80%90in%E2%80%90Bratislava</a></p>
<p></p>QGIS Project blog: QGIS Grants #9: Call for Grant Proposals 20242024-02-15T19:09:26Zunderdarknospam@nospam.comhttps://blog.qgis.org/2024/02/15/qgis-grants-9-call-for-grant-proposals-2024/<p>Dear QGIS Community,</p>
<p>We are very pleased to announce that this year’s round of grants is now available. The call is open to anybody who wants to make a contribution to QGIS funded by our grant fund, subject to the call conditions outlined in the application form.</p>
<p>The deadline for this round is in four weeks, on <strong>14 March 2024</strong>.</p>
<p><span style="font-weight: 400">There are no new procedures in 2024. Please note the following guidelines established in previous years: </span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">The proposal must be submitted as a ‘QEP’ (QGIS Enhancement Proposal) issue in the repo: </span><a href="https://github.com/qgis/QGIS-Enhancement-Proposals"><span style="font-weight: 400">https://github.com/qgis/QGIS-Enhancement-Proposals</span></a><span style="font-weight: 400"> (tagged as </span><span style="font-weight: 400">Grant-2024</span><span style="font-weight: 400">). Following this approach will allow </span><span style="font-weight: 400">people to ask questions and provide public feedback on individual proposals.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Proposals must clearly define the expected final result so that we can properly assess if the goal of the proposal has been reached.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">The project budgets should account for PR reviewing expenses to ensure timely handling of the project-related PRs and avoid delays caused by relying on reviewer volunteer time. </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">In the week after the QEP discussion period, the proposal authors are expected to write a short summary of the discussion that is suitable for use as a basis on which voting members make their decisions. </span></li>
</ul>
<p><span style="font-weight: 400">The PSC of QGIS.ORG will examine the proposals and has veto power in case a proposal does not follow guidelines or is not in line with project priorities. </span></p>
<p>For more details, please read the introduction provided in <a href="https://forms.gle/ydFS8RnL7Dt46MVx7"><strong>the application form</strong></a>.</p>
<p>We look forward to seeing all your great ideas for improving QGIS!</p>Mergin Maps: [Blog] Hello from Mergin Maps!2024-02-13T00:00:00Znospam@nospam.comhttps://merginmaps.com/blog/hello-from-mergin-maps?utm_source=qgisMergin Maps is a QGIS-powered field survey tool designed to collect data from the field. It is developed by Lutra Consulting, a longstanding contributor, developer, supporter and trainer within the QGIS community.QGIS NL Community: Hello world!2024-02-08T11:32:26Zadminnospam@nospam.comhttps://qgis.nl/uncategorized/hello-world/<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>QGIS Oslandia: Software quality in QGIS2024-02-07T12:55:33ZJulien Cabiecesnospam@nospam.comhttps://oslandia.com/en/2024/02/09/la-qualite-logicielle-dans-qgis/<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">According to the definition of software quality given by french Wikipedia</span></span> </span></p>
<blockquote><p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">An overall assessment of quality takes into account external factors, directly observable by the user, as well as internal factors, observable by engineers during code reviews or maintenance work.</span></span> </span></p></blockquote>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">I have chosen in this article to only talk about the latter.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">The quality of software and more precisely QGIS is therefore not limited to what is described here.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">There is still much to say about:</span></span> </span></p>
<ul>
<li><span class="HwtZe" lang="en"> <span class="jCAhz ChMk0b"><span class="ryNqvb">Taking user feedback into account,</span></span> </span></li>
<li><span class="HwtZe" lang="en"> <span class="jCAhz ChMk0b"><span class="ryNqvb">the documentation writing process,</span></span> </span></li>
<li><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">translation management,</span></span> </span></li>
<li><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">interoperability through the implementation of standards,</span></span> </span></li>
<li><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">the extensibility using API,</span></span> </span></li>
<li><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">the reversibility and resilience of the open source model…</span></span></span></li>
</ul>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">These are subjects that we care a lot and deserve their own article.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">I will focus here on the following issue: QGIS is free software and allows anyone with the necessary skills to modify the software.</span></span> <strong><span class="jCAhz ChMk0b"><span class="ryNqvb">But how can we ensure that the multiple proposals for modifications to the software contribute to its improvement and do not harm its future maintenance?</span></span> </strong></span></p>
<h1><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Self-discipline</span></span> </span></h1>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">All developers contributing to QGIS code doesn’t belong to the same organization.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">They don’t all live in the same country, don’t necessarily have the same culture and don’t necessarily share the same interests or ambitions for the software.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">However, they share the awareness of modifying a common good and the desire to take care of it.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">This awareness transcends professional awareness, the developer not only has a responsibility towards his employer, but also towards the entire community of users and contributors to the software.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">T</span></span></span><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">his self-discipline is the foundation of the quality of the contributions of software like QGIS.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">However, to err is human and it is essential to carry out checks for each modification proposal.</span></span> </span></p>
<h1><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Automatic checks</span></span> </span></h1>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">With each <a href="https://github.com/qgis/QGIS/pulls">modification proposal</a> (called Pull Request or Merge Request), the QGIS GitHub platform automatically launches a set of automatic checks.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb"><img class="size-full wp-image-8154 aligncenter" src="https://oslandia.com/wp-content/uploads/2024/01/gh_example.png" alt="" width="731" height="260" srcset="https://oslandia.com/wp-content/uploads/2024/01/gh_example.png 731w, https://oslandia.com/wp-content/uploads/2024/01/gh_example-300x107.png 300w" sizes="(max-width: 731px) 100vw, 731px" /></span></span></span></p>
<p style="text-align: center;"><em><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Example of proposed modification</span></span> </span></em></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb"><img class="size-full wp-image-8156 aligncenter" src="https://oslandia.com/wp-content/uploads/2024/01/gh_checks.png" alt="" width="681" height="247" srcset="https://oslandia.com/wp-content/uploads/2024/01/gh_checks.png 681w, https://oslandia.com/wp-content/uploads/2024/01/gh_checks-300x109.png 300w" sizes="(max-width: 681px) 100vw, 681px" /></span></span></span></p>
<p style="text-align: center;"><em><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Result of automatic checks on a modification proposal</span></span></span></em></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">The first of these checks is to build QGIS on the different systems on which it is distributed (Linux, Windows, MacOS) by integrating the proposed modification.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">It is inconceivable to integrate a modification that would prevent the application from being built on one of these systems.</span></span> </span></p>
<h2><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">The tests</span></span> </span></h2>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">The first problem posed by a proposed modification is the following <strong>“How can we be sure that what is going to be introduced does not break what already exists?”</strong></span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">To validate this assertion, we rely on automatic tests.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">This is a set of micro-programs called tests, which only purpose is to validate that part of the application behaves as expected.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">For example, there is a test which validates that when the user adds an entry in a data layer, then this entry is then present in the data layer.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">If a modification were to break this behavior, then the test would fail and the proposal would be rejected (or more likely corrected).</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">This makes it possible in particular to avoid regressions (they are very often called <em>non-regression tests</em>) and also to qualify the expected behavior.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">There are approximately 1.3 Million lines of code for the QGIS application and 420K lines of test code, a ratio of 1 to 3. The presence of tests is mandatory for adding functionality, therefore the</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">quantity of test code increases with the quantity of application code.</span></span> </span></p>
<p><img class="size-full wp-image-8159 aligncenter" src="https://oslandia.com/wp-content/uploads/2024/01/codevstest_graph.png" alt="" width="566" height="332" srcset="https://oslandia.com/wp-content/uploads/2024/01/codevstest_graph.png 566w, https://oslandia.com/wp-content/uploads/2024/01/codevstest_graph-300x176.png 300w" sizes="(max-width: 566px) 100vw, 566px" /></p>
<p style="text-align: center;"><em><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">In blue the number of lines of code in QGIS, in red the number of lines of tests</span></span></span></em></p>
<p><span class="HwtZe" lang="en"> <span class="jCAhz ChMk0b"><span class="ryNqvb">There are currently over 900 groups of automatic tests in QGIS, most of which run in less than 2 seconds, for a total execution time of around 30 minutes.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">We also see that certain parts of the QGIS code – the most recent – are better covered by the tests than other older ones.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">Developers are gradually working to improve this situation to reduce technical debt.</span></span> </span></p>
<h2><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Code checks</span></span> </span></h2>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Analogous to using a spell checker when writing a document, we carry out a set of quality checks on the source code.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">We check, for example, that the proposed modification does not contain misspelled words or “banned” words, that the API documentation has been correctly written or that the modified code respects certain formal rules of the programming language.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">We recently had the opportunity to add a check based on </span></span></span><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">the <a href="https://clang.llvm.org/extra/clang-tidy/">clang-tidy</a> tool. </span></span></span><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">The latter relies on the <a href="https://fr.wikipedia.org/wiki/Clang">Clang</a> compiler.</span></span> </span><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">It is capable of detecting programming errors by carrying out a static analysis of the code.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Clang-tidy is, for example, capable of detecting “narrowing conversions”.</span></span> </span></p>
<p><img class="size-full wp-image-8160 aligncenter" src="https://oslandia.com/wp-content/uploads/2024/01/narrowing_conversion.png" alt="" width="1142" height="71" srcset="https://oslandia.com/wp-content/uploads/2024/01/narrowing_conversion.png 1142w, https://oslandia.com/wp-content/uploads/2024/01/narrowing_conversion-300x19.png 300w, https://oslandia.com/wp-content/uploads/2024/01/narrowing_conversion-768x48.png 768w, https://oslandia.com/wp-content/uploads/2024/01/narrowing_conversion-1024x64.png 1024w" sizes="(max-width: 1142px) 100vw, 1142px" /></p>
<p style="text-align: center;"><em><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Example of detecting “narrowing conversions”</span></span></span></em></p>
<p><span class="HwtZe" lang="en"> <span class="jCAhz ChMk0b"><span class="ryNqvb">In the example above, Clang-tidy detects that there has been a “narrowing conversion” and that the value of the port used in the network proxy configuration “may” be corrupted.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">In this case, this problem was <a href="https://github.com/qgis/QGIS/issues/49179">reported</a> on the QGIS issues platform and had to be <a href="https://github.com/qgis/QGIS/pull/50016">corrected</a>.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">At that time, clang-tidy was not in place.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">Its use would have made it possible to avoid this anomaly and all the steps which led to its correction (exhaustive description of the issue, multiple exchanges to be able to reproduce it, investigation, correction, review of the modification), meaning a significant amount of </span></span><span class="jCAhz ChMk0b"><span class="ryNqvb">human time which could thus have been avoided.</span></span></span></p>
<h1><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Peer review</span></span> </span></h1>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">A proposed modification that would validate all of the automatic checks described above would not necessarily be integrated into the QGIS code automatically.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">In fact, its code may be poorly designed or the modification poorly thought out.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">The relevance of the functionality may be doubtful, or duplicated with another.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">The integration of the modification would therefore potentially cause a burden for the people in charge of the corrective or evolutionary maintenance of the software.</span></span></span></p>
<p><span class="HwtZe" lang="en"> <span class="jCAhz ChMk0b"><span class="ryNqvb">It is therefore essential to include a human review in the process of accepting a modification.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">This is more of a rereading of the substance of the proposal than of the form.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">For the latter, we favor the automatic checks described above in order to simplify the review process.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Therefore, human proofreading takes time, and this effort is growing with the quantity of modifications proposed in the QGIS code.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">The question of its funding arises, and discussions are <a href="https://lists.osgeo.org/pipermail/qgis-developer/2023-December/066299.html">in progress</a>.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">The QGIS.org association notably dedicates a significant part of its budget to fund code reviews.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb"><img class="size-full wp-image-8161 aligncenter" src="https://oslandia.com/wp-content/uploads/2024/01/gh_report.png" alt="" width="726" height="328" srcset="https://oslandia.com/wp-content/uploads/2024/01/gh_report.png 726w, https://oslandia.com/wp-content/uploads/2024/01/gh_report-300x136.png 300w" sizes="(max-width: 726px) 100vw, 726px" /></span></span></span></p>
<p style="text-align: center;"><em><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">More than 100 modification proposals were reviewed and integrated during the month of December 2023. More than 30 different people contributed.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">More than 2000 files have been modified.</span></span> </span></em></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">Therefore the wait for a proofreading can sometimes be long.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">It is also often the moment when disagreements are expressed.</span></span> <span class="jCAhz ChMk0b"><span class="ryNqvb">It is therefore a phase which can prove frustrating for contributors, but it is an important and rich moment in the community life of a free project.</span></span> </span></p>
<p><strong><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">To be continued !</span></span> </span></strong></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">As a core QGIS developer, and as a pure player OpenSource company, we believe it is fundamental to be involved in each step of the contribution process.</span></span> </span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">We are investing in the review process, improving automatic checks, and in the QGIS quality process in general. </span></span></span><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">And we will continue to invest in these topics in order to help make QGIS a long-lasting and stable software.</span></span></span></p>
<p><span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">If you would like to contribute or simply learn more about QGIS, do not hesitate to contact us at <a href="mailto:infos+qgis@oslandia.com">infos+qgis@oslandia.com</a> and consult our QGIS<a href="https://oslandia.com/offre-qgis/"> support proposal</a>.</span></span></span></p>QGIS Oslandia: (Fr) Rencontres QGIS-fr – Grenoble 27 & 28 mars 20242024-02-06T11:03:47ZCaroline Chanlonnospam@nospam.comhttps://oslandia.com/en/2024/02/06/rencontres-qgis-fr-grenoble-27-28-mars-2024/<p class="qtranxs-available-languages-message qtranxs-available-languages-message-en">Sorry, this entry is only available in <a href="http://oslandia.com/fr/tag/qgis-en/feed/atom/" class="qtranxs-available-language-link qtranxs-available-language-link-fr" title="Fr">French</a>.</p>Sourcepole: Designing QGIS Cloud QWC2 with CSS2024-02-06T00:00:00Znospam@nospam.comhttps://blog.sourcepole.ch/2024/02/06/qgiscloud-css/In an earlier post, I showed how it is possible to permanently position a legend in the QGIS Cloud map as part of a QGIS Cloud Pro subscription. To achieve this, the appearance of the map view was changed using CSS. In this post, I will describe exactly what this is and how it works.
The appearance of the QGIS Cloud Web Client is controlled via CSS. CSS stands for Cascading Style Sheets.Lutra Consulting: New point clouds and mesh features in QGIS 3.362024-02-05T08:00:00Znospam@nospam.comhttps://lutraconsulting.co.uk/blog/2024/02/05/new-features-in-qgis-36/<p>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.</p>
<h1 id="render-point-clouds-as-a-surface-in-2d-map-views">Render point clouds as a surface in 2D map views</h1>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<center>
<p><img title="Point clouds as surface" src="https://lutraconsulting.co.uk/img/posts/pc_as_surface_2d.gif" alt="Point clouds as surface" /></p>
<sub>Point clouds as individual points vs. as a TIN surface</sub>
</center>
<p>The good news is that rendering as a surface also works well with global map shading, allowing users to get a nice hillshade:</p>
<center>
<p><img title="Point clouds as surface with hillshade" src="https://lutraconsulting.co.uk/img/posts/pc_as_surface_2d_hillshade.png" alt="Point clouds as surface with hillshade with hillshade" /></p>
<sub>Point clouds as surface with hillshade</sub>
</center>
<p>To enable this feature, you need to check the option for <strong>Render as a Surface (Triangulate)</strong> under the <strong>Layer Styling</strong> panel.</p>
<center>
<p><img title="Setting to display point clouds as surface" src="https://lutraconsulting.co.uk/img/posts/pc_as_surface_style.png" alt="Point clouds styling panel" /></p>
<sub>Settings to display point clouds as surface</sub>
</center>
<p><strong>Pro-tip</strong>: 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.</p>
<h1 id="flexible-styling-of-classes">Flexible styling of classes</h1>
<p>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.</p>
<center>
<p><img title="Assigning size and opacity to each point cloud class" src="https://lutraconsulting.co.uk/img/posts/pc_size_opacity_panel.png" alt="Assigning size and opacity to each point cloud class" /></p>
<sub>Assigning size and opacity to each point cloud class</sub>
</center>
<center>
<p><img title="Point clouds with different sizes and opacity levels" src="https://lutraconsulting.co.uk/img/posts/pc_size_opacity.png" alt="Point clouds with different sizes and opacity levels" /></p>
<sub>Point clouds with different sizes and opacity levels</sub>
</center>
<h1 id="set-3d-map-view-extent-in-2d-map">Set 3D map view extent in 2D map</h1>
<p>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:</p>
<center>
<p><img title="Interactive selection of 3D map scene from 2D map" src="https://lutraconsulting.co.uk/img/posts/3d_map_bbox_interactive.png" alt="Interactive selection of 3D map scene from 2D map" /></p>
<sub>Interactive selection of 3D map scene from 2D map</sub>
</center>
<h1 id="python-api-for-3d-views">Python API for 3D views</h1>
<p>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.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># List all open 3D map canvases
</span><span class="n">iface</span><span class="p">.</span><span class="n">mapCanvases3D</span><span class="p">()</span>
<span class="c1"># [<qgis._3d.Qgs3DMapCanvas object at 0x7f23491b5e10>]
</span><span class="n">canvas</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">mapCanvases3D</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
</code></pre></div></div>
<p>Now let’s try something more complicated:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Let's change some settings!
</span><span class="n">ms</span> <span class="o">=</span> <span class="n">canvas</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">()</span>
<span class="n">ms</span><span class="p">.</span><span class="n">setEyeDomeLightingEnabled</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="n">ms</span><span class="p">.</span><span class="n">setBackgroundColor</span><span class="p">(</span><span class="n">QColor</span><span class="p">(</span><span class="s">'beige'</span><span class="p">))</span>
<span class="n">ms</span><span class="p">.</span><span class="n">setTerrainMapTheme</span><span class="p">(</span><span class="s">'dtm'</span><span class="p">)</span>
<span class="n">ms</span><span class="p">.</span><span class="n">setFieldOfView</span><span class="p">(</span><span class="mi">110</span><span class="p">)</span>
<span class="c1"># Move the camera to look at specific map coordinates in layer's CRS
</span><span class="n">cam</span> <span class="o">=</span> <span class="n">canvas</span><span class="p">.</span><span class="n">cameraController</span><span class="p">()</span>
<span class="n">mapPoint</span> <span class="o">=</span> <span class="n">QgsVector3D</span><span class="p">(</span><span class="o">-</span><span class="mf">498175.92</span><span class="p">,</span> <span class="o">-</span><span class="mf">1205400.58</span><span class="p">,</span> <span class="mi">210</span><span class="p">)</span>
<span class="n">worldPoint</span> <span class="o">=</span> <span class="n">ms</span><span class="p">.</span><span class="n">mapToWorldCoordinates</span><span class="p">(</span><span class="n">mapPoint</span><span class="p">)</span>
<span class="n">cam</span><span class="p">.</span><span class="n">setLookingAtPoint</span><span class="p">(</span><span class="n">worldPoint</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="c1"># Create four new 3D map views
</span><span class="n">c1</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">createNewMapCanvas3D</span><span class="p">(</span><span class="s">'South View'</span><span class="p">)</span>
<span class="n">c2</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">createNewMapCanvas3D</span><span class="p">(</span><span class="s">'West View'</span><span class="p">)</span>
<span class="n">c3</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">createNewMapCanvas3D</span><span class="p">(</span><span class="s">'North View'</span><span class="p">)</span>
<span class="n">c4</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">createNewMapCanvas3D</span><span class="p">(</span><span class="s">'East View'</span><span class="p">)</span>
<span class="c1"># Apply settings to all open 3D map views
</span><span class="k">for</span> <span class="n">canvas</span> <span class="ow">in</span> <span class="n">iface</span><span class="p">.</span><span class="n">mapCanvases3D</span><span class="p">():</span>
<span class="n">canvas</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">().</span><span class="n">setEyeDomeLightingEnabled</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="c1"># Define a camera pose to update the views' cameras
</span><span class="n">pose</span> <span class="o">=</span> <span class="n">QgsCameraPose</span><span class="p">()</span>
<span class="n">pose</span><span class="p">.</span><span class="n">setCenterPoint</span><span class="p">(</span><span class="n">QgsVector3D</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">210</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="c1"># This is in 3D world coordinates
</span><span class="n">pose</span><span class="p">.</span><span class="n">setDistanceFromCenterPoint</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="n">pose</span><span class="p">.</span><span class="n">setPitchAngle</span><span class="p">(</span><span class="mi">75</span><span class="p">)</span> <span class="c1"># Tilt the camera by 75 degrees
</span><span class="n">pose</span><span class="p">.</span><span class="n">setHeadingAngle</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Looking towards North
</span><span class="n">c1</span><span class="p">.</span><span class="n">cameraController</span><span class="p">().</span><span class="n">setCameraPose</span><span class="p">(</span><span class="n">pose</span><span class="p">)</span>
<span class="n">pose</span><span class="p">.</span><span class="n">setHeadingAngle</span><span class="p">(</span><span class="mi">90</span><span class="p">)</span> <span class="c1"># Towards East
</span><span class="n">c2</span><span class="p">.</span><span class="n">cameraController</span><span class="p">().</span><span class="n">setCameraPose</span><span class="p">(</span><span class="n">pose</span><span class="p">)</span>
<span class="n">pose</span><span class="p">.</span><span class="n">setHeadingAngle</span><span class="p">(</span><span class="mi">180</span><span class="p">)</span> <span class="c1"># Towards South
</span><span class="n">c3</span><span class="p">.</span><span class="n">cameraController</span><span class="p">().</span><span class="n">setCameraPose</span><span class="p">(</span><span class="n">pose</span><span class="p">)</span>
<span class="n">pose</span><span class="p">.</span><span class="n">setHeadingAngle</span><span class="p">(</span><span class="mi">270</span><span class="p">)</span> <span class="c1"># Towards West
</span><span class="n">c4</span><span class="p">.</span><span class="n">cameraController</span><span class="p">().</span><span class="n">setCameraPose</span><span class="p">(</span><span class="n">pose</span><span class="p">)</span>
<span class="c1"># 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
</span><span class="n">canvas</span> <span class="o">=</span> <span class="n">iface</span><span class="p">.</span><span class="n">mapCanvas</span><span class="p">()</span>
<span class="n">canvas</span><span class="p">.</span><span class="n">extentsChanged</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="k">lambda</span> <span class="p">:</span><span class="n">c1</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">().</span><span class="n">setExtent</span><span class="p">(</span><span class="n">canvas</span><span class="p">.</span><span class="n">extent</span><span class="p">()))</span>
<span class="n">canvas</span><span class="p">.</span><span class="n">extentsChanged</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="k">lambda</span> <span class="p">:</span><span class="n">c2</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">().</span><span class="n">setExtent</span><span class="p">(</span><span class="n">canvas</span><span class="p">.</span><span class="n">extent</span><span class="p">()))</span>
<span class="n">canvas</span><span class="p">.</span><span class="n">extentsChanged</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="k">lambda</span> <span class="p">:</span><span class="n">c3</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">().</span><span class="n">setExtent</span><span class="p">(</span><span class="n">canvas</span><span class="p">.</span><span class="n">extent</span><span class="p">()))</span>
<span class="n">canvas</span><span class="p">.</span><span class="n">extentsChanged</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="k">lambda</span> <span class="p">:</span><span class="n">c4</span><span class="p">.</span><span class="n">mapSettings</span><span class="p">().</span><span class="n">setExtent</span><span class="p">(</span><span class="n">canvas</span><span class="p">.</span><span class="n">extent</span><span class="p">()))</span>
</code></pre></div></div>
<center>
<p><img title="Changing 3D view settings through Python" src="https://lutraconsulting.co.uk/img/posts/3d_scene_change_view.png" alt="Changing 3D view settings through Python" /></p>
<sub>Changing 3D view settings through Python</sub>
</center>
<h1 id="more-point-clouds-attributes">More point clouds attributes</h1>
<p>LAS/LAZ/COPC point clouds have a <code class="highlighter-rouge">classificationFlags</code> 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.</p>
<p>To make it easier to use, we are following the approach introduced in PDAL 2.6: the <code class="highlighter-rouge">classificationFlags</code> 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.</p>
<h1 id="performance-enhancement-for-rendering">Performance enhancement for rendering</h1>
<p>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.</p>
<p>Performance can vary depending on actual data, but on a local sample COPC file, it renders 7 times faster with this change.</p>
<h1 id="labels-for-mesh-layer">Labels for mesh layer</h1>
<p>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.</p>
<p>To display labels for your mesh data, simply open the styling panel and enable labels for:</p>
<ul>
<li>Labels on Vertices</li>
<li>Labels on Surfaces</li>
</ul>
<center>
<p><img title="Label settings for mesh layers" src="https://lutraconsulting.co.uk/img/posts/mesh_label_settings.png" alt="Label settings for mesh layers" /></p>
<sub>Label settings for mesh layers</sub>
</center>
<p>Below is an example of mesh Z values at vertices (yellow) and mesh areas at cell centre (purple):</p>
<center>
<p><img title="Example of labels on a mesh layer" src="https://lutraconsulting.co.uk/img/posts/mesh_labels.png" alt="Example of labels on a mesh layer" /></p>
<sub>Example of labels on a mesh layer</sub>
</center>
<h1 id="want-more-changes-in-qgis">Want more changes in QGIS?</h1>
<p>Do you want to see more improvements and new features in QGIS? Do not hesitate to <a href="mailto:info@lutraconsulting.co.uk">contact us</a> to discuss your requiremnets.</p>anitagraser.com: Finding geospatial accounts on Mastodon2024-02-03T09:56:25Zunderdarknospam@nospam.comhttps://anitagraser.com/2024/02/03/finding-geospatial-accounts-on-mastodon/<p>Besides following hashtags, such as #GISChat, #QGIS, #OpenStreetMap, #FOSS4G, and #OSGeo, curating good lists is probably the best way to stay up to date with geospatial developments.</p>
<p>To get you started (or to potentially enrich your existing lists), I thought I’d share my <a href="https://gist.github.com/anitagraser/a37118d74b839602e0f474375f548dfd">Geospatial and SpatialDataScience lists</a> with you. And the best thing: you don’t need to go through all the >150 entries manually! Instead, go to your Mastodon account settings and under “Import and export” you’ll find a tool to import and merge my list.csv with your lists: </p>
<figure class="wp-block-image size-large"><a href="https://anitagraser.com/wp-content/uploads/2024/02/image.png"><img loading="lazy" width="1024" height="594" data-attachment-id="8782" data-permalink="https://anitagraser.com/2024/02/03/finding-geospatial-accounts-on-mastodon/image-44/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/02/image.png" data-orig-size="1117,648" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=1024" alt="" class="wp-image-8782" srcset="https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=1024 1024w, https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=300 300w, https://anitagraser.com/wp-content/uploads/2024/02/image.png?w=768 768w, https://anitagraser.com/wp-content/uploads/2024/02/image.png 1117w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>
<p>And if you are not following the geospatial hashtags yet, you can search or click on the hashtags you’re interested in and start following to get all tagged posts into your timeline: </p>
<figure class="wp-block-image size-large"><img loading="lazy" width="590" height="169" data-attachment-id="8791" data-permalink="https://anitagraser.com/2024/02/03/finding-geospatial-accounts-on-mastodon/image-3-11/" data-orig-file="https://anitagraser.com/wp-content/uploads/2024/02/image-3.png" data-orig-size="590,169" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-3" data-image-description="" data-image-caption="" data-medium-file="https://anitagraser.com/wp-content/uploads/2024/02/image-3.png?w=300" data-large-file="https://anitagraser.com/wp-content/uploads/2024/02/image-3.png?w=545" src="https://anitagraser.com/wp-content/uploads/2024/02/image-3.png?w=590" alt="" class="wp-image-8791" srcset="https://anitagraser.com/wp-content/uploads/2024/02/image-3.png 590w, https://anitagraser.com/wp-content/uploads/2024/02/image-3.png?w=150 150w, https://anitagraser.com/wp-content/uploads/2024/02/image-3.png?w=300 300w" sizes="(max-width: 590px) 100vw, 590px" /></figure>Mergin Maps: [Changelog] Enhanced synchronization performance and stability2024-02-01T13:25:27Znospam@nospam.comhttps://wishlist.merginmaps.com/changelog/enhanced-synchronization-performance-and-stability?utm_source=qgis<p>The mobile app 2.5.0 contains multiple synchronization fixes and enhancements. Enjoy faster and more reliable file transfers!</p>Mergin Maps: [Changelog] Enhanced feature identification speed2024-02-01T13:25:27Znospam@nospam.comhttps://wishlist.merginmaps.com/changelog/enhanced-feature-identification-speed?utm_source=qgis<p>In our latest update, we've turbocharged the speed of feature identification on the map! Enjoy a faster and more responsive experience as you navigate and identify features with efficiency.</p><p></p>Mergin Maps: [Changelog] Enhanced viewing: zoom feature now available in the mobile app2024-02-01T13:25:27Znospam@nospam.comhttps://wishlist.merginmaps.com/changelog/enhanced-viewing-zoom-feature-now-available-in-the-mobile-app?utm_source=qgis<p>In our latest mobile app update, we've added an enhanced viewing feature that allows users to smoothly zoom in and out of images. This new functionality provides a more detailed and flexible viewing experience, letting you focus on intricate details or take in the big picture with ease. Navigate your visual data with precision and control!</p><img src="https://vault.featureos.app/uploads/attachment/upload/thumb-e64e44810b242ba9627d61b042e4b4f0.gif" /><p></p><p></p><p></p>Mergin Maps: [Changelog] Reset local changes from QGIS2024-02-01T13:25:27Znospam@nospam.comhttps://wishlist.merginmaps.com/changelog/reset-local-changes-from-qgis?utm_source=qgis<p>With Mergin Maps QGIS Plugin 2024.1 you can now revert local changes of your QGIS project. Click on synchronise button in the toolbar and in the “Project status” dialog you will see new button to “Reset Changes”</p><p>Read the full changelog of the release: <a href="https://github.com/MerginMaps/qgis-plugin/releases/tag/2024.1" rel="noopener noreferrer nofollow" target="_blank">https://github.com/MerginMaps/qgis-plugin/releases/tag/2024.1</a></p>Mergin Maps: [Changelog] Position tracking is now available2024-02-01T13:25:27Znospam@nospam.comhttps://wishlist.merginmaps.com/changelog/position-tracking-is-now-available?utm_source=qgis<p>I am pleased to announce that <strong>position tracking 📡 </strong>has been released today as part of Mobile version 2.3.0 and Plugin version 2023.3.</p><p>You can learn more about the tracking feature and how to set it up by visiting: <a href="https://merginmaps.com/docs/field/tracking/" rel="noopener noreferrer nofollow" target="_blank">https://merginmaps.com/docs/field/tracking/</a></p><p>Enjoy the tracking, and please let us know your thoughts! If you encounter any issues, please don’t hesitate to contact us.</p>Mergin Maps: [Case Study] Improving wildfire prevention and firefighting readiness2024-02-01T13:25:27Znospam@nospam.comhttps://merginmaps.com/case-studies/improving-wildfire-prevention-and-firefighting-readiness?utm_source=qgisDavid Galloway works as a volunteer with the Wallcliffe Volunteer Fire Brigade in Western Australia. Volunteer brigades are the front line of firefighting and prevention across the State.