Related Plugins and Tags

QGIS Planet

Mapping Density with Hexagonal Grids

A very common approach for mapping point density is to use heat maps. If you are aiming for a different style, give hexagonal grids a try. The workflow is very simple in QGIS:

  1. Load the point layer
  2. Create a hexagonal grid using MMQGIS – Create Grid Layer
  3. Count points per polygon (Vector menu)

I’ve applied this method to an OGD dataset of the Viennese tree cadastre containing 119,744 tree positions:

Default style: One dot per tree

Rendering tree counts per hexagonal grid cell reveals some of Vienna’s greenest spots, such as the Prater or Türkenschanzpark.

Tree density in a hexagonal grid

There’s also a printable version.

Some notes on the necessary steps:

MMQGIS – Create Grid Layer performs great. Creating the 18,400 hexagons in this map was very fast. Note though, that this tool doesn’t seem to write correct projection information to the resulting Shapefile. Therefore it is necessary to set the projection manually after loading the file.

As a result, it is very likely that the Points in Polygon tool will warn you that the point and polygon layer are not in the same projection. I ignored the warning and everything went fine. This step was reasonably fast considering the number of points (119,744) and polygons (18,400).


Light Styles for OSM Layers in QGIS

The default look of OSM plugin layers is not well-suited for background map usage. It’s too colorful and any overlay just gets lost:

Default look of OSM plugin layers

A good background map has enough detail to allow the reader to orient himself but at the same time must not overwhelm the overlays. For data to be overlaid onto OSM plugin layers, a more neutral style is needed. And this is my first attempt at such a style, containing rules for the polygon and line layers (no point style yet):

Light OSM style applied to polygon and line layer

As before, these styles can be downloaded from my “QGIS-resources” Github repository. They are called osm_light_line.qml and osm_light_polygon.qml and require QGIS trunk. They do not work in QGIS 1.7.x because they contain some new features that are only available in the developer version (aka trunk).


New Download: Osm2po Light Style

Inspired by the “OSM Bright Minimal” style for Tilemill, I’ve created a similar background map style for osm2po layers in QGIS trunk (uses features unavailable in 1.7.3): osm2po_light_style.qml. Together with a grey background (RGB:232,232,232) and an OSM natural layer (RGB:208,208,208 for water), the style looks like this:

example map using osm2po_light_style.qml

It’s plain and bright, so any overlay will stand out nicely. Hope you find it useful.


Batch Application of QGIS Layer Styles

Ever had to apply the same style to multiple map layers? It’s a tedious task … if you don’t have MultiQML plugin by Gislab.

With MultiQML, you can apply a style to multiple raster or vector layers: First, select the layers you want to style (use shift/ctrl to select multiple layers), press “Apply style …” button and select the appropriate QML. That’s it!

MultiQML dialog

The tool even has an “undo” functionality called “Restore initial style”, which will certainly prove useful.

If you want to see MultiQML in action, Gislab provides a video tutorial on their plugin page.


New Download: Osm2po Style

I’ve added a new style for osm2po layers to the QGIS Resources Github repo. It contains the following rules:

the rules

and looks like this:

the map

Enjoy!


A Guide to Beautiful Reliefs in QGIS

This week Sourcepole released a new addition to the Raster Terrain Analysis plugin: a sophisticated Relief tool. (More info in their announcement) This plugin is shipped with QGIS (developer version, not in 1.7.3 release) by default but you might have to activate it in Plugin Manager:

The plugin dialog is quite self-explanatory. You can chose the elevation file, output path and any of the numerous raster formats. The z factor is a bit more mysterious. We will have a look at that in a second. The rest of the dialog is the relief color editor. Pressing Create automatically will give you a color gradient to start with.

Relief tool dialog

But what’s the z factor good for?

I’ve tried a few different settings using free NASA SRTM data and it seems that higher values lead to a smoother relief (Please ignore the water areas):

z factor = 100 z factor = 1000 z factor = 10000 z factor = 50000 z factor = 100000

Update:

As Marco noted in the comments: The z factor is used if the x/y units are different from the z unit.

  • If everything is in meters, use z factor 1.0 (default).
  • If x/y is in degree and z in meters, use z factor 111120.
  • If x/y degree and z is feet, use z factor 370400.

