From b271e34441ffcfa4e239dce4c76ed25385cc5a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 21 Sep 2023 16:55:25 -0700 Subject: [PATCH 01/11] Rewrote road layer --- src/layer/index.js | 78 +-- src/layer/road.js | 1407 ++++---------------------------------------- 2 files changed, 120 insertions(+), 1365 deletions(-) diff --git a/src/layer/index.js b/src/layer/index.js index 740eb6061..197624815 100644 --- a/src/layer/index.js +++ b/src/layer/index.js @@ -75,9 +75,9 @@ export function build(locales) { lyrConstruction.road, - lyrRoad.roadTunnel.casing(), - - lyrRoad.roadTunnel.fill(), + //lyrRoad.roadTunnel.casing(), + // + //lyrRoad.roadTunnel.fill(), lyrOneway.tunnel, @@ -88,41 +88,7 @@ export function build(locales) { lyrAeroway.taxiway, lyrAeroway.taxiwayArea, - lyrRoad.motorwayLink.casing(), - lyrRoad.trunkLink.casing(), - - lyrRoad.roadLinkSimpleCasing.casing(), - - lyrRoad.motorway.casing(), - lyrRoad.trunk.casing(), - lyrRoad.primaryExpressway.casing(), - lyrRoad.secondaryExpressway.casing(), - lyrRoad.tertiaryExpressway.casing(), - - lyrRoad.roadSimpleCasing.casing(), - - lyrRoad.motorwayLink.fill(), - lyrRoad.roadLinkSimpleFill.fill(), - lyrRoad.primaryLink.fill(), - lyrRoad.primaryLinkToll.fill(), - lyrRoad.secondaryLink.fill(), - lyrRoad.secondaryLinkToll.fill(), - lyrRoad.tertiaryLink.fill(), - lyrRoad.tertiaryLinkToll.fill(), - - lyrRoad.minor.fill(), - lyrRoad.minorToll.fill(), - lyrRoad.busway.fill(), - lyrRoad.tertiary.fill(), - lyrRoad.tertiaryToll.fill(), - lyrRoad.secondary.fill(), - lyrRoad.secondaryToll.fill(), - lyrRoad.primary.fill(), - lyrRoad.primaryToll.fill(), - lyrRoad.roadSimpleFill.fill(), - lyrRoad.motorway.fill(), - - lyrRoad.road.surface(), + lyrRoad.road, lyrRail.rail.dashes(), lyrRail.railService.dashes(), @@ -147,41 +113,7 @@ export function build(locales) { var bridgeLayers = [ lyrRail.bridgeCasing, - lyrRoad.trunkLinkBridge.casing(), - lyrRoad.motorwayLinkBridge.casing(), - - lyrRoad.roadLinkSimpleCasingBridge.casing(), - - lyrRoad.tertiaryExpresswayBridge.casing(), - lyrRoad.secondaryExpresswayBridge.casing(), - lyrRoad.primaryExpresswayBridge.casing(), - lyrRoad.trunkBridge.casing(), - lyrRoad.motorwayBridge.casing(), - - lyrRoad.roadSimpleCasingBridge.casing(), - - lyrRoad.tertiaryLinkBridge.fill(), - lyrRoad.tertiaryLinkTollBridge.fill(), - lyrRoad.secondaryLinkBridge.fill(), - lyrRoad.secondaryLinkTollBridge.fill(), - lyrRoad.primaryLinkBridge.fill(), - lyrRoad.primaryLinkTollBridge.fill(), - lyrRoad.roadLinkSimpleFillBridge.fill(), - lyrRoad.motorwayLinkBridge.fill(), - - lyrRoad.minorBridge.fill(), - lyrRoad.minorTollBridge.fill(), - lyrRoad.buswayBridge.fill(), - lyrRoad.tertiaryBridge.fill(), - lyrRoad.tertiaryTollBridge.fill(), - lyrRoad.secondaryBridge.fill(), - lyrRoad.secondaryTollBridge.fill(), - lyrRoad.primaryBridge.fill(), - lyrRoad.primaryTollBridge.fill(), - lyrRoad.roadSimpleFillBridge.fill(), - lyrRoad.motorwayBridge.fill(), - - lyrRoad.roadBridge.surface(), + //lyrRoad.road, lyrRail.railBridge.dashes(), lyrRail.railServiceBridge.dashes(), diff --git a/src/layer/road.js b/src/layer/road.js index 5e98b1be8..d9505ea69 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -2,1344 +2,167 @@ import * as Util from "../js/util.js"; -//At this zoom, render switches from unified to differentiated bridge/tunnel rendering -const minzoomBrunnel = 11; - -const minZoomAllRoads = 4; -const minZoomMotorwayTrunk = 5; -const minZoomPrimary = 7; -const minZoomSecondary = 9; -const minZoomTertiary = 11; -const minZoomMinor = 12; -const minZoomService = 13; -const minZoomSmallService = 15; - -//Exponent base for inter-zoom interpolation -const roadExp = 1.2; - -const roadHue = 0; -const tollRoadHue = 48; -const buswayHue = 322; - -//Tunnel casing dash pattern -const tunDashArray = [ - "step", - ["zoom"], - ["literal", [1]], - minzoomBrunnel, - ["literal", [0.5, 0.25]], -]; - -const getBrunnel = ["get", "brunnel"]; -const getClass = ["get", "class"]; -const getExpressway = ["coalesce", ["get", "expressway"], 0]; -const getLayer = ["coalesce", ["get", "layer"], 0]; -const getRamp = ["coalesce", ["get", "ramp"], 0]; -const getToll = ["coalesce", ["get", "toll"], 0]; +const motorwayHue = 218; +const stateHue = 40; +const tollRoadHue = 100; // Common filter expressions -const classSelector = ["match", getClass]; -const tollSelector = ["match", getToll, 1]; -const isToll = ["==", getToll, 1]; -const isNotToll = ["!=", getToll, 1]; -const isLink = ["==", getRamp, 1]; -const isNotLink = ["!=", getRamp, 1]; -const linkSelector = ["match", getRamp, 1]; -const isExpressway = ["==", getExpressway, 1]; -const isNotExpressway = ["!=", getExpressway, 1]; -const expresswaySelector = ["match", getExpressway, 1]; -const smallServiceSelector = [ +const isRoad = [ + "match", + ["get", "class"], + ["motorway", "trunk", "primary", "secondary", "tertiary", "minor", "service", "busway", "bus_guideway"], + true, + false, +]; +const isNotRamp = ["!=", ["get", "ramp"], 1]; +const isToll = ["==", ["get", "toll"], 1]; +const isNotToll = ["!=", ["get", "toll"], 1]; +const isMotorway = ["all", ["==", ["get", "class"], "motorway"], isNotRamp]; +const isNotMotorway = ["!=", ["get", "class"], "motorway"]; +const isState = ["match", ["get", "network"], ["us-highway", "us-state"], isNotRamp, false]; +const isExpressway = ["==", ["get", "expressway"], 1]; +const isNotExpressway = ["!=", ["get", "expressway"], 1]; +const isService = ["==", ["get", "class"], "service"]; +const isNotService = ["!=", ["get", "class"], "service"]; +const isMinorService = [ "match", ["get", "service"], ["parking_aisle", "driveway"], + true, false, ]; -const isUnpaved = ["==", ["get", "surface"], "unpaved"]; +const isConstruction = ["in", "_construction", ["get", "class"]]; +const isNotConstruction = ["!", isConstruction]; -function combineConstraints(constraint1, constraint2) { - if (constraint1 == null) { - if (constraint2 == null) { - return null; - } - return constraint2; - } - if (constraint2 == null) { - return constraint1; - } - return ["all", constraint1, constraint2]; -} - -const opacity = [ - "step", - ["zoom"], - [...linkSelector, 0, ["match", ["get", "network"], "us-interstate", 1, 0]], - minZoomMotorwayTrunk, - [...linkSelector, 0, [...classSelector, ["motorway", "trunk"], 1, 0]], - minZoomPrimary, - [...classSelector, ["motorway", "trunk", "primary"], 1, 0], - minZoomSecondary, - [...classSelector, ["motorway", "trunk", "primary", "secondary"], 1, 0], - minZoomTertiary, - [ - ...classSelector, - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary", - "busway", - "bus_guideway", - ], - 1, - 0, - ], - minZoomMinor, - [...classSelector, "service", 0, 1], - minZoomService, - [...classSelector, "service", [...smallServiceSelector, 0, 1], 1], - minZoomSmallService, - 1, -]; - -const motorwaySortKey = [ - "+", - getLayer, - 0.1, - ["*", -0.1, getRamp], - ["*", 0.2, getToll], -]; - -const expresswaySortKey = [ - "+", - getLayer, - 0.1, - ["*", -0.1, getRamp], - ["*", 0.2, getToll], - ["*", 0.4, getExpressway], -]; - -//Helper function to create a "filter" block for a particular road class. -function filterRoad(brunnel, constraints) { - var baseFilter = [ - "in", - getClass, - [ - "literal", - [ - "motorway", - "trunk", - "primary", - "secondary", - "tertiary", - "busway", - "bus_guideway", - "minor", - "service", - ], - ], - ]; - baseFilter = combineConstraints(baseFilter, constraints); - if (brunnel == null) { - return baseFilter; - } - let brunnelFilter = - brunnel === "surface" - ? ["!", ["in", getBrunnel, ["literal", ["bridge", "tunnel"]]]] - : ["==", getBrunnel, brunnel]; - return combineConstraints(baseFilter, brunnelFilter); -} - -//Base definition that applies to all roads (fill and casing). -var defRoad = { +export const road = { + id: "road", type: "line", source: "openmaptiles", "source-layer": "transportation", -}; - -//Generate a unique layer ID -function uniqueLayerID(part, brunnel, constraints) { - var layerID = ["road", part].join("_"); - if (brunnel != null) { - layerID += "_" + brunnel; - } - if (constraints != null) { - layerID += - "_" + constraints.join("_").replaceAll("=", "").replaceAll("-", "_"); - } - return layerID; -} - -function baseRoadLayer(id, brunnel, minzoom, maxzoom, constraints) { - var layer = Util.layerClone(defRoad, uniqueLayerID(id, brunnel, constraints)); - var roadFilter = filterRoad(brunnel, constraints); - if (roadFilter != null) { - layer.filter = roadFilter; - } - layer.minzoom = minzoom; - if (maxzoom) { - layer.maxzoom = maxzoom; - } - return layer; -} - -const widthFactor = [ - ...classSelector, - ["motorway", "trunk"], - [...linkSelector, 0.5, 1], - "primary", - [...linkSelector, 0.45, 0.9], - "secondary", - [...linkSelector, 0.3, [...expresswaySelector, 0.7, 0.6]], - ["tertiary", "busway", "bus_guideway"], - [...linkSelector, 0.25, 0.5], - "minor", - 0.3, - "service", - [...smallServiceSelector, 0.15, 0.2], - 0.2, -]; - -const roadFillWidth = [ - 4, - ["*", 0.5, widthFactor], - 9, - widthFactor, - 12, - [ - "*", - [...classSelector, "motorway", 3.2, [...expresswaySelector, 3.5, 4]], - widthFactor, - ], - 20, - ["*", [...expresswaySelector, 16, 18], widthFactor], -]; - -const roadCasingWidth = [ - 4, - ["*", [...classSelector, "motorway", 1.5, 0.5], widthFactor], - 9, - [ - "*", - [...classSelector, "motorway", 3, [...expresswaySelector, 3, 1.2]], - widthFactor, - ], - 12, - [ - "*", - [...classSelector, "motorway", 5, [...expresswaySelector, 7, 5]], - widthFactor, - ], - 20, - ["*", [...expresswaySelector, 28, 22], widthFactor], -]; - -const roadCasingColorTunnel = [ - "match", - getBrunnel, - "tunnel", - [ - ...classSelector, - ["motorway", "trunk"], - [ - ...tollSelector, - [ - ...expresswaySelector, - `hsl(${tollRoadHue}, 41%, 85%)`, - `hsl(${tollRoadHue}, 41%, 80%)`, - ], - `hsl(${roadHue}, 41%, 80%)`, - ], - ["primary", "secondary", "tertiary", "busway", "bus_guideway"], - "hsl(0, 0%, 80%)", - "hsl(0, 0%, 90%)", - ], -]; - -const roadCasingColorTrunkExpressway = [ - ...classSelector, - "trunk", - [ - ...tollSelector, - `hsl(${tollRoadHue}, 77%, 50%)`, - `hsl(${roadHue}, 77%, 50%)`, - ], -]; - -const roadCasingColor = [ - "step", - ["zoom"], - [ - ...roadCasingColorTunnel, - [...roadCasingColorTrunkExpressway, `hsl(0, 0%, 90%)`], - ], - 15, - [ - ...roadCasingColorTunnel, - [...roadCasingColorTrunkExpressway, `hsl(0, 0%, 23%)`], - ], -]; - -const roadFillColorTunnel = [ - "match", - getBrunnel, - "tunnel", - [ - ...classSelector, - "motorway", - [ - ...tollSelector, - `hsl(${tollRoadHue}, 71%, 90%)`, - `hsl(${roadHue}, 71%, 90%)`, - ], - "trunk", - [ - ...tollSelector, - `hsl(${tollRoadHue}, 77%, 90%)`, - `hsl(${roadHue}, 77%, 90%)`, - ], - ["busway", "bus_guideway"], - `hsl(${buswayHue}, 25%, 93%)`, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 100%, 95%)`, - `hsl(${roadHue}, 0%, 95%)`, - ], - ], -]; - -const highwayFillColor = [ - ...roadFillColorTunnel, - [ - ...classSelector, - "trunk", - [ - ...expresswaySelector, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 95%, 95%)`, - `hsl(${roadHue}, 95%, 95%)`, - ], - [ - ...tollSelector, - `hsl(${tollRoadHue}, 77%, 50%)`, - `hsl(${roadHue}, 77%, 50%)`, - ], - ], - [ - ...tollSelector, - `hsl(${tollRoadHue}, 100%, 75%)`, - `hsl(${roadHue}, 100%, 100%)`, - ], - ], -]; - -const roadSurfaceColor = [ - ...classSelector, - "motorway", - [ - ...tollSelector, - `hsl(${tollRoadHue}, 50%, 70%)`, - `hsl(${roadHue}, 50%, 70%)`, - ], - "trunk", - [ - ...tollSelector, - `hsl(${tollRoadHue}, 95%, 80%)`, - `hsl(${roadHue}, 95%, 80%)`, - ], - [ - ...tollSelector, - `hsl(${tollRoadHue}, 100%, 40%)`, - `hsl(${roadHue}, 0%, 80%)`, - ], -]; - -function roadFillColor(hue, minZoom, transitionZoom) { - let transitionStop = transitionZoom - ? [transitionZoom, `hsl(${hue}, 0%, 23%)`] - : []; - return [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - minZoom, - `hsl(${hue}, 0%, 75%)`, - ...transitionStop, - 14.9999, - `hsl(${hue}, 0%, 23%)`, - 15, - `hsl(${hue}, 100%, 100%)`, - ]; -} - -function tollRoadFillColor(hue, minZoom, transitionZoom) { - let transitionStop = transitionZoom - ? [transitionZoom, `hsl(${hue}, 100%, 40%)`] - : []; - return [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - minZoom, - `hsl(${hue}, 100%, 75%)`, - ...transitionStop, - 14.9999, - `hsl(${hue}, 100%, 40%)`, - 15, - `hsl(${hue}, 100%, 75%)`, - ]; -} - -function expresswayCasingColor(minZoom, transitionZoom) { - return [ - "interpolate", - ["exponential", roadExp], + filter: [ + "step", ["zoom"], - minZoom, - `hsl(0, 0%, 75%)`, - transitionZoom, - `hsl(0, 0%, 23%)`, - ]; -} - -//Base road class -class Road { - constructor() { - this.brunnel = "surface"; - this.minZoomFill = 4; - this.minZoomCasing = 4; - this.casingColor = roadCasingColor; - this.fillColor = highwayFillColor; - this.sortKey = expresswaySortKey; - } - fill = function () { - var layer = baseRoadLayer( - "fill", - this.brunnel, - this.minZoomFill, - this.maxZoomFill, - this.constraints - ); - layer.layout = { - "line-cap": "round", - "line-join": "round", - visibility: "visible", - "line-sort-key": this.sortKey, - }; - layer.paint = { - "line-opacity": opacity, - "line-color": this.fillColor, - "line-width": [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - ...roadFillWidth, - ], - "line-blur": 0.5, - }; - return layer; - }; - casing = function () { - var layer = baseRoadLayer( - "casing", - this.brunnel, - this.minZoomCasing, - this.maxZoomCasing, - this.constraints - ); - layer.layout = { - "line-cap": this.brunnel === "bridge" ? "butt" : "round", - "line-join": this.brunnel === "bridge" ? "bevel" : "round", - visibility: "visible", - "line-sort-key": this.sortKey, - }; - layer.paint = { - "line-opacity": opacity, - "line-color": this.casingColor, - "line-width": [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - ...roadCasingWidth, - ], - }; - if (this.brunnel === "tunnel") { - layer.paint["line-dasharray"] = tunDashArray; - } else { - layer.paint["line-blur"] = 0.5; - } - return layer; - }; - surface = function () { - var layer = baseRoadLayer( - "surface", - this.brunnel, - Math.min(this.minZoomCasing, this.minZoomFill), - Math.max(this.maxZoomCasing, this.maxZoomFill), - this.constraints - ); - layer.filter = combineConstraints(layer.filter, isUnpaved); - layer.layout = { - "line-cap": "butt", - "line-join": "round", - visibility: "visible", - "line-sort-key": this.sortKey, - }; - layer.paint = { - "line-opacity": opacity, - "line-dasharray": [4, 4], - "line-color": roadSurfaceColor, - "line-width": [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - ...roadFillWidth, - ], - "line-blur": 0.5, - }; - return layer; - }; -} - -class RoadSimpleCasing extends Road { - constructor() { - super(); - this.constraints = [ - "any", - [ - "all", - ["!", ["in", getClass, ["literal", ["motorway", "trunk"]]]], - isNotExpressway, - isNotLink, - ], - ["all", ["==", getClass, "trunk"], isExpressway], - ]; - } -} - -class RoadLinkSimpleCasing extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["!", ["in", getClass, ["literal", ["motorway", "trunk"]]]], - isNotExpressway, - isLink, - ]; - } -} - -class RoadSimpleFill extends Road { - constructor() { - super(); - this.constraints = [ - "any", - ["all", ["==", getClass, "trunk"], isNotLink], - [ - "all", - [ - "in", - getClass, - [ - "literal", - ["primary", "secondary", "tertiary", "busway", "bus_guideway"], - ], - ], - isExpressway, - ], - ]; - } -} - -class RoadLinkSimpleFill extends Road { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "trunk"], isLink]; - } -} - -class RoadBridge extends Road { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class RoadSimpleCasingBridge extends RoadSimpleCasing { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class RoadLinkSimpleCasingBridge extends RoadLinkSimpleCasing { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class RoadSimpleFillBridge extends RoadSimpleFill { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class RoadLinkSimpleFillBridge extends RoadLinkSimpleFill { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class RoadTunnel extends Road { - constructor() { - super(); - this.brunnel = "tunnel"; - } -} - -//Highway class styles -class Motorway extends Road { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "motorway"], isNotLink]; - this.sortKey = motorwaySortKey; - this.minZoomFill = minZoomAllRoads; - this.minZoomCasing = minZoomAllRoads; - - this.fillColor = [ - "interpolate", - ["exponential", roadExp], + false, + 4, ["all", ["==", ["get", "network"], "us-interstate"], isNotConstruction], + 5, ["match", ["get", "class"], ["motorway", "trunk"], isNotRamp, false], + 7, ["match", ["get", "class"], ["motorway", "trunk", "primary"], isNotRamp, false], + 9, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary"], true, false], + 11, ["all", isRoad, isNotService, isNotConstruction], + 12, ["all", isRoad, ["!", isMinorService], isNotConstruction], + 13, ["all", isRoad, isNotConstruction], + ], + layout: { + "line-cap": "butt", + "line-join": "round", + // TODO: line-sort-key + }, + paint: { + "line-color": [ + "interpolate-lab", + ["exponential", 1.2], ["zoom"], 4, [ - ...tollSelector, - `hsl(${tollRoadHue}, 70%, 76%)`, - `hsl(${roadHue}, 70%, 76%)`, - ], - 6, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 70%, 66%)`, - `hsl(${roadHue}, 70%, 66%)`, + "case", + isToll, `hsl(${tollRoadHue}, 60%, 70%)`, + isMotorway, `hsl(${motorwayHue}, 60%, 70%)`, + isState, `hsl(${stateHue}, 77%, 50%)`, + "#9c9c9c", ], - minzoomBrunnel - 0.5, + 8, [ - ...tollSelector, - `hsl(${tollRoadHue}, 70%, 60%)`, - `hsl(${roadHue}, 70%, 60%)`, + "case", + isToll, `hsl(${tollRoadHue}, 100%, 40%)`, + isMotorway, `hsl(${motorwayHue}, 100%, 45%)`, + isState, `hsl(${stateHue}, 77%, 50%)`, + "#9c9c9c", ], 14, [ - ...tollSelector, - `hsl(${tollRoadHue}, 71%, 45%)`, - `hsl(${roadHue}, 71%, 35%)`, + "case", + isToll, `hsl(${tollRoadHue}, 100%, 35%)`, + isMotorway, `hsl(${motorwayHue}, 100%, 35%)`, + isState, `hsl(${stateHue}, 77%, 50%)`, + "#9c9c9c", ], - ]; - this.casingColor = [ + ], + "line-width": [ "interpolate", - ["exponential", roadExp], + ["exponential", 1.2], ["zoom"], 4, + 1, + 8, [ - ...tollSelector, - `hsl(${tollRoadHue}, 10%, 85%)`, - `hsl(${roadHue}, 10%, 85%)`, - ], - 6, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 60%, 50%)`, - `hsl(${roadHue}, 60%, 50%)`, + "case", + isMotorway, 3, + ["all", isState, isNotExpressway], 2, + 1, ], - minzoomBrunnel - 0.5, + 18, [ - ...tollSelector, - `hsl(${tollRoadHue}, 71%, 40%)`, - `hsl(${roadHue}, 71%, 40%)`, + "case", + isMotorway, 6, + ["all", isState, isNotExpressway], 4, + isService, 1, + 3, ], - 14, + 20, [ - ...tollSelector, - `hsl(${tollRoadHue}, 51%, 9%)`, - `hsl(${roadHue}, 51%, 9%)`, + "case", + isMotorway, 10, + ["all", isState, isNotExpressway], 8, + isService, 1, + 6, ], - ]; - } -} - -class Trunk extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "trunk"], - isNotLink, - isNotExpressway, - ]; - - this.minZoomFill = minZoomAllRoads; - this.minZoomCasing = minZoomAllRoads; - - this.fillColor = highwayFillColor; - this.casingColor = [ - "interpolate", - ["exponential", roadExp], - ["zoom"], - 5, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 77%, 50%)`, - `hsl(${roadHue}, 77%, 50%)`, - ], - 9, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 77%, 50%)`, - `hsl(${roadHue}, 77%, 50%)`, - ], - 15, - [ - ...tollSelector, - `hsl(${tollRoadHue}, 70%, 18%)`, - `hsl(${roadHue}, 70%, 18%)`, - ], - ]; - } -} - -class Primary extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "primary"], - isNotLink, - isNotExpressway, - isNotToll, - ]; - - this.minZoomFill = minZoomPrimary; - this.minZoomCasing = minZoomPrimary; - - this.fillColor = roadFillColor( - roadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class PrimaryToll extends Primary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "primary"], - isNotLink, - isNotExpressway, - isToll, - ]; - - this.fillColor = tollRoadFillColor( - tollRoadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class PrimaryExpressway extends Primary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "primary"], - isNotLink, - isExpressway, - ]; - - this.fillColor = highwayFillColor; - this.casingColor = expresswayCasingColor( - this.minZoomCasing, - this.minZoomCasing + 2 - ); - } -} - -class Secondary extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "secondary"], - isNotLink, - isNotExpressway, - isNotToll, - ]; - - this.minZoomFill = minZoomSecondary; - this.minZoomCasing = minZoomSecondary; - - this.fillColor = roadFillColor( - roadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class SecondaryToll extends Secondary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "secondary"], - isNotLink, - isNotExpressway, - isToll, - ]; - - this.fillColor = tollRoadFillColor( - tollRoadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class SecondaryExpressway extends Secondary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "secondary"], - isNotLink, - isExpressway, - ]; - - this.fillColor = highwayFillColor; - this.casingColor = expresswayCasingColor( - this.minZoomCasing, - this.minZoomCasing + 2 - ); - } -} - -class Tertiary extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "tertiary"], - isNotLink, - isNotExpressway, - isNotToll, - ]; - - this.minZoomFill = minZoomTertiary; - this.minZoomCasing = minZoomTertiary; - - this.fillColor = roadFillColor( - roadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class TertiaryToll extends Tertiary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "tertiary"], - isNotLink, - isNotExpressway, - isToll, - ]; - - this.fillColor = tollRoadFillColor( - tollRoadHue, - this.minZoomFill, - this.minZoomFill + 2 - ); - } -} - -class TertiaryExpressway extends Tertiary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "tertiary"], - isNotLink, - isExpressway, - ]; - - this.fillColor = highwayFillColor; - this.casingColor = expresswayCasingColor( - this.minZoomCasing, - this.minZoomCasing + 2 - ); - } -} - -class Busway extends Tertiary { - constructor() { - super(); - this.constraints = [ - "in", - getClass, - ["literal", ["busway", "bus_guideway"]], - ]; - - this.minZoomFill = minZoomTertiary; - this.minZoomCasing = minZoomTertiary; - - this.fillColor = [ + ], + "line-gap-width": [ "interpolate", - ["exponential", roadExp], + ["exponential", 1.2], ["zoom"], - this.minZoomFill, - `hsl(${buswayHue}, 25%, 75%)`, - this.minZoomFill + 2, - `hsl(${buswayHue}, 25%, 50%)`, - 14.9999, - `hsl(${buswayHue}, 25%, 50%)`, - 15, - `hsl(${buswayHue}, 25%, 80%)`, - ]; - this.surfaceColor = `hsl(${this.hue}, 0%, 80%)`; - } -} - -class Minor extends Road { - constructor() { - super(); - this.constraints = [ - "all", - ["in", getClass, ["literal", ["minor", "service"]]], - isNotToll, - ]; - - this.minZoomFill = minZoomMinor; - this.minZoomCasing = minZoomMinor; - - this.fillColor = roadFillColor(roadHue, this.minZoomFill); - } -} - -class MinorToll extends Minor { - constructor() { - super(); - this.constraints = [ - "all", - ["in", getClass, ["literal", ["minor", "service"]]], - isToll, - ]; - - this.fillColor = tollRoadFillColor(tollRoadHue, this.minZoomFill); - } -} - -class MotorwayLink extends Motorway { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "motorway"], isLink]; - this.minZoomFill = minZoomPrimary; - this.minZoomCasing = minZoomPrimary; - } -} - -class TrunkLink extends Trunk { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "trunk"], isLink]; - this.minZoomFill = minZoomPrimary; - this.minZoomCasing = minZoomPrimary; - } -} - -class PrimaryLink extends Primary { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "primary"], isLink, isNotToll]; - } -} - -class PrimaryLinkToll extends PrimaryToll { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "primary"], isLink, isToll]; - } -} - -class SecondaryLink extends Secondary { - constructor() { - super(); - this.constraints = [ - "all", - ["==", getClass, "secondary"], - isLink, - isNotToll, - ]; - } -} - -class SecondaryLinkToll extends SecondaryToll { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "secondary"], isLink, isToll]; - } -} - -class TertiaryLink extends Tertiary { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "tertiary"], isLink, isNotToll]; - } -} - -class TertiaryLinkToll extends TertiaryToll { - constructor() { - super(); - this.constraints = ["all", ["==", getClass, "tertiary"], isLink, isToll]; - } -} - -//Bridges -class MotorwayBridge extends Motorway { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class TrunkBridge extends Trunk { - constructor() { - super(); - this.brunnel = "bridge"; - } -} - -class PrimaryBridge extends Primary { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class PrimaryTollBridge extends PrimaryToll { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class PrimaryExpresswayBridge extends PrimaryExpressway { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class SecondaryBridge extends Secondary { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class SecondaryTollBridge extends SecondaryToll { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class SecondaryExpresswayBridge extends SecondaryExpressway { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class TertiaryBridge extends Tertiary { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class TertiaryTollBridge extends TertiaryToll { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class TertiaryExpresswayBridge extends TertiaryExpressway { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class BuswayBridge extends Busway { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class MinorBridge extends Minor { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class MinorTollBridge extends MinorToll { - constructor() { - //undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class MotorwayLinkBridge extends MotorwayLink { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class TrunkLinkBridge extends TrunkLink { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class PrimaryLinkBridge extends PrimaryLink { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class PrimaryLinkTollBridge extends PrimaryLinkToll { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class SecondaryLinkBridge extends SecondaryLink { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class SecondaryLinkTollBridge extends SecondaryLinkToll { - constructor() { - super(); - //Undifferentiated - this.brunnel = "bridge"; - } -} - -class TertiaryLinkBridge extends TertiaryLink { - constructor() { - //Undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -class TertiaryLinkTollBridge extends TertiaryLinkToll { - constructor() { - //Undifferentiated - super(); - this.brunnel = "bridge"; - } -} - -export const road = new Road(); -export const roadBridge = new RoadBridge(); -export const roadTunnel = new RoadTunnel(); - -export const roadSimpleCasing = new RoadSimpleCasing(); -export const roadLinkSimpleCasing = new RoadLinkSimpleCasing(); -export const roadSimpleCasingBridge = new RoadSimpleCasingBridge(); -export const roadLinkSimpleCasingBridge = new RoadLinkSimpleCasingBridge(); - -export const roadSimpleFill = new RoadSimpleFill(); -export const roadLinkSimpleFill = new RoadLinkSimpleFill(); -export const roadSimpleFillBridge = new RoadSimpleFillBridge(); -export const roadLinkSimpleFillBridge = new RoadLinkSimpleFillBridge(); - -export const motorway = new Motorway(); -export const trunk = new Trunk(); -export const primary = new Primary(); -export const primaryToll = new PrimaryToll(); -export const primaryExpressway = new PrimaryExpressway(); -export const secondary = new Secondary(); -export const secondaryToll = new SecondaryToll(); -export const secondaryExpressway = new SecondaryExpressway(); -export const tertiary = new Tertiary(); -export const tertiaryToll = new TertiaryToll(); -export const tertiaryExpressway = new TertiaryExpressway(); -export const busway = new Busway(); -export const minor = new Minor(); -export const minorToll = new MinorToll(); - -export const motorwayBridge = new MotorwayBridge(); -export const trunkBridge = new TrunkBridge(); -export const primaryBridge = new PrimaryBridge(); -export const primaryTollBridge = new PrimaryTollBridge(); -export const primaryExpresswayBridge = new PrimaryExpresswayBridge(); -export const secondaryBridge = new SecondaryBridge(); -export const secondaryTollBridge = new SecondaryTollBridge(); -export const secondaryExpresswayBridge = new SecondaryExpresswayBridge(); -export const tertiaryBridge = new TertiaryBridge(); -export const tertiaryTollBridge = new TertiaryTollBridge(); -export const tertiaryExpresswayBridge = new TertiaryExpresswayBridge(); -export const buswayBridge = new BuswayBridge(); -export const minorBridge = new MinorBridge(); -export const minorTollBridge = new MinorTollBridge(); - -export const motorwayLink = new MotorwayLink(); -export const trunkLink = new TrunkLink(); -export const primaryLink = new PrimaryLink(); -export const primaryLinkToll = new PrimaryLinkToll(); -export const secondaryLink = new SecondaryLink(); -export const secondaryLinkToll = new SecondaryLinkToll(); -export const tertiaryLink = new TertiaryLink(); -export const tertiaryLinkToll = new TertiaryLinkToll(); - -export const motorwayLinkBridge = new MotorwayLinkBridge(); -export const trunkLinkBridge = new TrunkLinkBridge(); -export const primaryLinkBridge = new PrimaryLinkBridge(); -export const primaryLinkTollBridge = new PrimaryLinkTollBridge(); -export const secondaryLinkBridge = new SecondaryLinkBridge(); -export const secondaryLinkTollBridge = new SecondaryLinkTollBridge(); -export const tertiaryLinkBridge = new TertiaryLinkBridge(); -export const tertiaryLinkTollBridge = new TertiaryLinkTollBridge(); - -const normalRoadLayers = [ - motorway.fill().id, - motorway.casing().id, - trunk.casing().id, - primaryToll.fill().id, - secondaryToll.fill().id, - tertiaryToll.fill().id, - minorToll.fill().id, - roadSimpleCasing.casing().id, -]; + 4, + ["case", isExpressway, 1, 0], + 8, + ["case", isExpressway, 1, 0], + 14, + 0, + ], + }, +}; export const legendEntries = [ { - description: "Freeway (controlled access, divided)", - layers: [motorway.fill().id, motorway.casing().id], - filter: isNotToll, + description: "Controlled-access highway", + layers: [road.id], + filter: ["all", isMotorway, isNotToll], }, { - description: "Expressway (limited access, divided)", - layers: [ - roadSimpleFill.fill().id, - roadSimpleCasing.casing().id, - primaryExpressway.casing().id, - primaryExpressway.casing().id, - secondaryExpressway.casing().id, - tertiaryExpressway.casing().id, - ], + description: "Limited-access highway", + layers: [road.id], filter: ["all", isExpressway, isNotToll], }, { - description: "Principal highway", - layers: [trunk.casing().id], - filter: isNotToll, - }, - { - description: "Major arterial road", - layers: [primary.fill().id, roadSimpleCasing.casing().id], - filter: ["==", getClass, "primary"], - }, - { - description: "Minor arterial road", - layers: [secondary.fill().id, roadSimpleCasing.casing().id], - filter: ["==", getClass, "secondary"], - }, - { - description: "Collector road", - layers: [tertiary.fill().id, roadSimpleCasing.casing().id], - filter: ["==", getClass, "tertiary"], + description: "State highway", + layers: [road.id], + filter: ["all", isState, isNotToll, isNotExpressway], }, { description: "Local road", - layers: [minor.fill().id, roadSimpleCasing.casing().id], - filter: ["match", getClass, ["minor", "service"], true, false], + layers: [road.id], + filter: ["all", isNotMotorway, isNotToll, isNotExpressway, isNotRamp, isNotService], }, { - description: "Driveway or parking aisle", - layers: [minor.fill().id, roadSimpleCasing.casing().id], - filter: [ - "all", - ["==", getClass, "service"], - [...smallServiceSelector, true, false], - ], + description: "Service road", + layers: [road.id], + filter: isService, }, { description: "Toll road", - layers: [ - motorway.fill().id, - motorway.casing().id, - trunk.casing().id, - primaryToll.fill().id, - secondaryToll.fill().id, - tertiaryToll.fill().id, - minorToll.fill().id, - roadSimpleCasing.casing().id, - ], - filter: isToll, - }, - { - description: "Busway", - layers: [busway.fill().id, roadSimpleCasing.casing().id], - filter: ["==", getClass, "busway"], - }, - { - description: "Unpaved road", - layers: [ - road.surface().id, - trunk.casing().id, - primary.fill().id, - secondary.fill().id, - tertiary.fill().id, - minor.fill().id, - roadSimpleCasing.casing().id, - ], - filter: isUnpaved, + layers: [road.id], + filter: ["all", isToll, isNotRamp], }, + //{ + // description: "Unpaved road", + // layers: [road.id], + // filter: isUnpaved, + //}, ]; From c60e0a1f770f278517bd351e2d50ec539da216a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 01:05:21 -0700 Subject: [PATCH 02/11] Wider arterials, thinner local streets --- src/layer/road.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/layer/road.js b/src/layer/road.js index d9505ea69..b075c802f 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -95,14 +95,17 @@ export const road = { [ "case", isMotorway, 3, - ["all", isState, isNotExpressway], 2, - 1, + isExpressway, 1, + isState, 2, + ["match", ["get", "class"], ["trunk", "primary"], isNotRamp, false], 2, + 0.25, ], 18, [ "case", isMotorway, 6, ["all", isState, isNotExpressway], 4, + ["match", ["get", "class"], ["trunk", "primary", "secondary", "tertiary"], isNotRamp, false], 4, isService, 1, 3, ], @@ -111,6 +114,7 @@ export const road = { "case", isMotorway, 10, ["all", isState, isNotExpressway], 8, + ["match", ["get", "class"], ["trunk", "primary", "secondary", "tertiary"], isNotRamp, false], 8, isService, 1, 6, ], @@ -121,8 +125,8 @@ export const road = { ["zoom"], 4, ["case", isExpressway, 1, 0], - 8, - ["case", isExpressway, 1, 0], + 12, + ["case", isExpressway, 3, 0], 14, 0, ], From 1241fbb8b16daa74eb4af5908715cc3252108311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 01:14:16 -0700 Subject: [PATCH 03/11] Darkened ramps at high zoom levels --- src/layer/road.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layer/road.js b/src/layer/road.js index b075c802f..c8605cc55 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -14,7 +14,8 @@ const isRoad = [ true, false, ]; -const isNotRamp = ["!=", ["get", "ramp"], 1]; +const isRamp = ["==", ["get", "ramp"], 1]; +const isNotRamp = ["!", isRamp]; const isToll = ["==", ["get", "toll"], 1]; const isNotToll = ["!=", ["get", "toll"], 1]; const isMotorway = ["all", ["==", ["get", "class"], "motorway"], isNotRamp]; @@ -82,6 +83,7 @@ export const road = { isToll, `hsl(${tollRoadHue}, 100%, 35%)`, isMotorway, `hsl(${motorwayHue}, 100%, 35%)`, isState, `hsl(${stateHue}, 77%, 50%)`, + ["all", ["==", ["get", "class"], "motorway"], isRamp], "#000", "#9c9c9c", ], ], From c493f3a06f1ed7e6bebdf79da1611eb2ba641103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 01:28:20 -0700 Subject: [PATCH 04/11] Sort roads by network within layer --- src/layer/road.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/layer/road.js b/src/layer/road.js index c8605cc55..925676cb9 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -54,7 +54,12 @@ export const road = { layout: { "line-cap": "butt", "line-join": "round", - // TODO: line-sort-key + "line-sort-key": [ + "+", + ["to-number", isMotorway], + ["to-number", isState], + ["to-number", isRamp], + ], }, paint: { "line-color": [ From ecc31fbedf4289b5540877637d6b61155d8a38e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 01:38:59 -0700 Subject: [PATCH 05/11] Recolored roads under construction --- src/layer/construction.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/layer/construction.js b/src/layer/construction.js index 7f653ba0a..d1b9c800f 100644 --- a/src/layer/construction.js +++ b/src/layer/construction.js @@ -1,9 +1,10 @@ "use strict"; +const motorwayHue = 218; const majorConstruction = [ "match", ["get", "class"], - ["motorway_construction", "trunk_construction"], + "motorway_construction", ]; export const road = { @@ -34,11 +35,11 @@ export const road = { ["exponential", 2], ["zoom"], 10, - [...majorConstruction, "lightcoral", "lightslategray"], + [...majorConstruction, `hsl(${motorwayHue}, 60%, 70%)`, "lightslategray"], 13, - [...majorConstruction, "maroon", "lightslategray"], + [...majorConstruction, `hsl(${motorwayHue}, 100%, 45%)`, "lightslategray"], 15, - [...majorConstruction, "maroon", "slategray"], + [...majorConstruction, `hsl(${motorwayHue}, 100%, 35%)`, "slategray"], ], "line-opacity": ["interpolate", ["exponential", 2], ["zoom"], 10, 0, 11, 1], "line-blur": 0.75, From aa4da15f8e90ae6a6ddd659b09fa7b562cb9105a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 01:51:55 -0700 Subject: [PATCH 06/11] Offset one-way arrows off to the side --- src/layer/oneway.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/layer/oneway.js b/src/layer/oneway.js index ba681dcec..989a1c45a 100644 --- a/src/layer/oneway.js +++ b/src/layer/oneway.js @@ -53,19 +53,7 @@ export const surface = { 0.6, ], ], - "icon-image": [ - "match", - ["get", "brunnel"], - "tunnel", - "oneway_black", - [ - "match", - ["get", "toll"], - 1, - "oneway_black", - [...highwaySelector, "motorway", "oneway_white", "oneway_black"], - ], - ], + "icon-image": "oneway_black", visibility: "visible", "icon-padding": 2, "symbol-spacing": [ @@ -79,6 +67,8 @@ export const surface = { ], "symbol-placement": "line", "icon-rotation-alignment": "map", + // Assumes driving on the right. + "icon-offset": [0, 10], }, paint: { "icon-opacity": 0.5, From 027509b8c79b8187695d4e465b335cc06738753d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 02:09:47 -0700 Subject: [PATCH 07/11] Blur unpaved roads --- src/layer/road.js | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/layer/road.js b/src/layer/road.js index 925676cb9..b955d06ab 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -17,14 +17,15 @@ const isRoad = [ const isRamp = ["==", ["get", "ramp"], 1]; const isNotRamp = ["!", isRamp]; const isToll = ["==", ["get", "toll"], 1]; -const isNotToll = ["!=", ["get", "toll"], 1]; +const isNotToll = ["!", isToll]; const isMotorway = ["all", ["==", ["get", "class"], "motorway"], isNotRamp]; const isNotMotorway = ["!=", ["get", "class"], "motorway"]; const isState = ["match", ["get", "network"], ["us-highway", "us-state"], isNotRamp, false]; +const isNotState = ["!", isState]; const isExpressway = ["==", ["get", "expressway"], 1]; -const isNotExpressway = ["!=", ["get", "expressway"], 1]; +const isNotExpressway = ["!", isExpressway]; const isService = ["==", ["get", "class"], "service"]; -const isNotService = ["!=", ["get", "class"], "service"]; +const isNotService = ["!", isService]; const isMinorService = [ "match", ["get", "service"], @@ -33,6 +34,7 @@ const isMinorService = [ ]; const isConstruction = ["in", "_construction", ["get", "class"]]; const isNotConstruction = ["!", isConstruction]; +const isUnpaved = ["==", ["get", "surface"], "unpaved"]; export const road = { id: "road", @@ -137,6 +139,19 @@ export const road = { 14, 0, ], + "line-blur": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + ["case", isUnpaved, 1, 0], + 8, + ["case", isUnpaved, 2, 0], + 18, + ["case", isUnpaved, 3, 0], + 20, + ["case", isUnpaved, 6, 0], + ] }, }; @@ -159,7 +174,7 @@ export const legendEntries = [ { description: "Local road", layers: [road.id], - filter: ["all", isNotMotorway, isNotToll, isNotExpressway, isNotRamp, isNotService], + filter: ["all", isNotMotorway, isNotState, isNotToll, isNotExpressway, isNotRamp, isNotService], }, { description: "Service road", @@ -171,9 +186,9 @@ export const legendEntries = [ layers: [road.id], filter: ["all", isToll, isNotRamp], }, - //{ - // description: "Unpaved road", - // layers: [road.id], - // filter: isUnpaved, - //}, + { + description: "Unpaved road", + layers: [road.id], + filter: isUnpaved, + }, ]; From cf7a0901f0375123b401e508ca70d1f920921397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 03:17:57 -0700 Subject: [PATCH 08/11] Added tunnel layer --- src/layer/index.js | 4 +--- src/layer/road.js | 46 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/layer/index.js b/src/layer/index.js index 197624815..334dd68cc 100644 --- a/src/layer/index.js +++ b/src/layer/index.js @@ -75,9 +75,7 @@ export function build(locales) { lyrConstruction.road, - //lyrRoad.roadTunnel.casing(), - // - //lyrRoad.roadTunnel.fill(), + lyrRoad.roadTunnel, lyrOneway.tunnel, diff --git a/src/layer/road.js b/src/layer/road.js index b955d06ab..7b913aec0 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -36,23 +36,33 @@ const isConstruction = ["in", "_construction", ["get", "class"]]; const isNotConstruction = ["!", isConstruction]; const isUnpaved = ["==", ["get", "surface"], "unpaved"]; +function mapRampExpression(expression, callback) { + let start = expression[0] === "step" ? 1 : 3; + for (var i = start; i + 1 < expression.length; i += 2) { + expression[i + 1] = callback(expression[i], expression[i + 1]); + } + return expression; +} + +const roadFilter = [ + "step", + ["zoom"], + false, + 4, ["all", ["==", ["get", "network"], "us-interstate"], isNotConstruction], + 5, ["match", ["get", "class"], ["motorway", "trunk"], isNotRamp, false], + 7, ["match", ["get", "class"], ["motorway", "trunk", "primary"], isNotRamp, false], + 9, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary"], true, false], + 11, ["all", isRoad, isNotService, isNotConstruction], + 12, ["all", isRoad, ["!", isMinorService], isNotConstruction], + 13, ["all", isRoad, isNotConstruction], +]; + export const road = { id: "road", type: "line", source: "openmaptiles", "source-layer": "transportation", - filter: [ - "step", - ["zoom"], - false, - 4, ["all", ["==", ["get", "network"], "us-interstate"], isNotConstruction], - 5, ["match", ["get", "class"], ["motorway", "trunk"], isNotRamp, false], - 7, ["match", ["get", "class"], ["motorway", "trunk", "primary"], isNotRamp, false], - 9, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary"], true, false], - 11, ["all", isRoad, isNotService, isNotConstruction], - 12, ["all", isRoad, ["!", isMinorService], isNotConstruction], - 13, ["all", isRoad, isNotConstruction], - ], + filter: mapRampExpression([...roadFilter], (input, output) => ["all", output, ["!=", ["get", "brunnel"], "tunnel"]]), layout: { "line-cap": "butt", "line-join": "round", @@ -155,6 +165,18 @@ export const road = { }, }; +export const roadTunnel = { + ...road, + id: "road-tunnel", + filter: mapRampExpression([...roadFilter], (input, output) => ["all", output, ["==", ["get", "brunnel"], "tunnel"]]), + paint: { + ...road.paint, + "line-width": 1, + "line-gap-width": mapRampExpression([...road.paint["line-width"]], (input, output) => ["-", output, 1]), + "line-dasharray": [5, 5], + }, +}; + export const legendEntries = [ { description: "Controlled-access highway", From d049f0ff572b96e35da36c9e6236f78e67defc82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 04:03:04 -0700 Subject: [PATCH 09/11] Added bridge knockout and casing --- src/js/util.js | 32 +++++++++++++++++++++++++++++--- src/layer/index.js | 4 +++- src/layer/road.js | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index 4c14a71a8..bce6d34aa 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -23,10 +23,20 @@ export function layerClone(def, id) { //Make a clone of a layer definition, with a filter added export function filteredClone(def, filterStep, idSuffix) { var clone = layerClone(def, def.id + idSuffix); - if (!["all", "any"].includes(clone.filter[0])) { - throw new TypeError("Unlikely filter"); + switch (clone.filter[0]) { + case "all": + case "any": + clone.filter.push(filterStep); + break; + case "interpolate": + case "interpolate-hcl": + case "interpolate-lab": + case "step": + clone.filter = mapRampExpression(clone.filter, (input, output) => ["all", output, filterStep]); + break; + default: + throw new TypeError("Unlikely filter"); } - clone.filter.push(filterStep); return clone; } @@ -38,3 +48,19 @@ export function zoomMultiply(arr, multiplier) { } return transformedArray; } + +/** + * Returns a copy of the interpolate or step expression with each output replaced with the return value of the callback. + * + * @param expression An interpolate or step expression. + * @param callback A function that takes the expression's input value and output expression and returns a replacement expression. + * @returns A copy of the interpolate or step expression with the output expressions replaced. + */ +export function mapRampExpression(expression, callback) { + let copy = [...expression]; + let start = copy[0] === "step" ? 1 : 3; + for (var i = start; i + 1 < copy.length; i += 2) { + copy[i + 1] = callback(copy[i], copy[i + 1]); + } + return copy; +} diff --git a/src/layer/index.js b/src/layer/index.js index 334dd68cc..9161accde 100644 --- a/src/layer/index.js +++ b/src/layer/index.js @@ -86,6 +86,7 @@ export function build(locales) { lyrAeroway.taxiway, lyrAeroway.taxiwayArea, + lyrRoad.roadBridgeCasing, lyrRoad.road, lyrRail.rail.dashes(), @@ -111,7 +112,8 @@ export function build(locales) { var bridgeLayers = [ lyrRail.bridgeCasing, - //lyrRoad.road, + lyrRoad.roadBridgeKnockout, + lyrRoad.road, lyrRail.railBridge.dashes(), lyrRail.railServiceBridge.dashes(), diff --git a/src/layer/road.js b/src/layer/road.js index 7b913aec0..d26ae59b4 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -1,5 +1,6 @@ "use strict"; +import * as Color from "../constants/color.js"; import * as Util from "../js/util.js"; const motorwayHue = 218; @@ -36,14 +37,6 @@ const isConstruction = ["in", "_construction", ["get", "class"]]; const isNotConstruction = ["!", isConstruction]; const isUnpaved = ["==", ["get", "surface"], "unpaved"]; -function mapRampExpression(expression, callback) { - let start = expression[0] === "step" ? 1 : 3; - for (var i = start; i + 1 < expression.length; i += 2) { - expression[i + 1] = callback(expression[i], expression[i + 1]); - } - return expression; -} - const roadFilter = [ "step", ["zoom"], @@ -62,7 +55,7 @@ export const road = { type: "line", source: "openmaptiles", "source-layer": "transportation", - filter: mapRampExpression([...roadFilter], (input, output) => ["all", output, ["!=", ["get", "brunnel"], "tunnel"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["!=", ["get", "brunnel"], "tunnel"]]), layout: { "line-cap": "butt", "line-join": "round", @@ -168,15 +161,39 @@ export const road = { export const roadTunnel = { ...road, id: "road-tunnel", - filter: mapRampExpression([...roadFilter], (input, output) => ["all", output, ["==", ["get", "brunnel"], "tunnel"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "tunnel"]]), paint: { ...road.paint, "line-width": 1, - "line-gap-width": mapRampExpression([...road.paint["line-width"]], (input, output) => ["-", output, 1]), + "line-gap-width": Util.mapRampExpression(road.paint["line-width"], (input, output) => ["-", output, 1]), "line-dasharray": [5, 5], }, }; +export const roadBridgeKnockout = { + ...road, + id: "road-bridge-knockout", + filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "bridge"]]), + paint: { + "line-color": Color.backgroundFill, + "line-width": Util.mapRampExpression(road.paint["line-width"], (input, output) => ["*", output, 2]), + "line-gap-width": 0, + "line-blur": 0, + } +}; + +export const roadBridgeCasing = { + ...road, + id: "road-bridge-casing", + filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "bridge"]]), + paint: { + "line-color": "#9c9c9c", + "line-width": 0.5, + "line-gap-width": roadBridgeKnockout.paint["line-width"], + "line-blur": 0, + } +}; + export const legendEntries = [ { description: "Controlled-access highway", From 86e6b30acc6f23c791e497a170a45e9376a30fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sun, 24 Sep 2023 04:37:02 -0700 Subject: [PATCH 10/11] Formatted code --- src/js/util.js | 6 +- src/layer/construction.js | 12 +-- src/layer/road.js | 184 +++++++++++++++++++++++++++++--------- 3 files changed, 153 insertions(+), 49 deletions(-) diff --git a/src/js/util.js b/src/js/util.js index bce6d34aa..5db0f3069 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -32,7 +32,11 @@ export function filteredClone(def, filterStep, idSuffix) { case "interpolate-hcl": case "interpolate-lab": case "step": - clone.filter = mapRampExpression(clone.filter, (input, output) => ["all", output, filterStep]); + clone.filter = mapRampExpression(clone.filter, (input, output) => [ + "all", + output, + filterStep, + ]); break; default: throw new TypeError("Unlikely filter"); diff --git a/src/layer/construction.js b/src/layer/construction.js index d1b9c800f..b715c2ed4 100644 --- a/src/layer/construction.js +++ b/src/layer/construction.js @@ -1,11 +1,7 @@ "use strict"; const motorwayHue = 218; -const majorConstruction = [ - "match", - ["get", "class"], - "motorway_construction", -]; +const majorConstruction = ["match", ["get", "class"], "motorway_construction"]; export const road = { id: "highway-construction", @@ -37,7 +33,11 @@ export const road = { 10, [...majorConstruction, `hsl(${motorwayHue}, 60%, 70%)`, "lightslategray"], 13, - [...majorConstruction, `hsl(${motorwayHue}, 100%, 45%)`, "lightslategray"], + [ + ...majorConstruction, + `hsl(${motorwayHue}, 100%, 45%)`, + "lightslategray", + ], 15, [...majorConstruction, `hsl(${motorwayHue}, 100%, 35%)`, "slategray"], ], diff --git a/src/layer/road.js b/src/layer/road.js index d26ae59b4..eebd1487b 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -11,7 +11,17 @@ const tollRoadHue = 100; const isRoad = [ "match", ["get", "class"], - ["motorway", "trunk", "primary", "secondary", "tertiary", "minor", "service", "busway", "bus_guideway"], + [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "minor", + "service", + "busway", + "bus_guideway", + ], true, false, ]; @@ -21,7 +31,13 @@ const isToll = ["==", ["get", "toll"], 1]; const isNotToll = ["!", isToll]; const isMotorway = ["all", ["==", ["get", "class"], "motorway"], isNotRamp]; const isNotMotorway = ["!=", ["get", "class"], "motorway"]; -const isState = ["match", ["get", "network"], ["us-highway", "us-state"], isNotRamp, false]; +const isState = [ + "match", + ["get", "network"], + ["us-highway", "us-state"], + isNotRamp, + false, +]; const isNotState = ["!", isState]; const isExpressway = ["==", ["get", "expressway"], 1]; const isNotExpressway = ["!", isExpressway]; @@ -31,7 +47,8 @@ const isMinorService = [ "match", ["get", "service"], ["parking_aisle", "driveway"], - true, false, + true, + false, ]; const isConstruction = ["in", "_construction", ["get", "class"]]; const isNotConstruction = ["!", isConstruction]; @@ -41,13 +58,32 @@ const roadFilter = [ "step", ["zoom"], false, - 4, ["all", ["==", ["get", "network"], "us-interstate"], isNotConstruction], - 5, ["match", ["get", "class"], ["motorway", "trunk"], isNotRamp, false], - 7, ["match", ["get", "class"], ["motorway", "trunk", "primary"], isNotRamp, false], - 9, ["match", ["get", "class"], ["motorway", "trunk", "primary", "secondary"], true, false], - 11, ["all", isRoad, isNotService, isNotConstruction], - 12, ["all", isRoad, ["!", isMinorService], isNotConstruction], - 13, ["all", isRoad, isNotConstruction], + 4, + ["all", ["==", ["get", "network"], "us-interstate"], isNotConstruction], + 5, + ["match", ["get", "class"], ["motorway", "trunk"], isNotRamp, false], + 7, + [ + "match", + ["get", "class"], + ["motorway", "trunk", "primary"], + isNotRamp, + false, + ], + 9, + [ + "match", + ["get", "class"], + ["motorway", "trunk", "primary", "secondary"], + true, + false, + ], + 11, + ["all", isRoad, isNotService, isNotConstruction], + 12, + ["all", isRoad, ["!", isMinorService], isNotConstruction], + 13, + ["all", isRoad, isNotConstruction], ]; export const road = { @@ -55,7 +91,11 @@ export const road = { type: "line", source: "openmaptiles", "source-layer": "transportation", - filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["!=", ["get", "brunnel"], "tunnel"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => [ + "all", + output, + ["!=", ["get", "brunnel"], "tunnel"], + ]), layout: { "line-cap": "butt", "line-join": "round", @@ -74,26 +114,36 @@ export const road = { 4, [ "case", - isToll, `hsl(${tollRoadHue}, 60%, 70%)`, - isMotorway, `hsl(${motorwayHue}, 60%, 70%)`, - isState, `hsl(${stateHue}, 77%, 50%)`, + isToll, + `hsl(${tollRoadHue}, 60%, 70%)`, + isMotorway, + `hsl(${motorwayHue}, 60%, 70%)`, + isState, + `hsl(${stateHue}, 77%, 50%)`, "#9c9c9c", ], 8, [ "case", - isToll, `hsl(${tollRoadHue}, 100%, 40%)`, - isMotorway, `hsl(${motorwayHue}, 100%, 45%)`, - isState, `hsl(${stateHue}, 77%, 50%)`, + isToll, + `hsl(${tollRoadHue}, 100%, 40%)`, + isMotorway, + `hsl(${motorwayHue}, 100%, 45%)`, + isState, + `hsl(${stateHue}, 77%, 50%)`, "#9c9c9c", ], 14, [ "case", - isToll, `hsl(${tollRoadHue}, 100%, 35%)`, - isMotorway, `hsl(${motorwayHue}, 100%, 35%)`, - isState, `hsl(${stateHue}, 77%, 50%)`, - ["all", ["==", ["get", "class"], "motorway"], isRamp], "#000", + isToll, + `hsl(${tollRoadHue}, 100%, 35%)`, + isMotorway, + `hsl(${motorwayHue}, 100%, 35%)`, + isState, + `hsl(${stateHue}, 77%, 50%)`, + ["all", ["==", ["get", "class"], "motorway"], isRamp], + "#000", "#9c9c9c", ], ], @@ -106,28 +156,52 @@ export const road = { 8, [ "case", - isMotorway, 3, - isExpressway, 1, - isState, 2, - ["match", ["get", "class"], ["trunk", "primary"], isNotRamp, false], 2, + isMotorway, + 3, + isExpressway, + 1, + isState, + 2, + ["match", ["get", "class"], ["trunk", "primary"], isNotRamp, false], + 2, 0.25, ], 18, [ "case", - isMotorway, 6, - ["all", isState, isNotExpressway], 4, - ["match", ["get", "class"], ["trunk", "primary", "secondary", "tertiary"], isNotRamp, false], 4, - isService, 1, + isMotorway, + 6, + ["all", isState, isNotExpressway], + 4, + [ + "match", + ["get", "class"], + ["trunk", "primary", "secondary", "tertiary"], + isNotRamp, + false, + ], + 4, + isService, + 1, 3, ], 20, [ "case", - isMotorway, 10, - ["all", isState, isNotExpressway], 8, - ["match", ["get", "class"], ["trunk", "primary", "secondary", "tertiary"], isNotRamp, false], 8, - isService, 1, + isMotorway, + 10, + ["all", isState, isNotExpressway], + 8, + [ + "match", + ["get", "class"], + ["trunk", "primary", "secondary", "tertiary"], + isNotRamp, + false, + ], + 8, + isService, + 1, 6, ], ], @@ -154,18 +228,25 @@ export const road = { ["case", isUnpaved, 3, 0], 20, ["case", isUnpaved, 6, 0], - ] + ], }, }; export const roadTunnel = { ...road, id: "road-tunnel", - filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "tunnel"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => [ + "all", + output, + ["==", ["get", "brunnel"], "tunnel"], + ]), paint: { ...road.paint, "line-width": 1, - "line-gap-width": Util.mapRampExpression(road.paint["line-width"], (input, output) => ["-", output, 1]), + "line-gap-width": Util.mapRampExpression( + road.paint["line-width"], + (input, output) => ["-", output, 1] + ), "line-dasharray": [5, 5], }, }; @@ -173,25 +254,36 @@ export const roadTunnel = { export const roadBridgeKnockout = { ...road, id: "road-bridge-knockout", - filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "bridge"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => [ + "all", + output, + ["==", ["get", "brunnel"], "bridge"], + ]), paint: { "line-color": Color.backgroundFill, - "line-width": Util.mapRampExpression(road.paint["line-width"], (input, output) => ["*", output, 2]), + "line-width": Util.mapRampExpression( + road.paint["line-width"], + (input, output) => ["*", output, 2] + ), "line-gap-width": 0, "line-blur": 0, - } + }, }; export const roadBridgeCasing = { ...road, id: "road-bridge-casing", - filter: Util.mapRampExpression(roadFilter, (input, output) => ["all", output, ["==", ["get", "brunnel"], "bridge"]]), + filter: Util.mapRampExpression(roadFilter, (input, output) => [ + "all", + output, + ["==", ["get", "brunnel"], "bridge"], + ]), paint: { "line-color": "#9c9c9c", "line-width": 0.5, "line-gap-width": roadBridgeKnockout.paint["line-width"], "line-blur": 0, - } + }, }; export const legendEntries = [ @@ -213,7 +305,15 @@ export const legendEntries = [ { description: "Local road", layers: [road.id], - filter: ["all", isNotMotorway, isNotState, isNotToll, isNotExpressway, isNotRamp, isNotService], + filter: [ + "all", + isNotMotorway, + isNotState, + isNotToll, + isNotExpressway, + isNotRamp, + isNotService, + ], }, { description: "Service road", From 9bf9e5d19278e1386f781893e5cf127d4094eccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 4 Jan 2024 16:52:03 -0800 Subject: [PATCH 11/11] Color-code roads by functional classification --- src/layer/road.js | 94 +++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/src/layer/road.js b/src/layer/road.js index eebd1487b..250a5b46b 100644 --- a/src/layer/road.js +++ b/src/layer/road.js @@ -4,8 +4,8 @@ import * as Color from "../constants/color.js"; import * as Util from "../js/util.js"; const motorwayHue = 218; -const stateHue = 40; -const tollRoadHue = 100; +const trunkHue = 0; +const tollRoadHue = 50; // Common filter expressions const isRoad = [ @@ -31,16 +31,19 @@ const isToll = ["==", ["get", "toll"], 1]; const isNotToll = ["!", isToll]; const isMotorway = ["all", ["==", ["get", "class"], "motorway"], isNotRamp]; const isNotMotorway = ["!=", ["get", "class"], "motorway"]; -const isState = [ +const isTrunk = ["all", ["==", ["get", "class"], "trunk"], isNotRamp]; +const isNotTrunk = ["!", isTrunk]; +const isExpressway = ["==", ["get", "expressway"], 1]; +const isNotExpressway = ["!", isExpressway]; +const isDivided = ["any", isMotorway, isExpressway]; +const isArterial = [ "match", - ["get", "network"], - ["us-highway", "us-state"], - isNotRamp, + ["get", "class"], + ["primary", "secondary"], + true, false, ]; -const isNotState = ["!", isState]; -const isExpressway = ["==", ["get", "expressway"], 1]; -const isNotExpressway = ["!", isExpressway]; +const isNotArterial = ["!", isArterial]; const isService = ["==", ["get", "class"], "service"]; const isNotService = ["!", isService]; const isMinorService = [ @@ -101,8 +104,11 @@ export const road = { "line-join": "round", "line-sort-key": [ "+", - ["to-number", isMotorway], - ["to-number", isState], + [ + "index-of", + ["get", "class"], + ["literal", ["tertiary", "secondary", "primary", "trunk", "motorway"]], + ], ["to-number", isRamp], ], }, @@ -118,8 +124,8 @@ export const road = { `hsl(${tollRoadHue}, 60%, 70%)`, isMotorway, `hsl(${motorwayHue}, 60%, 70%)`, - isState, - `hsl(${stateHue}, 77%, 50%)`, + isTrunk, + `hsl(${trunkHue}, 60%, 70%)`, "#9c9c9c", ], 8, @@ -129,8 +135,8 @@ export const road = { `hsl(${tollRoadHue}, 100%, 40%)`, isMotorway, `hsl(${motorwayHue}, 100%, 45%)`, - isState, - `hsl(${stateHue}, 77%, 50%)`, + isTrunk, + `hsl(${trunkHue}, 60%, 60%)`, "#9c9c9c", ], 14, @@ -140,10 +146,12 @@ export const road = { `hsl(${tollRoadHue}, 100%, 35%)`, isMotorway, `hsl(${motorwayHue}, 100%, 35%)`, - isState, - `hsl(${stateHue}, 77%, 50%)`, + isTrunk, + `hsl(${trunkHue}, 60%, 60%)`, ["all", ["==", ["get", "class"], "motorway"], isRamp], - "#000", + "hsl(0, 0%, 20%)", + isArterial, + "hsl(0, 0%, 30%)", "#9c9c9c", ], ], @@ -153,30 +161,30 @@ export const road = { ["zoom"], 4, 1, + 7, + 1, 8, [ "case", - isMotorway, - 3, - isExpressway, + isDivided, 1, - isState, + isTrunk, 2, ["match", ["get", "class"], ["trunk", "primary"], isNotRamp, false], - 2, + 1, 0.25, ], 18, [ "case", - isMotorway, - 6, - ["all", isState, isNotExpressway], + ["all", isMotorway, isNotExpressway], + 4, + ["all", isTrunk, isNotExpressway], 4, [ "match", ["get", "class"], - ["trunk", "primary", "secondary", "tertiary"], + ["motorway", "trunk", "primary", "secondary", "tertiary"], isNotRamp, false, ], @@ -188,14 +196,14 @@ export const road = { 20, [ "case", - isMotorway, - 10, - ["all", isState, isNotExpressway], + ["all", isMotorway, isNotExpressway], + 8, + ["all", isTrunk, isNotExpressway], 8, [ "match", ["get", "class"], - ["trunk", "primary", "secondary", "tertiary"], + ["motorway", "trunk", "primary", "secondary", "tertiary"], isNotRamp, false, ], @@ -209,10 +217,12 @@ export const road = { "interpolate", ["exponential", 1.2], ["zoom"], - 4, - ["case", isExpressway, 1, 0], + 7, + 0, + 8, + ["case", isDivided, 1, 0], 12, - ["case", isExpressway, 3, 0], + ["case", isDivided, 3, 0], 14, 0, ], @@ -288,19 +298,24 @@ export const roadBridgeCasing = { export const legendEntries = [ { - description: "Controlled-access highway", + description: "Freeway (controlled access, divided)", layers: [road.id], filter: ["all", isMotorway, isNotToll], }, { - description: "Limited-access highway", + description: "Expressway (limited access, divided)", layers: [road.id], filter: ["all", isExpressway, isNotToll], }, { - description: "State highway", + description: "Principal highway", + layers: [road.id], + filter: ["all", isTrunk, isNotToll, isNotExpressway], + }, + { + description: "Arterial road", layers: [road.id], - filter: ["all", isState, isNotToll, isNotExpressway], + filter: ["all", isArterial, isNotToll, isNotExpressway], }, { description: "Local road", @@ -308,9 +323,10 @@ export const legendEntries = [ filter: [ "all", isNotMotorway, - isNotState, + isNotTrunk, isNotToll, isNotExpressway, + isNotArterial, isNotRamp, isNotService, ],