Category Archives: qgis

Fake chromatic aberration and dynamic label shadows in QGIS

Welcome to Part 43 of “Fun with Weird Hacks in QGIS”!

Fake Chromatic Aberration

Get some lines or polygons! I used German administrative polygons and a “Outline: Simple line” style.

Add a “Geometry Generator” to the same layer and set it to “LineString / MultiLineString”. If you used polygons, you will need to use “boundary($geometry)” to get the border lines of your polygons.

Translate (shift) the geometries radially away from the map center, with an amount of translation based on their distance to the map center. This will introduce ugly artifacts cool glitches for big geometries. Note the magic constant of 150 I divided the distances by, I cannot be arsed to turn this into percentages so you will have to figure out what works for you. Also, if your map is in a different CRS than the layer you do this with, you will need to transform the coordinates (I do that for the labels below).

 translate(
   boundary($geometry),
   (
    x(centroid($geometry))-x(@map_extent_center)
   )/150
   ,
   (
    y(centroid($geometry))-y(@map_extent_center)
   )/150
)

Color those lines in some fancy 80s color like #00FFFF.

We only want the color to appear in the edges of the map, so set the “Feature Blending” mode of the layer to “Lighten”. This will make sure the white lines do not get darker/colored.

I forgot to take an image for that and then it was lunch time. :x

