I've trying to find a solution to applying the OpenStreetMap z-order in QGIS after using osm2pgsql. Everything is working perfectly, until I add the each layer to the canvas, where the z-order is not being applied.

I've tried searching for solution for the last couple of hours and have yet to find anything that is working.

Here are the steps I've taken thus far:

  1. osm2pgsql -d OSM_Test -l -u -U 'username' -W -H 'host' -P 'port' -k 'filepath'/oregon-latest.osm.pbf

Note: '<...>' is being used as a placeholder.

  1. Each layer (line, point, polygon, road) is added with a land layer from Natural Earth.
  2. Rule-based styles are added for each OpenStreetMap road type.

I know that I can combine each road style with the z-order, however, this can create 60 different options for each road type/style.

Where am I going wrong? or am I missing something with a PostGIS function than can applied to the z-order?

I have confirmed that the z-order column is present for each.

2 Answers 2


Within a layer, you can use the z-order values to determine the QGIS feature rendering order:

  1. Open the respective layer's style panel.
    • Either in the layer properties or in the layer styling dock (both should work)
  2. Near the bottom of the layer style panel, check the Control feature rendering order checkbox.

    (The "Define order" window opens, probably with a single entry and empty Expression)

  3. In the Expression field type the name of the z-order attribute (column name) or choose it from that field's drop-down.

  4. Keep or set "Ascending" in the Asc / Desc field.

    (How to handle NULL values (NULLs last or NULLs first) shouldn't matter, as osm2pgsql does AFAIK not produce any NULL values for the z-order column of the roads table.)

  5. Click OK on the "Define Order" window and Apply or OK on the layer properties / layer style panel in the styling dock.

Rendering order of symbol levels takes precedence, so this might not bode well with road edges produced with multi-level symbols where you join the road interiors by having them on a higher render pass number than the "outlines" (actually wider lines). I was able to (partially) work around that by putting "outline" lines and interior lines on the same pass, ordering them correctly within the individual multilevel-symbols (possible by drag&drop), and choosing "Cap style" "Flat" for the "outline" lines and a different cap style for the interior lines. Like that, the wider "outline" lines will protrude from under the corresponding interior lines laterally, but not at the ends (where the road often continues on a separate segment).

Rendering order of layers will also take precedence, so this will only work between ways of the same layer. If e.g. railway ways are in a separate layer, they'll always be either above or below roads (controlled either by the order in the legend, or if enabled, the order in the layer order panel), even if you enable feature ordering within the railway layer, too.


The z_order is just a column in the database tables. You can filter the data for a certain value (or range of values), and apply your styles. Then you can duplicate the layer, but set the filter to another z value.

The order of rendering is defined by the order of the layers in the QGIS table of content. The top layer will be rendered on top of the others.

Points don't seem to have a z_order, I have only NULL values in the point table.

The original Mapnik style uses order by z_order in the SQL Query, but that is not possible in the simple QGIS query. So you have to use the DB Manager.

Select the PostGIS, your database, public schema, planet_line table, then click on the SQL Window icon, and enter:

Select * from planet_line order by z_order;

Check Load as new Layer, Click on Retreive Columns, select osm_id as unique integer and way as Geometry column, then click on Load now!.

This works as expected, but you will not get the nice road casing at crossings. The Mapnik style uses four rendering rules for bridges, filtered by the layer column, drawing casing and fill for each layer before rendering the next one.

  • Perfect. I only came across one bug where the layer was not being added, which a restart of qgis, in case anyone has the same issue.
    – PDX
    Oct 15, 2015 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.