This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git


The following commit(s) were added to refs/heads/main by this push:
     new f085bc79 Improve highway layers and fix issues related to basemap 
(#819)
f085bc79 is described below

commit f085bc796df2261332dba987bfb65d486fe9763a
Author: Bertil Chapuis <[email protected]>
AuthorDate: Fri Jan 5 14:58:29 2024 +0100

    Improve highway layers and fix issues related to basemap (#819)
    
    * Clean unused file and fix trunk width
    
    * Improve highways by interpolating line width
    
    * Simplify waterways and interpolate line width
    
    * Move tracks in the leisure overlay
    
    * Generalize the use of geometry-type filters
    
    * Add bridge and tunnels for minor roads
    
    * Recursively register the watch service to make it work with deep 
directory structures
---
 .../openstreetmap/function/WayGeometryBuilder.java |   1 +
 .../org/apache/baremaps/server/ChangeResource.java |  23 ++-
 .../layers/{route/style.js => aerialway/line.js}   |  13 +-
 basemap/layers/aeroway/{polygon.js => fill.js}     |   2 +-
 basemap/layers/aeroway/line.js                     |  10 +-
 basemap/layers/amenity/background.js               |   5 +-
 basemap/layers/amenity/fountain.js                 |   1 +
 basemap/layers/amenity/overlay.js                  |   1 +
 basemap/layers/boundary/line.js                    |   1 +
 basemap/layers/building/extrusion.js               |   1 +
 basemap/layers/building/{shape.js => fill.js}      |   6 +-
 basemap/layers/highway/bridge_line.js              |  90 ++++++++--
 basemap/layers/highway/bridge_outline.js           |  47 ++---
 basemap/layers/highway/construction_dash.js        | 115 ------------
 basemap/layers/highway/construction_line.js        |  30 ++--
 basemap/layers/highway/highway_dash.js             | 103 -----------
 .../{pedestrian_area.js => highway_fill.js}        |   2 +-
 basemap/layers/highway/highway_line.js             | 115 ++++++++----
 basemap/layers/highway/highway_outline.js          |  56 +++---
 basemap/layers/highway/tunnel_line.js              |  90 ++++++++--
 basemap/layers/highway/tunnel_outline.js           |  50 +++---
 basemap/layers/landuse/background.js               |   1 +
 basemap/layers/landuse/overlay.js                  |   1 +
 basemap/layers/leisure/background.js               |   6 +-
 basemap/layers/leisure/nature_reserve.js           |  38 ----
 basemap/layers/leisure/overlay.js                  |   6 +
 basemap/layers/man_made/bridge.js                  |   1 +
 basemap/layers/man_made/pier_line.js               |   6 +-
 basemap/layers/natural/background.js               |   1 +
 basemap/layers/natural/overlay.js                  |   1 +
 basemap/layers/natural/tree.js                     |   4 +-
 basemap/layers/natural/trunk.js                    |   2 +-
 basemap/layers/natural/water.js                    |  37 ----
 basemap/layers/power/background.js                 |   2 +-
 basemap/layers/power/cable.js                      |  12 +-
 basemap/layers/railway/line.js                     |  31 ++--
 basemap/layers/railway/prepare.sql                 |   2 +-
 basemap/layers/railway/tunnel.js                   |   5 +-
 basemap/layers/route/prepare.sql                   |   2 +-
 basemap/layers/route/style.js                      |   1 +
 .../{aerialway/style.js => waterway/area.js}       |  12 +-
 basemap/layers/waterway/line.js                    |  42 ++---
 basemap/layers/waterway/tunnel_casing.js           |  41 -----
 basemap/layers/waterway/tunnel_line.js             |  44 -----
 basemap/style.js                                   |  25 +--
 basemap/themes/default.js                          |  72 +++++---
 basemap/utils/layer.js                             | 195 ---------------------
 basemap/utils/utils.js                             |  78 ++++++++-
 48 files changed, 582 insertions(+), 848 deletions(-)

diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/function/WayGeometryBuilder.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/function/WayGeometryBuilder.java
index 8639d33d..a3d5e740 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/function/WayGeometryBuilder.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/function/WayGeometryBuilder.java
@@ -71,6 +71,7 @@ public class WayGeometryBuilder implements Consumer<Way> {
         // Ways can be open or closed depending on the geometry or the tags:
         // https://wiki.openstreetmap.org/wiki/Way
         if (!line.isClosed()
+            || way.getTags().containsKey("railway")
             || way.getTags().containsKey("highway")
             || way.getTags().containsKey("barrier")) {
           way.setGeometry(line);
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
index 9efe9c03..0b714edb 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
@@ -104,10 +104,10 @@ public class ChangeResource {
     public void run() {
       try (WatchService watchService = 
FileSystems.getDefault().newWatchService()) {
         if (tileset != null && Files.exists(tileset)) {
-          tileset.toAbsolutePath().getParent().register(watchService, 
ENTRY_MODIFY);
+          registerRecursively(tileset.toAbsolutePath().getParent(), 
watchService);
         }
         if (style != null && Files.exists(style)) {
-          style.toAbsolutePath().getParent().register(watchService, 
ENTRY_MODIFY);
+          registerRecursively(style.toAbsolutePath().getParent(), 
watchService);
         }
         WatchKey key;
         while ((key = watchService.take()) != null) {
@@ -137,5 +137,24 @@ public class ChangeResource {
         Thread.currentThread().interrupt();
       }
     }
+
+    /**
+     * Registers a directory and its sub-directories with the watch service.
+     *
+     * @param directory the directory
+     * @param watchService the watch service
+     * @throws IOException
+     */
+    private void registerRecursively(Path directory, WatchService 
watchService) throws IOException {
+      try (var directories = Files.walk(directory)) {
+        directories.filter(Files::isDirectory).forEach(path -> {
+          try {
+            path.register(watchService, ENTRY_MODIFY);
+          } catch (IOException e) {
+            logger.error(e.getMessage());
+          }
+        });
+      }
+    }
   }
 }
diff --git a/basemap/layers/route/style.js b/basemap/layers/aerialway/line.js
similarity index 77%
copy from basemap/layers/route/style.js
copy to basemap/layers/aerialway/line.js
index 621b2d7c..0431d909 100644
--- a/basemap/layers/route/style.js
+++ b/basemap/layers/aerialway/line.js
@@ -14,26 +14,27 @@
  See the License for the specific language governing permissions and
  limitations under the License.
  **/
-import {asLayerObject, withSortKeys} from "../../utils/utils.js";
 import theme from "../../theme.js";
+import {asLayerObject, withSortKeys} from "../../utils/utils";
 
 
 let directives = [
     {
-        filter: ['==', ['get', 'route'], 'ferry'],
-        'line-color': theme.routeStyleFerryLineColor,
-        'line-width': 1
+        filter: ['==', ["geometry-type"], 'LineString'],
+        'line-color': theme.aerialwayLineColor,
+        'line-width': 1,
     },
 ];
 
 export default asLayerObject(withSortKeys(directives), {
-    id: 'route_ferry',
+    id: 'aerialway_line',
     type: 'line',
     source: 'baremaps',
-    'source-layer': 'route',
+    'source-layer': 'aerialway',
     layout: {
         'line-cap': 'round',
         'line-join': 'round',
         visibility: 'visible',
     },
+    filter: ['==', ['geometry-type'], 'LineString'],
 });
diff --git a/basemap/layers/aeroway/polygon.js b/basemap/layers/aeroway/fill.js
similarity index 95%
rename from basemap/layers/aeroway/polygon.js
rename to basemap/layers/aeroway/fill.js
index c5243521..251ce58d 100644
--- a/basemap/layers/aeroway/polygon.js
+++ b/basemap/layers/aeroway/fill.js
@@ -20,7 +20,7 @@ import theme from "../../theme.js";
 let directives = [
     {
         filter: ['==', ['geometry-type'], 'Polygon'],
-        'fill-color': theme.aerowayPolygonLineColor,
+        'fill-color': theme.aerowayPolygonColor,
     },
 ];
 
diff --git a/basemap/layers/aeroway/line.js b/basemap/layers/aeroway/line.js
index db2103ee..21c4e812 100644
--- a/basemap/layers/aeroway/line.js
+++ b/basemap/layers/aeroway/line.js
@@ -21,14 +21,14 @@ import theme from "../../theme.js";
 let directives = [
     {
         'filter': ['==', ['get', 'aeroway'], 'runway'],
-        'line-color': theme.aerowayLineRunwayLineColor,
-        'road-width': 30,
+        'line-color': theme.aerowayRunwayLineColor,
+        'line-width': 1,
     },
     {
 
         'filter': ['==', ['get', 'aeroway'], 'taxiway'],
-        'line-color': theme.aerowayLineTaxiwayLineColor,
-        'road-width': 14,
+        'line-color': theme.aerowayTaxiwayLineColor,
+        'line-width': 1,
     },
 ];
 
@@ -37,10 +37,10 @@ export default asLayerObject(withSortKeys(directives), {
     type: 'line',
     source: 'baremaps',
     'source-layer': 'aeroway',
-    filter: ['==', ['geometry-type'], 'LineString'],
     layout: {
         'line-cap': 'round',
         'line-join': 'round',
         visibility: 'visible',
     },
+    filter: ['==', ['geometry-type'], 'LineString'],
 });
diff --git a/basemap/layers/amenity/background.js 
b/basemap/layers/amenity/background.js
index cb348ecc..e899ddf5 100644
--- a/basemap/layers/amenity/background.js
+++ b/basemap/layers/amenity/background.js
@@ -20,11 +20,11 @@ import theme from "../../theme.js";
 let directives = [
     {
         filter: ['==', ['get', 'amenity'], 'kindergarten'],
-        'fill-color': theme.amenityBackgroundKinderGartenFillColor,
+        'fill-color': theme.amenityKinderGartenFillColor,
     },
     {
         filter: ['==', ['get', 'amenity'], 'school'],
-        'fill-color': theme.amenityBackgroundSchoolFillColor,
+        'fill-color': theme.amenitySchoolFillColor,
     },
     {
         filter: ['==', ['get', 'amenity'], 'college'],
@@ -55,4 +55,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon'],
 });
diff --git a/basemap/layers/amenity/fountain.js 
b/basemap/layers/amenity/fountain.js
index b3134c5e..03553396 100644
--- a/basemap/layers/amenity/fountain.js
+++ b/basemap/layers/amenity/fountain.js
@@ -36,4 +36,5 @@ export default asLayerObject(directives, {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon'],
 });
diff --git a/basemap/layers/amenity/overlay.js 
b/basemap/layers/amenity/overlay.js
index f9329d37..47f16ac3 100644
--- a/basemap/layers/amenity/overlay.js
+++ b/basemap/layers/amenity/overlay.js
@@ -44,4 +44,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon'],
 });
diff --git a/basemap/layers/boundary/line.js b/basemap/layers/boundary/line.js
index db50bd00..8579a5dc 100644
--- a/basemap/layers/boundary/line.js
+++ b/basemap/layers/boundary/line.js
@@ -51,4 +51,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'line-dasharray': [4, 1, 1, 1],
     },
+    filter: ['==', ["geometry-type"], 'LineString'],
 });
