diff --git a/.gitignore b/.gitignore index ceff61a..5fb191b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ data main REPORT.txt -!/configs/tilemaker \ No newline at end of file +!/configs/tilemaker +!third_party/* \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a7d0bf0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "third_party/tilemaker"] + path = third_party/tilemaker + url = https://github.com/lambdajack/tilemaker +[submodule "third_party/tippecanoe"] + path = third_party/tippecanoe + url = https://github.com/lambdajack/tippecanoe +[submodule "third_party/libosmium"] + path = third_party/libosmium + url = https://github.com/lambdajack/libosmium +[submodule "third_party/osmium-tool"] + path = third_party/osmium-tool + url = https://github.com/lambdajack/osmium-tool diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f6e67b5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2022 Jack Bizzell + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 8ae5f15..82223c2 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,18 @@ 1. Have [Docker]('https://docs.docker.com/get-docker/') installed. -2. `git clone https://github.com/lambdajack/sequentially-generate-planet-mbtiles` +2. `git clone --recurse-submodules https://github.com/lambdajack/sequentially-generate-planet-mbtiles` -3. `sudo ./release/v2.0.0-sequentially-generate-planet-mbtiles.exe` +3. `sudo ./release/v2.2.0-sequentially-generate-planet-mbtiles.exe` -3. Rejoice - see acknowledgements below for people to thank. +4. Rejoice - see acknowledgements below for people to thank. ## config.json (defaults shown) #### config supplied with the -c flag: ```bash - sudo ./release/v2.0.0-sequentially-generate-planet-mbtiles.exe -c /path/to/config.json + sudo ./release/v2.2.0-sequentially-generate-planet-mbtiles.exe -c /path/to/config.json ``` ```json @@ -33,9 +33,9 @@ **_dataDir_** - This will be where the program stores all data downloaded and generated. Need approx 300GB space. If none is provided a 'data' folder will be created in the current working directory. -**_TilemakerConfig_** - The config file that will be passed to [Tilemaker](https://github.com/systemed/tilemaker). See the default used [here](configs/tilemaker/config.json). +**_TilemakerConfig_** - The config file that will be passed to [Tilemaker](https://github.com/systemed/tilemaker). See the default used [here](third_party/tilemaker/resources/config-openmaptiles.json). -**_TilemakerProcess_** - The process file that will be passed to [Tilemaker](https://github.com/systemed/tilemaker). See the default used [here](configs/tilemaker/process.lua). +**_TilemakerProcess_** - The process file that will be passed to [Tilemaker](https://github.com/systemed/tilemaker). See the default used [here](third_party/tilemaker/resources/process-openmaptiles.lua). Note the files used are slightly adjusted from the examples provided by Tilemaker to give a pleasant default presentation when used with [TileServerGL](https://github.com/maptiler/tileserver-gl). @@ -47,13 +47,13 @@ That's where [sequentially-generate-planet-mbtiles](https://github.com/lambdajac **_This programme aims to be a simple set and forget, one liner which gives anyone - a way to get a full-featured and bang up to date set of vector tiles for the entire planet on small hardware._** -It's also designed (work in progress) to be fail safe - meaning that if your hardward (or our software) does crash mid process, you have not lost all your data, and you are able to start again from a point mid-way through. +It's also designed (work in progress) to be fail safe - meaning that if your hardware (or our software) does crash mid process, you have not lost all your data, and you are able to start again from a point mid-way through. -This also uses the maptiler mbtiles spec, meaning when you serve the files with something like tileserver-gl, you don't have to worry about setting up styles, as the basic one will be automatically available. Use the -s option to automatically serve the files when done on `http://localhost:8080`. (-s not yet implemented). +This also uses the openmaptiles mbtiles spec, meaning that when accessing the served tiles you can easily use most of the open source styles available. The default is aimed at using the OSM Bright style. More information on styles can be found below. ## Considerations 1. Hardware usage - this will consume effectively 100% CPU for up to a few days and will also do millions of read/writes from ssd/RAM/CPUcache. While modern hardware and vps' are perfectly capable of handling this, if you are using old hardware, beware that its remaining lifespan may be significantly reduced. -2. Cost - related to the above, while this programme and everything it uses is entirely free and open source - the person's/company's computer you're running it on might charge you electricity / load costs etc. Please check with your provider, how they handle fair use. +2. Cost - related to the above, while this programme and everything it uses is entirely free and open source - the person's/company's computer you're running it on might charge you electricity/load costs etc. Please check with your provider, how they handle fair use. 3. Time - your hardware will be unable to do anything much other than run this programme while it is running. This is in order to be efficient and is by design. If your hardware is hosting other production software or will be needed for other things in the next few days, be aware that it will perform suboptimally while this is running. 4. Bandwidth - this will download the entire planet's worth of openstreetmap data directly from OSM. At the time of writing, this is approx. 64GB. **Please note: ** the programme will look for a `planet-latest.osm.pbf` file in the `data/pbf` folder. If this is already present, it will skip the download and use this file. If you already have the data you wish to generate mbtiles for, you can place it there to skip the download. This can be useful if you want historical data, or are generating the mbtiles on multiple computers. 5. Data generation - in order to remain relatively fast on low spec hardware, this programme systematically breaks up the OSM data into more manegable chunks before processing. Therefore, expect around 300GB of storage to be used up on completion. @@ -70,18 +70,41 @@ This also uses the maptiler mbtiles spec, meaning when you serve the files with 1. Have [Docker](https://www.docker.com/) installed. -## How to serve? +# Serving mbtiles -We would recommend something like [tileserver-gl]('https://github.com/maptiler/tileserver-gl). The style is designed to match the basic one tileserver-gl provides. Further reading can be found [here]('https://wiki.openstreetmap.org/wiki/MBTiles') (openstreetmap wiki). +## Software + +We would recommend something like [tileserver-gl](https://github.com/maptiler/tileserver-gl). Further reading can be found on the [openstreetmap wiki](https://wiki.openstreetmap.org/wiki/MBTiles). + +You can quickly serve using tileserver-gl: +```bash +docker run --rm -it -v $(pwd)/data:/data -p 8080:80 maptiler/tileserver-gl +``` + +## Styles + +The default output of `sequentially-generate-planet-mbtiles` looks to match with the open source OSM ['Bright'](https://github.com/openmaptiles/osm-bright-gl-style/blob/master/style.json) style. + +When accessing your tileserver with something like [MapLibre](https://maplibre.org/maplibre-gl-js-docs/api/) from a front end application, a good place to start would be passing it a copy of the above ['Bright'](https://github.com/openmaptiles/osm-bright-gl-style/blob/master/style.json) style, **making sure to edit the urls to point to the correct places**. + +You can edit the output of `sequentially-generate-planet-mbtiles` by providing a customised process or config file through the config file. + +### Style first considerations +If making your own style or editing an existing one, note that `sequentially-generate-planet-mbtiles` by default will write text to the `name:latin` tag. If your maps are displayed, but missing text, check that your style is looking for `name:latin` and not something else (e.g. simply `name`). + +Pay attention to your fonts. The OSM Bright style makes use of Noto Sans variants (bold, italic & regular). If you are using tileserver-gl to serve your tiles, it only comes with the regular variant of Noto Sans (not the bold or the italic); therefore, it may look like text labels are missing since the style won't be able to find the fonts. You should therefore consider editing the style and changing all mentions of the font to use only the regular variant. Alternatively, you could ensure that all fonts necessary are present. + +**Further to the above, please find in this repo, a slightly [edited](./configs/styles/sgpm-bright.json) OSM Bright style for use with the default tileserver-gl. Feed this to your MapLibre or similar front end for a pleasent map suitable for most use cases.** ## FAQ 1. **How long will this take?** Low spec hardware? Whole planet? A few days. Maybe less than 48 hours for 16 CPUs. -2. **_Would I use this if I have powerful hardware?_** Maybe. Since the programme essentially saves its progress as it goes, even if you have strong hardware, you are reducing the time taken to redo the process in the event of a crash or file corruption. Further, the RAM is what is really saved here so if you have say 32 cores and 64gb RAM, you still would not be able to generate the entire planet by loading it into memory. Additionally, it just saves time configuring everything. +2. **Would I use this if I have powerful hardware?** Maybe. Since the programme essentially saves its progress as it goes, even if you have strong hardware, you are reducing the time taken to redo the process in the event of a crash or file corruption. Further, the RAM is what is really saved here so if you have say 32 cores and 64gb RAM, you still would not be able to generate the entire planet by loading it into memory. Additionally, it just saves time configuring everything. 3. **Why do I have to run part of the programme with 'sudo' privileges?** Many docker installations require sudo to be executed. You may not have to execute the programme with sudo. 4. **Do I have to download the entire planet?** At present, yes. Since if you are not downloading the entire planet, there are other tools out there which do a fine job of getting you mbtiles. We are working on being able to generate mbtiles for smaller areas (such as continents which may still not fit into the average computers RAM) -5. **Does 'low spec' mean I can run it on my toaster?** Maybe, but mostly not. But you can happily run it on you 4core4gb ram home pc without too much trouble. Just time. -6. **Didn't this used to use GeoFabrik?** It did but the plan was always to move away from geofabrik sources for the planet since it felt unnecessary, when the data was already available direct from source. Further, the GeoFabrik data leaves gaps in the ocean and some of their slices require more than 4gb of ram to process in memory. Ultimately, by getting the data from source, we have more control over it. +5. **Does 'low spec' mean I can run it on my toaster?** Maybe, but mostly not. But you can happily run it on you 4core CPU/4gb RAM home pc without too much trouble. Just time. +6. **Didn't this used to use GeoFabrik?** It did but the plan was always to move away from geofabrik sources for the planet since it felt unnecessary, when the data was already available direct from source. Further, the GeoFabrik data leaves gaps in the ocean and some of their slices require more than 4gb RAM to process in memory. Ultimately, by getting the data from source, we have more control over it. +7. **Why would I use this over Planetiler?** Planetiler is a fantastic project, however it still requires minimum 32gb RAM to complete the entire planet (0.5x the size of the planet pbf file). ## Acknowledgements @@ -92,29 +115,11 @@ Please take the time to thank the folks over at [tilemaker](https://github.com/s Please attribute openmaptiles, openstreemap contributors and tippecanoe if any data derived from this programme is used in production. ## Licenses -Files generated by sequentially-generate-planet-mbtiles is subject to the licenses described by [tippecanoe](https://github.com/mapbox/tippecanoe) and [OpenStreetMap](https://www.openstreetmap.org/copyright) +Files generated by `sequentially-generate-planet-mbtiles` is subject to the licenses described by [tippecanoe](https://github.com/mapbox/tippecanoe) and [OpenStreetMap](https://www.openstreetmap.org/copyright). + +`sequentially-generate-planet-mbtiles` is subject to the MIT [license](LICENSE). ## Contributions -All welcome! Feature request, pull request, bug reports/fixes etc - go for it. - -We'd like to make this tool quite robust moving forward - since we needed it for a current project of ours, we have released it notwithstanding the current rough-and-ready nature. - -## Todo - -1. Extra error handling for if one of the third party processes should fail. -2. The ability to select different system drives for downloading/generating files. -3. Write tests before significant future development. -4. Make the console prettier. -5. Add option to include or not ocean tiles -o. -6. Add automatically serve on completion option -s. -7. Add sleep function at points in stdout user may wish to read and hold it there for a time. -8. Consider converting tile-join to operate iteratively - allowing the report to be updated after each join. -9. Add option to name output file -10. Add exit listeners -11. Add docker kill on SIGINT -12. Add skip quadrant generation (save space but slower) -13. Add remove pbfs (save space) -14. Embed docker file into build binary -15. Add landcover +All welcome! Feature request, pull request, bug reports/fixes etc - go for it. \ No newline at end of file diff --git a/build/osmium/Dockerfile b/build/osmium/Dockerfile index 4101210..5598b18 100644 --- a/build/osmium/Dockerfile +++ b/build/osmium/Dockerfile @@ -1,30 +1,21 @@ -FROM ubuntu +FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive -ENV OSMIUM_VERSION 2.18.0 -ENV OSMIUM_TOOL_VERSION 1.14.0 - RUN apt-get update RUN apt-get update && apt-get install -y \ - wget libosmium2-dev libprotozero-dev libboost-program-options-dev libbz2-dev zlib1g-dev liblz4-dev libexpat1-dev cmake pandoc build-essential + libosmium2-dev libprotozero-dev libboost-program-options-dev libbz2-dev zlib1g-dev liblz4-dev libexpat1-dev cmake pandoc build-essential RUN mkdir /var/install WORKDIR /var/install -RUN wget https://github.com/osmcode/libosmium/archive/v${OSMIUM_VERSION}.tar.gz && \ - tar xzvf v${OSMIUM_VERSION}.tar.gz && \ - rm v${OSMIUM_VERSION}.tar.gz && \ - mv libosmium-${OSMIUM_VERSION} libosmium +COPY libosmium libosmium RUN cd libosmium && \ mkdir build && cd build && \ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DINSTALL_PROTOZERO=ON .. && \ make -RUN wget https://github.com/osmcode/osmium-tool/archive/v${OSMIUM_TOOL_VERSION}.tar.gz && \ - tar xzvf v${OSMIUM_TOOL_VERSION}.tar.gz && \ - rm v${OSMIUM_TOOL_VERSION}.tar.gz && \ - mv osmium-tool-${OSMIUM_TOOL_VERSION} osmium-tool +COPY osmium-tool osmium-tool RUN cd osmium-tool && \ mkdir build && cd build && \ diff --git a/cmd/sequentially-generate-planet-mbtiles/main.go b/cmd/sequentially-generate-planet-mbtiles/main.go index d0ca834..7b8be74 100644 --- a/cmd/sequentially-generate-planet-mbtiles/main.go +++ b/cmd/sequentially-generate-planet-mbtiles/main.go @@ -2,7 +2,6 @@ package main import ( "github.com/lambdajack/sequentially-generate-planet-mbtiles/internal/buildthirdpartycontainers" - "github.com/lambdajack/sequentially-generate-planet-mbtiles/internal/clonerepos" "github.com/lambdajack/sequentially-generate-planet-mbtiles/internal/downloadosmdata" "github.com/lambdajack/sequentially-generate-planet-mbtiles/internal/extractquadrants" "github.com/lambdajack/sequentially-generate-planet-mbtiles/internal/extractslices" @@ -16,7 +15,6 @@ import ( func main() { flags.GetFlags() folders.SetupFolderStructure() - clonerepos.CloneRepos() buildthirdpartycontainers.BuildContainers() downloadosmdata.DownloadOsmData() unzippolygons.UnzipPolygons() diff --git a/configs/styles/sgpm-bright.json b/configs/styles/sgpm-bright.json new file mode 100644 index 0000000..f62fe31 --- /dev/null +++ b/configs/styles/sgpm-bright.json @@ -0,0 +1,2443 @@ +{ + "version": 8, + "name": "Bright", + "metadata": { + "mapbox:autocomposite": false, + "mapbox:groups": { + "1444849242106.713": {"collapsed": false, "name": "Places"}, + "1444849334699.1902": {"collapsed": true, "name": "Bridges"}, + "1444849345966.4436": {"collapsed": false, "name": "Roads"}, + "1444849354174.1904": {"collapsed": true, "name": "Tunnels"}, + "1444849364238.8171": {"collapsed": false, "name": "Buildings"}, + "1444849382550.77": {"collapsed": false, "name": "Water"}, + "1444849388993.3071": {"collapsed": false, "name": "Land"} + }, + "mapbox:type": "template", + "openmaptiles:mapbox:owner": "openmaptiles", + "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t", + "openmaptiles:version": "3.x" + }, + "center": [0, 0], + "zoom": 1, + "bearing": 0, + "pitch": 0, + "sources": { + "openmaptiles": { + "type": "vector", + "url": "http://localhost:8080/data/v3.json" + } + }, + "sprite": "https://openmaptiles.github.io/osm-bright-gl-style/sprite", + "glyphs": "http://localhost:8080/fonts/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "background", + "type": "background", + "paint": {"background-color": "#f8f4f0"} + }, + { + "id": "landcover-glacier", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", "subclass", "glacier"], + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": "#fff", + "fill-opacity": {"base": 1, "stops": [[0, 0.9], [10, 0.3]]} + } + }, + { + "id": "landuse-residential", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["in", "class", "residential", "suburb", "neighbourhood"] + ], + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": { + "base": 1, + "stops": [ + [12, "hsla(30, 19%, 90%, 0.4)"], + [16, "hsla(30, 19%, 90%, 0.2)"] + ] + } + } + }, + { + "id": "landuse-commercial", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["==", "$type", "Polygon"], + ["==", "class", "commercial"] + ], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "hsla(0, 60%, 87%, 0.23)"} + }, + { + "id": "landuse-industrial", + "type": "fill", + "source": "openmaptiles", + "source-layer": "landuse", + "filter": [ + "all", + ["==", "$type", "Polygon"], + ["in", "class", "industrial", "garages", "dam"] + ], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "hsla(49, 100%, 88%, 0.34)"} + }, + { + "id": "landuse-cemetery", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", "class", "cemetery"], + "paint": {"fill-color": "#e0e4dd"} + }, + { + "id": "landuse-hospital", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", "class", "hospital"], + "paint": {"fill-color": "#fde"} + }, + { + "id": "landuse-school", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", "class", "school"], + "paint": {"fill-color": "#f0e8f8"} + }, + { + "id": "landuse-railway", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landuse", + "filter": ["==", "class", "railway"], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "hsla(30, 19%, 90%, 0.4)"} + }, + { + "id": "landcover-wood", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", "class", "wood"], + "paint": { + "fill-antialias": {"base": 1, "stops": [[0, false], [9, true]]}, + "fill-color": "#6a4", + "fill-opacity": 0.1, + "fill-outline-color": "hsla(0, 0%, 0%, 0.03)" + } + }, + { + "id": "landcover-grass", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", "class", "grass"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 1} + }, + { + "id": "landcover-grass-park", + "type": "fill", + "metadata": {"mapbox:group": "1444849388993.3071"}, + "source": "openmaptiles", + "source-layer": "park", + "filter": ["==", "class", "public_park"], + "paint": {"fill-color": "#d8e8c8", "fill-opacity": 0.8} + }, + { + "id": "waterway_tunnel", + "type": "line", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 14, + "filter": [ + "all", + ["in", "class", "river", "stream", "canal"], + ["==", "brunnel", "tunnel"] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [2, 4], + "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 6]]} + } + }, + { + "id": "waterway-other", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["!in", "class", "canal", "river", "stream"], + ["==", "intermittent", 0] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 2]]} + } + }, + { + "id": "waterway-other-intermittent", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["!in", "class", "canal", "river", "stream"], + ["==", "intermittent", 1] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 2]]} + } + }, + { + "id": "waterway-stream-canal", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["in", "class", "canal", "stream"], + ["!=", "brunnel", "tunnel"], + ["==", "intermittent", 0] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 6]]} + } + }, + { + "id": "waterway-stream-canal-intermittent", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["in", "class", "canal", "stream"], + ["!=", "brunnel", "tunnel"], + ["==", "intermittent", 1] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [4, 3], + "line-width": {"base": 1.3, "stops": [[13, 0.5], [20, 6]]} + } + }, + { + "id": "waterway-river", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", "class", "river"], + ["!=", "brunnel", "tunnel"], + ["==", "intermittent", 0] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-width": {"base": 1.2, "stops": [[10, 0.8], [20, 6]]} + } + }, + { + "id": "waterway-river-intermittent", + "type": "line", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "waterway", + "filter": [ + "all", + ["==", "class", "river"], + ["!=", "brunnel", "tunnel"], + ["==", "intermittent", 1] + ], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "#a0c8f0", + "line-dasharray": [3, 2.5], + "line-width": {"base": 1.2, "stops": [[10, 0.8], [20, 6]]} + } + }, + { + "id": "water-offset", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "water", + "maxzoom": 8, + "filter": ["==", "$type", "Polygon"], + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": "#a0c8f0", + "fill-opacity": 1, + "fill-translate": {"base": 1, "stops": [[6, [2, 0]], [8, [0, 0]]]} + } + }, + { + "id": "water", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "water", + "filter": ["all", ["!=", "intermittent", 1], ["!=", "brunnel", "tunnel"]], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "hsl(210, 67%, 85%)"} + }, + { + "id": "water-intermittent", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "water", + "filter": ["all", ["==", "intermittent", 1]], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "hsl(210, 67%, 85%)", "fill-opacity": 0.7} + }, + { + "id": "water-pattern", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "water", + "filter": ["all"], + "layout": {"visibility": "visible"}, + "paint": {"fill-pattern": "wave", "fill-translate": [0, 2.5]} + }, + { + "id": "landcover-ice-shelf", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["==", "subclass", "ice_shelf"], + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": "#fff", + "fill-opacity": {"base": 1, "stops": [[0, 0.9], [10, 0.3]]} + } + }, + { + "id": "landcover-sand", + "type": "fill", + "metadata": {"mapbox:group": "1444849382550.77"}, + "source": "openmaptiles", + "source-layer": "landcover", + "filter": ["all", ["==", "class", "sand"]], + "layout": {"visibility": "visible"}, + "paint": {"fill-color": "rgba(245, 238, 188, 1)", "fill-opacity": 1} + }, + { + "id": "building", + "type": "fill", + "metadata": {"mapbox:group": "1444849364238.8171"}, + "source": "openmaptiles", + "source-layer": "building", + "paint": { + "fill-antialias": true, + "fill-color": {"base": 1, "stops": [[15.5, "#f2eae2"], [16, "#dfdbd7"]]} + } + }, + { + "id": "building-top", + "type": "fill", + "metadata": {"mapbox:group": "1444849364238.8171"}, + "source": "openmaptiles", + "source-layer": "building", + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": "#f2eae2", + "fill-opacity": {"base": 1, "stops": [[13, 0], [16, 1]]}, + "fill-outline-color": "#dfdbd7", + "fill-translate": {"base": 1, "stops": [[14, [0, 0]], [16, [-2, -2]]]} + } + }, + { + "id": "tunnel-service-track-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "service", "track"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-dasharray": [0.5, 0.25], + "line-width": {"base": 1.2, "stops": [[15, 1], [16, 4], [20, 11]]} + } + }, + { + "id": "tunnel-motorway-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "rgba(200, 147, 102, 1)", + "line-dasharray": [0.5, 0.25], + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] + } + } + }, + { + "id": "tunnel-minor-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "class", "minor"]], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": {"stops": [[12, 0], [12.5, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[12, 0.5], [13, 1], [14, 4], [20, 15]] + }, + "line-dasharray": [0.5, 0.25] + } + }, + { + "id": "tunnel-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] + }, + "line-dasharray": [0.5, 0.25] + } + }, + { + "id": "tunnel-secondary-tertiary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": {"base": 1.2, "stops": [[8, 1.5], [20, 17]]}, + "line-dasharray": [0.5, 0.25] + } + }, + { + "id": "tunnel-trunk-primary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "primary", "trunk"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": { + "base": 1.2, + "stops": [[5, 0.4], [6, 0.6], [7, 1.5], [20, 22]] + } + } + }, + { + "id": "tunnel-motorway-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "#e9ac77", + "line-dasharray": [0.5, 0.25], + "line-width": { + "base": 1.2, + "stops": [[5, 0.4], [6, 0.6], [7, 1.5], [20, 22]] + } + } + }, + { + "id": "tunnel-path", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "brunnel", "tunnel"], + ["==", "class", "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 4]]} + } + }, + { + "id": "tunnel-motorway-link", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "rgba(244, 209, 158, 1)", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "tunnel-service-track", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "service", "track"] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-width": {"base": 1.2, "stops": [[15.5, 0], [16, 2], [20, 7.5]]} + } + }, + { + "id": "tunnel-link", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "tunnel-minor", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "class", "minor"]], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": {"base": 1.2, "stops": [[13.5, 0], [14, 2.5], [20, 11.5]]} + } + }, + { + "id": "tunnel-secondary-tertiary", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 10]]} + } + }, + { + "id": "tunnel-trunk-primary", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["in", "class", "primary", "trunk"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fff4c6", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "tunnel-motorway", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "tunnel"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "#ffdaa6", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "tunnel-railway", + "type": "line", + "metadata": {"mapbox:group": "1444849354174.1904"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "brunnel", "tunnel"], ["==", "class", "rail"]], + "paint": { + "line-color": "#bbb", + "line-dasharray": [2, 2], + "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} + } + }, + { + "id": "ferry", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["in", "class", "ferry"]], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "rgba(108, 159, 182, 1)", + "line-dasharray": [2, 2], + "line-width": 1.1 + } + }, + { + "id": "aeroway-taxiway-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["all", ["in", "class", "taxiway"]], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": {"base": 1.5, "stops": [[11, 2], [17, 12]]} + } + }, + { + "id": "aeroway-runway-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 12, + "filter": ["all", ["in", "class", "runway"]], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "rgba(153, 153, 153, 1)", + "line-opacity": 1, + "line-width": {"base": 1.5, "stops": [[11, 5], [17, 55]]} + } + }, + { + "id": "aeroway-area", + "type": "fill", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["==", "$type", "Polygon"], + ["in", "class", "runway", "taxiway"] + ], + "layout": {"visibility": "visible"}, + "paint": { + "fill-color": "rgba(255, 255, 255, 1)", + "fill-opacity": {"base": 1, "stops": [[13, 0], [14, 1]]} + } + }, + { + "id": "aeroway-taxiway", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["in", "class", "taxiway"], + ["==", "$type", "LineString"] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": {"base": 1, "stops": [[11, 0], [12, 1]]}, + "line-width": {"base": 1.5, "stops": [[11, 1], [17, 10]]} + } + }, + { + "id": "aeroway-runway", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "aeroway", + "minzoom": 4, + "filter": [ + "all", + ["in", "class", "runway"], + ["==", "$type", "LineString"] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "rgba(255, 255, 255, 1)", + "line-opacity": {"base": 1, "stops": [[11, 0], [12, 1]]}, + "line-width": {"base": 1.5, "stops": [[11, 4], [17, 50]]} + } + }, + { + "id": "road_area_pier", + "type": "fill", + "metadata": {}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "$type", "Polygon"], ["==", "class", "pier"]], + "layout": {"visibility": "visible"}, + "paint": {"fill-antialias": true, "fill-color": "#f8f4f0"} + }, + { + "id": "road_pier", + "type": "line", + "metadata": {}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "$type", "LineString"], ["in", "class", "pier"]], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#f8f4f0", + "line-width": {"base": 1.2, "stops": [[15, 1], [17, 4]]} + } + }, + { + "id": "highway-area", + "type": "fill", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "$type", "Polygon"], ["!in", "class", "pier"]], + "layout": {"visibility": "visible"}, + "paint": { + "fill-antialias": false, + "fill-color": "hsla(0, 0%, 89%, 0.56)", + "fill-opacity": 0.9, + "fill-outline-color": "#cfcdca" + } + }, + { + "id": "highway-motorway-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 12, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] + } + } + }, + { + "id": "highway-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 15]] + } + } + }, + { + "id": "highway-minor-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!=", "brunnel", "tunnel"], + ["in", "class", "minor", "service", "track"] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": {"stops": [[12, 0], [12.5, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[12, 0.5], [13, 1], [14, 4], [20, 15]] + } + } + }, + { + "id": "highway-secondary-tertiary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "butt", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": {"base": 1.2, "stops": [[8, 1.5], [20, 17]]} + } + }, + { + "id": "highway-primary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "primary"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "butt", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#e9ac77", + "line-opacity": {"stops": [[7, 0], [8, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[7, 0], [8, 0.6], [9, 1.5], [20, 22]] + } + } + }, + { + "id": "highway-trunk-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "trunk"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "butt", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#e9ac77", + "line-opacity": {"stops": [[5, 0], [6, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[5, 0], [6, 0.6], [7, 1.5], [20, 22]] + } + } + }, + { + "id": "highway-motorway-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 4, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "butt", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#e9ac77", + "line-opacity": {"stops": [[4, 0], [5, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[4, 0], [5, 0.4], [6, 0.6], [7, 1.5], [20, 22]] + } + } + }, + { + "id": "highway-path", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 4]]} + } + }, + { + "id": "highway-motorway-link", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 12, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "highway-link", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#fea", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "highway-minor", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!=", "brunnel", "tunnel"], + ["in", "class", "minor", "service", "track"] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": {"base": 1.2, "stops": [[13.5, 0], [14, 2.5], [20, 11.5]]} + } + }, + { + "id": "highway-secondary-tertiary", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#fea", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [8, 0.5], [20, 13]]} + } + }, + { + "id": "highway-primary", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "primary"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#fea", + "line-width": {"base": 1.2, "stops": [[8.5, 0], [9, 0.5], [20, 18]]} + } + }, + { + "id": "highway-trunk", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!in", "brunnel", "bridge", "tunnel"], + ["in", "class", "trunk"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#fea", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "highway-motorway", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 5, + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "#fc8", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "railway-transit", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "class", "transit"], + ["!in", "brunnel", "tunnel"] + ], + "layout": {"visibility": "visible"}, + "paint": { + "line-color": "hsla(0, 0%, 73%, 0.77)", + "line-width": {"base": 1.4, "stops": [[14, 0.4], [20, 1]]} + } + }, + { + "id": "railway-transit-hatching", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "class", "transit"], + ["!in", "brunnel", "tunnel"] + ], + "layout": {"visibility": "visible"}, + "paint": { + "line-color": "hsla(0, 0%, 73%, 0.68)", + "line-dasharray": [0.2, 8], + "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 2], [20, 6]]} + } + }, + { + "id": "railway-service", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "class", "rail"], + ["has", "service"] + ], + "paint": { + "line-color": "hsla(0, 0%, 73%, 0.77)", + "line-width": {"base": 1.4, "stops": [[14, 0.4], [20, 1]]} + } + }, + { + "id": "railway-service-hatching", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "class", "rail"], + ["has", "service"] + ], + "layout": {"visibility": "visible"}, + "paint": { + "line-color": "hsla(0, 0%, 73%, 0.68)", + "line-dasharray": [0.2, 8], + "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 2], [20, 6]]} + } + }, + { + "id": "railway", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!has", "service"], + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} + } + }, + { + "id": "railway-hatching", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["!has", "service"], + ["!in", "brunnel", "bridge", "tunnel"], + ["==", "class", "rail"] + ], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 3], [20, 8]]} + } + }, + { + "id": "bridge-motorway-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 19]] + } + } + }, + { + "id": "bridge-link-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[12, 1], [13, 3], [14, 4], [20, 19]] + } + } + }, + { + "id": "bridge-secondary-tertiary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-opacity": 1, + "line-width": { + "base": 1.2, + "stops": [[5, 0.4], [7, 0.6], [8, 1.5], [20, 21]] + } + } + }, + { + "id": "bridge-trunk-primary-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "primary", "trunk"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "hsl(28, 76%, 67%)", + "line-width": { + "base": 1.2, + "stops": [[5, 0.4], [6, 0.6], [7, 1.5], [20, 26]] + } + } + }, + { + "id": "bridge-motorway-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#e9ac77", + "line-width": { + "base": 1.2, + "stops": [[5, 0.4], [6, 0.6], [7, 1.5], [20, 26]] + } + } + }, + { + "id": "bridge-minor-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "brunnel", "bridge"], + ["in", "class", "minor", "service", "track"] + ], + "layout": {"line-cap": "butt", "line-join": "round"}, + "paint": { + "line-color": "#cfcdca", + "line-opacity": {"stops": [[12, 0], [12.5, 1]]}, + "line-width": { + "base": 1.2, + "stops": [[12, 0.5], [13, 1], [14, 6], [20, 24]] + } + } + }, + { + "id": "bridge-path-casing", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "brunnel", "bridge"], + ["==", "class", "path"] + ], + "paint": { + "line-color": "#f8f4f0", + "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 18]]} + } + }, + { + "id": "bridge-path", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "brunnel", "bridge"], + ["==", "class", "path"] + ], + "paint": { + "line-color": "#cba", + "line-dasharray": [1.5, 0.75], + "line-width": {"base": 1.2, "stops": [[15, 1.2], [20, 4]]} + } + }, + { + "id": "bridge-motorway-link", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["==", "class", "motorway"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "bridge-link", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "trunk", "primary", "secondary", "tertiary"], + ["==", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": { + "base": 1.2, + "stops": [[12.5, 0], [13, 1.5], [14, 2.5], [20, 11.5]] + } + } + }, + { + "id": "bridge-minor", + "type": "line", + "metadata": {"mapbox:group": "1444849345966.4436"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "$type", "LineString"], + ["==", "brunnel", "bridge"], + ["in", "class", "minor", "service", "track"] + ], + "layout": {"line-cap": "round", "line-join": "round"}, + "paint": { + "line-color": "#fff", + "line-opacity": 1, + "line-width": {"base": 1.2, "stops": [[13.5, 0], [14, 2.5], [20, 11.5]]} + } + }, + { + "id": "bridge-secondary-tertiary", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "secondary", "tertiary"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [8, 0.5], [20, 13]]} + } + }, + { + "id": "bridge-trunk-primary", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["in", "class", "primary", "trunk"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fea", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "bridge-motorway", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": [ + "all", + ["==", "brunnel", "bridge"], + ["==", "class", "motorway"], + ["!=", "ramp", 1] + ], + "layout": {"line-join": "round"}, + "paint": { + "line-color": "#fc8", + "line-width": {"base": 1.2, "stops": [[6.5, 0], [7, 0.5], [20, 18]]} + } + }, + { + "id": "bridge-railway", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "brunnel", "bridge"], ["==", "class", "rail"]], + "paint": { + "line-color": "#bbb", + "line-width": {"base": 1.4, "stops": [[14, 0.4], [15, 0.75], [20, 2]]} + } + }, + { + "id": "bridge-railway-hatching", + "type": "line", + "metadata": {"mapbox:group": "1444849334699.1902"}, + "source": "openmaptiles", + "source-layer": "transportation", + "filter": ["all", ["==", "brunnel", "bridge"], ["==", "class", "rail"]], + "paint": { + "line-color": "#bbb", + "line-dasharray": [0.2, 8], + "line-width": {"base": 1.4, "stops": [[14.5, 0], [15, 3], [20, 8]]} + } + }, + { + "id": "cablecar", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", "subclass", "cable_car"], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "hsl(0, 0%, 70%)", + "line-width": {"base": 1, "stops": [[11, 1], [19, 2.5]]} + } + }, + { + "id": "cablecar-dash", + "type": "line", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 13, + "filter": ["==", "subclass", "cable_car"], + "layout": {"line-cap": "round", "visibility": "visible"}, + "paint": { + "line-color": "hsl(0, 0%, 70%)", + "line-dasharray": [2, 3], + "line-width": {"base": 1, "stops": [[11, 3], [19, 5.5]]} + } + }, + { + "id": "boundary-land-level-4", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "minzoom": 2, + "filter": [ + "all", + [">=", "admin_level", 3], + ["<=", "admin_level", 8], + ["!=", "maritime", 1] + ], + "layout": {"line-join": "round", "visibility": "visible"}, + "paint": { + "line-color": "#9e9cab", + "line-dasharray": [3, 1, 1, 1], + "line-width": {"base": 1.4, "stops": [[4, 0.4], [5, 1], [12, 3]]} + } + }, + { + "id": "boundary-land-level-2", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": [ + "all", + ["==", "admin_level", 2], + ["!=", "maritime", 1], + ["!=", "disputed", 1] + ], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "hsl(248, 7%, 66%)", + "line-width": { + "base": 1, + "stops": [[0, 0.6], [4, 1.4], [5, 2], [12, 8]] + } + } + }, + { + "id": "boundary-land-disputed", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "filter": ["all", ["!=", "maritime", 1], ["==", "disputed", 1]], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "hsl(248, 7%, 70%)", + "line-dasharray": [1, 3], + "line-width": { + "base": 1, + "stops": [[0, 0.6], [4, 1.4], [5, 2], [12, 8]] + } + } + }, + { + "id": "boundary-water", + "type": "line", + "source": "openmaptiles", + "source-layer": "boundary", + "minzoom": 4, + "filter": ["all", ["in", "admin_level", 2, 4], ["==", "maritime", 1]], + "layout": { + "line-cap": "round", + "line-join": "round", + "visibility": "visible" + }, + "paint": { + "line-color": "rgba(154, 189, 214, 1)", + "line-opacity": {"stops": [[6, 0.6], [10, 1]]}, + "line-width": { + "base": 1, + "stops": [[0, 0.6], [4, 1.4], [5, 2], [12, 8]] + } + } + }, + { + "id": "waterway-name", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "waterway", + "minzoom": 13, + "filter": ["all", ["==", "$type", "LineString"], ["has", "name"]], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": "{name:latin} {name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-rotation-alignment": "map", + "text-size": 14 + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water-name-lakeline", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": ["==", "$type", "LineString"], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 350, + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-rotation-alignment": "map", + "text-size": 14 + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water-name-ocean", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": ["all", ["==", "$type", "Point"], ["==", "class", "ocean"]], + "layout": { + "symbol-placement": "point", + "symbol-spacing": 350, + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-rotation-alignment": "map", + "text-size": 14 + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "water-name-other", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "water_name", + "filter": ["all", ["==", "$type", "Point"], ["!in", "class", "ocean"]], + "layout": { + "symbol-placement": "point", + "symbol-spacing": 350, + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.2, + "text-max-width": 5, + "text-rotation-alignment": "map", + "text-size": {"stops": [[0, 10], [6, 14]]}, + "visibility": "visible" + }, + "paint": { + "text-color": "#74aee9", + "text-halo-color": "rgba(255,255,255,0.7)", + "text-halo-width": 1.5 + } + }, + { + "id": "road_oneway", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", "oneway", 1], + [ + "in", + "class", + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "minor", + "service" + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": 90, + "icon-rotation-alignment": "map", + "icon-size": {"stops": [[15, 0.5], [19, 1]]}, + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "road_oneway_opposite", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation", + "minzoom": 15, + "filter": [ + "all", + ["==", "oneway", -1], + [ + "in", + "class", + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "minor", + "service" + ] + ], + "layout": { + "icon-image": "oneway", + "icon-padding": 2, + "icon-rotate": -90, + "icon-rotation-alignment": "map", + "icon-size": {"stops": [[15, 0.5], [19, 1]]}, + "symbol-placement": "line", + "symbol-spacing": 75 + }, + "paint": {"icon-opacity": 0.5} + }, + { + "id": "poi-level-3", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 16, + "filter": [ + "all", + ["==", "$type", "Point"], + [">=", "rank", 25], + ["any", ["!has", "level"], ["==", "level", 0]] + ], + "layout": { + "icon-image": "{class}_11", + "text-anchor": "top", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-padding": 2, + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "poi-level-2", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 15, + "filter": [ + "all", + ["==", "$type", "Point"], + ["<=", "rank", 24], + [">=", "rank", 15], + ["any", ["!has", "level"], ["==", "level", 0]] + ], + "layout": { + "icon-image": "{class}_11", + "text-anchor": "top", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-padding": 2, + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "poi-level-1", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 14, + "filter": [ + "all", + ["==", "$type", "Point"], + ["<=", "rank", 14], + ["has", "name"], + ["any", ["!has", "level"], ["==", "level", 0]] + ], + "layout": { + "icon-image": "{class}_11", + "text-anchor": "top", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-padding": 2, + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "poi-railway", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "poi", + "minzoom": 13, + "filter": [ + "all", + ["==", "$type", "Point"], + ["has", "name"], + ["==", "class", "railway"], + ["==", "subclass", "station"] + ], + "layout": { + "icon-allow-overlap": false, + "icon-ignore-placement": false, + "icon-image": "{class}_11", + "icon-optional": false, + "text-allow-overlap": false, + "text-anchor": "top", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-ignore-placement": false, + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-optional": true, + "text-padding": 2, + "text-size": 12 + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "highway-name-path", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15.5, + "filter": ["==", "class", "path"], + "layout": { + "symbol-placement": "line", + "text-field": "{name:latin} {name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": {"base": 1, "stops": [[13, 12], [14, 13]]} + }, + "paint": { + "text-color": "hsl(30, 23%, 62%)", + "text-halo-color": "#f8f4f0", + "text-halo-width": 0.5 + } + }, + { + "id": "highway-name-minor", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 15, + "filter": [ + "all", + ["==", "$type", "LineString"], + ["in", "class", "minor", "service", "track"] + ], + "layout": { + "symbol-placement": "line", + "text-field": "{name:latin} {name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": {"base": 1, "stops": [[13, 12], [14, 13]]} + }, + "paint": { + "text-color": "#765", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-name-major", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 12.2, + "filter": ["in", "class", "primary", "secondary", "tertiary", "trunk"], + "layout": { + "symbol-placement": "line", + "text-field": "{name:latin} {name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "map", + "text-size": {"base": 1, "stops": [[13, 12], [14, 13]]} + }, + "paint": { + "text-color": "#765", + "text-halo-blur": 0.5, + "text-halo-width": 1 + } + }, + { + "id": "highway-shield", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 8, + "filter": [ + "all", + ["<=", "ref_length", 6], + ["==", "$type", "LineString"], + ["!in", "network", "us-interstate", "us-highway", "us-state"] + ], + "layout": { + "icon-image": "road_{ref_length}", + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, + "symbol-spacing": 200, + "text-field": "{ref}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + }, + "paint": {} + }, + { + "id": "highway-shield-us-interstate", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 7, + "filter": [ + "all", + ["<=", "ref_length", 6], + ["==", "$type", "LineString"], + ["in", "network", "us-interstate"] + ], + "layout": { + "icon-image": "{network}_{ref_length}", + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": { + "base": 1, + "stops": [[7, "point"], [7, "line"], [8, "line"]] + }, + "symbol-spacing": 200, + "text-field": "{ref}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + }, + "paint": {"text-color": "rgba(0, 0, 0, 1)"} + }, + { + "id": "highway-shield-us-other", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "transportation_name", + "minzoom": 9, + "filter": [ + "all", + ["<=", "ref_length", 6], + ["==", "$type", "LineString"], + ["in", "network", "us-highway", "us-state"] + ], + "layout": { + "icon-image": "{network}_{ref_length}", + "icon-rotation-alignment": "viewport", + "icon-size": 1, + "symbol-placement": {"base": 1, "stops": [[10, "point"], [11, "line"]]}, + "symbol-spacing": 200, + "text-field": "{ref}", + "text-font": ["Noto Sans Regular"], + "text-rotation-alignment": "viewport", + "text-size": 10 + }, + "paint": {"text-color": "rgba(0, 0, 0, 1)"} + }, + { + "id": "airport-label-major", + "type": "symbol", + "source": "openmaptiles", + "source-layer": "aerodrome_label", + "minzoom": 10, + "filter": ["all", ["has", "iata"]], + "layout": { + "icon-image": "airport_11", + "icon-size": 1, + "text-anchor": "top", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 9, + "text-offset": [0, 0.6], + "text-optional": true, + "text-padding": 2, + "text-size": 12, + "visibility": "visible" + }, + "paint": { + "text-color": "#666", + "text-halo-blur": 0.5, + "text-halo-color": "#ffffff", + "text-halo-width": 1 + } + }, + { + "id": "place-other", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": [ + "!in", + "class", + "city", + "town", + "village", + "state", + "country", + "continent" + ], + "layout": { + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.1, + "text-max-width": 9, + "text-size": {"base": 1.2, "stops": [[12, 10], [15, 14]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#633", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-village", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": ["==", "class", "village"], + "layout": { + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": {"base": 1.2, "stops": [[10, 12], [15, 22]]}, + "visibility": "visible" + }, + "paint": { + "text-color": "#333", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-town", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": ["==", "class", "town"], + "layout": { + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": {"base": 1.2, "stops": [[10, 14], [15, 24]]}, + "visibility": "visible" + }, + "paint": { + "text-color": "#333", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-city", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": ["all", ["!=", "capital", 2], ["==", "class", "city"]], + "layout": { + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-size": {"base": 1.2, "stops": [[7, 14], [11, 24]]}, + "visibility": "visible" + }, + "paint": { + "text-color": "#333", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-city-capital", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": ["all", ["==", "capital", 2], ["==", "class", "city"]], + "layout": { + "icon-image": "star_11", + "icon-size": 0.8, + "text-anchor": "left", + "text-field": "{name:latin}\n{name:nonlatin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 8, + "text-offset": [0.4, 0], + "text-size": {"base": 1.2, "stops": [[7, 14], [11, 24]]}, + "visibility": "visible" + }, + "paint": { + "text-color": "#333", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-state", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": ["in", "class", "state"], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-letter-spacing": 0.1, + "text-max-width": 9, + "text-size": {"base": 1.2, "stops": [[12, 10], [15, 14]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#633", + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 1.2 + } + }, + { + "id": "place-country-other", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": [ + "all", + ["==", "class", "country"], + [">=", "rank", 3], + ["!has", "iso_a2"] + ], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 6.25, + "text-size": {"stops": [[3, 11], [7, 17]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#334", + "text-halo-blur": 1, + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 2 + } + }, + { + "id": "place-country-3", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": [ + "all", + ["==", "class", "country"], + [">=", "rank", 3], + ["has", "iso_a2"] + ], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 6.25, + "text-size": {"stops": [[3, 11], [7, 17]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#334", + "text-halo-blur": 1, + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 2 + } + }, + { + "id": "place-country-2", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": [ + "all", + ["==", "class", "country"], + ["==", "rank", 2], + ["has", "iso_a2"] + ], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 6.25, + "text-size": {"stops": [[2, 11], [5, 17]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#334", + "text-halo-blur": 1, + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 2 + } + }, + { + "id": "place-country-1", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "filter": [ + "all", + ["==", "class", "country"], + ["==", "rank", 1], + ["has", "iso_a2"] + ], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 6.25, + "text-size": {"stops": [[1, 11], [4, 17]]}, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#334", + "text-halo-blur": 1, + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 2 + } + }, + { + "id": "place-continent", + "type": "symbol", + "metadata": {"mapbox:group": "1444849242106.713"}, + "source": "openmaptiles", + "source-layer": "place", + "maxzoom": 1, + "filter": ["==", "class", "continent"], + "layout": { + "text-field": "{name:latin}", + "text-font": ["Noto Sans Regular"], + "text-max-width": 6.25, + "text-size": 14, + "text-transform": "uppercase", + "visibility": "visible" + }, + "paint": { + "text-color": "#334", + "text-halo-blur": 1, + "text-halo-color": "rgba(255,255,255,0.8)", + "text-halo-width": 2 + } + } + ], + "id": "bright" + } \ No newline at end of file diff --git a/configs/tilemaker/config.json b/configs/tilemaker/config.json deleted file mode 100644 index 3cb1a3b..0000000 --- a/configs/tilemaker/config.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "layers": { - "place": { "minzoom": 0, "maxzoom": 14 }, - "boundary": { "minzoom": 0, "maxzoom": 14, "simplify_below": 12, "simplify_level": 0.0003, "simplify_ratio": 2 }, - - "poi": { "minzoom": 12, "maxzoom": 14 }, - "poi_detail": { "minzoom": 14, "maxzoom": 14, "write_to": "poi"}, - - "housenumber": { "minzoom": 14, "maxzoom": 14 }, - - "waterway": { "minzoom": 8, "maxzoom": 14, "simplify_below": 12, "simplify_level": 0.0003, "simplify_ratio": 2 }, - "waterway_detail": { "minzoom": 12, "maxzoom": 14, "write_to": "waterway" }, - - "transportation": { "minzoom": 4, "maxzoom": 14, "simplify_below": 13, "simplify_level": 0.0003 }, - "transportation_name": { "minzoom": 8, "maxzoom": 14 }, - "transportation_name_mid": { "minzoom": 12, "maxzoom": 14, "write_to": "transportation_name" }, - "transportation_name_detail": { "minzoom": 14, "maxzoom": 14, "write_to": "transportation_name" }, - - "building": { "minzoom": 13, "maxzoom": 14 }, - - "water": { "minzoom": 6, "maxzoom": 14, "simplify_below": 12, "simplify_level": 0.0003, "simplify_ratio": 2}, - "ocean": { "minzoom": 0, "maxzoom": 14, "source": "coastline/water_polygons.shp", "simplify_below": 13, "simplify_level": 0.0001, "simplify_ratio": 2, "write_to": "water", "index": true }, - "water_name": { "minzoom": 14, "maxzoom": 14 }, - "water_name_detail": { "minzoom": 14, "maxzoom": 14, "write_to": "water_name" }, - - "aeroway": { "minzoom": 11, "maxzoom": 14 }, - "aerodrome_label": { "minzoom": 10, "maxzoom": 14 }, - "park": { "minzoom": 11, "maxzoom": 14 }, - "landuse": { "minzoom": 4, "maxzoom": 14, "simplify_below": 13, "simplify_level": 0.0003, "simplify_ratio": 2 }, - "urban_areas": { "minzoom": 4, "maxzoom": 8, "source": "landcover/ne_10m_urban_areas/ne_10m_urban_areas.shp", "source_columns": ["featurecla"], "simplify_below": 7, "simplify_level": 0.0003, "simplify_ratio": 2, "write_to": "landuse" }, - "landcover": { "minzoom": 0, "maxzoom": 14, "simplify_below": 13, "simplify_level": 0.0003, "simplify_ratio": 2 }, - "ice_shelf": { "minzoom": 0, "maxzoom": 9, "source": "landcover/ne_10m_antarctic_ice_shelves_polys/ne_10m_antarctic_ice_shelves_polys.shp", "source_columns": ["featurecla"], "simplify_below": 13, "simplify_level": 0.0005, "write_to": "landcover" }, - "glacier": { "minzoom": 2, "maxzoom": 9, "source": "landcover/ne_10m_glaciated_areas/ne_10m_glaciated_areas.shp", "source_columns": ["featurecla"], "simplify_below": 13, "simplify_level": 0.0005, "write_to": "landcover" }, - "mountain_peak": { "minzoom": 11, "maxzoom": 14 } - }, - "settings": { - "minzoom": 0, - "maxzoom": 14, - "basezoom": 14, - "include_ids": false, - "combine_below": 14, - "name": "Tilemaker to OpenMapTiles schema", - "version": "3.0", - "description": "Tile config based on OpenMapTiles schema", - "compress": "gzip", - "filemetadata": { - "tilejson": "2.0.0", - "scheme": "xyz", - "type": "baselayer", - "format": "pbf", - "tiles": ["https://example.com/liechtenstein/{z}/{x}/{y}.pbf"] - } - } -} - diff --git a/configs/tilemaker/process.lua b/configs/tilemaker/process.lua deleted file mode 100644 index 0f7c2ff..0000000 --- a/configs/tilemaker/process.lua +++ /dev/null @@ -1,1286 +0,0 @@ --- Data processing based on openmaptiles.org schema --- https://openmaptiles.org/schema/ --- Copyright (c) 2016, KlokanTech.com & OpenMapTiles contributors. --- Used under CC-BY 4.0 - --------- --- Alter these lines to control which languages are written for place/streetnames --- --- Preferred language can be (for example) "en" for English, "de" for German, or nil to use OSM's name tag: -preferred_language = nil --- This is written into the following vector tile attribute (usually "name:latin"): -preferred_language_attribute = "name" --- If OSM's name tag differs, then write it into this attribute (usually "name_int"): -default_language_attribute = "name" --- Also write these languages if they differ - for example, { "de", "fr" } -additional_languages = {} --------- - --- Enter/exit Tilemaker -function init_function() end -function exit_function() end - --- Implement Sets in tables -function Set(list) - local set = {} - for _, l in ipairs(list) do - set[l] = true - end - return set -end - --- Meters per pixel if tile is 256x256 -ZRES5 = 4891.97 -ZRES6 = 2445.98 -ZRES7 = 1222.99 -ZRES8 = 611.5 -ZRES9 = 305.7 -ZRES10 = 152.9 -ZRES11 = 76.4 -ZRES12 = 38.2 -ZRES13 = 19.1 - --- The height of one floor, in meters -BUILDING_FLOOR_HEIGHT = 3.66 - --- Process node/way tags -aerodromeValues = Set({ "international", "public", "regional", "military", "private" }) - --- Process node tags - -node_keys = { - "addr:housenumber", - "aerialway", - "aeroway", - "amenity", - "barrier", - "highway", - "historic", - "leisure", - "natural", - "office", - "place", - "railway", - "shop", - "sport", - "tourism", - "waterway", -} -function node_function(node) - -- Write 'aerodrome_label' - local aeroway = node:Find("aeroway") - if aeroway == "aerodrome" then - node:Layer("aerodrome_label", false) - SetNameAttributes(node) - node:Attribute("iata", node:Find("iata")) - SetEleAttributes(node) - node:Attribute("icao", node:Find("icao")) - - local aerodrome_value = node:Find("aerodrome") - local class - if aerodromeValues[aerodrome_value] then - class = aerodrome_value - else - class = "other" - end - node:Attribute("class", class) - end - -- Write 'housenumber' - local housenumber = node:Find("addr:housenumber") - if housenumber ~= "" then - node:Layer("housenumber", false) - node:Attribute("housenumber", housenumber) - end - - -- Write 'place' - -- note that OpenMapTiles has a rank for countries (1-3), states (1-6) and cities (1-10+); - -- we could potentially approximate it for cities based on the population tag - local place = node:Find("place") - if place ~= "" then - local rank = nil - local mz = 13 - local pop = tonumber(node:Find("population")) or 0 - - if place == "continent" then - mz = 0 - elseif place == "country" then - if pop > 50000000 then - rank = 1 - mz = 1 - elseif pop > 20000000 then - rank = 2 - mz = 2 - else - rank = 3 - mz = 3 - end - elseif place == "state" then - mz = 4 - elseif place == "city" then - mz = 5 - elseif place == "town" and pop > 8000 then - mz = 7 - elseif place == "town" then - mz = 8 - elseif place == "village" and pop > 2000 then - mz = 9 - elseif place == "village" then - mz = 10 - elseif place == "suburb" then - mz = 11 - elseif place == "hamlet" then - mz = 12 - elseif place == "neighbourhood" then - mz = 13 - elseif place == "locality" then - mz = 13 - end - - node:Layer("place", false) - node:Attribute("class", place) - node:MinZoom(mz) - if rank then - node:AttributeNumeric("rank", rank) - end - if place == "country" then - node:Attribute("iso_a2", node:Find("ISO3166-1:alpha2")) - end - SetNameAttributes(node) - return - end - - -- Write 'poi' - local rank, class, subclass = GetPOIRank(node) - if rank then - WritePOI(node, class, subclass, rank) - end - - -- Write 'mountain_peak' and 'water_name' - local natural = node:Find("natural") - if natural == "peak" or natural == "volcano" then - node:Layer("mountain_peak", false) - SetEleAttributes(node) - node:AttributeNumeric("rank", 1) - node:Attribute("class", natural) - SetNameAttributes(node) - return - end - if natural == "bay" then - node:Layer("water_name", false) - SetNameAttributes(node) - return - end -end - --- Process way tags - -majorRoadValues = Set({ "motorway", "trunk", "primary" }) -mainRoadValues = Set({ "secondary", "motorway_link", "trunk_link", "primary_link", "secondary_link" }) -midRoadValues = Set({ "tertiary", "tertiary_link" }) -minorRoadValues = Set({ "unclassified", "residential", "road", "living_street" }) -trackValues = Set({ "cycleway", "byway", "bridleway", "track" }) -pathValues = Set({ "footway", "path", "steps", "pedestrian" }) -linkValues = Set({ "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link" }) -constructionValues = Set({ "primary", "secondary", "tertiary", "motorway", "service", "trunk", "track" }) - -aerowayBuildings = Set({ "terminal", "gate", "tower" }) -landuseKeys = Set({ - "school", - "university", - "kindergarten", - "college", - "library", - "hospital", - "railway", - "cemetery", - "military", - "residential", - "commercial", - "industrial", - "retail", - "stadium", - "pitch", - "playground", - "theme_park", - "bus_station", - "zoo", -}) -landcoverKeys = { - wood = "wood", - forest = "wood", - wetland = "wetland", - beach = "sand", - sand = "sand", - farmland = "farmland", - farm = "farmland", - orchard = "farmland", - vineyard = "farmland", - plant_nursery = "farmland", - glacier = "ice", - ice_shelf = "ice", - grassland = "grass", - grass = "grass", - meadow = "grass", - allotments = "grass", - park = "grass", - village_green = "grass", - recreation_ground = "grass", - garden = "grass", - golf_course = "grass", -} - --- POI key/value pairs: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/mapping.yaml -poiTags = { - aerialway = Set({ "station" }), - amenity = Set({ - "arts_centre", - "bank", - "bar", - "bbq", - "bicycle_parking", - "bicycle_rental", - "biergarten", - "bus_station", - "cafe", - "cinema", - "clinic", - "college", - "community_centre", - "courthouse", - "dentist", - "doctors", - "embassy", - "fast_food", - "ferry_terminal", - "fire_station", - "food_court", - "fuel", - "grave_yard", - "hospital", - "ice_cream", - "kindergarten", - "library", - "marketplace", - "motorcycle_parking", - "nightclub", - "nursing_home", - "parking", - "pharmacy", - "place_of_worship", - "police", - "post_box", - "post_office", - "prison", - "pub", - "public_building", - "recycling", - "restaurant", - "school", - "shelter", - "swimming_pool", - "taxi", - "telephone", - "theatre", - "toilets", - "townhall", - "university", - "veterinary", - "waste_basket", - }), - barrier = Set({ - "bollard", - "border_control", - "cycle_barrier", - "gate", - "lift_gate", - "sally_port", - "stile", - "toll_booth", - }), - building = Set({ "dormitory" }), - highway = Set({ "bus_stop" }), - historic = Set({ "monument", "castle", "ruins" }), - landuse = Set({ "basin", "brownfield", "cemetery", "reservoir", "winter_sports" }), - leisure = Set({ - "dog_park", - "escape_game", - "garden", - "golf_course", - "ice_rink", - "hackerspace", - "marina", - "miniature_golf", - "park", - "pitch", - "playground", - "sports_centre", - "stadium", - "swimming_area", - "swimming_pool", - "water_park", - }), - railway = Set({ "halt", "station", "subway_entrance", "train_station_entrance", "tram_stop" }), - shop = Set({ - "accessories", - "alcohol", - "antiques", - "art", - "bag", - "bakery", - "beauty", - "bed", - "beverages", - "bicycle", - "books", - "boutique", - "butcher", - "camera", - "car", - "car_repair", - "carpet", - "charity", - "chemist", - "chocolate", - "clothes", - "coffee", - "computer", - "confectionery", - "convenience", - "copyshop", - "cosmetics", - "deli", - "delicatessen", - "department_store", - "doityourself", - "dry_cleaning", - "electronics", - "erotic", - "fabric", - "florist", - "frozen_food", - "furniture", - "garden_centre", - "general", - "gift", - "greengrocer", - "hairdresser", - "hardware", - "hearing_aids", - "hifi", - "ice_cream", - "interior_decoration", - "jewelry", - "kiosk", - "lamps", - "laundry", - "mall", - "massage", - "mobile_phone", - "motorcycle", - "music", - "musical_instrument", - "newsagent", - "optician", - "outdoor", - "perfume", - "perfumery", - "pet", - "photo", - "second_hand", - "shoes", - "sports", - "stationery", - "supermarket", - "tailor", - "tattoo", - "ticket", - "tobacco", - "toys", - "travel_agency", - "video", - "video_games", - "watches", - "weapons", - "wholesale", - "wine", - }), - sport = Set({ - "american_football", - "archery", - "athletics", - "australian_football", - "badminton", - "baseball", - "basketball", - "beachvolleyball", - "billiards", - "bmx", - "boules", - "bowls", - "boxing", - "canadian_football", - "canoe", - "chess", - "climbing", - "climbing_adventure", - "cricket", - "cricket_nets", - "croquet", - "curling", - "cycling", - "disc_golf", - "diving", - "dog_racing", - "equestrian", - "fatsal", - "field_hockey", - "free_flying", - "gaelic_games", - "golf", - "gymnastics", - "handball", - "hockey", - "horse_racing", - "horseshoes", - "ice_hockey", - "ice_stock", - "judo", - "karting", - "korfball", - "long_jump", - "model_aerodrome", - "motocross", - "motor", - "multi", - "netball", - "orienteering", - "paddle_tennis", - "paintball", - "paragliding", - "pelota", - "racquet", - "rc_car", - "rowing", - "rugby", - "rugby_league", - "rugby_union", - "running", - "sailing", - "scuba_diving", - "shooting", - "shooting_range", - "skateboard", - "skating", - "skiing", - "soccer", - "surfing", - "swimming", - "table_soccer", - "table_tennis", - "team_handball", - "tennis", - "toboggan", - "volleyball", - "water_ski", - "yoga", - }), - tourism = Set({ - "alpine_hut", - "aquarium", - "artwork", - "attraction", - "bed_and_breakfast", - "camp_site", - "caravan_site", - "chalet", - "gallery", - "guest_house", - "hostel", - "hotel", - "information", - "motel", - "museum", - "picnic_site", - "theme_park", - "viewpoint", - "zoo", - }), - waterway = Set({ "dock" }), -} - --- POI "class" values: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/poi.yaml -poiClasses = { - townhall = "town_hall", - public_building = "town_hall", - courthouse = "town_hall", - community_centre = "town_hall", - golf = "golf", - golf_course = "golf", - miniature_golf = "golf", - fast_food = "fast_food", - food_court = "fast_food", - park = "park", - bbq = "park", - bus_stop = "bus", - bus_station = "bus", - subway_entrance = "entrance", - train_station_entrance = "entrance", - camp_site = "campsite", - caravan_site = "campsite", - laundry = "laundry", - dry_cleaning = "laundry", - supermarket = "grocery", - deli = "grocery", - delicatessen = "grocery", - department_store = "grocery", - greengrocer = "grocery", - marketplace = "grocery", - books = "library", - library = "library", - university = "college", - college = "college", - hotel = "lodging", - motel = "lodging", - bed_and_breakfast = "lodging", - guest_house = "lodging", - hostel = "lodging", - chalet = "lodging", - alpine_hut = "lodging", - dormitory = "lodging", - chocolate = "ice_cream", - confectionery = "ice_cream", - post_box = "post", - post_office = "post", - cafe = "cafe", - school = "school", - kindergarten = "school", - alcohol = "alcohol_shop", - beverages = "alcohol_shop", - wine = "alcohol_shop", - bar = "bar", - nightclub = "bar", - marina = "harbor", - dock = "harbor", - car = "car", - car_repair = "car", - taxi = "car", - hospital = "hospital", - nursing_home = "hospital", - clinic = "hospital", - grave_yard = "cemetery", - cemetery = "cemetery", - attraction = "attraction", - viewpoint = "attraction", - biergarten = "beer", - pub = "beer", - music = "music", - musical_instrument = "music", - american_football = "stadium", - stadium = "stadium", - soccer = "stadium", - art = "art_gallery", - artwork = "art_gallery", - gallery = "art_gallery", - arts_centre = "art_gallery", - bag = "clothing_store", - clothes = "clothing_store", - swimming_area = "swimming", - swimming = "swimming", - castle = "castle", - ruins = "castle", -} -poiClassRanks = { - hospital = 1, - railway = 2, - bus = 3, - attraction = 4, - harbor = 5, - college = 6, - school = 7, - stadium = 8, - zoo = 9, - town_hall = 10, - campsite = 11, - cemetery = 12, - park = 13, - library = 14, - police = 15, - post = 16, - golf = 17, - shop = 18, - grocery = 19, - fast_food = 20, - clothing_store = 21, - bar = 22, -} -waterClasses = Set({ "river", "riverbank", "stream", "canal", "drain", "ditch", "dock" }) -waterwayClasses = Set({ "stream", "river", "canal", "drain", "ditch" }) - --- Scan relations for use in ways - -function relation_scan_function(relation) - if relation:Find("type") == "boundary" and relation:Find("boundary") == "administrative" then - relation:Accept() - end -end - --- Process way tags - -function way_function(way) - local route = way:Find("route") - local highway = way:Find("highway") - local waterway = way:Find("waterway") - local water = way:Find("water") - local building = way:Find("building") - local natural = way:Find("natural") - local historic = way:Find("historic") - local landuse = way:Find("landuse") - local leisure = way:Find("leisure") - local amenity = way:Find("amenity") - local aeroway = way:Find("aeroway") - local railway = way:Find("railway") - local service = way:Find("service") - local sport = way:Find("sport") - local shop = way:Find("shop") - local tourism = way:Find("tourism") - local man_made = way:Find("man_made") - local boundary = way:Find("boundary") - local isClosed = way:IsClosed() - local housenumber = way:Find("addr:housenumber") - local write_name = false - local construction = way:Find("construction") - - -- Miscellaneous preprocessing - if way:Find("disused") == "yes" then - return - end - if - boundary ~= "" - and way:Find("protection_title") == "National Forest" - and way:Find("operator") == "United States Forest Service" - then - return - end - if highway == "proposed" then - return - end - if aerowayBuildings[aeroway] then - building = "yes" - aeroway = "" - end - if landuse == "field" then - landuse = "farmland" - end - if landuse == "meadow" and way:Find("meadow") == "agricultural" then - landuse = "farmland" - end - - -- Boundaries within relations - local admin_level = 11 - local isBoundary = false - while true do - local rel = way:NextRelation() - if not rel then - break - end - isBoundary = true - admin_level = math.min(admin_level, tonumber(way:FindInRelation("admin_level")) or 11) - end - - -- Boundaries in ways - if boundary == "administrative" then - admin_level = math.min(admin_level, tonumber(way:Find("admin_level")) or 11) - isBoundary = true - end - - -- Administrative boundaries - -- https://openmaptiles.org/schema/#boundary - if isBoundary and not (way:Find("maritime") == "yes") then - local mz = 0 - if admin_level >= 3 and admin_level < 5 then - mz = 4 - elseif admin_level >= 5 and admin_level < 7 then - mz = 8 - elseif admin_level == 7 then - mz = 10 - elseif admin_level >= 8 then - mz = 12 - end - - way:Layer("boundary", false) - way:AttributeNumeric("admin_level", admin_level) - way:MinZoom(mz) - -- disputed status (0 or 1). some styles need to have the 0 to show it. - local disputed = way:Find("disputed") - if disputed == "yes" then - way:AttributeNumeric("disputed", 1) - else - way:AttributeNumeric("disputed", 0) - end - end - - -- Roads ('transportation' and 'transportation_name', plus 'transportation_name_detail') - if highway ~= "" then - local access = way:Find("access") - if access == "private" or access == "no" then - return - end - - local h = highway - local minzoom = 99 - local layer = "transportation" - if majorRoadValues[highway] then - minzoom = 4 - end - if highway == "trunk" then - minzoom = 5 - elseif highway == "primary" then - minzoom = 7 - end - if mainRoadValues[highway] then - minzoom = 9 - end - if midRoadValues[highway] then - minzoom = 11 - end - if minorRoadValues[highway] then - h = "minor" - minzoom = 12 - end - if trackValues[highway] then - h = "track" - minzoom = 14 - end - if pathValues[highway] then - h = "path" - minzoom = 14 - end - if h == "service" then - minzoom = 12 - end - - -- Links (ramp) - local ramp = false - if linkValues[highway] then - splitHighway = split(highway, "_") - highway = splitHighway[1] - h = highway - ramp = true - minzoom = 11 - end - - -- Construction - if highway == "construction" then - if constructionValues[construction] then - h = construction .. "_construction" - if construction ~= "service" and construction ~= "track" then - minzoom = 11 - else - minzoom = 12 - end - else - h = "minor_construction" - minzoom = 14 - end - end - - -- Write to layer - if minzoom <= 14 then - way:Layer(layer, false) - way:MinZoom(minzoom) - SetZOrder(way) - way:Attribute("class", h) - SetBrunnelAttributes(way) - if ramp then - way:AttributeNumeric("ramp", 1) - end - - -- Service - if highway == "service" and service ~= "" then - way:Attribute("service", service) - end - - local oneway = way:Find("oneway") - if oneway == "yes" or oneway == "1" then - way:AttributeNumeric("oneway", 1) - end - if oneway == "-1" then - -- **** TODO - end - - -- Write names - if minzoom < 8 then - minzoom = 8 - end - if highway == "motorway" or highway == "trunk" then - way:Layer("transportation_name", false) - way:MinZoom(minzoom) - elseif h == "minor" or h == "track" or h == "path" or h == "service" then - way:Layer("transportation_name_detail", false) - way:MinZoom(minzoom) - else - way:Layer("transportation_name_mid", false) - way:MinZoom(minzoom) - end - SetNameAttributes(way) - way:Attribute("class", h) - way:Attribute("network", "road") -- **** could also be us-interstate, us-highway, us-state - if h ~= highway then - way:Attribute("subclass", highway) - end - local ref = way:Find("ref") - if ref ~= "" then - way:Attribute("ref", ref) - way:AttributeNumeric("ref_length", ref:len()) - end - end - end - - -- Railways ('transportation' and 'transportation_name', plus 'transportation_name_detail') - if railway ~= "" then - way:Layer("transportation", false) - way:Attribute("class", railway) - SetZOrder(way) - SetBrunnelAttributes(way) - if service ~= "" then - way:Attribute("service", service) - way:MinZoom(12) - else - way:MinZoom(9) - end - - way:Layer("transportation_name", false) - SetNameAttributes(way) - way:MinZoom(14) - way:Attribute("class", "rail") - end - - -- Pier - if man_made == "pier" then - way:Layer("transportation", isClosed) - SetZOrder(way) - way:Attribute("class", "pier") - SetMinZoomByArea(way) - end - - -- 'Ferry' - if route == "ferry" then - way:Layer("transportation", false) - way:Attribute("class", "ferry") - SetZOrder(way) - way:MinZoom(9) - SetBrunnelAttributes(way) - - way:Layer("transportation_name", false) - SetNameAttributes(way) - way:MinZoom(12) - way:Attribute("class", "ferry") - end - - -- 'Aeroway' - if aeroway ~= "" then - way:Layer("aeroway", isClosed) - way:Attribute("class", aeroway) - way:Attribute("ref", way:Find("ref")) - write_name = true - end - - -- 'aerodrome_label' - if aeroway == "aerodrome" then - way:LayerAsCentroid("aerodrome_label") - SetNameAttributes(way) - way:Attribute("iata", way:Find("iata")) - SetEleAttributes(way) - way:Attribute("icao", way:Find("icao")) - - local aerodrome = way:Find(aeroway) - local class - if aerodromeValues[aerodrome] then - class = aerodrome - else - class = "other" - end - way:Attribute("class", class) - end - - -- Set 'waterway' and associated - if waterwayClasses[waterway] and not isClosed then - if waterway == "river" and way:Holds("name") then - way:Layer("waterway", false) - else - way:Layer("waterway_detail", false) - end - if way:Find("intermittent") == "yes" then - way:AttributeNumeric("intermittent", 1) - else - way:AttributeNumeric("intermittent", 0) - end - way:Attribute("class", waterway) - SetNameAttributes(way) - SetBrunnelAttributes(way) - elseif waterway == "boatyard" then - way:Layer("landuse", isClosed) - way:Attribute("class", "industrial") - way:MinZoom(12) - elseif waterway == "dam" then - way:Layer("building", isClosed) - elseif waterway == "fuel" then - way:Layer("landuse", isClosed) - way:Attribute("class", "industrial") - way:MinZoom(14) - end - -- Set names on rivers - if waterwayClasses[waterway] and not isClosed then - if waterway == "river" and way:Holds("name") then - way:Layer("water_name", false) - else - way:Layer("water_name_detail", false) - way:MinZoom(14) - end - way:Attribute("class", waterway) - SetNameAttributes(way) - end - - -- Set 'building' and associated - if building ~= "" then - way:Layer("building", true) - SetBuildingHeightAttributes(way) - SetMinZoomByArea(way) - end - - -- Set 'housenumber' - if housenumber ~= "" then - way:LayerAsCentroid("housenumber", false) - way:Attribute("housenumber", housenumber) - end - - -- Set 'water' - if - natural == "water" - or natural == "bay" - or leisure == "swimming_pool" - or landuse == "reservoir" - or landuse == "basin" - or waterClasses[waterway] - then - if way:Find("covered") == "yes" or not isClosed then - return - end - local class = "lake" - if natural == "bay" then - class = "ocean" - elseif waterway ~= "" then - class = "river" - end - if class == "lake" and way:Find("wikidata") == "Q192770" then - return - end - if class == "ocean" and isClosed and (way:AreaIntersecting("ocean") / way:Area() > 0.98) then - return - end - way:Layer("water", true) - SetMinZoomByArea(way) - way:Attribute("class", class) - - if way:Find("intermittent") == "yes" then - way:Attribute("intermittent", 1) - end - -- we only want to show the names of actual lakes not every man-made basin that probably doesn't even have a name other than "basin" - -- examples for which we don't want to show a name: - -- https://www.openstreetmap.org/way/25958687 - -- https://www.openstreetmap.org/way/27201902 - -- https://www.openstreetmap.org/way/25309134 - -- https://www.openstreetmap.org/way/24579306 - if way:Holds("name") and natural == "water" and water ~= "basin" and water ~= "wastewater" then - way:LayerAsCentroid("water_name_detail") - SetNameAttributes(way) - SetMinZoomByArea(way) - way:Attribute("class", class) - end - - return -- in case we get any landuse processing - end - - -- Set 'landcover' (from landuse, natural, leisure) - local l = landuse - if l == "" then - l = natural - end - if l == "" then - l = leisure - end - if landcoverKeys[l] then - way:Layer("landcover", true) - SetMinZoomByArea(way) - way:Attribute("class", landcoverKeys[l]) - if l == "wetland" then - way:Attribute("subclass", way:Find("wetland")) - else - way:Attribute("subclass", l) - end - write_name = true - - -- Set 'landuse' - else - if l == "" then - l = amenity - end - if l == "" then - l = tourism - end - if landuseKeys[l] then - way:Layer("landuse", true) - way:Attribute("class", l) - if l == "residential" then - if way:Area() < ZRES8 ^ 2 then - way:MinZoom(8) - else - SetMinZoomByArea(way) - end - else - way:MinZoom(11) - end - write_name = true - end - end - - -- Parks - -- **** name? - if boundary == "national_park" then - way:Layer("park", true) - way:Attribute("class", boundary) - SetNameAttributes(way) - elseif leisure == "nature_reserve" then - way:Layer("park", true) - way:Attribute("class", leisure) - SetNameAttributes(way) - end - - -- POIs ('poi' and 'poi_detail') - local rank, class, subclass = GetPOIRank(way) - if rank then - WritePOI(way, class, subclass, rank) - return - end - - -- Catch-all - if (building ~= "" or write_name) and way:Holds("name") then - way:LayerAsCentroid("poi_detail") - SetNameAttributes(way) - if write_name then - rank = 6 - else - rank = 25 - end - way:AttributeNumeric("rank", rank) - end -end - --- Remap coastlines -function attribute_function(attr, layer) - if attr["featurecla"] == "Glaciated areas" then - return { subclass = "glacier" } - elseif attr["featurecla"] == "Antarctic Ice Shelf" then - return { subclass = "ice_shelf" } - elseif attr["featurecla"] == "Urban area" then - return { class = "residential" } - else - return { class = "ocean" } - end -end - --- ========================================================== --- Common functions - --- Write a way centroid to POI layer -function WritePOI(obj, class, subclass, rank) - local layer = "poi" - if rank > 4 then - layer = "poi_detail" - end - obj:LayerAsCentroid(layer) - SetNameAttributes(obj) - obj:AttributeNumeric("rank", rank) - obj:Attribute("class", class) - obj:Attribute("subclass", subclass) -end - --- Set name attributes on any object -function SetNameAttributes(obj) - local name = obj:Find("name"), iname - local main_written = name - -- if we have a preferred language, then write that (if available), and additionally write the base name tag - if preferred_language and obj:Holds("name:" .. preferred_language) then - iname = obj:Find("name:" .. preferred_language) - obj:Attribute(preferred_language_attribute, iname) - if iname ~= name and default_language_attribute then - obj:Attribute(default_language_attribute, name) - else - main_written = iname - end - else - obj:Attribute(preferred_language_attribute, name) - end - -- then set any additional languages - for i, lang in ipairs(additional_languages) do - iname = obj:Find("name:" .. lang) - if iname == "" then - iname = name - end - if iname ~= main_written then - obj:Attribute("name:" .. lang, iname) - end - end -end - --- Set ele and ele_ft on any object -function SetEleAttributes(obj) - local ele = obj:Find("ele") - if ele ~= "" then - local meter = math.floor(tonumber(ele) or 0) - local feet = math.floor(meter * 3.2808399) - obj:AttributeNumeric("ele", meter) - obj:AttributeNumeric("ele_ft", feet) - end -end - -function SetBrunnelAttributes(obj) - if obj:Find("bridge") == "yes" then - obj:Attribute("brunnel", "bridge") - elseif obj:Find("tunnel") == "yes" then - obj:Attribute("brunnel", "tunnel") - elseif obj:Find("ford") == "yes" then - obj:Attribute("brunnel", "ford") - end -end - --- Set minimum zoom level by area -function SetMinZoomByArea(way) - local area = way:Area() - if area > ZRES5 ^ 2 then - way:MinZoom(6) - elseif area > ZRES6 ^ 2 then - way:MinZoom(7) - elseif area > ZRES7 ^ 2 then - way:MinZoom(8) - elseif area > ZRES8 ^ 2 then - way:MinZoom(9) - elseif area > ZRES9 ^ 2 then - way:MinZoom(10) - elseif area > ZRES10 ^ 2 then - way:MinZoom(11) - elseif area > ZRES11 ^ 2 then - way:MinZoom(12) - elseif area > ZRES12 ^ 2 then - way:MinZoom(13) - else - way:MinZoom(14) - end -end - --- Calculate POIs (typically rank 1-4 go to 'poi' z12-14, rank 5+ to 'poi_detail' z14) --- returns rank, class, subclass -function GetPOIRank(obj) - local k, list, v, class, rank - - -- Can we find the tag? - for k, list in pairs(poiTags) do - if list[obj:Find(k)] then - v = obj:Find(k) -- k/v are the OSM tag pair - class = poiClasses[v] or k - rank = poiClassRanks[class] or 25 - return rank, class, v - end - end - - -- Catch-all for shops - local shop = obj:Find("shop") - if shop ~= "" then - return poiClassRanks["shop"], "shop", shop - end - - -- Nothing found - return nil, nil, nil -end - -function SetBuildingHeightAttributes(way) - local height = tonumber(way:Find("height"), 10) - local minHeight = tonumber(way:Find("min_height"), 10) - local levels = tonumber(way:Find("building:levels"), 10) - local minLevel = tonumber(way:Find("building:min_level"), 10) - - local renderHeight = BUILDING_FLOOR_HEIGHT - if height or levels then - renderHeight = height or (levels * BUILDING_FLOOR_HEIGHT) - end - local renderMinHeight = 0 - if minHeight or minLevel then - renderMinHeight = minHeight or (minLevel * BUILDING_FLOOR_HEIGHT) - end - - -- Fix upside-down buildings - if renderHeight < renderMinHeight then - renderHeight = renderHeight + renderMinHeight - end - - way:AttributeNumeric("render_height", renderHeight) - way:AttributeNumeric("render_min_height", renderMinHeight) -end - --- Implement z_order as calculated by Imposm --- See https://imposm.org/docs/imposm3/latest/mapping.html#wayzorder for details. -function SetZOrder(way) - local highway = way:Find("highway") - local layer = tonumber(way:Find("layer")) - local bridge = way:Find("bridge") - local tunnel = way:Find("tunnel") - local zOrder = 0 - if bridge ~= "" and bridge ~= "no" then - zOrder = zOrder + 10 - elseif tunnel ~= "" and tunnel ~= "no" then - zOrder = zOrder - 10 - end - if not (layer == nil) then - if layer > 7 then - layer = 7 - elseif layer < -7 then - layer = -7 - end - zOrder = zOrder + layer * 10 - end - local hwClass = 0 - -- See https://github.com/omniscale/imposm3/blob/53bb80726ca9456e4a0857b38803f9ccfe8e33fd/mapping/columns.go#L251 - if highway == "motorway" then - hwClass = 9 - elseif highway == "trunk" then - hwClass = 8 - elseif highway == "primary" then - hwClass = 6 - elseif highway == "secondary" then - hwClass = 5 - elseif highway == "tertiary" then - hwClass = 4 - else - hwClass = 3 - end - zOrder = zOrder + hwClass - way:ZOrder(zOrder) -end - --- ========================================================== --- Lua utility functions - -function split(inputstr, sep) -- https://stackoverflow.com/a/7615129/4288232 - if sep == nil then - sep = "%s" - end - local t = {} - i = 1 - for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do - t[i] = str - i = i + 1 - end - return t -end - --- vim: tabstop=2 shiftwidth=2 noexpandtab diff --git a/internal/buildthirdpartycontainers/buildthirdpartycontainers.go b/internal/buildthirdpartycontainers/buildthirdpartycontainers.go index 6bdc92b..bd3a865 100644 --- a/internal/buildthirdpartycontainers/buildthirdpartycontainers.go +++ b/internal/buildthirdpartycontainers/buildthirdpartycontainers.go @@ -2,6 +2,7 @@ package buildthirdpartycontainers import ( "fmt" + "path/filepath" "github.com/lambdajack/sequentially-generate-planet-mbtiles/pkg/execute" ) @@ -10,10 +11,14 @@ var ContainerTilemakerName = "sequential-tilemaker" var ContainerTippecanoeName = "sequential-tippecanoe" var ContainerOsmiumName = "sequential-osmium" +var TilemakerPath = filepath.Clean("./third_party/tilemaker/Dockerfile") +var TippecanoePath = filepath.Clean("./third_party/tippecanoe/Dockerfile") +var OsmiumPath = filepath.Clean("./build/osmium/Dockerfile") + func BuildContainers() { - execute.OutputToConsole(fmt.Sprintf("docker build -t %v ./tilemaker", ContainerTilemakerName)) + execute.OutputToConsole(fmt.Sprintf("docker build -t %s -f %s third_party/tilemaker", ContainerTilemakerName, TilemakerPath)) - execute.OutputToConsole(fmt.Sprintf("docker build -t %v ./tippecanoe", ContainerTippecanoeName)) + execute.OutputToConsole(fmt.Sprintf("docker build -t %s -f %s third_party/tippecanoe", ContainerTippecanoeName, TippecanoePath)) - execute.OutputToConsole(fmt.Sprintf("docker build -t %v build/osmium", ContainerOsmiumName)) + execute.OutputToConsole(fmt.Sprintf("docker build -t %s -f %s third_party", ContainerOsmiumName, OsmiumPath)) } diff --git a/internal/clonerepos/clonerepos.go b/internal/clonerepos/clonerepos.go deleted file mode 100644 index c9a7474..0000000 --- a/internal/clonerepos/clonerepos.go +++ /dev/null @@ -1,22 +0,0 @@ -package clonerepos - -import ( - "fmt" - - "github.com/lambdajack/sequentially-generate-planet-mbtiles/pkg/clonerepo" - "github.com/lambdajack/sequentially-generate-planet-mbtiles/pkg/stderrorhandler" -) - -func CloneRepos() error { - reposToClone := [...]string{"systemed/tilemaker", "mapbox/tippecanoe"} - - for _, repo := range reposToClone { - err := clonerepo.CloneRepo(repo) - if err != nil { - stderrorhandler.StdErrorHandler(fmt.Sprintf("clonerepos.go | Failed to clone %s. Unable to proceed...", repo), err) - panic(err) - } - } - - return nil -} diff --git a/internal/folders/folders.go b/internal/folders/folders.go index 5f88531..48cb55d 100644 --- a/internal/folders/folders.go +++ b/internal/folders/folders.go @@ -13,12 +13,17 @@ var Pwd, _ = os.Getwd() var ConfigsFolder = formatFolderString(Pwd + "/" + "configs") -var TilemakerConfigFile = formatFolderString(Pwd + "/" + "configs" + "/" + "tilemaker" + "/" + "config.json") -var TilemakerProcessFile = formatFolderString(Pwd + "/" + "configs" + "/" + "tilemaker" + "/" + "process.lua") +var TilemakerConfigFile = formatFolderString(Pwd + "/" + "third_party" + "/" + "tilemaker" + "/" + "resources" + "/" + "config-openmaptiles.json") +var TilemakerProcessFile = formatFolderString(Pwd + "/" + "third_party" + "/" + "tilemaker" + "/" + "resources" + "/" + "process-openmaptiles.lua") var DataFolder = formatFolderString(Pwd + "/" + "data") var CoastlineFolder = formatFolderString(DataFolder + "/" + "coastline") + var LandcoverFolder = formatFolderString(DataFolder + "/" + "landcover") +var LandCoverUrbanDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_urban_areas") +var LandCoverIceShelvesDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_antarctic_ice_shelves_polys") +var LandCoverGlaciatedDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_glaciated_areas") + var PbfFolder = formatFolderString(DataFolder + "/" + "pbf") var PbfSlicesFolder = formatFolderString(PbfFolder + "/" + "slices") var PbfQuadrantSlicesFolder = formatFolderString(PbfSlicesFolder + "/" + "quadrants") @@ -30,6 +35,9 @@ func SetupFolderStructure() { DataFolder = formatFolderString(config.Config.DataDir) CoastlineFolder = formatFolderString(DataFolder + "/" + "coastline") LandcoverFolder = formatFolderString(DataFolder + "/" + "landcover") + LandCoverUrbanDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_urban_areas") + LandCoverIceShelvesDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_antarctic_ice_shelves_polys") + LandCoverGlaciatedDepth = formatFolderString(LandcoverFolder + "/" + "ne_10m_glaciated_areas") PbfFolder = formatFolderString(DataFolder + "/" + "pbf") PbfSlicesFolder = formatFolderString(PbfFolder + "/" + "slices") PbfQuadrantSlicesFolder = formatFolderString(PbfSlicesFolder + "/" + "quadrants") @@ -45,7 +53,7 @@ func SetupFolderStructure() { TilemakerProcessFile = formatFolderString(config.Config.TilemakerProcess) } - allFolders := [...]*string{&DataFolder, &CoastlineFolder, &LandcoverFolder, &PbfFolder, &PbfSlicesFolder, &PbfQuadrantSlicesFolder, &MbtilesFolder, &MbtilesMergedFolder} + allFolders := [...]*string{&DataFolder, &CoastlineFolder, &LandcoverFolder, &PbfFolder, &PbfSlicesFolder, &PbfQuadrantSlicesFolder, &MbtilesFolder, &MbtilesMergedFolder, &LandCoverUrbanDepth, &LandCoverIceShelvesDepth, &LandCoverGlaciatedDepth} for _, folder := range allFolders { err := os.MkdirAll(*folder, os.ModePerm) diff --git a/internal/unzippolygons/unzippolygons.go b/internal/unzippolygons/unzippolygons.go index e494f20..c45ae91 100644 --- a/internal/unzippolygons/unzippolygons.go +++ b/internal/unzippolygons/unzippolygons.go @@ -20,7 +20,11 @@ func UnzipPolygons() { landCoverIceShelves := unzipInformation{srcPath: "ne_10m_antarctic_ice_shelves_polys.zip", destPath: folders.LandcoverFolder} landCoverGlaciated := unzipInformation{srcPath: "ne_10m_glaciated_areas.zip", destPath: folders.LandcoverFolder} - fileNames := [...]*unzipInformation{&waterPolygons, &landCoverUrban, &landCoverIceShelves, &landCoverGlaciated} + urbanDepth := unzipInformation{srcPath: "ne_10m_urban_areas.zip", destPath: folders.LandCoverUrbanDepth} + iceShelves := unzipInformation{srcPath: "ne_10m_antarctic_ice_shelves_polys.zip", destPath: folders.LandCoverIceShelvesDepth} + glaciated := unzipInformation{srcPath: "ne_10m_glaciated_areas.zip", destPath: folders.LandCoverGlaciatedDepth} + + fileNames := [...]*unzipInformation{&waterPolygons, &landCoverUrban, &landCoverIceShelves, &landCoverGlaciated, &urbanDepth, &iceShelves, &glaciated} for i, zipFile := range fileNames { fileNames[i].srcPath = filepath.Clean(folders.DataFolder + "/" + zipFile.srcPath) diff --git a/pkg/clonerepo/clonerepo.go b/pkg/clonerepo/clonerepo.go deleted file mode 100644 index 0b92247..0000000 --- a/pkg/clonerepo/clonerepo.go +++ /dev/null @@ -1,42 +0,0 @@ -package clonerepo - -import ( - "fmt" - "os" - "os/exec" - "strings" - - "github.com/lambdajack/sequentially-generate-planet-mbtiles/pkg/stderrorhandler" -) - -func CloneRepo(repoToClone string) error { - // Ensure a string was provided - if repoToClone == "" { - panic("lambdajack/pkg/clonerepo | Received an empty string (no repo to clone)\n") - } - - // Check to see if the repo dir already exists, and skip if so. - splitPath := strings.Split(repoToClone, "/") - if _, err := os.Stat(splitPath[len(splitPath)-1]); !os.IsNotExist(err) { - return stderrorhandler.StdErrorHandler(fmt.Sprintf("clonerepo.go | %v already exists. Skipping clone.\n", splitPath[len(splitPath)-1]), err) - - } - - // Attempt to validate the url to clone the repo from and correct it if necessary. - if strings.HasPrefix(repoToClone, "github.com/") { - repoToClone = "https://" + repoToClone - } - if !strings.HasPrefix(repoToClone, "https://github.com/") && !strings.HasSuffix(repoToClone, "http://github.com/") { - repoToClone = "https://github.com/" + repoToClone - } - - // Execute git clone repoUrl - cmd := exec.Command("git", "clone", repoToClone) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Start(); err != nil { - return stderrorhandler.StdErrorHandler("clonerepo.go | Failed to execute git clone command", err) - } - cmd.Wait() - return nil -} diff --git a/pkg/generatembtiles/generatembtiles.go b/pkg/generatembtiles/generatembtiles.go index 67a52a0..4d41cdc 100644 --- a/pkg/generatembtiles/generatembtiles.go +++ b/pkg/generatembtiles/generatembtiles.go @@ -24,9 +24,9 @@ func GenerateMbTiles(inputFile, outputFile, pbfFolder, mbtilesFolder, coastlineF var generateMbtilesCmd string if processPath == configPath { - generateMbtilesCmd = fmt.Sprintf("docker run -v %s:/pbf -v %s:/mbtiles -v %s:/coastline -v %v:/config %s --input /pbf/%s --output /mbtiles/%s --config /config/%s --process /config/%s", pbfFolder, mbtilesFolder, coastlineFolder, configPath, containerName, inputFile, outputFile, configFile, processFile) + generateMbtilesCmd = fmt.Sprintf("docker run --rm -v %s:/pbf -v %s:/mbtiles -v %s:/coastline -v %v:/config %s --input /pbf/%s --output /mbtiles/%s --config /config/%s --process /config/%s", pbfFolder, mbtilesFolder, coastlineFolder, configPath, containerName, inputFile, outputFile, configFile, processFile) } else { - generateMbtilesCmd = fmt.Sprintf("docker run -v %s:/pbf -v %s:/mbtiles -v %s:/coastline -v %v:/config -v %v:/process %s --input /pbf/%s --output /mbtiles/%s --config /config/%s --process /process/%s", pbfFolder, mbtilesFolder, coastlineFolder, configPath, processPath, containerName, inputFile, outputFile, configFile, processFile) + generateMbtilesCmd = fmt.Sprintf("docker run --rm -v %s:/pbf -v %s:/mbtiles -v %s:/coastline -v %v:/config -v %v:/process %s --input /pbf/%s --output /mbtiles/%s --config /config/%s --process /process/%s", pbfFolder, mbtilesFolder, coastlineFolder, configPath, processPath, containerName, inputFile, outputFile, configFile, processFile) } err := execute.OutputToConsole(generateMbtilesCmd) diff --git a/release/v2.1.0-sequentially-generate-planet-mbtiles.exe b/release/v2.2.0-sequentially-generate-planet-mbtiles similarity index 61% rename from release/v2.1.0-sequentially-generate-planet-mbtiles.exe rename to release/v2.2.0-sequentially-generate-planet-mbtiles index e8850e6..25f080b 100755 Binary files a/release/v2.1.0-sequentially-generate-planet-mbtiles.exe and b/release/v2.2.0-sequentially-generate-planet-mbtiles differ diff --git a/release/v2.2.0-sequentially-generate-planet-mbtiles.exe b/release/v2.2.0-sequentially-generate-planet-mbtiles.exe new file mode 100755 index 0000000..25f080b Binary files /dev/null and b/release/v2.2.0-sequentially-generate-planet-mbtiles.exe differ diff --git a/third_party/libosmium b/third_party/libosmium new file mode 160000 index 0000000..04506b2 --- /dev/null +++ b/third_party/libosmium @@ -0,0 +1 @@ +Subproject commit 04506b22fca3e9660d65763c09755a99f3d7b985 diff --git a/third_party/osmium-tool b/third_party/osmium-tool new file mode 160000 index 0000000..4a21513 --- /dev/null +++ b/third_party/osmium-tool @@ -0,0 +1 @@ +Subproject commit 4a215130453beb9b3b15c16b095e8126195c39ba diff --git a/third_party/tilemaker b/third_party/tilemaker new file mode 160000 index 0000000..b90347b --- /dev/null +++ b/third_party/tilemaker @@ -0,0 +1 @@ +Subproject commit b90347b2a4fd475470b9870b8e44e2829d8e4d6d diff --git a/third_party/tippecanoe b/third_party/tippecanoe new file mode 160000 index 0000000..18e53cd --- /dev/null +++ b/third_party/tippecanoe @@ -0,0 +1 @@ +Subproject commit 18e53cd7fb9ae6be8b89d817d69d3ce06f30eb9d