In the example above SRTM rasters are in WGS84 with heights in meters. That’s why the result using a z factor of 100000 looks so good.

In my opinion the results look great even with the coarse SRTM dataset I used. Looking forward to all the great QGIS maps we will see in the future.


Easier Conditional Labels in QGIS

With Martin’s latest addition of conditional statements it’s now even easier to get conditional labels in QGIS. Following up on the example used in my previous post, we can simplify

substr(osm_name, 0, (clazz = 11 or clazz = 13 or clazz = 15 or clazz = 21)*-1)

to

CASE WHEN (clazz = 11 or clazz = 13 or clazz = 15 or clazz = 21) THEN osm_name END

which is much easier to read and remember.

To avoid roads from being labeled with only their road numbers, I added an additional check that the “osm_name” is longer than six characters. Thanks to Nathan’s syntax highlighting this new and powerful expression based labeling is also comfortable to use.

Conditional labels for an osm2po layer


Conditional Labels in QGIS

The latest QGIS development build (1.9.90) has a new feature “expression based labeling” which can be used to create conditional labels. One typical use case would be if you want to label only certain (high-level) road classes in your road layer. By default, QGIS labels the features rather randomly:

default labeling

How can we label only the more important roads? Here is an example using OSM data imported into PostGIS using osm2po:

If you have loaded OSM using osm2po, your OSM table will contain a “clazz” attribute. (Check osm2po.config for the exact mapping.) To label only motorways, trunks, primary and secondary roads and nothing else, I wrote this labeling expression:

substr(osm_name, 0, (clazz = 11 or clazz = 13 or clazz = 15 or clazz = 21)*-1)

If clazz equals 11, 13, 15 or 21, the expression returns the value of osm_name. Otherwise it returns an empty string. (All checks will return false or 0 which causes the function to evaluate to substr(osm_name,0,0).) Kudos to Giuseppe Sucameli who explained this on the mailing list.

expression based "conditional" labels


Mapping QGIS Users

For “QGIS Users Around the World” Gary Sherman collected and geocoded a few weeks of accesses to the plugin repositories. This map is my first attempt at mapping the data for use in QGIS publications:

Considering the coarse resolution of geocoded IP addresses, I’ve decided to count the number of unique IP addresses within each area (5×5 degrees). We can make out a lot of activity in Europe, Japan, Brazil and the US. The high number of accesses from the US mid west are due to IPs being mapped to country-level only.

I would love to hear your feedback on this one!


TimeManager is now on Github

TimeManager is now available on Github (right beside pgRoutingLayer).

If you want to try it, you can install version 0.4 from the new QGIS Plugin Repository. I’ve also uploaded some test data such as the twitter file used for the animation I presented recently.


How to Install Sphinx

This post summarizes how to install sphinx on Windows to contribute to PyQGIS Cookbook. I’m writing this as I go, so this most likely won’t be perfect.

I used my Python 2.6 stand-alone installation (not the one in OSGeo4W).

  1. Get the Sphinx egg from http://pypi.python.org/pypi/Sphinx
  2. If you don’t have it, install setuptools to get the easy_install script http://pypi.python.org/pypi/setuptools
  3. In C:\Python26\Scripts run easy_install -U sphinx
  4. Get the PyQGIS source from https://github.com/qgis/QGIS-Developer-Cookbook
  5. Create a build folder inside the QGIS-Developer-Cookbook
  6. Now you can build the Cookbook: sphinx-build "C:\Users\Anita\QGIS\QGIS-Developer-Cookbook\source" "C:\Users\Anita\QGIS\QGIS-Developer-Cookbook\build"

The build folder should now contain the Cookbook .html files.


Collected QGIS Resources

I’ve set up a GitHub repo where I will publish QGIS resources such as symbols and styles: https://github.com/anitagraser/QGIS-resources

You can already find symbols/styles described in these posts:


Google Road Symbols for QGIS

It’s Dec, 23rd and this is my early present to the QGIS community: a package of ready-to-use road symbols that make your OpenStreetMap data look like Google Maps.

In a previous post, I did already show how to prepare a view that will help get similar looking road labels. And now, here are the necessary symbols: osm_symbols.xml (Load using “Style Manager”.)

