Visualising QGIS data with Blender
Today I'll showcase a workflow I've been working on where I output data from QGIS and render it in 3D with Blender. I've used it for graphically visualising analysis output, and this post will first show examples of this, followed by a run through of the workflow.
If you're not familiar with Blender, it's a very powerful 3D modelling package that is also free and open source. You can download it and see some of its capabilites at www.blender.org.
[Edit 15/1 - 2013]
A fellow called DomLysz mailed me about a plugin he made for blender which allows the direct import of shapefiles and georasters. It makes the process described below A LOT smoother, probably cutting out all the preparations in QGIS. Presently you can find it here.
[/Edit]
[Edit 3/12 - 2012]
It struck me that I should probably introduce QGIS as well, if you just stumbled upon this post. QGIS, or Quantum GIS, is a free, open source Geographic Information System on par with commercial packages like ArcGis. More info and download is available at www.qgis.org.
[/Edit]
The first example is the result of a thought experiment. I'm currently involved in drafting the master plan for the city of Hässleholm, and one of the issues that have been discussed is density. As it is today, new construction tends to be area intensive single home developments and we started pondering how that would look if the trend continues. As such, we took the population increase from the last 7 years and projected that into the future to 2030 with two scenarios: "If we turn this population increase into single houses, what kind of area would that require as opposed to solving it with densification in the town center?"
Below is how I visualised the result. The circle is a 1 kilometer radius from the train station. Click for larger images.
4000 new inhabitants in single homes
4000 new inhabitants through densification
These images were much appreciated by the planning staff, other departments as well as the politicians who in the end are supposed to take the decisions regarding the master plan. I think the 3D presentation worked well for this kind of task as it made things a bit more tangible to people not used to reading maps.
The second example is a quick proof of concept for using DEM data in Blender. The geographic coverage is an area around Mariental and the Hardap dam, Namibia. The data comes from USGS Explorer.
I'd like to make clear that the results you get from this workflow are not meant for detailed analysis. They are meant as visualisation aid for analysis already completed within QGIS, or simply showcasing for example different planning proposals.
So, to the actual process.
In a nutshell, what I've done is output my vector data from a QGIS layout view as an SVG and then my raster data as images from the same view. When you export to SVG, apart from your map features (like buildings) QGIS also outputs a plane that is the size of the paper in its' layout view. And if your map viewport is the same size as the paper, you can use your aerial photo to texture that plane, and a black and white height map to displace it to get a terrain model.
So basically, you output three files from the same layout view; (1) an SVG that consists of your vector features and a background plane that is the same size as the view, (2) an aerial photo to texture the background plane with, and (3) a black and white height map to displace that plane with.
I'll assume that you're familiar with QGIS and Blender, so I wont be super detailed in each step. But if you run into problems you're welcome to contact me (info at the bottom of the page). I'll also assume that you have a QGIS project with an aerial photo raster, DEM raster, and a vector layer with for example buildings.
If you want some data to practice with you can get good elevation data and aerial photos from the USGS explorer and complement it with buildings and roads from OpenStreetMap (which QGIS has excellent tools for downloading from out of the box. Just remember to credit them if you publish something). I used data from work (urban planning office at the municipality of Hässleholm, Sweden).
Now, let's go through the steps.
First fire up a new layout view in QGIS. Make a new map in it and place it at the corner of the paper. I just turned the grid on and snapped it into the corner. Then make it the same size as the paper so that it perfectly covers the it. I just went with the default A4, so I got 297 x 210 mm. Make sure your extents are completely within your terrain raster. The result should look something like so:
Now now turn off all layers except your vector layers and save the layout as an SVG. Now turn off everything except your aerial photo and save the layout again, but this time as an image (I used PNG). Repeat this for the heightmap. Make sure you show the heightmap in grayscale and that you have stretched its contrast between the min and max values. Also make sure you save the bitmaps in a filepath without strange characters (like ö), otherwise they wont render (bug in Blender 1.63). Results should look like so:
Vector layers to save as SVG
Aerial photo to save as bitmap
Terrain model with contrast stretched to min and max values, save as bitmap
Now fire up Blender. Prepare by changing the rendering engine to Cycles and opening a UV-editor. Then import the SVG you created. Select all objects and set Origin to Geometry (Blender imports all SVG objects with their origin at the origo). You'll notice that there are actually three background planes created by QGIS. We only need one of these so remove the other two. Results should look like this (turned on wireframe rendering to show the spread out origins):
Now convert the background plane to a mesh (Alt + C). Go into edit mode, select the face of the plane and open your the bitmap with the aerial photo you saved earlier. Change your view so that you are looking from the top onto the plane, and open the UV menu for the plane (press U). Choose "Project from view (bounds)". Should look something like this:
Remove the SVG material Blender imported from the original file and add a new material with the aerial photo as texture. It should map it correctly with your UV map like so:
Next up, add a Displace modifier to the plane and connect it to the heightmap image. Make sure the Texture Coordinates in the modifier are set to UV. Just choose the UV map you created for the aerial photo (since they have the same extents).
Now you want to subdivide the plane so the displacer has some vertices to work with.Obviously, the more subdivisions the better it will look.
I also added a Smooth modifier after the displacer. Fiddle around with the number of smoothing operations and the strength of the displacer until the image suits your purposes (remember what I said about this not being something you can use to make accurate spatial calculations? Yeah...)
When you're happy with the terrain it's time to turn our attention to the buildings. To simplify things, select all the buildings and join them into one object (Ctrl + J). Then add a Shrinkwrap modifier to the building object and point it at the terrain object. Move the origin of the buildings as close to the terrain surface as possible and apply the modifier. Now you can just extrude the buildings (which are still curves). Should look like this (in wireframe mode):
The shrinkwrap works perfectly well for road layers as well, just use a short straight curve as an extrusion object for the road curve object.
Finally, set up your camera and lighting, and render the image. Here's my result:
The model I made for this tutorial is pretty crude, but with some refinement they can look very good. Obviously there are a million ways to do this and I encourage you to experiment (and if you find better ways of getting data out of QGIS into Blender, please let me know!).
[Edit 3/12 - 2012]
I came back to this as I wanted to show an alternate visualisation method. In the below image I used a height based colour map instead of the aerial photo, and made the model more fine grained.
I'd also like to add two comments. First of all I'd like to just note, if any QGIS devs are reading, that it would be very cool if QGIS could automagically accomplish the above process by outputting a 3D file containing a textured mesh based on a DEM + aerial photo. Just a little item for the wishlist.
Secondly, I'd like to point out that Blender has super smooth export to the Unity 3D engine, so it would be very easy to turn a model like this into an interactive environment that way. Maybe something for a later post...
[/Edit]
Thank you for your time,
Anton
If you have questions or comments, please drop me a mail on [email protected] or give me a shout on Twitter where I am @guldalder














