This post is about the making of an experimental video that dives into the land cover of Paris & its surroundings with a hint of RGB magic.
You'll see the purpose of gridding, how to cross a vector and a raster layer in R. Finally we'll cover one of the latest functionnality of QGIS 2.12 : data-defined layer combinations in atlases.
If the world were square
|
do you prefer ice creams or sandwiches ? |
|
Matrix is the first movie approaching grids |
Gridding is a way to simplify the representation of data on a large scale. It can be a useful way to "resample" the vision of a territory if you work on bigger units. These units, usually squares, are comparable, on the contrary to administrative units. If you can omit the administrative units, gridding is a way to get an homogeneous view of your territory. The larger your area of interest will be, the bigger the squares from your grid you might configure.
|
hexagons look ecologic, triangles ecclesiastic |
Also, you could prefer hexagonal units to square units for more harmony. Some prefer triangles. Anyway, the number of possible shapes are limited.
Land Cover of Paris & surroundings
I wanted to visualize the land cover of Ile-De-France width a grid. Ile-de-France is a region that includes Paris at its center. Precisely, I decided to study the repartition of urban , agricultural and natural (forests, gardens, etc...) areas, that is 3 variables over the whole area.
|
the best diagram I've ever made, even if pie charts are the worst |
The question was : how to represent 3 variables at a time on each square unit ? One answer could have been "diagrams", that is pie charts, histograms on the map
But I found it cooler to use an RGB representation.
|
A Freemason way of seeing data |
Let's suppose
R means urban,
G Natural and
B Agricultural. If the color of a square approaches
red, then it means urban; if it is
purple, it means urban & agricultural areas dominate but not natural; if it is
desaturated, it means the 3 types of cover are equally mixed.
The recipe
|
I remember a mushroom im my parents'garden had the same shape |
For the land cover of Ile-de-France, we have
a nice 2012 Corine Land Cover GeoTiff.
|
Laurent Manadou exploring data |
I wondered if one could adopt a dynamic view that goes from the global view to the zonal one in a sort of "data diving".
|
beware of the logarithmic launching pad |
I wondered what series of sizes to adopt. I decided to generate 100 images. 1km would be the minimum unit and we would reach the BIG square covering all the region, the width of Ile-De-France being precisely 154 451 km according to
GÉOFLA. The distribution, as illustrated, will be logarithmic.
|
The same sensation appears when you dive head first in a municipal pool |
Above is a GIF presenting the different calculation canvases.
Here is the video with land cover percentages encoded as colors, with reversed order, from the biggest to the smallest unit. The changing colors make it kind of animated dancefloor.
|
Dataekwondo |
This illustration, that I had made for a
GéoTribu post, illustrates the usual workflow I adopt, from production to design. I generated the distinct grids associated with the land cover percentage values with
R. I designed all the layers with
QGIS. With the same tool, I generated an atlas. With this atlas, I created a video with
ffmpeg.
Technical details
The QGIS part may interest the QGIS fans as it uses a new QGIS 2.12 functionnality :
data defined control over map layers and style presets
Generation : R
I created a function in R that generates a grid. The hack consists in polygonizing a raster layer, of which the resolution determinates the square size :
creerGrille = function(pol, size=50000) {
r = raster(extend(extent(pol), size)); res(r) = size; r[]=1
grille = rasterToPolygons(r)
grille = grille[which(gIntersects(grille, pol, byid=T)), ]
grille = grille[-which(gTouches(grille, reg, byid=T)), ]
return(grille)
}
The extract function crosses the vector grid and the 2012 CLC raster. The table function gives the number of pixels of each category :
counts = extract(clc2, grille,
method="simple",
fun=function(x,...)table(x),
na.rm=T)
The prop.table calculates the proportion of urban, natural and agricultural areas :
Design : QGIS
|
color RGB code from columns, named "R", "G", and "B" |
An expression defines the color of each square depending on its column values :
|
MultiQML plugin |
I saved the QML style file, then used the
multiQML plugin to apply it to the 99 other layers.
|
Data defined control over map layers and style presets |
To get a static coverage layer, I duplicated my area of interest as many times as the number of pages (or layers) and assigned the square size value to the layer names. In the latest version of QGIS, you can generate an atlas with a list of layers on each page defined by an expression.
Also, I used some
generative design tricks to get the animated halo effect around the IDF region.
|
Shapeburst fill and data-defined color |
The color follows the chromatic color circle, covering all the rainbow colors :
color_hsv(scale_linear(@atlas_featurenumber,1,100,0,360),40,27)
|
riding the wave of generative design |
|
sin wave shade distance |
while a sin function defines the shade distance. This way, we get a "flame" effect with increasing then decreasing shade width.
scale_linear(sin(scale_linear(@atlas_featurenumber,1,100,0,pi()*2)),0,1,5,10)
Video making: ffmpeg
Finally, this command line generates the video from images :
ffmpeg -framerate 25 -r 10 -i output_%d.jpg -vcodec mpeg4 -b 50000k -qscale:v 1 dancingVideo.avi
The code
The functions
The processing code
Credits
Images from
The Noun Project : diver
by Claire Jones, honey
by Angela Horton, sandwich
by Gareth Servant, biker
by Les vieux garçons, ice cream
by Rafaël Massé.
Aucun commentaire:
Enregistrer un commentaire