Z ordering single layer example

The OpenStreetMap dataset uses extensively a z_order attribute to model the above/below relationships between elements in the real world.

A small downloadable shapefile is provided that shows a small area with a rich set of different z-orders, where roads and rails go above and below each other. For reference, this is the dataset schema:

Name

Type

Notes

osm_id

numeric

type

string

The type of the segment, can be “mainroads”, “minorroads”, “railways”, …

bridge

numeric

0 or 1

ref

numeric

0 or 1

tunnel

numeric

oneway

numeric

0 or 1

z_order

numeric

class

string

The dataset contains several different values for z_order, in particular: -10, -7, -5, -3, -1, 0, 3, 4, 5, 7, 9, 10, 13, 14, 15, 17, 19.

Here is a sample CSS style using z-ordering, but not groups, to perform the display. Road casing is achieved by multiple FeatureTypeStyle, or z-index values in CSS:

[class = 'railways' and bridge = 1] {
  stroke: #333333;
  stroke-width: 8;
  z-index: 0;
}

[class = 'minorroads'] {
  stroke: #a69269;
  stroke-width: 3;
  z-index: 0;
}

[class = 'mainroads'] {
  stroke: #ff0000;
  stroke-width: 5;
  z-index: 0;
}

[class = 'motorways'] {
  stroke: #990000;
  stroke-width: 8;
  z-index: 0;
}

[class = 'railways' and bridge = 1] {
  stroke: #ffffff;
  stroke-width: 6;
  z-index: 1;
}

[class = 'railways'] {
  stroke: #333333;
  stroke-width: 3;
  z-index: 2;
}

[class = 'railways'] {
  stroke: #ffffff;
  stroke-width: 1.5;
  stroke-dasharray: 5, 5;
  z-index: 3;
}

[class = 'motorways'] {
  stroke: #ff6666;
  stroke-width: 6;
  stroke-linecap: round;
  z-index: 3;
}

[class = 'minorroads'] {
  stroke: #ffffff;
  stroke-width: 2,5;
  stroke-linecap: round;
  z-index: 3;
}

[class = 'mainroads'] {
  stroke: #ff9999;
  stroke-width: 4;
  stroke-linecap: round;
  z-index: 3;
}

* {
 sort-by: "z_order";
}

The sorting is achieved by using the sort-by property, which translates into a sortBy VendorOption in SLD. A full equivalent SLD is available for download.

This is the resulting map:

../../../../_images/roads-no-group.png

As one can see, there are evident issues:

  • Roads and rails are not showing any evident z-ordering, in fact, all rails are below roads, but their dashed white center shows a mix of below and above roads

  • The rails bridges (depicted with a third thicker line around the rail symbol) are consistently below some other road or rail, while they should be above.

This is mostly happening because the various FeatureTypeStyle elements are not put doctor in a single group.

A slight change in the CSS, grouping all levels in the same sortByGroup, solves the issues above:

[class = 'railways' and bridge = 1] {
  stroke: #333333;
  stroke-width: 8;
  z-index: 0;
}

[class = 'minorroads'] {
  stroke: #a69269;
  stroke-width: 3;
  z-index: 0;
}

[class = 'mainroads'] {
  stroke: #ff0000;
  stroke-width: 5;
  z-index: 0;
}

[class = 'motorways'] {
  stroke: #990000;
  stroke-width: 8;
  z-index: 0;
}

[class = 'railways' and bridge = 1] {
  stroke: #ffffff;
  stroke-width: 6;
  z-index: 1;
}

[class = 'railways'] {
  stroke: #333333;
  stroke-width: 3;
  z-index: 2;
}

[class = 'railways'] {
  stroke: #ffffff;
  stroke-width: 1.5;
  stroke-dasharray: 5, 5;
  z-index: 3;
}

[class = 'motorways'] {
  stroke: #ff6666;
  stroke-width: 6;
  stroke-linecap: round;
  z-index: 3;
}

[class = 'minorroads'] {
  stroke: #ffffff;
  stroke-width: 2,5;
  stroke-linecap: round;
  z-index: 3;
}

[class = 'mainroads'] {
  stroke: #ff9999;
  stroke-width: 4;
  stroke-linecap: round;
  z-index: 3;
}

* {
 sort-by: "z_order";
 sort-by-group: "roadsGroup";
}

A full equivalent SLD is also available for download.

The result now shows proper z-ordering:

../../../../_images/roads-group.png