diff --git a/basemap/layers/building/extrusion.js 
b/basemap/layers/building/extrusion.js
index 697f28e6..8e99a6e7 100644
--- a/basemap/layers/building/extrusion.js
+++ b/basemap/layers/building/extrusion.js
@@ -22,6 +22,7 @@ export default {
     source: 'baremaps',
     'source-layer': 'building',
     filter: ['all',
+        ['==', ['geometry-type'], 'Polygon'],
         ['!=', ['get', 'building'], 'no'],
         ['!=', ['get', 'building:part'], 'no']
     ],
diff --git a/basemap/layers/building/shape.js b/basemap/layers/building/fill.js
similarity index 88%
rename from basemap/layers/building/shape.js
rename to basemap/layers/building/fill.js
index 12a3f154..53d56ee0 100644
--- a/basemap/layers/building/shape.js
+++ b/basemap/layers/building/fill.js
@@ -21,7 +21,6 @@ export default {
     type: 'fill',
     source: 'baremaps',
     'source-layer': 'building',
-    filter: ['!=', ['get', 'building'], 'no'],
     layout: {
         visibility: 'visible',
     },
@@ -37,4 +36,9 @@ export default {
             13.5, 1
         ]
     },
+    filter: ['all',
+        ['==', ['geometry-type'], 'Polygon'],
+        ['!=', ['get', 'building'], 'no'],
+        ['!=', ['get', 'building:part'], 'no']
+    ],
 }
diff --git a/basemap/layers/highway/bridge_line.js 
b/basemap/layers/highway/bridge_line.js
index 19be03b1..9b9ece0a 100644
--- a/basemap/layers/highway/bridge_line.js
+++ b/basemap/layers/highway/bridge_line.js
@@ -18,6 +18,65 @@ import {asLayerObject, withSortKeys} from 
"../../utils/utils.js";
 import theme from "../../theme.js";
 
 let directives = [
+    {
+        filter: [
+            'all',
+            ['==', ['get', 'highway'], 'pedestrian'],
+            ['!=', ['get', 'area'], 'yes'],
+        ],
+        'line-color': theme.highwayPedestrianLineColor,
+        'line-width-stops': theme.highwayPedestrianLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'bridleway'],
+        'line-color': theme.highwayDashBridlewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'busway'],
+        'line-color': theme.highwayDashBuswayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            ['==', ['get', 'highway'], 'cycleway'],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['==', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashCyclewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            [
+                'in',
+                ['get', 'highway'],
+                ['literal', ['sidewalk', 'crossing', 'steps']],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'footway'],
+                ['!=', ['get', 'access'], 'private'],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['!=', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashHighwayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['all', ['==', ['get', 'highway'], 'track']],
+        'line-color': theme.highwayDashTrackLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
     {
         filter: [
             'any',
@@ -25,7 +84,7 @@ let directives = [
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
         'line-color': theme.bridgeLineMotorwayLineColor,
-        'road-width': 12,
+        'line-width-stops': theme.highwayMotorwayLineWidth,
     },
     {
         filter: [
@@ -34,7 +93,7 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
         'line-color': theme.bridgeLineTrunkLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayTrunkLineWidth,
     },
     {
         filter: [
@@ -43,7 +102,7 @@ let directives = [
             ['==', ['get', 'highway'], 'primary_link'],
         ],
         'line-color': theme.bridgeLinePrimaryLineColor,
-        'road-width': 10,
+        'line-width-stops': theme.highwayPrimaryLineWidth,
     },
     {
         filter: [
@@ -52,7 +111,7 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
         'line-color': theme.bridgeLineSecondaryLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwaySecondaryLineWidth,
     },
     {
         filter: [
@@ -61,46 +120,46 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
         'line-color': theme.bridgeLineTertiaryLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayTertiaryLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
         'line-color': theme.bridgeLineUnclassifiedLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayUnclassifiedLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
         'line-color': theme.bridgeLineResidentialLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayResidentialLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
         'line-color': theme.bridgeLineLivingStreetLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayLivingStreetLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
         'line-color': theme.bridgeLineServiceLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayServiceLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'track'],
         'line-color': theme.bridgeLineTrackLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.highwayMinorLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'raceway'],
         'line-color': theme.bridgeLineRacewayLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayRacewayLineWidth,
     },
     {
         filter: [
             'all',
             ['==', ['get', 'highway'], 'pedestrian'],
-            ['!=', ['get', '$type'], 'Polygon'],
+            ['!=', ['geometry-type'], 'Polygon'],
         ],
         'line-color': theme.bridgeLinePedestrianLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.highwayPedestrianLineWidth,
     },
 ]
 
@@ -114,5 +173,8 @@ export default asLayerObject(withSortKeys(directives), {
         'line-cap': 'butt',
         'line-join': 'miter',
     },
-    filter: ['any', ['==', ['get', 'bridge'], 'yes']],
+    filter: ['all',
+        ['==', ['geometry-type'], 'LineString'],
+        ['==', ['get', 'bridge'], 'yes']
+    ],
 });
diff --git a/basemap/layers/highway/bridge_outline.js 
b/basemap/layers/highway/bridge_outline.js
index f1ed2bcf..315d7cd4 100644
--- a/basemap/layers/highway/bridge_outline.js
+++ b/basemap/layers/highway/bridge_outline.js
@@ -25,8 +25,8 @@ let directives = [
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
         'line-color': theme.bridgeOutlineMotorwayLineColor,
-        'road-gap-width': 12,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayMotorwayLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -35,8 +35,8 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
         'line-color': theme.bridgeOutlineTrunkLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTrunkLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -45,8 +45,8 @@ let directives = [
             ['==', ['get', 'highway'], 'primary_link'],
         ],
         'line-color': theme.bridgeOutlinePrimaryLineColor,
-        'road-gap-width': 10,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPrimaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -55,8 +55,8 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
         'line-color': theme.bridgeOutlineSecondaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwaySecondaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -65,42 +65,42 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
         'line-color': theme.bridgeOutlineTertiaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTertiaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
         'line-color': theme.bridgeOutlineUnclassifiedLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayUnclassifiedLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
         'line-color': theme.bridgeOutlineResidentialLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayResidentialLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
         'line-color': theme.bridgeOutlineLivingStreetLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayLivingStreetLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
         'line-color': theme.bridgeOutlineServiceLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayServiceLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
             'all',
             ['==', ['get', 'highway'], 'pedestrian'],
-            ['!=', ['get', '$type'], 'Polygon'],
+            ['!=', ['geometry-type'], 'Polygon'],
         ],
         'line-color': theme.bridgeOutlinePedestrianLineColor,
-        'road-gap-width': 2,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPedestrianLineWidth,
+        'line-width': 1,
     },
 ];
 
@@ -114,5 +114,8 @@ export default asLayerObject(withSortKeys(directives), {
         'line-cap': 'butt',
         'line-join': 'miter',
     },
-    filter: ['any', ['==', ['get', 'bridge'], 'yes']],
+    filter: ['all',
+        ['==', ['geometry-type'], 'LineString'],
+        ['==', ['get', 'bridge'], 'yes']
+    ],
 });
diff --git a/basemap/layers/highway/construction_dash.js 
b/basemap/layers/highway/construction_dash.js
deleted file mode 100644
index 2ddadb08..00000000
--- a/basemap/layers/highway/construction_dash.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-import theme from "../../theme.js";
-import {asLayerObject, withSortKeys} from "../../utils/utils.js";
-
-
-let directives = [
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'motorway'],
-        ],
-        'line-color': theme.constructionDashConstructionMotorwayLineColor,
-        'road-width': 16,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'trunk'],
-        ],
-        'line-color': theme.constructionDashConstructionTrunkLineColor,
-        'road-width': 12,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'primary'],
-        ],
-        'line-color': theme.constructionDashConstructionPrimaryLineColor,
-        'road-width': 14,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'secondary'],
-        ],
-        'line-color': theme.constructionDashConstructionSecondaryLineColor,
-        'road-width': 12,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'tertiary'],
-        ],
-        'line-color': theme.constructionDashConstructionTertiaryLineColor,
-        'road-width': 12,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'unclassified'],
-        ],
-        'line-color': theme.constructionDashConstructionUnclassifiedLineColor,
-        'road-width': 8,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'residential'],
-        ],
-        'line-color': theme.constructionDashConstructionResidentialLineColor,
-        'road-width': 8,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'living_street'],
-        ],
-        'line-color': theme.constructionDashConstructionLivingStreetLineColor,
-        'road-width': 8,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'construction'],
-            ['==', ['get', 'construction'], 'service'],
-        ],
-        'line-color': theme.constructionDashConstructionServiceLineColor,
-        'road-width': 8,
-    },
-]
-
-export default asLayerObject(withSortKeys(directives), {
-    id: 'highway_construction_outline',
-    source: 'baremaps',
-    'source-layer': 'highway',
-    type: 'line',
-    layout: {
-        visibility: 'visible',
-        'line-cap': 'round',
-        'line-join': 'round',
-    },
-});
diff --git a/basemap/layers/highway/construction_line.js 
b/basemap/layers/highway/construction_line.js
index 7a77722b..2d9eb613 100644
--- a/basemap/layers/highway/construction_line.js
+++ b/basemap/layers/highway/construction_line.js
@@ -19,6 +19,15 @@ import {asLayerObject, withSortKeys} from 
"../../utils/utils.js";
 
 
 let directives = [
+    {
+        filter: [
+            'all',
+            ['==', ['get', 'highway'], 'construction'],
+            ['!', ['has', 'construction']],
+        ],
+        'line-color': theme.constructionLineConstructionDefaultLineColor,
+        'line-width-stops': theme.highwayConstructionLineWidth,
+    },
     {
         filter: [
             'all',
@@ -29,7 +38,7 @@ let directives = [
             ]
         ],
         'line-color': theme.constructionLineConstructionMotorwayLineColor,
-        'road-width': 16,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -41,7 +50,7 @@ let directives = [
             ]
         ],
         'line-color': theme.constructionLineConstructionTrunkLineColor,
-        'road-width': 12,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -53,7 +62,7 @@ let directives = [
             ]
         ],
         'line-color': theme.constructionLineConstructionPrimaryLineColor,