Now, you should have all necessary symbols available to create the style. I used the following rules to get the map shown above:

rules for "Google Maps" style

You can download the style here: v_osm_roads_style.qml

Merry Christmas!

OSM styled like "Google Maps"

PS: For water and natural areas, I used Cloudmade’s natural.shp


Osm2po Part 2 – PgRouting on OSM the Easy Way

This is the follow up post to “An osm2po Quickstart” which covers loading the OSM network into PostGIS and using the result with pgRouting. After parsing the OSM file, e.g.

C:\Users\Anita\temp\osm2po-4.2.30>java -jar osm2po-core-4.2.30-signed.jar prefix=at "C:\Users\Anita\Geodaten\OpenStreetMap Data\austria.osm.pbf"

you should find a folder with the name of the prefix you chose inside the osm2po folder. It contains a log file which in turn provides a command line template for importing the OSM network into PostGIS, e.g.

INFO commandline template: psql -U [username] -d [dbname] -q -f "C:\Users\Anita\temp\osm2po-4.2.30\at\at_2po_4pgr.sql"

Using this template, we can easily import the .sql file into an exiting database. My pgRouting-enabled database is called wien_ogd.

C:\Users\Anita\temp\osm2po-4.2.30\at>psql -U [username] -d wien_ogd -q -f C:\Users\Anita\temp\osm2po-4.2.30\at\at_2po_4pgr.sql

Now, the data is ready for usage in QGIS:

The osm2po table in QGIS

Using “pgRouting Layer” plugin, it’s now straightforward to calculate shortest paths. I had to apply some changes to the plugin code, so please get the latest version from Github.

A shortest path in osm2po network

Using osm2po turned out to be far less painful than I expected and I hope you’ll find this post useful too.


A First Glimpse at pgRouting Layer for QGIS

PgRouting is great. But (Yes, there is always a “but”.) those queries are not easy to remember. That’s why I started work on a pgRouting GUI today. It’s actually a QGIS plugin which I’ll call “pgRouting Layer” and it is based on Pablo T. Carreira’s “Fast SQL Layer” plugin which can execute arbitrary SQL statements against a PostGIS or SpatiaLite database and add the results in a map layer.

This first prototype supports pgRouting’s shortest_path() function as described in “A Beginners Guide to pgRouting”. Once supplied with the necessary information about attribute field names, the plugin allows you to route between pairs of nodes. For convenience, the resulting layer is named after its start and end node.

some shortest paths using "pgRouting Layer" plugin

Besides normal routing capabilities, I’d like to develop this plugin towards a user friendly tool for catchment zone analysis. If you are interested in teaming up to work towards this goal, let me know.


Nice Animations with Time Manager’s Offset Feature

You probably know this video from my previous post “Tweets to QGIS”. Today, I want to show you how it is done.

After importing the Twitter JSON file, I saved it as a Shapefile.
Every point in the Shapefile contains the timestamp of the tweet. Additionally, I added a second field called “forever” which will allow me to configure Time Manager to show features permanently.

A "forever" field will help with showing features permanently.

To create the flash effect you see in the video, we load the tweet Shapefile three times. Every layer gets a different role and style in the final animation:

  • Layer “start_flash” is a medium sized dot that marks the appearance of a new tweet.
  • Layer “big_flash” is a bigger dot of the same color which will appear after “start_flash”.
  • Layer “permanent” is a small dot that will be visible even after the flash vanishes.
Three layers with different styles will make the animation more interesting.

styling the tweet layers

We’ll plan the final animation with a time step size of 10 seconds. That means that every animation frame will cover a real-world timespan of 10 seconds.

We configure Time Manager by adding all three tweet layers:
Layer “start_flash” starts at the orginal time t. Layer “big_flash” gets an offset of -10 seconds, which means that it will display ten seconds after time t. Layer “permanent” gets an offset of -20 seconds and ends at time forever.

Layers can be timed using the "offset" feature.

Finally – in Time Manager dock – we can start the animation with a time step size of 10 seconds:

Use a time step size of 10 seconds so it fits to the offset values we specified earlier.