Now do the same but for distances the other way around and color that in something else (like foofy #FF00FF).

 translate(
   boundary($geometry),
   (
    x(@map_extent_center)-x(centroid($geometry))
   )/150
   ,
   (
    y(@map_extent_center)-y(centroid($geometry))
   )/150
)

Oh, can you see it already? Move the map around! Ohhh!

For the final touch, use the layer’s “Draw Effects” to replace the “Source” with a “Blur”. Be aware that the “Blur type” can quite strongly influence the look and find a setting for the “Blur strength” that works for you. I used “Guassian blur (quality)” with a strength of 2.

Dynamic Label Shadows

Get some data to label! I used ne_10m_populated_places_simple. Label it with labels placed “Offset from Point” without any actual offset. This is just to make sure calculations on the geometry’s location make sense to affect the labeling later.

Pick a wicked cool font like Lazer 84!

Add a “Buffer” to the labels and pick an appropriate color (BIG BOLD #FF00FF works well again).

Time for magic! Add a “Shadow” to the labels and use an appropriate color (I used the other color from earlier again, #00FFFF).

We want to make the label shadows be further away from the label if the feature is further away from the map center. So OVERRIDE the offset with code that does exactly that. Note another magic constant (relating to meters in EPSG:25832) and that I needed to transform coordinates here (my map is in EPSG:25832 while this layer is EPSG:4326).

distance(  
	transform(
		$geometry, 'EPSG:4326', 'EPSG:25832'
	),
	@map_extent_center
)/10000

Cool. But that just looks weird. Time for another magical ingredient while OVERRIDING the angle at which the label is placed. You guessed it, radially away from the map center!

degrees(
	azimuth(  
		transform(
			$geometry, 'EPSG:4326', 'EPSG:25832'
		),  
		@map_extent_center)
	)
-180

By the way, it does look best if your text encoding is introducing bad character marks and missing umlauts!

That’s it, move the map around and be WOWed by the sweet effects and the time it takes to render :o)

And now it is your turn to apply this to some MURICA geodata and rake in meaningless internet points that make you feel good! Sad but true ;)

And also TODO: Make the constants percentages instead, that should make sure it works on any projection and any scale.

Making a Star Wars hologram in QGIS

I like doing silly things in QGIS.

So I wanted to make a Star Wars hologram (you know, that “You’re my only hope” Leia one) showing real geodata. What better excuse for abusing QGIS’ Inverted Polygons and Raster Fills. So, here is what I did:

  1. Find some star wars hologram leia image.
  2. Crudly remove the princess (GIMP’s Clone and Healing tools work nicely for this).
  3. In QGIS create an empty Polygon-geometry Scratchpad layer and set the renderer to Inverted Polygons to fill the whole canvas.
  4. Set the Fill to a Raster image Fill and load your image.
  5. Load some geodata, style it accordingly and rejoice.
    1. Get some geodata. I used Natural Earth’s countries, populated places and tiny countries (to have some stuff in the oceans), all in 110m.
    2. Select a nice projection, I used “+proj=ortho +lat_0=39 +lon_0=139 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs”.
    3. I used a three layer style for the countries:
      • A Simple Line outline with color #4490f3, stroke width 0.3mm and the Dash Dot Line stroke style.
      • A Line Pattern Fill with a spacing of 0.8mm, color #46a8f3 and a stroke width of 0.4mm.
      • And on top of those, for some noisiness a black Line Pattern Fill rotated 45° with a spacing of 1mm and stroke width 0.1mm.
      • Then the Feature Blending Mode Dodge to the Layer Rendering and aha!
      • More special effects come from Draw Effects, I disabled Source and instead used a Blur (Gaussian, strength 2) to lose the crispness and also an Outer Glow (color #5da6ff, spread 3mm, blur radius 3) to, well, make it glow.





    4. I used a three layer style for the populated places:
      • I used a Simple Marker using the “cross” symbol and a size of 1.8mm. The Dash Line stroke style gives a nice depth effect when in Draw Effects the Source is replaced with a Drop Shadow (1 Pixel, Blur radius 2, color #d6daff).
      • A Blending Mode of Addition for the layer itself makes it blend nicely into the globe.
    5. I used a three layer style for the tiny countries:
      • I used a white Simple Marker with a size of 1.2mm and a stroke color #79c7ff, stroke width 0.4mm.
      • Feature Blending Mode Lighten makes sure that touching symbols blob nicely into each other.




  6. You can now export the image at your screen resolution (I guess) using Project -> Import/Export or just make a screenshot.
  7. Or add some more magic with random offsets and stroke widths in combination with refreshing the layers automatically at different intervals:

Building QGIS with debugging symbols

As I keep searching the web for way too long again and again, I hope this post will be #1 next I forget how to build QGIS with debugging symbols.

Add CMAKE_BUILD_TYPE=Debug to the cmake invocation.

E.g.:

cmake -G "Unix Makefiles" ../ \
    -DCMAKE_BUILD_TYPE=Debug
    ...

For a not as safe but more performant compilation, you can use RelWithDebInfo. I just found out today but will use that in the future rather than the full-blown Debug. See https://cmake.org/pipermail/cmake/2001-October/002479.html for some background.

On Archlinux, also add options=(debug !strip) in your PKGBUILD to have them not stripped away later.

Writing one WKT file per feature in QGIS

Someone in #qgis just asked about this so here is a minimal pyqgis (for QGIS 3) example how you can write a separate WKT file for each feature of the currently selected layer. Careful with too many features, filesystems do not like ten thousands of files in the same directory. I am writing them to /tmp/ with $fid.wkt as filename, adjust the path to your liking.

layer = iface.activeLayer()
features = layer.getFeatures()

for feature in features:
  geometry = feature.geometry()
  wkt = geometry.asWkt()
  
  fid = feature.attribute("fid")
  filename = "/tmp/{n}.wkt".format(n=fid)
  
  with open(filename, "w") as output:
    output.write(wkt)

QGIS: “no result set” with PostGIS

If QGIS tells you “no result set” while you are playing around with PostGIS query layers. If your query works fine in the DB Manager but “Load as Layer” fails (and not silently with “invalid PostgreSQL layer”).

Try turning it off and on again. Restart QGIS. It just might save you many minutes of unreasonable frustration.

More structural detail in hillshading with this one weird trick

I wanted to have more structural detail in my QGIS live hillshading so I blended a duplicate layer with the sun angle set to directly overhead (90°) and the blending mode as darken.

It seems to make steep structures more prominent.

A hurricane map in QGIS, from geodata and hacks

Cartography Inspirationator John Nelson made an awesome map of hurricanes and later posted detailed how-tos for ArcMap and recently ArcGIS Pro. Right after his first post I started rebuilding it in QGIS using draw effects for adding the colored outer glow instead of using image icons, adding a vignette on-the-fly and adjusting the background raster’s saturation on the fly. All in all, less manual work, more dynamic processing in QGIS. I quickly got frustrated though and gave up.

More than a year later (triggered by the new ArcGIS Pro how-to storymap) I revisited my draft and finished it. So here is the QGIS version. As no-one is paying me to write this, I currently cannot be arsed to make it as fancy as John’s posts. Sorry! :)

This project shows QGIS’ strength in features and struggle with performance. Also some bugs. I stopped working on this once I liked the looks. It is not optimized in any way. So this is just how I ended up doing it. You could do much better. I like proof of concepts. And short sentences.

Data sources (I host a lightning-fast mirror of Natural Earth at https://www.datenatlas.de/geodata/public/sources/www.naturalearthdata.com/ if downloads are 404 again…):

That’s right, nothing but pure, unaltered geodata!

  1. Load the NE2_LR_LC_SR_W_DR.tif raster. Lower the saturation to about -50.
  2. Set your project’s projection to EPSG:3031 so that you get a nice polar viewpoint.
  3. Rotate the canvas by 150° because that’s what John did.
  4. Load the graticules. Use a rule-based style for ‘"direction" = 'W' or "direction" = 'E' or "direction" is NULL‘ so that you get all longitudes but only the equator from the latitudes. Set the layer transparency to 60 or something like that.
  5. Load the coastline.
  6. Add a vignette using this trick.
  7. Load the Allstorms.ibtracs_all_points.v03r09.shp Shapefile and then:
    1. Create a rule-based style with rules for the storm categories. I think I used this.
    2. Use white markers without outlines. Set their sizes using an expression on the wind speed or like me, manually to e.g. 0.7, 0.8, 1, 1, 1.6, 2 millimeters. This is something to play around with until it looks good.
    3. I used transparency for the markers of the lowest classes, 85% and 70%, the others are not transparent. This is something to play around with until it looks good. If I recall correctly I used transparency on the layer level here to keep the bubbly looks.
    4. By now you should be quite annoyed at how slow the rendering process is. >:) But wait, it gets much worse! :o)
    5. For each of the classes, enable draw effects on the markers.
    6. Set the source to use Addition blend mode. Set the source to be somewhat transparent, I used 50%, 80%, 80%, 50%, 40%, 0%. This is something to play around with until it looks good.
    7. Add outer glow and choose an appropriate color (Hint: Use a lot of saturation). Then play around with the spread, blur radius and transparency until it looks good. For some reason I ended up using 1mm/3/95%, 1mm/4/95%, 1mm/3/80%, 1.2mm/4/50%, 1.5mm/4/40%, 3mm/1/50%. Only now that I post this I realise how weirdly inconsistent this is and a quick test shows how irrelevant the blur radius changes are (except for the highest class). Oh well. It’s not fun to interate if you have to click so much and rendering that 40-50 seconds…
  8. That’s it! Done!

This was both fun and incredibly annoying. QGIS has the features but lacks in speed for this funky project (no wonder, blending 300,000 glowing points is not that nice). Here is a realtime video of how it rendered on my machine (take away some seconds from manually enabling the layers after another):

PS: Oh god this WordPress style sucks…

Flowers in QGIS?

The other day I was working on visualisation of some intermediate research stuff and ended up with something looking like a bouquet of flowers.

Twitter liked it so here is a how-to.

  1. Have some lines that meet in a shared point. They should have a shared ID per group (in my case they were MultiLineStrings).
  2. Color them per ID.
  3. Turn the background black.
  4. Use an Arrow style for the lines. Set the Head thickness to half the Arrow width. Set the Head length to whatever you consider fancy.
  5. Remove the Outline (set No Pen).
  6. Set the Feature blending mode to Multiply (or to Screen or Dodge or Addition if you prefer fireworks to flowers).
  7. Set an appropriate color scheme. For flowers I think RdYlGn works great (that’s how I realised what my random tinkering had lead to) or PiYg or simply Spectral, for fireworks random colors.

That’s it! Now play around and have some fun!

This Stain On Old Paper Looks Just Like Germany OMG!

Following Doing things to the whole map canvas in QGIS and adding some blending to the mix (he-he), I ended up with this map. Nothing you could not do with simple post-processing in a raster image editor or even QGIS’ map composer I guess.

stain

It was simply the result of playing around, there probably is a faster or more efficient way.

First give your geometries some fancy texture with Raster image fill (left). Then constrict its display to just some blurry borders by using a grey fill, Blur draw effect with maximum strength and the Dodge Layer blending mode (right).

papergermanyborder

You could probably skip the texture for the geometry but I did not manage to get a similarly nice effect with a Simple fill.

Use the trick from Doing things to the whole map canvas in QGIS to fill your canvas with a polygon and give that a nice texture as well. Use Multiply as Layer blending mode and get social media hype for that unbelievable stain can you believe it looks like that???

From the same session comes this beauty (mostly due to Tom Patterson’s shading of course ;) ):
antarctica

