diff --git a/layers/aerodrome_label/aerodrome_label.yaml b/layers/aerodrome_label/aerodrome_label.yaml
index 17b0fbe5..0be152dd 100644
--- a/layers/aerodrome_label/aerodrome_label.yaml
+++ b/layers/aerodrome_label/aerodrome_label.yaml
@@ -15,12 +15,23 @@ layer:
           [`aerodrome`](http://wiki.openstreetmap.org/wiki/Proposed_features/Aerodrome)
           and `aerodrome:type` tags.
       values:
-      - international
-      - public
-      - regional
-      - military
-      - private
-      - other
+        international:
+          aerodrome: 'international'
+          aerodrome_type: 'international'
+        public:
+          aerodrome: 'public'
+          aerodrome_type: ['%public%', 'civil']
+        regional:
+          aerodrome: 'regional'
+          aerodrome_type: 'regional'
+        military:
+          aerodrome: 'military'
+          aerodrome_type: '%military%'
+          military: 'airfield'
+        private:
+          aerodrome: 'private'
+          aerodrome_type: 'private'
+        other:
     iata: 3-character code issued by the IATA.
     icao: 4-letter code issued by the ICAO.
     ele: Elevation (`ele`) in meters.
diff --git a/layers/aerodrome_label/layer.sql b/layers/aerodrome_label/layer.sql
index 8d5adfa1..4e91cc26 100644
--- a/layers/aerodrome_label/layer.sql
+++ b/layers/aerodrome_label/layer.sql
@@ -27,27 +27,7 @@ $$
     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'
+      %%FIELD_MAPPING: class %%
       ELSE 'other'
     END AS class,
     NULLIF(iata, '') AS iata,
diff --git a/layers/landcover/landcover.sql b/layers/landcover/landcover.sql
index 6d64b9aa..6b1f602c 100644
--- a/layers/landcover/landcover.sql
+++ b/layers/landcover/landcover.sql
@@ -11,15 +11,7 @@
 
 CREATE OR REPLACE FUNCTION landcover_class(subclass VARCHAR) RETURNS TEXT AS $$
     SELECT CASE
-        WHEN subclass IN ('farmland', 'farm', 'orchard', 'vineyard', 'plant_nursery') THEN 'farmland'
-        WHEN subclass IN ('glacier', 'ice_shelf') THEN 'ice'
-        WHEN subclass IN ('wood', 'forest') THEN 'wood'
-        WHEN subclass IN ('bare_rock', 'scree') THEN 'rock'
-        WHEN subclass IN ('fell', 'grassland', 'heath', 'scrub', 'tundra', 'grass', 'meadow', 'allotments',
-                          'park', 'village_green', 'recreation_ground', 'garden', 'golf_course') THEN 'grass'
-        WHEN subclass IN ('wetland', 'bog', 'swamp', 'wet_meadow', 'marsh', 'reedbed',
-                          'saltern', 'tidalflat', 'saltmarsh', 'mangrove') THEN 'wetland'
-        WHEN subclass IN ('beach', 'sand', 'dune') THEN 'sand'
+        %%FIELD_MAPPING: class %%
         ELSE NULL
     END;
 $$ LANGUAGE SQL IMMUTABLE;
diff --git a/layers/landcover/landcover.yaml b/layers/landcover/landcover.yaml
index 09e4e26f..6d51fe4f 100644
--- a/layers/landcover/landcover.yaml
+++ b/layers/landcover/landcover.yaml
@@ -10,12 +10,20 @@ layer:
       description: |
           Use the **class** to assign natural colors for **landcover**.
       values:
-      - farmland
-      - ice
-      - wood
-      - grass
-      - wetland
-      - sand
+        farmland:
+          subclass: ['farmland', 'farm', 'orchard', 'vineyard', 'plant_nursery']
+        ice:
+          subclass: ['glacier', 'ice_shelf']
+        wood:
+          subclass: ['wood', 'forest']
+        rock:
+          subclass: ['bare_rock', 'scree']
+        grass:
+          subclass: ['fell', 'grassland', 'heath', 'scrub', 'tundra', 'grass', 'meadow', 'allotments', 'park', 'village_green', 'recreation_ground', 'garden', 'golf_course']
+        wetland:
+          subclass: ['wetland', 'bog', 'swamp', 'wet_meadow', 'marsh', 'reedbed', 'saltern', 'tidalflat', 'saltmarsh', 'mangrove']
+        sand:
+          subclass: ['beach', 'sand', 'dune']
     subclass:
       description: |
           Use **subclass** to do more precise styling.
diff --git a/layers/poi/class.sql b/layers/poi/class.sql
index c991d228..c81573ab 100644
--- a/layers/poi/class.sql
+++ b/layers/poi/class.sql
@@ -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;
diff --git a/layers/poi/poi.yaml b/layers/poi/poi.yaml
index bd662857..8ed707d1 100644
--- a/layers/poi/poi.yaml
+++ b/layers/poi/poi.yaml
@@ -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
diff --git a/layers/transportation/class.sql b/layers/transportation/class.sql
index 187b5f81..9f95412f 100644
--- a/layers/transportation/class.sql
+++ b/layers/transportation/class.sql
@@ -11,23 +11,19 @@ $$ LANGUAGE SQL IMMUTABLE STRICT;
 -- https://github.com/ClearTables/ClearTables/blob/master/transportation.lua
 CREATE OR REPLACE FUNCTION highway_class(highway TEXT, public_transport TEXT, construction TEXT) RETURNS TEXT AS $$
     SELECT CASE
-        WHEN highway IN ('motorway', 'motorway_link') THEN 'motorway'
-        WHEN highway IN ('trunk', 'trunk_link') THEN 'trunk'
-        WHEN highway IN ('primary', 'primary_link') THEN 'primary'
-        WHEN highway IN ('secondary', 'secondary_link') THEN 'secondary'
-        WHEN highway IN ('tertiary', 'tertiary_link') THEN 'tertiary'
-        WHEN highway IN ('unclassified', 'residential', 'living_street', 'road') THEN 'minor'
-        WHEN highway IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor') OR public_transport IN ('platform') THEN 'path'
-        WHEN highway IN ('service', 'track', 'raceway') THEN highway
+        %%FIELD_MAPPING: class %%
         WHEN highway = 'construction' THEN CASE
           WHEN construction IN ('motorway', 'motorway_link') THEN 'motorway_construction'
           WHEN construction IN ('trunk', 'trunk_link') THEN 'trunk_construction'
           WHEN construction IN ('primary', 'primary_link') THEN 'primary_construction'
           WHEN construction IN ('secondary', 'secondary_link') THEN 'secondary_construction'
           WHEN construction IN ('tertiary', 'tertiary_link') THEN 'tertiary_construction'
-          WHEN construction = '' OR construction IN ('unclassified', 'residential', 'living_street', 'road') THEN 'minor_construction'
-          WHEN construction IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor') OR public_transport IN ('platform') THEN 'path_construction'
-          WHEN construction IN ('service', 'track', 'raceway') THEN CONCAT(highway, '_construction')
+          WHEN construction IN ('', 'unclassified', 'residential', 'living_street', 'road') THEN 'minor_construction'
+          WHEN construction IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor')
+              OR public_transport = 'platform' THEN 'path_construction'
+          WHEN construction = 'service' THEN 'service_construction'
+          WHEN construction = 'track' THEN 'track_construction'
+          WHEN construction = 'raceway' THEN 'raceway_construction'
           ELSE NULL
         END
         ELSE NULL
diff --git a/layers/transportation/transportation.yaml b/layers/transportation/transportation.yaml
index b92f6504..f4da3c34 100644
--- a/layers/transportation/transportation.yaml
+++ b/layers/transportation/transportation.yaml
@@ -24,33 +24,37 @@ layer:
           shipping ways), or
           [`man_made`](http://wiki.openstreetmap.org/wiki/Key:route).
       values:
-      - motorway
-      - trunk
-      - primary
-      - secondary
-      - tertiary
-      - minor
-      - service
-      - track
-      - path
-      - raceway
-      - motorway_construction
-      - trunk_construction
-      - primary_construction
-      - secondary_construction
-      - tertiary_construction
-      - minor_construction
-      - service_construction
-      - track_construction
-      - path_construction
-      - raceway_construction
-      - rail
-      - transit
-      - cable_car
-      - gondola
-      - ferry
-      - bridge
-      - pier
+        motorway:
+          highway: ['motorway', 'motorway_link']
+        trunk:
+          highway: ['trunk', 'trunk_link']
+        primary:
+          highway: ['primary', 'primary_link']
+        secondary:
+          highway: ['secondary', 'secondary_link']
+        tertiary:
+          highway: ['tertiary', 'tertiary_link']
+        minor:
+          highway: ['unclassified', 'residential', 'living_street', 'road']
+        path:
+          highway: ['pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor']
+          public_transport: 'platform'
+        service:
+          highway: service
+        track:
+          highway: track
+        raceway:
+          highway: raceway
+        motorway_construction:
+        trunk_construction:
+        primary_construction:
+        secondary_construction:
+        tertiary_construction:
+        minor_construction:
+        path_construction:
+        service_construction:
+        track_construction:
+        raceway_construction:
     subclass:
       description: |
           Distinguish more specific classes of railway and path:
diff --git a/layers/water/water.sql b/layers/water/water.sql
index a7ca1f6b..3f3a9c60 100644
--- a/layers/water/water.sql
+++ b/layers/water/water.sql
@@ -1,8 +1,6 @@
 CREATE OR REPLACE FUNCTION water_class(waterway TEXT) RETURNS TEXT AS $$
     SELECT CASE
-           WHEN waterway='' THEN 'lake'
-           WHEN waterway='lake' THEN 'lake'
-           WHEN waterway='dock' THEN 'dock'
+           %%FIELD_MAPPING: class %%
            ELSE 'river'
    END;
 $$ LANGUAGE SQL IMMUTABLE;
diff --git a/layers/water/water.yaml b/layers/water/water.yaml
index 2e77b7b9..24ecabe5 100644
--- a/layers/water/water.yaml
+++ b/layers/water/water.yaml
@@ -14,9 +14,12 @@ layer:
           All water polygons from [OpenStreetMapData](http://osmdata.openstreetmap.de/) have the class `ocean`.
           Water bodies are classified as `lake` or `river` for water bodies with the [`waterway`](http://wiki.openstreetmap.org/wiki/Key:waterway) tag.
       values:
-      - ocean
-      - lake
-      - river
+        lake:
+          waterway: ['', 'lake']
+        dock:
+          waterway: 'dock'
+        river:
+        ocean:
     intermittent:
       description: |
         Mark with `1` if it is an [intermittent](http://wiki.openstreetmap.org/wiki/Key:intermittent) water polygon.