diff --git a/layers/aerodrome_label/README.md b/layers/aerodrome_label/README.md new file mode 100644 index 0000000..b9f7903 --- /dev/null +++ b/layers/aerodrome_label/README.md @@ -0,0 +1,7 @@ +## Aerodrome Labels + +### Mapping Diagram +![Mapping diagram for aerodrome labels](mapping_diagram.png?raw=true) + +### ETL diagram +![ETL diagram for aerodrome labels](etl_diagram.png?raw=true) diff --git a/layers/aerodrome_label/aerodrome_label.yaml b/layers/aerodrome_label/aerodrome_label.yaml new file mode 100644 index 0000000..4942723 --- /dev/null +++ b/layers/aerodrome_label/aerodrome_label.yaml @@ -0,0 +1,37 @@ +layer: + id: "aerodrome_label" + description: | + [Aerodrome labels](http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome) + buffer_size: 64 + 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 + fields: + name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the aerodrome. + name_en: English name `name:en` if available, otherwise `name`. + name_de: German name `name:de` if available, otherwise `name` or `name:en`. + class: + description: | + Distinguish between more and less important aerodromes. + Class is derived from the value of + [`aerodrome`](http://wiki.openstreetmap.org/wiki/Proposed_features/Aerodrome) + and `aerodrome:type` tags. + values: + - international + - public + - regional + - military + - private + - other + iata: 3-character code issued by the IATA. + icao: 4-letter code issued by the ICAO. + ele: Elevation (`ele`) in meters. + ele_ft: Elevation (`ele`) in feets. + datasource: + geometry_field: geometry + srid: 900913 + query: (SELECT osm_id, geometry, name, name_en, name_de, {name_languages}, class, iata, icao, ele, ele_ft FROM layer_aerodrome_label (!bbox!, z(!scale_denominator!), !pixel_width!)) AS t +schema: + - ./update.sql + - ./layer.sql +datasources: + - type: imposm3 + mapping_file: ./mapping.yaml diff --git a/layers/aerodrome_label/etl_diagram.png b/layers/aerodrome_label/etl_diagram.png new file mode 100644 index 0000000..3e30825 Binary files /dev/null and b/layers/aerodrome_label/etl_diagram.png differ diff --git a/layers/aerodrome_label/layer.sql b/layers/aerodrome_label/layer.sql new file mode 100644 index 0000000..8d5adfa --- /dev/null +++ b/layers/aerodrome_label/layer.sql @@ -0,0 +1,60 @@ + +-- etldoc: layer_aerodrome_label[shape=record fillcolor=lightpink, style="rounded,filled", label="layer_aerodrome_label | z10+" ] ; + +CREATE OR REPLACE FUNCTION layer_aerodrome_label( + bbox geometry, + zoom_level integer, + pixel_width numeric) + RETURNS TABLE( + osm_id bigint, + geometry geometry, + name text, + name_en text, + name_de text, + tags hstore, + class text, + iata text, + icao text, + ele int, + ele_ft int) AS +$$ + -- etldoc: osm_aerodrome_label_point -> layer_aerodrome_label:z10_ + SELECT + osm_id, + geometry, + name, + COALESCE(NULLIF(name_en, ''), name) AS name_en, + COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de, + tags, + CASE + WHEN aerodrome = 'international' + OR aerodrome_type = 'international' + THEN 'international' + WHEN + aerodrome = 'public' + OR aerodrome_type LIKE '%public%' + OR aerodrome_type = 'civil' + THEN 'public' + WHEN + aerodrome = 'regional' + OR aerodrome_type = 'regional' + THEN 'regional' + WHEN + aerodrome = 'military' + OR aerodrome_type LIKE '%military%' + OR military = 'airfield' + THEN 'military' + WHEN + aerodrome = 'private' + OR aerodrome_type = 'private' + THEN 'private' + ELSE 'other' + END AS class, + NULLIF(iata, '') AS iata, + NULLIF(icao, '') AS icao, + substring(ele from E'^(-?\\d+)(\\D|$)')::int AS ele, + round(substring(ele from E'^(-?\\d+)(\\D|$)')::int*3.2808399)::int AS ele_ft + FROM osm_aerodrome_label_point + WHERE geometry && bbox AND zoom_level >= 10; + +$$ LANGUAGE SQL IMMUTABLE; diff --git a/layers/aerodrome_label/mapping.yaml b/layers/aerodrome_label/mapping.yaml new file mode 100644 index 0000000..46cdb71 --- /dev/null +++ b/layers/aerodrome_label/mapping.yaml @@ -0,0 +1,46 @@ +tables: + + # etldoc: imposm3 -> osm_aerodrome_label_point + aerodrome_label_point: + type: geometry + fields: + - name: osm_id + type: id + - name: geometry + type: geometry + - name: name + key: name + type: string + - name: name_en + key: name:en + type: string + - name: name_de + key: name:de + type: string + - name: tags + type: hstore_tags + - name: aerodrome_type + key: aerodrome:type + type: string + - name: aerodrome + key: aerodrome + type: string + - name: military + key: military + type: string + - name: iata + key: iata + type: string + - name: icao + key: icao + type: string + - name: ele + key: ele + type: string + type_mappings: + points: + aeroway: + - aerodrome + polygons: + aeroway: + - aerodrome diff --git a/layers/aerodrome_label/mapping_diagram.png b/layers/aerodrome_label/mapping_diagram.png new file mode 100644 index 0000000..bcaf83a Binary files /dev/null and b/layers/aerodrome_label/mapping_diagram.png differ diff --git a/layers/aerodrome_label/update.sql b/layers/aerodrome_label/update.sql new file mode 100644 index 0000000..79c6e3d --- /dev/null +++ b/layers/aerodrome_label/update.sql @@ -0,0 +1,51 @@ +DROP TRIGGER IF EXISTS trigger_flag ON osm_aerodrome_label_point; +DROP TRIGGER IF EXISTS trigger_refresh ON aerodrome_label.updates; + +-- etldoc: osm_aerodrome_label_point -> osm_aerodrome_label_point +CREATE OR REPLACE FUNCTION update_aerodrome_label_point() RETURNS VOID AS $$ +BEGIN + UPDATE osm_aerodrome_label_point + SET geometry = ST_Centroid(geometry) + WHERE ST_GeometryType(geometry) <> 'ST_Point'; + + UPDATE osm_aerodrome_label_point + SET tags = slice_language_tags(tags) || get_basic_names(tags, geometry) + WHERE COALESCE(tags->'name:latin', tags->'name:nonlatin', tags->'name_int') IS NULL; +END; +$$ LANGUAGE plpgsql; + +SELECT update_aerodrome_label_point(); + +-- Handle updates + +CREATE SCHEMA IF NOT EXISTS aerodrome_label; + +CREATE TABLE IF NOT EXISTS aerodrome_label.updates(id serial primary key, t text, unique (t)); +CREATE OR REPLACE FUNCTION aerodrome_label.flag() RETURNS trigger AS $$ +BEGIN + INSERT INTO aerodrome_label.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING; + RETURN null; +END; +$$ language plpgsql; + +CREATE OR REPLACE FUNCTION aerodrome_label.refresh() RETURNS trigger AS + $BODY$ + BEGIN + RAISE LOG 'Refresh aerodrome_label'; + PERFORM update_aerodrome_label_point(); + DELETE FROM aerodrome_label.updates; + RETURN null; + END; + $BODY$ +language plpgsql; + +CREATE TRIGGER trigger_flag + AFTER INSERT OR UPDATE OR DELETE ON osm_aerodrome_label_point + FOR EACH STATEMENT + EXECUTE PROCEDURE aerodrome_label.flag(); + +CREATE CONSTRAINT TRIGGER trigger_refresh + AFTER INSERT ON aerodrome_label.updates + INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE aerodrome_label.refresh(); diff --git a/openmaptiles.yaml b/openmaptiles.yaml index 326f39f..9996d07 100644 --- a/openmaptiles.yaml +++ b/openmaptiles.yaml @@ -15,6 +15,7 @@ tileset: - layers/place/place.yaml - layers/housenumber/housenumber.yaml - layers/poi/poi.yaml + - layers/aerodrome_label/aerodrome_label.yaml name: OpenMapTiles version: 3.3.0 id: openmaptiles