Doing things to the whole map canvas in QGIS

Due to a minor bug in QGIS you need a very recent testing build. 2.16.3 is not recent enough but 2.16.4 would be.

For cool tricks like vignetting or other eye candy, having a geometry that spans the whole map canvas in QGIS can be very useful.

Using the @map_* Variables available in expressions in combination with a Geometry generator style allows you to do this.

@map_extent_center returns a Point geometry of the current map canvas center, with x(@map_extent_center) and y(@map_extent_center) you get the x and y coordinates of it in the current CRS.
@map_extent_width and @map_extent_height return the width respectively height of the map canvas in CRS units.

Our goal is to create a polygon that exactly matches the map canvas extents. Some simple math gets you there.

First create Points for each of the corners by alternating the x+/-width and y+/-height. Then create a Line from all of them (the last point does not need to be the first again, make_polygon does that for you). And use the line as outer ring for a Polygon.

make_polygon(
 make_line(
  make_point(x(@map_extent_center)-@map_extent_width/2, y(@map_extent_center)-@map_extent_height/2),
  make_point(x(@map_extent_center)+@map_extent_width/2, y(@map_extent_center)-@map_extent_height/2),
  make_point(x(@map_extent_center)+@map_extent_width/2, y(@map_extent_center)+@map_extent_height/2),
  make_point(x(@map_extent_center)-@map_extent_width/2, y(@map_extent_center)+@map_extent_height/2)
 )
)

To actually see this, you need to use the style on a layer with at least one feature that is always visible where you want to focus your map canvas. Just make a polygon layer with one polygon that encloses the whole area. The layer must be in the same CRS as the project I think.

You now have a Polygon that corresponds with the map canvas. Give it a radial gradient fill with some transparency and party!

radialgradient
hh-bw
schiff-bw
stadion-bw
stadion-red

All aerial images in the examples are

Lizenz: Datenlizenz Deutschland Namensnennung 2.0
Namensnennung: Freie und Hansestadt Hamburg, Landesbetrieb Geoinformation und Vermessung
http://daten-hamburg.de/geographie_geologie_geobasisdaten/digitale_orthophotos/DOP20/DOP20_HH_fruehjahrsbefliegung_2015.zip

To make sure the feature you want to highlight is in the center, you could use another layer and @map_extent_center.

Yes, this totally is a hack but it’s fun!