-        'road-width': 14,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -65,7 +74,7 @@ let directives = [
             ]
         ],
         'line-color': theme.constructionLineConstructionSecondaryLineColor,
-        'road-width': 12,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -77,7 +86,7 @@ let directives = [
             ]
         ],
         'line-color': theme.constructionLineConstructionTertiaryLineColor,
-        'road-width': 12,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -86,7 +95,7 @@ let directives = [
             ['==', ['get', 'construction'], 'unclassified'],
         ],
         'line-color': theme.constructionLineConstructionUnclassifiedLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -95,7 +104,7 @@ let directives = [
             ['==', ['get', 'construction'], 'residential'],
         ],
         'line-color': theme.constructionLineConstructionResidentialLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -104,7 +113,7 @@ let directives = [
             ['==', ['get', 'construction'], 'living_street'],
         ],
         'line-color': theme.constructionLineConstructionLivingStreetLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -113,7 +122,7 @@ let directives = [
             ['==', ['get', 'construction'], 'service'],
         ],
         'line-color': theme.constructionLineConstructionServiceLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
     {
         filter: [
@@ -122,7 +131,7 @@ let directives = [
             ['==', ['get', 'construction'], 'raceway'],
         ],
         'line-color': theme.constructionLineConstructionRacewayLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayConstructionLineWidth,
     },
 ]
 
@@ -139,4 +148,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'line-dasharray': [1, 1],
     },
+    filter: ['==', ['geometry-type'], 'LineString'],
 });