Besides watching the animation inside QGIS, Time Manager also enables you to export the animation to an image series using “Export Video” button. Actual video export is not implemented yet, but you can use mencoder on the resulting image series to create a video file:

mencoder "mf://*.PNG" -mf fps=10 -o output.avi -ovc lavc -lavcopts vcodec=mpeg4

Time offsets are a new feature in version 0.4 of Time Manager. You can get it directly from the project SVN and soon from the official QGIS repo.


More Color Ramps for QGIS

Colorbrewer is a great resource for visually pleasing gradients that can be used for mapping. It was already possible to use color brewer ramps in QGIS but it was necessary to create the ramp with the final number of classes in mind.

Creating a Colobrewer ramp

That’s why I sat down and created continuous ramps from the Colorbrewer data:

Colorbrewer Ramps in QGIS Style Manager

If you want to use them, just import the following XML file into QGIS Style Manager:

<!DOCTYPE qgis_style>
<qgis_style version="0">
  <symbols/>
  <colorramps>
    <colorramp type="gradient" name="Blues">
      <prop k="color1" v="247,251,255,255"/>
      <prop k="color2" v="8,48,107,255"/>
      <prop k="stops" v="0.13;222,235,247,255:0.26;198,219,239,255:0.39;158,202,225,255:0.52;107,174,214,255:0.65;66,146,198,255:0.78;33,113,181,255:0.9;8,81,156,255"/>
    </colorramp>
    <colorramp type="gradient" name="BrBG">
      <prop k="color1" v="166,97,26,255"/>
      <prop k="color2" v="1,133,113,255"/>
      <prop k="stops" v="0.25;223,194,125,255:0.5;245,245,245,255:0.75;128,205,193,255"/>
    </colorramp>
    <colorramp type="gradient" name="BuGn">
      <prop k="color1" v="237,248,251,255"/>
      <prop k="color2" v="0,109,44,255"/>
      <prop k="stops" v="0.25;178,226,226,255:0.5;102,194,164,255:0.75;44,162,95,255"/>
    </colorramp>
    <colorramp type="gradient" name="BuPu">
      <prop k="color1" v="237,248,251,255"/>
      <prop k="color2" v="129,15,124,255"/>
      <prop k="stops" v="0.25;179,205,227,255:0.5;140,150,198,255:0.75;136,86,167,255"/>
    </colorramp>
    <colorramp type="gradient" name="GnBu">
      <prop k="color1" v="240,249,232,255"/>
      <prop k="color2" v="8,104,172,255"/>
      <prop k="stops" v="0.25;186,228,188,255:0.5;123,204,196,255:0.75;67,162,202,255"/>
    </colorramp>
    <colorramp type="gradient" name="Greens">
      <prop k="color1" v="247,252,245,255"/>
      <prop k="color2" v="0,68,27,255"/>
      <prop k="stops" v="0.13;229,245,224,255:0.26;199,233,192,255:0.39;161,217,155,255:0.52;116,196,118,255:0.65;65,171,93,255:0.78;35,139,69,255:0.9;0,109,44,255"/>
    </colorramp>
    <colorramp type="gradient" name="Greys">
      <prop k="color1" v="250,250,250,255"/>
      <prop k="color2" v="5,5,5,255"/>
    </colorramp>
    <colorramp type="gradient" name="OrRd">
      <prop k="color1" v="254,240,217,255"/>
      <prop k="color2" v="179,0,0,255"/>
      <prop k="stops" v="0.25;253,204,138,255:0.5;252,141,89,255:0.75;227,74,51,255"/>
    </colorramp>
    <colorramp type="gradient" name="Oranges">
      <prop k="color1" v="255,245,235,255"/>
      <prop k="color2" v="127,39,4,255"/>
      <prop k="stops" v="0.13;254,230,206,255:0.26;253,208,162,255:0.39;253,174,107,255:0.52;253,141,60,255:0.65;241,105,19,255:0.78;217,72,1,255:0.9;166,54,3,255"/>
    </colorramp>
    <colorramp type="gradient" name="PRGn">
      <prop k="color1" v="123,50,148,255"/>
      <prop k="color2" v="0,136,55,255"/>
      <prop k="stops" v="0.25;194,165,207,255:0.5;247,247,247,255:0.75;166,219,160,255"/>
    </colorramp>
    <colorramp type="gradient" name="PiYG">
      <prop k="color1" v="208,28,139,255"/>
      <prop k="color2" v="77,172,38,255"/>
      <prop k="stops" v="0.25;241,182,218,255:0.5;247,247,247,255:0.75;184,225,134,255"/>
    </colorramp>
    <colorramp type="gradient" name="PuBu">
      <prop k="color1" v="241,238,246,255"/>
      <prop k="color2" v="4,90,141,255"/>
      <prop k="stops" v="0.25;189,201,225,255:0.5;116,169,207,255:0.75;43,140,190,255"/>
    </colorramp>
    <colorramp type="gradient" name="PuBuGn">
      <prop k="color1" v="246,239,247,255"/>
      <prop k="color2" v="1,108,89,255"/>
      <prop k="stops" v="0.25;189,201,225,255:0.5;103,169,207,255:0.75;28,144,153,255"/>
    </colorramp>
    <colorramp type="gradient" name="PuOr">
      <prop k="color1" v="230,97,1,255"/>
      <prop k="color2" v="94,60,153,255"/>
      <prop k="stops" v="0.25;253,184,99,255:0.5;247,247,247,255:0.75;178,171,210,255"/>
    </colorramp>
    <colorramp type="gradient" name="PuRd">
      <prop k="color1" v="241,238,246,255"/>
      <prop k="color2" v="152,0,67,255"/>
      <prop k="stops" v="0.25;215,181,216,255:0.5;223,101,176,255:0.75;221,28,119,255"/>
    </colorramp>
    <colorramp type="gradient" name="Purples">
      <prop k="color1" v="252,251,253,255"/>
      <prop k="color2" v="63,0,125,255"/>
      <prop k="stops" v="0.13;239,237,245,255:0.26;218,218,235,255:0.39;188,189,220,255:0.52;158,154,200,255:0.65;128,125,186,255:0.75;106,81,163,255:0.9;84,39,143,255"/>
    </colorramp>
    <colorramp type="gradient" name="RdBu">
      <prop k="color1" v="202,0,32,255"/>
      <prop k="color2" v="5,113,176,255"/>
      <prop k="stops" v="0.25;244,165,130,255:0.5;247,247,247,255:0.75;146,197,222,255"/>
    </colorramp>
    <colorramp type="gradient" name="RdGy">
      <prop k="color1" v="202,0,32,255"/>
      <prop k="color2" v="64,64,64,255"/>
      <prop k="stops" v="0.25;244,165,130,255:0.5;255,255,255,255:0.75;186,186,186,255"/>
    </colorramp>
    <colorramp type="gradient" name="RdPu">
      <prop k="color1" v="254,235,226,255"/>
      <prop k="color2" v="122,1,119,255"/>
      <prop k="stops" v="0.25;251,180,185,255:0.5;247,104,161,255:0.75;197,27,138,255"/>
    </colorramp>
    <colorramp type="gradient" name="RdYlBu">
      <prop k="color1" v="215,25,28,255"/>
      <prop k="color2" v="44,123,182,255"/>
      <prop k="stops" v="0.25;253,174,97,255:0.5;255,255,191,255:0.75;171,217,233,255"/>
    </colorramp>
    <colorramp type="gradient" name="RdYlGn">
      <prop k="color1" v="215,25,28,255"/>
      <prop k="color2" v="26,150,65,255"/>
      <prop k="stops" v="0.25;253,174,97,255:0.5;255,255,192,255:0.75;166,217,106,255"/>
    </colorramp>
    <colorramp type="gradient" name="Reds">
      <prop k="color1" v="255,245,240,255"/>
      <prop k="color2" v="103,0,13,255"/>
      <prop k="stops" v="0.13;254,224,210,255:0.26;252,187,161,255:0.39;252,146,114,255:0.52;251,106,74,255:0.65;239,59,44,255:0.78;203,24,29,255:0.9;165,15,21,255"/>
    </colorramp>
    <colorramp type="gradient" name="Spectral">
      <prop k="color1" v="215,25,28,255"/>
      <prop k="color2" v="43,131,186,255"/>
      <prop k="stops" v="0.25;253,174,97,255:0.5;255,255,191,255:0.75;171,221,164,255"/>
    </colorramp>
    <colorramp type="gradient" name="YlGn">
      <prop k="color1" v="255,255,204,255"/>
      <prop k="color2" v="0,104,55,255"/>
      <prop k="stops" v="0.25;194,230,153,255:0.5;120,198,121,255:0.75;49,163,84,255"/>
    </colorramp>
    <colorramp type="gradient" name="YlGnBu">
      <prop k="color1" v="255,255,204,255"/>
      <prop k="color2" v="37,52,148,255"/>
      <prop k="stops" v="0.25;161,218,180,255:0.5;65,182,196,255:0.75;44,127,184,255"/>
    </colorramp>
    <colorramp type="gradient" name="YlOrBr">
      <prop k="color1" v="255,255,212,255"/>
      <prop k="color2" v="153,52,4,255"/>
      <prop k="stops" v="0.25;254,217,142,255:0.5;254,153,41,255:0.75;217,95,14,255"/>
    </colorramp>
    <colorramp type="gradient" name="YlOrRd">
      <prop k="color1" v="255,255,178,255"/>
      <prop k="color2" v="189,0,38,255"/>
      <prop k="stops" v="0.25;254,204,92,255:0.5;253,141,60,255:0.75;240,59,32,255"/>
    </colorramp>
  </colorramps>
