From 997a7fdf072b7af5dc716119215efff15a467c35 Mon Sep 17 00:00:00 2001 From: Lukas Sommer Date: Fri, 29 Jun 2018 21:08:15 +0000 Subject: [PATCH 1/2] New unpaved rendering --- Dockerfile | 9 +- INSTALL.md | 8 +- README.md | 4 + project.mml | 38 +- scripts/generate_unpaved_patterns.py | 143 +++++ style/roads.mss | 564 +++++++++++++++++- symbols/unpaved/unpaved.md | 9 + symbols/unpaved/unpaved.svg | 39 ++ symbols/unpaved/unpaved_aeroway-fill.svg | 39 ++ .../unpaved/unpaved_living-street-fill.svg | 39 ++ symbols/unpaved/unpaved_motorway-fill.svg | 39 ++ symbols/unpaved/unpaved_motorway-low-zoom.svg | 39 ++ symbols/unpaved/unpaved_pedestrian-fill.svg | 39 ++ symbols/unpaved/unpaved_platform-fill.svg | 39 ++ symbols/unpaved/unpaved_primary-fill.svg | 39 ++ symbols/unpaved/unpaved_primary-low-zoom.svg | 39 ++ symbols/unpaved/unpaved_raceway-fill.svg | 39 ++ symbols/unpaved/unpaved_residential-fill.svg | 39 ++ symbols/unpaved/unpaved_road-fill.svg | 39 ++ symbols/unpaved/unpaved_secondary-fill.svg | 39 ++ symbols/unpaved/unpaved_trunk-fill.svg | 39 ++ symbols/unpaved/unpaved_trunk-low-zoom.svg | 39 ++ 22 files changed, 1316 insertions(+), 44 deletions(-) create mode 100755 scripts/generate_unpaved_patterns.py create mode 100644 symbols/unpaved/unpaved.md create mode 100644 symbols/unpaved/unpaved.svg create mode 100644 symbols/unpaved/unpaved_aeroway-fill.svg create mode 100644 symbols/unpaved/unpaved_living-street-fill.svg create mode 100644 symbols/unpaved/unpaved_motorway-fill.svg create mode 100644 symbols/unpaved/unpaved_motorway-low-zoom.svg create mode 100644 symbols/unpaved/unpaved_pedestrian-fill.svg create mode 100644 symbols/unpaved/unpaved_platform-fill.svg create mode 100644 symbols/unpaved/unpaved_primary-fill.svg create mode 100644 symbols/unpaved/unpaved_primary-low-zoom.svg create mode 100644 symbols/unpaved/unpaved_raceway-fill.svg create mode 100644 symbols/unpaved/unpaved_residential-fill.svg create mode 100644 symbols/unpaved/unpaved_road-fill.svg create mode 100644 symbols/unpaved/unpaved_secondary-fill.svg create mode 100644 symbols/unpaved/unpaved_trunk-fill.svg create mode 100644 symbols/unpaved/unpaved_trunk-low-zoom.svg diff --git a/Dockerfile b/Dockerfile index 7baacb8e67..a22b52b347 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ -FROM ubuntu:bionic +FROM ubuntu:focal # Style dependencies RUN apt-get update && apt-get install --no-install-recommends -y \ ca-certificates curl gnupg postgresql-client python3 python3-distutils \ fonts-hanazono fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted \ - mapnik-utils nodejs npm ttf-unifont unzip && rm -rf /var/lib/apt/lists/* + mapnik-utils nodejs npm ttf-unifont unzip git && rm -rf /var/lib/apt/lists/* -# Kosmtik with plugins, forcing prefix to /usr because bionic sets +# Kosmtik with plugins, forcing prefix to /usr because Ubuntu sets # npm prefix to /usr/local, which breaks the install -RUN npm set prefix /usr && npm install -g kosmtik +# We install kosmtik not from release channel, but directly from a specific commit on github. +RUN npm set prefix /usr && npm install -g "git+https://git@github.com/kosmtik/kosmtik.git#f176c4c" WORKDIR /usr/lib/node_modules/kosmtik/ RUN kosmtik plugins --install kosmtik-overpass-layer \ diff --git a/INSTALL.md b/INSTALL.md index 74ae092974..92027b70af 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -68,7 +68,7 @@ scripts/get-fonts.sh ## Dependencies For development, a style design studio is needed. -* [Kosmtik](https://github.com/kosmtik/kosmtik) - Kosmtik can be launched with `node index.js serve path/to/openstreetmap-carto/project.mml` +* [Kosmtik](https://github.com/kosmtik/kosmtik) - Kosmtik can be launched with `node index.js serve path/to/openstreetmap-carto/project.mml` The 0.0.17 release of Kosmtik is not enough because we need up-to-date CartoCSS and Mapnik versions. To install the current master branch of Kosmtik, you can clone the Kosmtik repository and execute `npm install` within it. [TileMill](https://tilemill-project.github.io/tilemill/) is not officially supported, but you may be able to use a recent TileMill version by copying or symlinking the project directly into your Mapbox/project directory. @@ -91,7 +91,7 @@ Some colours, SVGs and other files are generated with helper scripts. Not all us For deployment, CartoCSS and Mapnik are required. -* [CartoCSS](https://github.com/mapbox/carto) >= 0.18.0 (we're using YAML) -* [Mapnik](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) >= 3.0 +* [CartoCSS](https://github.com/mapbox/carto) >= 1.2.0 *(we're using YAML)* +* [Mapnik](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) >= 3.0.22 -With CartoCSS you compile these sources into a Mapnik compatible XML file. When running CartoCSS, specify the Mapnik API version you are using (at least 3.0.0: `carto -a "3.0.0"`). +With CartoCSS you compile these sources into a Mapnik compatible XML file. When running CartoCSS, specify the Mapnik API version you are using (at least 3.0.22: `carto -a "3.0.22"`). \ No newline at end of file diff --git a/README.md b/README.md index 498342abe8..6dac60e95b 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,10 @@ to reload their databases, v3.x compatibility is not maintained. The v5.x series updates Lua tag transforms, linestring and polygon decisions have changed. +## Mapnik and CartoCSS update (v6.x) + +The v6.x series was triggered by an update to the required Mapnik and CartoCSS +versions. There are over [500 open requests](https://github.com/gravitystorm/openstreetmap-carto/issues), some that have been open for years. These need reviewing and dividing into obvious fixes, or additional new features diff --git a/project.mml b/project.mml index 3ed20bc6e2..0dffbe6f7e 100644 --- a/project.mml +++ b/project.mml @@ -499,7 +499,7 @@ Layer: CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, - CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 2 END + CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END ) AS tunnels properties: cache-features: true @@ -736,7 +736,12 @@ Layer: foot, bicycle, tracktype, - 'null', + CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', + 'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' + WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', + 'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' + ELSE NULL + END AS int_surface, CASE WHEN access IN ('destination') THEN 'destination'::text WHEN access IN ('no', 'private') THEN 'no'::text @@ -759,7 +764,7 @@ Layer: CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, - CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 2 END, + CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END, osm_id ) AS roads_sql properties: @@ -781,8 +786,14 @@ Layer: AND (tunnel NOT IN ('yes', 'building_passage') OR tunnel IS NULL) AND (covered NOT IN ('yes') OR covered IS NULL)) THEN railway END)), - (('aeroway_' || CASE WHEN aeroway IN ('runway', 'taxiway', 'helipad') THEN aeroway END)) - ) AS feature + (('aeroway_' || CASE WHEN aeroway IN ('runway', 'taxiway', 'helipad') THEN aeroway ELSE NULL END)) + ) AS feature, + CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', + 'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' + WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', + 'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' + ELSE NULL + END AS int_surface FROM planet_osm_polygon WHERE highway IN ('pedestrian', 'footway', 'service', 'living_street', 'platform', 'services') OR (railway IN ('platform') @@ -975,7 +986,7 @@ Layer: CASE WHEN substring(feature for 8) = 'railway_' THEN 2 ELSE 1 END, CASE WHEN feature IN ('railway_INT-preserved-ssy', 'railway_INT-spur-siding-yard', 'railway_tram-service') THEN 0 ELSE 1 END, CASE WHEN access IN ('no', 'private') THEN 0 WHEN access IN ('destination') THEN 1 ELSE 2 END, - CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 2 END + CASE WHEN int_surface IN ('unpaved') THEN 0 ELSE 1 END ) AS bridges properties: cache-features: true @@ -1020,11 +1031,20 @@ Layer: (SELECT way, aeroway, - bridge IN ('yes', 'boardwalk', 'cantilever', 'covered', 'low_water_crossing', 'movable', 'trestle', 'viaduct') AS bridge + bridge IN ('yes', 'boardwalk', 'cantilever', 'covered', 'low_water_crossing', 'movable', 'trestle', 'viaduct') AS bridge, + CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', + 'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 'unpaved' + WHEN surface IN ('paved', 'asphalt', 'cobblestone', 'cobblestone:flattened', 'sett', 'concrete', 'concrete:lanes', + 'concrete:plates', 'paving_stones', 'metal', 'wood', 'unhewn_cobblestone') THEN 'paved' + ELSE NULL + END AS int_surface FROM planet_osm_line WHERE aeroway IN ('runway', 'taxiway') - ORDER BY bridge NULLS FIRST, - CASE WHEN aeroway = 'runway' THEN 1 ELSE 0 END + ORDER BY + bridge NULLS FIRST, + CASE WHEN aeroway = 'runway' THEN 1 ELSE 0 END, + CASE WHEN surface IN ('unpaved', 'compacted', 'dirt', 'earth', 'fine_gravel', 'grass', 'grass_paver', 'gravel', 'ground', + 'mud', 'pebblestone', 'salt', 'sand', 'woodchips', 'clay', 'ice', 'snow') THEN 0 ELSE 1 END ) AS aeroways properties: cache-features: true diff --git a/scripts/generate_unpaved_patterns.py b/scripts/generate_unpaved_patterns.py new file mode 100755 index 0000000000..941bcc0a81 --- /dev/null +++ b/scripts/generate_unpaved_patterns.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 + +# Colours for unpaved roads + +# This reads some color variables from some .mss files and also reads +# symbols/unpaved/unpaved.svg and generates colourized versions of +# the unpaved pattern for all road types and saves them in the symbols/unpaved +# folder. Existing files of the same name are overwritten! +# +# This script produces patterns that perceptually have the same overall +# brightness as the original road color. Therefor, the pattern foreground +# is darker than the original color, and the pattern background lighter than +# the original color. This script does its very best, but the same overall +# brightness is not always possible (for example for white roads) and also +# depends on the monitor gammut on which the pattern is finally displayed. +# +# Usage: Call this script in the main directory of openstreetmap-carto +# without further parameters. +# +# Customize: +# You can customize this script by changing the first variables of in the main() +# function (color_names, file_names, darken, brighten_darken_ratio). + +from colormath.color_objects import LabColor, sRGBColor +from colormath.color_conversions import convert_color + +# def get_color_value_by_name(variable_name, file_names): +# +# Searches in MSS files for variable values with the given name. Returns +# the first value it finds. Only supports very basic syntax like: +# @test: 12; # Comment +# which would return "12". +# +# Paramaters: +# variable_name: the name of the variable for which we search the value +# file_names: list of files where we search for the variable value +# +# Return value: the variable value (if any) +def get_color_value_by_name(variable_name, file_names): + for files in file_names: + with open(files) as f: + for line in f: + if line.startswith("@" + variable_name + ":"): + temp = line.strip("@" + variable_name + ":").split(";")[0].strip() + # test if the value length is okay (#abc or #aabbcc) + if (len(temp) == 4) or (len(temp)== 7): + # remove the first character (#) + temp = temp[1:] + # expand value like #abc to #aabbcc + if len(temp) == 3: + temp = temp[0] + temp [0] + temp [1] + temp [1] + temp [2] + temp [2] + # make sure that the content is really a (lowercase) hex value + if all(c in set("0123456789abcdef") for c in temp): + # if so, return the hex value with a leading "#" + return ("#" + temp) + +# Takes an RGB hex values, applies the indicated Lab lightness change and returns the result as RGB hex value again +# def change_lightness(base_color_rgb_hex, lightness_change): +# +# Changes the lightness of a given color. This function +# tries to do a perceptual transformation. +# +# Paramaters: +# base_color_rgb_hex: An RGB hex value like #1212ab +# lightness_change: A number (positive or negative), interpreted as change to the lightness component like in Lab perceptual color space (range: 0..100) +# +# Return value: The RGB hex value with the lightness change applied. If the lightness change leaves +# us with an out-of-gammut value, it is clipped to make sure to be within the RGB gammut. So the return +# value is guarantied to be always a valid RGB value. +def change_lightness(base_color_rgb_hex, lightness_change): + base_color_lab = convert_color(sRGBColor.new_from_rgb_hex(base_color_rgb_hex), LabColor) + new_color_lab = LabColor( + base_color_lab.lab_l + lightness_change, # This value might be out of gammut and therefor invalid + base_color_lab.lab_a, + base_color_lab.lab_b, + base_color_lab.observer, + base_color_lab.illuminant) + new_color_rgb = convert_color(new_color_lab, sRGBColor) # This value might be out of gammut and therefor invalid + # use the "clamped" values which means they are within the gammut and therefor valid + new_color_rgb_clamped = sRGBColor( + new_color_rgb.clamped_rgb_r, + new_color_rgb.clamped_rgb_g, + new_color_rgb.clamped_rgb_b) + return new_color_rgb_clamped.get_rgb_hex() + +def main(): + + # List of names of color variables in mss code for which we will generate patterns + color_names = { + 'motorway-low-zoom', + 'trunk-low-zoom', + 'primary-low-zoom', + 'motorway-fill', + 'trunk-fill', + 'primary-fill', + 'secondary-fill', + 'platform-fill', + 'aeroway-fill', + 'road-fill', + 'pedestrian-fill', + 'living-street-fill', + 'raceway-fill', + 'residential-fill' + } + + # List of names of mss files in which we search for color variables + file_names = { + 'style/roads.mss', + 'style/road-colors-generated.mss' + } + + # The value by which the original color is darkened for the pattern foreground + # This value should always be negative. + darken = -60 + + # The pattern foreground occupies less space than the background. So lightening + # the background has to be less intense than darkening the foreground. This + # value is multiplied with the negative value of "darken" to get a value for + # "brighten", so brighten_darken_ration must also be negative to make sure + # the "brighten" result is positive. This value should (only) be changed when + # the pattern itself is changed. + brighten_darken_ratio = -0.065 + + # actual code + for color_name in color_names: + print("\nColor name: " + color_name) + original_color_value = get_color_value_by_name(color_name, file_names) + print("Plain color: " + original_color_value) + pattern_colors = [change_lightness(original_color_value, darken), + change_lightness(original_color_value, darken * brighten_darken_ratio)] + print("Colors for pattern: " + str(pattern_colors)) + if pattern_colors: + with open('symbols/unpaved/unpaved.svg', 'rt') as fin: + with open('symbols/unpaved/unpaved_' + color_name + '.svg', 'wt') as fout: + for line in fin: + temp = line + temp = temp.replace('#0000ff', pattern_colors[0]) + temp = temp.replace('fill:none', 'fill:' + pattern_colors[1]) + fout.write(temp) + print("Pattern file: " + 'symbols/unpaved/unpaved_' + color_name + '.svg') + +if __name__ == "__main__": + main() diff --git a/style/roads.mss b/style/roads.mss index 5c8b75d8a0..8595ceed16 100644 --- a/style/roads.mss +++ b/style/roads.mss @@ -5,7 +5,7 @@ @service-fill: @residential-fill; @living-street-fill: #ededed; @pedestrian-fill: #dddde8; -@raceway-fill: pink; +@raceway-fill: #ffc0cb; @road-fill: #ddd; @footway-fill: salmon; @footway-fill-noaccess: #bbbbbb; @@ -17,6 +17,7 @@ @bridleway-fill-noaccess: #aaddaa; @track-fill: #996600; @track-fill-noaccess: #e2c5bb; +@platform-fill: #bbbbbb; @aeroway-fill: #bbc; @runway-fill: @aeroway-fill; @taxiway-fill: @aeroway-fill; @@ -1357,7 +1358,10 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_motorway'] { + #roads-low-zoom[feature = 'highway_motorway'][int_surface != 'unpaved'], + #roads-fill[feature = 'highway_motorway'][int_surface != 'unpaved'], + #bridges[feature = 'highway_motorway'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_motorway'] { [zoom >= 6][link != 'yes'], [zoom >= 10] { line-color: @motorway-low-zoom; @@ -1412,7 +1416,66 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_trunk'] { + #roads-low-zoom[feature = 'highway_motorway'][int_surface = 'unpaved'], + #roads-fill[feature = 'highway_motorway'][int_surface = 'unpaved'], + #bridges[feature = 'highway_motorway'][int_surface = 'unpaved'] { + [zoom >= 6][link != 'yes'], + [zoom >= 10] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-width: @motorway-width-z6; + line-pattern-file: url("symbols/unpaved/unpaved_motorway-low-zoom.svg"); + [zoom >= 7] { line-pattern-width: @motorway-width-z7; } + [zoom >= 8] { line-pattern-width: @motorway-width-z8; } + [zoom >= 9] { line-pattern-width: @motorway-width-z9; } + [zoom >= 10] { line-pattern-width: @motorway-width-z10; } + [zoom >= 11] { line-pattern-width: @motorway-width-z11; } + [zoom >= 12] { + line-pattern-file: url("symbols/unpaved/unpaved_motorway-fill.svg"); + line-pattern-width: @motorway-width-z12 - 2 * @major-casing-width-z12; + [zoom >= 13] { line-pattern-width: @motorway-width-z13 - 2 * @major-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @motorway-width-z15 - 2 * @major-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @motorway-width-z17 - 2 * @major-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @motorway-width-z18 - 2 * @major-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @motorway-width-z19 - 2 * @major-casing-width-z19; } + [zoom >= 20] { line-pattern-width: @motorway-width-z20 - 2 * @major-casing-width-z20; } + [link = 'yes'] { + line-pattern-width: @motorway-link-width-z12 - 2 * @casing-width-z12; + [zoom >= 13] { line-pattern-width: @motorway-link-width-z13 - 2 * @casing-width-z13; } + [zoom >= 15] { line-pattern-width: @motorway-link-width-z15 - 2 * @casing-width-z15; } + [zoom >= 17] { line-pattern-width: @motorway-link-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @motorway-link-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @motorway-link-width-z19 - 2 * @casing-width-z19; } + [zoom >= 20] { line-pattern-width: @motorway-link-width-z20 - 2 * @casing-width-z20; } + } + #bridges { + line-pattern-width: @motorway-width-z12 - 2 * @major-bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @motorway-width-z13 - 2 * @major-bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @motorway-width-z15 - 2 * @major-bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @motorway-width-z17 - 2 * @major-bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @motorway-width-z18 - 2 * @major-bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @motorway-width-z19 - 2 * @major-bridge-casing-width-z19; } + [zoom >= 20] { line-pattern-width: @motorway-width-z20 - 2 * @major-bridge-casing-width-z20; } + [link = 'yes'] { + line-pattern-width: @motorway-link-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @motorway-link-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @motorway-link-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @motorway-link-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @motorway-link-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @motorway-link-width-z19 - 2 * @bridge-casing-width-z19; } + [zoom >= 20] { line-pattern-width: @motorway-link-width-z20 - 2 * @bridge-casing-width-z20; } + } + } + line-pattern-cap: round; + line-pattern-join: round; + } + } + } + + #roads-low-zoom[feature = 'highway_trunk'][int_surface != 'unpaved'], + #roads-fill[feature = 'highway_trunk'][int_surface != 'unpaved'], + #bridges[feature = 'highway_trunk'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_trunk'] { [zoom >= 6][link != 'yes'], [zoom >= 10] { line-width: @trunk-width-z6; @@ -1463,7 +1526,62 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_primary'] { + #roads-low-zoom[feature = 'highway_trunk'][int_surface = 'unpaved'], + #roads-fill[feature = 'highway_trunk'][int_surface = 'unpaved'], + #bridges[feature = 'highway_trunk'][int_surface = 'unpaved'] { + [zoom >= 6][link != 'yes'], + [zoom >= 10] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-width: @trunk-width-z6; + line-pattern-file: url("symbols/unpaved/unpaved_trunk-low-zoom.svg"); + [zoom >= 7] { line-pattern-width: @trunk-width-z7; } + [zoom >= 8] { line-pattern-width: @trunk-width-z8; } + [zoom >= 9] { line-pattern-width: @trunk-width-z9; } + [zoom >= 10] { line-pattern-width: @trunk-width-z10; } + [zoom >= 11] { line-pattern-width: @trunk-width-z11; } + [zoom >= 12] { + line-pattern-file: url("symbols/unpaved/unpaved_trunk-fill.svg"); + line-pattern-width: @trunk-width-z12 - 2 * @major-casing-width-z12; + [zoom >= 13] { line-pattern-width: @trunk-width-z13 - 2 * @major-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @trunk-width-z15 - 2 * @major-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @trunk-width-z17 - 2 * @major-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @trunk-width-z18 - 2 * @major-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @trunk-width-z19 - 2 * @major-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @trunk-link-width-z12 - 2 * @casing-width-z12; + [zoom >= 13] { line-pattern-width: @trunk-link-width-z13 - 2 * @casing-width-z13; } + [zoom >= 15] { line-pattern-width: @trunk-link-width-z15 - 2 * @casing-width-z15; } + [zoom >= 17] { line-pattern-width: @trunk-link-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @trunk-link-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @trunk-link-width-z19 - 2 * @casing-width-z19; } + } + #bridges { + line-pattern-width: @trunk-width-z12 - 2 * @major-bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @trunk-width-z13 - 2 * @major-bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @trunk-width-z15 - 2 * @major-bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @trunk-width-z17 - 2 * @major-bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @trunk-width-z18 - 2 * @major-bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @trunk-width-z19 - 2 * @major-bridge-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @trunk-link-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @trunk-link-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @trunk-link-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @trunk-link-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @trunk-link-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @trunk-link-width-z19 - 2 * @bridge-casing-width-z19; } + } + } + line-pattern-cap: round; + line-pattern-join: round; + } + } + } + + #roads-low-zoom[feature = 'highway_primary'][int_surface != 'unpaved'], + #roads-fill[feature = 'highway_primary'][int_surface != 'unpaved'], + #bridges[feature = 'highway_primary'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_primary'] { [zoom >= 8][link != 'yes'], [zoom >= 10] { line-width: @primary-width-z8; @@ -1512,6 +1630,56 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } + #roads-low-zoom[feature = 'highway_primary'][int_surface = 'unpaved'], + #roads-fill[feature = 'highway_primary'][int_surface = 'unpaved'], + #bridges[feature = 'highway_primary'][int_surface = 'unpaved'] { + [zoom >= 8][link != 'yes'], + [zoom >= 10] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-width: @primary-width-z8; + line-pattern-file: url("symbols/unpaved/unpaved_primary-low-zoom.svg"); + [zoom >= 9] { line-pattern-width: @primary-width-z9; } + [zoom >= 10] { line-pattern-width: @primary-width-z10; } + [zoom >= 11] { line-pattern-width: @primary-width-z11; } + [zoom >= 12] { + line-pattern-file: url("symbols/unpaved/unpaved_primary-fill.svg"); + line-pattern-width: @primary-width-z12 - 2 * @major-casing-width-z12; + [zoom >= 13] { line-pattern-width: @primary-width-z13 - 2 * @major-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @primary-width-z15 - 2 * @major-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @primary-width-z17 - 2 * @major-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @primary-width-z18 - 2 * @major-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @primary-width-z19 - 2 * @major-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @primary-link-width-z12 - 2 * @casing-width-z12; + [zoom >= 13] { line-pattern-width: @primary-link-width-z13 - 2 * @casing-width-z13; } + [zoom >= 15] { line-pattern-width: @primary-link-width-z15 - 2 * @casing-width-z15; } + [zoom >= 17] { line-pattern-width: @primary-link-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @primary-link-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @primary-link-width-z19 - 2 * @casing-width-z19; } + } + #bridges { + line-pattern-width: @primary-width-z12 - 2 * @major-bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @primary-width-z13 - 2 * @major-bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @primary-width-z15 - 2 * @major-bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @primary-width-z17 - 2 * @major-bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @primary-width-z18 - 2 * @major-bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @primary-width-z19 - 2 * @major-bridge-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @primary-link-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @primary-link-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @primary-link-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @primary-link-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @primary-link-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @primary-link-width-z19 - 2 * @bridge-casing-width-z19; } + } + } + line-pattern-cap: round; + line-pattern-join: round; + } + } + } + [feature = 'highway_secondary'] { [zoom >= 9][link != 'yes'], [zoom >= 10] { @@ -1564,6 +1732,53 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } + #roads-fill[feature = 'highway_secondary'][int_surface = 'unpaved'], + #bridges[feature = 'highway_secondary'][int_surface = 'unpaved'] { + [zoom >= 12] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-width: @secondary-width-z12 - 2 * @secondary-casing-width-z12; + line-pattern-file: url("symbols/unpaved/unpaved_secondary-fill.svg"); + line-pattern-cap: round; + line-pattern-join: round; + [zoom >= 13] { + [zoom >= 13] { line-pattern-width: @secondary-width-z13 - 2 * @secondary-casing-width-z13; } + [zoom >= 14] { line-pattern-width: @secondary-width-z14 - 2 * @secondary-casing-width-z14; } + [zoom >= 15] { line-pattern-width: @secondary-width-z15 - 2 * @secondary-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @secondary-width-z16 - 2 * @secondary-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @secondary-width-z17 - 2 * @secondary-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @secondary-width-z18 - 2 * @secondary-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @secondary-width-z19 - 2 * @secondary-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @secondary-link-width-z12 - 2 * @casing-width-z12; + [zoom >= 13] { line-pattern-width: @secondary-link-width-z13 - 2 * @casing-width-z13; } + [zoom >= 15] { line-pattern-width: @secondary-link-width-z15 - 2 * @casing-width-z15; } + [zoom >= 17] { line-pattern-width: @secondary-link-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @secondary-link-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @secondary-link-width-z19 - 2 * @casing-width-z19; } + } + #bridges { + line-pattern-width: @secondary-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @secondary-width-z13 - 2 * @major-bridge-casing-width-z13; } + [zoom >= 14] { line-pattern-width: @secondary-width-z14 - 2 * @major-bridge-casing-width-z14; } + [zoom >= 15] { line-pattern-width: @secondary-width-z15 - 2 * @major-bridge-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @secondary-width-z16 - 2 * @major-bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @secondary-width-z17 - 2 * @major-bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @secondary-width-z18 - 2 * @major-bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @secondary-width-z19 - 2 * @major-bridge-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @secondary-link-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @secondary-link-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @secondary-link-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @secondary-link-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @secondary-link-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @secondary-link-width-z19 - 2 * @bridge-casing-width-z19; } + } + } + } + } + } + [feature = 'highway_tertiary'] { [zoom >= 10] { line-color: @unimportant-road; @@ -1616,6 +1831,51 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } + #roads-fill[feature = 'highway_tertiary'][int_surface = 'unpaved'], + #bridges[feature = 'highway_tertiary'][int_surface = 'unpaved'] { + [zoom >= 12] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-width: @tertiary-width-z12 - 2 * @casing-width-z12; + line-pattern-file: url("symbols/unpaved/unpaved_residential-fill.svg"); + [zoom >= 13] { line-pattern-width: @tertiary-width-z13 - 2 * @casing-width-z13; } + [zoom >= 14] { line-pattern-width: @tertiary-width-z14 - 2 * @casing-width-z14; } + [zoom >= 15] { line-pattern-width: @tertiary-width-z15 - 2 * @casing-width-z15; } + [zoom >= 16] { line-pattern-width: @tertiary-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @tertiary-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @tertiary-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @tertiary-width-z19 - 2 * @casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @tertiary-link-width-z12 - 2 * @casing-width-z12; + [zoom >= 13] { line-pattern-width: @tertiary-link-width-z13 - 2 * @casing-width-z13; } + [zoom >= 15] { line-pattern-width: @tertiary-link-width-z15 - 2 * @casing-width-z15; } + [zoom >= 17] { line-pattern-width: @tertiary-link-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @tertiary-link-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @tertiary-link-width-z19 - 2 * @casing-width-z19; } + } + #bridges { + line-pattern-width: @tertiary-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @tertiary-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 14] { line-pattern-width: @tertiary-width-z14 - 2 * @bridge-casing-width-z14; } + [zoom >= 15] { line-pattern-width: @tertiary-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @tertiary-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @tertiary-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @tertiary-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @tertiary-width-z19 - 2 * @bridge-casing-width-z19; } + [link = 'yes'] { + line-pattern-width: @tertiary-link-width-z12 - 2 * @bridge-casing-width-z12; + [zoom >= 13] { line-pattern-width: @tertiary-link-width-z13 - 2 * @bridge-casing-width-z13; } + [zoom >= 15] { line-pattern-width: @tertiary-link-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 17] { line-pattern-width: @tertiary-link-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @tertiary-link-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @tertiary-link-width-z19 - 2 * @bridge-casing-width-z19; } + } + } + line-pattern-cap: round; + line-pattern-join: round; + } + } + [feature = 'highway_residential'], [feature = 'highway_unclassified'] { [zoom = 12][feature = 'highway_residential'] { @@ -1654,7 +1914,38 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_living_street'] { + #roads-fill[feature = 'highway_residential'][int_surface = 'unpaved'], + #bridges[feature = 'highway_residential'][int_surface = 'unpaved'], + #roads-fill[feature = 'highway_unclassified'][int_surface = 'unpaved'], + #bridges[feature = 'highway_unclassified'][int_surface = 'unpaved'] { + [zoom >= 13] { + line-pattern-width: @residential-width-z13 - 2 * @residential-casing-width-z13; + [zoom >= 14] { line-pattern-width: @residential-width-z14 - 2 * @casing-width-z14; } + [zoom >= 15] { line-pattern-width: @residential-width-z15 - 2 * @casing-width-z15; } + [zoom >= 16] { line-pattern-width: @residential-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @residential-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @residential-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @residential-width-z19 - 2 * @casing-width-z19; } + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_residential-fill.svg"); + #bridges { + line-pattern-width: @residential-width-z13 - 2 * @bridge-casing-width-z13; + [zoom >= 14] { line-pattern-width: @residential-width-z14 - 2 * @bridge-casing-width-z14; } + [zoom >= 15] { line-pattern-width: @residential-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @residential-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @residential-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @residential-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @residential-width-z19 - 2 * @bridge-casing-width-z19; } + } + line-pattern-cap: round; + line-pattern-join: round; + } + } + + #roads-fill[feature = 'highway_living_street'][int_surface != 'unpaved'], + #bridges[feature = 'highway_living_street'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_living_street'] { [zoom >= 13] { line-width: @living-street-width-z13 - 2 * @casing-width-z13; [zoom >= 14] { line-width: @living-street-width-z14 - 2 * @casing-width-z14; } @@ -1683,6 +1974,33 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } + #roads-fill[feature = 'highway_living_street'][int_surface = 'unpaved'], + #bridges[feature = 'highway_living_street'][int_surface = 'unpaved'] { + [zoom >= 13] { + line-pattern-width: @living-street-width-z13 - 2 * @casing-width-z13; + [zoom >= 14] { line-pattern-width: @living-street-width-z14 - 2 * @casing-width-z14; } + [zoom >= 15] { line-pattern-width: @living-street-width-z15 - 2 * @casing-width-z15; } + [zoom >= 16] { line-pattern-width: @living-street-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @living-street-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @living-street-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @living-street-width-z19 - 2 * @casing-width-z19; } + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_living-street-fill.svg"); + #bridges { + line-pattern-width: @living-street-width-z13 - 2 * @casing-width-z13; + [zoom >= 14] { line-pattern-width: @living-street-width-z14 - 2 * @bridge-casing-width-z14; } + [zoom >= 15] { line-pattern-width: @living-street-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @living-street-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @living-street-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @living-street-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @living-street-width-z19 - 2 * @bridge-casing-width-z19; } + } + line-pattern-join: round; + line-pattern-cap: round; + } + } + [feature = 'highway_road'] { [zoom >= 10] { line-width: 1; @@ -1713,7 +2031,32 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_service'] { + #roads-fill[feature = 'highway_road'][int_surface = 'unpaved'], + #bridges[feature = 'highway_road'][int_surface = 'unpaved'] { + [zoom >= 14] { + line-pattern-join: round; + line-pattern-cap: round; + line-pattern-width: @road-width-z14 - 2 * @casing-width-z14; + [zoom >= 16] { line-pattern-width: @road-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @road-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @road-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @road-width-z19 - 2 * @casing-width-z19; } + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_road-fill.svg"); + #bridges { + line-pattern-width: @road-width-z14 - 2 * @bridge-casing-width-z14; + [zoom >= 16] { line-pattern-width: @road-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @road-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @road-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @road-width-z19 - 2 * @bridge-casing-width-z19; } + } + } + } + + #roads-fill[feature = 'highway_service'][int_surface != 'unpaved'], + #bridges[feature = 'highway_service'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_service'] { [zoom >= 14][service = 'INT-normal'], [zoom >= 16][service = 'INT-minor'] { line-color: @service-fill; @@ -1757,7 +2100,51 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_pedestrian'] { + #roads-fill[feature = 'highway_service'][int_surface = 'unpaved'], + #bridges[feature = 'highway_service'][int_surface = 'unpaved'] { + [zoom >= 14][service = 'INT-normal'], + [zoom >= 16][service = 'INT-minor'] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_residential-fill.svg"); + [service = 'INT-normal'] { + line-pattern-width: @service-width-z14 - 2 * @casing-width-z14; + [zoom >= 16] { line-pattern-width: @service-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @service-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @service-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @service-width-z19 - 2 * @casing-width-z19; } + [zoom >= 20] { line-pattern-width: @service-width-z20 - 2 * @casing-width-z20; } + } + [service = 'INT-minor'] { + line-pattern-width: @minor-service-width-z16 - 2 * @casing-width-z16; + [zoom >= 17] { line-pattern-width: @minor-service-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @minor-service-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @minor-service-width-z19 - 2 * @casing-width-z19; } + [zoom >= 20] { line-pattern-width: @minor-service-width-z20 - 2 * @casing-width-z20; } + } + line-pattern-join: round; + line-pattern-cap: round; + #bridges { + [service = 'INT-normal'] { + line-pattern-width: @service-width-z14 - 2 * @bridge-casing-width-z14; + [zoom >= 16] { line-pattern-width: @service-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @service-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @service-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @service-width-z19 - 2 * @bridge-casing-width-z19; } + [zoom >= 20] { line-pattern-width: @service-width-z20 - 2 * @bridge-casing-width-z20; } + } + [service = 'INT-minor'] { + line-pattern-width: @minor-service-width-z16 - 2 * @bridge-casing-width-z16; + [zoom >= 17] { line-pattern-width: @minor-service-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @minor-service-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @minor-service-width-z19 - 2 * @bridge-casing-width-z19; } + [zoom >= 20] { line-pattern-width: @minor-service-width-z20 - 2 * @bridge-casing-width-z20; } + } + } + } + } + + [feature = 'highway_pedestrian'][int_surface != 'unpaved'] { [zoom >= 14] { line-width: @pedestrian-width-z14 - 2 * @casing-width-z14; [zoom >= 15] { line-width: @pedestrian-width-z15 - 2 * @casing-width-z15; } @@ -1779,7 +2166,31 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_raceway'] { + [feature = 'highway_pedestrian'][int_surface = 'unpaved'] { + [zoom >= 14] { + line-pattern-width: @pedestrian-width-z14 - 2 * @casing-width-z14; + [zoom >= 15] { line-pattern-width: @pedestrian-width-z15 - 2 * @casing-width-z15; } + [zoom >= 16] { line-pattern-width: @pedestrian-width-z16 - 2 * @casing-width-z16; } + [zoom >= 17] { line-pattern-width: @pedestrian-width-z17 - 2 * @casing-width-z17; } + [zoom >= 18] { line-pattern-width: @pedestrian-width-z18 - 2 * @casing-width-z18; } + [zoom >= 19] { line-pattern-width: @pedestrian-width-z19 - 2 * @casing-width-z19; } + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_pedestrian-fill.svg"); + #bridges { + line-pattern-width: @pedestrian-width-z14 - 2 * @bridge-casing-width-z14; + [zoom >= 15] { line-pattern-width: @pedestrian-width-z15 - 2 * @bridge-casing-width-z15; } + [zoom >= 16] { line-pattern-width: @pedestrian-width-z16 - 2 * @bridge-casing-width-z16; } + [zoom >= 17] { line-pattern-width: @pedestrian-width-z17 - 2 * @bridge-casing-width-z17; } + [zoom >= 18] { line-pattern-width: @pedestrian-width-z18 - 2 * @bridge-casing-width-z18; } + [zoom >= 19] { line-pattern-width: @pedestrian-width-z19 - 2 * @bridge-casing-width-z19; } + } + line-pattern-join: round; + line-pattern-cap: round; + } + } + + [feature = 'highway_raceway'][int_surface != 'unpaved'] { [zoom >= 12] { line-color: @raceway-fill; line-width: 1.2; @@ -1794,19 +2205,51 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ [zoom >= 20] { line-width: 24; } } - [feature = 'highway_platform'] { + [feature = 'highway_raceway'][int_surface = 'unpaved'] { + [zoom >= 12] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_raceway-fill.svg"); + line-pattern-width: 1.2; + line-pattern-join: round; + line-pattern-cap: round; + } + [zoom >= 13] { line-pattern-width: 2; } + [zoom >= 14] { line-pattern-width: 3; } + [zoom >= 15] { line-pattern-width: 6; } + [zoom >= 18] { line-pattern-width: 8; } + [zoom >= 19] { line-pattern-width: 12; } + [zoom >= 20] { line-pattern-width: 24; } + } + + [feature = 'highway_platform'][int_surface != 'unpaved'] { [zoom >= 16] { line-join: round; line-width: 6; line-color: grey; line-cap: round; b/line-width: 4; - b/line-color: #bbbbbb; + b/line-color: @platform-fill; b/line-cap: round; b/line-join: round; } } + [feature = 'highway_platform'][int_surface = 'unpaved'] { + [zoom >= 16] { + line-join: round; + line-width: 6; + line-color: grey; + line-cap: round; + b/line-pattern-width: 4; + b/line-pattern-type: repeat; + b/line-pattern-alignment: global; + b/line-pattern-file: url("symbols/unpaved/unpaved_platform-fill.svg"); + b/line-pattern-cap: round; + b/line-pattern-join: round; + } + } + [feature = 'highway_steps'] { [zoom >= 14][access != 'no'], [zoom >= 15] { @@ -2292,19 +2735,34 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'railway_platform'] { + [feature = 'railway_platform'][int_surface != 'unpaved'] { [zoom >= 16] { line-join: round; line-width: 6; line-color: grey; line-cap: round; b/line-width: 4; - b/line-color: #bbbbbb; + b/line-color: @platform-fill; b/line-cap: round; b/line-join: round; } } + [feature = 'railway_platform'][int_surface = 'unpaved'] { + [zoom >= 16] { + line-join: round; + line-width: 6; + line-color: grey; + line-cap: round; + b/line-pattern-width: 4; + b/line-pattern-type: repeat; + b/line-pattern-alignment: global; + b/line-pattern-file: url("symbols/unpaved/unpaved_platform-fill.svg"); + b/line-pattern-cap: round; + b/line-pattern-join: round; + } + } + [feature = 'railway_turntable'] { [zoom >= 16] { line-width: 1.5; @@ -2706,11 +3164,19 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ #highway-area-fill { [feature = 'highway_living_street'][zoom >= 14] { polygon-fill: @living-street-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_living-street-fill.svg'); + polygon-pattern-alignment: global; + } } [feature = 'highway_service'] { [zoom >= 14] { polygon-fill: #fff; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_residential-fill.svg'); + polygon-pattern-alignment: global; + } } } @@ -2718,27 +3184,46 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ [feature = 'highway_pedestrian'] { [zoom >= 15] { polygon-fill: @pedestrian-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_pedestrian-fill.svg'); + polygon-pattern-alignment: global; + } } } [feature = 'highway_platform'], [feature = 'railway_platform'] { [zoom >= 16] { - polygon-fill: #bbbbbb; - polygon-gamma: 0.65; + polygon-fill: @platform-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_platform-fill.svg'); + polygon-pattern-alignment: global; + } } } [feature = 'aeroway_runway'][zoom >= 11] { polygon-fill: @runway-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_aeroway-fill.svg'); + polygon-pattern-alignment: global; + } } [feature = 'aeroway_taxiway'][zoom >= 13] { polygon-fill: @taxiway-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_aeroway-fill.svg'); + polygon-pattern-alignment: global; + } } [feature = 'aeroway_helipad'][zoom >= 16] { polygon-fill: @helipad-fill; + [int_surface = 'unpaved'] { + polygon-pattern-file: url('symbols/unpaved/unpaved_aeroway-fill.svg'); + polygon-pattern-alignment: global; + } } } @@ -2974,13 +3459,26 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ [zoom >= 18] { line-width: 24 + 2*@major-casing-width-z18; } } ::fill { - line-color: @runway-fill; - line-width: 2; - [zoom >= 12] { line-width: 4; } - [zoom >= 13] { line-width: 6; } - [zoom >= 14] { line-width: 12; } - [zoom >= 15] { line-width: 18; } - [zoom >= 16] { line-width: 24; } + [int_surface != 'unpaved'] { + line-color: @runway-fill; + line-width: 2; + [zoom >= 12] { line-width: 4; } + [zoom >= 13] { line-width: 6; } + [zoom >= 14] { line-width: 12; } + [zoom >= 15] { line-width: 18; } + [zoom >= 16] { line-width: 24; } + } + [int_surface = 'unpaved'] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_aeroway-fill.svg"); + line-pattern-width: 2; + [zoom >= 12] { line-pattern-width: 4; } + [zoom >= 13] { line-pattern-width: 6; } + [zoom >= 14] { line-pattern-width: 12; } + [zoom >= 15] { line-pattern-width: 18; } + [zoom >= 16] { line-pattern-width: 24; } + } } } } @@ -2996,12 +3494,24 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ [zoom >= 18] { line-width: 8 + 2*@secondary-casing-width-z18; } } ::fill { - line-color: @taxiway-fill ; - line-width: 1; - [zoom >= 13] { line-width: 2; } - [zoom >= 14] { line-width: 4; } - [zoom >= 15] { line-width: 6; } - [zoom >= 16] { line-width: 8; } + [int_surface != 'unpaved'] { + line-color: @taxiway-fill ; + line-width: 1; + [zoom >= 13] { line-width: 2; } + [zoom >= 14] { line-width: 4; } + [zoom >= 15] { line-width: 6; } + [zoom >= 16] { line-width: 8; } + } + [int_surface = 'unpaved'] { + line-pattern-type: repeat; + line-pattern-alignment: global; + line-pattern-file: url("symbols/unpaved/unpaved_aeroway-fill.svg"); + line-pattern-width: 1; + [zoom >= 13] { line-pattern-width: 2; } + [zoom >= 14] { line-pattern-width: 4; } + [zoom >= 15] { line-pattern-width: 6; } + [zoom >= 16] { line-pattern-width: 8; } + } } } } diff --git a/symbols/unpaved/unpaved.md b/symbols/unpaved/unpaved.md new file mode 100644 index 0000000000..57ad3d0644 --- /dev/null +++ b/symbols/unpaved/unpaved.md @@ -0,0 +1,9 @@ +Base pattern file for unpaved roads is generated in two steps. + +In the first step visit [jsdotpattern (command sequence is recorded)](www.imagico.de/map/jsdotpattern.php#x,64,jdp59980;g,2.25,16,16;rx,250,2,8,8;rx,250,2,8,8;s,jdp58799;s,jdp49103;rx,250,2,8,8;rx,250,2,8,8;s,jdp94534;rx,250,2,8,8;rd,0,0,1,scree,0.07,5,10,0,jdp40148,0000ff,ffffff;) + +Use "get pattern SVG data" (it is expected that background will be transparent, background colour in jsdotpattern is only for display). + +Generated SVG image is sanitized for use with Mapnik by the script svg_pattern.sh from the jsdotpattern repository at http://github.com/imagico/jsdotpattern. The sanitized file is then edited manually, and the element is put above the element. The file is saved as unpaved.svg. + +From sanitized base SVG file (unpaved.svg), the coloured SVG versions are created. Just create a copy of the file, and within the SVG code replace fill:#0000ff with the actual foreground colour and fill:none with the actual background colour. This can be done automatically with scripts/generate_unpaved_patterns.py. diff --git a/symbols/unpaved/unpaved.svg b/symbols/unpaved/unpaved.svg new file mode 100644 index 0000000000..2e75e78df7 --- /dev/null +++ b/symbols/unpaved/unpaved.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_aeroway-fill.svg b/symbols/unpaved/unpaved_aeroway-fill.svg new file mode 100644 index 0000000000..a4c7645ab3 --- /dev/null +++ b/symbols/unpaved/unpaved_aeroway-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_living-street-fill.svg b/symbols/unpaved/unpaved_living-street-fill.svg new file mode 100644 index 0000000000..ccd7c1873f --- /dev/null +++ b/symbols/unpaved/unpaved_living-street-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_motorway-fill.svg b/symbols/unpaved/unpaved_motorway-fill.svg new file mode 100644 index 0000000000..df63ebd530 --- /dev/null +++ b/symbols/unpaved/unpaved_motorway-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_motorway-low-zoom.svg b/symbols/unpaved/unpaved_motorway-low-zoom.svg new file mode 100644 index 0000000000..0e789aabf9 --- /dev/null +++ b/symbols/unpaved/unpaved_motorway-low-zoom.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_pedestrian-fill.svg b/symbols/unpaved/unpaved_pedestrian-fill.svg new file mode 100644 index 0000000000..ef7eacb628 --- /dev/null +++ b/symbols/unpaved/unpaved_pedestrian-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_platform-fill.svg b/symbols/unpaved/unpaved_platform-fill.svg new file mode 100644 index 0000000000..320295e351 --- /dev/null +++ b/symbols/unpaved/unpaved_platform-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_primary-fill.svg b/symbols/unpaved/unpaved_primary-fill.svg new file mode 100644 index 0000000000..146725d731 --- /dev/null +++ b/symbols/unpaved/unpaved_primary-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_primary-low-zoom.svg b/symbols/unpaved/unpaved_primary-low-zoom.svg new file mode 100644 index 0000000000..a3b75a9dee --- /dev/null +++ b/symbols/unpaved/unpaved_primary-low-zoom.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_raceway-fill.svg b/symbols/unpaved/unpaved_raceway-fill.svg new file mode 100644 index 0000000000..31d8e4696b --- /dev/null +++ b/symbols/unpaved/unpaved_raceway-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_residential-fill.svg b/symbols/unpaved/unpaved_residential-fill.svg new file mode 100644 index 0000000000..56a803e3e6 --- /dev/null +++ b/symbols/unpaved/unpaved_residential-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_road-fill.svg b/symbols/unpaved/unpaved_road-fill.svg new file mode 100644 index 0000000000..c7205dec32 --- /dev/null +++ b/symbols/unpaved/unpaved_road-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_secondary-fill.svg b/symbols/unpaved/unpaved_secondary-fill.svg new file mode 100644 index 0000000000..082a97385c --- /dev/null +++ b/symbols/unpaved/unpaved_secondary-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_trunk-fill.svg b/symbols/unpaved/unpaved_trunk-fill.svg new file mode 100644 index 0000000000..805f0a7374 --- /dev/null +++ b/symbols/unpaved/unpaved_trunk-fill.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + diff --git a/symbols/unpaved/unpaved_trunk-low-zoom.svg b/symbols/unpaved/unpaved_trunk-low-zoom.svg new file mode 100644 index 0000000000..fad9581030 --- /dev/null +++ b/symbols/unpaved/unpaved_trunk-low-zoom.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + Created with Snap + From 75e7dc87218e7eb949cf6b5a7b3eb04e013d1493 Mon Sep 17 00:00:00 2001 From: Lukas Sommer Date: Sun, 21 Aug 2022 11:48:54 +0000 Subject: [PATCH 2/2] Consistent behaviour for unpaved tunnels --- style/roads.mss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/style/roads.mss b/style/roads.mss index 8595ceed16..53c203980a 100644 --- a/style/roads.mss +++ b/style/roads.mss @@ -2144,7 +2144,9 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_pedestrian'][int_surface != 'unpaved'] { + #roads-fill[feature = 'highway_pedestrian'][int_surface != 'unpaved'], + #bridges[feature = 'highway_pedestrian'][int_surface != 'unpaved'], + #tunnels[feature = 'highway_pedestrian'] { [zoom >= 14] { line-width: @pedestrian-width-z14 - 2 * @casing-width-z14; [zoom >= 15] { line-width: @pedestrian-width-z15 - 2 * @casing-width-z15; } @@ -2166,7 +2168,8 @@ tertiary is rendered from z10 and is not included in osm_planet_roads. */ } } - [feature = 'highway_pedestrian'][int_surface = 'unpaved'] { + #roads-fill[feature = 'highway_pedestrian'][int_surface = 'unpaved'], + #bridges[feature = 'highway_pedestrian'][int_surface = 'unpaved'] { [zoom >= 14] { line-pattern-width: @pedestrian-width-z14 - 2 * @casing-width-z14; [zoom >= 15] { line-pattern-width: @pedestrian-width-z15 - 2 * @casing-width-z15; }