Mon, 14 Sep 2020 22:55:45 +0300
restore .hg...
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,5 @@ +syntax:glob +data +symbols/shields +project-spaces.mml +mapnik.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,36 @@ +SHELL=/bin/bash + +all: + echo + +clear-cache: + rm -rf /var/lib/mod_tile/ajt + +restart: + sudo service renderd stop + rm -rf /var/lib/mod_tile/ajt + sudo service renderd start + +update: build-style clear-cache restart +build-shields: + python3 scripts/generate_shields.py + +build-style: build-shields + sed 's/\t/ /g' project.mml >project-spaces.mml + carto project-spaces.mml > mapnik.xml + +test-style: clear-cache + renderd -f -c /usr/local/etc/renderd.conf + +import: + osm2pgsql \ + -d gis \ + --create \ + --slim \ + -G \ + --hstore \ + --tag-transform-script ~/style/openstreetmap-carto.lua \ + -C 9000 \ + --number-processes 8 \ + -S ~/style/openstreetmap-carto.style \ + ~/data/map.pbf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/external-data.yml Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,81 @@ +settings: + temp_schema: loading + schema: public + data_dir: data + database: gis + metadata_table: external_data +sources: + simplified_water_polygons: + # The type of file this source is + type: shp + # Where to get it + url: https://osmdata.openstreetmap.de/download/simplified-water-polygons-split-3857.zip + # The location within the archive + file: simplified-water-polygons-split-3857/simplified_water_polygons.shp + archive: + format: zip + # Files to extract from the archive + files: + - simplified-water-polygons-split-3857/simplified_water_polygons.cpg + - simplified-water-polygons-split-3857/simplified_water_polygons.dbf + - simplified-water-polygons-split-3857/simplified_water_polygons.prj + - simplified-water-polygons-split-3857/simplified_water_polygons.shp + - simplified-water-polygons-split-3857/simplified_water_polygons.shx + water_polygons: + type: shp + url: https://osmdata.openstreetmap.de/download/water-polygons-split-3857.zip + file: water-polygons-split-3857/water_polygons.shp + archive: + format: zip + files: + - water-polygons-split-3857/water_polygons.cpg + - water-polygons-split-3857/water_polygons.dbf + - water-polygons-split-3857/water_polygons.prj + - water-polygons-split-3857/water_polygons.shp + - water-polygons-split-3857/water_polygons.shx + icesheet_polygons: + type: shp + url: https://osmdata.openstreetmap.de/download/antarctica-icesheet-polygons-3857.zip + file: antarctica-icesheet-polygons-3857/icesheet_polygons.shp + archive: + format: zip + files: + - antarctica-icesheet-polygons-3857/icesheet_polygons.cpg + - antarctica-icesheet-polygons-3857/icesheet_polygons.dbf + - antarctica-icesheet-polygons-3857/icesheet_polygons.prj + - antarctica-icesheet-polygons-3857/icesheet_polygons.shp + - antarctica-icesheet-polygons-3857/icesheet_polygons.shx + icesheet_outlines: + type: shp + url: https://osmdata.openstreetmap.de/download/antarctica-icesheet-outlines-3857.zip + file: antarctica-icesheet-outlines-3857/icesheet_outlines.shp + ogropts: + - "-explodecollections" + archive: + format: zip + files: + - antarctica-icesheet-outlines-3857/icesheet_outlines.cpg + - antarctica-icesheet-outlines-3857/icesheet_outlines.dbf + - antarctica-icesheet-outlines-3857/icesheet_outlines.prj + - antarctica-icesheet-outlines-3857/icesheet_outlines.shp + - antarctica-icesheet-outlines-3857/icesheet_outlines.shx + + ne_110m_admin_0_boundary_lines_land: + type: shp + url: http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/ne_110m_admin_0_boundary_lines_land.zip + file: ne_110m_admin_0_boundary_lines_land.shp + ogropts: &ne_opts + - "--config" + - "SHAPE_ENCODING" + - "WINDOWS-1252" + - "-explodecollections" + # needs reprojecting + - '-t_srs' + - 'EPSG:3857' + archive: + format: zip + files: + - ne_110m_admin_0_boundary_lines_land.dbf + - ne_110m_admin_0_boundary_lines_land.prj + - ne_110m_admin_0_boundary_lines_land.shp + - ne_110m_admin_0_boundary_lines_land.shx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flex.lua Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,1011 @@ +-- This configuration for the flex backend tries to be compatible with the +-- original pgsql c-transform backend. There might be some corner cases but +-- it should mostly do exactly the same. + +-- Set this to true if you were using option -K|--keep-coastlines. +local keep_coastlines = true + +-- Set this to the table name prefix (what used to be option -p|--prefix). +local prefix = 'planet_osm' + +-- Set this to true if multipolygons should be written as polygons into db +-- (what used to be option -G|--multi-geometry). +local multi_geometry = true + +-- Set this to true if you want an hstore column (what used to be option +-- -k|--hstore). Can not be true if "hstore_all" is true. +local hstore = true + +-- Set this to true if you want all tags in an hstore column (what used to +-- be option -j|--hstore-all). Can not be true if "hstore" is true. +local hstore_all = false + +-- Only keep objects that have a value in one of the non-hstore columns +-- (normal action with --hstore is to keep all objects). Equivalent to +-- what used to be set through option --hstore-match-only. +local hstore_match_only = true + +-- Set this to add an additional hstore (key/value) column containing all tags +-- that start with the specified string, eg "name:". Will produce an extra +-- hstore column that contains all "name:xx" tags. Equivalent to what used to +-- be set through option -z|--hstore-column. +local hstore_column = nil + +-- There is some very old specialized handling of route relations in osm2pgsql, +-- which you probably don't need. This is disabled here, but you can enable +-- it by setting this to true. If you don't understand this, leave it alone. +local enable_legacy_route_processing = false + +-- --------------------------------------------------------------------------- + +if hstore and hstore_all then + error("hstore and hstore_all can't be both true") +end + +-- Used for splitting up long linestrings +if osm2pgsql.srid == 4326 then + max_length = 1 +else + max_length = 100000 +end + +-- Ways with any of the following keys will be treated as polygon +local polygon_keys = { + 'aeroway', + 'amenity', + 'building', + 'harbour', + 'historic', + 'landuse', + 'leisure', + 'man_made', + 'military', + 'natural', + 'office', + 'place', + 'power', + 'public_transport', + 'shop', + 'sport', + 'tourism', + 'water', + 'waterway', + 'wetland', + 'abandoned:aeroway', + 'abandoned:amenity', + 'abandoned:building', + 'abandoned:landuse', + 'abandoned:power', + 'area:highway' +} + +-- Objects without any of the following keys will be deleted +local generic_keys = { + 'access', + 'addr:housename', + 'addr:housenumber', + 'addr:interpolation', + 'admin_level', + 'aerialway', + 'aeroway', + 'amenity', + 'area', + 'barrier', + 'bicycle', + 'boundary', + 'brand', + 'bridge', + 'building', + 'capital', + 'construction', + 'covered', + 'culvert', + 'cutting', + 'denomination', + 'disused', + 'ele', + 'embankment', + 'foot', + 'generation:source', + 'harbour', + 'healthcare', + 'highway', + 'historic', + 'hours', + 'intermittent', + 'junction', + 'landuse', + 'layer', + 'leisure', + 'lock', + 'man_made', + 'military', + 'motorcar', + 'name', + 'natural', + 'office', + 'oneway', + 'operator', + 'place', + 'population', + 'power', + 'power_source', + 'public_transport', + 'railway', + 'ref', + 'religion', + 'route', + 'service', + 'shop', + 'sport', + 'surface', + 'toll', + 'tourism', + 'tower:type', + 'tracktype', + 'tunnel', + 'water', + 'waterway', + 'wetland', + 'width', + 'wood', + 'abandoned:aeroway', + 'abandoned:amenity', + 'abandoned:building', + 'abandoned:landuse', + 'abandoned:power', + 'area:highway' +} + +-- The following keys will be deleted +local delete_keys = { + 'attribution', + 'comment', + 'created_by', + 'fixme', + 'note', + 'note:*', + 'odbl', + 'odbl:note', + 'source', + 'source:*', + 'source_ref', + 'way', + 'way_area', + 'z_order', +} + +local point_columns = { + 'access', + 'addr:housename', + 'addr:housenumber', + 'addr:interpolation', + 'admin_level', + 'aerialway', + 'aeroway', + 'amenity', + 'area', + 'barrier', + 'bicycle', + 'brand', + 'bridge', + 'boundary', + 'building', + 'capital', + 'construction', + 'covered', + 'culvert', + 'cutting', + 'denomination', + 'disused', + 'ele', + 'embankment', + 'foot', + 'generator:source', + 'harbour', + 'highway', + 'historic', + 'horse', + 'intermittent', + 'junction', + 'landuse', + 'layer', + 'leisure', + 'lock', + 'man_made', + 'military', + 'motorcar', + 'name', + 'name:fi', + 'name:sv', + 'minority_name', + 'majority_name', + 'bilingual_name', + 'natural', + 'office', + 'oneway', + 'operator', + 'place', + 'population', + 'power', + 'power_source', + 'public_transport', + 'railway', + 'ref', + 'religion', + 'route', + 'service', + 'shop', + 'sport', + 'surface', + 'toll', + 'tourism', + 'tower:type', + 'tunnel', + 'water', + 'waterway', + 'wetland', + 'width', + 'wood', +} + +local non_point_columns = { + 'access', + 'addr:housename', + 'addr:housenumber', + 'addr:interpolation', + 'admin_level', + 'aerialway', + 'aeroway', + 'amenity', + 'area', + 'barrier', + 'bicycle', + 'brand', + 'bridge', + 'boundary', + 'building', + 'construction', + 'covered', + 'culvert', + 'cutting', + 'denomination', + 'disused', + 'embankment', + 'foot', + 'generator:source', + 'harbour', + 'highway', + 'historic', + 'horse', + 'intermittent', + 'junction', + 'landuse', + 'layer', + 'leisure', + 'lock', + 'man_made', + 'military', + 'motorcar', + 'name', + 'name:fi', + 'name:sv', + 'minority_name', + 'majority_name', + 'bilingual_name', + 'natural', + 'office', + 'oneway', + 'operator', + 'place', + 'population', + 'power', + 'power_source', + 'public_transport', + 'railway', + 'ref', + 'ref_class', + 'ref_width', + 'religion', + 'route', + 'service', + 'shop', + 'sport', + 'surface', + 'toll', + 'tourism', + 'tower:type', + 'tracktype', + 'tunnel', + 'water', + 'waterway', + 'wetland', + 'width', + 'wood', +} + +-- highlight some suburbs in the capital region +boroughs = { + -- Helsinki + ["Q2116584"] = 1, -- Vuosaari / Nordsjö + ["Q2510635"] = 1, -- Oulunkylä / Åggelby + ["Q3130945"] = 1, -- Viikki / Vik + ["Q1614778"] = 1, -- Herttoniemi / Hertonäs + -- Espoo + ["Q166942"] = 1, -- Leppävaara / Alberga + ["Q3107346"] = 1, -- Matinkylä / Mattby + ["Q211491"] = 1, -- Espoonlahti / Esboviken + ["Q211489"] = 1, -- Espoon keskus / Esbo centrum + ["Q219044"] = 1, -- Kauklahti / Köklax + ["Q1668730"] = 1, -- Tapiola / Hagalund + -- Vantaa + ["Q2640455"] = 1, -- Tikkurila / Dickursby + ["Q4412122"] = 1, -- Aviapolis + ["Q3736737"] = 1, -- Myyrmäki / Myrbacka + ["Q4557316"] = 1, -- Kivistö + ["Q4556551"] = 1, -- Koivukylä / Björkby + ["Q3742144"] = 1, -- Korso + ["Q4556262"] = 1, -- Hakunila / Håkansböle +} + +-- +-- Name in majority language for object. This is name unless both name:fi and +-- name:sv disagree with name. +-- @param tags Raw OSM tags +-- @return Bilingual name +-- +function majority_name(tags) + if tags.name ~= nil and tags['name:sv'] ~= nil and tags['name:fi'] and tags.name ~= tags['name:fi'] and tags.name ~= tags['name:sv'] + then + return tags['name:fi'] + else + return tags.name + end +end +-- +-- Name in minority language for object. This is the Swedish name if name is in +-- Finnish, and the Finnish name if name is in Swedish. +-- @param tags Raw OSM tags +-- @return Bilingual name +-- +function minority_name(tags) + if tags['name:sv'] ~= nil and tags['name'] ~= tags['name:sv'] + then + return tags['name:sv'] + elseif tags['name:fi'] ~= nil and tags['name'] ~= tags['name:fi'] + then + return tags['name:fi'] + else + return nil + end +end + +function bilingual_name(tags) + if tags.majority_name ~= nil and tags.minority_name ~= nil + then + return tags.majority_name .. '\n' .. tags.minority_name + else + return tags.majority_name + end +end + +-- Makes highway classes more sensible +function highway_class(tags) + if string.match(tags.highway, '_link$') + then + if tags.tags.functional_class == 'service' or tags.tags.functional_class == 'unclassified' + then + return tags.tags.functional_class + elseif tags.tags.functional_class ~= nil + then + return tags.tags.functional_class..'_link' + elseif tags.highway == 'motorway_link' + then + return 'trunk_link' + else + return tags.highway + end + elseif tags.highway == 'motorway' + then + if tags.tags.functional_class == 'primary' or tags.tags.functional_class == 'secondary' or tags.tags.functional_class == 'tertiary' + then + return tags.tags.functional_class + elseif tags.tags.functional_class == 'service' + then + return 'service' + else + return 'trunk' + end + else + if tags.highway ~= nil and tags.tags.functional_class ~= nil + then + return tags.tags.functional_class + else + return tags.highway + end + end +end + +function has_shields(tags) + return (tags.highway == 'trunk' or tags.highway == 'primary' or tags.highway == 'secondary' or tags.highway == 'tertiary') +end + +-- https://stackoverflow.com/a/7615129 +function mysplit(inputstr, sep) + if sep == nil then + sep = "%s" + end + local t={} + for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + table.insert(t, str) + end + return t +end + +function combine_stringlists(a, b) + if a ~= nil and a ~= '' + then + if b ~= nil and b ~= '' + then + return a..';'..b + else + return a + end + else + return b + end +end + +function combine_refs(a, b) + return combine_stringlists(a, b) +end + +-- Widths of ref characters in Liikenne font, used to calculate shield sizes +character_widths = { + ['0'] = 616, + ['1'] = 337, + ['2'] = 600, + ['3'] = 621, + ['4'] = 689, + ['5'] = 623, + ['6'] = 566, + ['7'] = 499, + ['8'] = 616, + ['9'] = 566, + [' '] = 260, + ['E'] = 613, +} + +function ref_width(ref) + local result = 0 + for i = 1, #ref + do + result = result + (character_widths[ref:sub(i, i)] or 0) + end + return math.max(math.ceil((result - 1000) / 77), 1) +end + +function ref_widths(refs) + local result = '' + for _, ref in ipairs(mysplit(refs, ';')) + do + result = combine_stringlists(result, ref_width(ref)) + end + return result +end + +-- Makes refs more sensible. +-- 5-digit refs are not found on the ground so they are omitted. +-- int_ref is added to refs. +function highway_refs(tags) + if has_shields(tags) and (tags.ref ~= nil or tags.tags.int_ref ~= nil) + then + if tags.junction == 'roundabout' + then + return nil + else + local result = '' + local all_refs = combine_refs(tags.ref, tags.tags.int_ref) + for _, ref in ipairs(mysplit(all_refs, ';')) + do + if tonumber(ref) == nil or tonumber(ref) < 10000 + then + ref = string.gsub(ref, '^E 0', 'E ') + result = combine_refs(result, ref) + end + end + return result + end + else + return tags.ref + end +end + +-- classify road type by number +function road_class_by_ref(ref) + local n = tonumber(ref) + if n ~= nil and n > 0 + then + if n < 40 + then + return 'valtatie' + elseif n < 100 + then + return 'kantatie' + elseif n < 1000 + then + return 'seututie' + else + return 'yhdystie' + end + elseif string.match(ref, '^E ?%d+$') + then + return 'eurooppatie' + else + return 'unknown' + end +end + +function classify_road_numbers(refs) + local result = '' + for _, ref in ipairs(mysplit(refs, ';')) + do + result = combine_stringlists(result, road_class_by_ref(ref)) + end + return result +end + +function gen_columns(text_columns, with_hstore, area, geometry_type) + columns = {} + + local add_column = function (name, type) + columns[#columns + 1] = { column = name, type = type } + end + + for _, c in ipairs(text_columns) do + add_column(c, 'text') + end + + add_column('z_order', 'int') + + if area ~= nil then + if area then + add_column('way_area', 'area') + else + add_column('way_area', 'real') + end + end + + if hstore_column then + add_column(hstore_column, 'hstore') + end + + if with_hstore then + add_column('tags', 'hstore') + end + + add_column('way', geometry_type) + + return columns +end + +local tables = {} + +tables.point = osm2pgsql.define_table{ + name = prefix .. '_point', + ids = { type = 'node', id_column = 'osm_id' }, + columns = gen_columns(point_columns, hstore or hstore_all, nil, 'point') +} + +tables.line = osm2pgsql.define_table{ + name = prefix .. '_line', + ids = { type = 'way', id_column = 'osm_id' }, + columns = gen_columns(non_point_columns, hstore or hstore_all, false, 'linestring') +} + +tables.polygon = osm2pgsql.define_table{ + name = prefix .. '_polygon', + ids = { type = 'area', id_column = 'osm_id' }, + columns = gen_columns(non_point_columns, hstore or hstore_all, true, 'geometry') +} + +tables.roads = osm2pgsql.define_table{ + name = prefix .. '_roads', + ids = { type = 'way', id_column = 'osm_id' }, + columns = gen_columns(non_point_columns, hstore or hstore_all, false, 'linestring') +} + +local z_order_lookup = { + proposed = {1, false}, + construction = {2, false}, + steps = {10, false}, + cycleway = {10, false}, + bridleway = {10, false}, + footway = {10, false}, + path = {10, false}, + track = {11, false}, + service = {15, false}, + + tertiary_link = {24, false}, + secondary_link = {25, true}, + primary_link = {27, true}, + trunk_link = {28, true}, + motorway_link = {29, true}, + + raceway = {30, false}, + pedestrian = {31, false}, + living_street = {32, false}, + road = {33, false}, + unclassified = {33, false}, + residential = {33, false}, + tertiary = {34, false}, + secondary = {36, true}, + primary = {37, true}, + trunk = {38, true}, + motorway = {39, true} +} + +function as_bool(value) + return value == 'yes' or value == 'true' or value == '1' +end + +function get_z_order(tags) + local z_order = 100 * math.floor(tonumber(tags.layer or '0') or 0) + local roads = false + + local highway = tags['highway'] + if highway then + local r = z_order_lookup[highway] or {0, false} + z_order = z_order + r[1] + roads = r[2] + end + + if tags.railway then + z_order = z_order + 35 + roads = true + end + + if tags.boundary and tags.boundary == 'administrative' then + roads = true + end + + if as_bool(tags.bridge) then + z_order = z_order + 100 + end + + if as_bool(tags.tunnel) then + z_order = z_order - 100 + end + + return z_order, roads +end + +function make_check_in_list_func(list) + local h = {} + for _, k in ipairs(list) do + h[k] = true + end + return function(tags) + for k, _ in pairs(tags) do + if h[k] then + return true + end + end + return false + end +end + +local is_polygon = make_check_in_list_func(polygon_keys) +local clean_tags = osm2pgsql.make_clean_tags_func(delete_keys) + +function make_column_hash(columns) + local h = {} + + for _, k in ipairs(columns) do + h[k] = true + end + + return h +end + +function make_get_output(columns, hstore_all) + local h = make_column_hash(columns) + if hstore_all then + return function(tags) + local output = {} + local hstore_entries = {} + + for k, _ in pairs(tags) do + if h[k] then + output[k] = tags[k] + end + hstore_entries[k] = tags[k] + end + + return output, hstore_entries + end + else + return function(tags) + local output = {} + local hstore_entries = {} + + for k, _ in pairs(tags) do + if h[k] then + output[k] = tags[k] + else + hstore_entries[k] = tags[k] + end + end + + return output, hstore_entries + end + end +end + +local has_generic_tag = make_check_in_list_func(generic_keys) + +local get_point_output = make_get_output(point_columns, hstore_all) +local get_non_point_output = make_get_output(non_point_columns, hstore_all) + +function get_hstore_column(tags) + local len = #hstore_column + local h = {} + for k, v in pairs(tags) do + if k:sub(1, len) == hstore_column then + h[k:sub(len + 1)] = v + end + end + + if next(h) then + return h + end + return nil +end + +function add_generic_tags(object, output) + output.majority_name = majority_name(output) + output.minority_name = minority_name(output) + output.bilingual_name = bilingual_name(output) + return output +end + +function osm2pgsql.process_node(object) + if clean_tags(object.tags) then + return + end + + if object.tags.layer then + object.tags.layer = tonumber(object.tags.layer) + end + + local output + local output_hstore = {} + if hstore or hstore_all then + output, output_hstore = get_point_output(object.tags) + if not next(output) and not next(output_hstore) then + return + end + if hstore_match_only and not has_generic_tag(object.tags) then + return + end + else + output = object.tags + if not has_generic_tag(object.tags) then + return + end + end + + output = add_generic_tags(object, output) + output.tags = output_hstore + + if hstore_column then + output[hstore_column] = get_hstore_column(object.tags) + end + + tables.point:add_row(output) +end + +function osm2pgsql.process_way(object) + if clean_tags(object.tags) then + return + end + + if object.tags.layer then + object.tags.layer = tonumber(object.tags.layer) + end + + + local add_area = false + if object.tags.natural == 'coastline' then + add_area = true + if not keep_coastlines then + object.tags.natural = nil + end + end + + local output + local output_hstore = {} + if hstore or hstore_all then + output, output_hstore = get_non_point_output(object.tags) + if not next(output) and not next(output_hstore) then + return + end + if hstore_match_only and not has_generic_tag(object.tags) then + return + end + if add_area and hstore_all then + output_hstore.area = 'yes' + end + else + output = object.tags + if not has_generic_tag(object.tags) then + return + end + end + + local polygon + local area_tag = object.tags.area + if area_tag == 'yes' or area_tag == '1' or area_tag == 'true' then + polygon = true + elseif area_tag == 'no' or area_tag == '0' or area_tag == 'false' then + polygon = false + else + polygon = is_polygon(object.tags) + end + + if add_area then + output.area = 'yes' + polygon = true + end + + local z_order, roads = get_z_order(object.tags) + output.z_order = z_order + output = add_generic_tags(object, output) + + output.tags = output_hstore + + if output.highway ~= nil + then + if output.highway == 'construction' + then + return + end + output.highway = highway_class(output) + output.ref = highway_refs(output) + if output.highway == 'construction' and output.construction == 'motorway' + then + output.construction = 'trunk' + elseif output.highway == 'construction' and output.construction == 'motorway_link' + then + output.construction = 'trunk_link' + end + + -- classify references for for Finland shield rendering + if output.ref ~= nil + then + output.ref_class = classify_road_numbers(output.ref) + output.ref_width = ref_widths(output.ref) + end + end + + if hstore_column then + output[hstore_column] = get_hstore_column(object.tags) + end + + if polygon and object.is_closed then + output.way = { create = 'area' } + tables.polygon:add_row(output) + else + output.way = { create = 'line', split_at = max_length } + tables.line:add_row(output) + if roads then + tables.roads:add_row(output) + end + end +end + +function osm2pgsql.process_relation(object) + if clean_tags(object.tags) then + return + end + + local type = object.tags.type + if (type ~= 'route') and (type ~= 'multipolygon') and (type ~= 'boundary') then + return + end + object.tags.type = nil + + local output + local output_hstore = {} + if hstore or hstore_all then + output, output_hstore = get_non_point_output(object.tags) + if not next(output) and not next(output_hstore) then + return + end + if hstore_match_only and not has_generic_tag(object.tags) then + return + end + else + output = object.tags + if not has_generic_tag(object.tags) then + return + end + end + + if not next(output) and not next(output_hstore) then + return + end + + if enable_legacy_route_processing and (hstore or hstore_all) and type == 'route' then + if not object.tags.route_name then + output_hstore.route_name = object.tags.name + end + + local state = object.tags.state + if state ~= 'alternate' and state ~= 'connection' then + state = 'yes' + end + + local network = object.tags.network + if network == 'lcn' then + output_hstore.lcn = output_hstore.lcn or state + output_hstore.lcn_ref = output_hstore.lcn_ref or object.tags.ref + elseif network == 'rcn' then + output_hstore.rcn = output_hstore.rcn or state + output_hstore.rcn_ref = output_hstore.rcn_ref or object.tags.ref + elseif network == 'ncn' then + output_hstore.ncn = output_hstore.ncn or state + output_hstore.ncn_ref = output_hstore.ncn_ref or object.tags.ref + elseif network == 'lwn' then + output_hstore.lwn = output_hstore.lwn or state + output_hstore.lwn_ref = output_hstore.lwn_ref or object.tags.ref + elseif network == 'rwn' then + output_hstore.rwn = output_hstore.rwn or state + output_hstore.rwn_ref = output_hstore.rwn_ref or object.tags.ref + elseif network == 'nwn' then + output_hstore.nwn = output_hstore.nwn or state + output_hstore.nwn_ref = output_hstore.nwn_ref or object.tags.ref + end + + local pc = object.tags.preferred_color + if pc == '0' or pc == '1' or pc == '2' or pc == '3' or pc == '4' then + output_hstore.route_pref_color = pc + else + output_hstore.route_pref_color = '0' + end + end + + local make_boundary = false + local make_polygon = false + if type == 'boundary' then + make_boundary = true + elseif type == 'multipolygon' and object.tags.boundary then + make_boundary = true + elseif type == 'multipolygon' then + make_polygon = true + end + + local z_order, roads = get_z_order(object.tags) + output.z_order = z_order + output = add_generic_tags(object, output) + + output.tags = output_hstore + + if hstore_column then + output[hstore_column] = get_hstore_column(object.tags) + end + + if not make_polygon then + output.way = { create = 'line', split_at = max_length } + tables.line:add_row(output) + if roads then + tables.roads:add_row(output) + end + end + + if make_boundary or make_polygon then + output.way = { create = 'area', multi = multi_geometry } + tables.polygon:add_row(output) + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project.mml Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,804 @@ +scale: 1 +metatile: 2 +name: +description: A general-purpose OpenStreetMap mapnik style, in CartoCSS +bounds: &world + - -180 + - -85.05112877980659 + - 180 + - 85.05112877980659 +center: + - 0 + - 0 + - 4 +format: png +interactivity: false +minzoom: 0 +maxzoom: 22 +srs: "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" + +# Various parts to be included later on +_parts: + # Extents are used for tilemill, and don't actually make it to the generated XML + extents: &extents + extent: *world + srs-name: "900913" + srs: "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" + osm2pgsql: &osm2pgsql + type: "postgis" + dbname: "gis" + key_field: "" + geometry_field: "way" + extent: "-20037508,-20037508,20037508,20037508" + +Stylesheet: + - style/style.mss + - style/roads.mss + - style/buildings.mss + - style/places.mss + - style/shapefiles.mss + - style/amenity.mss + - style/roadref.mss +Layer: + - id: landcover + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + (CASE WHEN + "landuse" IN ('grass', 'meadow', 'recreation_ground') + OR ("leisure" IN ('park', 'playground', 'arena', 'stadium', 'sports_centre') AND landuse IS NULL) + OR "natural" = 'scrub' + THEN 'grass' + ELSE CASE WHEN ("landuse" IN ('commercial', 'retail') OR "amenity" IN ('bus_station', 'ferry_terminal')) + THEN 'commercial' + ELSE CASE WHEN ("natural" = 'wood' OR "landuse" = 'forest') + THEN 'forest' + ELSE CASE WHEN ("natural" = 'water' OR "landuse" IN ('reservoir')) + THEN 'water' + ELSE CASE WHEN ("landuse" IN ('religious', 'cemetery') OR "amenity" = 'grave_yard') + THEN 'religious' + ELSE CASE WHEN ("landuse" = 'railway') + THEN 'industrial' + ELSE "landuse" + END + END + END + END + END + END) AS feature, + way_area/NULLIF(POW(!scale_denominator!*0.001*0.28,2),0) AS way_pixels, + way_area + FROM planet_osm_polygon + WHERE (landuse IN ('forest', 'farmland', 'residential', 'commercial', 'retail', 'industrial', 'meadow', 'grass', 'vineyard', 'orchard', 'religious', 'railway', 'construction', 'cemetery') + OR "natural" IN ('wood', 'wetland', 'mud', 'sand', 'scree', 'shingle', 'bare_rock', 'heath', 'grassland', 'scrub', 'water')) + OR "leisure" IN ('park', 'playground', 'arena', 'stadium', 'sports_centre') + OR "amenity" IN ('bus_station', 'ferry_terminal', 'grave_yard') + AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real + AND building IS NULL + ORDER BY way_area DESC, feature + ) AS landcover + properties: + cache-features: true + minzoom: 5 + - id: inland-water + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way + FROM planet_osm_polygon + WHERE ("natural" = 'water' OR landuse IN ('reservoir', 'basin') OR waterway = 'riverbank') + ) AS landcover + properties: + cache-features: true + minzoom: 5 + - id: ocean-lz + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way + FROM simplified_water_polygons + ) AS ocean_lz + properties: + maxzoom: 9 + - id: civic-services + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way + FROM planet_osm_polygon + WHERE ("amenity" IN ('hospital', 'community_centre', 'fire_station', 'school', 'university', 'kindergarten', 'childcare', 'social_facility') OR landuse IN ('civic_services', 'civic_admin')) + ) AS civic_services + properties: + cache-features: true + minzoom: 5 + - id: aerodrome + geometry: polygon + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way + FROM planet_osm_polygon + WHERE aeroway = 'aerodrome' + ) AS aerodrome + properties: + minzoom: 10 + - id: runway + geometry: line + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + aeroway, + ref + FROM planet_osm_line + WHERE aeroway IN ('runway', 'taxiway') + ) AS aerodrome + properties: + minzoom: 10 + - id: ocean + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way + FROM water_polygons + ) AS ocean + properties: + minzoom: 10 + - id: coastline + geometry: line + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT way FROM planet_osm_line WHERE "natural" = 'coastline') AS coastlines + properties: + minzoom: 12 + - id: buildings + geometry: polygon + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + building + FROM planet_osm_polygon + WHERE building IS NOT NULL + ) AS landcover + properties: + cache-features: true + minzoom: 14 + - id: road-casing-low-zoom + geometry: line + Datasource: + <<: *osm2pgsql + table: &road_low_zoom_sql |- + (SELECT + way, + highway + FROM planet_osm_roads + WHERE "highway" IN ('primary', 'trunk') + AND (tags->"access" IS NULL OR tags->"access" NOT IN ('private', 'no')) + ORDER BY + CASE + WHEN highway = 'trunk' THEN 37 + WHEN highway = 'primary' THEN 36 + END ASC NULLS LAST + ) AS road + properties: + minzoom: 4 + maxzoom: 9 + - id: road-low-zoom + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_low_zoom_sql + properties: + minzoom: 4 + maxzoom: 9 + - id: road-casing-layer-n1 + geometry: line + Datasource: + <<: *osm2pgsql + table: &road_sql |- + (SELECT + way, + (CASE WHEN "highway" IN ('motorway', 'trunk', 'primary', 'secondary', 'tertiary') + THEN 'road_major' + ELSE CASE WHEN "highway" IN ('motorway_link', 'trunk_link', 'primary_link', 'secondary_link', 'tertiary_link', 'residential', 'unclassified', 'living_street') + THEN 'road_minor' + ELSE CASE WHEN "highway" IN ('path', 'footway', 'cycleway', 'track', 'steps', 'pedestrian', 'platform') + THEN 'road_path' + ELSE 'road_' || "highway" + END + END + END) AS feature, + name, + minority_name, + highway, + COALESCE(layer::integer, 0) AS layer + FROM planet_osm_line + WHERE "highway" IS NOT NULL + AND (tags->"access" IS NULL OR tags->"access" NOT IN ('private', 'no')) + ORDER BY + CASE + WHEN highway = 'motorway' THEN 38 + WHEN highway = 'trunk' THEN 37 + WHEN highway = 'primary' THEN 36 + WHEN highway = 'secondary' THEN 35 + WHEN highway = 'tertiary' THEN 34 + + WHEN highway = 'motorway_link' THEN 28 + WHEN highway = 'trunk_link' THEN 27 + WHEN highway = 'primary_link' THEN 26 + WHEN highway = 'secondary_link' THEN 25 + WHEN highway = 'tertiary_link' THEN 24 + + WHEN highway = 'residential' THEN 10 + WHEN highway = 'unclassified' THEN 10 + WHEN highway = 'path' THEN 8 + WHEN highway = 'footway' THEN 8 + WHEN highway = 'cycleway' THEN 8 + WHEN highway = 'service' THEN 5 + + WHEN highway = 'runway' THEN 6 + WHEN highway = 'taxiway' THEN 5 + END ASC NULLS LAST + ) AS road + properties: + minzoom: 10 + - id: road-layer-n1 + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 10 + - id: rail-layer-n1 + geometry: linestring + Datasource: + <<: *osm2pgsql + table: &rail_sql |- + (SELECT + way, + name, + minority_name, + service, + COALESCE(layer::integer, 0) AS layer, + tags->'electrified' AS electrified, + tags->'usage' AS usage + FROM planet_osm_line + WHERE "railway" = 'rail' + ORDER BY + CASE + WHEN service IS NULL THEN 20 + WHEN service IS NOT NULL THEN 30 + END DESC NULLS LAST + ) AS rail + - id: road-casing + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 12 + - id: road + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 12 + - id: rail + geometry: linestring + Datasource: + <<: *osm2pgsql + table: *rail_sql + - id: bridge-area + geometry: polygon + Datasource: + <<: *osm2pgsql + table: &bridge_area_sql |- + (SELECT + way, + name, + bilingual_name, + '0' AS natural + FROM planet_osm_polygon + WHERE "man_made" = 'bridge' + ) AS bridge_area + properties: + minzoom: 12 + - id: road-casing-layer-1 + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 12 + - id: road-layer-1 + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 12 + - id: rail-layer-1 + geometry: linestring + Datasource: + <<: *osm2pgsql + table: *rail_sql + - id: place-major + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + place + FROM planet_osm_point + WHERE "place" IN ('city', 'town') + ) AS place_major + properties: + minzoom: 6 + maxzoom: 15 + - id: train-stations + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + railway, + tags->'railway:ref' AS ref + FROM planet_osm_point + WHERE "railway" IN ('station', 'halt') + ) AS train_stations + - id: place-medium + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + place + FROM planet_osm_point + WHERE "place" IN ('suburb', 'borough', 'village') + ) AS place_medium + properties: + minzoom: 12 + maxzoom: 17 + - id: stations + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + COALESCE( + 'amenity_' || CASE WHEN amenity IN ('bus_station') THEN amenity END + ) AS feature + FROM + ( + SELECT + ST_PointOnSurface(way) AS way, + name, + bilingual_name, + amenity + FROM planet_osm_polygon + WHERE way && !bbox! + AND way_area < 768000*POW(!scale_denominator!*0.001*0.28,2) + UNION ALL + SELECT + way, + bilingual_name, + name, + amenity + FROM planet_osm_point + WHERE way && !bbox! + ) AS station_subquery + WHERE ( + "amenity" IN ('bus_station') + ) + ) AS stations + properties: + minzoom: 13 + - id: place-natural + geometry: polygon + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + place, + way_area/NULLIF(POW(!scale_denominator!*0.001*0.28,2),0) AS way_pixels, + way_area + FROM planet_osm_polygon + WHERE ( + "place" IN ('island', 'peninsula', 'isthmus', 'islet') + OR "natural" IN ('peak', 'hill', 'fell') + ) + ) AS place_natural + properties: + minzoom: 8 + - id: place-minor + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + (CASE WHEN ("place" = 'locality' OR "natural" IN ('peak', 'hill', 'fell')) THEN 1 ELSE 0 END) AS natural + FROM planet_osm_point + WHERE ( + "place" IN ('neighbourhood', 'quarter', 'farm', 'hamlet', 'locality') + OR "natural" IN ('peak', 'hill', 'fell') + ) + ) AS place_medium + properties: + minzoom: 15 + - id: train-sites + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + railway, + tags->'railway:ref' AS ref + FROM planet_osm_point + WHERE "railway" IN ('site', 'yard', 'crossover', 'junction', 'technical_station', 'service_station') + ) AS train_stations + - id: poi-name + geometry: polygon + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + 0 as natural + FROM + ( + SELECT + ST_PointOnSurface(way) AS way, + name, + bilingual_name, + man_made, + building, + leisure, + amenity, + historic + FROM planet_osm_polygon + WHERE way && !bbox! + AND way_area < 768000*POW(!scale_denominator!*0.001*0.28,2) + UNION ALL + SELECT + way, + name, + bilingual_name, + building, + man_made, + leisure, + amenity, + historic + FROM planet_osm_point + WHERE way && !bbox! + ) AS poi_name_subquery + WHERE ( + "man_made" IN ('bridge') + OR "amenity" IN ('hospital', 'university', 'exhibition_centre') + OR "leisure" IN ('stadium') + OR "historic" IN ('castle') + ) + ) AS poi_name + properties: + minzoom: 15 + - id: poi-name-medium + geometry: polygon + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + shop, + 0 as natural + FROM + ( + SELECT + ST_PointOnSurface(way) AS way, + name, + bilingual_name, + amenity, + shop + FROM planet_osm_polygon + WHERE way && !bbox! + AND way_area < 768000*POW(!scale_denominator!*0.001*0.28,2) + UNION ALL + SELECT + way, + name, + bilingual_name, + shop, + amenity + FROM planet_osm_point + WHERE way && !bbox! + ) AS poi_name_subquery + WHERE ( + "amenity" IN ('school', 'marketplace', 'fire_station') + OR "shop" = 'mall' + ) + ) AS poi_name_medium + properties: + minzoom: 16 + - id: aerodrome-name + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + aeroway, + name, + bilingual_name, + ref + FROM + ( + SELECT + ST_PointOnSurface(way) AS way, + aeroway, + name, + bilingual_name, + COALESCE(tags->'iata', tags->'icao', ref) as ref + FROM planet_osm_polygon + WHERE way && !bbox! + AND way_area < 768000*POW(!scale_denominator!*0.001*0.28,2) + UNION ALL + SELECT + way, + aeroway, + name, + bilingual_name, + COALESCE(tags->'iata', tags->'icao', ref) as ref + FROM planet_osm_point + WHERE way && !bbox! + ) AS station_subquery + WHERE "aeroway" = 'aerodrome' + ) AS stations + properties: + minzoom: 9 + + - id: poi-name-minor + geometry: polygon + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + name, + bilingual_name, + 0 as natural + FROM + ( + SELECT + ST_PointOnSurface(way) AS way, + name, + bilingual_name, + highway, + area, + amenity + FROM planet_osm_polygon + WHERE way && !bbox! + AND way_area < 768000*POW(!scale_denominator!*0.001*0.28,2) + UNION ALL + SELECT + way, + name, + bilingual_name, + highway, + NULL as area, + amenity + FROM planet_osm_point + WHERE way && !bbox! + ) AS poi_name_subquery + WHERE ( + "amenity" IN ('kindergarten', 'social_facility') + OR ("highway" IN ('footway', 'pedestrian') AND area = 'yes') + ) + ) AS poi_name_medium + properties: + minzoom: 17 + - id: train-milestones + geometry: point + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + tags->'railway:position' AS position, + railway + FROM planet_osm_point + WHERE "railway" = 'milestone' + ) AS train_milestones + - id: road-text + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 14 + - id: road-text-minority + geometry: line + Datasource: + <<: *osm2pgsql + table: *road_sql + properties: + minzoom: 14 + - id: roads-text-ref + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: &road-ref-sql |- + (SELECT + way, + highway, + refs, + ref_1, + ref_2, + ref_3, + ref_4, + ref_5, + ref_6, + ref_class_1, + ref_class_2, + ref_class_3, + ref_class_4, + ref_class_5, + ref_class_6, + ref_length_1, + ref_length_2, + ref_length_3, + ref_length_4, + ref_length_5, + ref_length_6 + FROM ( + SELECT + osm_id, + way, + highway, + array_to_string(refs, E'\n') AS refs, + refs[1] as ref_1, + refs[2] as ref_2, + refs[3] as ref_3, + refs[4] as ref_4, + refs[5] as ref_5, + refs[6] as ref_6, + ref_classes[1] as ref_class_1, + ref_classes[2] as ref_class_2, + ref_classes[3] as ref_class_3, + ref_classes[4] as ref_class_4, + ref_classes[5] as ref_class_5, + ref_classes[6] as ref_class_6, + ref_widths[1] as ref_length_1, + ref_widths[2] as ref_length_2, + ref_widths[3] as ref_length_3, + ref_widths[4] as ref_length_4, + ref_widths[5] as ref_length_5, + ref_widths[6] as ref_length_6 + FROM ( + SELECT + osm_id, + way, + highway, + string_to_array(ref, ';') AS refs, + string_to_array(ref_class, ';') AS ref_classes, + string_to_array(ref_width, ';') AS ref_widths + FROM planet_osm_line + WHERE (highway IN ('motorway', 'trunk', 'primary', 'secondary', 'tertiary')) + AND ref IS NOT NULL + ) AS p) AS q + ORDER BY + CASE + WHEN highway = 'motorway' THEN 38 + WHEN highway = 'trunk' THEN 37 + WHEN highway = 'primary' THEN 36 + WHEN highway = 'secondary' THEN 35 + WHEN highway = 'tertiary' THEN 34 + WHEN highway = 'taxiway' THEN 5 + END DESC NULLS LAST, + refs, + osm_id + ) AS roads_text_ref + properties: + minzoom: 8 + - id: roads-text-ref2 + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: *road-ref-sql + properties: + minzoom: 10 + - id: roads-text-ref3 + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: *road-ref-sql + properties: + minzoom: 10 + - id: roads-text-ref4 + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: *road-ref-sql + properties: + minzoom: 10 + - id: roads-text-ref5 + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: *road-ref-sql + properties: + minzoom: 10 + - id: roads-text-ref6 + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: *road-ref-sql + properties: + minzoom: 10 + - id: railway-platform-ref + geometry: linestring + <<: *extents + Datasource: + <<: *osm2pgsql + table: |- + (SELECT + way, + COALESCE(tags->'local_ref', ref) AS ref + FROM planet_osm_line + WHERE "railway" = 'platform_edge' + ORDER BY ref + ) AS railway_platform_edge_ref + properties: + minzoom: 17
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/generate_shields.py Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# Generate highway shields as SVG files in symbols/shields. + +from __future__ import print_function +import copy, lxml.etree, math, os + + +def main(): + namespace = 'http://www.w3.org/2000/svg' + svgns = '{' + namespace + '}' + svgnsmap = {None: namespace} + + config = {} + config['base'] = {} + + # font_height and font_width are determined by trial and error + config['base']['rounded_corners'] = 2 + config['base']['font_height'] = 11 + config['base']['font_width'] = 0.85 + config['base']['padding_x'] = 8 + config['base']['padding_y'] = 2 + config['base']['stroke_width'] = 1 + + # Fall back colours used if no colours are defined in road-colours.yaml for a road type. + config['base']['fill'] = '#f1f1f1' + config['base']['stroke_fill'] = '#c6c6c6' + + config['global'] = {} + + config['global']['types'] = ['valtatie', 'kantatie', 'seututie', 'yhdystie', 'eurooppatie'] + config['global']['max_width'] = 48 + config['global']['output_dir'] = '../symbols/shields/' # specified relative to the script location + + config['valtatie'] = {'fill': '#ff163c', 'stroke_fill': 'white'} + config['kantatie'] = {'fill': '#ffd90f', 'stroke_fill': 'black', 'stroke_width': 0.5} + config['seututie'] = {'fill': 'white', 'stroke_fill': 'black', 'stroke_width': 0.5} + config['yhdystie'] = {'fill': '#005eb7', 'stroke_fill': 'white'} + config['eurooppatie'] = {'fill': '#00997c', 'stroke_fill': 'white'} + + if not os.path.exists(os.path.dirname(config['global']['output_dir'])): + os.makedirs(os.path.dirname(config['global']['output_dir'])) + + height = 1 + shield_size = 'base' + + dirpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir']) + try: + os.makedirs(dirpath) + except FileExistsError: + pass + + for width in range(1, config['global']['max_width'] + 1): + for shield_type in config['global']['types']: + + # merge base config and specific styles + vars = copy.deepcopy(config['base']) + if shield_type in config: + for option in config[shield_type]: + vars[option] = config[shield_type][option] + + shield_width = 2 * vars['padding_x'] + math.ceil(vars['font_width'] * width) + shield_height = 2 * vars['padding_y'] + math.ceil(vars['font_height'] * height) + + svg = lxml.etree.Element('svg', nsmap=svgnsmap) + svg.set('width', '100%') + svg.set('height', '100%') + svg.set('viewBox', '0 0 ' + str(shield_width + vars['stroke_width']) + ' ' + str(shield_height + vars['stroke_width'])) + + if vars['stroke_width'] > 0: + offset_x = vars['stroke_width'] / 2.0 + offset_y = vars['stroke_width'] / 2.0 + else: + offset_x = 0 + offset_y = 0 + + background = lxml.etree.Element(svgns + 'rect') + background.set('x', str(offset_x)) + background.set('y', str(offset_y)) + background.set('width', str(shield_width)) + background.set('height', str(shield_height)) + background.set('id', 'shield-background') + background.set('style', 'fill:' + vars['fill']) + svg.append(background) + + shield = lxml.etree.Element(svgns + 'rect') + shield.set('x', str(offset_x + 0.5)) + shield.set('y', str(offset_y + 0.5)) + shield.set('width', str(shield_width - 1)) + shield.set('height', str(shield_height - 1)) + if vars['rounded_corners'] > 0: + shield.set('rx', str(vars['rounded_corners'])) + shield.set('ry', str(vars['rounded_corners'])) + shield.set('id', 'shield') + + stroke = '' + if vars['stroke_width'] > 0: + stroke = 'stroke:' + vars['stroke_fill'] + ';stroke-width:' + str(vars['stroke_width']) + ';' + + shield.set('style', 'fill:' + vars['fill'] + ';' + stroke) + + svg.append(shield) + + filename = shield_type + '_' + str(width) + 'x' + str(height) + if shield_size != 'base': + filename = filename + '_' + shield_size + + filename = filename + '.svg' + + # save file + try: + shieldpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir'] + filename) + print('Writing', os.path.realpath(shieldpath)) + shieldfile = open(shieldpath, 'wb') + shieldfile.write(lxml.etree.tostring(svg, encoding='utf-8', xml_declaration=True, pretty_print=True)) + shieldfile.close() + except IOError: + print('Could not save file ' + filename + '.') + continue + +if __name__ == "__main__": + main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/get-external-data.py Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,258 @@ +#!/usr/bin/env python3 +'''This script is designed to load quasi-static data into a PostGIS database +for rendering maps. It differs from the usual scripts to do this in that it is +designed to take its configuration from a file rather than be a series of shell +commands. + +Some implicit assumptions are +- Time spent querying (rendering) the data is more valuable than the one-time + cost of loading it +- The script will not be running multiple times in parallel. This is not + normally likely because the script is likely to be called daily or less, + not minutely. +- Usage patterns will be similar to typical map rendering +''' + +import yaml +import os +import re +import argparse +import shutil + +# modules for getting data +import zipfile +import requests +import io + +# modules for converting and postgres loading +import subprocess +import psycopg2 + +import logging + + +def database_setup(conn, temp_schema, schema, metadata_table): + with conn.cursor() as cur: + cur.execute('''CREATE SCHEMA IF NOT EXISTS {temp_schema};''' + .format(temp_schema=temp_schema)) + cur.execute(('''CREATE TABLE IF NOT EXISTS "{schema}"."{metadata_table}"''' + ''' (name text primary key, last_modified text);''') + .format(schema=schema, metadata_table=metadata_table)) + conn.commit() + + +class Table: + def __init__(self, name, conn, temp_schema, schema, metadata_table): + self._name = name + self._conn = conn + self._temp_schema = temp_schema + self._dst_schema = schema + self._metadata_table = metadata_table + + # Clean up the temporary schema in preperation for loading + def clean_temp(self): + with self._conn.cursor() as cur: + cur.execute('''DROP TABLE IF EXISTS "{temp_schema}"."{name}"''' + .format(name=self._name, temp_schema=self._temp_schema)) + self._conn.commit() + + # get the last modified date from the metadata table + def last_modified(self): + with self._conn.cursor() as cur: + cur.execute('''SELECT last_modified FROM "{schema}"."{metadata_table}" WHERE name = %s''' + .format(schema=self._dst_schema, metadata_table=self._metadata_table), [self._name]) + results = cur.fetchone() + if results is not None: + return results[0] + + def index(self): + with self._conn.cursor() as cur: + # Disable autovacuum while manipulating the table, since it'll get clustered towards the end. + cur.execute('''ALTER TABLE "{temp_schema}"."{name}" SET ( autovacuum_enabled = FALSE );''' + .format(name=self._name, temp_schema=self._temp_schema)) + # ogr creates a ogc_fid column we don't need + cur.execute('''ALTER TABLE "{temp_schema}"."{name}" DROP COLUMN ogc_fid;''' + .format(name=self._name, temp_schema=self._temp_schema)) + + # Null geometries are useless for rendering + cur.execute('''DELETE FROM "{temp_schema}"."{name}" WHERE way IS NULL;''' + .format(name=self._name, temp_schema=self._temp_schema)) + cur.execute('''ALTER TABLE "{temp_schema}"."{name}" ALTER COLUMN way SET NOT NULL;''' + .format(name=self._name, temp_schema=self._temp_schema)) + # sorting static tables helps performance and reduces size from the column drop above + cur.execute(('''CREATE INDEX "{name}_order" ON "{temp_schema}"."{name}" ''' + '''(ST_Envelope(way));''' + '''CLUSTER "{temp_schema}"."{name}" ''' + '''USING "{name}_order";''' + '''DROP INDEX "{temp_schema}"."{name}_order";''' + '''CREATE INDEX ON "{temp_schema}"."{name}" ''' + '''USING GIST (way) WITH (fillfactor=100);''') + .format(name=self._name, temp_schema=self._temp_schema)) + # Reset autovacuum. The table is static, so this doesn't really + # matter since it'll never need a vacuum. + cur.execute('''ALTER TABLE "{temp_schema}"."{name}" RESET ( autovacuum_enabled );''' + .format(name=self._name, temp_schema=self._temp_schema)) + self._conn.commit() + + # VACUUM can't be run in transaction, so autocommit needs to be turned on + old_autocommit = self._conn.autocommit + try: + self._conn.autocommit = True + with self._conn.cursor() as cur: + cur.execute('''VACUUM ANALYZE "{temp_schema}"."{name}";''' + .format(name=self._name, temp_schema=self._temp_schema)) + finally: + self._conn.autocommit = old_autocommit + + def replace(self, new_last_modified): + with self._conn.cursor() as cur: + cur.execute('''BEGIN;''') + cur.execute(('''DROP TABLE IF EXISTS "{schema}"."{name}";''' + '''ALTER TABLE "{temp_schema}"."{name}" SET SCHEMA "{schema}";''') + .format(name=self._name, temp_schema=self._temp_schema, schema=self._dst_schema)) + + # We checked if the metadata table had this table way up above + cur.execute('''SELECT 1 FROM "{schema}"."{metadata_table}" WHERE name = %s''' + .format(schema=self._dst_schema, metadata_table=self._metadata_table), + [self._name]) + if cur.rowcount == 0: + cur.execute(('''INSERT INTO "{schema}"."{metadata_table}" ''' + '''(name, last_modified) VALUES (%s, %s)''') + .format(schema=self._dst_schema, metadata_table=self._metadata_table), + [self._name, new_last_modified]) + else: + cur.execute('''UPDATE "{schema}"."{metadata_table}" SET last_modified = %s WHERE name = %s''' + .format(schema=self._dst_schema, metadata_table=self._metadata_table), + [new_last_modified, self._name]) + self._conn.commit() + + +def main(): + # parse options + parser = argparse.ArgumentParser(description="Load external data into a database") + + parser.add_argument("-f", "--force", action="store_true", help="Download new data, even if not required") + + parser.add_argument("-c", "--config", action="store", default="external-data.yml", + help="Name of configuration file (default external-data.yml)") + parser.add_argument("-D", "--data", action="store", help="Override data download directory") + + parser.add_argument("-d", "--database", action="store", help="Override database name to connect to") + parser.add_argument("-H", "--host", action="store", + help="Override database server host or socket directory") + parser.add_argument("-p", "--port", action="store", help="Override database server port") + parser.add_argument("-U", "--username", action="store", help="Override database user name") + parser.add_argument("-v", "--verbose", action="store_true", help="Be more verbose. Overrides -q") + parser.add_argument("-q", "--quiet", action="store_true", help="Only report serious problems") + + opts = parser.parse_args() + + if opts.verbose: + logging.basicConfig(level=logging.DEBUG) + elif opts.quiet: + logging.basicConfig(level=logging.WARNING) + else: + logging.basicConfig(level=logging.INFO) + + with open(opts.config) as config_file: + config = yaml.safe_load(config_file) + data_dir = opts.data or config["settings"]["data_dir"] + os.makedirs(data_dir, exist_ok=True) + + # If the DB options are unspecified in both on the command line and in the + # config file, libpq will pick what to use with the None + database = opts.database or config["settings"].get("database") + host = opts.host or config["settings"].get("host") + port = opts.port or config["settings"].get("port") + user = opts.username or config["settings"].get("username") + with requests.Session() as s, \ + psycopg2.connect(database=database, + host=host, port=port, + user=user) as conn: + + s.headers.update({'User-Agent': 'get-external-data.py/osm-carto'}) + + # DB setup + database_setup(conn, config["settings"]["temp_schema"], + config["settings"]["schema"], + config["settings"]["metadata_table"]) + + for name, source in config["sources"].items(): + logging.info("Checking table {}".format(name)) + # Don't attempt to handle strange names + # Even if there was code to escape them properly here, you don't want + # in a style with all the quoting headaches + if not re.match('''^[a-zA-Z0-9_]+$''', name): + raise RuntimeError("Only ASCII alphanumeric table are names supported") + + workingdir = os.path.join(data_dir, name) + # Clean up anything left over from an aborted run + shutil.rmtree(workingdir, ignore_errors=True) + + os.makedirs(workingdir, exist_ok=True) + + this_table = Table(name, conn, + config["settings"]["temp_schema"], + config["settings"]["schema"], + config["settings"]["metadata_table"]) + this_table.clean_temp() + + if not opts.force: + headers = {'If-Modified-Since': this_table.last_modified()} + else: + headers = {} + + download = s.get(source["url"], headers=headers) + download.raise_for_status() + + if (download.status_code == 200): + if "Last-Modified" in download.headers: + new_last_modified = download.headers["Last-Modified"] + else: + new_last_modified = None + if "archive" in source and source["archive"]["format"] == "zip": + zip = zipfile.ZipFile(io.BytesIO(download.content)) + for member in source["archive"]["files"]: + zip.extract(member, workingdir) + + ogrpg = "PG:dbname={}".format(database) + + if port is not None: + ogrpg = ogrpg + " port={}".format(port) + if user is not None: + ogrpg = ogrpg + " user={}".format(user) + if host is not None: + ogrpg = ogrpg + " host={}".format(host) + + ogrcommand = ["ogr2ogr", + '-f', 'PostgreSQL', + '-lco', 'GEOMETRY_NAME=way', + '-lco', 'SPATIAL_INDEX=FALSE', + '-lco', 'EXTRACT_SCHEMA_FROM_LAYER_NAME=YES', + '-nln', "{}.{}".format(config["settings"]["temp_schema"], name)] + + if "ogropts" in source: + ogrcommand += source["ogropts"] + + ogrcommand += [ogrpg, os.path.join(workingdir, source["file"])] + + logging.debug("running {}".format(subprocess.list2cmdline(ogrcommand))) + + # ogr2ogr can raise errors here, so they need to be caught + try: + subprocess.check_output(ogrcommand, stderr=subprocess.PIPE, universal_newlines=True) + except subprocess.CalledProcessError as e: + # Add more detail on stdout for the logs + logging.critical("ogr2ogr returned {} with layer {}".format(e.returncode, name)) + logging.critical("Command line was {}".format(subprocess.list2cmdline(e.cmd))) + logging.critical("Output was\n{}".format(e.output)) + raise RuntimeError("ogr2ogr error when loading table {}".format(name)) + + this_table.index() + this_table.replace(new_last_modified) + else: + logging.info("Table {} did not require updating".format(name)) + + +if __name__ == '__main__': + main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/amenity.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,138 @@ +@standard-font-size: 10; +@standard-wrap-width: 30; // 3 em +@standard-line-spacing-size: -1.5; // -0.15 em +@standard-font: @regular-font; +@traffic-blue: #005eb8; +@railway-name-color: #644d70; +@aerodrome-name-color: #463d70; + +#stations[zoom >= 15] +{ + [feature = 'railway_station'], + [feature = 'railway_halt'] + { + marker-file: url('symbols/train-station.svg'); + } + [feature = 'amenity_bus_station'] + { + marker-file: url('symbols/bus-station.svg'); + } + [feature = 'aeroway_aerodrome'] + { + marker-file: url('symbols/aerodrome.svg'); + } + marker-clip: false; + text-name: "[bilingual_name]"; + text-size: @standard-font-size; + text-wrap-width: @standard-wrap-width; + text-line-spacing: @standard-line-spacing-size; + text-fill: @traffic-blue; + text-dy: 11; + text-face-name: @bold-font; + text-halo-radius: @standard-halo-radius; + text-halo-fill: @standard-halo-fill; +} + +#train-stations +{ + [zoom >= 12] + { + text-name: "[ref]"; + [zoom >= 14] + { + text-name: "[bilingual_name]"; + } + text-size: 10; + text-wrap-width: @standard-wrap-width; + text-line-spacing: @standard-line-spacing-size; + text-fill: white; + text-clip: true; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; + [zoom >= 16] { text-size: 11; } + [zoom >= 17] { text-size: 12; } + [zoom >= 18] { text-size: 13; } + text-face-name: "FreeSans Bold"; + text-halo-radius: 1.5 * @standard-halo-radius; + text-halo-fill: blue; + /* + [zoom >= 16] + { + text-transform: uppercase; + } + */ + } +} + +#train-sites +{ + [zoom >= 15] + { + text-name: "[ref]"; + [zoom >= 16] + { + text-name: "[bilingual_name]"; + } + text-size: @standard-font-size; + text-wrap-width: @standard-wrap-width; + text-line-spacing: @standard-line-spacing-size; + text-fill: @railway-name-color; + text-clip: false; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; + [zoom >= 16] { text-size: 11; } + [zoom >= 17] { text-size: 12; } + [zoom >= 18] { text-size: 13; } + text-face-name: "FreeSans Bold"; + text-halo-radius: 0.75 * @standard-halo-radius; + text-halo-fill: @standard-halo-fill; + } +} + +#train-milestones +{ + [zoom >= 16] + { + text-name: "[position]"; + text-size: @standard-font-size; + text-wrap-width: @standard-wrap-width; + text-line-spacing: @standard-line-spacing-size; + text-fill: @railway-name-color; + text-clip: false; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; + [zoom >= 17] { text-size: 11; } + [zoom >= 18] { text-size: 12; } + [zoom >= 19] { text-size: 13; } + text-face-name: "FreeSans Bold"; + text-halo-radius: @standard-halo-radius; + text-halo-fill: @standard-halo-fill; + } +} + +@aerodrome-color: #dedced; +#aerodrome +{ + polygon-fill: @aerodrome-color; + [zoom >= 17] + { + line-color: saturate(darken(@aerodrome-color, 20%), 20%); + } +} + +#aerodrome-name +{ + text-name: "[ref]"; + [zoom >= 12] + { + text-name: "[bilingual_name]"; + } + text-size: @standard-font-size; + text-wrap-width: @standard-wrap-width; + text-line-spacing: @standard-line-spacing-size; + text-clip: false; + text-fill: @aerodrome-name-color; + text-face-name: @bold-font; + text-halo-radius: @standard-halo-radius; + text-halo-fill: @standard-halo-fill; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/buildings.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,11 @@ +@building-color: #bbbab4; + +#buildings +{ + polygon-fill: @building-color; + line-width: 0.5; + line-color: darken(@building-color, 20%); + [building = 'construction'] { + line-dasharray: 4,4; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/places.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,112 @@ +@place-halo-fill: rgba(255,255,255,60%); +@place-halo-radius: 1.5; + +@landcover-font-size: 10; +@landcover-wrap-width-size: 30; // 3 em +@landcover-line-spacing-size: -1.5; // -0.15 em +@landcover-font-size-big: 12; +@landcover-wrap-width-size-big: 36; // 3 em +@landcover-line-spacing-size-big: -1.8; // -0.15 em +@landcover-font-size-bigger: 15; +@landcover-wrap-width-size-bigger: 45; // 3 em +@landcover-line-spacing-size-bigger: -2.25; // -0.15 em +@landcover-face-name: @oblique-fonts; + +#place-major[zoom >= 10], +#place-major[place='city'] { + text-name: "[bilingual_name]"; + text-size: 10; + [zoom >= 11] { text-size: 11; } + [zoom >= 12] { text-size: 12; } + [zoom >= 13] { text-size: 13; } + [zoom >= 14] { text-size: 14; } + [zoom >= 15] { text-size: 15; } + text-fill: #000; + text-face-name: @place-font; + [place='city'][zoom >= 10], + [zoom >= 12] { + text-face-name: @place-font-bold; + } + [place='city'][zoom >= 12], + [zoom >= 13] { + text-transform: uppercase; + } + text-halo-radius: @place-halo-radius; + text-halo-fill: @place-halo-fill; + text-clip: false; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; +} + +#place-medium { + text-name: "[bilingual_name]"; + text-size: 10; + [zoom >= 13] { text-size: 11; } + [zoom >= 14] { text-size: 12; } + [zoom >= 15] { text-size: 14; } + [zoom >= 16] { text-size: 15; } + [zoom >= 17] { text-size: 17; } + text-fill: #000; + text-face-name: @place-font; + [zoom >= 13] { + text-face-name: @place-font-bold; + } + text-halo-radius: @place-halo-radius; + text-halo-fill: @place-halo-fill; + text-clip: false; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; +} + +#poi-name, +#poi-name-medium, +#poi-name-minor, +#place-minor +{ + text-name: "[bilingual_name]"; + text-size: 10; + [zoom >= 15] { text-size: 11; } + [zoom >= 16] { text-size: 12; } + [zoom >= 17] { text-size: 13; } + [zoom >= 18] { text-size: 14; } + text-fill: #000; + text-face-name: @place-font; + #place-minor[natural = 0][zoom >= 17] { + text-face-name: @place-font-bold; + } + [natural = 1] { + text-face-name: @natural-font; + } + text-halo-radius: @place-halo-radius; + text-halo-fill: @place-halo-fill; + text-clip: false; + text-placement-type: simple; + text-placements: E,NE,SE,W,NW,SW; +} + +#place-natural +{ + [zoom >= 4][way_pixels > 3000], + [zoom >= 16], + [zoom >= 11][way_pixels > 3000], + [zoom >= 17] { + text-name: "[bilingual_name]"; + text-fill: #000; + text-size: 10; + text-wrap-width: @landcover-wrap-width-size; + text-line-spacing: @landcover-line-spacing-size; + [way_pixels > 12000] { + text-size: @landcover-font-size-big; + text-wrap-width: @landcover-wrap-width-size-big; + text-line-spacing: @landcover-line-spacing-size-big; + } + [way_pixels > 48000] { + text-size: @landcover-font-size-bigger; + text-wrap-width: @landcover-wrap-width-size-bigger; + text-line-spacing: @landcover-line-spacing-size-bigger; + } + text-face-name: @natural-font; + text-halo-radius: @place-halo-radius; + text-halo-fill: @place-halo-fill; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/roadref.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,232 @@ +// Shield’s line wrap is based on OpenStreetMap data and not on line-wrap-width, +// but lines are typically rather short, so we use narrow line spacing. +@shield-size: 10; +@shield-line-spacing: -2; // -1.50; // -0.15 em +@shield-size-z16: 11; +@shield-line-spacing-z16: -2.25; // -1.65; // -0.15 em +@shield-size-z18: 12; +@shield-line-spacing-z18: -2.5; // -1.80; // -0.15 em +@shield-spacing: 760; +@shield-repeat-distance: 400; +@shield-margin: 40; +@shield-font: "Liikenne Regular"; +@shield-clip: false; + +#roads-text-ref +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_1 = 'valtatie'][zoom >= 8], + [ref_class_1 = 'eurooppatie'][zoom >= 12], + [ref_class_1 = 'kantatie'][zoom >= 10], + [ref_class_1 = 'seututie'][zoom >= 12] + { + [ref_1 != null][ref_class_1 != null][ref_class_1 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_1]_[ref_length_1]x1.svg"); + [ref_class_1 = 'valtatie'], + [ref_class_1 = 'yhdystie'], + [ref_class_1 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_1 = 'kantatie'], + [ref_class_1 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_1]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +} + +#roads-text-ref2 +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_2 = 'valtatie'][zoom >= 12], + [ref_class_2 = 'eurooppatie'][zoom >= 12], + [ref_class_2 = 'kantatie'][zoom >= 12], + [ref_class_2 = 'seututie'][zoom >= 12] + { + [ref_2 != null][ref_class_2 != null][ref_class_2 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_2]_[ref_length_2]x1.svg"); + [ref_class_2 = 'valtatie'], + [ref_class_2 = 'yhdystie'], + [ref_class_2 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_2 = 'kantatie'], + [ref_class_2 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_2]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +} + +#roads-text-ref3 +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_3 = 'valtatie'][zoom >= 12], + [ref_class_3 = 'eurooppatie'][zoom >= 12], + [ref_class_3 = 'kantatie'][zoom >= 12], + [ref_class_3 = 'seututie'][zoom >= 12] + { + [ref_3 != null][ref_class_3 != null][ref_class_3 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_3]_[ref_length_3]x1.svg"); + [ref_class_3 = 'valtatie'], + [ref_class_3 = 'yhdystie'], + [ref_class_3 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_3 = 'kantatie'], + [ref_class_3 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_3]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +} +#roads-text-ref4 +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_4 = 'valtatie'][zoom >= 10], + [ref_class_4 = 'eurooppatie'][zoom >= 11], + [ref_class_4 = 'kantatie'][zoom >= 11], + [ref_class_4 = 'seututie'][zoom >= 12] + { + [ref_4 != null][ref_class_4 != null][ref_class_4 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_4]_[ref_length_4]x1.svg"); + [ref_class_4 = 'valtatie'], + [ref_class_4 = 'yhdystie'], + [ref_class_4 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_4 = 'kantatie'], + [ref_class_4 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_4]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +} +#roads-text-ref5 +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_5 = 'valtatie'][zoom >= 12], + [ref_class_5 = 'eurooppatie'][zoom >= 12], + [ref_class_5 = 'kantatie'][zoom >= 12], + [ref_class_5 = 'seututie'][zoom >= 12] + { + [ref_5 != null][ref_class_5 != null][ref_class_5 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_5]_[ref_length_5]x1.svg"); + [ref_class_5 = 'valtatie'], + [ref_class_5 = 'yhdystie'], + [ref_class_5 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_5 = 'kantatie'], + [ref_class_5 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_5]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +} +#roads-text-ref6 +{ + [highway = 'trunk'][zoom >= 13], + [highway = 'primary'][zoom >= 13], + [highway = 'secondary'][zoom >= 13], + [highway = 'tertiary'][zoom >= 13], + [ref_class_6 = 'valtatie'][zoom >= 10], + [ref_class_6 = 'eurooppatie'][zoom >= 12], + [ref_class_6 = 'kantatie'][zoom >= 12], + [ref_class_6 = 'seututie'][zoom >= 12] + { + [ref_6 != null][ref_class_6 != null][ref_class_6 != 'unknown'] + { + shield-face-name: @shield-font; + shield-file: url("symbols/shields/[ref_class_6]_[ref_length_6]x1.svg"); + [ref_class_6 = 'valtatie'], + [ref_class_6 = 'yhdystie'], + [ref_class_6 = 'eurooppatie'] + { + shield-fill: white; + } + [ref_class_6 = 'kantatie'], + [ref_class_6 = 'seututie'] + { + shield-fill: black; + } + shield-name: "[ref_6]"; + shield-size: 12; + shield-placement: line; + shield-spacing: @shield-spacing; + shield-repeat-distance: @shield-repeat-distance; + shield-margin: @shield-margin; + shield-clip: @shield-clip; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/roads.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,603 @@ +@highway-trunk-width-z4: 1; +@highway-trunk-width-z5: 1; +@highway-trunk-width-z6: 1.5; +@highway-trunk-width-z7: 1.5; +@highway-trunk-width-z8: 1.5; +@highway-trunk-width-z9: 2; +@highway-trunk-width-z10: 2; +@highway-trunk-width-z11: 2; +@highway-trunk-width-z12: 3; +@highway-trunk-width-z13: 4; +@highway-trunk-width-z14: 5; +@highway-trunk-width-z15: 7; +@highway-trunk-width-z16: 10; +@highway-trunk-width-z17: 14; +@highway-trunk-width-z18: 22; +@highway-trunk-casing-width: @road-major-casing-width; + +@highway-primary-width-z10: 1.5; +@highway-primary-width-z11: 1.5; +@highway-primary-width-z12: 2; +@highway-primary-width-z13: 4; +@highway-primary-width-z14: 5; +@highway-primary-width-z15: 6; +@highway-primary-width-z16: 9; +@highway-primary-width-z17: 14; +@highway-primary-width-z18: 22; +@highway-primary-casing-width: @road-major-casing-width; + +@highway-secondary-width-z10: 1; +@highway-secondary-width-z11: 1; +@highway-secondary-width-z12: 1.5; +@highway-secondary-width-z13: 2; +@highway-secondary-width-z14: 4; +@highway-secondary-width-z15: 5; +@highway-secondary-width-z16: 6; +@highway-secondary-width-z17: 14; +@highway-secondary-width-z18: 22; +@highway-secondary-casing-width: @road-major-casing-width; + +@highway-tertiary-width-z10: 0; +@highway-tertiary-width-z11: 1; +@highway-tertiary-width-z12: 1; +@highway-tertiary-width-z13: 1.5; +@highway-tertiary-width-z14: 2; +@highway-tertiary-width-z15: 3; +@highway-tertiary-width-z16: 6; +@highway-tertiary-width-z17: 14; +@highway-tertiary-width-z18: 22; +@highway-tertiary-casing-width: @road-major-casing-width; + +@highway-unclassified-width-z10: 0; +@highway-unclassified-width-z11: 0; +@highway-unclassified-width-z12: 0.5; +@highway-unclassified-width-z13: 1; +@highway-unclassified-width-z14: 1.5; +@highway-unclassified-width-z15: 2; +@highway-unclassified-width-z16: 4; +@highway-unclassified-width-z17: 8; +@highway-unclassified-width-z18: 12; +@highway-unclassified-casing-width: @road-minor-casing-width; + +@highway-service-width-z15: 0.5; +@highway-service-width-z16: 1; +@highway-service-width-z17: 1.5; +@highway-service-width-z18: 3; +@highway-service-width-z19: 4; +@highway-service-width-z20: 5; +@highway-service-casing-width: @road-minor-casing-width; + +@highway-trunk-link-width-z10: 1; +@highway-trunk-link-width-z11: 1; +@highway-trunk-link-width-z12: 1.5; +@highway-trunk-link-width-z13: 2; +@highway-trunk-link-width-z14: 3; +@highway-trunk-link-width-z15: 3; +@highway-trunk-link-width-z16: 6; +@highway-trunk-link-width-z17: 14; +@highway-trunk-link-width-z18: 22; +@highway-trunk-link-casing-width: @road-major-casing-width; + +@highway-path-width-z14: 0.5; +@highway-path-width-z15: 0.75; +@highway-path-width-z16: 1; +@highway-path-width-z17: 2; +@highway-path-width-z18: 3; + +@road-minor-casing-width: 1.5; +@road-major-casing-width: 2; +@road-text-scale-factor: 1; + +@road-fill: #f4f4ff; +@road-casing: #bbb; +@pedestrian-fill: #ccc; +@living-street-fill: #ddd; + +#road-low-zoom +{ + [highway = 'trunk'] + { + [zoom >= 4] { line-width: @highway-trunk-width-z4; } + [zoom >= 5] { line-width: @highway-trunk-width-z5; } + [zoom >= 6] { line-width: @highway-trunk-width-z6; } + [zoom >= 7] { line-width: @highway-trunk-width-z7; } + [zoom >= 8] { line-width: @highway-trunk-width-z8; } + [zoom >= 9] { line-width: @highway-trunk-width-z9; } + line-color: #bbb; + [zoom >= 9] + { + line-color: @road-fill; + } + } +} + +#road-low-zoom-casing +{ + [highway = 'trunk'][zoom >= 9] + { + line-width: @highway-trunk-width-z9 + @highway-trunk-casing-width; + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } +} + +#road-layer-n1, +#road[layer = 0], +#road-layer-1[layer >= 1] +{ + [highway = 'trunk'] + { + line-width: @highway-trunk-width-z10; + [zoom >= 11] { line-width: @highway-trunk-width-z11; } + [zoom >= 12] { line-width: @highway-trunk-width-z12; } + [zoom >= 13] { line-width: @highway-trunk-width-z13; } + [zoom >= 14] { line-width: @highway-trunk-width-z14; } + [zoom >= 15] { line-width: @highway-trunk-width-z15; } + [zoom >= 16] { line-width: @highway-trunk-width-z16; } + [zoom >= 17] { line-width: @highway-trunk-width-z17; } + [zoom >= 18] { line-width: @highway-trunk-width-z18; } + line-color: @road-fill; + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'primary'] + { + line-width: @highway-primary-width-z10; + [zoom >= 11] { line-width: @highway-primary-width-z11; } + [zoom >= 12] { line-width: @highway-primary-width-z12; } + [zoom >= 13] { line-width: @highway-primary-width-z13; } + [zoom >= 14] { line-width: @highway-primary-width-z14; } + [zoom >= 15] { line-width: @highway-primary-width-z15; } + [zoom >= 16] { line-width: @highway-primary-width-z16; } + [zoom >= 17] { line-width: @highway-primary-width-z17; } + [zoom >= 18] { line-width: @highway-primary-width-z18; } + line-color: @road-fill; + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'secondary'] + { + line-width: @highway-secondary-width-z10; + [zoom >= 11] { line-width: @highway-secondary-width-z11; } + [zoom >= 12] { line-width: @highway-secondary-width-z12; } + [zoom >= 13] { line-width: @highway-secondary-width-z13; } + [zoom >= 14] { line-width: @highway-secondary-width-z14; } + [zoom >= 15] { line-width: @highway-secondary-width-z15; } + [zoom >= 16] { line-width: @highway-secondary-width-z16; } + [zoom >= 17] { line-width: @highway-secondary-width-z17; } + [zoom >= 18] { line-width: @highway-secondary-width-z18; } + line-color: #bbb; + [zoom >= 11] + { + line-color: @road-fill; + } + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'tertiary'][zoom >= 11], + [highway = 'tertiary_link'][zoom >= 11] + { + line-width: @highway-tertiary-width-z10; + [zoom >= 11] { line-width: @highway-tertiary-width-z11; } + [zoom >= 12] { line-width: @highway-tertiary-width-z12; } + [zoom >= 13] { line-width: @highway-tertiary-width-z13; } + [zoom >= 14] { line-width: @highway-tertiary-width-z14; } + [zoom >= 15] { line-width: @highway-tertiary-width-z15; } + [zoom >= 16] { line-width: @highway-tertiary-width-z16; } + [zoom >= 17] { line-width: @highway-tertiary-width-z17; } + [zoom >= 18] { line-width: @highway-tertiary-width-z18; } + line-color: #bbb; + [zoom >= 12] { line-color: #b2b2b2; } + [zoom >= 13] { line-color: @road-fill; } + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'unclassified'][zoom >= 12], + [highway = 'residential'][zoom >= 12], + [highway = 'living_street'][zoom >= 12], + [highway = 'pedestrian'][zoom >= 12] + { + line-width: @highway-unclassified-width-z10; + [zoom >= 11] { line-width: @highway-unclassified-width-z11; } + [zoom >= 12] { line-width: @highway-unclassified-width-z12; } + [zoom >= 13] { line-width: @highway-unclassified-width-z13; } + [zoom >= 14] { line-width: @highway-unclassified-width-z14; } + [zoom >= 15] { line-width: @highway-unclassified-width-z15; } + [zoom >= 16] { line-width: @highway-unclassified-width-z16; } + [zoom >= 17] { line-width: @highway-unclassified-width-z17; } + [zoom >= 18] { line-width: @highway-unclassified-width-z18; } + line-color: #bbb; + [zoom >= 14] { line-color: #b2b2b2; } + [zoom >= 15] { line-color: @road-fill; } + [zoom >= 15][highway = 'living_street'] { line-color: @living-street-fill; } + [zoom >= 15][highway = 'pedestrian'] { line-color: @pedestrian-fill; } + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'trunk_link'], + [highway = 'primary_link'] + { + line-width: @highway-trunk-link-width-z10; + [zoom >= 11] { line-width: @highway-trunk-link-width-z11; } + [zoom >= 12] { line-width: @highway-trunk-link-width-z12; } + [zoom >= 13] { line-width: @highway-trunk-link-width-z13; } + [zoom >= 14] { line-width: @highway-trunk-link-width-z14; } + [zoom >= 15] { line-width: @highway-trunk-link-width-z15; } + [zoom >= 16] { line-width: @highway-trunk-link-width-z16; } + [zoom >= 17] { line-width: @highway-trunk-link-width-z17; } + [zoom >= 18] { line-width: @highway-trunk-link-width-z18; } + line-color: @road-fill; + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'secondary_link'] + { + line-width: @highway-tertiary-width-z10; + [zoom >= 11] { line-width: @highway-tertiary-width-z11; } + [zoom >= 12] { line-width: @highway-tertiary-width-z12; } + [zoom >= 13] { line-width: @highway-tertiary-width-z13; } + [zoom >= 14] { line-width: @highway-tertiary-width-z14; } + [zoom >= 15] { line-width: @highway-tertiary-width-z15; } + [zoom >= 16] { line-width: @highway-tertiary-width-z16; } + [zoom >= 17] { line-width: @highway-tertiary-width-z17; } + [zoom >= 18] { line-width: @highway-tertiary-width-z18; } + line-color: #bbb; + [zoom >= 11] + { + line-color: @road-fill; + } + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'service'][zoom >= 15] + { + [zoom >= 15] { line-width: @highway-service-width-z15; } + [zoom >= 16] { line-width: @highway-service-width-z16; } + [zoom >= 17] { line-width: @highway-service-width-z17; } + [zoom >= 18] { line-width: @highway-service-width-z18; } + [zoom >= 19] { line-width: @highway-service-width-z19; } + [zoom >= 20] { line-width: @highway-service-width-z20; } + line-color: #bbb; + [zoom >= 17] + { + line-color: @road-fill; + } + line-join: round; + #road-layer-n1 { line-cap: round; } + } + + [highway = 'path'][zoom >= 14], + [highway = 'footway'][zoom >= 14], + [highway = 'track'][zoom >= 14], + [highway = 'cycleway'][zoom >= 14] + { + line-width: @highway-path-width-z14; + [zoom >= 15] { line-width: @highway-path-width-z15; } + [zoom >= 16] { line-width: @highway-path-width-z16; } + [zoom >= 17] { line-width: @highway-path-width-z17; } + [zoom >= 18] { line-width: @highway-path-width-z18; } + line-color: #aaa; + [feature = 'road_path'] + { + line-dasharray: 6, 6; + } + line-join: round; + #road-layer-n1 + { + line-cap: round; + } + } +} + +#road-casing-layer-n1, +#road-casing[layer = 0], +#road-casing-layer-1[layer >= 1] +{ + [highway = 'trunk'] + { + line-width: @highway-trunk-width-z10 + @highway-trunk-casing-width; + [zoom >= 11] { line-width: @highway-trunk-width-z11 + @highway-trunk-casing-width; } + [zoom >= 12] { line-width: @highway-trunk-width-z12 + @highway-trunk-casing-width; } + [zoom >= 13] { line-width: @highway-trunk-width-z13 + @highway-trunk-casing-width; } + [zoom >= 14] { line-width: @highway-trunk-width-z14 + @highway-trunk-casing-width; } + [zoom >= 15] { line-width: @highway-trunk-width-z15 + @highway-trunk-casing-width; } + [zoom >= 16] { line-width: @highway-trunk-width-z16 + @highway-trunk-casing-width; } + [zoom >= 17] { line-width: @highway-trunk-width-z17 + @highway-trunk-casing-width; } + [zoom >= 18] { line-width: @highway-trunk-width-z18 + @highway-trunk-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'primary'] + { + line-width: @highway-primary-width-z10 + @highway-primary-casing-width; + [zoom >= 11] { line-width: @highway-primary-width-z11 + @highway-primary-casing-width; } + [zoom >= 12] { line-width: @highway-primary-width-z12 + @highway-primary-casing-width; } + [zoom >= 13] { line-width: @highway-primary-width-z13 + @highway-primary-casing-width; } + [zoom >= 14] { line-width: @highway-primary-width-z14 + @highway-primary-casing-width; } + [zoom >= 15] { line-width: @highway-primary-width-z15 + @highway-primary-casing-width; } + [zoom >= 16] { line-width: @highway-primary-width-z16 + @highway-primary-casing-width; } + [zoom >= 17] { line-width: @highway-primary-width-z17 + @highway-primary-casing-width; } + [zoom >= 18] { line-width: @highway-primary-width-z18 + @highway-primary-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'secondary'][zoom >= 11] + { + line-width: @highway-secondary-width-z10 + @highway-secondary-casing-width; + [zoom >= 11] { line-width: @highway-secondary-width-z11 + @highway-secondary-casing-width; } + [zoom >= 12] { line-width: @highway-secondary-width-z12 + @highway-secondary-casing-width; } + [zoom >= 13] { line-width: @highway-secondary-width-z13 + @highway-secondary-casing-width; } + [zoom >= 14] { line-width: @highway-secondary-width-z14 + @highway-secondary-casing-width; } + [zoom >= 15] { line-width: @highway-secondary-width-z15 + @highway-secondary-casing-width; } + [zoom >= 16] { line-width: @highway-secondary-width-z16 + @highway-secondary-casing-width; } + [zoom >= 17] { line-width: @highway-secondary-width-z17 + @highway-secondary-casing-width; } + [zoom >= 18] { line-width: @highway-secondary-width-z18 + @highway-secondary-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'tertiary'][zoom >= 13], + [highway = 'tertiary_link'][zoom >= 13] + { + line-width: @highway-tertiary-width-z10 + @highway-tertiary-casing-width; + [zoom >= 11] { line-width: @highway-tertiary-width-z11 + @highway-tertiary-casing-width; } + [zoom >= 12] { line-width: @highway-tertiary-width-z12 + @highway-tertiary-casing-width; } + [zoom >= 13] { line-width: @highway-tertiary-width-z13 + @highway-tertiary-casing-width; } + [zoom >= 14] { line-width: @highway-tertiary-width-z14 + @highway-tertiary-casing-width; } + [zoom >= 15] { line-width: @highway-tertiary-width-z15 + @highway-tertiary-casing-width; } + [zoom >= 16] { line-width: @highway-tertiary-width-z16 + @highway-tertiary-casing-width; } + [zoom >= 17] { line-width: @highway-tertiary-width-z17 + @highway-tertiary-casing-width; } + [zoom >= 18] { line-width: @highway-tertiary-width-z18 + @highway-tertiary-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'unclassified'][zoom >= 15], + [highway = 'residential'][zoom >= 15], + [highway = 'pedestrian'][zoom >= 15], + [highway = 'living_street'][zoom >= 15] + { + line-width: @highway-unclassified-width-z10 + @highway-unclassified-casing-width; + [zoom >= 11] { line-width: @highway-unclassified-width-z11 + @highway-unclassified-casing-width; } + [zoom >= 12] { line-width: @highway-unclassified-width-z12 + @highway-unclassified-casing-width; } + [zoom >= 13] { line-width: @highway-unclassified-width-z13 + @highway-unclassified-casing-width; } + [zoom >= 14] { line-width: @highway-unclassified-width-z14 + @highway-unclassified-casing-width; } + [zoom >= 15] { line-width: @highway-unclassified-width-z15 + @highway-unclassified-casing-width; } + [zoom >= 16] { line-width: @highway-unclassified-width-z16 + @highway-unclassified-casing-width; } + [zoom >= 17] { line-width: @highway-unclassified-width-z17 + @highway-unclassified-casing-width; } + [zoom >= 18] { line-width: @highway-unclassified-width-z18 + @highway-unclassified-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'trunk_link'], + [highway = 'primary_link'] + { + line-width: @highway-trunk-link-width-z10 + @highway-trunk-link-casing-width; + [zoom >= 11] { line-width: @highway-trunk-link-width-z11 + @highway-trunk-link-casing-width; } + [zoom >= 12] { line-width: @highway-trunk-link-width-z12 + @highway-trunk-link-casing-width; } + [zoom >= 13] { line-width: @highway-trunk-link-width-z13 + @highway-trunk-link-casing-width; } + [zoom >= 14] { line-width: @highway-trunk-link-width-z14 + @highway-trunk-link-casing-width; } + [zoom >= 15] { line-width: @highway-trunk-link-width-z15 + @highway-trunk-link-casing-width; } + [zoom >= 16] { line-width: @highway-trunk-link-width-z16 + @highway-trunk-link-casing-width; } + [zoom >= 17] { line-width: @highway-trunk-link-width-z17 + @highway-trunk-link-casing-width; } + [zoom >= 18] { line-width: @highway-trunk-link-width-z18 + @highway-trunk-link-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'secondary_link'][zoom >= 11] + { + line-width: @highway-tertiary-width-z10 + @highway-tertiary-casing-width; + [zoom >= 11] { line-width: @highway-tertiary-width-z11 + @highway-tertiary-casing-width; } + [zoom >= 12] { line-width: @highway-tertiary-width-z12 + @highway-tertiary-casing-width; } + [zoom >= 13] { line-width: @highway-tertiary-width-z13 + @highway-tertiary-casing-width; } + [zoom >= 14] { line-width: @highway-tertiary-width-z14 + @highway-tertiary-casing-width; } + [zoom >= 15] { line-width: @highway-tertiary-width-z15 + @highway-tertiary-casing-width; } + [zoom >= 16] { line-width: @highway-tertiary-width-z16 + @highway-tertiary-casing-width; } + [zoom >= 17] { line-width: @highway-tertiary-width-z17 + @highway-tertiary-casing-width; } + [zoom >= 18] { line-width: @highway-tertiary-width-z18 + @highway-tertiary-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + [highway = 'service'][zoom >= 17] + { + [zoom >= 17] { line-width: @highway-service-width-z17 + @highway-service-casing-width; } + [zoom >= 18] { line-width: @highway-service-width-z18 + @highway-service-casing-width; } + [zoom >= 19] { line-width: @highway-service-width-z19 + @highway-service-casing-width; } + [zoom >= 20] { line-width: @highway-service-width-z20 + @highway-service-casing-width; } + line-color: @road-casing; + line-join: round; + #road-casing-layer-n1 { line-cap: round; } + } + /* + [feature = 'road_minor'][zoom >= 15] + { + line-width: @road-minor-width-z13 + @road-minor-casing-width; + [zoom >= 14] { line-width: @road-minor-width-z14 + @road-minor-casing-width; } + [zoom >= 15] { line-width: @road-minor-width-z15 + @road-minor-casing-width; } + [zoom >= 16] { line-width: @road-minor-width-z16 + @road-minor-casing-width; } + [zoom >= 17] { line-width: @road-minor-width-z17 + @road-minor-casing-width; } + [zoom >= 18] { line-width: @road-minor-width-z18 + @road-minor-casing-width; } + line-color: #ccc; + line-join: round; + #road-casing-layer-n1 + { + line-cap: round; + } + } + */ +} +#road-text, +#road-text-minority +{ + [feature = 'road_major'] + { + text-name: "[name]"; + #road-text-minority + { + text-name: "[minority_name]"; + } + text-size: 10; + [zoom >= 16] { + text-size: 11; + } + [zoom >= 17] { + text-size: 12; + } + text-fill: #000; + text-face-name: "Liberation Sans Regular"; + text-repeat-distance: 300; + [minority_name != null] + { + text-repeat-distance: 600; + text-margin: 25; + } + text-placement: line; + text-halo-radius: 1; + text-halo-fill: white; + text-clip: false; + text-avoid-edges: true; + [highway = 'trunk'][zoom >= 14], + [highway = 'primary'][zoom >= 14], + [zoom >= 15] + { + text-face-name: "Liberation Sans Bold"; + } + } + [feature = 'road_minor'][zoom >= 15], + [feature = 'road_path'][zoom >= 15] + { + text-name: "[name]"; + #road-text-minority + { + text-name: "[minority_name]"; + } + text-size: 9; + [zoom >= 16] { + text-size: 10; + } + [zoom >= 17] { + text-size: 11; + } + text-fill: #000; + text-face-name: "Liberation Sans Regular"; + text-repeat-distance: 300; + [minority_name != null] + { + text-repeat-distance: 600; + [zoom >= 16] + { + text-margin: 25; + } + } + text-placement: line; + text-halo-radius: 1; + text-halo-fill: white; + text-clip: false; + text-avoid-edges: true; + } +} + +#rail-layer-n1, +#rail[layer = 0], +#rail-layer-1[layer >= 1] +{ + [service = null][zoom < 11] + { + line-width: 0.5; + [zoom >= 8] { line-width: 0.75; } + [zoom >= 9] { line-width: 1; } + line-color: #555; + } + [zoom >= 14], + [service = null][zoom >= 11] + { + line-color: #444; + b/line-color: white; + [service != null] + { + line-color: #888; + b/line-color: #ccc; + } + b/line-dasharray: 8, 8; + line-width: 2; + b/line-width: 1; + [zoom >= 17] + { + line-width: 3; + b/line-width: 1.5; + } + [zoom >= 18] + { + line-width: 4; + b/line-width: 2; + } + } +} + +#railway-platform-ref +{ + shield-name: "[ref]"; + shield-size: 12; + shield-fill: blue; + shield-spacing: 300; + shield-clip: false; + shield-placement: line; + shield-face-name: @railway-fonts-bold; + shield-halo-radius: @standard-halo-radius * 2; + shield-halo-fill: white; + shield-file: url('empty.png'); + shield-repeat-distance: 10; +} + +#runway[aeroway = 'runway'], +#runway[aeroway = 'taxiway'][zoom >= 14] +{ + line-width: 4; + [aeroway = 'taxiway'] + { + line-width: 1.5; + [zoom >= 15] { line-width: 3; } + [zoom >= 16] { line-width: 4; } + [zoom >= 17] { line-width: 6; } + [zoom >= 18] { line-width: 8; } + [zoom >= 19] { line-width: 12; } + [zoom >= 20] { line-width: 25; } + } + [aeroway = 'runway'] + { + [zoom >= 11] { line-width: 3; } + [zoom >= 12] { line-width: 4; } + [zoom >= 13] { line-width: 6; } + [zoom >= 14] { line-width: 8; } + [zoom >= 15] { line-width: 12; } + [zoom >= 16] { line-width: 25; } + [zoom >= 17] { line-width: 50; } + [zoom >= 18] { line-width: 100; } + [zoom >= 19] { line-width: 200; } + [zoom >= 20] { line-width: 400; } + } + line-color: #8b8998; + text-name: "[ref]"; + text-fill: black; + text-face-name: "Liberation Sans Oblique"; + text-repeat-distance: 300; + text-placement: line; + text-halo-radius: 1; + text-halo-fill: white; + text-clip: false; + text-avoid-edges: true; + text-size: 12; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/shapefiles.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,40 @@ +#necountries { + [zoom >= 1][zoom < 4] { + line-width: 0.2; + [zoom >= 2] { + line-width: 0.3; + } + [zoom >= 3] { + line-width: 0.4; + } + line-color: @admin-boundaries; + } +} + +#ocean-lz, +#ocean { + polygon-fill: @water-color; +} + +#icesheet-poly { + [zoom >= 5] { + polygon-fill: @glacier; + } +} + +#icesheet-outlines { + [zoom >= 5] { + [ice_edge = 'ice_ocean'], + [ice_edge = 'ice_land'] { + line-width: 0.375; + line-color: @glacier-line; + [zoom >= 8] { + line-width: 0.5; + } + [zoom >= 10] { + line-dasharray: 4,2; + line-width: 0.75; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/style/style.mss Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,121 @@ +/* This is from osm-carto */ +Map { + background-color: @land-color; +} + +@regular-font: "Tahoma Regular", "Liberation Sans Regular"; +@bold-font: "Tahoma Bold", "Liberation Sans Bold"; +@natural-font: "Liberation Serif Italic"; +@railway-fonts-bold: "FreeSans Bold"; +@place-font: @regular-font; +@place-font-bold: @bold-font; + +@water-color: #bfdbe8; +@land-color: #f2efe9; + +@standard-halo-radius: 1; +@standard-halo-fill: rgba(255,255,255,0.6); + +@residential-color: #d8d8e2; +@commercial-color: #ebd0d0; +@forest-color: #a1c8a7; +@farmland-color: #e9dfc9; +@grass-color: #dfebc6; +@industrial-color: #e3d7e9; +@religious-color: #c2cdb6; +@construction-color: #ada9a0; +@civic-services-color: #f0edcd; + +#railway-landuse +{ + polygon-fill: @industrial-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@industrial-color, 20%), 20%); + } +} + +#landcover { + [feature = 'residential'] { + polygon-fill: @residential-color; + [zoom >= 17] { + line-width: 0.5; + line-color: darken(@residential-color, 20%); + } + } + [feature = 'commercial'] { + polygon-fill: @commercial-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@commercial-color, 20%), 20%); + } + } + [feature = 'forest'] { + polygon-fill: @forest-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@forest-color, 20%), 20%); + } + } + [feature = 'farmland'] { + polygon-fill: @farmland-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@farmland-color, 20%), 20%); + } + } + [feature = 'grass'] { + polygon-fill: @grass-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@grass-color, 20%), 20%); + } + } + [feature = 'industrial'] { + polygon-fill: @industrial-color; + [zoom >= 17] { + line-width: 0.5; + line-color: saturate(darken(@industrial-color, 20%), 20%); + } + } + [feature = 'religious'] { + polygon-fill: @religious-color; + [zoom >= 17] { + line-width: 0.5; + line-color: darken(@religious-color, 20%); + } + } + [feature = 'construction'] { + polygon-fill: @construction-color; + [zoom >= 17] { + line-width: 0.5; + line-color: darken(@construction-color, 20%); + } + } +} + +#civic-services { + polygon-fill: @civic-services-color; + [zoom >= 17] { + line-width: 0.5; + line-color: darken(@civic-services-color, 20%); + } +} + +#inland-water { + polygon-fill: @water-color; + [zoom >= 12] { + line-width: 0.5; + line-color: saturate(darken(@water-color, 20%), 20%); + } +} + +#bridge-area { + polygon-fill: @land-color; +} + +#coastline +{ + line-width: 0.5; + line-color: saturate(darken(@water-color, 20%), 20%); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbols/aerodrome.svg Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Layer_1" + x="0px" + y="0px" + width="18" + height="18" + viewBox="0 0 18 17.999999" + xml:space="preserve" + sodipodi:docname="F39_Lentoasema.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"><metadata + id="metadata19"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs17" /><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1021" + id="namedview15" + showgrid="false" + inkscape:zoom="11.313709" + inkscape:cx="17.719841" + inkscape:cy="9.337293" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Layer_1" /> + + + +<g + id="g834" + transform="matrix(0.04517294,0,0,0.04517294,-0.62844556,17.81126)"><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_145_"> + + <rect + id="rect2" + height="396.85599" + width="396.85001" + style="fill:#005eb8;stroke:#005eb8;stroke-width:0.5;stroke-miterlimit:10" + y="14.17" + x="14.173" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_143_"> + <path + inkscape:connector-curvature="0" + id="path5" + d="M 59.527,411.026 H 365.67 c 25.047,0 45.354,-20.309 45.354,-45.355 V 59.527 C 411.024,34.478 390.717,14.17 365.67,14.17 H 59.527 c -25.046,0 -45.354,20.308 -45.354,45.357 v 306.144 c 0,25.047 20.308,45.355 45.354,45.355 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_144_"> + <path + inkscape:connector-curvature="0" + id="path8" + d="M 59.527,388.345 H 365.67 c 12.521,0 22.68,-10.148 22.68,-22.674 V 59.527 C 388.35,47.003 378.192,36.85 365.67,36.85 H 59.527 C 47.004,36.85 36.85,47.002 36.85,59.527 v 306.144 c 0,12.525 10.154,22.674 22.677,22.674 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_151_"> + <polygon + id="polygon11" + points="326.681,209.558 335.808,170.01 320.589,170.01 302.337,206.513 236.933,195.865 236.933,157.841 252.146,87.872 224.767,87.872 168.49,194.347 118.294,194.347 77.229,212.599 118.294,230.856 168.49,230.856 224.767,337.323 252.146,337.323 236.933,267.358 236.933,229.325 302.337,218.685 320.589,255.187 335.808,255.187 326.681,215.636 347.966,212.599 " + style="fill:#ffffff" /> +</g></g> +</svg> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbols/bus-station.svg Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Layer_1" + x="0px" + y="0px" + width="18" + height="18" + viewBox="0 0 18 17.999999" + xml:space="preserve" + sodipodi:docname="bus-station.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"><metadata + id="metadata52"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs50" /><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1021" + id="namedview48" + showgrid="false" + inkscape:zoom="45.254834" + inkscape:cx="12.93299" + inkscape:cy="10.461887" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Layer_1" /> + + + + + + + + + + + + + + +<g + id="g892" + transform="matrix(0.04535683,0,0,0.04535683,-0.62827696,18.086153)"><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_145_"> + + <rect + id="rect2" + height="396.85101" + width="396.85101" + style="fill:#005eb8;stroke:#005eb8;stroke-width:0.5;stroke-miterlimit:10" + y="14.173" + x="14.173" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_143_"> + <path + inkscape:connector-curvature="0" + id="path5" + d="M 59.527,411.023 H 365.67 c 25.045,0 45.354,-20.306 45.354,-45.353 V 59.528 c 0,-25.049 -20.309,-45.355 -45.354,-45.355 H 59.527 c -25.047,0 -45.354,20.306 -45.354,45.355 v 306.143 c 0,25.047 20.307,45.352 45.354,45.352 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_144_"> + <path + inkscape:connector-curvature="0" + id="path8" + d="M 59.527,388.341 H 365.67 c 12.523,0 22.676,-10.147 22.676,-22.67 V 59.528 c 0,-12.526 -10.152,-22.676 -22.676,-22.676 H 59.527 c -12.523,0 -22.677,10.15 -22.677,22.676 v 306.143 c 0,12.522 10.153,22.67 22.677,22.67 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-413.19601)" + id="CIRCLE_14_"> + <path + inkscape:connector-curvature="0" + id="path11" + d="m 135.825,136.367 c 0,-17.938 -14.54,-32.479 -32.479,-32.479 -17.939,0 -32.479,14.541 -32.479,32.479 0,17.938 14.54,32.48 32.479,32.48 17.939,0 32.479,-14.542 32.479,-32.48 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="CIRCLE_15_"> + <path + inkscape:connector-curvature="0" + id="path14" + d="m 131.102,136.367 c 0,-15.328 -12.429,-27.756 -27.756,-27.756 -15.332,0 -27.756,12.428 -27.756,27.756 0,15.33 12.424,27.756 27.756,27.756 15.327,0.001 27.756,-12.426 27.756,-27.756 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_171_"> + <path + inkscape:connector-curvature="0" + id="path17" + d="m 104.738,137.762 8.35,-8.354 c 0.771,-0.767 0.771,-2.015 0,-2.784 -0.764,-0.767 -2.012,-0.767 -2.781,0 l -4.992,4.99 v -14.929 c 0,-1.09 -0.879,-1.97 -1.968,-1.97 -1.089,0 -1.968,0.879 -1.968,1.97 v 19.682 c 0,0.523 0.209,1.022 0.576,1.395 0.77,0.767 2.012,0.767 2.783,0 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="CIRCLE_8_"> + <path + inkscape:connector-curvature="0" + id="path20" + d="m 148.474,335.139 c 0,-10.6 -8.592,-19.188 -19.191,-19.188 -10.594,0 -19.186,8.588 -19.186,19.188 0,10.598 8.592,19.191 19.186,19.191 10.599,0 19.191,-8.594 19.191,-19.191 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="CIRCLE_9_"> + <path + inkscape:connector-curvature="0" + id="path23" + d="m 303.962,335.139 c 0,-10.6 -8.593,-19.188 -19.191,-19.188 -10.594,0 -19.187,8.588 -19.187,19.188 0,10.598 8.593,19.191 19.187,19.191 10.599,0 19.191,-8.594 19.191,-19.191 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_160_"> + <path + inkscape:connector-curvature="0" + id="path26" + d="m 309.173,336.139 h 38.323 c 3.771,0 6.832,-3.062 6.832,-6.839 v -85.881 c 0,-3.775 -3.062,-6.837 -6.832,-6.837 H 92.808 c -3.123,0 -5.85,2.115 -6.625,5.146 l -15.315,59.878 v 34.533 h 34.018 c -0.027,-0.664 -0.027,-1.331 0,-1.996 0.55,-13.473 11.918,-23.952 25.397,-23.402 13.475,0.551 23.953,11.919 23.402,25.398 h 106.688 c -0.027,-0.664 -0.027,-1.331 0,-1.996 0.549,-13.473 11.918,-23.952 25.397,-23.402 13.476,0.55 23.953,11.918 23.403,25.398 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_170_"> + <path + inkscape:connector-curvature="0" + id="path29" + d="M 354.329,70.866 H 74.018 c -1.743,0 -3.15,1.411 -3.15,3.149 0,1.62 1.227,2.976 2.837,3.135 l 280.624,44.739 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_161_"> + <polygon + id="polygon32" + points="79.394,294.655 120.542,294.655 126.782,243.52 92.478,243.52 " + style="fill:#005eb8" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_162_"> + <polygon + id="polygon35" + points="128.584,282.766 175.527,282.766 175.527,243.52 133.374,243.52 " + style="fill:#005eb8" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_163_"> + <rect + id="rect38" + height="39.245998" + width="50.152" + style="fill:#005eb8" + y="243.52" + x="182.069" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_164_"> + <rect + id="rect41" + height="39.245998" + width="50.152" + style="fill:#005eb8" + y="243.52" + x="238.763" /> +</g><g + transform="translate(0,-413.19601)" + id="LWPOLYLINE_165_"> + <rect + id="rect44" + height="39.245998" + width="50.146" + style="fill:#005eb8" + y="243.52" + x="295.45801" /> +</g></g> +</svg> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbols/train-station.svg Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Layer_1" + x="0px" + y="0px" + width="18" + height="18" + viewBox="0 0 18 17.999999" + xml:space="preserve" + sodipodi:docname="train-station.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"><metadata + id="metadata37"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs35" /><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1021" + id="namedview33" + showgrid="false" + inkscape:zoom="11.313709" + inkscape:cx="-16.290539" + inkscape:cy="9.790908" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Layer_1" /> + + + + + + + + + +<g + id="g864" + transform="matrix(0.04523964,0,0,0.04523964,-0.62115711,17.811806)"><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_150_"> + + <rect + id="rect2" + height="396.85101" + width="396.85001" + style="fill:#005eb8;stroke:#005eb8;stroke-width:0.5;stroke-miterlimit:10" + y="14.173" + x="14.173" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_148_"> + <path + inkscape:connector-curvature="0" + id="path5" + d="m 59.527,411.023 h 306.141 c 25.049,0 45.355,-20.306 45.355,-45.353 V 59.529 c 0,-25.048 -20.307,-45.356 -45.355,-45.356 H 59.527 c -25.046,0 -45.354,20.309 -45.354,45.356 v 306.142 c 0,25.047 20.307,45.352 45.354,45.352 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_149_"> + <path + inkscape:connector-curvature="0" + id="path8" + d="m 59.527,388.342 h 306.141 c 12.523,0 22.676,-10.148 22.676,-22.671 V 59.529 c 0,-12.525 -10.152,-22.676 -22.676,-22.676 H 59.527 c -12.523,0 -22.676,10.15 -22.676,22.676 v 306.142 c 0,12.522 10.153,22.671 22.676,22.671 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-407.19601)" + id="CIRCLE_14_"> + <path + inkscape:connector-curvature="0" + id="path11" + d="m 135.824,136.369 c 0,-17.938 -14.54,-32.479 -32.478,-32.479 -17.939,0 -32.479,14.54 -32.479,32.479 0,17.938 14.54,32.48 32.479,32.48 17.938,0.001 32.478,-14.542 32.478,-32.48 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-407.19601)" + id="CIRCLE_15_"> + <path + inkscape:connector-curvature="0" + id="path14" + d="m 131.102,136.369 c 0,-15.33 -12.429,-27.757 -27.755,-27.757 -15.333,0 -27.756,12.427 -27.756,27.757 0,15.328 12.424,27.756 27.756,27.756 15.326,0 27.755,-12.428 27.755,-27.756 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_156_"> + <path + inkscape:connector-curvature="0" + id="path17" + d="m 349.968,194.583 v -17.449 h -69.777 v 43.61 h -65.413 v -13.083 c 0,-9.639 -7.813,-17.444 -17.444,-17.444 -9.637,0 -17.443,7.806 -17.443,17.444 v 13.083 h -47.97 v -34.886 h -21.808 v 34.886 H 83.946 v 85.61 h 12.231 c -7.229,12.519 -2.941,28.521 9.577,35.745 0.55,0.318 1.105,0.615 1.677,0.89 H 70.868 v 11.342 h 283.459 v -11.342 h -49.646 c 13.006,-6.299 18.443,-21.944 12.144,-34.951 -0.274,-0.572 -0.573,-1.133 -0.891,-1.684 h 34.034 v -72.525 h -17.443 v 21.803 h -34.892 v -61.049 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_190_"> + <path + inkscape:connector-curvature="0" + id="path20" + d="m 104.737,137.762 8.35,-8.353 c 0.77,-0.767 0.77,-2.015 0,-2.785 -0.764,-0.768 -2.012,-0.768 -2.781,0 l -4.992,4.992 v -14.932 c 0,-1.088 -0.879,-1.968 -1.967,-1.968 -1.089,0 -1.969,0.88 -1.969,1.968 v 19.685 c 0,0.521 0.209,1.022 0.577,1.393 0.77,0.766 2.012,0.766 2.782,0 z" + style="fill:#ffffff" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_157_"> + <path + inkscape:connector-curvature="0" + id="path23" + d="m 194.509,344.034 h -64.923 c 13.105,-6.351 18.586,-22.122 12.237,-35.233 -0.275,-0.577 -0.578,-1.137 -0.896,-1.693 h 42.236 c -7.285,12.616 -2.963,28.746 9.653,36.031 0.555,0.318 1.116,0.619 1.693,0.895 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_158_"> + <path + inkscape:connector-curvature="0" + id="path26" + d="M 281.867,342.989 H 217.46 c 13.006,-6.299 18.443,-21.944 12.143,-34.951 -0.274,-0.572 -0.57,-1.133 -0.891,-1.684 h 41.9 c -7.223,12.519 -2.934,28.521 9.578,35.745 0.55,0.319 1.111,0.616 1.677,0.89 z" + style="fill:#005eb8" /> +</g><g + transform="translate(0,-407.19601)" + id="LWPOLYLINE_189_"> + <path + inkscape:connector-curvature="0" + id="path29" + d="M 354.328,70.868 H 74.018 c -1.743,0 -3.149,1.409 -3.149,3.149 0,1.619 1.226,2.974 2.836,3.133 l 280.623,44.741 z" + style="fill:#ffffff" /> +</g></g> +</svg> \ No newline at end of file