Manage field mapping in SQL declaratively

Simplify some of the OSM->OMT field value mappings using declarative syntax.

This approach is not for all cases, but in many it removes
the need of storing the same field in both the .yaml and .sql files.

TODO: support more complex AND/OR cases
This commit is contained in:
Yuri Astrakhan
2019-10-26 04:28:51 -04:00
parent f3667170f6
commit 1614a4656c
10 changed files with 156 additions and 120 deletions

View File

@@ -30,39 +30,10 @@ $$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION poi_class(subclass TEXT, mapping_key TEXT)
RETURNS TEXT AS $$
SELECT CASE
WHEN subclass IN ('accessories','antiques','beauty','bed','boutique','camera','carpet','charity','chemist','coffee','computer','convenience','copyshop','cosmetics','garden_centre','doityourself','erotic','electronics','fabric','florist','frozen_food','furniture','video_games','video','general','gift','hardware','hearing_aids','hifi','ice_cream','interior_decoration','jewelry','kiosk','lamps','mall','massage','motorcycle','mobile_phone','newsagent','optician','outdoor','perfumery','perfume','pet','photo','second_hand','shoes','sports','stationery','tailor','tattoo','ticket','tobacco','toys','travel_agency','watches','weapons','wholesale') THEN 'shop'
WHEN subclass IN ('townhall','public_building','courthouse','community_centre') THEN 'town_hall'
WHEN subclass IN ('golf','golf_course','miniature_golf') THEN 'golf'
WHEN subclass IN ('fast_food','food_court') THEN 'fast_food'
WHEN subclass IN ('park','bbq') THEN 'park'
WHEN subclass IN ('bus_stop','bus_station') THEN 'bus'
WHEN (subclass='station' AND mapping_key = 'railway') OR subclass IN ('halt', 'tram_stop', 'subway') THEN 'railway'
WHEN (subclass='station' AND mapping_key = 'aerialway') THEN 'aerialway'
WHEN subclass IN ('subway_entrance','train_station_entrance') THEN 'entrance'
WHEN subclass IN ('camp_site','caravan_site') THEN 'campsite'
WHEN subclass IN ('laundry','dry_cleaning') THEN 'laundry'
WHEN subclass IN ('supermarket','deli','delicatessen','department_store','greengrocer','marketplace') THEN 'grocery'
WHEN subclass IN ('books','library') THEN 'library'
WHEN subclass IN ('university','college') THEN 'college'
WHEN subclass IN ('hotel','motel','bed_and_breakfast','guest_house','hostel','chalet','alpine_hut','dormitory') THEN 'lodging'
WHEN subclass IN ('chocolate','confectionery') THEN 'ice_cream'
WHEN subclass IN ('post_box','post_office') THEN 'post'
WHEN subclass IN ('cafe') THEN 'cafe'
WHEN subclass IN ('school','kindergarten') THEN 'school'
WHEN subclass IN ('alcohol','beverages','wine') THEN 'alcohol_shop'
WHEN subclass IN ('bar','nightclub') THEN 'bar'
WHEN subclass IN ('marina','dock') THEN 'harbor'
WHEN subclass IN ('car','car_repair','taxi') THEN 'car'
WHEN subclass IN ('hospital','nursing_home', 'clinic') THEN 'hospital'
WHEN subclass IN ('grave_yard','cemetery') THEN 'cemetery'
WHEN subclass IN ('attraction','viewpoint') THEN 'attraction'
WHEN subclass IN ('biergarten','pub') THEN 'beer'
WHEN subclass IN ('music','musical_instrument') THEN 'music'
WHEN subclass IN ('american_football','stadium','soccer') THEN 'stadium'
WHEN subclass IN ('art','artwork','gallery','arts_centre') THEN 'art_gallery'
WHEN subclass IN ('bag','clothes') THEN 'clothing_store'
WHEN subclass IN ('swimming_area','swimming') THEN 'swimming'
WHEN subclass IN ('castle','ruins') THEN 'castle'
%%FIELD_MAPPING: class %%
WHEN (subclass = 'station' AND mapping_key = 'railway')
OR (subclass IN ('halt', 'tram_stop', 'subway')) THEN 'railway'
WHEN (subclass = 'station' AND mapping_key = 'aerialway') THEN 'aerialway'
ELSE subclass
END;
$$ LANGUAGE SQL IMMUTABLE;

