1 of 38

Solving Complex Spatial Analysis Problems with QGIS

Ujaval Gandhi

Spatial Thoughts LLP

ujaval@spatialthoughts.com

QGIS Open Day

August 2023

2 of 38

Watch Video Recording

3 of 38

Spatial Thoughts

  • A learning platform for modern geospatial technologies.
  • Free and open learning content for QGIS, Python, GDAL and Google Earth Engine.
    • Learning materials used by 1 million+ users every year.
    • All material is licensed under CC-BY
  • Online academy for cohort-based instructor-led classes.
    • Personalized mentoring and support
    • Trained participants from over 100 countries.

✅ QGIS.org certified training provider

✅ QGIS.org sustaining member

❤️

4 of 38

#SpatialAnalysisChallenge

  • A friendly challenge to inspire the geospatial community to spark creativity and enhance their skills.
  • Challenges are inspired from real-world issues.
  • Participants are encouraged to use any software, programming language, database or systems they are familiar with.

5 of 38

The Past Challenges

  • Extract Buildings with Holes
  • Name a Line Layer with Closest Points
  • Connect buildings to Nearest Point on the Road
  • Count Points in Overlapping Polygons
  • Variable Buffers
  • Conditional Spatial Join

See the archive

6 of 38

In Today’s Talk

  • Extract Buildings with Holes
  • Name a Line Layer with Closest Points
  • Connect buildings to Nearest Point on the Road ✅
  • Count Points in Overlapping Polygons
  • Variable Buffers ✅
  • Conditional Spatial Join ✅

  • A Bonus Challenge ❓

7 of 38

Challenge 1:

Connect Buildings to Nearest Point on the Road

8 of 38

Problem Statement

Connect each building's road-facing edge to the nearest point on the street segment.

Datasets:

  • Building Polygons
  • Road Network Lines

Sample Data

9 of 38

10 of 38

Solution 1: QGIS Processing Algorithms

  • Convert each building polygon to lines and extract the centroid of each edge.
  • Connect each centroid with the roads layer
  • Extract the line with the shortest distance

Full Solution [video][model]

11 of 38

Solution 2: QGIS Expressions

  • Salvatore Fiandaca solved the problem in just 2 steps using QGIS Expressions
  • Used the functions with shortest_line() and overlay_nearest()
  • The resulting expressions can be implemented using Geometry Generators or using Geometry by Expression algorithm

Full solution [github]

12 of 38

Other Solutions

See the original Twitter Thread and LinkedIn Post with all solutions

13 of 38

PostGIS

14 of 38

RStats / Python / QGIS Expressions

15 of 38

Challenge 2:

Creating Variable Buffers

16 of 38

Problem Statement

Buffer each point in Layer A so that the buffer contains at exactly 5 points from Layer B

Datasets:

  • 2 Point Layers

Sample Data

17 of 38

18 of 38

Solution: QGIS Expressions

  • Abhimanyu S came up with a clever QGIS expression to compute the distance to the 5th neighbor for each point
  • Expression uses overlay_nearest() function to find the the 6th neighbor.
  • Use the distance() function to compute the buffer distance.
  • Expression is used in the ‘Buffer’ algorithm.

19 of 38

Solution: QGIS Expressions (Improved)

  • Michaël Galien suggested a PostGIS solution that is an improved version of the previous solution.
  • Instead of buffering by the distance of 5th neighbor and potentially missing the 5th point, we can compute distance between 5th and 6th neighbor and buffer by the average value.
  • We can adapt the previous QGIS expression to use this method.

Full Solution [video]

20 of 38

Other Solutions

See the original Twitter Thread and LinkedIn Post with all solutions

21 of 38

QGIS

22 of 38

RStats / Python

23 of 38

Google Earth Engine / FME

24 of 38

Challenge 3:

Conditional Spatial Join

25 of 38

Problem Statement

Add the name of the place within the polygon having the highest population

Datasets:

  • Urban Area Polygons
  • Populated Places Points

Sample Data

26 of 38

27 of 38

Solution 1: Geometry Generators

  • Totò Fiandaca used QGIS Expressions and Geometry Generators to dynamically find and label the point with the highest population.
  • Used nested overlay_contains() to find all intersecting points and then array_max() to pick the one with the highest population.

Full solution [twitter]

28 of 38

Solution 2: PyQGIS Processing Algorithms

  • A optimized join algorithm that makes use of a spatial index.
  • Find all intersecting point features within each polygon.
  • Sort the features by the chosen attribute (population) and pick the feature having the highest value
  • Copy the required attribute (name) from the selected feature

Full Solution [video][script]

29 of 38

Solution 3: PostGIS

  • PostgreSQL provides a DISTINCT ON expression that can be used with SELECT to remove duplicate and keep the first row of the result.
  • This makes it very easy to write a SQL query to find all intersecting points, sort them by population and keep the first one.
  • We can run this query via PostgreSQL execute SQL algorithm in QGIS Processing Toolbox.

30 of 38

Other Solutions

See the original Twitter Thread and LinkedIn Post with all solutions

31 of 38

PostGIS

32 of 38

QGIS Modeler / GeoPandas

33 of 38

Bonus Challenge:

Constrained Nearest Neighbor Analysis

34 of 38

Problem Statement

Connect each school to the nearest college in the same administrative region

Datasets:

  • School points
  • College points
  • Administrative boundary Polygons

Sample Data

35 of 38

36 of 38

37 of 38

Connect and Participate in the challenge!

38 of 38

Summary

  • QGIS offers a lot of functionality out-of-the-box!
  • Explore the Processing Toolbox and Modeler.
  • Expressions are very powerful. Learn to use aggregate expressions!
  • Use PyQGIS to extend the core toolset.
  • Connect QGIS with PostGIS to scale your analysis

Contact:

ujaval@spatialthoughts.com

Free QGIS learning materials

https://spatialthoughts.com/