[openstreetmap-carto] 01/04: Imported Upstream version 4.0.0
Bas Couwenberg
sebastic at debian.org
Sun May 28 08:14:45 UTC 2017
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository openstreetmap-carto.
commit c408e5ab5e112366878313e2b13c0656a84fe7a7
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sun May 28 10:11:35 2017 +0200
Imported Upstream version 4.0.0
---
.travis.yml | 9 +-
CHANGELOG.md | 17 +-
CONTRIBUTING.md | 14 +-
INSTALL.md | 8 +-
README.md | 7 +-
openstreetmap-carto.lua | 422 ++++++++++++++++++++++++++++++++++++
openstreetmap-carto.style | 141 ++----------
project.mml | 100 ++++-----
scripts/lua/README.md | 5 +
scripts/lua/openstreetmap-carto.lua | 1 +
scripts/lua/test.lua | 165 ++++++++++++++
water.mss | 12 +-
12 files changed, 712 insertions(+), 189 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 3426d02..3a6229b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,12 @@ language: node_js
sudo: false
node_js:
- "0.10"
+addons:
+ apt:
+ packages:
+ - lua5.1
env:
- - CARTO=0.16.0 MAPNIK='3.0.0 3.0.12'
- - CARTO=0.16.3 MAPNIK='3.0.0 3.0.12'
+ - CARTO=0.18.0 MAPNIK='3.0.0 3.0.12'
install:
- npm install carto@$CARTO
- mkdir -p data/world_boundaries data/simplified-land-polygons-complete-3857 data/ne_110m_admin_0_boundary_lines_land data/ne_10m_populated_places data/land-polygons-split-3857
@@ -16,3 +19,5 @@ script:
- for m in $MAPNIK; do ./node_modules/carto/bin/carto -a $m project.mml | xmllint - | wc -l; done
# Validate that the SVGs are valid XML
- find symbols/ -name '*.svg' | xargs xmllint --noout
+ # Check the Lua transforms
+ - lua scripts/lua/test.lua
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 49713e6..8094eb5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,19 @@
-## [Unreleased](https://github.com/gravitystorm/openstreetmap-carto/compare/v3.3.0...master)
+## [Unreleased](https://github.com/gravitystorm/openstreetmap-carto/compare/v4.0.0...master)
+
+## [v4.0.0](https://github.com/gravitystorm/openstreetmap-carto/compare/v3.3.0...v4.0.0)
+### Major changes
+- The database schema has changed from the osm2pgsql default. This requires a database reload.
+- osm2pgsql Lua transforms are used for some preprocessing. This requires osm2pgsql built with lua support, which most versions will have.
+
+### Changes
+- Old-style multipolygons (those with tags on the outer way instead of the relation) are no longer supported
+- Multipolygons composed of multiple areas are now rendered with one label
+- Fixes to various problems determining if an object is an area or not
+- CartoCSS 0.18.0 is required
+
+## [v3.3.1](https://github.com/gravitystorm/openstreetmap-carto/compare/v3.3.0...v3.3.1) - 2017-05-22
+### Changes
+- Fix a regression in intermittent waterways
## [v3.3.0](https://github.com/gravitystorm/openstreetmap-carto/compare/v3.2.0...v3.3.0) - 2017-05-10
### Changes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 107be6f..f6b79ce 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,6 +17,16 @@ contain a cropped screenshot of the problem, and a link to the area. Don't assum
that we will see exactly what you see. If a particular OSM object is an issue,
the issue should contain the tagging of the object.
+## 3.x compatibility
+
+OpenStreetMap Carto is currently maintaining compatibility in the output of 3.x
+and 4.x to allow users to smoothly transition and reload their databases. Pull
+requests which cannot be backported to 3.x are not being accepted at this time
+and will be closed.
+
+Whenever a pull request is merged into master, it also needs to be backported to
+the 3.x branch at the same time by the person merging.
+
## Easy pickings
Some [easy issues](https://github.com/gravitystorm/openstreetmap-carto/issues?q=is%3Aopen+is%3Aissue+label%3Aeasy) have been selected
@@ -26,7 +36,7 @@ that are particularly suitable for new contributors to get familiar with the pro
OpenStreetMap Carto uses a YAML file for defining layers, because it [works much
better for big projects](https://github.com/gravitystorm/openstreetmap-carto/issues/711).
-This requires CartoCSS 0.16.0 or later. If you need JSON MML, you can generate it
+This requires CartoCSS 0.18.0 or later. If you need JSON MML, you can generate it
with `python -c 'import sys, yaml, json; json.dump(yaml.safe_load(sys.stdin), sys.stdout)' < project.mml > project.json`
or the equivalent in a different language.
@@ -115,6 +125,8 @@ Because SQL within JSON or YAML will not generally be syntax highlighted, indent
* Add indentation if necessary for complex function calls, WHERE parenthesis, and CASE statements
* One space before and after = etc
* Name SQL subqueries after the layer name (but use underscores)
+* When extracting tags from hstore, use `tags->'foo'`, not `tags -> 'foo'`, and only add parenthesis if needed for order of operations
+* To check if a tag is in the tags hstore, use `tags @> 'foo=>bar'`, relying on automatic conversion from `text` to `hstore`.
## Map Icon Guidelines
diff --git a/INSTALL.md b/INSTALL.md
index afb19d2..0f40031 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,12 +1,12 @@
# Installation
## OpenStreetMap data
-You need OpenStreetMap data loaded into a PostGIS database (see below for [dependencies](#dependencies)). These stylesheets currently work only with the osm2pgsql defaults (i.e. database name is `gis`, table names are `planet_osm_point`, etc).
+You need OpenStreetMap data loaded into a PostGIS database (see below for [dependencies](#dependencies)). These stylesheets expect a database generated with osm2pgsql using the pgsql backend (table names of `planet_osm_point`, etc), the default database name (`gis`), and the [lua transforms](https://github.com/openstreetmap/osm2pgsql/blob/master/docs/lua.md) documented in the instructions below.
-It's probably easiest to grab an PBF of OSM data from [Mapzen](https://mapzen.com/metro-extracts/) or [geofabrik](http://download.geofabrik.de/). Once you've set up your PostGIS database, import with osm2pgsql:
+Start by setting up your database to have PostGIS and hstore with ``psql -d gis -c 'CREATE EXTENSION postgis; CREATE EXTENSION hstore;'``, then grab some OSM data. It's probably easiest to grab an PBF of OSM data from [Mapzen](https://mapzen.com/metro-extracts/) or [geofabrik](http://download.geofabrik.de/). Once you've done that, import with osm2pgsql:
```
-osm2pgsql -d gis ~/path/to/data.osm.pbf --style openstreetmap-carto.style
+osm2pgsql -G --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua -d gis ~/path/to/data.osm.pbf
```
You can find a more detailed guide to setting up a database and loading data with osm2pgsql at [switch2osm.org](http://switch2osm.org/loading-osm-data/).
@@ -93,7 +93,7 @@ For development, a style design studio is needed.
For deployment, CartoCSS and Mapnik are required.
-* [CartoCSS](https://github.com/mapbox/carto) >= 0.16.0 (we're using YAML)
+* [CartoCSS](https://github.com/mapbox/carto) >= 0.18.0 (we're using YAML)
* [Mapnik](https://github.com/mapnik/mapnik/wiki/Mapnik-Installation) >= 3.0
Remember to run CartoCSS with proper API version to avoid errors (at least 3.0.0: `carto -a "3.0.0"`).
diff --git a/README.md b/README.md
index 82d0a29..361da62 100644
--- a/README.md
+++ b/README.md
@@ -76,10 +76,9 @@ and issues have their own [tag](https://github.com/gravitystorm/openstreetmap-ca
Initial releases will not make use of the new features, maintaining compatibility
with v3.x and v3.x releases will continue with backports, allowing the style to be
-rendered from either a new database or an old one.
-
-When sufficient time has passed for users to reload their databases, new features
-can be used and 3.x compatibility will not be maintained.
+rendered from either a new database or an old one. In order to allow time for users
+to reload their databases, this will be maintained until at least two MINOR
+releases have occurred. After that compatibility will not be maintained.
# Alternatives
diff --git a/openstreetmap-carto.lua b/openstreetmap-carto.lua
new file mode 100644
index 0000000..26117e3
--- /dev/null
+++ b/openstreetmap-carto.lua
@@ -0,0 +1,422 @@
+-- For documentation of Lua tag transformations, see:
+-- https://github.com/openstreetmap/osm2pgsql/blob/master/docs/lua.md
+
+-- Objects with any of the following keys will be treated as polygon
+local polygon_keys = {
+ 'abandoned:aeroway',
+ 'abandoned:amenity',
+ 'abandoned:building',
+ 'abandoned:landuse',
+ 'abandoned:power',
+ 'aeroway',
+ 'amenity',
+ 'area:highway',
+ 'building',
+ 'building:part',
+ 'harbour',
+ 'historic',
+ 'landuse',
+ 'leisure',
+ 'man_made',
+ 'military',
+ 'natural',
+ 'office',
+ 'place',
+ 'power',
+ 'public_transport',
+ 'shop',
+ 'tourism',
+ 'water',
+ 'waterway',
+ 'wetland'
+}
+
+-- Objects with any of the following key/value combinations will be treated as linestring
+local linestring_values = {
+ leisure = {track = true, slipway = true},
+ man_made = {embankment = true, breakwater = true, groyne = true},
+ natural = {cliff = true, tree_row = true},
+ historic = {citywalls = true},
+ waterway = {canal = true, derelict_canal = true, ditch = true, drain = true, river = true, stream = true, wadi = true, weir = true},
+ power = {line = true, minor_line = true},
+ natural = {ridge = true, arete = true}
+}
+
+-- Objects with any of the following key/value combinations will be treated as polygon
+local polygon_values = {
+ highway = {services = true, rest_area = true},
+ junction = {yes = true}
+}
+
+-- The following keys will be deleted
+local delete_tags = {
+ 'note',
+ 'source',
+ 'source_ref',
+ 'attribution',
+ 'comment',
+ 'fixme',
+ -- Tags generally dropped by editors, not otherwise covered
+ 'created_by',
+ 'odbl',
+ 'odbl:note',
+ -- Lots of import tags
+ -- EUROSHA (Various countries)
+ 'project:eurosha_2012',
+
+ -- UrbIS (Brussels, BE)
+ 'ref:UrbIS',
+
+ -- NHN (CA)
+ 'accuracy:meters',
+ 'sub_sea:type',
+ 'waterway:type',
+ -- StatsCan (CA)
+ 'statscan:rbuid',
+
+ -- RUIAN (CZ)
+ 'ref:ruian:addr',
+ 'ref:ruian',
+ 'building:ruian:type',
+ -- DIBAVOD (CZ)
+ 'dibavod:id',
+ -- UIR-ADR (CZ)
+ 'uir_adr:ADRESA_KOD',
+
+ -- GST (DK)
+ 'gst:feat_id',
+
+ -- Maa-amet (EE)
+ 'maaamet:ETAK',
+ -- FANTOIR (FR)
+ 'ref:FR:FANTOIR',
+
+ -- 3dshapes (NL)
+ '3dshapes:ggmodelk',
+ -- AND (NL)
+ 'AND_nosr_r',
+
+ -- OPPDATERIN (NO)
+ 'OPPDATERIN',
+ -- Various imports (PL)
+ 'addr:city:simc',
+ 'addr:street:sym_ul',
+ 'building:usage:pl',
+ 'building:use:pl',
+ -- TERYT (PL)
+ 'teryt:simc',
+
+ -- RABA (SK)
+ 'raba:id',
+ -- DCGIS (Washington DC, US)
+ 'dcgis:gis_id',
+ -- Building Identification Number (New York, US)
+ 'nycdoitt:bin',
+ -- Chicago Building Inport (US)
+ 'chicago:building_id',
+ -- Louisville, Kentucky/Building Outlines Import (US)
+ 'lojic:bgnum',
+ -- MassGIS (Massachusetts, US)
+ 'massgis:way_id',
+
+ -- misc
+ 'import',
+ 'import_uuid',
+ 'OBJTYPE',
+ 'SK53_bulk:load'
+}
+delete_prefixes = {
+ 'note:',
+ 'source:',
+ -- Corine (CLC) (Europe)
+ 'CLC:',
+
+ -- Geobase (CA)
+ 'geobase:',
+ -- CanVec (CA)
+ 'canvec:',
+ -- Geobase (CA)
+ 'geobase:',
+
+ -- osak (DK)
+ 'osak:',
+ -- kms (DK)
+ 'kms:',
+
+ -- ngbe (ES)
+ -- See also note:es and source:file above
+ 'ngbe:',
+
+ -- Friuli Venezia Giulia (IT)
+ 'it:fvg:',
+
+ -- KSJ2 (JA)
+ -- See also note:ja and source_ref above
+ 'KSJ2:',
+ -- Yahoo/ALPS (JA)
+ 'yh:',
+
+ -- LINZ (NZ)
+ 'LINZ2OSM:',
+ 'linz2osm:',
+ 'LINZ:',
+
+ -- WroclawGIS (PL)
+ 'WroclawGIS:',
+ -- Naptan (UK)
+ 'naptan:',
+
+ -- TIGER (US)
+ 'tiger:',
+ -- GNIS (US)
+ 'gnis:',
+ -- National Hydrography Dataset (US)
+ 'NHD:',
+ 'nhd:',
+ -- mvdgis (Montevideo, UY)
+ 'mvdgis:'
+}
+
+-- Big table for z_order and roads status for certain tags. z=0 is turned into
+-- nil by the z_order function
+local roads_info = {
+ highway = {
+ motorway = {z = 380, roads = true},
+ trunk = {z = 370, roads = true},
+ primary = {z = 360, roads = true},
+ secondary = {z = 350, roads = true},
+ tertiary = {z = 340, roads = false},
+ residential = {z = 330, roads = false},
+ unclassified = {z = 330, roads = false},
+ road = {z = 330, roads = false},
+ living_street = {z = 320, roads = false},
+ pedestrian = {z = 310, roads = false},
+ raceway = {z = 300, roads = false},
+ motorway_link = {z = 240, roads = true},
+ trunk_link = {z = 230, roads = true},
+ primary_link = {z = 220, roads = true},
+ secondary_link = {z = 210, roads = true},
+ tertiary_link = {z = 200, roads = false},
+ service = {z = 150, roads = false},
+ track = {z = 110, roads = false},
+ path = {z = 100, roads = false},
+ footway = {z = 100, roads = false},
+ bridleway = {z = 100, roads = false},
+ cycleway = {z = 100, roads = false},
+ steps = {z = 90, roads = false},
+ platform = {z = 90, roads = false},
+ construction = {z = 10, roads = false}
+ },
+ railway = {
+ rail = {z = 440, roads = true},
+ subway = {z = 420, roads = true},
+ narrow_gauge = {z = 420, roads = true},
+ light_rail = {z = 420, roads = true},
+ funicular = {z = 420, roads = true},
+ preserved = {z = 420, roads = false},
+ monorail = {z = 420, roads = false},
+ miniature = {z = 420, roads = false},
+ turntable = {z = 420, roads = false},
+ tram = {z = 410, roads = false},
+ disused = {z = 400, roads = false},
+ construction = {z = 400, roads = false},
+ platform = {z = 90, roads = false},
+ },
+ aeroway = {
+ runway = {z = 60, roads = false},
+ taxiway = {z = 50, roads = false},
+ },
+ boundary = {
+ administrative = {z = 0, roads = true}
+ },
+}
+
+local excluded_railway_service = {
+ spur = true,
+ siding = true,
+ yard = true
+}
+--- Gets the z_order for a set of tags
+-- @param tags OSM tags
+-- @return z_order if an object with z_order, otherwise nil
+function z_order(tags)
+ local z = 0
+ for k, v in pairs(tags) do
+ if roads_info[k] and roads_info[k][v] then
+ z = math.max(z, roads_info[k][v].z)
+ end
+ end
+ return z ~= 0 and z or nil
+end
+
+--- Gets the roads table status for a set of tags
+-- @param tags OSM tags
+-- @return 1 if it belongs in the roads table, 0 otherwise
+function roads(tags)
+ for k, v in pairs(tags) do
+ if roads_info[k] and roads_info[k][v] and roads_info[k][v].roads then
+ if not (k ~= 'railway' or tags.service) then
+ return 1
+ elseif not excluded_railway_service[tags.service] then
+ return 1
+ end
+ end
+ end
+ return 0
+end
+
+--- Generic filtering of OSM tags
+-- @param tags Raw OSM tags
+-- @return Filtered OSM tags
+function filter_tags_generic(tags)
+ -- Short-circuit for untagged objects
+ if next(tags) == nil then
+ return 1, {}
+ end
+
+ -- Delete tags listed in delete_tags
+ for _, d in ipairs(delete_tags) do
+ tags[d] = nil
+ end
+
+ -- By using a second loop for wildcards we avoid checking already deleted tags
+ for tag, _ in pairs (tags) do
+ for _, d in ipairs(delete_prefixes) do
+ if string.sub(tag, 1, string.len(d)) == d then
+ tags[tag] = nil
+ break
+ end
+ end
+ end
+
+ -- Filter out objects that have no tags after deleting
+ if next(tags) == nil then
+ return 1, {}
+ end
+
+ -- Convert layer to an integer
+ tags['layer'] = layer(tags['layer'])
+ return 0, tags
+end
+
+-- Filtering on nodes
+function filter_tags_node (keyvalues, numberofkeys)
+ return filter_tags_generic(keyvalues)
+end
+
+-- Filtering on relations
+function filter_basic_tags_rel (keyvalues, numberofkeys)
+ -- Filter out objects that are filtered out by filter_tags_generic
+ local filter, keyvalues = filter_tags_generic(keyvalues)
+ if filter == 1 then
+ return 1, keyvalues
+ end
+
+ -- Filter out all relations except route, multipolygon and boundary relations
+ if ((keyvalues["type"] ~= "route") and (keyvalues["type"] ~= "multipolygon") and (keyvalues["type"] ~= "boundary")) then
+ return 1, keyvalues
+ end
+
+ return 0, keyvalues
+end
+
+-- Filtering on ways
+function filter_tags_way (keyvalues, numberofkeys)
+ local filter = 0 -- Will object be filtered out?
+ local polygon = 0 -- Will object be treated as polygon?
+
+ -- Filter out objects that are filtered out by filter_tags_generic
+ filter, keyvalues = filter_tags_generic(keyvalues)
+ if filter == 1 then
+ return filter, keyvalues, polygon, roads
+ end
+
+ polygon = isarea(keyvalues)
+
+ -- Add z_order column
+ keyvalues["z_order"] = z_order(keyvalues)
+
+ return filter, keyvalues, polygon, roads(keyvalues)
+end
+
+--- Handling for relation members and multipolygon generation
+-- @param keyvalues OSM tags, after processing by relation transform
+-- @param keyvaluemembers OSM tags of relation members, after processing by way transform
+-- @param roles OSM roles of relation members
+-- @param membercount number of members
+-- @return filter, cols, member_superseded, boundary, polygon, roads
+function filter_tags_relation_member (keyvalues, keyvaluemembers, roles, membercount)
+ local members_superseded = {}
+
+ -- Start by assuming that this not an old-style MP
+ for i = 1, membercount do
+ members_superseded[i] = 0
+ end
+
+ local type = keyvalues["type"]
+
+ -- Remove type key
+ keyvalues["type"] = nil
+
+ -- Filter out relations with just a type tag or no tags
+ if next(keyvalues) == nil then
+ return 1, keyvalues, members_superseded, 0, 0, 0
+ end
+
+ if type == "boundary" or (type == "multipolygon" and keyvalues["boundary"]) then
+ keyvalues.z_order = z_order(keyvalues)
+ return 0, keyvalues, members_superseded, 1, 0, roads(keyvalues)
+ -- For multipolygons...
+ elseif (type == "multipolygon") then
+ -- Multipolygons by definition are polygons, so we know roads = linestring = 0, polygon = 1
+ keyvalues.z_order = z_order(keyvalues)
+ return 0, keyvalues, members_superseded, 0, 1, 0
+ elseif type == "route" then
+ keyvalues.z_order = z_order(keyvalues)
+ return 0, keyvalues, members_superseded, 1, 0, roads(keyvalues)
+ end
+
+ -- Unknown type of relation or no type tag
+ return 1, keyvalues, members_superseded, 0, 0, 0
+end
+
+--- Check if an object with given tags should be treated as polygon
+-- @param tags OSM tags
+-- @return 1 if area, 0 if linear
+function isarea (tags)
+ -- Treat objects tagged as area=yes polygon, other area as no
+ if tags["area"] then
+ return tags["area"] == "yes" and 1 or 0
+ end
+
+ -- Search through object's tags
+ for k, v in pairs(tags) do
+ -- Check if it has a polygon key and not a linestring override, or a polygon k=v
+ for _, ptag in ipairs(polygon_keys) do
+ if k == ptag and not (linestring_values[k] and linestring_values[k][v]) then
+ return 1
+ end
+ end
+
+ if (polygon_values[k] and polygon_values[k][v]) then
+ return 1
+ end
+ end
+ return 0
+end
+
+function is_in (needle, haystack)
+ for index, value in ipairs (haystack) do
+ if value == needle then
+ return true
+ end
+ end
+ return false
+end
+
+--- Normalizes layer tags
+-- @param v The layer tag value
+-- @return An integer for the layer tag
+function layer (v)
+ return v and string.find(v, "^-?%d+$") and tonumber(v) < 100 and tonumber(v) > -100 and v or nil
+end
diff --git a/openstreetmap-carto.style b/openstreetmap-carto.style
index d3a005c..77134cb 100644
--- a/openstreetmap-carto.style
+++ b/openstreetmap-carto.style
@@ -1,154 +1,55 @@
-# This is the .style file for OpenStreetMap Carto, which is currently
-# the same as the upstream osm2pgsql style
-# phstore is used instead of polygon,nocolumn to preserve compatibility
-# with older osm2pgsql versions
+# This is the osm2pgsql .style file for openstreetmap-carto.
+# It is inteded to be used with openstreetmap-carto.lua and osm2pgsql Lua
+# transforms. Full usage details are in INSTALL.md
+# Among things, this means that the linear vs polygon distinction in this file
+# doesn't matter, because that is set in the Lua and this file is only used for
+# column names and types.
# OsmType Tag DataType Flags
node,way access text linear
node,way addr:housename text linear
node,way addr:housenumber text linear
-node,way addr:interpolation text linear
+way addr:interpolation text linear
node,way admin_level text linear
node,way aerialway text linear
node,way aeroway text polygon
node,way amenity text polygon
-node,way area text polygon # hard coded support for area=1/yes => polygon is in osm2pgsql
node,way barrier text linear
-node,way bicycle text linear
-node,way brand text linear
-node,way bridge text linear
+way bicycle text linear
+way bridge text linear
node,way boundary text linear
node,way building text polygon
-node capital text linear
-node,way construction text linear
-node,way covered text linear
-node,way culvert text linear
-node,way cutting text linear
-node,way denomination text linear
-node,way disused text linear
-node ele text linear
-node,way embankment text linear
-node,way foot text linear
-node,way generator:source text linear
-node,way harbour text polygon
+way construction text linear
+way covered text linear
+way foot text linear
node,way highway text linear
node,way historic text polygon
-node,way horse text linear
-node,way intermittent text linear
+way horse text linear
node,way junction text linear
node,way landuse text polygon
-node,way layer text linear
+node,way layer int4 linear
node,way leisure text polygon
node,way lock text linear
node,way man_made text polygon
node,way military text polygon
-node,way motorcar text linear
node,way name text linear
-node,way natural text polygon # natural=coastline tags are discarded by a hard coded rule in osm2pgsql
-node,way office text polygon
+node,way natural text polygon
node,way oneway text linear
-node,way operator text linear
node,way place text polygon
-node,way population text linear
node,way power text polygon
-node,way power_source text linear
-node,way public_transport text polygon
node,way railway text linear
node,way ref text linear
node,way religion text linear
-node,way route text linear
-node,way service text linear
+way route text linear
+way service text linear
node,way shop text polygon
-node,way sport text polygon
-node,way surface text linear
-node,way toll text linear
+way surface text linear
node,way tourism text polygon
-node,way tower:type text linear
way tracktype text linear
-node,way tunnel text linear
+way tunnel text linear
node,way water text polygon
node,way waterway text polygon
-node,way wetland text polygon
-node,way width text linear
-node,way wood text linear
-node,way z_order int4 linear # This is calculated during import
way way_area real linear # This is calculated during import
-# Area tags
-# We don't make columns for these tags, but objects with them are areas.
-way abandoned:aeroway text phstore
-way abandoned:amenity text phstore
-way abandoned:building text phstore
-way abandoned:landuse text phstore
-way abandoned:power text phstore
-way area:highway text phstore
-
-# Deleted tags
-# These are tags that are generally regarded as useless for most rendering.
-# Most of them are from imports or intended as internal information for mappers
-# Some of them are automatically deleted by editors.
-# If you want some of them, perhaps for a debugging layer, just delete the lines.
-
-# These tags are used by mappers to keep track of data.
-# They aren't very useful for rendering.
-node,way note text delete
-node,way note:* text delete
-node,way source text delete
-node,way source_ref text delete
-node,way source:* text delete
-node,way attribution text delete
-node,way comment text delete
-node,way fixme text delete
-
-# Tags generally dropped by editors, not otherwise covered
-node,way created_by text delete
-node,way odbl text delete
-node,way odbl:note text delete
-node,way SK53_bulk:load text delete
-
-# Lots of import tags
-# TIGER (US)
-node,way tiger:* text delete
-
-# NHD (US)
-# NHD has been converted every way imaginable
-node,way NHD:* text delete
-node,way nhd:* text delete
-
-# GNIS (US)
-node,way gnis:* text delete
-
-# Geobase (CA)
-node,way geobase:* text delete
-# NHN (CA)
-node,way accuracy:meters text delete
-node,way sub_sea:type text delete
-node,way waterway:type text delete
-
-# KSJ2 (JA)
-# See also note:ja and source_ref above
-node,way KSJ2:* text delete
-# Yahoo/ALPS (JA)
-node,way yh:* text delete
-
-# osak (DK)
-node,way osak:* text delete
-
-# kms (DK)
-node,way kms:* text delete
-
-# ngbe (ES)
-# See also note:es and source:file above
-node,way ngbe:* text delete
-
-# naptan (UK)
-node,way naptan:* text delete
-
-# Corine (CLC) (Europe)
-node,way CLC:* text delete
-
-# misc
-node,way 3dshapes:ggmodelk text delete
-node,way AND_nosr_r text delete
-node,way import text delete
-node,way it:fvg:* text delete
+# Columns defined in openstreetmap-carto.lua file
+way z_order int4 linear
diff --git a/project.mml b/project.mml
index f986ca1..023fcab 100644
--- a/project.mml
+++ b/project.mml
@@ -108,14 +108,14 @@ Layer:
way, COALESCE(name, '') AS name,
('landuse_' || (CASE WHEN landuse IN ('forest', 'military') THEN landuse ELSE NULL END)) AS landuse,
('natural_' || (CASE WHEN "natural" IN ('wood', 'sand', 'scree', 'shingle', 'bare_rock') THEN "natural" ELSE NULL END)) AS "natural",
- ('wetland_' || (CASE WHEN "natural" IN ('wetland', 'mud') THEN (CASE WHEN "natural" IN ('mud') THEN "natural" ELSE wetland END) ELSE NULL END)) AS wetland,
+ ('wetland_' || (CASE WHEN "natural" IN ('wetland', 'mud') THEN (CASE WHEN "natural" IN ('mud') THEN "natural" ELSE tags->'wetland' END) ELSE NULL END)) AS wetland,
way_area/NULLIF(!pixel_width!::real*!pixel_height!::real,0) AS way_pixels
FROM planet_osm_polygon
WHERE (landuse IN ('forest', 'military')
OR "natural" IN ('wood', 'wetland', 'mud', 'sand', 'scree', 'shingle', 'bare_rock'))
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
AND building IS NULL
- ORDER BY CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS features
) AS landcover_low_zoom
properties:
@@ -146,7 +146,7 @@ Layer:
'track', 'dog_park') THEN leisure ELSE NULL END)) AS leisure,
('military_' || (CASE WHEN military IN ('danger_area') THEN military ELSE NULL END)) AS military,
('natural_' || (CASE WHEN "natural" IN ('beach', 'shoal', 'heath', 'grassland', 'wood', 'sand', 'scree', 'shingle', 'bare_rock', 'scrub') THEN "natural" ELSE NULL END)) AS "natural",
- ('wetland_' || (CASE WHEN "natural" IN ('wetland', 'marsh', 'mud') THEN (CASE WHEN "natural" IN ('marsh', 'mud') THEN "natural" ELSE wetland END) ELSE NULL END)) AS wetland,
+ ('wetland_' || (CASE WHEN "natural" IN ('wetland', 'marsh', 'mud') THEN (CASE WHEN "natural" IN ('marsh', 'mud') THEN "natural" ELSE tags->'wetland' END) ELSE NULL END)) AS wetland,
('power_' || (CASE WHEN power IN ('station', 'sub_station', 'substation', 'generator') THEN power ELSE NULL END)) AS power,
('tourism_' || (CASE WHEN tourism IN ('attraction', 'camp_site', 'caravan_site', 'picnic_site') THEN tourism ELSE NULL END)) AS tourism,
('highway_' || (CASE WHEN highway IN ('services', 'rest_area') THEN highway ELSE NULL END)) AS highway,
@@ -166,7 +166,7 @@ Layer:
OR highway IN ('services', 'rest_area')
OR railway = 'station')
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
- ORDER BY CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS landcover
) AS features
properties:
@@ -193,7 +193,7 @@ Layer:
<<: *osm2pgsql
table: |-
(SELECT
- way, waterway, intermittent,
+ way, waterway, tags->'intermittent' as intermittent,
CASE WHEN tunnel IN ('yes', 'culvert') THEN 'yes' ELSE 'no' END AS int_tunnel
FROM planet_osm_line
WHERE waterway IN ('stream', 'drain', 'ditch')
@@ -210,7 +210,7 @@ Layer:
(SELECT
way,
waterway,
- intermittent
+ tags->'intermittent' as intermittent
FROM planet_osm_line
WHERE waterway = 'river'
) AS water_lines_low_zoom
@@ -247,7 +247,7 @@ Layer:
OR "natural" IN ('water', 'glacier'))
AND building IS NULL
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
- ORDER BY z_order, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS water_areas
properties:
minzoom: 4
@@ -263,10 +263,10 @@ Layer:
COALESCE(CASE WHEN landuse = 'forest' THEN 'wood' ELSE NULL END, "natural") AS "natural",
CASE WHEN "natural" IN ('marsh', 'mud')
THEN "natural"
- ELSE CASE WHEN ("natural" = 'wetland' AND wetland IS NULL)
+ ELSE CASE WHEN ("natural" = 'wetland' AND NOT tags ? 'wetland')
THEN 'wetland'
ELSE CASE WHEN ("natural" = 'wetland')
- THEN wetland
+ THEN tags->'wetland'
ELSE NULL
END
END
@@ -275,7 +275,7 @@ Layer:
WHERE ("natural" IN ('marsh', 'mud', 'wetland', 'wood', 'beach', 'shoal', 'reef', 'scrub') OR landuse = 'forest')
AND building IS NULL
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
- ORDER BY z_order, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS landcover_area_symbols
properties:
minzoom: 10
@@ -297,13 +297,13 @@ Layer:
<<: *osm2pgsql
table: |-
(SELECT
- way, waterway, name, intermittent,
+ way, waterway, name, tags->'intermittent' as intermittent,
CASE WHEN tunnel IN ('yes', 'culvert') THEN 'yes' ELSE 'no' END AS int_tunnel,
'no' AS bridge
FROM planet_osm_line
WHERE waterway IN ('river', 'canal', 'derelict_canal', 'stream', 'drain', 'ditch', 'wadi')
AND (bridge IS NULL OR bridge NOT IN ('yes', 'aqueduct'))
- ORDER BY z_order
+ ORDER BY COALESCE(layer,0)
) AS water_lines
properties:
minzoom: 12
@@ -429,7 +429,7 @@ Layer:
AND (amenity IS NULL OR amenity != 'place_of_worship')
AND building != 'train_station'
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
- ORDER BY z_order, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS buildings
properties:
minzoom: 13
@@ -450,7 +450,7 @@ Layer:
AND building != 'no'
AND (aeroway = 'terminal' OR amenity = 'place_of_worship' OR building = 'train_station')
AND way_area > 0.01*!pixel_width!::real*!pixel_height!::real
- ORDER BY z_order, way_area DESC)
+ ORDER BY COALESCE(layer,0), way_area DESC)
AS buildings_major
properties:
minzoom: 13
@@ -506,7 +506,7 @@ Layer:
WHEN substr(highway, length(highway)-3, 4) = 'link' THEN 'yes'
ELSE 'no'
END AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel = 'yes' OR tunnel = 'building_passage' OR covered = 'yes')
AND highway IS NOT NULL -- end of road select
@@ -532,7 +532,7 @@ Layer:
construction,
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service,
'no' AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel = 'yes' OR tunnel = 'building_passage' OR covered = 'yes')
AND (railway IS NOT NULL OR aeroway IS NOT NULL) -- end of rail/aero select
@@ -723,7 +723,7 @@ Layer:
FROM planet_osm_polygon
WHERE highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'track', 'path', 'platform')
OR railway IN ('platform')
- ORDER BY z_order, way_area DESC
+ ORDER BY COALESCE(layer,0), way_area DESC
) AS highway_area_casing
properties:
minzoom: 14
@@ -775,7 +775,7 @@ Layer:
WHEN substr(highway, length(highway)-3, 4) = 'link' THEN 'yes'
ELSE 'no'
END AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel IS NULL OR NOT tunnel IN ('yes', 'building_passage'))
AND (covered IS NULL OR NOT covered = 'yes')
@@ -803,7 +803,7 @@ Layer:
construction,
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service,
'no' AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel IS NULL OR NOT tunnel IN ('yes', 'building_passage'))
AND (covered IS NULL OR NOT covered = 'yes')
@@ -883,7 +883,7 @@ Layer:
WHERE highway IN ('residential', 'unclassified', 'pedestrian', 'service', 'footway', 'living_street', 'track', 'path', 'platform', 'services')
OR railway IN ('platform')
OR aeroway IN ('runway', 'taxiway', 'helipad')
- ORDER BY z_order, way_area desc
+ ORDER BY COALESCE(layer,0), way_area desc
) AS highway_area_fill
properties:
minzoom: 14
@@ -940,7 +940,7 @@ Layer:
WHEN substr(highway, length(highway)-3, 4) = 'link' THEN 'yes'
ELSE 'no'
END AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel IS NULL OR NOT tunnel IN ('yes', 'building_passage'))
AND (covered IS NULL OR NOT covered = 'yes')
@@ -968,7 +968,7 @@ Layer:
construction,
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service,
'no' AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE (tunnel IS NULL OR NOT tunnel IN ('yes', 'building_passage'))
AND (covered IS NULL OR NOT covered = 'yes')
@@ -1099,7 +1099,7 @@ Layer:
WHERE highway IS NOT NULL
OR (railway IS NOT NULL AND railway != 'preserved'
AND (service IS NULL OR service NOT IN ('spur', 'siding', 'yard')))
- ORDER BY z_order
+ ORDER BY COALESCE(layer,0)
) AS roads_low_zoom
properties:
minzoom: 5
@@ -1116,13 +1116,13 @@ Layer:
way,
waterway,
name,
- intermittent,
+ tags->'intermittent' as intermittent,
CASE WHEN tunnel IN ('yes', 'culvert') THEN 'yes' ELSE 'no' END AS int_tunnel,
'yes' AS bridge
FROM planet_osm_line
WHERE waterway IN ('river', 'canal', 'derelict_canal', 'stream', 'drain', 'ditch', 'wadi')
AND bridge IN ('yes', 'aqueduct')
- ORDER BY z_order
+ ORDER BY COALESCE(layer,0)
) AS waterway_bridges
properties:
minzoom: 12
@@ -1174,7 +1174,7 @@ Layer:
WHEN substr(highway, length(highway)-3, 4) = 'link' THEN 'yes'
ELSE 'no'
END AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE bridge IN ('yes', 'boardwalk', 'cantilever', 'covered', 'low_water_crossing', 'movable', 'trestle', 'viaduct')
AND highway IS NOT NULL -- end of road select
@@ -1200,7 +1200,7 @@ Layer:
construction,
CASE WHEN service IN ('parking_aisle', 'drive-through', 'driveway') THEN 'INT-minor'::text ELSE 'INT-normal'::text END AS service,
'no' AS link,
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END AS layernotnull
+ COALESCE(layer,0) AS layernotnull
FROM planet_osm_line
WHERE bridge IN ('yes', 'boardwalk', 'cantilever', 'covered', 'low_water_crossing', 'movable', 'trestle', 'viaduct')
AND (railway IS NOT NULL OR aeroway IS NOT NULL) -- end of rail/aero select
@@ -1446,13 +1446,13 @@ Layer:
way,
name,
CASE
- WHEN (population ~ '^[0-9]{1,8}$') THEN population::INTEGER ELSE 0
+ WHEN (tags->'population' ~ '^[0-9]{1,8}$') THEN (tags->'population')::INTEGER ELSE 0
END as population,
round(ascii(md5(osm_id::text)) / 55) AS dir -- base direction factor on geometry to be consistent across metatiles
FROM planet_osm_point
WHERE place IN ('city', 'town', 'village', 'hamlet')
AND name IS NOT NULL
- AND capital = 'yes'
+ AND tags @> 'capital=>yes'
ORDER BY population DESC
) AS capital_names
properties:
@@ -1504,21 +1504,21 @@ Layer:
name,
(
(CASE
- WHEN (population ~ '^[0-9]{1,8}$') THEN population::INTEGER
+ WHEN (tags->'population' ~ '^[0-9]{1,8}$') THEN (tags->'population')::INTEGER
WHEN (place = 'city') THEN 100000
WHEN (place = 'town') THEN 1000
ELSE 1
END)
*
(CASE
- WHEN (capital = '4') THEN 2
+ WHEN (tags @> 'capital=>4') THEN 2
ELSE 1
END)
) AS score
FROM planet_osm_point
WHERE place IN ('city', 'town')
AND name IS NOT NULL
- AND (capital IS NULL OR capital != 'yes')
+ AND NOT (tags @> 'capital=>yes')
) as p
ORDER BY score DESC, length(name) DESC, name
) AS placenames_medium
@@ -1539,7 +1539,7 @@ Layer:
FROM planet_osm_point
WHERE place IN ('village', 'hamlet')
AND name IS NOT NULL
- AND (capital IS NULL OR capital != 'yes')
+ AND NOT tags @> 'capital=>yes'
OR place IN ('suburb', 'neighbourhood', 'locality', 'isolated_dwelling', 'farm')
AND name IS NOT NULL
ORDER BY CASE
@@ -1634,9 +1634,9 @@ Layer:
) AS feature,
access,
religion,
- denomination,
- "generator:source",
- power_source,
+ tags->'denomination' as denomination,
+ tags->'generator:source' as "generator:source",
+ tags->'power_source' as power_source,
CASE WHEN shop IN ('supermarket', 'bag', 'bakery', 'beauty', 'books', 'butcher', 'clothes', 'computer',
'confectionery', 'fashion', 'convenience', 'department_store', 'doityourself', 'hardware', 'fishmonger', 'florist',
'garden_centre', 'hairdresser', 'hifi', 'ice_cream', 'car', 'car_repair', 'bicycle', 'mall', 'pet',
@@ -1666,7 +1666,7 @@ Layer:
OR "natural" IN ('spring')
OR historic IN ('memorial', 'monument', 'archaeological_site')
OR highway IN ('bus_stop', 'elevator', 'traffic_signals')
- OR (power = 'generator' AND ("generator:source" = 'wind' OR power_source = 'wind'))
+ OR (power = 'generator' AND (tags @> '"generator:source"=>wind' OR tags @> 'power_source=>wind'))
ORDER BY way_area desc
) AS amenity_points_poly
properties:
@@ -1709,15 +1709,15 @@ Layer:
CASE
WHEN "natural" IN ('peak', 'volcano', 'saddle') THEN
CASE
- WHEN ele ~ '^-?\d{1,4}(\.\d+)?$' THEN ele::NUMERIC
+ WHEN tags->'ele' ~ '^-?\d{1,4}(\.\d+)?$' THEN (tags->'ele')::NUMERIC
ELSE NULL
END
ELSE NULL
END AS score,
religion,
- denomination,
- "generator:source",
- power_source,
+ tags->'denomination' as denomination,
+ tags->'generator:source' as "generator:source",
+ tags->'power_source' as power_source,
CASE WHEN shop IN ('supermarket', 'bag', 'bakery', 'beauty', 'books', 'butcher', 'clothes', 'computer',
'confectionery', 'fashion', 'convenience', 'department_store', 'doityourself', 'hardware', 'fishmonger', 'florist',
'garden_centre', 'hairdresser', 'hifi', 'ice_cream', 'car', 'car_repair', 'bicycle', 'mall', 'pet',
@@ -1748,7 +1748,7 @@ Layer:
OR "natural" IN ('peak', 'volcano', 'saddle', 'spring', 'cave_entrance')
OR historic IN ('memorial', 'monument', 'archaeological_site', 'wayside_cross')
OR highway IN ('bus_stop', 'elevator', 'traffic_signals', 'ford')
- OR (power = 'generator' AND ("generator:source" = 'wind' OR power_source = 'wind'))
+ OR (power = 'generator' AND (tags @> '"generator:source"=>wind' OR tags @> 'power_source=>wind'))
ORDER BY score DESC NULLS LAST
) AS amenity_points
properties:
@@ -1993,7 +1993,7 @@ Layer:
OR junction IN ('roundabout'))
ORDER BY
prio DESC, -- put important roads first
- CASE WHEN layer~E'^-?\\d+$' AND length(layer)<10 THEN layer::integer ELSE 0 END DESC, -- put top layered roads first
+ COALESCE(layer, 0), -- put top layered roads first
length(name) DESC, -- Try to fit big labels in first
name DESC, -- Force a consistent ordering between differently named streets
l.osm_id DESC -- Force an ordering for streets of the same name, e.g. dualized roads
@@ -2105,7 +2105,7 @@ Layer:
) AS feature,
access,
name,
- operator,
+ tags->'operator' as operator,
ref,
way_area,
CASE WHEN building = 'no' OR building IS NULL THEN 'no' ELSE 'yes' END AS is_building
@@ -2147,7 +2147,7 @@ Layer:
COALESCE('man_made_' || man_made, 'waterway_' || waterway, 'natural_' || "natural") AS feature,
access,
name,
- operator,
+ tags->'operator' as operator,
ref,
NULL AS way_area,
CASE WHEN building = 'no' OR building IS NULL THEN 'no' ELSE 'yes' END AS is_building
@@ -2238,13 +2238,13 @@ Layer:
CASE
WHEN "natural" IN ('peak', 'volcano', 'saddle') OR tourism = 'alpine_hut' OR amenity = 'shelter' THEN
CASE
- WHEN ele ~ '^-?\d{1,4}(\.\d+)?$' THEN ele::NUMERIC
+ WHEN tags->'ele' ~ '^-?\d{1,4}(\.\d+)?$' THEN (tags->'ele')::NUMERIC
ELSE NULL
END
ELSE NULL
END AS elevation,
"natural",
- operator,
+ tags->'operator' as operator,
ref,
NULL AS way_area,
CASE WHEN building = 'no' OR building IS NULL THEN 'no' ELSE 'yes' END AS is_building
@@ -2269,7 +2269,7 @@ Layer:
OR boundary IN ('national_park')
OR waterway IN ('dam', 'weir'))
AND (name IS NOT NULL
- OR (ele IS NOT NULL AND ("natural" IN ('peak', 'volcano', 'saddle') OR tourism = 'alpine_hut' OR amenity = 'shelter'))
+ OR (tags?'ele' AND ("natural" IN ('peak', 'volcano', 'saddle') OR tourism = 'alpine_hut' OR amenity = 'shelter'))
OR (ref IS NOT NULL AND aeroway IN ('gate'))
)
) AS p
@@ -2349,13 +2349,13 @@ Layer:
waterway,
lock,
name,
- intermittent,
+ tags->'intermittent' as intermittent,
CASE WHEN tunnel IN ('yes', 'culvert') THEN 'yes' ELSE 'no' END AS int_tunnel
FROM planet_osm_line
WHERE waterway IN ('river', 'canal', 'derelict_canal', 'stream', 'drain', 'ditch', 'wadi')
AND (tunnel IS NULL or tunnel != 'culvert')
AND name IS NOT NULL
- ORDER BY z_order
+ ORDER BY COALESCE(layer,0)
) AS water_lines_text
properties:
minzoom: 13
diff --git a/scripts/lua/README.md b/scripts/lua/README.md
new file mode 100644
index 0000000..b5c3a4e
--- /dev/null
+++ b/scripts/lua/README.md
@@ -0,0 +1,5 @@
+# Lua helper scripts #
+
+These scripts are for developing, testing, and profiling the [Lua tag transform](../../openstreetmap-carto.lua). There is a symlink to the transform in this directory so it can be `require`d by other files.
+
+They are not necessary for map rendering or most development.
diff --git a/scripts/lua/openstreetmap-carto.lua b/scripts/lua/openstreetmap-carto.lua
new file mode 120000
index 0000000..ba19fbe
--- /dev/null
+++ b/scripts/lua/openstreetmap-carto.lua
@@ -0,0 +1 @@
+../../openstreetmap-carto.lua
\ No newline at end of file
diff --git a/scripts/lua/test.lua b/scripts/lua/test.lua
new file mode 100644
index 0000000..ed4d5bb
--- /dev/null
+++ b/scripts/lua/test.lua
@@ -0,0 +1,165 @@
+--[[
+This file is part of OpenStreetMap Carto and used for validating the Lua tag transforms.
+
+Run it with lua test.lua
+]]
+
+require ("openstreetmap-carto")
+
+--- compare two tables.
+-- @param t1 A table
+-- @param t2 A table
+-- @return true or false
+function equaltables (t1,t2)
+ for k, v in pairs(t1) do
+ if t2[k] ~= v then return false end
+ end
+ for k, v in pairs(t2) do
+ if t1[k] ~= v then return false end
+ end
+ return true
+end
+
+print("TESTING: z_order")
+
+assert(z_order({}) == nil, "test failed: no tags")
+assert(z_order({foo="bar"}) == nil, "test failed: other tags")
+assert(z_order({highway="motorway"}) == 380 , "test failed: motorway")
+assert(z_order({highway="motorway", railway="rail"}) == 440 , "test failed: motorway + rail")
+
+print("TESTING: roads")
+assert(roads({}) == 0, "test failed: no tags")
+assert(roads({foo="bar"}) == 0, "test failed: other tags")
+assert(roads({highway="motorway"}) == 1, "test failed: motorway")
+assert(roads({railway="rail"}) == 1, "test failed: rail")
+assert(roads({highway="residential", railway="rail"}) == 1, "test failed: rail+residential")
+assert(roads({railway="turntable"}) == 0, "test failed: rail=turntable")
+assert(roads({railway="rail", service="spur"}) == 0, "test failed: rail SSY")
+assert(roads({railway="rail", service="main"}) == 1, "test failed: rail non-SSY")
+assert(roads({boundary="administrative"}) == 1, "test failed: boundary administrative")
+
+print("TESTING: isarea")
+assert(isarea({}) == 0, "test failed: no tags")
+assert(isarea({foo = "bar"}) == 0, "test failed: random tag")
+assert(isarea({area = "yes"}) == 1, "test failed: explicit area")
+assert(isarea({area = "no"}) == 0, "test failed: explicit not area")
+assert(isarea({area = "no", landuse = "forest"}) == 0, "test failed: explicit not area with polygon tag")
+assert(isarea({leisure = "track"}) == 0, "test failed: leisure=track")
+assert(isarea({area = "yes", leisure = "track"}) == 1, "test failed: leisure=track with area tag")
+assert(isarea({waterway = "river"}) == 0, "test failed: river")
+assert(isarea({waterway = "riverbank"}) == 1, "test failed: river")
+assert(isarea({highway = "services"}) == 1, "test failed: river")
+
+print("TESTING: filter_tags_generic")
+assert(({filter_tags_generic({})})[1] == 1, "Untagged filter")
+assert(equaltables(({filter_tags_generic({})})[2], {}), "Untagged tags")
+assert(({filter_tags_generic({note="foo"})})[1] == 1, "deleted filter")
+assert(equaltables(({filter_tags_generic({note="foo"})})[2], {}), "deleted tags")
+assert(({filter_tags_generic({foo="bar"})})[1] == 0, "single tag filter")
+assert(equaltables(({filter_tags_generic({foo="bar"})})[2], {foo="bar"}), "single tag tags")
+assert(({filter_tags_generic({foo="bar", note="baz"})})[1] == 0, "tag + deleted tag filter")
+assert(equaltables(({filter_tags_generic({foo="bar", note="baz"})})[2], {foo="bar"}), "tag + deleted tags")
+assert(({filter_tags_generic({["note:xx"]="foo"})})[1] == 1, "wildcard deleted filter")
+assert(equaltables(({filter_tags_generic({["note:xx"]="foo"})})[2], {}), "wildcard deleted tags")
+assert(({filter_tags_generic({["note:xx"]="foo", foo="bar"})})[1] == 0, "wildcard deleted + tag filter")
+assert(equaltables(({filter_tags_generic({["note:xx"]="foo", foo="bar"})})[2], {foo="bar"}), "wildcard deleted + tag tags")
+
+assert(({filter_tags_generic({["foo:note:xx"]="foo"})})[1] == 0, "prefix later in tag filter")
+assert(equaltables(({filter_tags_generic({["foo:note:xx"]="foo"})})[2], {["foo:note:xx"]="foo"}), "prefix later in tag tags")
+
+print("TESTING: filter_tags_relation_member")
+
+--- Tests filter_tags_relation_member against expected values
+-- @param keyvalues OSM tags, after processing by relation transform
+-- @param keyvaluemembers OSM tags of relation members, after processing by way transform
+-- @param filter expected filter result
+-- @param cols expected cols result
+-- @param member_superseded expected member_superseded result
+-- @param boundary expected boundary result
+-- @param polygon expected polygon result
+-- @param roads expected roads result
+local function check_rel_member(keyvalues, keyvaluemembers, filter, cols, member_superseded, boundary, polygon, roads)
+
+ local i = 0
+ for _ in pairs(keyvaluemembers) do
+ i = i + 1
+ end
+
+ local actual_filter, actual_cols, actual_member_superseded, actual_boundary, actual_polygon, actual_roads
+ = filter_tags_relation_member(keyvalues, keyvaluemembers, nil, i)
+
+ if actual_filter ~= filter then
+ print("filter mismatch")
+ return false
+ end
+ if not equaltables(actual_cols, cols) then
+ print("cols mismatch")
+ return false
+ end
+ if not equaltables(actual_member_superseded, member_superseded) then
+ print("member_superseded mismatch, actual table was")
+ for i, v in ipairs(actual_member_superseded) do
+ print(i, v)
+ end
+ return false
+ end
+ if actual_boundary ~= boundary then
+ print("boundary mismatch")
+ return false
+ end
+ if actual_polygon ~= polygon then
+ print("polygon mismatch")
+ return false
+ end
+ if actual_roads ~= roads then
+ print("roads mismatch")
+ return false
+ end
+ return true
+end
+
+assert(check_rel_member({}, {}, 1, {}, {}, 0, 0, 0), "test failed: untagged memberless relation")
+assert(check_rel_member({}, {{}}, 1, {}, {0}, 0, 0, 0), "test failed: untagged relation")
+
+assert(check_rel_member({type="multipolygon"}, {{}}, 1, {}, {0}, 0, 0, 0),
+ "test failed: untagged MP")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{}}, 0, {foo="bar"}, {0}, 0, 1, 0),
+ "test failed: MP with tag")
+
+-- New-style MPs
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{},{}}, 0, {foo="bar"}, {0,0}, 0, 1, 0),
+ "test failed: MP with tag, two ways")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{baz="qax"}}, 0, {foo="bar"}, {0}, 0, 1, 0),
+ "test failed: MP with tag, way with different tag")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{baz="qax"}, {}}, 0, {foo="bar"}, {0,0}, 0, 1, 0),
+ "test failed: MP with tag, way with different tag + untagged way")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{foo="bar"}}, 0, {foo="bar"}, {0}, 0, 1, 0),
+ "test failed: MP with tag, way with same tag")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{foo="bar"},{}}, 0, {foo="bar"}, {0,0}, 0, 1, 0),
+ "test failed: MP with tag, way with same tag + untagged way")
+assert(check_rel_member({type="multipolygon", foo="bar"}, {{foo="bar"}, {baz="qax"}}, 0, {foo="bar"}, {0,0}, 0, 1, 0),
+ "test failed: MP with tag, way with same tag")
+
+-- Old-style MPs
+assert(check_rel_member({type="multipolygon"}, {{foo="bar"}}, 1, {}, {0}, 0, 0, 0),
+ "test failed: MP w/o tag, way with tag")
+assert(check_rel_member({type="multipolygon"}, {{foo="bar"}, {}}, 1, {}, {0,0}, 0, 0, 0),
+ "test failed: MP w/o tag, way with tag + untagged way")
+assert(check_rel_member({type="multipolygon"}, {{foo="bar"}, {baz="qax"}}, 1, {}, {0,0}, 0, 0, 0),
+ "test failed: MP w/o tag, way with tag + way with other tag")
+
+-- Boundary relations
+assert(check_rel_member({type="boundary"}, {{}}, 1, {}, {0}, 0, 0, 0),
+ "test failed: untagged boundary")
+assert(check_rel_member({type="boundary", boundary="administrative"}, {{}}, 0, {boundary="administrative"}, {0}, 1, 0, 1),
+ "test failed: untagged boundary")
+assert(check_rel_member({type="boundary", boundary="administrative"}, {{}}, 0, {boundary="administrative"}, {0}, 1, 0, 1),
+ "test failed: untagged boundary")
+assert(check_rel_member({type="boundary", boundary="administrative"}, {{foo="bar"}}, 0, {boundary="administrative"}, {0}, 1, 0, 1),
+ "test failed: untagged boundary, tagged way")
+
+-- Route relations
+assert(check_rel_member({type="route"}, {{}}, 1, {}, {0}, 0, 0, 0),
+ "test failed: untagged route")
+assert(check_rel_member({type="route", route="road"}, {{}}, 0, {route="road"}, {0}, 1, 0, 0),
+ "test failed: tagged route")
diff --git a/water.mss b/water.mss
index 456b698..3a766df 100644
--- a/water.mss
+++ b/water.mss
@@ -103,10 +103,6 @@
background/line-cap: round;
background/line-join: round;
}
- water/line-color: @water-color;
- water/line-width: 2;
- water/line-cap: round;
- water/line-join: round;
[bridge = 'yes'] {
[zoom >= 14] {
@@ -119,6 +115,11 @@
}
}
+ water/line-color: @water-color;
+ water/line-width: 2;
+ water/line-cap: round;
+ water/line-join: round;
+
[intermittent = 'yes'],
[waterway = 'wadi'] {
[bridge = 'yes'][zoom >= 14] {
@@ -192,9 +193,6 @@
water/line-cap: butt;
water/line-join: round;
water/line-clip: false;
- background/line-cap: butt;
- background/line-join: round;
- background/line-clip: false;
}
[waterway = 'stream'][zoom >= 15] {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/openstreetmap-carto.git
More information about the Pkg-grass-devel
mailing list