View File

@@ -9,11 +9,84 @@ layer:
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the POI.
name_en: English name `name:en` if available, otherwise `name`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`.
class: |
class:
description: |
More general classes of POIs. If there is no more general `class` for the `subclass`
this field will contain the same value as `subclass`.
But for example for schools you only need to style the class `school` to filter the subclasses `school`
and `kindergarten`. Or use the class `shop` to style all shops.
values:
shop:
subclass: ['accessories', 'antiques', 'beauty', 'bed', 'boutique', 'camera', 'carpet', 'charity', 'chemist',
'coffee', 'computer', 'convenience', 'copyshop', 'cosmetics', 'garden_centre', 'doityourself',
'erotic', 'electronics', 'fabric', 'florist', 'frozen_food', 'furniture', 'video_games', 'video',
'general', 'gift', 'hardware', 'hearing_aids', 'hifi', 'ice_cream', 'interior_decoration',
'jewelry', 'kiosk', 'lamps', 'mall', 'massage', 'motorcycle', 'mobile_phone', 'newsagent',
'optician', 'outdoor', 'perfumery', 'perfume', 'pet', 'photo', 'second_hand', 'shoes', 'sports',
'stationery', 'tailor', 'tattoo', 'ticket', 'tobacco', 'toys', 'travel_agency', 'watches',
'weapons', 'wholesale']
town_hall:
subclass: ['townhall', 'public_building', 'courthouse', 'community_centre']
golf:
subclass: ['golf', 'golf_course', 'miniature_golf']
fast_food:
subclass: ['fast_food', 'food_court']
park:
subclass: ['park', 'bbq']
bus:
subclass: ['bus_stop', 'bus_station']
railway:
aerialway:
entrance:
subclass: ['subway_entrance', 'train_station_entrance']
campsite:
subclass: ['camp_site', 'caravan_site']
laundry:
subclass: ['laundry', 'dry_cleaning']
grocery:
subclass: ['supermarket', 'deli', 'delicatessen', 'department_store', 'greengrocer', 'marketplace']
library:
subclass: ['books', 'library']
college:
subclass: ['university', 'college']
lodging:
subclass: ['hotel', 'motel', 'bed_and_breakfast', 'guest_house', 'hostel', 'chalet', 'alpine_hut', 'dormitory']
ice_cream:
subclass: ['chocolate', 'confectionery']
post:
subclass: ['post_box', 'post_office']
cafe:
subclass: ['cafe']
school:
subclass: ['school', 'kindergarten']
alcohol_shop:
subclass: ['alcohol', 'beverages', 'wine']
bar:
subclass: ['bar', 'nightclub']
harbor:
subclass: ['marina', 'dock']
car:
subclass: ['car', 'car_repair', 'taxi']
hospital:
subclass: ['hospital', 'nursing_home', 'clinic']
cemetery:
subclass: ['grave_yard', 'cemetery']
attraction:
subclass: ['attraction', 'viewpoint']
beer:
subclass: ['biergarten', 'pub']
music:
subclass: ['music', 'musical_instrument']
stadium:
subclass: ['american_football', 'stadium', 'soccer']
art_gallery:
subclass: ['art', 'artwork', 'gallery', 'arts_centre']
clothing_store:
subclass: ['bag', 'clothes']
swimming:
subclass: ['swimming_area', 'swimming']
castle:
subclass: ['castle', 'ruins']
subclass:
description: |
Original value of either the