├── .eslintrc ├── .github ├── dependabot.yml └── workflows │ └── check_version.yml ├── .gitignore ├── .prettierrc ├── LICENSE.md ├── README.md ├── bin └── styletool-cli ├── cli ├── extract_difference.js ├── fileMappings.js ├── index.js ├── render.js ├── reorder.js ├── split.js └── static │ ├── 3d.json │ ├── driver-info.json │ ├── greyscale.json │ ├── near-bus-routes.json │ ├── near-bus-stops.json │ ├── print.json │ ├── regular-routes.json │ ├── regular-stops.json │ ├── routes-with-departures-only.json │ ├── simplified.json │ ├── stops-with-route-info.json │ ├── text-en.json │ ├── text-fisv.json │ └── text-sv.json ├── data ├── kuntarajat.json ├── rail.geojson ├── subway.geojson ├── ticket-zone-labels.json └── ticket-zones.json ├── index.html ├── index.js ├── map-icons ├── icon-citybike-station.svg ├── icon-citybike-station2.svg ├── icon-direction1.svg ├── icon-direction2.svg ├── icon-entrance-lift.svg ├── icon-entrance-stairs.svg ├── icon-entrance-subway.svg ├── icon-entrance-wheelchair.svg ├── icon-letter-00.svg ├── icon-letter-A.svg ├── icon-letter-B.svg ├── icon-letter-C.svg ├── icon-letter-D.svg ├── icon-letter-E.svg ├── icon-letter-F.svg ├── icon-letter-G.svg ├── icon-letter-H.svg ├── icon-letter-I.svg ├── icon-letter-J.svg ├── icon-letter-K.svg ├── icon-letter-L.svg ├── icon-letter-M.svg ├── icon-letter-N.svg ├── icon-letter-O.svg ├── icon-letter-P.svg ├── icon-letter-Q.svg ├── icon-letter-R.svg ├── icon-letter-S.svg ├── icon-letter-T.svg ├── icon-letter-U.svg ├── icon-letter-V.svg ├── icon-letter-W.svg ├── icon-letter-X.svg ├── icon-letter-Y.svg ├── icon-letter-Z.svg ├── icon-letter-Ä.svg ├── icon-letter-Å.svg ├── icon-letter-Ö.svg ├── icon-one-way.svg ├── icon-park-and-ride.svg ├── icon-platform-bus.svg ├── icon-platform-train.svg ├── icon-platform-tram.svg ├── icon-stop-bus.svg ├── icon-stop-ferry.svg ├── icon-stop-hybrid.svg ├── icon-stop-train.svg ├── icon-stop-tram.svg ├── icon-terminal-aerodrome.svg ├── icon-terminal-bus.svg ├── icon-terminal-ferry.svg ├── icon-terminal-ship.svg ├── icon-terminal-subway.svg ├── icon-terminal-train.svg ├── icon-tickets-machine-parking.svg ├── icon-tickets-machine.svg ├── icon-tickets-sales-point.svg ├── icon-tickets-service-point.svg ├── icon-time1.svg ├── icon-time2.svg ├── icon-wetland.svg ├── icon-zone-A.svg ├── icon-zone-B.svg ├── icon-zone-C.svg └── icon-zone-D.svg ├── package.json ├── server.js ├── sprite.json ├── sprite.png ├── sprite@2x.json ├── sprite@2x.png ├── sprite@3x.json ├── sprite@3x.png ├── spritezero ├── .nvmrc ├── README.md ├── package.json └── yarn.lock ├── style.json ├── style ├── hsl-map-style-base.json ├── hsl-map-style-citybikes.json ├── hsl-map-style-icon.json ├── hsl-map-style-municipal-borders.json ├── hsl-map-style-park-and-ride.json ├── hsl-map-style-routes.json ├── hsl-map-style-stops.json ├── hsl-map-style-subway-entrance.json ├── hsl-map-style-text.json ├── hsl-map-style-ticket-sales.json ├── hsl-map-style-ticket-zone-labels.json ├── hsl-map-style-ticket-zones.json ├── hsl-map-template.json ├── hsl-map-theme-3d.json ├── hsl-map-theme-driver-info.json ├── hsl-map-theme-greyscale.json ├── hsl-map-theme-near-bus-routes.json ├── hsl-map-theme-near-bus-stops.json ├── hsl-map-theme-print.json ├── hsl-map-theme-regular-routes.json ├── hsl-map-theme-regular-stops.json ├── hsl-map-theme-routes-with-departures-only.json ├── hsl-map-theme-simplified.json ├── hsl-map-theme-stops-with-route-info.json ├── hsl-map-theme-text-en.json ├── hsl-map-theme-text-fisv.json └── hsl-map-theme-text-sv.json └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-base", "plugin:prettier/recommended"], 3 | "plugins": ["import"], 4 | "rules": { 5 | "quotes": ["error", "double", {"avoidEscape": true}], 6 | "vars-on-top": "off", 7 | "global-require": "off", 8 | "import/order": "off", 9 | "no-plusplus": "off", 10 | "import/no-extraneous-dependencies": ["error", { "devDependencies": true }] 11 | }, 12 | "env": { 13 | "browser": true, 14 | "node": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Specify a non-default branch for pull requests for npm 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: "npm" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | # Raise pull requests for version updates 10 | # to npm against the `development` branch 11 | target-branch: "development" 12 | # Labels on pull requests for version updates only 13 | labels: 14 | - "NPM Dependencies" 15 | -------------------------------------------------------------------------------- /.github/workflows/check_version.yml: -------------------------------------------------------------------------------- 1 | name: Check version 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | check_version: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | - name: Check if version has been updated 15 | id: check 16 | uses: EndBug/version-check@v2 17 | - name: Fail if version is not changed 18 | if: steps.check.outputs.changed == 'false' 19 | uses: actions/github-script@v3 20 | with: 21 | script: | 22 | core.setFailed('No version number change found. Run `yarn version`-command to upgrade version before merge can be completed.') 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | fontstack/ 2 | Gotham Rounded OpenType/ 3 | node_modules/ 4 | master/ 5 | fonts 6 | .DS_Store -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "arrowParens": "always", 4 | "bracketSpacing": true, 5 | "printWidth": 85, 6 | "semi": true, 7 | "trailingComma": "es5" 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Code license: MIT License 2 | 3 | Copyright (c) 2018, HSL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | 24 | # Design license: CC-BY 4.0 25 | 26 | The visual design features of the style (also known as the "look and feel" of the map) are licensed under the Creative Commons Attribution 4.0 license. 27 | 28 | To view a copy of the license, visit https://creativecommons.org/licenses/by/4.0/. 29 | 30 | Attribution for the design defined in this repository does not need to be provided on map images, but should be reasonably accessible from maps based on this style (for example, in a webpage linked from copyright notice on the map). 31 | -------------------------------------------------------------------------------- /bin/styletool-cli: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@" 3 | 4 | const styletool = require('../cli/index') 5 | styletool() 6 | -------------------------------------------------------------------------------- /cli/extract_difference.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs-extra"); 3 | const get = require("lodash/get"); 4 | const differenceBy = require("lodash/differenceBy"); 5 | const merge = require("lodash/merge"); 6 | 7 | module.exports = async function(file, compareFile) { 8 | const filePath = path.resolve(process.cwd(), file); 9 | const compareFilePath = path.resolve(process.cwd(), compareFile); 10 | 11 | const fileJson = await fs.readJson(filePath); 12 | const compareFileJson = await fs.readJson(compareFilePath); 13 | 14 | const layers = get(fileJson, "layers", []); 15 | 16 | if (layers.length === 0) { 17 | throw new Error("No layers in file!"); 18 | } 19 | 20 | const compareLayers = get(compareFileJson, "layers", []); 21 | 22 | if (compareLayers.length === 0) { 23 | throw new Error("No layers in order file!"); 24 | } 25 | 26 | const diffLayers = differenceBy(layers, compareLayers, "id"); 27 | 28 | const diffFilejson = { 29 | layers: diffLayers, 30 | }; 31 | 32 | diffLayers.forEach((layer) => { 33 | const source = get(layer, "source"); 34 | const mapboxGroup = get(layer, "metadata.mapbox:group", ""); 35 | 36 | if (source) { 37 | merge(diffFilejson, { 38 | sources: { [source]: fileJson.sources[source] }, 39 | }); 40 | } 41 | 42 | if (mapboxGroup) { 43 | merge(diffFilejson, { 44 | metadata: { 45 | "mapbox:groups": { 46 | [mapboxGroup]: fileJson.metadata["mapbox:groups"][mapboxGroup], 47 | }, 48 | }, 49 | }); 50 | } 51 | }); 52 | 53 | const newLayers = layers.filter((layer) => { 54 | const isDiff = diffLayers.find((dl) => dl.id === layer.id); 55 | return !isDiff; 56 | }); 57 | 58 | fileJson.layers = newLayers; 59 | 60 | await fs.writeJson(filePath, fileJson, { spaces: 2 }); 61 | await fs.writeJson( 62 | path.resolve(path.dirname(filePath), `layerdiff_${path.basename(file)}`), 63 | diffFilejson, 64 | { spaces: 2 } 65 | ); 66 | 67 | process.exit(0); 68 | }; 69 | -------------------------------------------------------------------------------- /cli/fileMappings.js: -------------------------------------------------------------------------------- 1 | const some = require("lodash/some"); 2 | const reduce = require("lodash/reduce"); 3 | const get = require("lodash/get"); 4 | 5 | const select = (values, value) => some(values, (val) => val === value); 6 | const inGroups = (values, value) => some(values, (val) => value.startsWith(val)); 7 | 8 | /** 9 | * Map layers to files. FileMappers is a map of file names and the criteria 10 | * a layer has to fulfill with its id or source-layer property to be included 11 | * in the file. The criteria can be either a function that returns a boolean 12 | * to indicate whether or not the layer should be included, or an array of 13 | * strings that the layer's id or source-layer prop should match. 14 | * 15 | * The order is important. Later file matchers override earlier ones. For a 16 | * layer called "rail_tunnel", and the files "routes" and "base", the layer 17 | * will be included in the "base" file if both criterias match. 18 | */ 19 | 20 | const fileMappers = { 21 | base: (value) => { 22 | const names = ["background", "admin_country"]; 23 | const groups = [ 24 | "landuse", 25 | "water", 26 | "aeroway", 27 | "building", 28 | "road", 29 | "tunnel", 30 | "bridge", 31 | ]; 32 | if (inGroups(groups, value)) { 33 | return true; 34 | } 35 | return select(names, value); 36 | }, 37 | "municipal-borders": ["municipal_border"], 38 | routes: (value) => inGroups(["route"], value), 39 | stops: (value) => inGroups(["stops"], value), 40 | "ticket-zones": (value) => inGroups(["ticket-zones"], value), 41 | "ticket-zone-labels": (value) => inGroups(["ticket-zone-label"], value), 42 | text: (value) => inGroups(["label"], value), 43 | "subway-entrance": (value) => inGroups(["subway-entrance"], value), 44 | icon: (value) => inGroups(["icon"], value), 45 | "park-and-ride": (value) => inGroups(["park-and-ride"], value), 46 | "ticket-sales": (value) => inGroups(["ticket-sales"], value), 47 | citybikes: (value) => inGroups(["citybike"], value), 48 | }; 49 | 50 | function layerToFile(layer) { 51 | const sourceLayer = get(layer, "source-layer", "base"); 52 | const layerId = get(layer, "id", "base"); 53 | 54 | return reduce( 55 | fileMappers, 56 | (groupName, match, layerGroupName) => { 57 | const matchToGroup = (val) => { 58 | if (typeof match === "function") { 59 | return match(val); 60 | } 61 | if (Array.isArray(match)) { 62 | return select(match, val); 63 | } 64 | 65 | return false; 66 | }; 67 | 68 | // The matchers will be called with the sourceLayer first, and then the layerId. 69 | let isInGroup = matchToGroup(sourceLayer); 70 | 71 | if (!isInGroup) { 72 | isInGroup = matchToGroup(layerId); 73 | } 74 | 75 | if (isInGroup) { 76 | return layerGroupName; 77 | } 78 | 79 | return groupName; 80 | }, 81 | sourceLayer 82 | ); 83 | } 84 | 85 | module.exports = layerToFile; 86 | -------------------------------------------------------------------------------- /cli/index.js: -------------------------------------------------------------------------------- 1 | const program = require("commander"); 2 | const split = require("./split"); 3 | const render = require("./render"); 4 | const reorder = require("./reorder"); 5 | const extract_difference = require("./extract_difference"); 6 | 7 | module.exports = function() { 8 | program.version("1.0.0"); 9 | 10 | program 11 | .command("split ") 12 | .description( 13 | "Split a style json file into distinct parts. Splits file into partials and writes them into dir. Dir will be created if it doesn't exist." 14 | ) 15 | .action(split); 16 | 17 | program 18 | .command("render") 19 | .description( 20 | "Render a complete style.json from parts. Toggle partials in cli/render.js." 21 | ) 22 | .action(render); 23 | 24 | program 25 | .command("matchorder ") 26 | .description( 27 | "Match layer order between different style files. Rewrites fileA to have its layers in the same order as fileB." 28 | ) 29 | .action(reorder); 30 | 31 | program 32 | .command("extract-diff ") 33 | .description( 34 | "Move layers out from fileA that don't exist in fileB. Modifies fileA." 35 | ) 36 | .action(extract_difference); 37 | 38 | program.parse(process.argv); 39 | }; 40 | -------------------------------------------------------------------------------- /cli/render.js: -------------------------------------------------------------------------------- 1 | const style = require("../index"); 2 | 3 | module.exports = () => { 4 | const styleJson = style.generateStyle({ 5 | sourcesUrl: "https://api.digitransit.fi/", 6 | glyphsUrl: "", 7 | spriteUrl: "", 8 | 9 | queryParams: [ 10 | { 11 | url: "https://api.digitransit.fi/", 12 | name: "digitransit-subscription-key", 13 | value: "my-secret-key", 14 | }, 15 | ], 16 | components: { 17 | // Set each layer you want to include to true 18 | // Styles 19 | base: { enabled: true }, // Enabled by default 20 | municipal_borders: { enabled: false }, 21 | routes: { enabled: false }, 22 | text: { enabled: true }, // Enabled by default 23 | subway_entrance: { enabled: false }, 24 | poi: { enabled: false }, 25 | park_and_ride: { enabled: false }, 26 | ticket_sales: { enabled: false }, 27 | stops: { enabled: false }, 28 | citybikes: { enabled: false }, 29 | ticket_zones: { enabled: false }, 30 | ticket_zone_labels: { enabled: false }, 31 | // Themes 32 | text_sv: { enabled: false }, 33 | text_fisv: { enabled: false }, 34 | text_en: { enabled: false }, 35 | regular_routes: { enabled: false }, 36 | near_bus_routes: { enabled: false }, 37 | routes_with_departures_only: { enabled: true }, // Enabled by default. Doesn't do anything until routes is enabled 38 | regular_stops: { enabled: false }, 39 | near_bus_stops: { enabled: false }, 40 | print: { enabled: false }, 41 | greyscale: { enabled: false }, 42 | simplified: { enabled: false }, 43 | "3d": { enabled: false }, 44 | driver_info: { enabled: false }, 45 | }, 46 | routeFilter: [], 47 | joreDate: null, // defaults to current date in API 48 | }); 49 | 50 | process.stdout.write(JSON.stringify(styleJson, null, 2)); 51 | process.exit(0); 52 | }; 53 | -------------------------------------------------------------------------------- /cli/reorder.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs-extra"); 3 | const get = require("lodash/get"); 4 | const sortBy = require("lodash/sortBy"); 5 | 6 | module.exports = async function(file, orderFile) { 7 | const filePath = path.resolve(process.cwd(), file); 8 | const orderFilePath = path.resolve(process.cwd(), orderFile); 9 | 10 | const fileJson = await fs.readJson(filePath); 11 | const orderFileJson = await fs.readJson(orderFilePath); 12 | 13 | const layers = get(fileJson, "layers", []); 14 | 15 | if (layers.length === 0) { 16 | throw new Error("No layers in file!"); 17 | } 18 | 19 | const orderLayers = get(orderFileJson, "layers", []); 20 | 21 | if (orderLayers.length === 0) { 22 | throw new Error("No layers in order file!"); 23 | } 24 | 25 | const newLayers = sortBy(layers, (layer) => 26 | orderLayers.findIndex((ol) => ol.id === layer.id) 27 | ); 28 | 29 | fileJson.layers = newLayers; 30 | await fs.writeJson(filePath, fileJson, { spaces: 2 }); 31 | 32 | process.exit(0); 33 | }; 34 | -------------------------------------------------------------------------------- /cli/split.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs-extra"); 3 | const get = require("lodash/get"); 4 | const set = require("lodash/set"); 5 | const reduce = require("lodash/reduce"); 6 | const merge = require("lodash/merge"); 7 | const layerToFile = require("./fileMappings"); 8 | 9 | const FILENAME_PREFIX = "hsl-map-"; 10 | 11 | module.exports = async function(file, dir) { 12 | const filePath = path.resolve(process.cwd(), file); 13 | const outputPath = path.resolve(process.cwd(), dir); 14 | const staticPath = path.resolve(__dirname, "static"); 15 | 16 | const writeFile = async (name, content) => { 17 | await fs.writeJson(path.resolve(outputPath, FILENAME_PREFIX + name), content, { 18 | spaces: 2, 19 | }); 20 | }; 21 | 22 | await fs.mkdirp(outputPath); 23 | 24 | const styleJson = await fs.readJson(filePath); 25 | const mapboxGroups = get(styleJson, "metadata.mapbox:groups", {}); 26 | const sources = get(styleJson, "sources", {}); 27 | const layers = get(styleJson, "layers", []); 28 | 29 | console.log("Resetting style wrapper..."); 30 | 31 | // Reset these to empty things 32 | set(styleJson, "metadata.mapbox-groups", {}); 33 | set(styleJson, "sources", {}); 34 | set(styleJson, "layers", []); 35 | 36 | console.log("Writing style wrapper..."); 37 | 38 | await writeFile("template.json", styleJson); 39 | 40 | console.log("Splitting layers..."); 41 | 42 | // Determine which layers go into which files. 43 | const layerGroups = reduce( 44 | layers, 45 | (groups, layer) => { 46 | const fileGroup = layerToFile(layer); 47 | 48 | if (!(fileGroup in groups)) { 49 | set(groups, fileGroup, []); 50 | } 51 | 52 | groups[fileGroup].push(layer); 53 | return groups; 54 | }, 55 | {} 56 | ); 57 | 58 | // Create the json structure that will be written into the file 59 | const fileGroups = reduce( 60 | layerGroups, 61 | (files, groupLayers, groupName) => { 62 | const container = { 63 | layers: groupLayers, 64 | }; 65 | 66 | groupLayers.forEach((layer) => { 67 | const source = get(layer, "source"); 68 | const mapboxGroup = get(layer, "metadata.mapbox:group", ""); 69 | 70 | if (source) { 71 | merge(container, { 72 | sources: { [source]: sources[source] }, 73 | }); 74 | } 75 | 76 | if (mapboxGroup) { 77 | merge(container, { 78 | metadata: { 79 | "mapbox:groups": { [mapboxGroup]: mapboxGroups[mapboxGroup] }, 80 | }, 81 | }); 82 | } 83 | }); 84 | 85 | files.push({ name: groupName, content: container }); 86 | return files; 87 | }, 88 | [] 89 | ); 90 | 91 | const writePromises = fileGroups.map((styleFile) => { 92 | console.log("Writing file %s", styleFile.name); 93 | return writeFile(`style-${styleFile.name}.json`, styleFile.content); 94 | }); 95 | 96 | const staticFiles = await fs.readdir(staticPath); 97 | 98 | staticFiles.forEach((staticFile) => { 99 | writePromises.push( 100 | fs.copy( 101 | path.resolve(staticPath, staticFile), 102 | path.resolve(outputPath, `${FILENAME_PREFIX}theme-${staticFile}`) 103 | ) 104 | ); 105 | }); 106 | 107 | await Promise.all(writePromises); 108 | 109 | process.exit(0); 110 | }; 111 | -------------------------------------------------------------------------------- /cli/static/3d.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "building_shadow", 5 | "layout": { 6 | "visibility": "none" 7 | } 8 | }, 9 | { 10 | "id": "building", 11 | "layout": { 12 | "visibility": "none" 13 | } 14 | }, 15 | { 16 | "id": "building_3d", 17 | "layout": { 18 | "visibility": "visible" 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /cli/static/driver-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "stops_case", 5 | "source": "stops-by-routes", 6 | "minzoom": 0, 7 | "filter": ["==", ["get", "timingStopType"], 0], 8 | "paint": { 9 | "circle-radius": 9 10 | } 11 | }, 12 | { 13 | "id": "stops_rail_case", 14 | "source": "stops-by-routes", 15 | "minzoom": 0, 16 | "filter": ["==", ["get", "timingStopType"], 0], 17 | "paint": { 18 | "circle-radius": 9 19 | } 20 | }, 21 | { 22 | "id": "stops_rail", 23 | "source": "stops-by-routes", 24 | "minzoom": 0, 25 | "filter": ["==", ["get", "timingStopType"], 0], 26 | "paint": { 27 | "circle-radius": 8 28 | } 29 | }, 30 | { 31 | "id": "stops_bus", 32 | "source": "stops-by-routes", 33 | "minzoom": 0, 34 | "filter": ["==", ["get", "timingStopType"], 0], 35 | "paint": { 36 | "circle-radius": 8 37 | } 38 | }, 39 | { 40 | "id": "stops_trunk", 41 | "source": "stops-by-routes", 42 | "minzoom": 0, 43 | "filter": ["==", ["get", "timingStopType"], 0], 44 | "paint": { 45 | "circle-radius": 8 46 | } 47 | }, 48 | { 49 | "id": "stops_ferry", 50 | "source": "stops-by-routes", 51 | "minzoom": 0, 52 | "filter": ["==", ["get", "timingStopType"], 0], 53 | "paint": { 54 | "circle-radius": 8 55 | } 56 | }, 57 | { 58 | "id": "stops_tram", 59 | "source": "stops-by-routes", 60 | "minzoom": 0, 61 | "filter": ["==", ["get", "timingStopType"], 0], 62 | "paint": { 63 | "circle-radius": 8 64 | } 65 | }, 66 | { 67 | "id": "stops_lrail", 68 | "source": "stops-by-routes", 69 | "minzoom": 0, 70 | "filter": ["==", ["get", "timingStopType"], 0], 71 | "paint": { 72 | "circle-radius": 8 73 | } 74 | }, 75 | { 76 | "id": "stops_subway", 77 | "source": "stops-by-routes", 78 | "minzoom": 0, 79 | "filter": ["==", ["get", "timingStopType"], 0], 80 | "paint": { 81 | "circle-radius": 8 82 | } 83 | }, 84 | { 85 | "id": "stops_hub", 86 | "source": "stops-by-routes", 87 | "minzoom": 0, 88 | "filter": ["==", ["get", "timingStopType"], 0], 89 | "paint": { 90 | "circle-radius": 5.5 91 | } 92 | }, 93 | { 94 | "id": "stops_rail_hub", 95 | "source": "stops-by-routes", 96 | "minzoom": 0, 97 | "filter": ["==", ["get", "timingStopType"], 0], 98 | "paint": { 99 | "circle-radius": 5.5 100 | } 101 | }, 102 | { 103 | "id": "stops_timing_icon", 104 | "minzoom": 0, 105 | "layout": { 106 | "visibility": "visible" 107 | } 108 | }, 109 | { 110 | "id": "stops_start_icon", 111 | "minzoom": 0, 112 | "layout": { 113 | "visibility": "visible" 114 | } 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /cli/static/near-bus-routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "routes": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/near-bus-routes/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /cli/static/near-bus-stops.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "stops": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/near-bus-stops/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cli/static/print.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "landuse_park", 5 | "paint": { 6 | "fill-color": "#eaf2e0" 7 | } 8 | }, 9 | { 10 | "id": "landuse_wood", 11 | "paint": { 12 | "fill-color": "#e3eed4" 13 | } 14 | }, 15 | { 16 | "id": "landuse_grass", 17 | "paint": { 18 | "fill-color": "#dfebd0" 19 | } 20 | }, 21 | { 22 | "id": "landuse_scrub", 23 | "paint": { 24 | "fill-color": "#d6e5c3" 25 | } 26 | }, 27 | { 28 | "id": "landuse_agriculture", 29 | "paint": { 30 | "fill-color": "#eef4dc" 31 | } 32 | }, 33 | { 34 | "id": "landuse_cemetery", 35 | "paint": { 36 | "fill-color": "#e0ebd2", 37 | "fill-outline-color": "#d4e3c3" 38 | } 39 | }, 40 | { 41 | "id": "landuse_athletics", 42 | "paint": { 43 | "fill-color": "#e1ecd3", 44 | "fill-outline-color": "#cdddb9" 45 | } 46 | }, 47 | { 48 | "id": "label_poi_general", 49 | "paint": { 50 | "text-color": "#000" 51 | } 52 | }, 53 | { 54 | "id": "label_poi_harbour", 55 | "paint": { 56 | "text-color": "#000" 57 | } 58 | }, 59 | { 60 | "id": "label_place_island", 61 | "paint": { 62 | "text-color": "#000" 63 | } 64 | }, 65 | { 66 | "id": "label_road_path_cycleway_track_service", 67 | "paint": { 68 | "text-color": "#000" 69 | } 70 | }, 71 | { 72 | "id": "label_road_street", 73 | "paint": { 74 | "text-color": "#000" 75 | } 76 | }, 77 | { 78 | "id": "label_road_primary", 79 | "paint": { 80 | "text-color": "#000" 81 | } 82 | }, 83 | { 84 | "id": "label_place_other", 85 | "paint": { 86 | "text-color": "#000" 87 | } 88 | }, 89 | { 90 | "id": "label_place_town", 91 | "paint": { 92 | "text-color": "#000" 93 | } 94 | }, 95 | { 96 | "id": "label_place_city", 97 | "paint": { 98 | "text-color": "#000" 99 | } 100 | }, 101 | { 102 | "id": "label_country", 103 | "paint": { 104 | "text-color": "#000" 105 | } 106 | } 107 | ] 108 | } 109 | -------------------------------------------------------------------------------- /cli/static/regular-routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "routes": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/regular-routes/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cli/static/regular-stops.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "stops": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/regular-stops/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cli/static/routes-with-departures-only.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "route_bus_case", 5 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 6 | }, 7 | { 8 | "id": "route_bus", 9 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 10 | }, 11 | { 12 | "id": "route_bus_inner", 13 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 14 | }, 15 | { 16 | "id": "route_tram_case", 17 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 18 | }, 19 | { 20 | "id": "route_tram", 21 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 22 | }, 23 | { 24 | "id": "route_tram_inner", 25 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 26 | }, 27 | { 28 | "id": "route_lrail_case", 29 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 30 | }, 31 | { 32 | "id": "route_lrail", 33 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 34 | }, 35 | { 36 | "id": "route_lrail_inner", 37 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 38 | }, 39 | { 40 | "id": "route_trunk_case", 41 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 42 | }, 43 | { 44 | "id": "route_trunk", 45 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 46 | }, 47 | { 48 | "id": "route_trunk_inner", 49 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 50 | }, 51 | { 52 | "id": "route_ferry", 53 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /cli/static/simplified.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "road_service_area", 5 | "minzoom": 14 6 | }, 7 | { 8 | "id": "building_shadow", 9 | "minzoom": 17 10 | }, 11 | { 12 | "id": "building", 13 | "minzoom": 16 14 | }, 15 | { 16 | "id": "tunnel_walk", 17 | "minzoom": 17 18 | }, 19 | { 20 | "id": "tunnel_cycleway", 21 | "minzoom": 16 22 | }, 23 | { 24 | "id": "tunnel_street", 25 | "minzoom": 13 26 | }, 27 | { 28 | "id": "road_path", 29 | "minzoom": 16 30 | }, 31 | { 32 | "id": "road_path_steps_case", 33 | "minzoom": 16 34 | }, 35 | { 36 | "id": "road_path_steps", 37 | "minzoom": 16 38 | }, 39 | { 40 | "id": "road_cycleway_track", 41 | "minzoom": 15 42 | }, 43 | { 44 | "id": "road_service", 45 | "minzoom": 14 46 | }, 47 | { 48 | "id": "road_street_case", 49 | "minzoom": 13 50 | }, 51 | { 52 | "id": "road_street", 53 | "minzoom": 13 54 | }, 55 | { 56 | "id": "bridge_path_case", 57 | "minzoom": 16 58 | }, 59 | { 60 | "id": "bridge_path_bg", 61 | "minzoom": 16 62 | }, 63 | { 64 | "id": "bridge_path", 65 | "minzoom": 16 66 | }, 67 | { 68 | "id": "bridge_cycleway_track_case", 69 | "minzoom": 15 70 | }, 71 | { 72 | "id": "bridge_cycleway_track_bg", 73 | "minzoom": 15 74 | }, 75 | { 76 | "id": "bridge_cycleway_track", 77 | "minzoom": 15 78 | }, 79 | { 80 | "id": "bridge_service_case", 81 | "minzoom": 14 82 | }, 83 | { 84 | "id": "bridge_service_bg", 85 | "minzoom": 14 86 | }, 87 | { 88 | "id": "bridge_service", 89 | "minzoom": 14 90 | }, 91 | { 92 | "id": "bridge_street", 93 | "minzoom": 13 94 | }, 95 | { 96 | "id": "label_housenum", 97 | "minzoom": 17 98 | }, 99 | { 100 | "id": "label_poi_general", 101 | "minzoom": 15 102 | }, 103 | { 104 | "id": "label_poi_park", 105 | "minzoom": 14 106 | }, 107 | { 108 | "id": "label_road_path_cycleway_track_service", 109 | "minzoom": 16 110 | }, 111 | { 112 | "id": "label_road_street", 113 | "minzoom": 13 114 | }, 115 | { 116 | "id": "label_place_other", 117 | "layout": { 118 | "text-font": ["Gotham Rounded Medium"] 119 | } 120 | }, 121 | { 122 | "id": "label_place_town", 123 | "layout": { 124 | "text-font": ["Gotham Rounded Medium"] 125 | } 126 | }, 127 | { 128 | "id": "label_place_city", 129 | "paint": { 130 | "text-color": "#333", 131 | "text-halo-width": 0.5 132 | } 133 | } 134 | ] 135 | } -------------------------------------------------------------------------------- /cli/static/stops-with-route-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "stops_case", 5 | "source": "stops-by-routes" 6 | }, 7 | { 8 | "id": "stops_rail_case", 9 | "source": "stops-by-routes" 10 | }, 11 | { 12 | "id": "stops_rail", 13 | "source": "stops-by-routes" 14 | }, 15 | { 16 | "id": "stops_bus", 17 | "source": "stops-by-routes" 18 | }, 19 | { 20 | "id": "stops_trunk", 21 | "source": "stops-by-routes" 22 | }, 23 | { 24 | "id": "stops_ferry", 25 | "source": "stops-by-routes" 26 | }, 27 | { 28 | "id": "stops_tram", 29 | "source": "stops-by-routes" 30 | }, 31 | { 32 | "id": "stops_lrail", 33 | "source": "stops-by-routes" 34 | }, 35 | { 36 | "id": "stops_subway", 37 | "source": "stops-by-routes" 38 | }, 39 | { 40 | "id": "stops_hub", 41 | "source": "stops-by-routes" 42 | }, 43 | { 44 | "id": "stops_rail_hub", 45 | "source": "stops-by-routes" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /cli/static/text-en.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name_en}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name_en}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name_en}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name_en}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name_en}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name_en}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name_en}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name_en}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name_en}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name_en}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_town", 65 | "layout": { 66 | "text-field": "{name_en}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_city", 71 | "layout": { 72 | "text-field": "{name_en}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name_en}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameFi}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameFi}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameFi}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name_en}" 103 | } 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /cli/static/text-fisv.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name}\n{name_sv_nodefault}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name}\n{name_sv_nodefault}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name}\n{name_sv_nodefault}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name}\n{name_sv_nodefault}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name}\n{name_sv_nodefault}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name}\n{name_sv_nodefault}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name} {name_sv_nodefault}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name} {name_sv_nodefault}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name} {name_sv_nodefault}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name}\n{name_sv_nodefault}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_city", 65 | "layout": { 66 | "text-field": "{name}\n{name_sv_nodefault}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_town", 71 | "layout": { 72 | "text-field": "{name}\n{name_sv_nodefault}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name}\n{name_sv_nodefault}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameFi}\n{nameSe}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameFi}\n{nameSe}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameFi}\n{nameSe}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name}\n{name_sv_nodefault}" 103 | } 104 | } 105 | ] 106 | } -------------------------------------------------------------------------------- /cli/static/text-sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name_sv}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name_sv}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name_sv}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name_sv}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name_sv}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name_sv}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name_sv}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name_sv}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name_sv}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name_sv}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_town", 65 | "layout": { 66 | "text-field": "{name_sv}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_city", 71 | "layout": { 72 | "text-field": "{name_sv}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name_sv}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameSe}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameSe}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameSe}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name_sv}" 103 | } 104 | } 105 | ] 106 | } -------------------------------------------------------------------------------- /data/ticket-zone-labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "name": "Ticket zone labels", 4 | "description": "This file contains a set of predefined points to render ticket labels.", 5 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, 6 | "features": [ 7 | { 8 | "type": "Feature", 9 | "properties": { 10 | "Zone": "A" 11 | }, 12 | "geometry": { 13 | "type": "Point", 14 | "coordinates": [24.927, 60.19] 15 | } 16 | }, 17 | { 18 | "type": "Feature", 19 | "properties": { 20 | "Zone": "B" 21 | }, 22 | "geometry": { 23 | "type": "Point", 24 | "coordinates": [24.925, 60.258] 25 | } 26 | }, 27 | { 28 | "type": "Feature", 29 | "properties": { 30 | "Zone": "B" 31 | }, 32 | "geometry": { 33 | "type": "Point", 34 | "coordinates": [24.78, 60.202] 35 | } 36 | }, 37 | { 38 | "type": "Feature", 39 | "properties": { 40 | "Zone": "B" 41 | }, 42 | "geometry": { 43 | "type": "Point", 44 | "coordinates": [25.09, 60.213] 45 | } 46 | }, 47 | { 48 | "type": "Feature", 49 | "properties": { 50 | "Zone": "C" 51 | }, 52 | "geometry": { 53 | "type": "Point", 54 | "coordinates": [25.1794, 60.264] 55 | } 56 | }, 57 | { 58 | "type": "Feature", 59 | "properties": { 60 | "Zone": "C" 61 | }, 62 | "geometry": { 63 | "type": "Point", 64 | "coordinates": [24.791, 60.323] 65 | } 66 | }, 67 | { 68 | "type": "Feature", 69 | "properties": { 70 | "Zone": "C" 71 | }, 72 | "geometry": { 73 | "type": "Point", 74 | "coordinates": [25.038, 60.33] 75 | } 76 | }, 77 | { 78 | "type": "Feature", 79 | "properties": { 80 | "Zone": "C" 81 | }, 82 | "geometry": { 83 | "type": "Point", 84 | "coordinates": [24.63, 60.25] 85 | } 86 | }, 87 | { 88 | "type": "Feature", 89 | "properties": { 90 | "Zone": "D" 91 | }, 92 | "geometry": { 93 | "type": "Point", 94 | "coordinates": [24.98, 60.415] 95 | } 96 | }, 97 | { 98 | "type": "Feature", 99 | "properties": { 100 | "Zone": "D" 101 | }, 102 | "geometry": { 103 | "type": "Point", 104 | "coordinates": [25.228, 60.401] 105 | } 106 | }, 107 | { 108 | "type": "Feature", 109 | "properties": { 110 | "Zone": "D" 111 | }, 112 | "geometry": { 113 | "type": "Point", 114 | "coordinates": [25.331, 60.31] 115 | } 116 | }, 117 | { 118 | "type": "Feature", 119 | "properties": { 120 | "Zone": "D" 121 | }, 122 | "geometry": { 123 | "type": "Point", 124 | "coordinates": [24.371, 60.18] 125 | } 126 | }, 127 | { 128 | "type": "Feature", 129 | "properties": { 130 | "Zone": "D" 131 | }, 132 | "geometry": { 133 | "type": "Point", 134 | "coordinates": [24.5, 60.091] 135 | } 136 | } 137 | ] 138 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HSL Map Style 5 | 6 | 7 | 8 | 29 | 30 | 31 |
32 |
33 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /map-icons/icon-citybike-station.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 24 | 27 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /map-icons/icon-citybike-station2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-citybike_station-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /map-icons/icon-direction1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-direction2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-entrance-lift.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 16 | 23 | 25 | 29 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /map-icons/icon-entrance-stairs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 13 | 15 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /map-icons/icon-entrance-subway.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /map-icons/icon-entrance-wheelchair.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-00.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-A.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-B.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-C.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-D.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-E.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-F.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-G.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-H.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-I.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-J.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-K.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-L.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-M.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-N.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-O.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-P.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Q.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-R.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-S.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-T.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-U.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-V.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-W.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-X.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Ä.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Å.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-letter-Ö.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-one-way.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /map-icons/icon-park-and-ride.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /map-icons/icon-platform-bus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-platform-bus-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-platform-train.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-platform-train-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-platform-tram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-platform-tram-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-stop-bus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-stop-bus-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /map-icons/icon-stop-ferry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-stop-hsl_ferry-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /map-icons/icon-stop-hybrid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-stop-hybrid-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /map-icons/icon-stop-train.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-stop-train-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /map-icons/icon-stop-tram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-stop-tram-small 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-aerodrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-bus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-ferry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-hsl_ferry-16 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-ship.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-ship_terminal-16 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-subway.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /map-icons/icon-terminal-train.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon-train-16 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /map-icons/icon-tickets-machine-parking.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /map-icons/icon-tickets-sales-point.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-tickets-service-point.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /map-icons/icon-time1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-time2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /map-icons/icon-wetland.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /map-icons/icon-zone-A.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Zone-A-v2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /map-icons/icon-zone-B.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Zone-B-v2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /map-icons/icon-zone-C.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Zone-C-v2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /map-icons/icon-zone-D.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-Zone-D-v2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hsl-map-style", 3 | "version": "1.2.2", 4 | "description": "", 5 | "main": "index.js", 6 | "bin": { 7 | "styletool": "./bin/styletool-cli" 8 | }, 9 | "scripts": { 10 | "start": "node server", 11 | "watch": "nodemon --watch . -e js,json,html server.js", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "", 15 | "devDependencies": { 16 | "commander": "^11.0.0", 17 | "eslint": "^8.30.0", 18 | "eslint-config-airbnb-base": "^15.0.0", 19 | "eslint-config-prettier": "^8.5.0", 20 | "eslint-plugin-import": "^2.26.0", 21 | "eslint-plugin-prettier": "^4.2.1", 22 | "express": "^4.18.2", 23 | "fs-extra": "^11.1.0", 24 | "nodemon": "^2.0.20", 25 | "prettier": "^2.8.1" 26 | }, 27 | "dependencies": { 28 | "lodash": "^4.17.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const express = require("express"); 3 | 4 | const index = fs.readFileSync("index.html", "utf8"); 5 | 6 | const style = require("./index").generateStyle({ 7 | // Urls to replace 8 | sourcesUrl: "http://localhost:8080/", 9 | glyphsUrl: "", 10 | spriteUrl: "", 11 | 12 | queryParams: [ 13 | { 14 | url: "https://dev-api.digitransit.fi/", 15 | name: "digitransit-subscription-key", 16 | value: "my-secret-key", 17 | }, 18 | ], 19 | components: { 20 | // Set each layer you want to include to true 21 | // Styles 22 | base: { enabled: true }, // Enabled by default 23 | municipal_borders: { enabled: false }, 24 | routes: { enabled: false }, 25 | text: { enabled: true }, // Enabled by default 26 | subway_entrance: { enabled: false }, 27 | poi: { enabled: false }, 28 | park_and_ride: { enabled: false }, 29 | ticket_sales: { enabled: false }, 30 | stops: { enabled: false }, 31 | citybikes: { enabled: false }, 32 | ticket_zones: { enabled: false }, 33 | ticket_zone_labels: { enabled: false }, 34 | // Themes 35 | text_sv: { enabled: false }, 36 | text_fisv: { enabled: false }, 37 | text_en: { enabled: false }, 38 | regular_routes: { enabled: false }, 39 | near_bus_routes: { enabled: false }, 40 | routes_with_departures_only: { enabled: true }, // Enabled by default. Doesn't do anything until routes is enabled. 41 | regular_stops: { enabled: false }, 42 | near_bus_stops: { enabled: false }, 43 | print: { enabled: false }, 44 | greyscale: { enabled: false }, 45 | simplified: { enabled: false }, 46 | "3d": { enabled: false }, 47 | }, 48 | // optional property to show only listed routes by jore id 49 | routeFilter: [], 50 | }); 51 | 52 | const app = express(); 53 | 54 | app.get("/", (req, res) => { 55 | res.redirect("/index.html"); 56 | }); 57 | 58 | app.get("/index.html", (req, res) => { 59 | res.set("Content-Type", "text/html"); 60 | res.send(index); 61 | }); 62 | 63 | app.get("/style.json", (req, res) => { 64 | res.set("Content-Type", "application/json"); 65 | res.send(style); 66 | }); 67 | 68 | app.listen(3000, () => { 69 | console.log("Listening at localhost:3000"); 70 | }); 71 | -------------------------------------------------------------------------------- /sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HSLdevcom/hsl-map-style/305b1123504d54d28e12298aeb21442f06758309/sprite.png -------------------------------------------------------------------------------- /sprite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HSLdevcom/hsl-map-style/305b1123504d54d28e12298aeb21442f06758309/sprite@2x.png -------------------------------------------------------------------------------- /sprite@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HSLdevcom/hsl-map-style/305b1123504d54d28e12298aeb21442f06758309/sprite@3x.png -------------------------------------------------------------------------------- /spritezero/.nvmrc: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /spritezero/README.md: -------------------------------------------------------------------------------- 1 | # Spritezero instructions 2 | 3 | ## Installation 4 | 5 | Requirements: 6 | - node v16 7 | - yarn package manager 8 | 9 | ``` 10 | yarn install 11 | ``` 12 | 13 | ## How to add new icons 14 | 15 | 1. Download new icons as svg to your machine. Rename them logically. 16 | 2. (Optional step) Resize the icons to match the current ones. You can use rsvg-convert to do it. 17 | ``` 18 | # Installation 19 | sudo apt install librsvg2-bin 20 | 21 | # Resize to the size 16x16 (or somewhat similar, depending of the aspect ratio of the icon) 22 | rsvg-convert -w 16 -h 16 -f svg icon.svg > resized-icon.svg 23 | 24 | # The batch process example 25 | for i in $(find new-icons/*.svg -printf "%f\n"); do rsvg-convert -w 16 -h 16 -f svg new-icons/$i > test-icons/$i; done; 26 | ``` 27 | 3. Place the icons in the root of `map-icons` directory 28 | 4. Run the script: 29 | ``` 30 | yarn run icons 31 | ``` 32 | 5. Check that new icons are in `sprite.png` 33 | 34 | Now the icons should be available through the sprite. 35 | 36 | 6. Upload the newest sprite into Karttatuotanto Azure blob storage, overwriting the older sprite files. 37 | -------------------------------------------------------------------------------- /spritezero/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spritezero-run", 3 | "scripts": { 4 | "icons": "spritezero ../sprite ../map-icons && spritezero --ratio=2 ../sprite@2x ../map-icons && spritezero --ratio=3 ../sprite@3x ../map-icons" 5 | }, 6 | "devDependencies": { 7 | "@mapbox/spritezero-cli": "^2.1.0" 8 | }, 9 | "resolutions": { 10 | "@mapbox/spritezero-cli/@mapbox/spritezero": "^8.0.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /style/hsl-map-style-citybikes.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "citybike_stops_case", 5 | "type": "circle", 6 | "source": "citybike", 7 | "source-layer": "rentalStations", 8 | "minzoom": 13, 9 | "maxzoom": 14, 10 | "paint": { 11 | "circle-color": "#fff", 12 | "circle-radius": [ 13 | "interpolate", 14 | [ 15 | "exponential", 16 | 1.15 17 | ], 18 | [ 19 | "zoom" 20 | ], 21 | 12, 22 | 1.5, 23 | 22, 24 | 26 25 | ] 26 | } 27 | }, 28 | { 29 | "id": "citybike_stops", 30 | "type": "circle", 31 | "source": "citybike", 32 | "source-layer": "rentalStations", 33 | "minzoom": 13, 34 | "maxzoom": 14, 35 | "paint": { 36 | "circle-color": "#fcbc19", 37 | "circle-radius": [ 38 | "interpolate", 39 | [ 40 | "exponential", 41 | 1.15 42 | ], 43 | [ 44 | "zoom" 45 | ], 46 | 12, 47 | 1, 48 | 22, 49 | 24 50 | ] 51 | } 52 | }, 53 | { 54 | "id": "citybike_icon", 55 | "type": "symbol", 56 | "source": "citybike", 57 | "source-layer": "rentalStations", 58 | "minzoom": 14, 59 | "layout": { 60 | "icon-offset": [ 61 | 0, 62 | -6 63 | ], 64 | "icon-image": "icon-citybike-station", 65 | "icon-allow-overlap": false, 66 | "icon-size": { 67 | "stops": [ 68 | [ 69 | 13, 70 | 0.8 71 | ], 72 | [ 73 | 20, 74 | 1.2 75 | ] 76 | ] 77 | } 78 | } 79 | } 80 | ], 81 | "sources": { 82 | "citybike": { 83 | "url": "https://api.digitransit.fi/map/v3/hsl/fi/rentalStations/tilejson.json", 84 | "type": "vector" 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /style/hsl-map-style-icon.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "icon_bus-station", 5 | "type": "symbol", 6 | "source": "terminals", 7 | "source-layer": "terminals", 8 | "minzoom": 11, 9 | "filter": [ 10 | "all", 11 | [ 12 | "==", 13 | "$type", 14 | "Point" 15 | ], 16 | [ 17 | "==", 18 | "mode", 19 | "BUS" 20 | ] 21 | ], 22 | "layout": { 23 | "text-optional": true, 24 | "text-size": 10, 25 | "text-field": "{nameFi}", 26 | "text-font": [ 27 | "Gotham Rounded Medium" 28 | ], 29 | "text-anchor": "top", 30 | "text-max-width": 8, 31 | "text-offset": [ 32 | 0, 33 | 0.5 34 | ], 35 | "icon-image": "icon-terminal-bus", 36 | "icon-size": 0.9 37 | }, 38 | "paint": { 39 | "text-color": "#666", 40 | "text-halo-color": "#fff", 41 | "text-halo-width": 1, 42 | "icon-translate": [ 43 | 0, 44 | -5.25 45 | ] 46 | } 47 | }, 48 | { 49 | "id": "icon_subway-station", 50 | "type": "symbol", 51 | "source": "terminals", 52 | "source-layer": "terminals", 53 | "minzoom": 11, 54 | "filter": [ 55 | "all", 56 | [ 57 | "==", 58 | "$type", 59 | "Point" 60 | ], 61 | [ 62 | "==", 63 | "mode", 64 | "SUBWAY" 65 | ] 66 | ], 67 | "layout": { 68 | "text-optional": true, 69 | "text-size": 10, 70 | "text-field": "{nameFi}", 71 | "text-font": [ 72 | "Gotham Rounded Medium" 73 | ], 74 | "text-anchor": "top", 75 | "text-max-width": 8, 76 | "text-offset": [ 77 | 0, 78 | 0.5 79 | ], 80 | "icon-image": "icon-terminal-subway", 81 | "icon-size": 0.9 82 | }, 83 | "paint": { 84 | "text-color": "#666", 85 | "text-halo-color": "#fff", 86 | "text-halo-width": 1, 87 | "icon-translate": [ 88 | 0, 89 | -5.25 90 | ] 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "type": "symbol", 96 | "source": "terminals", 97 | "source-layer": "terminals", 98 | "minzoom": 11, 99 | "filter": [ 100 | "all", 101 | [ 102 | "==", 103 | "$type", 104 | "Point" 105 | ], 106 | [ 107 | "==", 108 | "mode", 109 | "RAIL" 110 | ] 111 | ], 112 | "layout": { 113 | "text-optional": true, 114 | "text-size": 10, 115 | "text-field": "{nameFi}", 116 | "text-font": [ 117 | "Gotham Rounded Medium" 118 | ], 119 | "text-anchor": "top", 120 | "text-max-width": 8, 121 | "text-offset": [ 122 | 0, 123 | 0.75 124 | ], 125 | "icon-image": "icon-terminal-train", 126 | "icon-size": 0.9 127 | }, 128 | "paint": { 129 | "text-color": "#666", 130 | "text-halo-color": "#fff", 131 | "text-halo-width": 1, 132 | "icon-translate": [ 133 | 0, 134 | -5.25 135 | ] 136 | } 137 | }, 138 | { 139 | "id": "icon_aerodrome", 140 | "type": "symbol", 141 | "source": "vector", 142 | "source-layer": "aerodrome_label", 143 | "minzoom": 5, 144 | "filter": [ 145 | "all", 146 | [ 147 | "==", 148 | "$type", 149 | "Point" 150 | ], 151 | [ 152 | "in", 153 | "class", 154 | "international", 155 | "public", 156 | "regional" 157 | ] 158 | ], 159 | "layout": { 160 | "text-optional": true, 161 | "text-size": 10, 162 | "text-field": "{name}", 163 | "text-font": [ 164 | "Gotham Rounded Medium" 165 | ], 166 | "text-anchor": "top", 167 | "text-max-width": 8, 168 | "text-offset": [ 169 | 0, 170 | 0.5 171 | ], 172 | "icon-image": "icon-terminal-aerodrome", 173 | "icon-size": 0.9 174 | }, 175 | "paint": { 176 | "text-color": "#666", 177 | "text-halo-color": "#fff", 178 | "text-halo-width": 1, 179 | "icon-translate": [ 180 | 0, 181 | -5.25 182 | ] 183 | } 184 | } 185 | ], 186 | "sources": { 187 | "terminals": { 188 | "url": "https://kartat.hsl.fi/jore/tiles/terminals/index.json", 189 | "type": "vector" 190 | }, 191 | "vector": { 192 | "type": "vector", 193 | "url": "https://api.digitransit.fi/map/v3/hsl-vector-map/index.json" 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /style/hsl-map-style-municipal-borders.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "municipal_border", 5 | "type": "line", 6 | "source": "borders", 7 | "minzoom": 7, 8 | "layout": { 9 | "line-cap": "round", 10 | "line-join": "round" 11 | }, 12 | "paint": { 13 | "line-color": "#ccc", 14 | "line-width": { 15 | "stops": [ 16 | [ 17 | 10, 18 | 3 19 | ], 20 | [ 21 | 18, 22 | 6 23 | ] 24 | ] 25 | }, 26 | "line-dasharray": [ 27 | 2, 28 | 2 29 | ] 30 | } 31 | } 32 | ], 33 | "sources": { 34 | "borders": { 35 | "data": "https://hslstoragekarttatuotanto.z6.web.core.windows.net/kuntarajat.json", 36 | "type": "geojson" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /style/hsl-map-style-park-and-ride.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "park-and-ride_icon_hub", 5 | "type": "symbol", 6 | "source": "parkandride", 7 | "source-layer": "vehicleParking", 8 | "minzoom": 14, 9 | "filter": [ 10 | "==", 11 | [ 12 | "get", 13 | "carPlaces" 14 | ], 15 | true 16 | ], 17 | "layout": { 18 | "icon-image": "icon-park-and-ride", 19 | "icon-allow-overlap": false, 20 | "icon-size": 1 21 | }, 22 | "paint": { 23 | "icon-translate": [ 24 | 0, 25 | -5.25 26 | ] 27 | } 28 | } 29 | ], 30 | "sources": { 31 | "parkandride": { 32 | "url": "https://api.digitransit.fi/map/v3/hsl/fi/vehicleParking/tilejson.json", 33 | "type": "vector" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /style/hsl-map-style-subway-entrance.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "subway-entrance_icon", 5 | "type": "symbol", 6 | "source": "vector", 7 | "source-layer": "poi", 8 | "minzoom": 16, 9 | "filter": [ 10 | "all", 11 | [ 12 | "==", 13 | "$type", 14 | "Point" 15 | ], 16 | [ 17 | "in", 18 | "class", 19 | "entrance" 20 | ], 21 | [ 22 | "in", 23 | "subclass", 24 | "subway_entrance" 25 | ] 26 | ], 27 | "layout": { 28 | "icon-image": "icon-entrance-subway", 29 | "icon-allow-overlap": true, 30 | "icon-anchor": "bottom", 31 | "icon-size": [ 32 | "interpolate", 33 | [ 34 | "exponential", 35 | 1.15 36 | ], 37 | [ 38 | "zoom" 39 | ], 40 | 15, 41 | 0.533, 42 | 20, 43 | 0.8 44 | ] 45 | }, 46 | "paint": { 47 | "icon-translate": [ 48 | 0, 49 | -5.25 50 | ] 51 | } 52 | }, 53 | { 54 | "id": "subway-entrance_letter", 55 | "type": "symbol", 56 | "source": "vector", 57 | "source-layer": "poi", 58 | "minzoom": 17, 59 | "filter": [ 60 | "all", 61 | [ 62 | "==", 63 | "$type", 64 | "Point" 65 | ], 66 | [ 67 | "in", 68 | "class", 69 | "entrance" 70 | ], 71 | [ 72 | "in", 73 | "subclass", 74 | "subway_entrance" 75 | ], 76 | [ 77 | "has", 78 | "ref" 79 | ] 80 | ], 81 | "layout": { 82 | "icon-image": [ 83 | "concat", 84 | "icon-letter-", 85 | [ 86 | "get", 87 | "ref" 88 | ] 89 | ], 90 | "icon-allow-overlap": true, 91 | "icon-anchor": "bottom", 92 | "icon-size": [ 93 | "interpolate", 94 | [ 95 | "exponential", 96 | 1.15 97 | ], 98 | [ 99 | "zoom" 100 | ], 101 | 13, 102 | 0.8, 103 | 20, 104 | 1.2 105 | ] 106 | }, 107 | "paint": { 108 | "icon-translate": [ 109 | 0, 110 | -5.25 111 | ] 112 | } 113 | }, 114 | { 115 | "id": "subway-entrance_accessibility", 116 | "type": "symbol", 117 | "source": "vector", 118 | "source-layer": "poi", 119 | "minzoom": 17, 120 | "filter": [ 121 | "all", 122 | [ 123 | "==", 124 | "$type", 125 | "Point" 126 | ], 127 | [ 128 | "in", 129 | "class", 130 | "entrance" 131 | ], 132 | [ 133 | "in", 134 | "subclass", 135 | "subway_entrance" 136 | ], 137 | [ 138 | "==", 139 | "wheelchair", 140 | 1 141 | ] 142 | ], 143 | "layout": { 144 | "icon-image": "icon-entrance-wheelchair", 145 | "icon-allow-overlap": true, 146 | "icon-anchor": "top", 147 | "icon-size": [ 148 | "interpolate", 149 | [ 150 | "exponential", 151 | 1.15 152 | ], 153 | [ 154 | "zoom" 155 | ], 156 | 13, 157 | 0.8, 158 | 20, 159 | 1.2 160 | ] 161 | }, 162 | "paint": { 163 | "icon-translate": [ 164 | 0, 165 | -5.25 166 | ] 167 | } 168 | } 169 | ], 170 | "sources": { 171 | "vector": { 172 | "type": "vector", 173 | "url": "https://api.digitransit.fi/map/v3/hsl-vector-map/index.json" 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /style/hsl-map-style-ticket-sales.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "ticket-sales_icon_sales-point", 5 | "type": "symbol", 6 | "source": "ticket-sales", 7 | "minzoom": 15, 8 | "filter": [ 9 | "all", 10 | [ 11 | "==", 12 | "$type", 13 | "Point" 14 | ], 15 | [ 16 | "in", 17 | "Tyyppi", 18 | "Myyntipiste", 19 | "myyntipiste" 20 | ] 21 | ], 22 | "layout": { 23 | "icon-image": "icon-tickets-sales-point" 24 | } 25 | }, 26 | { 27 | "id": "ticket-sales_icon_ticket-machine", 28 | "type": "symbol", 29 | "source": "ticket-sales", 30 | "minzoom": 15, 31 | "filter": [ 32 | "all", 33 | [ 34 | "==", 35 | "$type", 36 | "Point" 37 | ], 38 | [ 39 | "in", 40 | "Tyyppi", 41 | "Kertalippuautomaatti", 42 | "Monilippuautomaatti" 43 | ] 44 | ], 45 | "layout": { 46 | "icon-image": "icon-tickets-machine" 47 | } 48 | }, 49 | { 50 | "id": "ticket-sales_icon_ticket-machine-parking", 51 | "type": "symbol", 52 | "source": "ticket-sales", 53 | "minzoom": 15, 54 | "filter": [ 55 | "all", 56 | [ 57 | "==", 58 | "$type", 59 | "Point" 60 | ], 61 | [ 62 | "==", 63 | "Tyyppi", 64 | "Pysäköintiautomaatti" 65 | ] 66 | ], 67 | "layout": { 68 | "icon-image": "icon-tickets-machine-parking", 69 | "visibility": "none" 70 | } 71 | }, 72 | { 73 | "id": "ticket-sales_icon_service-point", 74 | "type": "symbol", 75 | "source": "ticket-sales", 76 | "minzoom": 15, 77 | "filter": [ 78 | "all", 79 | [ 80 | "==", 81 | "$type", 82 | "Point" 83 | ], 84 | [ 85 | "==", 86 | "Tyyppi", 87 | "Palvelupiste" 88 | ] 89 | ], 90 | "layout": { 91 | "icon-image": "icon-tickets-service-point" 92 | } 93 | } 94 | ], 95 | "sources": { 96 | "ticket-sales": { 97 | "data": "https://data-hslhrt.opendata.arcgis.com/datasets/f9388fc8a8f848fda3bc584b607afe97_0.geojson", 98 | "type": "geojson" 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /style/hsl-map-style-ticket-zone-labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "ticket-zone-labels", 5 | "type": "symbol", 6 | "source": "ticketzone-labels", 7 | "minzoom": 8, 8 | "maxzoom": 13, 9 | "layout": { 10 | "icon-image": [ 11 | "concat", 12 | "icon-zone-", 13 | [ 14 | "get", 15 | "Zone" 16 | ] 17 | ], 18 | "icon-rotation-alignment": "map", 19 | "icon-size": 0.7, 20 | "icon-padding": 1, 21 | "symbol-avoid-edges": false, 22 | "icon-allow-overlap": true 23 | }, 24 | "paint": { 25 | "icon-translate-anchor": "viewport" 26 | } 27 | } 28 | ], 29 | "sources": { 30 | "ticketzone-labels": { 31 | "data": "https://hslstoragekarttatuotanto.z6.web.core.windows.net/ticket-zone-labels.json", 32 | "type": "geojson" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /style/hsl-map-style-ticket-zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "ticket-zones_case", 5 | "type": "line", 6 | "source": "ticketzones", 7 | "layout": { 8 | "line-join": "round", 9 | "line-cap": "round" 10 | }, 11 | "paint": { 12 | "line-color": "#333333", 13 | "line-width": [ 14 | "interpolate", 15 | [ 16 | "exponential", 17 | 1.2 18 | ], 19 | [ 20 | "zoom" 21 | ], 22 | 10, 23 | 4, 24 | 22, 25 | 80 26 | ], 27 | "line-opacity": 0.2 28 | } 29 | }, 30 | { 31 | "id": "ticket-zones", 32 | "type": "line", 33 | "source": "ticketzones", 34 | "layout": { 35 | "line-join": "round", 36 | "line-cap": "round" 37 | }, 38 | "paint": { 39 | "line-color": "#333333", 40 | "line-width": [ 41 | "interpolate", 42 | [ 43 | "exponential", 44 | 1.2 45 | ], 46 | [ 47 | "zoom" 48 | ], 49 | 10, 50 | 1, 51 | 22, 52 | 6 53 | ] 54 | } 55 | } 56 | ], 57 | "sources": { 58 | "ticketzones": { 59 | "data": "https://hslstoragekarttatuotanto.z6.web.core.windows.net/ticket-zones.json", 60 | "type": "geojson" 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /style/hsl-map-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 8, 3 | "name": "HSL v2.0", 4 | "metadata": { 5 | "maputnik:renderer": "mbgljs", 6 | "mapbox-groups": {} 7 | }, 8 | "sources": {}, 9 | "sprite": "https://hslstoragekarttatuotanto.z6.web.core.windows.net/sprite", 10 | "glyphs": "https://hslstoragestatic.azureedge.net/mapfonts/{fontstack}/{range}.pbf", 11 | "layers": [] 12 | } 13 | -------------------------------------------------------------------------------- /style/hsl-map-theme-3d.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "building_shadow", 5 | "layout": { 6 | "visibility": "none" 7 | } 8 | }, 9 | { 10 | "id": "building", 11 | "layout": { 12 | "visibility": "none" 13 | } 14 | }, 15 | { 16 | "id": "building_3d", 17 | "layout": { 18 | "visibility": "visible" 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /style/hsl-map-theme-driver-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "stops_case", 5 | "source": "stops-by-routes", 6 | "minzoom": 0, 7 | "filter": ["==", ["get", "timingStopType"], 0], 8 | "paint": { 9 | "circle-radius": 9 10 | } 11 | }, 12 | { 13 | "id": "stops_rail_case", 14 | "source": "stops-by-routes", 15 | "minzoom": 0, 16 | "filter": ["==", ["get", "timingStopType"], 0], 17 | "paint": { 18 | "circle-radius": 9 19 | } 20 | }, 21 | { 22 | "id": "stops_rail", 23 | "source": "stops-by-routes", 24 | "minzoom": 0, 25 | "filter": ["==", ["get", "timingStopType"], 0], 26 | "paint": { 27 | "circle-radius": 8 28 | } 29 | }, 30 | { 31 | "id": "stops_bus", 32 | "source": "stops-by-routes", 33 | "minzoom": 0, 34 | "filter": ["==", ["get", "timingStopType"], 0], 35 | "paint": { 36 | "circle-radius": 8 37 | } 38 | }, 39 | { 40 | "id": "stops_trunk", 41 | "source": "stops-by-routes", 42 | "minzoom": 0, 43 | "filter": ["==", ["get", "timingStopType"], 0], 44 | "paint": { 45 | "circle-radius": 8 46 | } 47 | }, 48 | { 49 | "id": "stops_ferry", 50 | "source": "stops-by-routes", 51 | "minzoom": 0, 52 | "filter": ["==", ["get", "timingStopType"], 0], 53 | "paint": { 54 | "circle-radius": 8 55 | } 56 | }, 57 | { 58 | "id": "stops_tram", 59 | "source": "stops-by-routes", 60 | "minzoom": 0, 61 | "filter": ["==", ["get", "timingStopType"], 0], 62 | "paint": { 63 | "circle-radius": 8 64 | } 65 | }, 66 | { 67 | "id": "stops_lrail", 68 | "source": "stops-by-routes", 69 | "minzoom": 0, 70 | "filter": ["==", ["get", "timingStopType"], 0], 71 | "paint": { 72 | "circle-radius": 8 73 | } 74 | }, 75 | { 76 | "id": "stops_subway", 77 | "source": "stops-by-routes", 78 | "minzoom": 0, 79 | "filter": ["==", ["get", "timingStopType"], 0], 80 | "paint": { 81 | "circle-radius": 8 82 | } 83 | }, 84 | { 85 | "id": "stops_hub", 86 | "source": "stops-by-routes", 87 | "minzoom": 0, 88 | "filter": ["==", ["get", "timingStopType"], 0], 89 | "paint": { 90 | "circle-radius": 5.5 91 | } 92 | }, 93 | { 94 | "id": "stops_rail_hub", 95 | "source": "stops-by-routes", 96 | "minzoom": 0, 97 | "filter": ["==", ["get", "timingStopType"], 0], 98 | "paint": { 99 | "circle-radius": 5.5 100 | } 101 | }, 102 | { 103 | "id": "stops_timing_icon", 104 | "minzoom": 0, 105 | "layout": { 106 | "visibility": "visible" 107 | } 108 | }, 109 | { 110 | "id": "stops_start_icon", 111 | "minzoom": 0, 112 | "layout": { 113 | "visibility": "visible" 114 | } 115 | } 116 | ] 117 | } 118 | -------------------------------------------------------------------------------- /style/hsl-map-theme-near-bus-routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "routes": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/near-bus-routes/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /style/hsl-map-theme-near-bus-stops.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "stops": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/near-bus-stops/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /style/hsl-map-theme-print.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "landuse_park", 5 | "paint": { 6 | "fill-color": "#eaf2e0" 7 | } 8 | }, 9 | { 10 | "id": "landuse_wood", 11 | "paint": { 12 | "fill-color": "#e3eed4" 13 | } 14 | }, 15 | { 16 | "id": "landuse_grass", 17 | "paint": { 18 | "fill-color": "#dfebd0" 19 | } 20 | }, 21 | { 22 | "id": "landuse_scrub", 23 | "paint": { 24 | "fill-color": "#d6e5c3" 25 | } 26 | }, 27 | { 28 | "id": "landuse_agriculture", 29 | "paint": { 30 | "fill-color": "#eef4dc" 31 | } 32 | }, 33 | { 34 | "id": "landuse_cemetery", 35 | "paint": { 36 | "fill-color": "#e0ebd2", 37 | "fill-outline-color": "#d4e3c3" 38 | } 39 | }, 40 | { 41 | "id": "landuse_athletics", 42 | "paint": { 43 | "fill-color": "#e1ecd3", 44 | "fill-outline-color": "#cdddb9" 45 | } 46 | }, 47 | { 48 | "id": "label_poi_general", 49 | "paint": { 50 | "text-color": "#000" 51 | } 52 | }, 53 | { 54 | "id": "label_poi_harbour", 55 | "paint": { 56 | "text-color": "#000" 57 | } 58 | }, 59 | { 60 | "id": "label_place_island", 61 | "paint": { 62 | "text-color": "#000" 63 | } 64 | }, 65 | { 66 | "id": "label_road_path_cycleway_track_service", 67 | "paint": { 68 | "text-color": "#000" 69 | } 70 | }, 71 | { 72 | "id": "label_road_street", 73 | "paint": { 74 | "text-color": "#000" 75 | } 76 | }, 77 | { 78 | "id": "label_road_primary", 79 | "paint": { 80 | "text-color": "#000" 81 | } 82 | }, 83 | { 84 | "id": "label_place_other", 85 | "paint": { 86 | "text-color": "#000" 87 | } 88 | }, 89 | { 90 | "id": "label_place_town", 91 | "paint": { 92 | "text-color": "#000" 93 | } 94 | }, 95 | { 96 | "id": "label_place_city", 97 | "paint": { 98 | "text-color": "#000" 99 | } 100 | }, 101 | { 102 | "id": "label_country", 103 | "paint": { 104 | "text-color": "#000" 105 | } 106 | } 107 | ] 108 | } 109 | -------------------------------------------------------------------------------- /style/hsl-map-theme-regular-routes.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "routes": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/regular-routes/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /style/hsl-map-theme-regular-stops.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "stops": { 4 | "url": "https://kartat.hsl.fi/jore/tiles/regular-stops/index.json", 5 | "type": "vector" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /style/hsl-map-theme-routes-with-departures-only.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "route_bus_case", 5 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 6 | }, 7 | { 8 | "id": "route_bus", 9 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 10 | }, 11 | { 12 | "id": "route_bus_inner", 13 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 14 | }, 15 | { 16 | "id": "route_tram_case", 17 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 18 | }, 19 | { 20 | "id": "route_tram", 21 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 22 | }, 23 | { 24 | "id": "route_tram_inner", 25 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 26 | }, 27 | { 28 | "id": "route_lrail_case", 29 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 30 | }, 31 | { 32 | "id": "route_lrail", 33 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 34 | }, 35 | { 36 | "id": "route_lrail_inner", 37 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 38 | }, 39 | { 40 | "id": "route_trunk_case", 41 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 42 | }, 43 | { 44 | "id": "route_trunk", 45 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 46 | }, 47 | { 48 | "id": "route_trunk_inner", 49 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 50 | }, 51 | { 52 | "id": "route_ferry", 53 | "filter": ["!=", ["boolean", ["get", "hasRegularDayDepartures"]], false] 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /style/hsl-map-theme-simplified.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "road_service_area", 5 | "minzoom": 14 6 | }, 7 | { 8 | "id": "building_shadow", 9 | "minzoom": 17 10 | }, 11 | { 12 | "id": "building", 13 | "minzoom": 16 14 | }, 15 | { 16 | "id": "tunnel_walk", 17 | "minzoom": 17 18 | }, 19 | { 20 | "id": "tunnel_cycleway", 21 | "minzoom": 16 22 | }, 23 | { 24 | "id": "tunnel_street", 25 | "minzoom": 13 26 | }, 27 | { 28 | "id": "road_path", 29 | "minzoom": 16 30 | }, 31 | { 32 | "id": "road_path_steps_case", 33 | "minzoom": 16 34 | }, 35 | { 36 | "id": "road_path_steps", 37 | "minzoom": 16 38 | }, 39 | { 40 | "id": "road_cycleway_track", 41 | "minzoom": 15 42 | }, 43 | { 44 | "id": "road_service", 45 | "minzoom": 14 46 | }, 47 | { 48 | "id": "road_street_case", 49 | "minzoom": 13 50 | }, 51 | { 52 | "id": "road_street", 53 | "minzoom": 13 54 | }, 55 | { 56 | "id": "bridge_path_case", 57 | "minzoom": 16 58 | }, 59 | { 60 | "id": "bridge_path_bg", 61 | "minzoom": 16 62 | }, 63 | { 64 | "id": "bridge_path", 65 | "minzoom": 16 66 | }, 67 | { 68 | "id": "bridge_cycleway_track_case", 69 | "minzoom": 15 70 | }, 71 | { 72 | "id": "bridge_cycleway_track_bg", 73 | "minzoom": 15 74 | }, 75 | { 76 | "id": "bridge_cycleway_track", 77 | "minzoom": 15 78 | }, 79 | { 80 | "id": "bridge_service_case", 81 | "minzoom": 14 82 | }, 83 | { 84 | "id": "bridge_service_bg", 85 | "minzoom": 14 86 | }, 87 | { 88 | "id": "bridge_service", 89 | "minzoom": 14 90 | }, 91 | { 92 | "id": "bridge_street", 93 | "minzoom": 13 94 | }, 95 | { 96 | "id": "label_housenum", 97 | "minzoom": 17 98 | }, 99 | { 100 | "id": "label_poi_general", 101 | "minzoom": 15 102 | }, 103 | { 104 | "id": "label_poi_park", 105 | "minzoom": 14 106 | }, 107 | { 108 | "id": "label_road_path_cycleway_track_service", 109 | "minzoom": 16 110 | }, 111 | { 112 | "id": "label_road_street", 113 | "minzoom": 13 114 | }, 115 | { 116 | "id": "label_place_other", 117 | "layout": { 118 | "text-font": ["Gotham Rounded Medium"] 119 | } 120 | }, 121 | { 122 | "id": "label_place_town", 123 | "layout": { 124 | "text-font": ["Gotham Rounded Medium"] 125 | } 126 | }, 127 | { 128 | "id": "label_place_city", 129 | "paint": { 130 | "text-color": "#333", 131 | "text-halo-width": 0.5 132 | } 133 | } 134 | ] 135 | } -------------------------------------------------------------------------------- /style/hsl-map-theme-stops-with-route-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "stops_case", 5 | "source": "stops-by-routes" 6 | }, 7 | { 8 | "id": "stops_rail_case", 9 | "source": "stops-by-routes" 10 | }, 11 | { 12 | "id": "stops_rail", 13 | "source": "stops-by-routes" 14 | }, 15 | { 16 | "id": "stops_bus", 17 | "source": "stops-by-routes" 18 | }, 19 | { 20 | "id": "stops_trunk", 21 | "source": "stops-by-routes" 22 | }, 23 | { 24 | "id": "stops_ferry", 25 | "source": "stops-by-routes" 26 | }, 27 | { 28 | "id": "stops_tram", 29 | "source": "stops-by-routes" 30 | }, 31 | { 32 | "id": "stops_lrail", 33 | "source": "stops-by-routes" 34 | }, 35 | { 36 | "id": "stops_subway", 37 | "source": "stops-by-routes" 38 | }, 39 | { 40 | "id": "stops_hub", 41 | "source": "stops-by-routes" 42 | }, 43 | { 44 | "id": "stops_rail_hub", 45 | "source": "stops-by-routes" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /style/hsl-map-theme-text-en.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name_en}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name_en}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name_en}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name_en}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name_en}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name_en}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name_en}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name_en}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name_en}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name_en}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_town", 65 | "layout": { 66 | "text-field": "{name_en}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_city", 71 | "layout": { 72 | "text-field": "{name_en}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name_en}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameFi}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameFi}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameFi}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name_en}" 103 | } 104 | } 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /style/hsl-map-theme-text-fisv.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name}\n{name_sv_nodefault}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name}\n{name_sv_nodefault}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name}\n{name_sv_nodefault}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name}\n{name_sv_nodefault}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name}\n{name_sv_nodefault}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name}\n{name_sv_nodefault}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name} {name_sv_nodefault}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name} {name_sv_nodefault}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name} {name_sv_nodefault}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name}\n{name_sv_nodefault}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_city", 65 | "layout": { 66 | "text-field": "{name}\n{name_sv_nodefault}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_town", 71 | "layout": { 72 | "text-field": "{name}\n{name_sv_nodefault}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name}\n{name_sv_nodefault}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameFi}\n{nameSe}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameFi}\n{nameSe}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameFi}\n{nameSe}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name}\n{name_sv_nodefault}" 103 | } 104 | } 105 | ] 106 | } -------------------------------------------------------------------------------- /style/hsl-map-theme-text-sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers": [ 3 | { 4 | "id": "label_poi_general", 5 | "layout": { 6 | "text-field": "{name_sv}" 7 | } 8 | }, 9 | { 10 | "id": "label_poi_park", 11 | "layout": { 12 | "text-field": "{name_sv}" 13 | } 14 | }, 15 | { 16 | "id": "label_poi_harbour", 17 | "layout": { 18 | "text-field": "{name_sv}" 19 | } 20 | }, 21 | { 22 | "id": "label_water_point", 23 | "layout": { 24 | "text-field": "{name_sv}" 25 | } 26 | }, 27 | { 28 | "id": "label_water_line", 29 | "layout": { 30 | "text-field": "{name_sv}" 31 | } 32 | }, 33 | { 34 | "id": "label_place_island", 35 | "layout": { 36 | "text-field": "{name_sv}" 37 | } 38 | }, 39 | { 40 | "id": "label_road_path_cycleway_track_service", 41 | "layout": { 42 | "text-field": "{name_sv}" 43 | } 44 | }, 45 | { 46 | "id": "label_road_street", 47 | "layout": { 48 | "text-field": "{name_sv}" 49 | } 50 | }, 51 | { 52 | "id": "label_road_primary", 53 | "layout": { 54 | "text-field": "{name_sv}" 55 | } 56 | }, 57 | { 58 | "id": "label_place_other", 59 | "layout": { 60 | "text-field": "{name_sv}" 61 | } 62 | }, 63 | { 64 | "id": "label_place_town", 65 | "layout": { 66 | "text-field": "{name_sv}" 67 | } 68 | }, 69 | { 70 | "id": "label_place_city", 71 | "layout": { 72 | "text-field": "{name_sv}" 73 | } 74 | }, 75 | { 76 | "id": "label_country", 77 | "layout": { 78 | "text-field": "{name_sv}" 79 | } 80 | }, 81 | { 82 | "id": "icon_subway-station", 83 | "layout": { 84 | "text-field": "{nameSe}" 85 | } 86 | }, 87 | { 88 | "id": "icon_bus-station", 89 | "layout": { 90 | "text-field": "{nameSe}" 91 | } 92 | }, 93 | { 94 | "id": "icon_railway-station", 95 | "layout": { 96 | "text-field": "{nameSe}" 97 | } 98 | }, 99 | { 100 | "id": "icon_aerodrome", 101 | "layout": { 102 | "text-field": "{name_sv}" 103 | } 104 | } 105 | ] 106 | } --------------------------------------------------------------------------------