diff --git a/basemap/layers/highway/highway_dash.js 
b/basemap/layers/highway/highway_dash.js
deleted file mode 100644
index bca6e844..00000000
--- a/basemap/layers/highway/highway_dash.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-import {asLayerObject, withSortKeys} from "../../utils/utils.js";
-import theme from "../../theme.js";
-
-let directives = [
-    {
-        filter: ['==', ['get', 'highway'], 'bridleway'],
-        'line-color': theme.highwayDashBridlewayLineColor,
-        'road-width': 1,
-    },
-    {
-        filter: ['==', ['get', 'highway'], 'busway'],
-        'line-color': theme.highwayDashBuswayLineColor,
-        'road-width': 1,
-    },
-    {
-        filter: [
-            'any',
-            ['==', ['get', 'highway'], 'cycleway'],
-            [
-                'all',
-                ['==', ['get', 'highway'], 'path'],
-                ['==', ['get', 'bicycle'], 'designated'],
-            ],
-        ],
-        'line-color': theme.highwayDashCyclewayLineColor,
-        'road-width': 1,
-    },
-    {
-        filter: [
-            'any',
-            [
-                'all',
-                ['==', ['get', 'highway'], 'footway'],
-                ['==', ['get', 'access'], 'private'],
-            ],
-            [
-                'all',
-                ['==', ['get', 'highway'], 'service'],
-                ['in', ['get', 'access'], ['literal', ['private', 'no']]],
-            ],
-        ],
-        'line-color': theme.highwayDashFootwayLineColor,
-        'road-width': 1,
-    },
-    {
-        filter: [
-            'any',
-            [
-                'in',
-                ['get', 'highway'],
-                ['literal', ['sidewalk', 'crossing', 'steps']],
-            ],
-            [
-                'all',
-                ['==', ['get', 'highway'], 'footway'],
-                ['!=', ['get', 'access'], 'private'],
-            ],
-            [
-                'all',
-                ['==', ['get', 'highway'], 'path'],
-                ['!=', ['get', 'bicycle'], 'designated'],
-            ],
-        ],
-        'line-color': theme.highwayDashHighwayLineColor,
-        'road-width': 1,
-    },
-    {
-        filter: ['all', ['==', ['get', 'highway'], 'track']],
-        'line-color': theme.highwayDashTrackLineColor,
-        'road-width': 1,
-    },
-];
-
-export default asLayerObject(withSortKeys(directives), {
-    id: 'highway_dash',
-    type: 'line',
-    source: 'baremaps',
-    'source-layer': 'highway',
-    layout: {
-        'line-cap': 'round',
-        'line-join': 'round',
-        visibility: 'visible',
-    },
-    paint: {
-        'line-dasharray': [2, 2],
-    },
-});
diff --git a/basemap/layers/highway/pedestrian_area.js 
b/basemap/layers/highway/highway_fill.js
similarity index 93%
rename from basemap/layers/highway/pedestrian_area.js
rename to basemap/layers/highway/highway_fill.js
index 41eb100f..2fd2e7de 100644
--- a/basemap/layers/highway/pedestrian_area.js
+++ b/basemap/layers/highway/highway_fill.js
@@ -26,7 +26,7 @@ export default {
     },
     filter: [
         'all',
-        ['==', 'area', 'yes'],
+        ['has', 'area'], // Some pedestrian areas are not closed polygons, 
hence the need for this filter
         [
             'any',
             ['==', 'highway', 'pedestrian'],
diff --git a/basemap/layers/highway/highway_line.js 
b/basemap/layers/highway/highway_line.js
index d8fcc6cf..8173e165 100644
--- a/basemap/layers/highway/highway_line.js
+++ b/basemap/layers/highway/highway_line.js
@@ -18,14 +18,73 @@ import {asLayerObject, withSortKeys} from 
"../../utils/utils.js";
 import theme from "../../theme.js";
 
 let directives = [
+    {
+        filter: [
+            'all',
+            ['==', ['get', 'highway'], 'pedestrian'],
+            ['!=', ['get', 'area'], 'yes'],
+        ],
+        'line-color': theme.highwayPedestrianLineColor,
+        'line-width-stops': theme.highwayPedestrianLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'bridleway'],
+        'line-color': theme.highwayDashBridlewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'busway'],
+        'line-color': theme.highwayDashBuswayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            ['==', ['get', 'highway'], 'cycleway'],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['==', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashCyclewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            [
+                'in',
+                ['get', 'highway'],
+                ['literal', ['sidewalk', 'crossing', 'steps']],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'footway'],
+                ['!=', ['get', 'access'], 'private'],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['!=', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashHighwayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['all', ['==', ['get', 'highway'], 'track']],
+        'line-color': theme.highwayDashTrackLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
     {
         filter: [
             'any',
             ['==', ['get', 'highway'], 'motorway'],
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
-        'line-color': theme.highwayLineMotorwayLineColor,
-        'road-width': 12,
+        'line-color': theme.highwayMotorwayLineColor,
+        'line-width-stops': theme.highwayMotorwayLineWidth,
     },
     {
         filter: [
@@ -33,8 +92,8 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk'],
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
-        'line-color': theme.highwayLineTrunkLineColor,
-        'road-width': 8,
+        'line-color': theme.highwayTrunkLineColor,
+        'line-width-stops': theme.highwayTrunkLineWidth,
     },
     {
         filter: [
@@ -42,8 +101,8 @@ let directives = [
             ['==', ['get', 'highway'], 'primary'],
             ['==', ['get', 'highway'], 'primary_link'],
         ],
-        'line-color': theme.highwayLinePrimaryLineColor,
-        'road-width': 10,
+        'line-color': theme.highwayPrimaryLineColor,
+        'line-width-stops': theme.highwayPrimaryLineWidth,
     },
     {
         filter: [
@@ -51,8 +110,8 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary'],
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
-        'line-color': theme.highwayLineSecondaryLineColor,
-        'road-width': 8,
+        'line-color': theme.highwaySecondaryLineColor,
+        'line-width-stops': theme.highwaySecondaryLineWidth,
     },
     {
         filter: [
@@ -60,47 +119,38 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary'],
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
-        'line-color': theme.highwayLineTertiaryLineColor,
-        'road-width': 8,
+        'line-color': theme.highwayTertiaryLineColor,
+        'line-width-stops': theme.highwayTertiaryLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'busway'],
-        'line-color': theme.highwayLineBuswayLineColor,
-        'road-width': 8,
+        'line-color': theme.highwayBuswayLineColor,
+        'line-width-stops': theme.highwayBuswayLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
-        'line-color': theme.highwayLineUnclassifiedLineColor,
-        'road-width': 4,
+        'line-color': theme.highwayUnclassifiedLineColor,
+        'line-width-stops': theme.highwayUnclassifiedLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
-        'line-color': theme.highwayLineResidentialLineColor,
-        'road-width': 4,
+        'line-color': theme.highwayResidentialLineColor,
+        'line-width-stops': theme.highwayResidentialLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
-        'line-color': theme.highwayLineLivingStreetLineColor,
-        'road-width': 4,
+        'line-color': theme.highwayLivingStreetLineColor,
+        'line-width-stops': theme.highwayLivingStreetLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
-        'line-color': theme.highwayLineServiceLineColor,
-        'road-width': 4,
+        'line-color': theme.highwayServiceLineColor,
+        'line-width-stops': theme.highwayServiceLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'raceway'],
-        'line-color': theme.highwayLineRacewayLineColor,
-        'road-width': 4,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'pedestrian'],
-            ['!=', ['get', 'area'], 'yes'],
-        ],
-        'line-color': theme.highwayLinePedestrianLineColor,
-        'road-width': 2,
+        'line-color': theme.highwayRacewayLineColor,
+        'line-width-stops': theme.highwayRacewayLineWidth,
     },
 ];
 
@@ -116,9 +166,8 @@ export default asLayerObject(withSortKeys(directives), {
     },
     filter: [
         'all',
+        ['==', ['geometry-type'], 'LineString'],
         ['!=', ['get', 'bridge'], 'yes'],
         ['!=', ['get', 'tunnel'], 'yes'],
-        ['!=', ['get', 'layer'], '-1'],
-        ['!=', ['get', 'covered'], 'yes'],
     ],
 });
diff --git a/basemap/layers/highway/highway_outline.js 
b/basemap/layers/highway/highway_outline.js
index c69638b2..297c39d5 100644
--- a/basemap/layers/highway/highway_outline.js
+++ b/basemap/layers/highway/highway_outline.js
@@ -25,8 +25,8 @@ let directives = [
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
         'line-color': theme.highwayOutlineMotorwayLineColor,
-        'road-gap-width': 12,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayMotorwayLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: [
@@ -35,8 +35,8 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
         'line-color': theme.highwayOutlineTrunkLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTrunkLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: [
@@ -45,8 +45,8 @@ let directives = [
             ['==', ['get', 'highway'], 'primary_link'],
         ],
         'line-color': theme.highwayOutlinePrimaryLineColor,
-        'road-gap-width': 10,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPrimaryLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: [
@@ -55,8 +55,8 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
         'line-color': theme.highwayOutlineSecondaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwaySecondaryLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: [
@@ -65,38 +65,38 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
         'line-color': theme.highwayOutlineTertiaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTertiaryLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'busway'],
         'line-color': theme.highwayOutlineBuswayLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayBuswayLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
         'line-color': theme.highwayOutlineUnclassifiedLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayUnclassifiedLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
         'line-color': theme.highwayOutlineResidentialLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayResidentialLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
         'line-color': theme.highwayOutlineLivingStreetLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayLivingStreetLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
         'line-color': theme.highwayOutlineServiceLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayServiceLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
     {
         filter: [
@@ -105,17 +105,8 @@ let directives = [
             ['!=', ['get', 'area'], 'yes'],
         ],
         'line-color': theme.highwayOutlinePedestrianLineColor,
-        'road-gap-width': 2,
-        'road-width': 2,
-    },
-    {
-        filter: [
-            'all',
-            ['==', ['get', 'highway'], 'pedestrian'],
-            ['==', ['get', 'area'], 'yes'],
-        ],
-        'line-color': theme.highwayOutlinePedestrianBisLineColor,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPedestrianLineWidth,
+        'line-width-stops': theme.highwayOutlineWidth,
     },
 ]
 
@@ -131,9 +122,8 @@ export default asLayerObject(withSortKeys(directives), {
     },
     filter: [
         'all',
+        ['==', ['geometry-type'], 'LineString'],
         ['!=', ['get', 'bridge'], 'yes'],
         ['!=', ['get', 'tunnel'], 'yes'],
-        ['!=', ['get', 'layer'], '-1'],
-        ['!=', ['get', 'covered'], 'yes'],
     ],
 });
diff --git a/basemap/layers/highway/tunnel_line.js 
b/basemap/layers/highway/tunnel_line.js
index 9d3f6c4e..e4e6e7bc 100644
--- a/basemap/layers/highway/tunnel_line.js
+++ b/basemap/layers/highway/tunnel_line.js
@@ -19,6 +19,65 @@ import {asLayerObject, withSortKeys} from 
"../../utils/utils.js";
 import theme from "../../theme.js";
 
 let directives = [
+    {
+        filter: [
+            'all',
+            ['==', ['get', 'highway'], 'pedestrian'],
+            ['!=', ['get', 'area'], 'yes'],
+        ],
+        'line-color': theme.highwayPedestrianLineColor,
+        'line-width-stops': theme.highwayPedestrianLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'bridleway'],
+        'line-color': theme.highwayDashBridlewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['==', ['get', 'highway'], 'busway'],
+        'line-color': theme.highwayDashBuswayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            ['==', ['get', 'highway'], 'cycleway'],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['==', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashCyclewayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: [
+            'any',
+            [
+                'in',
+                ['get', 'highway'],
+                ['literal', ['sidewalk', 'crossing', 'steps']],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'footway'],
+                ['!=', ['get', 'access'], 'private'],
+            ],
+            [
+                'all',
+                ['==', ['get', 'highway'], 'path'],
+                ['!=', ['get', 'bicycle'], 'designated'],
+            ],
+        ],
+        'line-color': theme.highwayDashHighwayLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
+    {
+        filter: ['all', ['==', ['get', 'highway'], 'track']],
+        'line-color': theme.highwayDashTrackLineColor,
+        'line-width-stops': theme.highwayMinorLineWidth,
+    },
     {
         filter: [
             'any',
@@ -26,7 +85,7 @@ let directives = [
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
         'line-color': theme.tunnelLineMotorwayLineColor,
-        'road-width': 12,
+        'line-width-stops': theme.highwayMotorwayLineWidth,
     },
     {
         filter: [
@@ -35,7 +94,7 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
         'line-color': theme.tunnelLineTrunkLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayTrunkLineWidth,
     },
     {
         filter: [
@@ -44,7 +103,7 @@ let directives = [
             ['==', ['get', 'highway'], 'primary_link'],
         ],
         'line-color': theme.tunnelLinePrimaryLineColor,
-        'road-width': 10,
+        'line-width-stops': theme.highwayPrimaryLineWidth,
     },
     {
         filter: [
@@ -53,7 +112,7 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
         'line-color': theme.tunnelLineSecondaryLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwaySecondaryLineWidth,
     },
     {
         filter: [
@@ -62,46 +121,46 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
         'line-color': theme.tunnelLineTertiaryLineColor,
-        'road-width': 8,
+        'line-width-stops': theme.highwayTertiaryLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
         'line-color': theme.tunnelLineUnclassifiedLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayUnclassifiedLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
         'line-color': theme.tunnelLineResidentialLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayResidentialLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
         'line-color': theme.tunnelLineLivingStreetLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayLivingStreetLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
         'line-color': theme.tunnelLineServiceLineColor,
-        'road-width': 4,
+        'line-width-stops': theme.highwayServiceLineWidth,
     },
     {
         filter: [
             'all',
             ['==', ['get', 'highway'], 'pedestrian'],
-            ['!=', ['get', '$type'], 'Polygon'],
+            ['!=', ['geometry-type'], 'Polygon'],
         ],
         'line-color': theme.tunnelLinePedestrianLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.highwayPedestrianLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'raceway'],
         'line-color': theme.tunnelLineRacewayLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.highwayRacewayLineWidth,
     },
     {
         filter: ['==', ['get', 'highway'], 'track'],
         'line-color': theme.tunnelLineTrackLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.highwayMinorLineWidth,
     },
 ];
 
@@ -116,9 +175,8 @@ export default asLayerObject(withSortKeys(directives), {
         'line-join': 'miter',
     },
     filter: [
-        'any',
+        'all',
+        ['==', ['geometry-type'], 'LineString'],
         ['==', ['get', 'tunnel'], 'yes'],
-        ['==', ['get', 'layer'], '-1'],
-        ['==', ['get', 'covered'], 'yes'],
     ],
 });
diff --git a/basemap/layers/highway/tunnel_outline.js 
b/basemap/layers/highway/tunnel_outline.js
index 13526e5a..b7bb5e24 100644
--- a/basemap/layers/highway/tunnel_outline.js
+++ b/basemap/layers/highway/tunnel_outline.js
@@ -26,8 +26,8 @@ let directives = [
             ['==', ['get', 'highway'], 'motorway_link'],
         ],
         'line-color': theme.tunnelOutlineMotorwayLineColor,
-        'road-gap-width': 12,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayMotorwayLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -36,8 +36,8 @@ let directives = [
             ['==', ['get', 'highway'], 'trunk_link'],
         ],
         'line-color': theme.tunnelOutlineTrunkLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTrunkLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -46,8 +46,8 @@ let directives = [
             ['==', ['get', 'highway'], 'primary_link'],
         ],
         'line-color': theme.tunnelOutlinePrimaryLineColor,
-        'road-gap-width': 10,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPrimaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -56,8 +56,8 @@ let directives = [
             ['==', ['get', 'highway'], 'secondary_link'],
         ],
         'line-color': theme.tunnelOutlineSecondaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwaySecondaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
@@ -66,42 +66,42 @@ let directives = [
             ['==', ['get', 'highway'], 'tertiary_link'],
         ],
         'line-color': theme.tunnelOutlineTertiaryLineColor,
-        'road-gap-width': 8,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayTertiaryLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'unclassified'],
         'line-color': theme.tunnelOutlineUnclassifiedLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayUnclassifiedLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'residential'],
         'line-color': theme.tunnelOutlineResidentialLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayResidentialLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'living_street'],
         'line-color': theme.tunnelOutlineLivingStreetLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayLivingStreetLineWidth,
+        'line-width': 1,
     },
     {
         filter: ['==', ['get', 'highway'], 'service'],
         'line-color': theme.tunnelOutlineServiceLineColor,
-        'road-gap-width': 4,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayServiceLineWidth,
+        'line-width': 1,
     },
     {
         filter: [
             'all',
             ['==', ['get', 'highway'], 'pedestrian'],
-            ['!=', ['get', '$type'], 'Polygon'],
+            ['!=', ['geometry-type'], 'Polygon'],
         ],
         'line-color': theme.tunnelOutlinePedestrianLineColor,
-        'road-gap-width': 2,
-        'road-width': 2,
+        'line-gap-width-stops': theme.highwayPedestrianLineWidth,
+        'line-width': 1,
     },
 ];
 
@@ -116,12 +116,8 @@ export default asLayerObject(withSortKeys(directives), {
         'line-join': 'miter',
     },
     filter: [
-        'any',
+        'all',
+        ['==', ['geometry-type'], 'LineString'],
         ['==', ['get', 'tunnel'], 'yes'],
-        ['==', ['get', 'layer'], '-1'],
-        ['==', ['get', 'covered'], 'yes'],
     ],
-    paint: {
-        'line-dasharray': [1, 1],
-    },
 });
diff --git a/basemap/layers/landuse/background.js 
b/basemap/layers/landuse/background.js
index 97ce6960..5f4c6178 100644
--- a/basemap/layers/landuse/background.js
+++ b/basemap/layers/landuse/background.js
@@ -128,4 +128,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ['geometry-type'], 'Polygon'],
 });
diff --git a/basemap/layers/landuse/overlay.js 
b/basemap/layers/landuse/overlay.js
index 8270e08b..9978f723 100644
--- a/basemap/layers/landuse/overlay.js
+++ b/basemap/layers/landuse/overlay.js
@@ -52,4 +52,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ['geometry-type'], 'Polygon'],
 });