</qgis_style>

For a big selection of point, line and polygon styles check “QGIS symbology set” by S.S. Rebelious.


Expression-based Labeling for QGIS

The latest development build version of QGIS contain a great new feature: Expression-based labeling, brought to you by Nathan.

QGIS new labeling dialog is extended by a new expression builder that facilitates building your own expressions using layer attributes together with various functions for data manipulation:

expression builder with function help

Thanks to it’s preview ability, it is easy to see how changes affect the final label output:

combine fields and follow changes in preview

For an in depth introduction into this new feature, check Nathan’s blog and enjoy!


Easy Rectangles, Circles and Ellipses in QGIS

“Rectangles ovals digitizing” plugin by Pavol Kapusta adds editing tools that make it really easy to create rectangles, squares, circles and ellipses. These are the tools provided by the new plugin:

Tools in "Rectangles ovals digitizing"

Give it a try!


Tweets to QGIS

The idea behind this post was to create a video of twitter activity using Time Manager. You can watch the results of my first test run here:

And this is how it’s done:

First, you have to collect some tweets with location information. The following command will collect tweets within a certain geographic region from the Twitter Stream API using curl. You need a Twitter user account to use the API. (Curl comes readily available with OSGeo4W install.)

curl -k -d @locations.txt https://stream.twitter.com/1/statuses/filter.json -uuser:password > tweets.json

