diff --git a/app/src/main/assets/map_style_good.json b/app/src/main/assets/map_style_good.json new file mode 100644 index 0000000..f2b5836 --- /dev/null +++ b/app/src/main/assets/map_style_good.json @@ -0,0 +1,3147 @@ +{ + "version": 8, + "metadata": {"maputnik:renderer": "mlgljs"}, + "sources": { + "ne2_shaded": { + "maxzoom": 6, + "tileSize": 256, + "tiles": [ + "https://tiles.openfreemap.org/natural_earth/ne2sr/{z}/{x}/{y}.png" + ], + "type": "raster" + }, + "openmaptiles": { + "type": "vector", + "url": "https://tiles.openfreemap.org/planet" + } + }, + "sprite": "https://tiles.openfreemap.org/sprites/ofm_f384/ofm", + "glyphs": "https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "background", + "paint": {"background-color": "#f8f4f0"} + }, + { + "id": "landcover-glacier", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "subclass"], "glacier"], + "paint": { + "fill-color": "#fff", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.9, 10, 0.3] + } + }, + { + "id": "landuse-residential", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["neighbourhood", "residential"], + true, + false + ], + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + "hsla(30,19%,90%,0.4)", + 16, + "hsla(30,19%,90%,0.2)" + ] + } + }, + { + "id": "landuse-suburb", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "maxzoom": 10, + "filter": ["==", ["get", "class"], "suburb"], + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + "hsla(30,19%,90%,0.4)", + 10, + "hsla(30,19%,90%,0.0)" + ] + } + }, + { + "id": "landuse-commercial", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["==", ["get", "class"], "commercial"] + ], + "paint": {"fill-color": "hsla(0,60%,87%,0.23)"} + }, + { + "id": "landuse-industrial", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + [ + "match", + ["get", "class"], + ["dam", "garages", "industrial"], + true, + false + ] + ], + "paint": {"fill-color": "hsla(49,100%,88%,0.34)"} + }, + { + "id": "landuse-cemetery", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "cemetery"], + "paint": {"fill-color": "#e0e4dd"} + }, + { + "id": "landuse-hospital", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "hospital"], + "paint": {"fill-color": "#fde"} + }, + { + "id": "landuse-school", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "school"], + "paint": {"fill-color": "#f0e8f8"} + }, + { + "id": "landuse-railway", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "railway"], + "paint": {"fill-color": "hsla(30,19%,90%,0.4)"} + }, + { + "id": "park", + "type": "fill", + "source": "openmaptiles", + "source-layer": "park", + "filter": [ + "match", + ["geometry-type"], + ["MultiPolygon", "Polygon"], + true, + false + ], + "paint": { + "fill-color": "#d8e8c8", + "fill-opacity": [ + "interpolate", + ["exponential", 1.8], + ["zoom"], + 9, + 0.5, + 12, + 0.2 + ] + } + }, + { + "id": "landcover-wood", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "wood"], + "paint": { + "fill-antialias": ["step", ["zoom"], false, 9, true], + "fill-color": "#6a4", + "fill-opacity": 0.1, + "fill-outline-color": "hsla(0,0%,0%,0.03)" + } + }, + { + "id": "landcover-grass", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "grass"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 1} + }, + { + "id": "landcover-grass-park", + "type": "fill", + "source": "openmaptiles", + "source-layer": "park", + "filter": ["==", ["get", "class"], "public_park"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 0.8} + }, + { + "id": "waterway_tunnel", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 14, + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], true, false], + ["==", ["get", "brunnel"], "tunnel"] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [2, 4], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-other", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], false, true], + ["==", ["get", "intermittent"], 0] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 2 + ] + } + }, + { + "id": "waterway-other-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], false, true], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 2 + ] + } + }, + { + "id": "waterway-stream-canal", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "stream"], true, false], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 0] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-stream-canal-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "stream"], true, false], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-river", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", ["get", "class"], "river"], + ["!=", ["get", "brunnel"], "tunnel"], + ["!=", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 10, + 0.8, + 20, + 6 + ] + } + }, + { + "id": "waterway-river-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", ["get", "class"], "river"], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [3, 2.5], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 10, + 0.8, + 20, + 6 + ] + } + }, + { + "id": "water", + "type": "fill", + "source": "openmaptiles", + "source-layer": "water", + "filter": [ + "all", + ["!=", ["get", "intermittent"], 1], + ["!=", ["get", "brunnel"], "tunnel"] + ], + "paint": {"fill-color": "#AECFE2"} + }, + { + "id": "water-intermittent", + "type": "fill", + "source": "openmaptiles", + "source-layer": "water", + "filter": ["==", ["get", "intermittent"], 1], + "paint": {"fill-color": "hsl(210,67%,85%)", "fill-opacity": 0.7} + }, + { + "id": "landcover-ice-shelf", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "subclass"], "ice_shelf"], + "paint": { + "fill-color": "#fff", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.9, 10, 0.3] + } + }, + { + "id": "landcover-sand", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "sand"], + "paint": {"fill-color": "rgba(245, 238, 188, 1)", "fill-opacity": 1} + }, + { + "id": "building", + "type": "fill", + "source": "openmaptiles", + "source-layer": "building", + "paint": { + "fill-antialias": true, + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15.5, + "#f2eae2", + 16, + "#dfdbd7" + ] + } + }, + { + "id": "building-top", + "type": "fill", + "source": "openmaptiles", + "source-layer": "building", + "paint": { + "fill-color": "#f2eae2", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 13, 0, 16, 1], + "fill-outline-color": "#dfdbd7", + "fill-translate": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [0, 0]], + 16, + ["literal", [-2, -2]] + ] + } + }, + { + "id": "tunnel-service-track-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["service", "track"], true, false] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1, + 16, + 4, + 20, + 11 + ] + } + }, + { + "id": "tunnel-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(200, 147, 102, 1)", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "minor"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-dasharray": [0.5, 0.25], + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8, + 1.5, + 20, + 17 + ] + } + }, + { + "id": "tunnel-trunk-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "tunnel-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "tunnel-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "tunnel-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(244, 209, 158, 1)", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-service-track", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["service", "track"], true, false] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15.5, + 0, + 16, + 2, + 20, + 7.5 + ] + } + }, + { + "id": "tunnel-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "minor"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 10 + ] + } + }, + { + "id": "tunnel-trunk-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "tunnel-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#ffdaa6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "tunnel-railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [2, 2], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "ferry", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["match", ["get", "class"], ["ferry"], true, false], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(108, 159, 182, 1)", + "line-dasharray": [2, 2], + "line-width": 1.1 + } + }, + { + "id": "aeroway-taxiway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["match", ["get", "class"], ["taxiway"], true, false], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 2, + 17, + 12 + ] + } + }, + { + "id": "aeroway-runway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["match", ["get", "class"], ["runway"], true, false], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 5, + 17, + 55 + ] + } + }, + { + "id": "aeroway-area", + "type": "fill", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["match", ["get", "class"], ["runway", "taxiway"], true, false] + ], + "paint": { + "fill-color": "rgba(255, 255, 255, 1)", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 13, 0, 14, 1] + } + }, + { + "id": "aeroway-taxiway", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "class"], ["taxiway"], true, false], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 12, 1], + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 1, + 17, + 10 + ] + } + }, + { + "id": "aeroway-runway", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "class"], ["runway"], true, false], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 12, 1], + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 4, + 17, + 50 + ] + } + }, + { + "id": "road_area_pier", + "type": "fill", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["==", ["get", "class"], "pier"] + ], + "paint": {"fill-antialias": true, "fill-color": "#f8f4f0"} + }, + { + "id": "road_pier", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "class"], ["pier"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#f8f4f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1, + 17, + 4 + ] + } + }, + { + "id": "highway-area", + "type": "fill", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["match", ["get", "class"], ["pier"], false, true] + ], + "paint": { + "fill-antialias": false, + "fill-color": "hsla(0,0%,89%,0.56)", + "fill-opacity": 0.9, + "fill-outline-color": "#cfcdca" + } + }, + { + "id": "highway-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!=", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8, + 1.5, + 20, + 17 + ] + } + }, + { + "id": "highway-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["primary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 7, 0, 8, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 0, + 8, + 0.6, + 9, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-trunk-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 5, 0, 6, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 4, 0, 5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 0, + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "highway-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 12, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!=", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 8, + 0.5, + 20, + 13 + ] + } + }, + { + "id": "highway-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["primary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8.5, + 0, + 9, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "highway-trunk", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "highway-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "railway-transit", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "transit"], + ["match", ["get", "brunnel"], ["tunnel"], false, true] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.77)", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 20, + 1 + ] + } + }, + { + "id": "railway-transit-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "transit"], + ["match", ["get", "brunnel"], ["tunnel"], false, true] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.68)", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 2, + 20, + 6 + ] + } + }, + { + "id": "railway-service", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "rail"], + ["has", "service"] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.77)", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 20, + 1 + ] + } + }, + { + "id": "railway-service-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "rail"], + ["has", "service"] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.68)", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 2, + 20, + 6 + ] + } + }, + { + "id": "railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!", ["has", "service"]], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "railway-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!", ["has", "service"]], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 3, + 20, + 8 + ] + } + }, + { + "id": "bridge-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 19 + ] + } + }, + { + "id": "bridge-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 19 + ] + } + }, + { + "id": "bridge-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 7, + 0.6, + 8, + 1.5, + 20, + 21 + ] + } + }, + { + "id": "bridge-trunk-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "hsl(28,76%,67%)", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 26 + ] + } + }, + { + "id": "bridge-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 26 + ] + } + }, + { + "id": "bridge-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 6, + 20, + 24 + ] + } + }, + { + "id": "bridge-path-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#f8f4f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 18 + ] + } + }, + { + "id": "bridge-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "bridge-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 8, + 0.5, + 20, + 13 + ] + } + }, + { + "id": "bridge-trunk-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "bridge-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "bridge-railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "bridge-railway-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 3, + 20, + 8 + ] + } + }, + { + "id": "cablecar", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", ["get", "subclass"], "cable_car"], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-width": ["interpolate", ["linear"], ["zoom"], 11, 1, 19, 2.5] + } + }, + { + "id": "cablecar-dash", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", ["get", "subclass"], "cable_car"], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-dasharray": [2, 3], + "line-width": ["interpolate", ["linear"], ["zoom"], 11, 3, 19, 5.5] + } + }, + { + "id": "boundary_3", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "minzoom": 5, + "filter": [ + "all", + [">=", ["get", "admin_level"], 3], + ["<=", ["get", "admin_level"], 6], + ["!=", ["get", "maritime"], 1], + ["!=", ["get", "disputed"], 1], + ["!", ["has", "claimed_by"]] + ], + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-dasharray": [1, 1], + "line-width": ["interpolate", ["linear", 1], ["zoom"], 7, 1, 11, 2] + } + }, + { + "id": "boundary_2", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": [ + "all", + ["==", ["get", "admin_level"], 2], + ["!=", ["get", "maritime"], 1], + ["!=", ["get", "disputed"], 1], + ["!", ["has", "claimed_by"]] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "hsl(248,7%,66%)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.4, 4, 1], + "line-width": ["interpolate", ["linear"], ["zoom"], 3, 1, 5, 1.2, 12, 3] + } + }, + { + "id": "boundary_disputed", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": [ + "all", + ["!=", ["get", "maritime"], 1], + ["==", ["get", "disputed"], 1] + ], + "paint": { + "line-color": "hsl(248,7%,66%)", + "line-dasharray": [1, 2], + "line-width": ["interpolate", ["linear"], ["zoom"], 3, 1, 5, 1.2, 12, 3] + } + }, + { + "id": "road_oneway", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", ["get", "oneway"], 1], + [ + "match", + ["get", "class"], + [ + "minor", + "motorway", + "primary", + "secondary", + "service", + "tertiary", + "trunk" + ], + true, + false + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": 90, + "icon-rotation-alignment": "map", + "icon-size": ["interpolate", ["linear"], ["zoom"], 15, 0.5, 19, 1], + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "road_oneway_opposite", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", ["get", "oneway"], -1], + [ + "match", + ["get", "class"], + [ + "minor", + "motorway", + "primary", + "secondary", + "service", + "tertiary", + "trunk" + ], + true, + false + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": -90, + "icon-rotation-alignment": "map", + "icon-size": ["interpolate", ["linear"], ["zoom"], 15, 0.5, 19, 1], + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "waterway_line_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 10, + "filter": [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": 14 + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water_name_point_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": [ + "match", + ["geometry-type"], + ["MultiPoint", "Point"], + true, + false + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": ["interpolate", ["linear"], ["zoom"], 0, 10, 8, 14] + }, + "paint": { + "text-color": "#495e91", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water_name_line_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": 14 + }, + "paint": { + "text-color": "#495e91", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "poi_hos", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 15, + "filter": [ + "all", + ["==", "$type", "Point"], + ["has", "name"], + ["==", "class", "railway"], + ["==", "subclass", "station"] + ], + "layout": { + "icon-image": [ + "match", + ["get", "subclass"], + ["florist", "furniture"], + ["get", "subclass"], + ["get", "class"] + ], + "text-anchor": "top", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-size": 12, + "visibility": "none" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "poi_r1", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 15, + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPoint", "Point"], true, false], + [">=", ["get", "rank"], 1], + ["<=", ["get", "rank"], 6], + ["!=", ["get", "subclass"], "bus_stop"], + ["!=", ["get", "subclass"], "tram_stop"] + ], + "layout": { + "icon-image": [ + "match", + ["get", "subclass"], + ["florist", "furniture"], + ["get", "subclass"], + ["get", "class"] + ], + "text-anchor": "top", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "highway-name-path", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15.5, + "filter": ["==", ["get", "class"], "path"], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "hsl(30,23%,62%)", + "text-halo-color": "#f8f4f0", + "text-halo-width": 0.5 + } + }, + { + "id": "highway-name-minor", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-name-major", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 12.2, + "filter": [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-shield-non-us", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 8, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + [ + "match", + ["get", "network"], + ["us-highway", "us-interstate", "us-state"], + false, + true + ] + ], + "layout": { + "icon-image": ["concat", "road_", ["get", "ref_length"]], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "highway-shield-us-interstate", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 7, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "network"], ["us-interstate"], true, false] + ], + "layout": { + "icon-image": [ + "concat", + ["get", "network"], + "_", + ["get", "ref_length"] + ], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 7, "line", 8, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "road_shield_us", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 9, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "network"], ["us-highway", "us-state"], true, false] + ], + "layout": { + "icon-image": [ + "concat", + ["get", "network"], + "_", + ["get", "ref_length"] + ], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "airport", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "aerodrome_label", + "minzoom": 10, + "filter": ["all", ["has", "iata"]], + "layout": { + "icon-image": "airport_11", + "icon-size": 1, + "text-anchor": "top", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-optional": true, + "text-padding": 2, + "text-size": 12 + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "label_other", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 8, + "filter": [ + "match", + ["get", "class"], + ["city", "continent", "country", "state", "town", "village"], + false, + true + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.1, + "text-max-width": 9, + "text-size": ["interpolate", ["linear"], ["zoom"], 8, 9, 12, 10], + "text-transform": "uppercase" + }, + "paint": { + "text-color": "#333", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_village", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 9, + "filter": ["==", ["get", "class"], "village"], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 10, ""], + "icon-optional": false, + "icon-size": 0.2, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 10, + 11, + 12 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_town", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 6, + "filter": ["==", ["get", "class"], "town"], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 10, ""], + "icon-optional": false, + "icon-size": 0.2, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 12, + 11, + 14 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_state", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 5, + "maxzoom": 8, + "filter": ["==", ["get", "class"], "state"], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 9, + "text-size": ["interpolate", ["linear"], ["zoom"], 5, 10, 8, 14], + "text-transform": "uppercase" + }, + "paint": { + "text-color": "#333", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_city", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 3, + "filter": [ + "all", + ["==", ["get", "class"], "city"], + ["!=", ["get", "capital"], 2] + ], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 9, ""], + "icon-optional": false, + "icon-size": 0.4, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-offset": [0, -0.1], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 11, + 7, + 13, + 11, + 18 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_city_capital", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 3, + "filter": [ + "all", + ["==", ["get", "class"], "city"], + ["==", ["get", "capital"], 2] + ], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 9, ""], + "icon-optional": false, + "icon-size": 0.5, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 8, + "text-offset": [0, -0.2], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 12, + 7, + 14, + 11, + 20 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_3", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 2, + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + [">=", ["get", "rank"], 3] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 3, 9, 7, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_2", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + ["==", ["get", "rank"], 2] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 2, 9, 5, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_1", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + ["==", ["get", "rank"], 1] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 1, 9, 4, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + } + ], + "id": "94huyrm" +} diff --git a/app/src/main/assets/map_style_good_noshops.json b/app/src/main/assets/map_style_good_noshops.json new file mode 100644 index 0000000..be46c83 --- /dev/null +++ b/app/src/main/assets/map_style_good_noshops.json @@ -0,0 +1,3107 @@ +{ + "version": 8, + "metadata": {"maputnik:renderer": "mlgljs"}, + "sources": { + "ne2_shaded": { + "maxzoom": 6, + "tileSize": 256, + "tiles": [ + "https://tiles.openfreemap.org/natural_earth/ne2sr/{z}/{x}/{y}.png" + ], + "type": "raster" + }, + "openmaptiles": { + "type": "vector", + "url": "https://tiles.openfreemap.org/planet" + } + }, + "sprite": "https://tiles.openfreemap.org/sprites/ofm_f384/ofm", + "glyphs": "https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "background", + "paint": {"background-color": "#f8f4f0"} + }, + { + "id": "landcover-glacier", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "subclass"], "glacier"], + "paint": { + "fill-color": "#fff", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.9, 10, 0.3] + } + }, + { + "id": "landuse-residential", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "match", + ["get", "class"], + ["neighbourhood", "residential"], + true, + false + ], + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 12, + "hsla(30,19%,90%,0.4)", + 16, + "hsla(30,19%,90%,0.2)" + ] + } + }, + { + "id": "landuse-suburb", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "maxzoom": 10, + "filter": ["==", ["get", "class"], "suburb"], + "paint": { + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 8, + "hsla(30,19%,90%,0.4)", + 10, + "hsla(30,19%,90%,0.0)" + ] + } + }, + { + "id": "landuse-commercial", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["==", ["get", "class"], "commercial"] + ], + "paint": {"fill-color": "hsla(0,60%,87%,0.23)"} + }, + { + "id": "landuse-industrial", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + [ + "match", + ["get", "class"], + ["dam", "garages", "industrial"], + true, + false + ] + ], + "paint": {"fill-color": "hsla(49,100%,88%,0.34)"} + }, + { + "id": "landuse-cemetery", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "cemetery"], + "paint": {"fill-color": "#e0e4dd"} + }, + { + "id": "landuse-hospital", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "hospital"], + "paint": {"fill-color": "#fde"} + }, + { + "id": "landuse-school", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "school"], + "paint": {"fill-color": "#f0e8f8"} + }, + { + "id": "landuse-railway", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", ["get", "class"], "railway"], + "paint": {"fill-color": "hsla(30,19%,90%,0.4)"} + }, + { + "id": "park", + "type": "fill", + "source": "openmaptiles", + "source-layer": "park", + "filter": [ + "match", + ["geometry-type"], + ["MultiPolygon", "Polygon"], + true, + false + ], + "paint": { + "fill-color": "#d8e8c8", + "fill-opacity": [ + "interpolate", + ["exponential", 1.8], + ["zoom"], + 9, + 0.5, + 12, + 0.2 + ] + } + }, + { + "id": "landcover-wood", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "wood"], + "paint": { + "fill-antialias": ["step", ["zoom"], false, 9, true], + "fill-color": "#6a4", + "fill-opacity": 0.1, + "fill-outline-color": "hsla(0,0%,0%,0.03)" + } + }, + { + "id": "landcover-grass", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "grass"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 1} + }, + { + "id": "landcover-grass-park", + "type": "fill", + "source": "openmaptiles", + "source-layer": "park", + "filter": ["==", ["get", "class"], "public_park"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 0.8} + }, + { + "id": "waterway_tunnel", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 14, + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], true, false], + ["==", ["get", "brunnel"], "tunnel"] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [2, 4], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-other", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], false, true], + ["==", ["get", "intermittent"], 0] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 2 + ] + } + }, + { + "id": "waterway-other-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "river", "stream"], false, true], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 2 + ] + } + }, + { + "id": "waterway-stream-canal", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "stream"], true, false], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 0] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-stream-canal-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["match", ["get", "class"], ["canal", "stream"], true, false], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": [ + "interpolate", + ["exponential", 1.3], + ["zoom"], + 13, + 0.5, + 20, + 6 + ] + } + }, + { + "id": "waterway-river", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", ["get", "class"], "river"], + ["!=", ["get", "brunnel"], "tunnel"], + ["!=", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 10, + 0.8, + 20, + 6 + ] + } + }, + { + "id": "waterway-river-intermittent", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", ["get", "class"], "river"], + ["!=", ["get", "brunnel"], "tunnel"], + ["==", ["get", "intermittent"], 1] + ], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [3, 2.5], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 10, + 0.8, + 20, + 6 + ] + } + }, + { + "id": "water", + "type": "fill", + "source": "openmaptiles", + "source-layer": "water", + "filter": [ + "all", + ["!=", ["get", "intermittent"], 1], + ["!=", ["get", "brunnel"], "tunnel"] + ], + "paint": {"fill-color": "#AECFE2"} + }, + { + "id": "water-intermittent", + "type": "fill", + "source": "openmaptiles", + "source-layer": "water", + "filter": ["==", ["get", "intermittent"], 1], + "paint": {"fill-color": "hsl(210,67%,85%)", "fill-opacity": 0.7} + }, + { + "id": "landcover-ice-shelf", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "subclass"], "ice_shelf"], + "paint": { + "fill-color": "#fff", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.9, 10, 0.3] + } + }, + { + "id": "landcover-sand", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", ["get", "class"], "sand"], + "paint": {"fill-color": "rgba(245, 238, 188, 1)", "fill-opacity": 1} + }, + { + "id": "building", + "type": "fill", + "source": "openmaptiles", + "source-layer": "building", + "paint": { + "fill-antialias": true, + "fill-color": [ + "interpolate", + ["linear"], + ["zoom"], + 15.5, + "#f2eae2", + 16, + "#dfdbd7" + ] + } + }, + { + "id": "building-top", + "type": "fill", + "source": "openmaptiles", + "source-layer": "building", + "paint": { + "fill-color": "#f2eae2", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 13, 0, 16, 1], + "fill-outline-color": "#dfdbd7", + "fill-translate": [ + "interpolate", + ["linear"], + ["zoom"], + 14, + ["literal", [0, 0]], + 16, + ["literal", [-2, -2]] + ] + } + }, + { + "id": "tunnel-service-track-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["service", "track"], true, false] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1, + 16, + 4, + 20, + 11 + ] + } + }, + { + "id": "tunnel-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(200, 147, 102, 1)", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "minor"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-dasharray": [0.5, 0.25], + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "tunnel-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8, + 1.5, + 20, + 17 + ] + } + }, + { + "id": "tunnel-trunk-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "tunnel-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "tunnel-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "tunnel-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(244, 209, 158, 1)", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-service-track", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["service", "track"], true, false] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15.5, + 0, + 16, + 2, + 20, + 7.5 + ] + } + }, + { + "id": "tunnel-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "minor"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "tunnel-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 10 + ] + } + }, + { + "id": "tunnel-trunk-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "tunnel-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#ffdaa6", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "tunnel-railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "tunnel"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [2, 2], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "ferry", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["match", ["get", "class"], ["ferry"], true, false], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "rgba(108, 159, 182, 1)", + "line-dasharray": [2, 2], + "line-width": 1.1 + } + }, + { + "id": "aeroway-taxiway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["match", ["get", "class"], ["taxiway"], true, false], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 2, + 17, + 12 + ] + } + }, + { + "id": "aeroway-runway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["match", ["get", "class"], ["runway"], true, false], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 5, + 17, + 55 + ] + } + }, + { + "id": "aeroway-area", + "type": "fill", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["match", ["get", "class"], ["runway", "taxiway"], true, false] + ], + "paint": { + "fill-color": "rgba(255, 255, 255, 1)", + "fill-opacity": ["interpolate", ["linear"], ["zoom"], 13, 0, 14, 1] + } + }, + { + "id": "aeroway-taxiway", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "class"], ["taxiway"], true, false], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 12, 1], + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 1, + 17, + 10 + ] + } + }, + { + "id": "aeroway-runway", + "type": "line", + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "class"], ["runway"], true, false], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 12, 1], + "line-width": [ + "interpolate", + ["exponential", 1.5], + ["zoom"], + 11, + 4, + 17, + 50 + ] + } + }, + { + "id": "road_area_pier", + "type": "fill", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["==", ["get", "class"], "pier"] + ], + "paint": {"fill-antialias": true, "fill-color": "#f8f4f0"} + }, + { + "id": "road_pier", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "class"], ["pier"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#f8f4f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1, + 17, + 4 + ] + } + }, + { + "id": "highway-area", + "type": "fill", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPolygon", "Polygon"], true, false], + ["match", ["get", "class"], ["pier"], false, true] + ], + "paint": { + "fill-antialias": false, + "fill-color": "hsla(0,0%,89%,0.56)", + "fill-opacity": 0.9, + "fill-outline-color": "#cfcdca" + } + }, + { + "id": "highway-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!=", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 4, + 20, + 15 + ] + } + }, + { + "id": "highway-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8, + 1.5, + 20, + 17 + ] + } + }, + { + "id": "highway-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["primary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 7, 0, 8, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 0, + 8, + 0.6, + 9, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-trunk-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 5, 0, 6, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 4, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 4, 0, 5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 0, + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 22 + ] + } + }, + { + "id": "highway-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "highway-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 12, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!=", ["get", "brunnel"], "tunnel"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "highway-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 8, + 0.5, + 20, + 13 + ] + } + }, + { + "id": "highway-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["primary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 8.5, + 0, + 9, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "highway-trunk", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["match", ["get", "class"], ["trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "highway-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "railway-transit", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "transit"], + ["match", ["get", "brunnel"], ["tunnel"], false, true] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.77)", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 20, + 1 + ] + } + }, + { + "id": "railway-transit-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "transit"], + ["match", ["get", "brunnel"], ["tunnel"], false, true] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.68)", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 2, + 20, + 6 + ] + } + }, + { + "id": "railway-service", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "rail"], + ["has", "service"] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.77)", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 20, + 1 + ] + } + }, + { + "id": "railway-service-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "class"], "rail"], + ["has", "service"] + ], + "paint": { + "line-color": "hsla(0,0%,73%,0.68)", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 2, + 20, + 6 + ] + } + }, + { + "id": "railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!", ["has", "service"]], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "railway-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["!", ["has", "service"]], + ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 3, + 20, + 8 + ] + } + }, + { + "id": "bridge-motorway-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 19 + ] + } + }, + { + "id": "bridge-link-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 1, + 13, + 3, + 14, + 4, + 20, + 19 + ] + } + }, + { + "id": "bridge-secondary-tertiary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 7, + 0.6, + 8, + 1.5, + 20, + 21 + ] + } + }, + { + "id": "bridge-trunk-primary-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "hsl(28,76%,67%)", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 26 + ] + } + }, + { + "id": "bridge-motorway-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 5, + 0.4, + 6, + 0.6, + 7, + 1.5, + 20, + 26 + ] + } + }, + { + "id": "bridge-minor-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 12, 0, 12.5, 1], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12, + 0.5, + 13, + 1, + 14, + 6, + 20, + 24 + ] + } + }, + { + "id": "bridge-path-casing", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#f8f4f0", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 18 + ] + } + }, + { + "id": "bridge-path", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 15, + 1.2, + 20, + 4 + ] + } + }, + { + "id": "bridge-motorway-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-link", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + ["==", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 12.5, + 0, + 13, + 1.5, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-minor", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 13.5, + 0, + 14, + 2.5, + 20, + 11.5 + ] + } + }, + { + "id": "bridge-secondary-tertiary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["secondary", "tertiary"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 8, + 0.5, + 20, + 13 + ] + } + }, + { + "id": "bridge-trunk-primary", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["match", ["get", "class"], ["primary", "trunk"], true, false], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "bridge-motorway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "motorway"], + ["!=", ["get", "ramp"], 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 6.5, + 0, + 7, + 0.5, + 20, + 18 + ] + } + }, + { + "id": "bridge-railway", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14, + 0.4, + 15, + 0.75, + 20, + 2 + ] + } + }, + { + "id": "bridge-railway-hatching", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", ["get", "brunnel"], "bridge"], + ["==", ["get", "class"], "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": [ + "interpolate", + ["exponential", 1.4], + ["zoom"], + 14.5, + 0, + 15, + 3, + 20, + 8 + ] + } + }, + { + "id": "cablecar", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", ["get", "subclass"], "cable_car"], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-width": ["interpolate", ["linear"], ["zoom"], 11, 1, 19, 2.5] + } + }, + { + "id": "cablecar-dash", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", ["get", "subclass"], "cable_car"], + "layout": {"line-cap": "round"}, + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-dasharray": [2, 3], + "line-width": ["interpolate", ["linear"], ["zoom"], 11, 3, 19, 5.5] + } + }, + { + "id": "boundary_3", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "minzoom": 5, + "filter": [ + "all", + [">=", ["get", "admin_level"], 3], + ["<=", ["get", "admin_level"], 6], + ["!=", ["get", "maritime"], 1], + ["!=", ["get", "disputed"], 1], + ["!", ["has", "claimed_by"]] + ], + "paint": { + "line-color": "hsl(0,0%,70%)", + "line-dasharray": [1, 1], + "line-width": ["interpolate", ["linear", 1], ["zoom"], 7, 1, 11, 2] + } + }, + { + "id": "boundary_2", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": [ + "all", + ["==", ["get", "admin_level"], 2], + ["!=", ["get", "maritime"], 1], + ["!=", ["get", "disputed"], 1], + ["!", ["has", "claimed_by"]] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "hsl(248,7%,66%)", + "line-opacity": ["interpolate", ["linear"], ["zoom"], 0, 0.4, 4, 1], + "line-width": ["interpolate", ["linear"], ["zoom"], 3, 1, 5, 1.2, 12, 3] + } + }, + { + "id": "boundary_disputed", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": [ + "all", + ["!=", ["get", "maritime"], 1], + ["==", ["get", "disputed"], 1] + ], + "paint": { + "line-color": "hsl(248,7%,66%)", + "line-dasharray": [1, 2], + "line-width": ["interpolate", ["linear"], ["zoom"], 3, 1, 5, 1.2, 12, 3] + } + }, + { + "id": "road_oneway", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", ["get", "oneway"], 1], + [ + "match", + ["get", "class"], + [ + "minor", + "motorway", + "primary", + "secondary", + "service", + "tertiary", + "trunk" + ], + true, + false + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": 90, + "icon-rotation-alignment": "map", + "icon-size": ["interpolate", ["linear"], ["zoom"], 15, 0.5, 19, 1], + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "road_oneway_opposite", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", ["get", "oneway"], -1], + [ + "match", + ["get", "class"], + [ + "minor", + "motorway", + "primary", + "secondary", + "service", + "tertiary", + "trunk" + ], + true, + false + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": -90, + "icon-rotation-alignment": "map", + "icon-size": ["interpolate", ["linear"], ["zoom"], 15, 0.5, 19, 1], + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "waterway_line_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 10, + "filter": [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": 14 + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water_name_point_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": [ + "match", + ["geometry-type"], + ["MultiPoint", "Point"], + true, + false + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": ["interpolate", ["linear"], ["zoom"], 0, 10, 8, 14] + }, + "paint": { + "text-color": "#495e91", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water_name_line_label", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-size": 14 + }, + "paint": { + "text-color": "#495e91", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "poi_r1", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 15, + "filter": [ + "all", + ["match", ["geometry-type"], ["MultiPoint", "Point"], true, false], + [">=", ["get", "rank"], 1], + ["<=", ["get", "rank"], 6], + ["!=", ["get", "subclass"], "bus_stop"], + ["!=", ["get", "subclass"], "tram_stop"], + ["!=", ["get", "class"], "shop"] + ], + "layout": { + "icon-image": [ + "match", + ["get", "subclass"], + ["florist", "furniture"], + ["get", "subclass"], + ["get", "class"] + ], + "text-anchor": "top", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "highway-name-path", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15.5, + "filter": ["==", ["get", "class"], "path"], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "hsl(30,23%,62%)", + "text-halo-color": "#f8f4f0", + "text-halo-width": 0.5 + } + }, + { + "id": "highway-name-minor", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15, + "filter": [ + "all", + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "class"], ["minor", "service", "track"], true, false] + ], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-name-major", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 12.2, + "filter": [ + "match", + ["get", "class"], + ["primary", "secondary", "tertiary", "trunk"], + true, + false + ], + "layout": { + "symbol-placement": "line", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], " ", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": ["interpolate", ["linear"], ["zoom"], 13, 12, 14, 13] + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-shield-non-us", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 8, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + [ + "match", + ["get", "network"], + ["us-highway", "us-interstate", "us-state"], + false, + true + ] + ], + "layout": { + "icon-image": ["concat", "road_", ["get", "ref_length"]], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "highway-shield-us-interstate", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 7, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "network"], ["us-interstate"], true, false] + ], + "layout": { + "icon-image": [ + "concat", + ["get", "network"], + "_", + ["get", "ref_length"] + ], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 7, "line", 8, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "road_shield_us", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 9, + "filter": [ + "all", + ["<=", ["get", "ref_length"], 6], + [ + "match", + ["geometry-type"], + ["LineString", "MultiLineString"], + true, + false + ], + ["match", ["get", "network"], ["us-highway", "us-state"], true, false] + ], + "layout": { + "icon-image": [ + "concat", + ["get", "network"], + "_", + ["get", "ref_length"] + ], + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": ["step", ["zoom"], "point", 11, "line"], + "symbol-spacing": 200, + "text-field": ["to-string", ["get", "ref"]], + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + } + }, + { + "id": "airport", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "aerodrome_label", + "minzoom": 10, + "filter": ["all", ["has", "iata"]], + "layout": { + "icon-image": "airport_11", + "icon-size": 1, + "text-anchor": "top", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-optional": true, + "text-padding": 2, + "text-size": 12 + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "label_other", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 8, + "filter": [ + "match", + ["get", "class"], + ["city", "continent", "country", "state", "town", "village"], + false, + true + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.1, + "text-max-width": 9, + "text-size": ["interpolate", ["linear"], ["zoom"], 8, 9, 12, 10], + "text-transform": "uppercase" + }, + "paint": { + "text-color": "#333", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_village", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 9, + "filter": ["==", ["get", "class"], "village"], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 10, ""], + "icon-optional": false, + "icon-size": 0.2, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 10, + 11, + 12 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_town", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 6, + "filter": ["==", ["get", "class"], "town"], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 10, ""], + "icon-optional": false, + "icon-size": 0.2, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 7, + 12, + 11, + 14 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_state", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 5, + "maxzoom": 8, + "filter": ["==", ["get", "class"], "state"], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Italic"], + "text-letter-spacing": 0.2, + "text-max-width": 9, + "text-size": ["interpolate", ["linear"], ["zoom"], 5, 10, 8, 14], + "text-transform": "uppercase" + }, + "paint": { + "text-color": "#333", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_city", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 3, + "filter": [ + "all", + ["==", ["get", "class"], "city"], + ["!=", ["get", "capital"], 2] + ], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 9, ""], + "icon-optional": false, + "icon-size": 0.4, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-offset": [0, -0.1], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 11, + 7, + 13, + 11, + 18 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_city_capital", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 3, + "filter": [ + "all", + ["==", ["get", "class"], "city"], + ["==", ["get", "capital"], 2] + ], + "layout": { + "icon-allow-overlap": true, + "icon-image": ["step", ["zoom"], "circle_11_black", 9, ""], + "icon-optional": false, + "icon-size": 0.5, + "text-anchor": "bottom", + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 8, + "text-offset": [0, -0.2], + "text-size": [ + "interpolate", + ["exponential", 1.2], + ["zoom"], + 4, + 12, + 7, + 14, + 11, + 20 + ] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_3", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "minzoom": 2, + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + [">=", ["get", "rank"], 3] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 3, 9, 7, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_2", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + ["==", ["get", "rank"], 2] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 2, 9, 5, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + }, + { + "id": "label_country_1", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "place", + "maxzoom": 9, + "filter": [ + "all", + ["==", ["get", "class"], "country"], + ["==", ["get", "rank"], 1] + ], + "layout": { + "text-field": [ + "case", + ["has", "name:nonlatin"], + ["concat", ["get", "name:latin"], "\n", ["get", "name:nonlatin"]], + ["coalesce", ["get", "name_en"], ["get", "name"]] + ], + "text-font": ["Noto Sans Bold"], + "text-max-width": 6.25, + "text-size": ["interpolate", ["linear"], ["zoom"], 1, 9, 4, 17] + }, + "paint": { + "text-color": "#000", + "text-halo-blur": 1, + "text-halo-color": "#fff", + "text-halo-width": 1 + } + } + ], + "id": "94huyrm" +} \ No newline at end of file diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragmentKt.kt b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragmentKt.kt index 08aa2fe..2a319a4 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragmentKt.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragmentKt.kt @@ -1,771 +1,768 @@ /* BusTO - Fragments components Copyright (C) 2020 Andrea Ugo Copyright (C) 2021 Fabio Mazza This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package it.reyboz.bustorino.fragments import android.Manifest import android.animation.ObjectAnimator import android.annotation.SuppressLint import android.content.Context import android.location.LocationManager import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageButton import android.widget.Toast import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.res.ResourcesCompat +import androidx.fragment.app.viewModels import androidx.lifecycle.ViewModelProvider import androidx.preference.PreferenceManager import it.reyboz.bustorino.R import it.reyboz.bustorino.backend.Stop import it.reyboz.bustorino.backend.gtfs.LivePositionUpdate import it.reyboz.bustorino.backend.mato.MQTTMatoClient import it.reyboz.bustorino.backend.utils import it.reyboz.bustorino.data.gtfs.MatoPattern import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops import it.reyboz.bustorino.map.BusInfoWindow import it.reyboz.bustorino.map.CustomInfoWindow import it.reyboz.bustorino.map.CustomInfoWindow.TouchResponder import it.reyboz.bustorino.map.LocationOverlay import it.reyboz.bustorino.map.LocationOverlay.OverlayCallbacks import it.reyboz.bustorino.map.MarkerUtils import it.reyboz.bustorino.middleware.GeneralActivity import it.reyboz.bustorino.util.Permissions import it.reyboz.bustorino.viewmodels.LivePositionsViewModel import it.reyboz.bustorino.viewmodels.StopsMapViewModel import org.osmdroid.config.Configuration import org.osmdroid.events.DelayedMapListener import org.osmdroid.events.MapListener import org.osmdroid.events.ScrollEvent import org.osmdroid.events.ZoomEvent import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView import org.osmdroid.views.overlay.FolderOverlay import org.osmdroid.views.overlay.Marker import org.osmdroid.views.overlay.infowindow.InfoWindow import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider open class MapFragmentKt : ScreenBaseFragment() { protected var listenerMain: FragmentListenerMain? = null private var shownStops: HashSet? = null private lateinit var map: MapView var ctx: Context? = null private lateinit var mLocationOverlay: LocationOverlay private lateinit var stopsFolderOverlay: FolderOverlay private var savedMapState: Bundle? = null protected lateinit var btCenterMap: ImageButton protected lateinit var btFollowMe: ImageButton protected var coordLayout: CoordinatorLayout? = null private var hasMapStartFinished = false private var followingLocation = false //the ViewModel from which we get the stop to display in the map - private var stopsViewModel: StopsMapViewModel? = null + private val stopsViewModel: StopsMapViewModel by viewModels() //private GtfsPositionsViewModel gtfsPosViewModel; //= new ViewModelProvider(this).get(MapViewModel.class); - private var livePositionsViewModel: LivePositionsViewModel? = null + private val livePositionsViewModel: LivePositionsViewModel by viewModels() private var useMQTTViewModel = true private val busPositionMarkersByTrip = HashMap() private var busPositionsOverlay: FolderOverlay? = null private val tripMarkersAnimators = HashMap() protected val responder = TouchResponder { stopID, stopName -> if (listenerMain != null) { Log.d(DEBUG_TAG, "Asked to show arrivals for stop ID: $stopID") listenerMain!!.requestArrivalsForStopID(stopID) } } protected val locationCallbacks: OverlayCallbacks = object : OverlayCallbacks { override fun onDisableFollowMyLocation() { updateGUIForLocationFollowing(false) followingLocation = false } override fun onEnableFollowMyLocation() { updateGUIForLocationFollowing(true) followingLocation = true } } private val positionRequestLauncher = registerForActivityResult, Map>( ActivityResultContracts.RequestMultiplePermissions(), ActivityResultCallback { result -> if (result == null) { Log.w(DEBUG_TAG, "Got asked permission but request is null, doing nothing?") - } else if (java.lang.Boolean.TRUE == result[Manifest.permission.ACCESS_COARSE_LOCATION] && java.lang.Boolean.TRUE == result[Manifest.permission.ACCESS_FINE_LOCATION]) { + } else if (java.lang.Boolean.TRUE == result[Manifest.permission.ACCESS_COARSE_LOCATION] + && java.lang.Boolean.TRUE == result[Manifest.permission.ACCESS_FINE_LOCATION]) { + // We can use the position, restart location overlay map.overlays.remove(mLocationOverlay) startLocationOverlay(true, map) if (context == null || requireContext().getSystemService(Context.LOCATION_SERVICE) == null) return@ActivityResultCallback ///@registerForActivityResult val locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager @SuppressLint("MissingPermission") val userLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) if (userLocation != null) { map!!.controller.setZoom(POSITION_FOUND_ZOOM) val startPoint = GeoPoint(userLocation) setLocationFollowing(true) map!!.controller.setCenter(startPoint) } } else Log.w(DEBUG_TAG, "No location permission") }) //public static MapFragment getInstance(@NonNull Stop stop){ // return getInstance(stop.getLatitude(), stop.getLongitude(), stop.getStopDisplayName(), stop.ID); //} override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { //use the same layout as the activity val root = inflater.inflate(R.layout.fragment_map, container, false) val context = requireContext() ctx = context.applicationContext Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(context)) map = root.findViewById(R.id.map) map.setTileSource(TileSourceFactory.MAPNIK) //map.setTilesScaledToDpi(true); map.setFlingEnabled(true) // add ability to zoom with 2 fingers map.setMultiTouchControls(true) btCenterMap = root.findViewById(R.id.icon_center_map) btFollowMe = root.findViewById(R.id.icon_follow) coordLayout = root.findViewById(R.id.coord_layout) //setup FolderOverlay stopsFolderOverlay = FolderOverlay() //setup Bus Markers Overlay busPositionsOverlay = FolderOverlay() //reset shown bus updates busPositionMarkersByTrip.clear() tripMarkersAnimators.clear() //set map not done hasMapStartFinished = false val keySourcePositions = getString(R.string.pref_positions_source) useMQTTViewModel = PreferenceManager.getDefaultSharedPreferences(requireContext()) .getString(keySourcePositions, SettingsFragment.LIVE_POSITIONS_PREF_MQTT_VALUE) .contentEquals(SettingsFragment.LIVE_POSITIONS_PREF_MQTT_VALUE) //Start map from bundle if (savedInstanceState != null) startMap(arguments, savedInstanceState) else startMap( arguments, savedMapState ) //set listeners map.addMapListener(DelayedMapListener(object : MapListener { override fun onScroll(paramScrollEvent: ScrollEvent): Boolean { requestStopsToShow() //Log.d(DEBUG_TAG, "Scrolling"); //if (moveTriggeredByCode) moveTriggeredByCode =false; //else setLocationFollowing(false); return true } override fun onZoom(event: ZoomEvent): Boolean { requestStopsToShow() return true } })) btCenterMap.setOnClickListener(View.OnClickListener { v: View? -> //Log.i(TAG, "centerMap clicked "); if (Permissions.bothLocationPermissionsGranted(context)) { val myPosition = mLocationOverlay!!.myLocation map.getController().animateTo(myPosition) } else Toast.makeText(context, R.string.enable_position_message_map, Toast.LENGTH_SHORT) .show() }) btFollowMe.setOnClickListener(View.OnClickListener { v: View? -> //Log.i(TAG, "btFollowMe clicked "); if (Permissions.bothLocationPermissionsGranted(context)) setLocationFollowing(!followingLocation) else Toast.makeText( context, R.string.enable_position_message_map, Toast.LENGTH_SHORT ) .show() }) return root } override fun onAttach(context: Context) { super.onAttach(context) - val provider = ViewModelProvider(this) - //gtfsPosViewModel = provider.get(GtfsPositionsViewModel.class); - livePositionsViewModel = provider.get(LivePositionsViewModel::class.java) - stopsViewModel = provider.get(StopsMapViewModel::class.java) listenerMain = if (context is FragmentListenerMain) { context } else { throw RuntimeException( context.toString() + " must implement FragmentListenerMain" ) } } override fun onDetach() { super.onDetach() listenerMain = null - //stop animations - // setupOnAttached = true; Log.w(DEBUG_TAG, "Fragment detached") } override fun onPause() { super.onPause() Log.w(DEBUG_TAG, "On pause called mapfrag") saveMapState() for (animator in tripMarkersAnimators.values) { if (animator != null && animator.isRunning) { animator.cancel() } } tripMarkersAnimators.clear() if (useMQTTViewModel) livePositionsViewModel!!.stopMatoUpdates() } /** * Save the map state inside the fragment * (calls saveMapState(bundle)) */ private fun saveMapState() { savedMapState = Bundle() saveMapState(savedMapState!!) } /** * Save the state of the map to restore it to a later time * @param bundle the bundle in which to save the data */ private fun saveMapState(bundle: Bundle) { Log.d(DEBUG_TAG, "Saving state, location following: $followingLocation") bundle.putBoolean(FOLLOWING_LOCAT_KEY, followingLocation) if (map == null) { //The map is null, it can happen? Log.e(DEBUG_TAG, "Cannot save map center, map is null") return } val loc = map!!.mapCenter bundle.putDouble(MAP_CENTER_LAT_KEY, loc.latitude) bundle.putDouble(MAP_CENTER_LON_KEY, loc.longitude) bundle.putDouble(MAP_CURRENT_ZOOM_KEY, map!!.zoomLevelDouble) } override fun onResume() { super.onResume() //TODO: cleanup duplicate code (maybe merging the positions classes?) if (listenerMain != null) listenerMain!!.readyGUIfor(FragmentKind.MAP) /// choose which to use val keySourcePositions = getString(R.string.pref_positions_source) useMQTTViewModel = PreferenceManager.getDefaultSharedPreferences(requireContext()) .getString(keySourcePositions, SettingsFragment.LIVE_POSITIONS_PREF_MQTT_VALUE) .contentEquals( SettingsFragment.LIVE_POSITIONS_PREF_MQTT_VALUE ) if (livePositionsViewModel != null) { //gtfsPosViewModel.requestUpdates(); if (useMQTTViewModel) livePositionsViewModel!!.requestMatoPosUpdates(MQTTMatoClient.LINES_ALL) else livePositionsViewModel!!.requestGTFSUpdates() //mapViewModel.testCascade(); livePositionsViewModel!!.isLastWorkResultGood.observe(this) { d: Boolean -> Log.d( DEBUG_TAG, "Last trip download result is $d" ) } livePositionsViewModel!!.tripsGtfsIDsToQuery.observe(this) { dat: List -> Log.i(DEBUG_TAG, "Have these trips IDs missing from the DB, to be queried: $dat") livePositionsViewModel!!.downloadTripsFromMato(dat) } } /*else if(gtfsPosViewModel!=null){ gtfsPosViewModel.requestUpdates(); gtfsPosViewModel.getTripsGtfsIDsToQuery().observe(this, dat -> { Log.i(DEBUG_TAG, "Have these trips IDs missing from the DB, to be queried: "+dat); //gtfsPosViewModel.downloadTripsFromMato(dat); MatoTripsDownloadWorker.Companion.downloadTripsFromMato(dat,getContext().getApplicationContext(), "BusTO-MatoTripDownload"); }); } */ else Log.e(DEBUG_TAG, "livePositionsViewModel is null at onResume") //rerequest stop stopsViewModel!!.requestStopsInBoundingBox(map!!.boundingBox) } private fun startRequestsPositions() { if (livePositionsViewModel != null) { //should always be the case livePositionsViewModel!!.updatesWithTripAndPatterns.observe(viewLifecycleOwner) { data: HashMap> -> Log.d( DEBUG_TAG, "Have " + data.size + " trip updates, has Map start finished: " + hasMapStartFinished ) if (hasMapStartFinished) updateBusPositionsInMap(data) if (!isDetached && !useMQTTViewModel) livePositionsViewModel!!.requestDelayedGTFSUpdates( 3000 ) } } else { Log.e(DEBUG_TAG, "PositionsViewModel is null") } } override fun onSaveInstanceState(outState: Bundle) { saveMapState(outState) super.onSaveInstanceState(outState) } //own methods /** * Switch following the location on and off * @param value true if we want to follow location */ fun setLocationFollowing(value: Boolean) { followingLocation = value if (mLocationOverlay == null || context == null || map == null) //nothing else to do return if (value) { mLocationOverlay!!.enableFollowLocation() } else { mLocationOverlay!!.disableFollowLocation() } } /** * Do all the stuff you need to do on the gui, when parameter is changed to value * @param following value */ protected fun updateGUIForLocationFollowing(following: Boolean) { if (following) btFollowMe!!.setImageResource(R.drawable.ic_follow_me_on) else btFollowMe!!.setImageResource( R.drawable.ic_follow_me ) } /** * Build the location overlay. Enable only when * a) we know we have the permission * b) the location map is set */ private fun startLocationOverlay(enableLocation: Boolean, map: MapView?) { checkNotNull(activity) { "Cannot enable LocationOverlay now" } // Location Overlay // from OpenBikeSharing (THANK GOD) Log.d(DEBUG_TAG, "Starting position overlay") val imlp = GpsMyLocationProvider(requireActivity().baseContext) imlp.locationUpdateMinDistance = 5f imlp.locationUpdateMinTime = 2000 val overlay = LocationOverlay(imlp, map, locationCallbacks) if (enableLocation) overlay.enableMyLocation() overlay.isOptionsMenuEnabled = true //map.getOverlays().add(this.mLocationOverlay); mLocationOverlay = overlay map!!.overlays.add(mLocationOverlay) } fun startMap(incoming: Bundle?, savedInstanceState: Bundle?) { //Check that we're attached val activity = if (activity is GeneralActivity) activity as GeneralActivity? else null if (context == null || activity == null) { //we are not attached Log.e(DEBUG_TAG, "Calling startMap when not attached") return } else { Log.d(DEBUG_TAG, "Starting map from scratch") } //clear previous overlays map!!.overlays.clear() //parse incoming bundle var marker: GeoPoint? = null var name: String? = null var ID: String? = null var routesStopping: String? = "" if (incoming != null) { val lat = incoming.getDouble(BUNDLE_LATIT) val lon = incoming.getDouble(BUNDLE_LONGIT) marker = GeoPoint(lat, lon) name = incoming.getString(BUNDLE_NAME) ID = incoming.getString(BUNDLE_ID) routesStopping = incoming.getString(BUNDLE_ROUTES_STOPPING, "") } //ask for location permission if (!Permissions.bothLocationPermissionsGranted(activity)) { if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { //TODO: show dialog for permission rationale Toast.makeText(activity, R.string.enable_position_message_map, Toast.LENGTH_SHORT) .show() } positionRequestLauncher.launch(Permissions.LOCATION_PERMISSIONS) } shownStops = HashSet() // move the map on the marker position or on a default view point: Turin, Piazza Castello // and set the start zoom val mapController = map!!.controller var startPoint: GeoPoint? = null startLocationOverlay( Permissions.bothLocationPermissionsGranted(activity), map ) // set the center point if (marker != null) { //startPoint = marker; mapController.setZoom(POSITION_FOUND_ZOOM) setLocationFollowing(false) // put the center a little bit off (animate later) startPoint = GeoPoint(marker) startPoint.latitude = marker.latitude + utils.angleRawDifferenceFromMeters(20.0) startPoint.longitude = marker.longitude - utils.angleRawDifferenceFromMeters(20.0) //don't need to do all the rest since we want to show a point } else if (savedInstanceState != null && savedInstanceState.containsKey(MAP_CURRENT_ZOOM_KEY)) { mapController.setZoom(savedInstanceState.getDouble(MAP_CURRENT_ZOOM_KEY)) mapController.setCenter( GeoPoint( savedInstanceState.getDouble(MAP_CENTER_LAT_KEY), savedInstanceState.getDouble(MAP_CENTER_LON_KEY) ) ) Log.d( DEBUG_TAG, "Location following from savedInstanceState: " + savedInstanceState.getBoolean( FOLLOWING_LOCAT_KEY ) ) setLocationFollowing(savedInstanceState.getBoolean(FOLLOWING_LOCAT_KEY)) } else { Log.d(DEBUG_TAG, "No position found from intent or saved state") var found = false val locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager //check for permission if (Permissions.bothLocationPermissionsGranted(activity)) { @SuppressLint("MissingPermission") val userLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) if (userLocation != null) { val distan = utils.measuredistanceBetween( userLocation.latitude, userLocation.longitude, DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON ) if (distan < 100000.0) { mapController.setZoom(POSITION_FOUND_ZOOM) startPoint = GeoPoint(userLocation) found = true setLocationFollowing(true) } } } if (!found) { startPoint = GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON) mapController.setZoom(NO_POSITION_ZOOM) setLocationFollowing(false) } } // set the minimum zoom level map!!.minZoomLevel = 15.0 //add contingency check (shouldn't happen..., but) if (startPoint != null) { mapController.setCenter(startPoint) } //add stops overlay //map.getOverlays().add(mLocationOverlay); map!!.overlays.add(stopsFolderOverlay) Log.d(DEBUG_TAG, "Requesting stops load") // This is not necessary, by setting the center we already move // the map and we trigger a stop request //requestStopsToShow(); if (marker != null) { // make a marker with the info window open for the searched marker //TODO: make Stop Bundle-able val stopMarker = makeMarker(marker, ID, name, routesStopping, true) map!!.controller.animateTo(marker) } //add the overlays with the bus stops if (busPositionsOverlay == null) { //Log.i(DEBUG_TAG, "Null bus positions overlay,redo"); busPositionsOverlay = FolderOverlay() } startRequestsPositions() if (stopsViewModel != null) { stopsViewModel!!.stopsInBoundingBox.observe(viewLifecycleOwner) { stops: List? -> showStopsMarkers( stops ) } } else Log.d(DEBUG_TAG, "Cannot observe new stops in map, stopsViewModel is null") map!!.overlays.add(busPositionsOverlay) //set map as started hasMapStartFinished = true } /** * Start a request to load the stops that are in the current view * from the database */ private fun requestStopsToShow() { // get the top, bottom, left and right screen's coordinate val bb = map!!.boundingBox Log.d( DEBUG_TAG, "Requesting stops in bounding box, stopViewModel is null " + (stopsViewModel == null) ) if (stopsViewModel != null) { stopsViewModel!!.requestStopsInBoundingBox(bb) } } private fun updateBusMarker( marker: Marker?, posUpdate: LivePositionUpdate, justCreated: Boolean ) { val position: GeoPoint val updateID = posUpdate.tripID if (!justCreated) { position = marker!!.position if (posUpdate.latitude != position.latitude || posUpdate.longitude != position.longitude) { val newpos = GeoPoint(posUpdate.latitude, posUpdate.longitude) val valueAnimator = MarkerUtils.makeMarkerAnimator( map, marker, newpos, MarkerUtils.LINEAR_ANIMATION, 1200 ) valueAnimator.setAutoCancel(true) tripMarkersAnimators[updateID] = valueAnimator valueAnimator.start() } //marker.setPosition(new GeoPoint(posUpdate.getLatitude(), posUpdate.getLongitude())); } else { position = GeoPoint(posUpdate.latitude, posUpdate.longitude) marker!!.position = position } if (posUpdate.bearing != null) marker.rotation = posUpdate.bearing * -1f } private fun updateBusPositionsInMap(tripsPatterns: HashMap>) { Log.d(DEBUG_TAG, "Updating positions of the buses") //if(busPositionsOverlay == null) busPositionsOverlay = new FolderOverlay(); val noPatternsTrips = ArrayList() for (tripID in tripsPatterns.keys) { val (update, tripWithPatternStops) = tripsPatterns[tripID] ?: continue //check if Marker is already created if (busPositionMarkersByTrip.containsKey(tripID)) { //need to change the position of the marker val marker = busPositionMarkersByTrip[tripID]!! updateBusMarker(marker, update, false) if (marker.infoWindow != null && marker.infoWindow is BusInfoWindow) { val window = marker.infoWindow as BusInfoWindow if (tripWithPatternStops != null) { //Log.d(DEBUG_TAG, "Update pattern for trip: "+tripID); window.setPatternAndDraw(tripWithPatternStops.pattern) } } } else { //marker is not there, need to make it if (map == null) Log.e( DEBUG_TAG, "Creating marker with null map, things will explode" ) val marker = Marker(map) /*final Drawable mDrawable = DrawableUtils.Companion.getScaledDrawableResources( getResources(), R.drawable.point_heading_icon, R.dimen.map_icons_size, R.dimen.map_icons_size); */ //String route = GtfsUtils.getLineNameFromGtfsID(update.getRouteID()); val mdraw = ResourcesCompat.getDrawable(resources, R.drawable.map_bus_position_icon, null)!! //mdraw.setBounds(0,0,28,28); marker.icon = mdraw if (tripWithPatternStops == null) { noPatternsTrips.add(tripID) } var markerPattern: MatoPattern? = null if (tripWithPatternStops != null && tripWithPatternStops.pattern != null) markerPattern = tripWithPatternStops.pattern marker.infoWindow = BusInfoWindow(map!!, update, markerPattern, false) { pattern: MatoPattern? -> } marker.setInfoWindowAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) updateBusMarker(marker, update, true) // the overlay is null when it's not attached yet?5 // cannot recreate it because it becomes null very soon // if(busPositionsOverlay == null) busPositionsOverlay = new FolderOverlay(); //save the marker if (busPositionsOverlay != null) { busPositionsOverlay!!.add(marker) busPositionMarkersByTrip[tripID] = marker } } } if (noPatternsTrips.size > 0) { Log.i(DEBUG_TAG, "These trips have no matching pattern: $noPatternsTrips") } } /** * Add stops as Markers on the map * @param stops the list of stops that must be included */ protected fun showStopsMarkers(stops: List?) { if (context == null || stops == null) { //we are not attached return } var good = true for (stop in stops) { if (shownStops!!.contains(stop.ID)) { continue } if (stop.longitude == null || stop.latitude == null) continue shownStops!!.add(stop.ID) if (!map!!.isShown) { if (good) Log.d( DEBUG_TAG, "Need to show stop but map is not shown, probably detached already" ) good = false continue } else if (map!!.repository == null) { Log.e(DEBUG_TAG, "Map view repository is null") } val marker = GeoPoint(stop.latitude!!, stop.longitude!!) val stopMarker = makeMarker(marker, stop, false) stopsFolderOverlay!!.add(stopMarker) if (!map!!.overlays.contains(stopsFolderOverlay)) { Log.w(DEBUG_TAG, "Map doesn't have folder overlay") } good = true } //Log.d(DEBUG_TAG,"We have " +stopsFolderOverlay.getItems().size()+" stops in the folderOverlay"); //force redraw of markers map!!.invalidate() } fun makeMarker(geoPoint: GeoPoint?, stop: Stop, isStartMarker: Boolean): Marker { return makeMarker( geoPoint, stop.ID, stop.stopDefaultName, stop.routesThatStopHereToString(), isStartMarker ) } fun makeMarker( geoPoint: GeoPoint?, stopID: String?, stopName: String?, routesStopping: String?, isStartMarker: Boolean ): Marker { // add a marker val marker = Marker(map) // set custom info window as info window val popup = CustomInfoWindow( map, stopID, stopName, routesStopping, responder, R.layout.linedetail_stop_infowindow, R.color.red_darker ) marker.infoWindow = popup // make the marker clickable marker.setOnMarkerClickListener { thisMarker: Marker, mapView: MapView? -> if (thisMarker.isInfoWindowOpen) { // on second click Log.w(DEBUG_TAG, "Pressed on the click marker") } else { // on first click // hide all opened info window InfoWindow.closeAllInfoWindowsOn(map) // show this particular info window thisMarker.showInfoWindow() // move the map to its position map!!.controller.animateTo(thisMarker.position) } true } // set its position marker.position = geoPoint marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) // add to it an icon //marker.setIcon(getResources().getDrawable(R.drawable.bus_marker)); marker.icon = ResourcesCompat.getDrawable(resources, R.drawable.bus_stop, ctx!!.theme) // add to it a title marker.title = stopName // set the description as the ID marker.snippet = stopID // show popup info window of the searched marker if (isStartMarker) { marker.showInfoWindow() //map.getController().animateTo(marker.getPosition()); } return marker } override fun getBaseViewForSnackBar(): View? { return coordLayout } companion object { //private static final String TAG = "Busto-MapActivity"; private const val MAP_CURRENT_ZOOM_KEY = "map-current-zoom" private const val MAP_CENTER_LAT_KEY = "map-center-lat" private const val MAP_CENTER_LON_KEY = "map-center-lon" private const val FOLLOWING_LOCAT_KEY = "following" const val BUNDLE_LATIT = "lat" const val BUNDLE_LONGIT = "lon" const val BUNDLE_NAME = "name" const val BUNDLE_ID = "ID" const val BUNDLE_ROUTES_STOPPING = "routesStopping" const val FRAGMENT_TAG = "BusTOMapFragment" private const val DEFAULT_CENTER_LAT = 45.0708 private const val DEFAULT_CENTER_LON = 7.6858 private const val POSITION_FOUND_ZOOM = 18.3 const val NO_POSITION_ZOOM = 17.1 private const val DEBUG_TAG = FRAGMENT_TAG @JvmStatic fun getInstance(): MapFragmentKt { return MapFragmentKt() } @JvmStatic fun getInstance(stop: Stop): MapFragmentKt { val fragment = MapFragmentKt() val args = Bundle() args.putDouble(MapFragment.BUNDLE_LATIT, stop.latitude!!) args.putDouble(MapFragment.BUNDLE_LONGIT, stop.longitude!!) args.putString(MapFragment.BUNDLE_NAME, stop.stopDisplayName) args.putString(MapFragment.BUNDLE_ID, stop.ID) args.putString(MapFragment.BUNDLE_ROUTES_STOPPING, stop.routesThatStopHereToString()) fragment.arguments = args return fragment } } } diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt index de3c814..3ce278c 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt @@ -1,363 +1,366 @@ package it.reyboz.bustorino.fragments import android.annotation.SuppressLint import android.content.Context import android.graphics.drawable.Drawable import android.location.Location import android.os.Bundle import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.viewModels import com.google.gson.Gson import com.google.gson.JsonObject import it.reyboz.bustorino.R import it.reyboz.bustorino.backend.Stop import it.reyboz.bustorino.map.Styles +import it.reyboz.bustorino.util.ViewUtils import it.reyboz.bustorino.viewmodels.StopsMapViewModel import org.maplibre.android.MapLibre import org.maplibre.android.camera.CameraPosition import org.maplibre.android.maps.MapView import org.maplibre.android.geometry.LatLng import org.maplibre.android.geometry.LatLngBounds import org.maplibre.android.location.LocationComponent import org.maplibre.android.location.LocationComponentActivationOptions import org.maplibre.android.location.LocationComponentOptions import org.maplibre.android.location.engine.LocationEngineRequest import org.maplibre.android.location.modes.CameraMode import org.maplibre.android.maps.MapLibreMap import org.maplibre.android.maps.OnMapReadyCallback import org.maplibre.android.maps.Style import org.maplibre.android.style.layers.PropertyFactory import org.maplibre.android.style.layers.SymbolLayer import org.maplibre.android.style.sources.GeoJsonSource import org.maplibre.geojson.Feature import org.maplibre.geojson.FeatureCollection import org.maplibre.geojson.Point // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" private const val ARG_PARAM2 = "param2" /** * A simple [Fragment] subclass. * Use the [MapLibreFragment.newInstance] factory method to * create an instance of this fragment. */ class MapLibreFragment : Fragment(), OnMapReadyCallback { //private var param1: String? = null //private var param2: String? = null // Declare a variable for MapView private lateinit var mapView: MapView private lateinit var locationComponent: LocationComponent private var lastLocation: Location? = null private val stopsViewModel: StopsMapViewModel by viewModels() private val gson = Gson() private var stopsShowing = ArrayList(0) protected var map: MapLibreMap? = null // Sources for stops and buses private lateinit var stopsSource: GeoJsonSource private lateinit var busesSource: GeoJsonSource private var isStopsLayerStarted = false private var lastStopsSizeShown = 0 private var lastBBox = LatLngBounds.from(2.0, 2.0, 1.0,1.0) private lateinit var mapStyle: Style override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) /*arguments?.let { param1 = it.getString(ARG_PARAM1) param2 = it.getString(ARG_PARAM2) } */ MapLibre.getInstance(requireContext()) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment val rootView = inflater.inflate(R.layout.fragment_map_libre, container, false) // Init layout view // Init the MapView mapView = rootView.findViewById(R.id.libreMapView) mapView.getMapAsync(this) //{ //map -> //map.setStyle("https://demotiles.maplibre.org/style.json") } return rootView } override fun onMapReady(mapReady: MapLibreMap) { this.map = mapReady mapReady.cameraPosition = CameraPosition.Builder().target(LatLng(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON)).zoom( 15.0).build() + val mjson = Styles.getJsonStyleFromAsset(requireContext(), "map_style_good_noshops.json")//ViewUtils.loadJsonFromAsset(requireContext(),"map_style_good.json") activity?.run { - mapReady.setStyle(Styles.CARTO_VOYAGER ) { style -> + + mapReady.setStyle(Style.Builder().fromJson(mjson!!)) { style -> mapStyle = style setupLayers(style) // Start observing data observeViewModels() initLocation(style, mapReady, requireContext()) } mapReady.addOnCameraIdleListener { map?.let { val newBbox = it.projection.visibleRegion.latLngBounds if ((newBbox.center==lastBBox.center) && (newBbox.latitudeSpan==lastBBox.latitudeSpan) && (newBbox.longitudeSpan==lastBBox.latitudeSpan)){ //do nothing } else { stopsViewModel.loadStopsInLatLngBounds(newBbox) lastBBox = newBbox } } } //makeStyleMapBoxUrl(false)) } } @SuppressLint("MissingPermission") private fun initLocation(style: Style, map: MapLibreMap, context: Context){ locationComponent = map.locationComponent val locationComponentOptions = LocationComponentOptions.builder(context) .pulseEnabled(true) .build() val locationComponentActivationOptions = buildLocationComponentActivationOptions(style, locationComponentOptions, context) locationComponent.activateLocationComponent(locationComponentActivationOptions) locationComponent.isLocationComponentEnabled = true locationComponent.cameraMode = CameraMode.TRACKING //CameraMode.TRACKING locationComponent.forceLocationUpdate(lastLocation) } private fun buildLocationComponentActivationOptions( style: Style, locationComponentOptions: LocationComponentOptions, context: Context ): LocationComponentActivationOptions { return LocationComponentActivationOptions .builder(context, style) .locationComponentOptions(locationComponentOptions) .useDefaultLocationEngine(true) .locationEngineRequest( LocationEngineRequest.Builder(750) .setFastestInterval(750) .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY) .build() ) .build() } private fun startLayerStops(style: Style, features:FeatureCollection){ stopsSource = GeoJsonSource(STOPS_SOURCE_ID,features) style.addSource(stopsSource) // add icon style.addImage(STOP_IMAGE_ID, ResourcesCompat.getDrawable(resources,R.drawable.bus_stop, activity?.theme)!!) // Stops layer val stopsLayer = SymbolLayer(STOPS_LAYER_ID, STOPS_SOURCE_ID) stopsLayer.withProperties( PropertyFactory.iconImage(STOP_IMAGE_ID), PropertyFactory.iconAllowOverlap(true), PropertyFactory.iconIgnorePlacement(true) ) style.addLayerBelow(stopsLayer, "label_country_1") isStopsLayerStarted = true } /** * Setup the Map Layers */ private fun setupLayers(style: Style) { // Stops source // Buses source // TODO when adding the buses //busesSource = GeoJsonSource(BUSES_SOURCE_ID) //style.addSource(busesSource) /* // TODO when adding the buses // Buses layer val busesLayer = SymbolLayer(BUSES_LAYER_ID, BUSES_SOURCE_ID).apply { withProperties( PropertyFactory.iconImage("bus"), PropertyFactory.iconSize(1.0f), PropertyFactory.iconAllowOverlap(true), PropertyFactory.iconRotate(Expression.get("bearing")) ) } style.addLayer(busesLayer) */ } /** * Incremental updates of the layers */ fun updateLayerIncrementally(newPoints: List, layerSourceId: String) { val source = map?.style?.getSourceAs(layerSourceId) ?: return //source.querySourceFeatures(null) // Get existing features val existingFeatures = source.querySourceFeatures(null).toMutableList() // Add new features val newFeatures = newPoints.map { point -> Feature.fromGeometry(point) } existingFeatures.addAll(newFeatures) // Update source source.setGeoJson(FeatureCollection.fromFeatures(existingFeatures)) } override fun onStart() { super.onStart() mapView.onStart() } override fun onResume() { super.onResume() mapView.onResume() } override fun onPause() { super.onPause() mapView.onPause() } override fun onStop() { super.onStop() mapView.onStop() } override fun onLowMemory() { super.onLowMemory() mapView.onLowMemory() } override fun onDestroy() { super.onDestroy() mapView.onDestroy() } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) mapView.onSaveInstanceState(outState) } private fun observeViewModels() { // Observe stops stopsViewModel.stopsToShow.observe(viewLifecycleOwner) { stops -> stopsShowing = stops displayStops(stops) } } /** * Add the stops to the layers */ private fun displayStops(stops: List?) { if (stops.isNullOrEmpty()) return if (stops.size==lastStopsSizeShown){ Log.d(DEBUG_TAG, "Not updating, we have the same stop (can only increase!)") return } val features = stops.mapNotNull { stop -> stop.latitude?.let { lat -> stop.longitude?.let { lon -> Feature.fromGeometry( Point.fromLngLat(lon, lat), JsonObject().apply { addProperty("id", stop.ID) addProperty("name", stop.stopDefaultName) addProperty("routes", stop.routesThatStopHereToString()) // Add routes array to JSON object } ) } } } Log.d(DEBUG_TAG,"Have put ${features.size} stops to display") if (isStopsLayerStarted) { stopsSource.setGeoJson(FeatureCollection.fromFeatures(features)) lastStopsSizeShown = features.size } else map?.let { startLayerStops(mapStyle, FeatureCollection.fromFeatures(features)) Log.d(DEBUG_TAG,"Started stops layer on map") lastStopsSizeShown = features.size } } companion object { private const val STOPS_SOURCE_ID = "stops-source" private const val STOPS_LAYER_ID = "stops-layer" private const val BUSES_SOURCE_ID = "buses-source" private const val BUSES_LAYER_ID = "buses-layer" private const val STOP_IMAGE_ID ="bus-stop-icon" private const val DEFAULT_CENTER_LAT = 45.0708 private const val DEFAULT_CENTER_LON = 7.6858 private const val POSITION_FOUND_ZOOM = 16.5 private const val NO_POSITION_ZOOM = 17.1 private const val ACCESS_TOKEN="KxO8lF4U3kiO63m0c7lzqDCDrMUVg1OA2JVzRXxxmYSyjugr1xpe4W4Db5rFNvbQ" private const val MAPLIBRE_URL = "https://api.jawg.io/styles/" private const val DEBUG_TAG = "BusTO-MapLibreFrag" /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment MapLibreFragment. */ // TODO: Rename and change types and number of parameters @JvmStatic fun newInstance(param1: String, param2: String) = MapLibreFragment().apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) putString(ARG_PARAM2, param2) } } private fun makeStyleUrl(style: String = "jawg-streets") = "${MAPLIBRE_URL+ style}.json?access-token=${ACCESS_TOKEN}" private fun makeStyleMapBoxUrl(dark: Boolean) = if(dark) "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json" else //"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json" const val OPENFREEMAP_LIBERY = "https://tiles.openfreemap.org/styles/liberty" const val OPENFREEMAP_BRIGHT = "https://tiles.openfreemap.org/styles/bright" } } \ No newline at end of file diff --git a/app/src/main/java/it/reyboz/bustorino/map/Styles.kt b/app/src/main/java/it/reyboz/bustorino/map/Styles.kt index d797f66..8c76ada 100644 --- a/app/src/main/java/it/reyboz/bustorino/map/Styles.kt +++ b/app/src/main/java/it/reyboz/bustorino/map/Styles.kt @@ -1,50 +1,56 @@ package it.reyboz.bustorino.map +import android.content.Context +import it.reyboz.bustorino.util.ViewUtils import org.maplibre.android.maps.Style object Styles { const val DEMOTILES = "https://demotiles.maplibre.org/style.json" const val VERSATILES = "https://tiles.versatiles.org/assets/styles/colorful.json" const val AMERICANA = "https://americanamap.org/style.json" - const val OPENFREEMAP_LIBERY = "https://tiles.openfreemap.org/styles/liberty" + const val OPENFREEMAP_LIBERTY = "https://tiles.openfreemap.org/styles/liberty" const val OPENFREEMAP_BRIGHT = "https://tiles.openfreemap.org/styles/bright" + const val BASIC_V8 = "mapbox://styles/mapbox/streets-v8" + + const val AWS_OPEN_DATA_STANDARD_LIGHT = "https://maps.geo.us-east-2.amazonaws.com/maps/v0/maps/OpenDataStyle/style-descriptor?key=v1.public.eyJqdGkiOiI1NjY5ZTU4My0yNWQwLTQ5MjctODhkMS03OGUxOTY4Y2RhMzgifR_7GLT66TNRXhZJ4KyJ-GK1TPYD9DaWuc5o6YyVmlikVwMaLvEs_iqkCIydspe_vjmgUVsIQstkGoInXV_nd5CcmqRMMa-_wb66SxDdbeRDvmmkpy2Ow_LX9GJDgL2bbiCws0wupJPFDwWCWFLwpK9ICmzGvNcrPbX5uczOQL0N8V9iUvziA52a1WWkZucIf6MUViFRf3XoFkyAT15Ll0NDypAzY63Bnj8_zS8bOaCvJaQqcXM9lrbTusy8Ftq8cEbbK5aMFapXRjug7qcrzUiQ5sr0g23qdMvnKJQFfo7JuQn8vwAksxrQm6A0ByceEXSfyaBoVpFcTzEclxUomhY.NjAyMWJkZWUtMGMyOS00NmRkLThjZTMtODEyOTkzZTUyMTBi" private fun protomaps(style: String): String { return "https://api.protomaps.com/styles/v2/${style}.json?key=e761cc7daedf832a" } private fun makeStyleMapBoxUrl(dark: Boolean) = if (dark) "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json" else //"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json" val PROTOMAPS_LIGHT = protomaps("light") val PROTOMAPS_DARK = protomaps("dark") val PROTOMAPS_GRAYSCALE = protomaps("grayscale") val PROTOMAPS_WHITE = protomaps("white") val PROTOMAPS_BLACK = protomaps("black") val CARTO_DARK = makeStyleMapBoxUrl(true) val CARTO_VOYAGER = makeStyleMapBoxUrl(false) fun getPredefinedStyleWithFallback(name: String): String { try { val style = Style.getPredefinedStyle(name) return style } catch (e: Exception) { - return OPENFREEMAP_LIBERY + return OPENFREEMAP_LIBERTY } } + fun getJsonStyleFromAsset(context: Context, filename: String) = ViewUtils.loadJsonFromAsset(context,filename) } \ No newline at end of file diff --git a/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt b/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt index bb4071c..0a3947a 100644 --- a/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt +++ b/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt @@ -1,109 +1,119 @@ package it.reyboz.bustorino.util import android.R import android.content.Context import android.content.res.Resources.Theme import android.graphics.Rect import android.util.Log import android.util.TypedValue import android.view.View import android.view.WindowManager import android.view.animation.Animation import android.view.animation.Transformation import androidx.annotation.ColorInt import androidx.core.widget.NestedScrollView +import java.io.IOException class ViewUtils { companion object{ const val DEBUG_TAG="BusTO:ViewUtils" fun isViewFullyVisibleInScroll(view: View, scrollView: NestedScrollView): Boolean { val scrollBounds = Rect() scrollView.getDrawingRect(scrollBounds) val top = view.y val bottom = top + view.height Log.d(DEBUG_TAG, "Scroll bounds are $scrollBounds, top:${view.y}, bottom $bottom") return (scrollBounds.top < top && scrollBounds.bottom > bottom) } fun isViewPartiallyVisibleInScroll(view: View, scrollView: NestedScrollView): Boolean{ val scrollBounds = Rect() scrollView.getHitRect(scrollBounds) Log.d(DEBUG_TAG, "Scroll bounds are $scrollBounds") if (view.getLocalVisibleRect(scrollBounds)) { return true } else { return false } } //from https://stackoverflow.com/questions/4946295/android-expand-collapse-animation fun expand(v: View,duration: Long, layoutHeight: Int = WindowManager.LayoutParams.WRAP_CONTENT) { val matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec((v.parent as View).width, View.MeasureSpec.EXACTLY) val wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) v.measure(matchParentMeasureSpec, wrapContentMeasureSpec) val targetHeight = v.measuredHeight // Older versions of android (pre API 21) cancel animations for views with a height of 0. v.layoutParams.height = 1 v.visibility = View.VISIBLE val a: Animation = object : Animation() { override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { v.layoutParams.height = if (interpolatedTime == 1f) layoutHeight else (targetHeight * interpolatedTime).toInt() v.requestLayout() } override fun willChangeBounds(): Boolean { return true } } // Expansion speed of 1dp/ms if(duration == DEF_DURATION) a.duration = (targetHeight / v.context.resources.displayMetrics.density).toInt().toLong() else a.duration = duration v.startAnimation(a) } fun collapse(v: View, duration: Long): Animation { val initialHeight = v.measuredHeight val a: Animation = object : Animation() { override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { if (interpolatedTime == 1f) { v.visibility = View.GONE } else { v.layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt() v.requestLayout() } } override fun willChangeBounds(): Boolean { return true } } // Collapse speed of 1dp/ms if (duration == DEF_DURATION) a.duration = (initialHeight / v.context.resources.displayMetrics.density).toInt().toLong() else a.duration = duration v.startAnimation(a) return a } const val DEF_DURATION: Long = -2 fun getColorFromTheme(context: Context, resId: Int): Int { val typedValue = TypedValue() val theme: Theme = context.getTheme() theme.resolveAttribute(resId, typedValue, true) val color = typedValue.data return color } + fun loadJsonFromAsset(context: Context, fileName: String): String? { + return try { + context.assets.open(fileName).bufferedReader().use { it.readText() } + } catch (e: IOException) { + e.printStackTrace() + null + } + } + } } \ No newline at end of file