diff --git a/basemap/layers/leisure/background.js 
b/basemap/layers/leisure/background.js
index d2d9645f..b69a657e 100644
--- a/basemap/layers/leisure/background.js
+++ b/basemap/layers/leisure/background.js
@@ -23,11 +23,6 @@ let directives = [
         filter: ['==', ['get', 'leisure'], 'golf_course'],
         'fill-color': theme.leisureBackgroundGolfCourseFillColor,
     },
-    {
-        filter: ['==', ['get', 'leisure'], 'track'],
-        'fill-color': theme.leisureBackgroundTrackFillColor,
-        'fill-outline-color': theme.leisureBackgroundTrackFillOutlineColor,
-    },
     {
         filter: ['==', ['get', 'leisure'], 'sports_centre'],
         'fill-color': theme.leisureBackgroundSportsCentreFillColor,
@@ -53,4 +48,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon'],
 });
diff --git a/basemap/layers/leisure/nature_reserve.js 
b/basemap/layers/leisure/nature_reserve.js
deleted file mode 100644
index 41dc9bd7..00000000
--- a/basemap/layers/leisure/nature_reserve.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-
-import {withFillSortKey} from "../../utils/utils.js";
-import theme from "../../theme.js";
-
-let directives = [
-    {
-        filter: ['==', 'leisure', 'nature_reserve'],
-        'line-width': 5,
-        'line-color': theme.leisureNatureReserveLineColor,
-    },
-];
-
-export default {
-    id: 'leisure_nature_reserve',
-    type: 'line',
-    source: 'baremaps',
-    'source-layer': 'leisure',
-    layout: {
-        visibility: 'visible',
-    },
-    directives: directives.map(withFillSortKey),
-}
diff --git a/basemap/layers/leisure/overlay.js 
b/basemap/layers/leisure/overlay.js
index 31ff3e70..1d8dc3f1 100644
--- a/basemap/layers/leisure/overlay.js
+++ b/basemap/layers/leisure/overlay.js
@@ -57,6 +57,11 @@ let directives = [
         'fill-color': theme.leisureOverlayPitchFillColor,
         'fill-outline-color': theme.leisureOverlayPitchFillOutlineColor,
     },
+    {
+        filter: ['==', ['get', 'leisure'], 'track'],
+        'fill-color': theme.leisureBackgroundTrackFillColor,
+        'fill-outline-color': theme.leisureBackgroundTrackFillOutlineColor,
+    },
     {
         filter: ['==', ['get', 'leisure'], 'stadium'],
         'fill-color': theme.leisureOverlayStadiumFillColor,
@@ -74,4 +79,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon']
 });
diff --git a/basemap/layers/man_made/bridge.js 
b/basemap/layers/man_made/bridge.js
index b89867dc..d02b2843 100644
--- a/basemap/layers/man_made/bridge.js
+++ b/basemap/layers/man_made/bridge.js
@@ -36,4 +36,5 @@ export default asLayerObject(directives, {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ["geometry-type"], 'Polygon']
 });
diff --git a/basemap/layers/man_made/pier_line.js 
b/basemap/layers/man_made/pier_line.js
index 4640f1b3..c12fa069 100644
--- a/basemap/layers/man_made/pier_line.js
+++ b/basemap/layers/man_made/pier_line.js
@@ -20,7 +20,6 @@ import theme from "../../theme.js";
 export default {
     id: 'man_made_pier_line',
     type: 'line',
-    filter: ['==', ['get', 'man_made'], 'pier'],
     source: 'baremaps',
     'source-layer': 'man_made',
     layout: {
@@ -31,4 +30,9 @@ export default {
         'line-color': theme.manMadePierLineLineColor,
         'line-width': ['interpolate', ['exponential', 1], ['zoom'], 12, 0.5, 
18, 2],
     },
+    filter: [
+        'all',
+        ['==', ["geometry-type"], 'LineString'],
+        ['==', ['get', 'man_made'], 'pier'],
+    ]
 }
diff --git a/basemap/layers/natural/background.js 
b/basemap/layers/natural/background.js
index e6833631..91baa991 100644
--- a/basemap/layers/natural/background.js
+++ b/basemap/layers/natural/background.js
@@ -72,4 +72,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ['geometry-type'], 'Polygon'],
 });
diff --git a/basemap/layers/natural/overlay.js 
b/basemap/layers/natural/overlay.js
index 16c91613..97e7cb47 100644
--- a/basemap/layers/natural/overlay.js
+++ b/basemap/layers/natural/overlay.js
@@ -59,4 +59,5 @@ export default asLayerObject(withSortKeys(directives), {
     paint: {
         'fill-antialias': false,
     },
+    filter: ['==', ['geometry-type'], 'Polygon'],
 });
diff --git a/basemap/layers/natural/tree.js b/basemap/layers/natural/tree.js
index fa614d30..c8732a49 100644
--- a/basemap/layers/natural/tree.js
+++ b/basemap/layers/natural/tree.js
@@ -19,7 +19,6 @@ import theme from "../../theme.js";
 export default {
     id: 'natural_tree',
     type: 'circle',
-    filter: ['all', ['==', 'natural', 'tree']],
     source: 'baremaps',
     'source-layer': 'point',
     layout: {
@@ -38,4 +37,7 @@ export default {
             200,
         ],
     },
+    filter: ['all',
+        ['==', 'natural', 'tree'],
+    ],
 }
diff --git a/basemap/layers/natural/trunk.js b/basemap/layers/natural/trunk.js
index 472bab78..8a836638 100644
--- a/basemap/layers/natural/trunk.js
+++ b/basemap/layers/natural/trunk.js
@@ -19,7 +19,6 @@ import theme from "../../theme.js";
 export default {
     id: 'natural_trunk',
     type: 'circle',
-    filter: ['all', ['==', 'natural', 'tree']],
     source: 'baremaps',
     'source-layer': 'point',
     layout: {
@@ -38,4 +37,5 @@ export default {
             50,
         ],
     },
+    filter: ['all', ['==', 'natural', 'tree']],
 };
diff --git a/basemap/layers/natural/water.js b/basemap/layers/natural/water.js
deleted file mode 100644
index 77c26dee..00000000
--- a/basemap/layers/natural/water.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-import theme from "../../theme.js";
-
-export default {
-    id: 'natural_water',
-    type: 'fill',
-    source: 'baremaps',
-    'source-layer': 'natural',
-    layout: {
-        visibility: 'visible',
-    },
-    paint: {
-        'fill-antialias': false,
-    },
-    directives: [
-        {
-            filter: ['==', ['get', 'natural'], 'water'],
-            'fill-color': theme.naturalWaterFillColor,
-            'fill-sort-key': 10,
-        }
-    ]
-}
diff --git a/basemap/layers/power/background.js 
b/basemap/layers/power/background.js
index 1aeb34b6..5e91c72a 100644
--- a/basemap/layers/power/background.js
+++ b/basemap/layers/power/background.js
@@ -20,7 +20,6 @@ import theme from "../../theme.js";
 export default {
     id: 'power_plant',
     type: 'fill',
-    filter: ['any', ['==', 'power', 'plant'], ['==', 'power', 'substation']],
     source: 'baremaps',
     'source-layer': 'power',
     layout: {
@@ -31,4 +30,5 @@ export default {
         'fill-color': theme.powerBackgroundPowerPlantFillColor,
         'fill-outline-color': theme.powerBackgroundPowerPlantFillOutlineColor,
     },
+    filter: ['any', ['==', 'power', 'plant'], ['==', 'power', 'substation']],
 }
diff --git a/basemap/layers/power/cable.js b/basemap/layers/power/cable.js
index 397f3a1c..b8c72d06 100644
--- a/basemap/layers/power/cable.js
+++ b/basemap/layers/power/cable.js
@@ -20,12 +20,6 @@ import theme from "../../theme.js";
 export default {
     id: 'power_cable',
     type: 'line',
-    filter: [
-        'any',
-        ['==', 'power', 'cable'],
-        ['==', 'power', 'line'],
-        ['==', 'power', 'minor_line'],
-    ],
     source: 'baremaps',
     'source-layer': 'power',
     layout: {
@@ -37,4 +31,10 @@ export default {
         'line-width': ['interpolate', ['exponential', 1.2], ['zoom'], 4, 0, 
20, 4],
         'line-color': theme.powerCableLineColor,
     },
+    filter: [
+        'any',
+        ['==', 'power', 'cable'],
+        ['==', 'power', 'line'],
+        ['==', 'power', 'minor_line'],
+    ],
 }
diff --git a/basemap/layers/railway/line.js b/basemap/layers/railway/line.js
index 238f6cb2..136db1dc 100644
--- a/basemap/layers/railway/line.js
+++ b/basemap/layers/railway/line.js
@@ -26,7 +26,7 @@ export let directives = [
             ['!', ['has', 'service']],
         ],
         'line-color': theme.railwayLineRailLineColor,
-        'road-width': 10,
+        'line-width-stops': theme.railwayRailLineWidth,
     },
     {
         'filter': ['all',
@@ -34,62 +34,62 @@ export let directives = [
             ['has', 'service']
         ],
         'line-color': theme.railwayLineAllRailsLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayServiceLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'subway'],
         'line-color': theme.railwayLineSubwayLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwaySubwayLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'tram'],
         'line-color': theme.railwayLineTramLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayTramLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'preserved'],
         'line-color': theme.railwayLinePreservedLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayPreservedLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'funicular'],
         'line-color': theme.railwayLineFunicularLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayFunicularLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'monorail'],
         'line-color': theme.railwayLineMonorailLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayMonorailLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'light_rail'],
         'line-color': theme.railwayLineLigthRailLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayLightRailLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'construction'],
         'line-color': theme.railwayLineConstructionLineColor,