The contents of locations.txt is the geographic extent you are interested in, e.g. for Austria:

locations=9,45,17,50

After collecting some data, you can load the tweets into QGIS. Executing the following lines in Python Console will add an in-memory point layer to the map. (I am only extracting coordinates and time stamp from the tweets, but you can access more information through the JSON object.)

import simplejson
from PyQt4.QtCore import *
from datetime import *

f=open('C:/temp/tweets.json','r')

# create layer
vl = QgsVectorLayer("Point", "tweets", "memory")
vl.startEditing()
pr = vl.dataProvider()

# add fields
pr.addAttributes( [ QgsField("t", QVariant.String) ] )

# create features
for line in f:
   try:
      j=simplejson.loads(line)
      fet=QgsFeature()
      fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(j['geo']['coordinates'][1],j['geo']['coordinates'][0])))
      fet.setAttributeMap({0:QVariant(str(datetime.strptime(j['created_at'],'%a %b %d %H:%M:%S +0000 %Y')))})
      pr.addFeatures([fet])
   except:
      pass

vl.commitChanges()
vl.updateExtents()

QgsMapLayerRegistry.instance().addMapLayer(vl)

To use the result in Time Manager, you have to export the layer to e.g. Shapefile because it’s not possible to add query strings to in-memory layers.

If you are interested in learning more about PyQGIS, you can find a lot of useful material in the PyQGIS Cookbook.


Back to Top

Sustaining Members