-        'road-width': 6,
+        'line-width-stops': theme.railwayConstructionLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'abandoned'],
         'line-color': theme.railwayLineAbandonedLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.railwayAbandonedLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'disused'],
         'line-color': theme.railwayLineisuedLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.railwayDisusedLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'miniature'],
         'line-color': theme.railwayLineMiniatureLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.railwayMiniatureLineWidth,
     },
     {
         'filter': ['==', ['get', 'railway'], 'narrow_gauge'],
         'line-color': theme.railwayLineMarrowGaugeLineColor,
-        'road-width': 2,
+        'line-width-stops': theme.railwayNarrowGaugeLineWidth,
     },
 ];
 
@@ -98,10 +98,13 @@ export default asLayerObject(withSortKeys(directives), {
     'source': 'baremaps',
     'source-layer': 'railway',
     'type': 'line',
-    'filter': ['!=', ['get', 'tunnel'], 'yes'],
     'layout': {
         'visibility': 'visible',
         'line-cap': 'round',
         'line-join': 'round',
     },
+    'filter': ['all',
+        ['==', ['geometry-type'], 'LineString'],
+        ['!=', ['get', 'tunnel'], 'yes'],
+    ],
 });
diff --git a/basemap/layers/railway/prepare.sql 
b/basemap/layers/railway/prepare.sql
index 7ccfa2a3..e9f9c029 100644
--- a/basemap/layers/railway/prepare.sql
+++ b/basemap/layers/railway/prepare.sql
@@ -23,4 +23,4 @@ FROM (
    FROM osm_ways
    WHERE tags ->> 'railway' IN ('light_rail', 'monorail', 'rail', 'subway', 
'tram')
    GROUP BY tags -> 'railway', tags -> 'service'
-) AS merge;
+) AS mergedDirective;
diff --git a/basemap/layers/railway/tunnel.js b/basemap/layers/railway/tunnel.js
index 4842603b..b63e0add 100644
--- a/basemap/layers/railway/tunnel.js
+++ b/basemap/layers/railway/tunnel.js
@@ -24,7 +24,6 @@ export default asLayerObject(withSortKeys(directives), {
     'source': 'baremaps',
     'source-layer': 'railway',
     'type': 'line',
-    'filter': ['==', ['get', 'tunnel'], 'yes'],
     'layout': {
         'visibility': 'visible',
         'line-cap': 'round',
@@ -33,4 +32,8 @@ export default asLayerObject(withSortKeys(directives), {
     'paint': {
         'line-dasharray': [1, 2]
     },
+    'filter': ['all',
+        ['==', ['geometry-type'], 'LineString'],
+        ['==', ['get', 'tunnel'], 'yes'],
+    ],
 });
diff --git a/basemap/layers/route/prepare.sql b/basemap/layers/route/prepare.sql
index a06761fb..e7881c16 100644
--- a/basemap/layers/route/prepare.sql
+++ b/basemap/layers/route/prepare.sql
@@ -26,6 +26,6 @@ FROM (
    WHERE tags ->> 'route' IN ('light_rail', 'monorail', 'rail', 'subway', 
'tram')
    AND NOT tags ? 'service'
    GROUP BY tags -> 'route'
-) AS merge;
+) AS mergedDirective;
 
 CREATE INDEX IF NOT EXISTS osm_route_geom_index ON osm_route USING SPGIST 
(geom);
diff --git a/basemap/layers/route/style.js b/basemap/layers/route/style.js
index 621b2d7c..d119e59f 100644
--- a/basemap/layers/route/style.js
+++ b/basemap/layers/route/style.js
@@ -36,4 +36,5 @@ export default asLayerObject(withSortKeys(directives), {
         'line-join': 'round',
         visibility: 'visible',
     },
+    filter: ['==', ['geometry-type'], 'LineString'],
 });
diff --git a/basemap/layers/aerialway/style.js b/basemap/layers/waterway/area.js
similarity index 81%
rename from basemap/layers/aerialway/style.js
rename to basemap/layers/waterway/area.js
index 63273a2b..20b9f5c7 100644
--- a/basemap/layers/aerialway/style.js
+++ b/basemap/layers/waterway/area.js
@@ -17,16 +17,16 @@
 import theme from "../../theme.js";
 
 export default {
-    id: 'aerialway_line',
-    type: 'line',
+    id: 'waterway_polygon',
     source: 'baremaps',
-    'source-layer': 'aerialway',
+    'source-layer': 'waterway',
+    type: 'fill',
     layout: {
-        'line-cap': 'round',
-        'line-join': 'round',
         visibility: 'visible',
     },
+    filter: ['==', ['geometry-type'], 'Polygon'],
     paint: {
-        'line-color': theme.aerialwayStyleLinePaintLineColor,
+        'fill-antialias': false,
+        'fill-color': theme.waterwayLineColor,
     },
 }
diff --git a/basemap/layers/waterway/line.js b/basemap/layers/waterway/line.js
index d321c9cf..d7b88fe2 100644
--- a/basemap/layers/waterway/line.js
+++ b/basemap/layers/waterway/line.js
@@ -15,30 +15,32 @@
  limitations under the License.
  **/
 import theme from "../../theme.js";
+import {asLayerObject, withSortKeys} from "../../utils/utils.js";
 
+let directives = [
+    {
+        "filter": ["!", ["has", "tunnel"]],
+        "line-color": theme.waterwayLineColor,
+        "line-width-stops": [4, 1, 14, 1],
+    },
+    {
+        "filter": ["has", "tunnel"],
+        "line-color": theme.waterwayTunnelColor,
+        "line-width-stops": [4, 1, 14, 1],
+    },
+];
 
-export default {
+let layer = asLayerObject(withSortKeys(directives), {
     "id": "waterway",
     "type": "line",
-    "filter": [
-        "all",
-        ["!=", "tunnel", "yes"],
-        ["!=", "tunnel", "culvert"]
-    ],
     "source": "baremaps",
     "source-layer": "waterway",
-    "layout": {
-        "line-cap": "round",
-        "line-join": "round",
-        "visibility": "visible"
+    filter: ['==', ['geometry-type'], 'LineString'],
+    layout: {
+        visibility: 'visible',
+        'line-cap': 'round',
+        'line-join': 'round',
     },
-    "paint": {
-        "line-width": [
-            "interpolate",
-            ["exponential", 1.2],
-            ["zoom"],
-            4, 0, 20, 12
-        ],
-        "line-color": theme.waterwayLineWaterwayLineColor
-    }
-}
+});
+
+export default layer;
diff --git a/basemap/layers/waterway/tunnel_casing.js 
b/basemap/layers/waterway/tunnel_casing.js
deleted file mode 100644
index a74011b8..00000000
--- a/basemap/layers/waterway/tunnel_casing.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-import theme from "../../theme.js";
-
-
-export default {
-    "id": "waterway_tunnel_casing",
-    "type": "line",
-    "filter": [
-        "any",
-        ["==", "tunnel", "yes"],
-        ["==", "tunnel", "culvert"]
-    ],
-    "source": "baremaps",
-    "source-layer": "waterway",
-    "layout": {
-        "visibility": "visible"
-    },
-    "paint": {
-        "line-width": [
-            "interpolate", ["exponential", 1.2], ["zoom"], 4, 0, 20,
-            12
-        ],
-        "line-color": theme.waterwayTunnelCasingLineColor,
-        "line-dasharray": [0.3, 0.15]
-    }
-}
diff --git a/basemap/layers/waterway/tunnel_line.js 
b/basemap/layers/waterway/tunnel_line.js
deleted file mode 100644
index 0d946076..00000000
--- a/basemap/layers/waterway/tunnel_line.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-import theme from "../../theme.js";
-
-
-export default {
-    "id": "waterway_tunnel",
-    "type": "line",
-    "filter": [
-        "any",
-        ["==", "tunnel", "yes"],
-        ["==", "tunnel", "culvert"]
-    ],
-    "source": "baremaps",
-    "source-layer": "waterway",
-    "layout": {
-        "line-cap": "round",
-        "line-join": "round",
-        "visibility": "visible"
-    },
-    "paint": {
-        "line-width": [
-            "interpolate",
-            ["exponential", 1.2],
-            ["zoom"],
-            4, 0, 20, 8
-        ],
-        "line-color": theme.waterwayTunnelLineLineColor
-    }
-}
diff --git a/basemap/style.js b/basemap/style.js
index ab23bca4..0ea9a4b0 100644
--- a/basemap/style.js
+++ b/basemap/style.js
@@ -18,7 +18,7 @@ import config from "./config.js";
 
 import background from "./layers/background/style.js";
 import aeroway_line from "./layers/aeroway/line.js";
-import aeroway_polygon from "./layers/aeroway/polygon.js";
+import aeroway_fill from "./layers/aeroway/fill.js";
 import amenity_background from "./layers/amenity/background.js";
 import amenity_fountain from "./layers/amenity/fountain.js";
 import amenity_overlay from "./layers/amenity/overlay.js";
@@ -37,31 +37,26 @@ import leisure_overlay from "./layers/leisure/overlay.js";
 import railway_tunnel from "./layers/railway/tunnel.js";
 import railway_line from "./layers/railway/line.js";
 
-
 import highway_line from './layers/highway/highway_line.js';
 import highway_outline from './layers/highway/highway_outline.js';
-import highway_dash from './layers/highway/highway_dash.js';
 import highway_tunnel_line from './layers/highway/tunnel_line.js';
 import highway_tunnel_outline from './layers/highway/tunnel_outline.js';
-import highway_pedestrian_area from './layers/highway/pedestrian_area.js';
+import highway_fill from './layers/highway/highway_fill.js';
 import highway_bridge_line from './layers/highway/bridge_line.js';
 import highway_bridge_outline from './layers/highway/bridge_outline.js';
 import highway_construction_line from "./layers/highway/construction_line.js";
-import highway_construction_dash from "./layers/highway/construction_dash.js";
 import highway_label from './layers/highway/highway_label.js';
 
 import ocean_overlay from './layers/ocean/overlay.js';
 import route_line from "./layers/route/style.js"
-import building_shape from "./layers/building/shape.js";
+import building_fill from "./layers/building/fill.js";
 import building_extrusion from "./layers/building/extrusion.js";
-import building_number from "./layers/building/number.js";
 import man_made_bridge from "./layers/man_made/bridge.js";
 import man_made_pier_line from "./layers/man_made/pier_line.js";
 import man_made_pier_label from "./layers/man_made/pier_label.js";
 import waterway_line from "./layers/waterway/line.js"
+import waterway_area from "./layers/waterway/area.js"
 import waterway_label from "./layers/waterway/label.js"
-import waterway_tunnel_line from "./layers/waterway/tunnel_line.js"
-import waterway_tunnel_casing from "./layers/waterway/tunnel_casing.js"
 import icon from "./layers/point/icon.js";
 import country_label from './layers/point/country_label.js';
 import point_label from './layers/point/point_label.js';
@@ -82,7 +77,7 @@ export default {
     "layers": [
         background,
         power_background,
-        aeroway_polygon,
+        aeroway_fill,
         landuse_background,
         leisure_background,
         amenity_background,
@@ -93,21 +88,17 @@ export default {
         leisure_overlay,
         ocean_overlay,
         waterway_line,
-        waterway_tunnel_casing,
-        waterway_tunnel_line,
+        waterway_area,
         man_made_bridge,
         amenity_fountain,
         highway_tunnel_outline,
         highway_tunnel_line,
         railway_tunnel,
-        building_shape,
-        building_number,
-        highway_construction_dash,
+        building_fill,
         highway_construction_line,
         highway_outline,
         highway_line,
-        highway_dash,
-        highway_pedestrian_area,
+        highway_fill,
         railway_line,
         highway_bridge_outline,
         highway_bridge_line,
diff --git a/basemap/themes/default.js b/basemap/themes/default.js
index 87ef3b61..05f70dcd 100644
--- a/basemap/themes/default.js
+++ b/basemap/themes/default.js
@@ -1,13 +1,13 @@
 export default {
-    aerialwayStyleLinePaintLineColor: 'rgb(177, 177, 175)',
-    aerowayLineRunwayLineColor: 'rgba(187, 187, 204, 1.0)',
-    aerowayLineTaxiwayLineColor: 'rgba(187, 187, 204, 1.0)',
-    aerowayPolygonLineColor: 'rgba(213, 213, 220, 1.0)',
+    aerialwayLineColor: 'rgb(177, 177, 175)',
+    aerowayRunwayLineColor: 'rgba(187, 187, 204, 1.0)',
+    aerowayTaxiwayLineColor: 'rgba(187, 187, 204, 1.0)',
+    aerowayPolygonColor: 'rgba(213, 213, 220, 1.0)',
     amenityBackgroundCollegeFillColor: 'rgb(255, 255, 228)',
     amenityBackgroundGraveYardFillColor: 'rgb(170, 203, 175)',
     amenityBackgroundHospitalFillColor: 'rgb(255, 255, 228)',
-    amenityBackgroundKinderGartenFillColor: 'rgb(255, 255, 228)',
-    amenityBackgroundSchoolFillColor: 'rgb(255, 255, 228)',
+    amenityKinderGartenFillColor: 'rgb(255, 255, 228)',
+    amenitySchoolFillColor: 'rgb(255, 255, 228)',
     amenityBackgroundUniversityFillColor: 'rgb(255, 255, 228)',
     amenityFountainFillColor: 'rgb(170, 211, 223)',
     amenityFountainFillOutlineColor: 'rgb(170, 211, 223)',
@@ -55,6 +55,7 @@ export default {
     constructionDashConstructionUnclassifiedLineColor: 'rgb(254, 254, 254)',
     constructionLineConstructionLivingStreetLineColor: 'rgb(207, 207, 207)',
     constructionLineConstructionMotorwayLineColor: 'rgb(233, 144, 161)',
+    constructionLineConstructionDefaultLineColor: 'rgb(170, 170, 170)',
     constructionLineConstructionPrimaryLineColor: 'rgb(253, 221, 179)',
     constructionLineConstructionRacewayLineColor: 'rgb(213, 211, 211)',
     constructionLineConstructionResidentialLineColor: 'rgb(211, 207, 206)',
@@ -71,18 +72,18 @@ export default {
     highwayDashTrackLineColor: 'rgb(177, 140, 63)',
     highwayLabelPaintTextColor: 'rgb(96,96,96)',
     highwayLabelPaintTextHaloColor: 'rgba(255,255,255,0.8)',
-    highwayLineBuswayLineColor: 'rgb(254, 254, 254)',
-    highwayLineLivingStreetLineColor: 'rgb(237, 237, 237)',
-    highwayLineMotorwayLineColor: 'rgb(233, 144, 161)',
-    highwayLinePedestrianLineColor: 'rgb(221, 221, 231)',
-    highwayLinePrimaryLineColor: 'rgb(253, 221, 179)',
-    highwayLineRacewayLineColor: 'rgb(255, 192, 203)',
-    highwayLineResidentialLineColor: 'rgb(254, 254, 254)',
-    highwayLineSecondaryLineColor: 'rgb(248, 250, 202)',
-    highwayLineServiceLineColor: 'rgb(254, 254, 254)',
-    highwayLineTertiaryLineColor: 'rgb(254, 254, 254)',
-    highwayLineTrunkLineColor: 'rgb(250, 193, 172)',
-    highwayLineUnclassifiedLineColor: 'rgb(254, 254, 254)',
+    highwayBuswayLineColor: 'rgb(254, 254, 254)',
+    highwayLivingStreetLineColor: 'rgb(237, 237, 237)',
+    highwayMotorwayLineColor: 'rgb(233, 144, 161)',
+    highwayPedestrianLineColor: 'rgb(221, 221, 231)',
+    highwayPrimaryLineColor: 'rgb(253, 221, 179)',
+    highwayRacewayLineColor: 'rgb(255, 192, 203)',
+    highwayResidentialLineColor: 'rgb(254, 254, 254)',
+    highwaySecondaryLineColor: 'rgb(248, 250, 202)',
+    highwayServiceLineColor: 'rgb(239,239,239)',
+    highwayTertiaryLineColor: 'rgb(254, 254, 254)',
+    highwayTrunkLineColor: 'rgb(250, 193, 172)',
+    highwayUnclassifiedLineColor: 'rgb(254, 254, 254)',
     highwayOutlineBuswayLineColor: 'rgb(190, 189, 188)',
     highwayOutlineLivingStreetLineColor: 'rgb(207, 207, 207)',
     highwayOutlineMotorwayLineColor: 'rgb(227, 82, 126)',
@@ -603,7 +604,36 @@ export default {
     tunnelOutlineUnclassifiedLineColor: 'rgba(211, 207, 206, 1)',
     waterwayLabelTextColor: 'rgba(26, 109, 187, 1)',
     waterwayLabelTextHaloColor: 'rgba(255, 255, 255, 0.8)',
-    waterwayLineWaterwayLineColor: 'rgb(170, 211, 223)',
-    waterwayTunnelCasingLineColor: 'rgb(170, 211, 223)',
-    waterwayTunnelLineLineColor: 'rgb(243, 247, 247)'
+    waterwayLineColor: 'rgb(170, 211, 223)',
+    waterwayTunnelColor: 'rgb(216,237,250)',
+    highwayMotorwayLineWidth: [5, 0.5, 16, 7],
+    highwayTrunkLineWidth: [5, 0.5, 16, 6],
+    highwayPrimaryLineWidth: [5, 0.5, 16, 6],
+    highwaySecondaryLineWidth: [5, 0.5, 16, 5],
+    highwayTertiaryLineWidth: [5, 0.5, 16, 4],
+    highwayBuswayLineWidth: [5, 0.5, 16, 4],
+    highwayUnclassifiedLineWidth: [5, 0.5, 16, 3],
+    highwayResidentialLineWidth: [5, 0.5, 16, 3],
+    highwayLivingStreetLineWidth: [5, 0.5, 16, 3],
+    highwayServiceLineWidth: [5, 0.5, 16, 2],
+    highwayRacewayLineWidth: [5, 0.5, 16, 3],
+    highwayPedestrianLineWidth: [5, 0.5, 16, 3],
+    highwayConstructionLineWidth: [5, 0.5, 16, 2],
+    highwayMinorLineWidth: [5, 0.5, 16, 0.5],
+    railwayAbandonedLineWidth: [5, 0.5, 16, 1],
+    railwayAllRailsLineWidth: [5, 0.5, 16, 2],
+    railwayConstructionLineWidth: [5, 0.5, 16, 1],
+    railwayFunicularLineWidth: [5, 0.5, 16, 1],
+    railwayLightRailLineWidth: [5, 0.5, 16, 1],
+    railwayNarrowGaugeLineWidth: [5, 0.5, 16, 1],
+    railwayServiceLineWidth: [5, 0.5, 16, 1],
+    railwayMarrowGaugeLineWidth: [5, 0.5, 16, 1],
+    railwayMiniatureLineWidth: [5, 0.5, 16, 0.5],
+    railwayMonorailLineWidth: [5, 0.5, 16, 2],
+    railwayPreservedLineWidth: [5, 0.5, 16, 2],
+    railwayRailLineWidth: [5, 0.5, 16, 3],
+    railwaySubwayLineWidth: [5, 0.5, 16, 3],
+    railwayTramLineWidth: [5, 0.5, 16, 3],
+    railwayDisusedLineWidth: [5, 0.5, 16, 1],
+    highwayOutlineWidth: [5, 0.5, 16, 1, 22, 1],
 };
diff --git a/basemap/utils/layer.js b/basemap/utils/layer.js
deleted file mode 100644
index 49f85665..00000000
--- a/basemap/utils/layer.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to you under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- **/
-export default function layer(layer) {
-    return {
-        id: layer['id'],
-        type: layer['type'],
-        filter: filter(layer),
-        source: layer['source'],
-        'source-layer': layer['source-layer'],
-        minzoom: layer['minzoom'],
-        maxzoom: layer['maxzoom'],
-        layout: layer['directives']
-            ? Object.assign(
-                {
-                    ...textFont(layer),
-                    ...textField(layer),
-                    ...textSize(layer),
-                    ...textMaxWidth(layer),
-                    ...iconImage(layer),
-                    ...lineSortKey(layer),
-                    ...fillSortKey(layer),
-                },
-                layer['layout'],
-            )
-            : layer['layout'],
-        paint: layer['directives']
-            ? Object.assign(
-                {
-                    ...textColor(layer),
-                    ...textHaloColor(layer),
-                    ...textHaloWidth(layer),
-                    ...iconColor(layer),
-                    ...fillColor(layer),
-                    ...fillOutlineColor(layer),
-                    ...lineColor(layer),
-                    ...lineWidth(layer),
-                    ...lineGapWidth(layer),
-                    ...roadWidth(layer),
-                    ...roadGapWidth(layer),
-                },
-                layer['paint'],
-            )
-            : layer['paint'],
-    }
-}
-
-function filter(layer) {
-    if (layer['filter'] && layer['directives']) {
-        return [
-            'all',
-            layer['filter'],
-            ['any', ...layer['directives'].map((rule) => rule['filter'])],
-        ]
-    } else if (layer['directives']) {
-        return ['any', ...layer['directives'].map((rule) => rule['filter'])]
-    } else if (layer['filter']) {
-        return layer['filter']
-    } else {
-        return []
-    }
-}
-
-
-function iconImage(layer) {
-    return mergeDirectives(layer, 'icon-image', 'none')
-}
-
-function iconColor(layer) {
-    return mergeDirectives(layer, 'icon-color', 'rgba(0, 0, 0, 0)')
-}
-
-function textFont(layer) {
-    return mergeDirectives(layer, 'text-font', "Arial")
-}
-
-function textField(layer) {
-    return mergeDirectives(layer, 'text-field', null)
-}
-
-function textSize(layer) {
-    return mergeDirectives(layer, 'text-size', 12)
-}
-
-function textMaxWidth(layer) {
-    return mergeDirectives(layer, 'text-max-width', 4)
-}
-
-function textColor(layer) {
-    return mergeDirectives(layer, 'text-color', 'rgba(0, 0, 0, 0)')
-}
-
-function textHaloColor(layer) {
-    return mergeDirectives(layer, 'text-halo-color', 'rgba(0, 0, 0, 0)')
-}
-
-function textHaloWidth(layer) {
-    return mergeDirectives(layer, 'text-halo-width', 0)
-}
-
-function fillColor(layer) {
-    return mergeDirectives(layer, 'fill-color', 'rgba(0, 0, 0, 0)')
-}
-
-function fillOutlineColor(layer) {
-    return mergeDirectives(layer, 'fill-outline-color', 'rgba(0, 0, 0, 0)')
-}
-
-function lineColor(layer) {
-    return mergeDirectives(layer, 'line-color', 'rgba(0, 0, 0, 0)')
-}
-
-function lineWidth(layer) {
-    return mergeDirectives(layer, 'line-width', 0)
-}
-
-function lineGapWidth(layer) {
-    return mergeDirectives(layer, 'line-gap-width', 0)
-}
-
-function lineSortKey(layer) {
-    return mergeDirectives(layer, 'line-sort-key', 0)
-}
-
-function fillSortKey(layer) {
-    return mergeDirectives(layer, 'fill-sort-key', 0)
-}
-
-function mergeDirectives(layer, property, value) {
-    let cases = layer['directives'].flatMap((rule) => {
-        if (rule[property]) {
-            return [rule['filter'], rule[property]]
-        } else {
-            return []
-        }
-    })
-    if (cases.length == 0) {
-        return {}
-    }
-    return {
-        [property]: ['case', ...cases, value],
-    }
-}
-
-function roadWidth(layer) {
-    return mergeInterpolatedDirective(layer, 'road-width', 'line-width', 1)
-}
-
-function roadGapWidth(layer) {
-    return mergeInterpolatedDirective(layer, 'road-gap-width', 
'line-gap-width', 1)
-}
-
-function mergeInterpolatedDirective(layer, property, alias, value) {
-    let cases = layer['directives'].flatMap((directive) => {
-        if (directive[property]) {
-            return [directive['filter'], directive[property]]
-        } else {
-            return []
-        }
-    })
-    if (cases.length == 0) {
-        return {}
-    }
-    return {
-        [alias]: [
-            'interpolate',
-            ['exponential', 1.1],
-            ['zoom'],
-            5,
-            0.1,
-            20,
-            ['case', ...cases, value],
-        ],
-    }
-}
-
-function groupBy(xs, key) {
-    return xs.reduce(function (rv, x) {
-        ;(rv[x[key]] = rv[x[key]] || []).push(x)
-        return rv
-    }, {})
-}
diff --git a/basemap/utils/utils.js b/basemap/utils/utils.js
index 622abf52..c05aaaa1 100644
--- a/basemap/utils/utils.js
+++ b/basemap/utils/utils.js
@@ -14,6 +14,7 @@
  See the License for the specific language governing permissions and
  limitations under the License.
  **/
+
 export function withSortKeys(directives) {
     return directives
         .map(withFillSortKey)
@@ -28,7 +29,7 @@ export function withFillSortKey(directive, index, array) {
 }
 
 export function withLineSortKey(directive, index, array) {
-    return directive['line-width'] ? {
+    return directive['line-width'] || directive['line-width-stops'] ? {
         ...directive,
         'line-sort-key': array.length - index,
     } : directive;
@@ -101,7 +102,7 @@ export function asFilterProperty(directives = [], filter = 
[]) {
     } else if (directives.length > 0) {
         return ['any', ...directives.map((rule) => rule['filter'])];
     } else if (filter.length > 0) {
-        return filter;
+        return ['all', filter];
     } else {
         return [];
     }
@@ -192,22 +193,49 @@ function mergeDirectives(directives, property, value) {
 }
 
 function roadWidth(directives) {
-    return mergeInterpolatedDirective(directives, 'road-width', 'line-width', 
1)
+    return mergeRoadDirective(directives, 'line-width-stops', 'line-width', 1)
 }
 
 function roadGapWidth(directives) {
-    return mergeInterpolatedDirective(directives, 'road-gap-width', 
'line-gap-width', 1)
+    return mergeRoadDirective(directives, 'line-gap-width-stops', 
'line-gap-width', 1)
 }
 
 function labelColor(directives) {
     return mergeInterpolatedColorDirective(directives, 'label-color', 
'text-color', 6, 8, 'rgb(0, 0, 0)')
 }
 
-
 function labelSize(directives) {
     return mergeInterpolatedNumberDirective(directives, 'label-size', 
'text-size', 6, 8, 4, 14)
 }
 
+function mergeRoadDirective(directives, property, alias, value) {
+    if (directives.filter((directive) => directive[property]).length == 0) {
+        return {};
+    }
+    var mergedDirective = [
+        'interpolate',
+        ['linear'],
+        ['zoom'],
+    ];
+    for (let zoom = 0; zoom <= 22; zoom++) {
+        mergedDirective.push(zoom);
+        let cases = ['case']
+        for (let directive of directives) {
+            if (directive[property]) {
+                let filter = directive['filter'];
+                let value = interpolate(zoom, directive[property]);
+                cases.push(filter);
+                cases.push(value);
+            }
+        }
+        cases.push(value);
+        mergedDirective.push(cases);
+    }
+    return {
+        [alias]: mergedDirective,
+    }
+}
+
 function mergeInterpolatedDirective(directives, property, alias, value) {
     let cases = directives.flatMap((rule) => {
         if (rule[property]) {
@@ -285,4 +313,42 @@ function groupBy(xs, key) {
         ;(rv[x[key]] = rv[x[key]] || []).push(x)
         return rv
     }, {})
-}
\ No newline at end of file
+}
+
+/**
+ * Given an array in the form of [zoom_level_n, value_n, zoom_level_m, 
value_m, ...], with n < m, n >= 0, and m <= 22,
+ * the function linearly interpolates the value for the given zoom level.
+ *
+ * The values before zoom_level_n are assumed to be equal to 0.
+ * The values after zoom_level_m are assumed to be equal to value_m * 2 ** 
(zoom - zoom_level_m).
+ *
+ * Here are a few examples:
+ * interpolate(0, [10, 1, 14, 5]) = 0
+ * interpolate(9, [10, 1, 14, 5]) = 0
+ * interpolate(10, [10, 1, 14, 5]) = 1
+ * interpolate(11, [10, 1, 14, 5]) = 2
+ * interpolate(12, [10, 1, 14, 5]) = 3
+ * interpolate(13, [10, 1, 14, 5]) = 4
+ * interpolate(14, [10, 1, 14, 5]) = 5
+ * interpolate(15, [10, 1, 14, 5]) = 10
+ * interpolate(17, [10, 1, 14, 5]) = 40
+ * interpolate(22, [10, 1, 14, 5]) = 5
+ */
+export function interpolate(zoom, values) {
+    let i = 0
+    while (i < values.length && zoom >= values[i]) {
+        i += 2;
+    }
+    if (i >= values.length) {
+        return values[values.length - 1] * 2 ** (zoom - values[values.length - 
2]);
+    }
+    if (i === 0) {
+        return 0;
+    }
+    const zoomN = values[i - 2];
+    const valueN = values[i - 1];
+    const zoomM = values[i];
+    const valueM = values[i + 1];
+    return valueN + (valueM - valueN) * (zoom - zoomN) / (zoomM - zoomN);
+}
+


Reply via email to