├── .eslintrc.json
├── .github
└── workflows
│ └── node.js.yml
├── .gitignore
├── LICENSE
├── README.md
├── build
├── glsl-plugin.js
└── rollup.config.js
├── dist
└── tile-setter.js
├── examples
├── circles
│ ├── globe.svg
│ ├── index.html
│ ├── light-wells.json
│ ├── main.js
│ ├── main.min.js
│ ├── ne_50m_geography_regions_elevation_points.json
│ └── styles.css
├── geojson
│ ├── geojsonGeometriesLines.geojson
│ ├── geojsonGeometriesPoints.geojson
│ ├── globe.svg
│ ├── index.html
│ ├── klokantech-basic-style-geojson-sampler.json
│ ├── klokantech-basic-style-geojson-usStates.json
│ ├── main.js
│ ├── main.min.js
│ ├── styles.css
│ └── us-states.geojson
├── klokan-basic
│ ├── globe.svg
│ ├── index.html
│ ├── klokan-fill-line.json
│ ├── klokantech-basic-style.json
│ ├── main.js
│ ├── main.min.js
│ └── styles.css
├── macrostrat
│ ├── globe.svg
│ ├── index.html
│ ├── light-macrostrat.json
│ ├── macrostrat-only.json
│ ├── main.js
│ ├── main.min.js
│ └── styles.css
├── mapbox-streets
│ ├── globe.svg
│ ├── index.html
│ ├── main.js
│ ├── main.min.js
│ ├── streets-v8-noInteractive.json
│ └── styles.css
├── rollup.config.js
└── set-center-zoom
│ ├── globe.svg
│ ├── index.html
│ ├── klokantech-basic-style.json
│ ├── main.js
│ ├── main.min.js
│ └── styles.css
├── package-lock.json
├── package.json
└── src
├── bounds.js
├── caches.js
├── coords.js
├── feature-coords.js
├── grid.js
├── index.js
├── metric.js
├── params.js
├── projection.js
├── raster.js
├── renderer.js
├── selection.js
├── sources.js
└── tile-coords.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "globeletjs"
3 | }
4 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [12.x, 14.x, 16.x]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | cache: 'npm'
29 | - name: Reconfigure git to use HTTP authentication
30 | # https://github.com/actions/setup-node/issues/214#issuecomment-842538631
31 | run: >
32 | git config --global url."https://github.com/".insteadOf
33 | ssh://git@github.com/
34 | - run: npm ci
35 | - run: npm run build --if-present
36 | - run: npm test
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 | *.sql
27 | *.sqlite
28 |
29 | # OS generated files #
30 | ######################
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | ehthumbs.db
37 | Thumbs.db
38 |
39 | # Other #
40 | ######################
41 | node_modules/
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021-2022 Jeshurun Hembd, Ananya Roy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tile-setter
2 |
3 | 
4 |
5 | Tiled vector map powered by a lightweight WebGL renderer
6 |
7 | Rendering is guided by a [MapLibre style document][MapLibre]. See a simple
8 | [example][] using a style from [OpenMapTiles][].
9 |
10 | [MapLibre]: https://maplibre.org/maplibre-gl-js-docs/style-spec/
11 | [example]: https://globeletjs.github.io/tile-setter/examples/klokan-basic/index.html
12 | [OpenMapTiles]: https://openmaptiles.org/styles/
13 |
14 | ## Installation
15 | tile-setter is provided as an ESM import
16 | ```javascript
17 | import * as tileSetter from 'tile-setter';
18 | ```
19 |
20 | ## Syntax
21 | ```javascript
22 | const map = tileSetter.init(params);
23 | ```
24 |
25 | ## Parameters
26 | The supplied parameters object has the following properties:
27 | - `.context` (REQUIRED): A WebGL context wrapper, as created by the
28 | [yawgl][] method `initContext`
29 | - `.framebuffer`: A framebuffer object, as created by `context.initFramebuffer`,
30 | to which the map will be rendered. If not supplied, the map will be rendered
31 | to `context.gl.canvas`
32 | - `.center`: The initial center of the map, given as [longitude, latitude]
33 | in degrees. Default: [0.0, 0.0]
34 | - `.zoom`: The initial zoom of the map. Default: 4
35 | - `.style` (REQUIRED): A link to a MapLibre style document
36 | - `.mapboxToken`: Your API token for Mapbox services (if needed)
37 | - `.clampY`: If true (default), the scale and Y-coordinate of the map will be
38 | adjusted to ensure the viewport is not crossing the North or South limits of
39 | the world map
40 | - `.units`: The units that will be used for subsequent calls to
41 | `map.setCenterZoom` and `map.select`. Possible values:
42 | - "xy": Assumes an input [x, y] in global Web Mercator coordinates,
43 | with [0, 0] at the top left corner of the map
44 | - "radians": Assumes an input [longitude, latitude] in radians
45 | - "degrees" (DEFAULT): Assumes input [longitude, latitude] in degrees
46 | - `.projScale`: A Boolean flag indicating whether to scale style dimensions
47 | by the ratio of the projection scale at each feature, vs. the projection scale
48 | at the camera position
49 |
50 | [yawgl]: https://github.com/GlobeletJS/yawgl
51 |
52 | ## API
53 | The returned map object exposes the following properties and methods:
54 | - `gl`: A link back to the WebGL rendering context (supplied on init)
55 | - `projection`: The projection from the `units` specified on initialization
56 | to global Web Mercator coordinates. Includes 3 methods:
57 | - `projection.forward(point)`: Converts an Array of 2 coordinates from
58 | input units to global Web Mercator [X, Y]
59 | - `projection.inverse(point)`: Converts an Array of 2 coordinates from
60 | global Web Mercator [X, Y] to input units
61 | - `projection.scale(point)`: Return value scales a (differential) distance
62 | in the input coordinates to a distance in global Web Mercator coordinates
63 | - `setTransform(transform)`: Sets the map transform, where `transform` has
64 | properties `{ k, y, x }`, defined as in the [d3-zoom transform][]. Actual
65 | transform for rendering will be rounded to ensure tile pixels align with
66 | screen pixels. Return value: a flag indicating whether the transform has
67 | changed
68 | - `setCenterZoom(center, zoom)`: Sets the map transform to position
69 | the map at the supplied center and zoom. Parameters:
70 | - `center`: An array of `[x, y]` or `[longitude, latitude]` coordinates,
71 | in the units specified on initialization
72 | - `zoom`: The desired zoom level
73 | - `getViewport()`: Returns the current viewport dimensions in CSS
74 | pixels, as a 2-element array
75 | - `getTransform()`: Returns a copy of the current transform
76 | - `getZoom()`: Returns the transform scale converted to a zoom level.
77 | Zoom calculation assumes 512px tiles
78 | - `getCamPos()`: Returns the position of the camera within the current map,
79 | expressed as an array of 2 floats between 0 and 1, with `[0, 0]`
80 | corresponding to the top left corner of the map
81 | - `getScale()`: Returns the scale of the whole map relative to the current
82 | viewport dimensions, as an array of two floats
83 | - `localToGlobal([x, y])`: converts pixel coordinates [x, y] within
84 | the current map to global XY
85 | - `promise`: A Promise that resolves to an updated API, after the MapLibre
86 | style document (supplied on init) is fully loaded and parsed
87 | - `draw()`: Returns `null` until `map.promise` resolves
88 | - `select()`: Returns `null` until `map.promise` resolves
89 |
90 | All the above properties and methods are available immediately upon
91 | initialization (*synchronously*). After `map.promise` resolves, the following
92 | methods are updated or added:
93 | - `draw(params)`: Draws the map for the supplied transform. Returns a
94 | fractional number (from 0.0 to 1.0) indicating the loading status, expressed
95 | as a fraction of the tiles that are needed to render the current view.
96 | The `params` object has the following properties:
97 | - `.pixRatio`: the number of renderbuffer pixels per CSS pixel, e.g., as
98 | as returned by [window.devicePixelRatio][]. Default: 1.0
99 | - `.dzScale`: An additional scalar to be multiplied with the camera
100 | projection scale, if `projScale === true` on initialization. This can
101 | be used to account for the internal zoom being different from the
102 | requested—for example, if after `.setCenterZoom(center, zoom)`,
103 | we find that `api.getZoom() !== zoom`, due to transform rounding or
104 | `clampY === true`
105 | - `select(params)`: Finds map features near a given location. The `params`
106 | object has the following properties:
107 | - `layer` (String): The name of the layer in the MapLibre style document
108 | containing the features to be queried
109 | - `point` (Array): The location to be queried, specified as a 2-element
110 | Array of coordinates, in the units specified on initialization
111 | - `radius` (Number): The maximum pixel distance between `point` and the
112 | selected feature. Default: 5
113 | - `hideLayer(layer)`: Turns off rendering for the given layer
114 | - `showLayer(layer)`: Turns on rendering for the given layer
115 |
116 | [d3-zoom transform]: https://github.com/d3/d3-zoom/blob/master/README.md#zoom-transforms
117 | [window.devicePixelRatio]: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
118 |
--------------------------------------------------------------------------------
/build/glsl-plugin.js:
--------------------------------------------------------------------------------
1 | // Plugin for .glsl and .js.glsl files
2 | export function glsl() {
3 | return { transform };
4 | }
5 |
6 | function transform(source, id) {
7 | // Confirm filename extension is .glsl
8 | if (/\.glsl$/.test(id) === false) return;
9 |
10 | const transFunc = (/\.js\.glsl$/.test(id))
11 | ? tagTemplateLiteral
12 | : templateLiteral;
13 |
14 | return {
15 | code: transFunc(source),
16 | map: { mappings: '' }, // No map
17 | };
18 | }
19 |
20 | function templateLiteral(source) {
21 | // Export as a constant string, but template literal preserves line breaks
22 | return "export default `" + source + "`";
23 | }
24 |
25 | const glslInterp = `function glslInterp(strings, ...expressions) {
26 | return strings.reduce( (acc, val, i) => acc + expressions[i-1]() + val );
27 | }
28 | `;
29 |
30 | function tagTemplateLiteral(source) {
31 | // Export as a function that will interpolate values from an args object
32 | // NOTE: args MUST be defined where the function is called, with
33 | // property names matching the variables in the *.js.glsl file
34 | return glslInterp + "export default (args) => glslInterp`" + source + "`";
35 | }
36 |
--------------------------------------------------------------------------------
/build/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve';
2 | import commonjs from '@rollup/plugin-commonjs'; // Yuck. Needed for @turf!!
3 | import { glsl } from "./glsl-plugin.js";
4 | import pkg from "../package.json";
5 |
6 | export default {
7 | input: 'src/index.js',
8 | plugins: [
9 | glsl(),
10 | resolve(),
11 | commonjs(),
12 | ],
13 | output: {
14 | file: pkg.main,
15 | //sourcemap: 'inline',
16 | format: 'esm',
17 | name: pkg.name
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/examples/circles/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/circles/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
20 |
21 |
22 | Show wells
23 | Hide wells
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/circles/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as d3 from "d3";
3 | import * as tileMap from "../../";
4 |
5 | export function main() {
6 | const canvas = document.getElementById("mapCanvas");
7 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
8 | const context = yawgl.initContext(canvas);
9 |
10 | tileMap.init({
11 | context,
12 | center: [-100, 31],
13 | zoom: 6,
14 | style: "./light-wells.json",
15 | // eslint-disable-next-line max-len
16 | mapboxToken: "pk.eyJ1IjoiamhlbWJkIiwiYSI6ImNqcHpueHpyZjBlMjAzeG9kNG9oNzI2NTYifQ.K7fqhk2Z2YZ8NIV94M-5nA",
17 | units: "xy",
18 | projScale: true,
19 | }).promise.then(api => setup(api, canvas))
20 | .catch(console.log);
21 | }
22 |
23 | function setup(api, canvas) {
24 | const viewport = api.getViewport();
25 |
26 | const { k, x, y } = api.getTransform();
27 | let transform = d3.zoomIdentity
28 | .translate(x, y)
29 | .scale(k);
30 |
31 | const zoomer = d3.zoom()
32 | .scaleExtent([1 << 10, 1 << 26])
33 | .extent([[0, 0], viewport])
34 | .translateExtent([[-Infinity, -0.5], [Infinity, 0.5]])
35 | .on("zoom", (event) => {
36 | transform = event.transform;
37 | });
38 |
39 | d3.select(canvas)
40 | .call(zoomer)
41 | .call(zoomer.transform, transform);
42 |
43 | let mouse = [];
44 | d3.select(canvas).on("mousemove", (event) => {
45 | mouse = d3.pointer(event);
46 | });
47 |
48 | document.getElementById("showWells")
49 | .addEventListener("click", () => api.showLayer("twdb-groundwater-v2"));
50 | document.getElementById("hideWells")
51 | .addEventListener("click", () => api.hideLayer("twdb-groundwater-v2"));
52 |
53 | const loadStatus = document.getElementById("loadStatus");
54 | const infoBox = document.getElementById("info");
55 |
56 | requestAnimationFrame(animate);
57 | function animate() {
58 | const pixRatio = window.devicePixelRatio;
59 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
60 | api.setTransform(transform);
61 | const percent = api.draw({ pixRatio }) * 100;
62 | loadStatus.innerHTML = (percent < 100)
63 | ? "Loading: " + percent.toFixed(0) + "%"
64 | : "Complete! " + percent.toFixed(0) + "%";
65 | loadStatus.innerHTML += "
Mouse: " + mouse;
66 | const point = api.localToGlobal(mouse);
67 | loadStatus.innerHTML += "
Global: " + point.map(n => n.toFixed(4));
68 |
69 | const feature = api.select({
70 | layer: "twdb-groundwater-v2",
71 | point, // : api.localToGlobal(mouse),
72 | radius: 3,
73 | }) || api.select({
74 | layer: "mountains",
75 | point,
76 | radius: 6,
77 | });
78 | infoBox.innerHTML = "
" + JSON.stringify(feature, null, 2) + " ";
79 |
80 | requestAnimationFrame(animate);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/examples/circles/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | .container {
11 | display: flex;
12 | flex-direction: row;
13 | height: 100vh;
14 | }
15 | #main {
16 | flex: auto;
17 | height: 100%;
18 | position: relative;
19 | }
20 | #right {
21 | flex: none;
22 | width: 600px;
23 | height: 100%;
24 | position: relative;
25 | }
26 | pre {
27 | white-space: pre-wrap;
28 | word-wrap: break-word;
29 | }
30 | #mapCanvas {
31 | width: 100%;
32 | height: 100%;
33 | display: block;
34 | background-color: gray;
35 | position: relative;
36 | }
37 | .attribution {
38 | background: rgba(255, 255, 255, 0.8);
39 | position: absolute;
40 | bottom: 0;
41 | right: 0;
42 | padding: 0 4px 0 4px;
43 | }
44 | #loadStatus {
45 | position: absolute;
46 | top: 0;
47 | right: 0;
48 | width: 20ch;
49 | text-align: right;
50 | background: rgba(60, 60, 60, 0.5);
51 | color: white;
52 | padding: 0 4px 0 4px;
53 | }
54 |
--------------------------------------------------------------------------------
/examples/geojson/geojsonGeometriesLines.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type":"FeatureCollection",
3 | "features":[
4 | {"type":"Feature",
5 | "geometry":{
6 | "type":"LineString",
7 | "coordinates":[[40,-20],[80,20]]
8 | },
9 | "properties":{
10 | "name":"LineString"
11 | }
12 | },
13 | {"type":"Feature",
14 | "geometry":{
15 | "type":"LineString",
16 | "coordinates":[[40,20],[80,-20]]
17 | },
18 | "properties":{
19 | "name": "LineString"
20 | }
21 | },
22 | {"type":"Feature",
23 | "geometry":{
24 | "type":"Polygon",
25 | "coordinates":[[[-50,-10],[-40,10],[-30,-10],[-50,-10]]]
26 | },
27 | "properties":{
28 | "name": "Polygon"
29 | }
30 | },
31 | {"type":"Feature",
32 | "geometry":
33 | {"type":"MultiLineString",
34 | "coordinates":[[[-10,-7.5],[-10,7.5]],[[10,-7.5],[10,7.5]],[[-7.5,-10],[7.5,-10]],[[-7.5,10],[7.5,10]]]
35 | },
36 | "properties":{
37 | "name":"MultiLineString"
38 | }
39 | },
40 | {"type":"Feature",
41 | "geometry":{
42 | "type":"MultiPolygon",
43 | "coordinates":[[[[-50,60],[-50,80],[-30,80],[-30,60],[-50,60]]],[[[-20,60],[-20,80],[0,80],[0,60],[-20,60]]],[[[10,60],[10,80],[30,80],[30,60],[10,60]]]]
44 | },
45 | "properties":{
46 | "name":"MultiPolygon"
47 | }
48 | }
49 | ]}
50 |
--------------------------------------------------------------------------------
/examples/geojson/geojsonGeometriesPoints.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type":"FeatureCollection",
3 | "features":[
4 | {"type":"Feature",
5 | "geometry":{
6 | "type":"Point",
7 | "coordinates":[0,0]
8 | },
9 | "properties":{
10 | "name": "Point"
11 | }
12 | },
13 | {"type":"Feature",
14 | "geometry":{
15 | "type":"MultiPoint",
16 | "coordinates":[[5,0],[5,1]]
17 | },
18 | "properties":{
19 | "name":"MultiPoint"
20 | }
21 | }
22 | ]}
23 |
--------------------------------------------------------------------------------
/examples/geojson/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/geojson/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
tile-setter - beta
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/geojson/klokantech-basic-style-geojson-sampler.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Basic",
4 | "metadata": {
5 | "mapbox:autocomposite": false,
6 | "mapbox:type": "template",
7 | "maputnik:renderer": "mbgljs",
8 | "openmaptiles:version": "3.x",
9 | "openmaptiles:mapbox:owner": "openmaptiles",
10 | "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
11 | },
12 | "sources": {
13 | "openmaptiles": {
14 | "type": "vector",
15 | "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=mrAq6zQEFxOkanukNbGm"
16 | },
17 | "geojsonSamplerPoints": {
18 | "type": "geojson",
19 | "data": "./geojsonGeometriesPoints.geojson",
20 | "minzoom" :0,
21 | "maxzoom" :14,
22 | "tileSize": 512
23 | },
24 | "geojsonSamplerLines": {
25 | "type": "geojson",
26 | "data": "./geojsonGeometriesLines.geojson",
27 | "minzoom" :0,
28 | "maxzoom" :14,
29 | "tileSize": 512
30 | }
31 | },
32 | "glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=mrAq6zQEFxOkanukNbGm",
33 | "layers": [{
34 | "id": "background",
35 | "paint": {
36 | "background-color": "hsl(47, 26%, 88%)"
37 | },
38 | "type": "background"
39 | }, {
40 | "filter": ["all", ["==", "$type", "Polygon"],
41 | ["in", "class", "residential", "suburb", "neighbourhood"]
42 | ],
43 | "id": "landuse-residential",
44 | "layout": {
45 | "visibility": "visible"
46 | },
47 | "paint": {
48 | "fill-color": "hsl(47, 13%, 86%)",
49 | "fill-opacity": 0.7
50 | },
51 | "source": "openmaptiles",
52 | "source-layer": "landuse",
53 | "type": "fill"
54 | }, {
55 | "filter": ["==", "class", "grass"],
56 | "id": "landcover_grass",
57 | "paint": {
58 | "fill-color": "hsl(82, 46%, 72%)",
59 | "fill-opacity": 0.45
60 | },
61 | "source": "openmaptiles",
62 | "source-layer": "landcover",
63 | "type": "fill"
64 | }, {
65 | "filter": ["==", "class", "wood"],
66 | "id": "landcover_wood",
67 | "paint": {
68 | "fill-color": "hsl(82, 46%, 72%)",
69 | "fill-opacity": {
70 | "base": 1,
71 | "stops": [
72 | [8, 0.6],
73 | [22, 1]
74 | ]
75 | }
76 | },
77 | "source": "openmaptiles",
78 | "source-layer": "landcover",
79 | "type": "fill"
80 | }, {
81 | "filter": ["all", ["==", "$type", "Polygon"],
82 | ["!=", "intermittent", 1]
83 | ],
84 | "id": "water",
85 | "paint": {
86 | "fill-color": "hsl(205, 56%, 73%)"
87 | },
88 | "source": "openmaptiles",
89 | "source-layer": "water",
90 | "type": "fill",
91 | "layout": {
92 | "visibility": "visible"
93 | }
94 | }, {
95 | "filter": ["all", ["==", "$type", "Polygon"],
96 | ["==", "intermittent", 1]
97 | ],
98 | "id": "water_intermittent",
99 | "paint": {
100 | "fill-color": "hsl(205, 56%, 73%)",
101 | "fill-opacity": 0.7
102 | },
103 | "source": "openmaptiles",
104 | "source-layer": "water",
105 | "type": "fill",
106 | "layout": {
107 | "visibility": "visible"
108 | }
109 | }, {
110 | "filter": ["==", "subclass", "ice_shelf"],
111 | "id": "landcover-ice-shelf",
112 | "layout": {
113 | "visibility": "visible"
114 | },
115 | "paint": {
116 | "fill-color": "hsl(47, 26%, 88%)",
117 | "fill-opacity": 0.8
118 | },
119 | "source": "openmaptiles",
120 | "source-layer": "landcover",
121 | "type": "fill"
122 | }, {
123 | "filter": ["==", "subclass", "glacier"],
124 | "id": "landcover-glacier",
125 | "layout": {
126 | "visibility": "visible"
127 | },
128 | "paint": {
129 | "fill-color": "hsl(47, 22%, 94%)",
130 | "fill-opacity": {
131 | "base": 1,
132 | "stops": [
133 | [0, 1],
134 | [8, 0.5]
135 | ]
136 | }
137 | },
138 | "source": "openmaptiles",
139 | "source-layer": "landcover",
140 | "type": "fill"
141 | }, {
142 | "filter": ["all", ["in", "class", "sand"]],
143 | "id": "landcover_sand",
144 | "metadata": {},
145 | "paint": {
146 | "fill-antialias": false,
147 | "fill-color": "rgba(232, 214, 38, 1)",
148 | "fill-opacity": 0.3
149 | },
150 | "source": "openmaptiles",
151 | "source-layer": "landcover",
152 | "type": "fill"
153 | }, {
154 | "filter": ["==", "class", "agriculture"],
155 | "id": "landuse",
156 | "layout": {
157 | "visibility": "visible"
158 | },
159 | "paint": {
160 | "fill-color": "#eae0d0"
161 | },
162 | "source": "openmaptiles",
163 | "source-layer": "landuse",
164 | "type": "fill"
165 | }, {
166 | "filter": ["==", "class", "national_park"],
167 | "id": "landuse_overlay_national_park",
168 | "paint": {
169 | "fill-color": "#E1EBB0",
170 | "fill-opacity": {
171 | "base": 1,
172 | "stops": [
173 | [5, 0],
174 | [9, 0.75]
175 | ]
176 | }
177 | },
178 | "source": "openmaptiles",
179 | "source-layer": "landcover",
180 | "type": "fill"
181 | }, {
182 | "filter": ["all", ["==", "$type", "LineString"],
183 | ["==", "brunnel", "tunnel"]
184 | ],
185 | "id": "waterway-tunnel",
186 | "paint": {
187 | "line-color": "hsl(205, 56%, 73%)",
188 | "line-dasharray": [3, 3],
189 | "line-gap-width": {
190 | "stops": [
191 | [12, 0],
192 | [20, 6]
193 | ]
194 | },
195 | "line-opacity": 1,
196 | "line-width": {
197 | "base": 1.4,
198 | "stops": [
199 | [8, 1],
200 | [20, 2]
201 | ]
202 | }
203 | },
204 | "source": "openmaptiles",
205 | "source-layer": "waterway",
206 | "type": "line",
207 | "layout": {
208 | "visibility": "visible"
209 | }
210 | }, {
211 | "filter": ["all", ["==", "$type", "LineString"],
212 | ["!in", "brunnel", "tunnel", "bridge"],
213 | ["!=", "intermittent", 1]
214 | ],
215 | "id": "waterway",
216 | "paint": {
217 | "line-color": "hsl(205, 56%, 73%)",
218 | "line-opacity": 1,
219 | "line-width": {
220 | "base": 1.4,
221 | "stops": [
222 | [8, 1],
223 | [20, 8]
224 | ]
225 | }
226 | },
227 | "source": "openmaptiles",
228 | "source-layer": "waterway",
229 | "type": "line",
230 | "layout": {
231 | "visibility": "visible"
232 | }
233 | }, {
234 | "filter": ["all", ["==", "$type", "LineString"],
235 | ["!in", "brunnel", "tunnel", "bridge"],
236 | ["==", "intermittent", 1]
237 | ],
238 | "id": "waterway_intermittent",
239 | "paint": {
240 | "line-color": "hsl(205, 56%, 73%)",
241 | "line-opacity": 1,
242 | "line-width": {
243 | "base": 1.4,
244 | "stops": [
245 | [8, 1],
246 | [20, 8]
247 | ]
248 | },
249 | "line-dasharray": [2, 1]
250 | },
251 | "source": "openmaptiles",
252 | "source-layer": "waterway",
253 | "type": "line",
254 | "layout": {
255 | "visibility": "visible"
256 | }
257 | }, {
258 | "filter": ["all", ["==", "$type", "LineString"],
259 | ["==", "brunnel", "tunnel"],
260 | ["==", "class", "transit"]
261 | ],
262 | "id": "tunnel_railway_transit",
263 | "layout": {
264 | "line-cap": "butt",
265 | "line-join": "miter"
266 | },
267 | "minzoom": 0,
268 | "paint": {
269 | "line-color": "hsl(34, 12%, 66%)",
270 | "line-dasharray": [3, 3],
271 | "line-opacity": {
272 | "base": 1,
273 | "stops": [
274 | [11, 0],
275 | [16, 1]
276 | ]
277 | }
278 | },
279 | "source": "openmaptiles",
280 | "source-layer": "transportation",
281 | "type": "line"
282 | }, {
283 | "id": "building",
284 | "paint": {
285 | "fill-antialias": true,
286 | "fill-color": "rgba(222, 211, 190, 1)",
287 | "fill-opacity": {
288 | "base": 1,
289 | "stops": [
290 | [13, 0],
291 | [15, 1]
292 | ]
293 | },
294 | "fill-outline-color": {
295 | "stops": [
296 | [15, "rgba(212, 177, 146, 0)"],
297 | [16, "rgba(212, 177, 146, 0.5)"]
298 | ]
299 | }
300 | },
301 | "source": "openmaptiles",
302 | "source-layer": "building",
303 | "type": "fill"
304 | }, {
305 | "filter": ["==", "$type", "Point"],
306 | "id": "housenumber",
307 | "layout": {
308 | "text-field": "{housenumber}",
309 | "text-font": ["Noto Sans Regular"],
310 | "text-size": 10
311 | },
312 | "minzoom": 17,
313 | "paint": {
314 | "text-color": "rgba(212, 177, 146, 1)"
315 | },
316 | "source": "openmaptiles",
317 | "source-layer": "housenumber",
318 | "type": "symbol"
319 | }, {
320 | "id": "road_area_pier",
321 | "type": "fill",
322 | "metadata": {},
323 | "source": "openmaptiles",
324 | "source-layer": "transportation",
325 | "filter": ["all", ["==", "$type", "Polygon"],
326 | ["==", "class", "pier"]
327 | ],
328 | "layout": {
329 | "visibility": "visible"
330 | },
331 | "paint": {
332 | "fill-color": "hsl(47, 26%, 88%)",
333 | "fill-antialias": true
334 | }
335 | }, {
336 | "id": "road_pier",
337 | "type": "line",
338 | "metadata": {},
339 | "source": "openmaptiles",
340 | "source-layer": "transportation",
341 | "filter": ["all", ["==", "$type", "LineString"],
342 | ["in", "class", "pier"]
343 | ],
344 | "layout": {
345 | "line-cap": "round",
346 | "line-join": "round"
347 | },
348 | "paint": {
349 | "line-color": "hsl(47, 26%, 88%)",
350 | "line-width": {
351 | "base": 1.2,
352 | "stops": [
353 | [15, 1],
354 | [17, 4]
355 | ]
356 | }
357 | }
358 | }, {
359 | "filter": ["all", ["==", "$type", "Polygon"],
360 | ["in", "brunnel", "bridge"]
361 | ],
362 | "id": "road_bridge_area",
363 | "layout": {},
364 | "paint": {
365 | "fill-color": "hsl(47, 26%, 88%)",
366 | "fill-opacity": 0.5
367 | },
368 | "source": "openmaptiles",
369 | "source-layer": "transportation",
370 | "type": "fill"
371 | }, {
372 | "filter": ["all", ["==", "$type", "LineString"],
373 | ["in", "class", "path", "track"]
374 | ],
375 | "id": "road_path",
376 | "layout": {
377 | "line-cap": "square",
378 | "line-join": "bevel"
379 | },
380 | "paint": {
381 | "line-color": "hsl(0, 0%, 97%)",
382 | "line-dasharray": [1, 1],
383 | "line-width": {
384 | "base": 1.55,
385 | "stops": [
386 | [4, 0.25],
387 | [20, 10]
388 | ]
389 | }
390 | },
391 | "source": "openmaptiles",
392 | "source-layer": "transportation",
393 | "type": "line"
394 | }, {
395 | "filter": ["all", ["==", "$type", "LineString"],
396 | ["in", "class", "minor", "service"]
397 | ],
398 | "id": "road_minor",
399 | "layout": {
400 | "line-cap": "round",
401 | "line-join": "round"
402 | },
403 | "paint": {
404 | "line-color": "hsl(0, 0%, 97%)",
405 | "line-width": {
406 | "base": 1.55,
407 | "stops": [
408 | [4, 0.25],
409 | [20, 30]
410 | ]
411 | }
412 | },
413 | "source": "openmaptiles",
414 | "source-layer": "transportation",
415 | "type": "line",
416 | "minzoom": 13
417 | }, {
418 | "filter": ["all", ["==", "$type", "LineString"],
419 | ["==", "brunnel", "tunnel"],
420 | ["==", "class", "minor_road"]
421 | ],
422 | "id": "tunnel_minor",
423 | "layout": {
424 | "line-cap": "butt",
425 | "line-join": "miter"
426 | },
427 | "paint": {
428 | "line-color": "#efefef",
429 | "line-dasharray": [0.36, 0.18],
430 | "line-width": {
431 | "base": 1.55,
432 | "stops": [
433 | [4, 0.25],
434 | [20, 30]
435 | ]
436 | }
437 | },
438 | "source": "openmaptiles",
439 | "source-layer": "transportation",
440 | "type": "line"
441 | }, {
442 | "filter": ["all", ["==", "$type", "LineString"],
443 | ["==", "brunnel", "tunnel"],
444 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
445 | ],
446 | "id": "tunnel_major",
447 | "layout": {
448 | "line-cap": "butt",
449 | "line-join": "miter"
450 | },
451 | "paint": {
452 | "line-color": "#fff",
453 | "line-dasharray": [0.28, 0.14],
454 | "line-width": {
455 | "base": 1.4,
456 | "stops": [
457 | [6, 0.5],
458 | [20, 30]
459 | ]
460 | }
461 | },
462 | "source": "openmaptiles",
463 | "source-layer": "transportation",
464 | "type": "line"
465 | }, {
466 | "filter": ["all", ["==", "$type", "Polygon"],
467 | ["in", "class", "runway", "taxiway"]
468 | ],
469 | "id": "aeroway-area",
470 | "layout": {
471 | "visibility": "visible"
472 | },
473 | "metadata": {
474 | "mapbox:group": "1444849345966.4436"
475 | },
476 | "minzoom": 4,
477 | "paint": {
478 | "fill-color": "rgba(255, 255, 255, 1)",
479 | "fill-opacity": {
480 | "base": 1,
481 | "stops": [
482 | [13, 0],
483 | [14, 1]
484 | ]
485 | }
486 | },
487 | "source": "openmaptiles",
488 | "source-layer": "aeroway",
489 | "type": "fill"
490 | }, {
491 | "filter": ["all", ["in", "class", "taxiway"],
492 | ["==", "$type", "LineString"]
493 | ],
494 | "id": "aeroway-taxiway",
495 | "layout": {
496 | "line-cap": "round",
497 | "line-join": "round",
498 | "visibility": "visible"
499 | },
500 | "metadata": {
501 | "mapbox:group": "1444849345966.4436"
502 | },
503 | "minzoom": 12,
504 | "paint": {
505 | "line-color": "rgba(255, 255, 255, 1)",
506 | "line-opacity": 1,
507 | "line-width": {
508 | "base": 1.5,
509 | "stops": [
510 | [12, 1],
511 | [17, 10]
512 | ]
513 | }
514 | },
515 | "source": "openmaptiles",
516 | "source-layer": "aeroway",
517 | "type": "line"
518 | }, {
519 | "filter": ["all", ["in", "class", "runway"],
520 | ["==", "$type", "LineString"]
521 | ],
522 | "id": "aeroway-runway",
523 | "layout": {
524 | "line-cap": "round",
525 | "line-join": "round",
526 | "visibility": "visible"
527 | },
528 | "metadata": {
529 | "mapbox:group": "1444849345966.4436"
530 | },
531 | "minzoom": 4,
532 | "paint": {
533 | "line-color": "rgba(255, 255, 255, 1)",
534 | "line-opacity": 1,
535 | "line-width": {
536 | "base": 1.5,
537 | "stops": [
538 | [11, 4],
539 | [17, 50]
540 | ]
541 | }
542 | },
543 | "source": "openmaptiles",
544 | "source-layer": "aeroway",
545 | "type": "line"
546 | }, {
547 | "filter": ["all", ["==", "$type", "LineString"],
548 | ["in", "class", "trunk", "primary"]
549 | ],
550 | "id": "road_trunk_primary",
551 | "layout": {
552 | "line-cap": "round",
553 | "line-join": "round"
554 | },
555 | "paint": {
556 | "line-color": "#fff",
557 | "line-width": {
558 | "base": 1.4,
559 | "stops": [
560 | [6, 0.5],
561 | [20, 30]
562 | ]
563 | }
564 | },
565 | "source": "openmaptiles",
566 | "source-layer": "transportation",
567 | "type": "line"
568 | }, {
569 | "filter": ["all", ["==", "$type", "LineString"],
570 | ["in", "class", "secondary", "tertiary"]
571 | ],
572 | "id": "road_secondary_tertiary",
573 | "layout": {
574 | "line-cap": "round",
575 | "line-join": "round"
576 | },
577 | "paint": {
578 | "line-color": "#fff",
579 | "line-width": {
580 | "base": 1.4,
581 | "stops": [
582 | [6, 0.5],
583 | [20, 20]
584 | ]
585 | }
586 | },
587 | "source": "openmaptiles",
588 | "source-layer": "transportation",
589 | "type": "line"
590 | }, {
591 | "filter": ["all", ["==", "$type", "LineString"],
592 | ["==", "class", "motorway"]
593 | ],
594 | "id": "road_major_motorway",
595 | "layout": {
596 | "line-cap": "round",
597 | "line-join": "round"
598 | },
599 | "paint": {
600 | "line-color": "hsl(0, 0%, 100%)",
601 | "line-offset": 0,
602 | "line-width": {
603 | "base": 1.4,
604 | "stops": [
605 | [8, 1],
606 | [16, 10]
607 | ]
608 | }
609 | },
610 | "source": "openmaptiles",
611 | "source-layer": "transportation",
612 | "type": "line"
613 | }, {
614 | "filter": ["all", ["==", "class", "transit"],
615 | ["!=", "brunnel", "tunnel"]
616 | ],
617 | "id": "railway-transit",
618 | "layout": {
619 | "visibility": "visible"
620 | },
621 | "paint": {
622 | "line-color": "hsl(34, 12%, 66%)",
623 | "line-opacity": {
624 | "base": 1,
625 | "stops": [
626 | [11, 0],
627 | [16, 1]
628 | ]
629 | }
630 | },
631 | "source": "openmaptiles",
632 | "source-layer": "transportation",
633 | "type": "line"
634 | }, {
635 | "filter": ["==", "class", "rail"],
636 | "id": "railway",
637 | "layout": {
638 | "visibility": "visible"
639 | },
640 | "paint": {
641 | "line-color": "hsl(34, 12%, 66%)",
642 | "line-opacity": {
643 | "base": 1,
644 | "stops": [
645 | [11, 0],
646 | [16, 1]
647 | ]
648 | }
649 | },
650 | "source": "openmaptiles",
651 | "source-layer": "transportation",
652 | "type": "line"
653 | }, {
654 | "filter": ["all", ["==", "$type", "LineString"],
655 | ["==", "brunnel", "bridge"]
656 | ],
657 | "id": "waterway-bridge-case",
658 | "layout": {
659 | "line-cap": "butt",
660 | "line-join": "miter"
661 | },
662 | "paint": {
663 | "line-color": "#bbbbbb",
664 | "line-gap-width": {
665 | "base": 1.55,
666 | "stops": [
667 | [4, 0.25],
668 | [20, 30]
669 | ]
670 | },
671 | "line-width": {
672 | "base": 1.6,
673 | "stops": [
674 | [12, 0.5],
675 | [20, 10]
676 | ]
677 | }
678 | },
679 | "source": "openmaptiles",
680 | "source-layer": "waterway",
681 | "type": "line"
682 | }, {
683 | "filter": ["all", ["==", "$type", "LineString"],
684 | ["==", "brunnel", "bridge"]
685 | ],
686 | "id": "waterway-bridge",
687 | "layout": {
688 | "line-cap": "round",
689 | "line-join": "round"
690 | },
691 | "paint": {
692 | "line-color": "hsl(205, 56%, 73%)",
693 | "line-width": {
694 | "base": 1.55,
695 | "stops": [
696 | [4, 0.25],
697 | [20, 30]
698 | ]
699 | }
700 | },
701 | "source": "openmaptiles",
702 | "source-layer": "waterway",
703 | "type": "line"
704 | }, {
705 | "filter": ["all", ["==", "$type", "LineString"],
706 | ["==", "brunnel", "bridge"],
707 | ["==", "class", "minor_road"]
708 | ],
709 | "id": "bridge_minor case",
710 | "layout": {
711 | "line-cap": "butt",
712 | "line-join": "miter"
713 | },
714 | "paint": {
715 | "line-color": "#dedede",
716 | "line-gap-width": {
717 | "base": 1.55,
718 | "stops": [
719 | [4, 0.25],
720 | [20, 30]
721 | ]
722 | },
723 | "line-width": {
724 | "base": 1.6,
725 | "stops": [
726 | [12, 0.5],
727 | [20, 10]
728 | ]
729 | }
730 | },
731 | "source": "openmaptiles",
732 | "source-layer": "transportation",
733 | "type": "line"
734 | }, {
735 | "filter": ["all", ["==", "$type", "LineString"],
736 | ["==", "brunnel", "bridge"],
737 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
738 | ],
739 | "id": "bridge_major case",
740 | "layout": {
741 | "line-cap": "butt",
742 | "line-join": "miter"
743 | },
744 | "paint": {
745 | "line-color": "#dedede",
746 | "line-gap-width": {
747 | "base": 1.55,
748 | "stops": [
749 | [4, 0.25],
750 | [20, 30]
751 | ]
752 | },
753 | "line-width": {
754 | "base": 1.6,
755 | "stops": [
756 | [12, 0.5],
757 | [20, 10]
758 | ]
759 | }
760 | },
761 | "source": "openmaptiles",
762 | "source-layer": "transportation",
763 | "type": "line"
764 | }, {
765 | "filter": ["all", ["==", "$type", "LineString"],
766 | ["==", "brunnel", "bridge"],
767 | ["==", "class", "minor_road"]
768 | ],
769 | "id": "bridge_minor",
770 | "layout": {
771 | "line-cap": "round",
772 | "line-join": "round"
773 | },
774 | "paint": {
775 | "line-color": "#efefef",
776 | "line-width": {
777 | "base": 1.55,
778 | "stops": [
779 | [4, 0.25],
780 | [20, 30]
781 | ]
782 | }
783 | },
784 | "source": "openmaptiles",
785 | "source-layer": "transportation",
786 | "type": "line"
787 | }, {
788 | "filter": ["all", ["==", "$type", "LineString"],
789 | ["==", "brunnel", "bridge"],
790 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
791 | ],
792 | "id": "bridge_major",
793 | "layout": {
794 | "line-cap": "round",
795 | "line-join": "round"
796 | },
797 | "paint": {
798 | "line-color": "#fff",
799 | "line-width": {
800 | "base": 1.4,
801 | "stops": [
802 | [6, 0.5],
803 | [20, 30]
804 | ]
805 | }
806 | },
807 | "source": "openmaptiles",
808 | "source-layer": "transportation",
809 | "type": "line"
810 | }, {
811 | "filter": ["in", "admin_level", 4, 6, 8],
812 | "id": "admin_sub",
813 | "layout": {
814 | "visibility": "visible"
815 | },
816 | "paint": {
817 | "line-color": "hsla(0, 0%, 60%, 0.5)",
818 | "line-dasharray": [2, 1]
819 | },
820 | "source": "openmaptiles",
821 | "source-layer": "boundary",
822 | "type": "line"
823 | }, {
824 | "filter": ["all", ["<=", "admin_level", 2],
825 | ["==", "$type", "LineString"]
826 | ],
827 | "id": "admin_country",
828 | "layout": {
829 | "line-cap": "round",
830 | "line-join": "round"
831 | },
832 | "paint": {
833 | "line-color": "hsl(0, 0%, 60%)",
834 | "line-width": {
835 | "base": 1.3,
836 | "stops": [
837 | [3, 0.5],
838 | [22, 15]
839 | ]
840 | }
841 | },
842 | "source": "openmaptiles",
843 | "source-layer": "boundary",
844 | "type": "line"
845 | }, {
846 | "filter": ["all", ["==", "$type", "Point"],
847 | ["==", "rank", 1]
848 | ],
849 | "id": "poi_label",
850 | "layout": {
851 | "icon-size": 1,
852 | "text-anchor": "top",
853 | "text-field": "{name:latin}\n{name:nonlatin}",
854 | "text-font": ["Noto Sans Regular"],
855 | "text-max-width": 8,
856 | "text-offset": [0, 0.5],
857 | "text-size": 11,
858 | "visibility": "visible"
859 | },
860 | "minzoom": 14,
861 | "paint": {
862 | "text-color": "#666",
863 | "text-halo-blur": 1,
864 | "text-halo-color": "rgba(255,255,255,0.75)",
865 | "text-halo-width": 1
866 | },
867 | "source": "openmaptiles",
868 | "source-layer": "poi",
869 | "type": "symbol"
870 | }, {
871 | "filter": ["all", ["has", "iata"]],
872 | "id": "airport-label",
873 | "layout": {
874 | "icon-size": 1,
875 | "text-anchor": "top",
876 | "text-field": "{name:latin}\n{name:nonlatin}",
877 | "text-font": ["Noto Sans Regular"],
878 | "text-max-width": 8,
879 | "text-offset": [0, 0.5],
880 | "text-size": 11,
881 | "visibility": "visible"
882 | },
883 | "minzoom": 10,
884 | "paint": {
885 | "text-color": "#666",
886 | "text-halo-blur": 1,
887 | "text-halo-color": "rgba(255,255,255,0.75)",
888 | "text-halo-width": 1
889 | },
890 | "source": "openmaptiles",
891 | "source-layer": "aerodrome_label",
892 | "type": "symbol"
893 | }, {
894 | "filter": ["==", "$type", "LineString"],
895 | "id": "road_major_label",
896 | "layout": {
897 | "symbol-placement": "line",
898 | "text-field": "{name:latin} {name:nonlatin}",
899 | "text-font": ["Noto Sans Regular"],
900 | "text-letter-spacing": 0.1,
901 | "text-rotation-alignment": "map",
902 | "text-size": {
903 | "base": 1.4,
904 | "stops": [
905 | [10, 8],
906 | [20, 14]
907 | ]
908 | },
909 | "text-transform": "uppercase"
910 | },
911 | "paint": {
912 | "text-color": "#000",
913 | "text-halo-color": "hsl(0, 0%, 100%)",
914 | "text-halo-width": 2
915 | },
916 | "source": "openmaptiles",
917 | "source-layer": "transportation_name",
918 | "type": "symbol"
919 | }, {
920 | "filter": ["all", ["==", "$type", "Point"],
921 | ["!in", "class", "city", "state", "country", "continent"]
922 | ],
923 | "id": "place_label_other",
924 | "layout": {
925 | "text-anchor": "center",
926 | "text-field": "{name:latin}\n{name:nonlatin}",
927 | "text-font": ["Noto Sans Regular"],
928 | "text-max-width": 6,
929 | "text-size": {
930 | "stops": [
931 | [6, 10],
932 | [12, 14]
933 | ]
934 | },
935 | "visibility": "visible"
936 | },
937 | "minzoom": 8,
938 | "paint": {
939 | "text-color": "hsl(0, 0%, 25%)",
940 | "text-halo-blur": 0,
941 | "text-halo-color": "hsl(0, 0%, 100%)",
942 | "text-halo-width": 2
943 | },
944 | "source": "openmaptiles",
945 | "source-layer": "place",
946 | "type": "symbol"
947 | }, {
948 | "filter": ["all", ["==", "$type", "Point"],
949 | ["==", "class", "city"]
950 | ],
951 | "id": "place_label_city",
952 | "layout": {
953 | "text-field": "{name:latin}\n{name:nonlatin}",
954 | "text-font": ["Noto Sans Regular"],
955 | "text-max-width": 10,
956 | "text-size": {
957 | "stops": [
958 | [3, 12],
959 | [8, 16]
960 | ]
961 | }
962 | },
963 | "maxzoom": 16,
964 | "paint": {
965 | "text-color": "hsl(0, 0%, 0%)",
966 | "text-halo-blur": 0,
967 | "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
968 | "text-halo-width": 2
969 | },
970 | "source": "openmaptiles",
971 | "source-layer": "place",
972 | "type": "symbol"
973 | }, {
974 | "filter": ["all", ["==", "$type", "Point"],
975 | ["==", "class", "country"],
976 | ["!has", "iso_a2"]
977 | ],
978 | "id": "country_label-other",
979 | "layout": {
980 | "text-field": "{name:latin}",
981 | "text-font": ["Noto Sans Regular"],
982 | "text-max-width": 10,
983 | "text-size": {
984 | "stops": [
985 | [3, 12],
986 | [8, 22]
987 | ]
988 | },
989 | "visibility": "visible"
990 | },
991 | "maxzoom": 12,
992 | "paint": {
993 | "text-color": "hsl(0, 0%, 13%)",
994 | "text-halo-blur": 0,
995 | "text-halo-color": "rgba(255,255,255,0.75)",
996 | "text-halo-width": 2
997 | },
998 | "source": "openmaptiles",
999 | "source-layer": "place",
1000 | "type": "symbol"
1001 | }, {
1002 | "filter": ["all", ["==", "$type", "Point"],
1003 | ["==", "class", "country"],
1004 | ["has", "iso_a2"]
1005 | ],
1006 | "id": "country_label",
1007 | "layout": {
1008 | "text-field": "{name:latin}",
1009 | "text-font": ["Noto Sans Bold"],
1010 | "text-max-width": 10,
1011 | "text-size": {
1012 | "stops": [
1013 | [3, 12],
1014 | [8, 22]
1015 | ]
1016 | },
1017 | "visibility": "visible"
1018 | },
1019 | "maxzoom": 12,
1020 | "paint": {
1021 | "text-color": "hsl(0, 0%, 13%)",
1022 | "text-halo-blur": 0,
1023 | "text-halo-color": "rgba(255,255,255,0.75)",
1024 | "text-halo-width": 2
1025 | },
1026 | "source": "openmaptiles",
1027 | "source-layer": "place",
1028 | "type": "symbol"
1029 | },{
1030 | "id": "geojsonSamplerPoints",
1031 | "type": "circle",
1032 | "source": "geojsonSamplerPoints",
1033 | "source-layer": "geojsonSamplerPoints",
1034 | "layout": {
1035 | "visibility": "visible"
1036 | },
1037 | "paint": {
1038 | "circle-radius": 2,
1039 | "circle-color": "red",
1040 | "circle-opacity": 1
1041 | }
1042 | },
1043 | {
1044 | "id": "geojsonSamplerLines",
1045 | "type": "line",
1046 | "source": "geojsonSamplerLines",
1047 | "source-layer": "geojsonSamplerLines",
1048 | "layout": {
1049 | "visibility": "visible"
1050 | },
1051 | "paint": {
1052 | "line-width": 2,
1053 | "line-color": "red",
1054 | "line-opacity": 1
1055 | }
1056 | }
1057 | ],
1058 | "id": "basic"
1059 | }
1060 |
--------------------------------------------------------------------------------
/examples/geojson/klokantech-basic-style-geojson-usStates.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Basic",
4 | "metadata": {
5 | "mapbox:autocomposite": false,
6 | "mapbox:type": "template",
7 | "maputnik:renderer": "mbgljs",
8 | "openmaptiles:version": "3.x",
9 | "openmaptiles:mapbox:owner": "openmaptiles",
10 | "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
11 | },
12 | "sources": {
13 | "openmaptiles": {
14 | "type": "vector",
15 | "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=mrAq6zQEFxOkanukNbGm"
16 | },
17 | "states": {
18 | "type": "geojson",
19 | "data": "./us-states.geojson",
20 | "minzoom" :0,
21 | "maxzoom" :14,
22 | "tileSize": 512
23 | }
24 | },
25 | "glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=mrAq6zQEFxOkanukNbGm",
26 | "layers": [{
27 | "id": "background",
28 | "paint": {
29 | "background-color": "hsl(47, 26%, 88%)"
30 | },
31 | "type": "background"
32 | }, {
33 | "filter": ["all", ["==", "$type", "Polygon"],
34 | ["in", "class", "residential", "suburb", "neighbourhood"]
35 | ],
36 | "id": "landuse-residential",
37 | "layout": {
38 | "visibility": "visible"
39 | },
40 | "paint": {
41 | "fill-color": "hsl(47, 13%, 86%)",
42 | "fill-opacity": 0.7
43 | },
44 | "source": "openmaptiles",
45 | "source-layer": "landuse",
46 | "type": "fill"
47 | }, {
48 | "filter": ["==", "class", "grass"],
49 | "id": "landcover_grass",
50 | "paint": {
51 | "fill-color": "hsl(82, 46%, 72%)",
52 | "fill-opacity": 0.45
53 | },
54 | "source": "openmaptiles",
55 | "source-layer": "landcover",
56 | "type": "fill"
57 | }, {
58 | "filter": ["==", "class", "wood"],
59 | "id": "landcover_wood",
60 | "paint": {
61 | "fill-color": "hsl(82, 46%, 72%)",
62 | "fill-opacity": {
63 | "base": 1,
64 | "stops": [
65 | [8, 0.6],
66 | [22, 1]
67 | ]
68 | }
69 | },
70 | "source": "openmaptiles",
71 | "source-layer": "landcover",
72 | "type": "fill"
73 | }, {
74 | "filter": ["all", ["==", "$type", "Polygon"],
75 | ["!=", "intermittent", 1]
76 | ],
77 | "id": "water",
78 | "paint": {
79 | "fill-color": "hsl(205, 56%, 73%)"
80 | },
81 | "source": "openmaptiles",
82 | "source-layer": "water",
83 | "type": "fill",
84 | "layout": {
85 | "visibility": "visible"
86 | }
87 | }, {
88 | "filter": ["all", ["==", "$type", "Polygon"],
89 | ["==", "intermittent", 1]
90 | ],
91 | "id": "water_intermittent",
92 | "paint": {
93 | "fill-color": "hsl(205, 56%, 73%)",
94 | "fill-opacity": 0.7
95 | },
96 | "source": "openmaptiles",
97 | "source-layer": "water",
98 | "type": "fill",
99 | "layout": {
100 | "visibility": "visible"
101 | }
102 | }, {
103 | "filter": ["==", "subclass", "ice_shelf"],
104 | "id": "landcover-ice-shelf",
105 | "layout": {
106 | "visibility": "visible"
107 | },
108 | "paint": {
109 | "fill-color": "hsl(47, 26%, 88%)",
110 | "fill-opacity": 0.8
111 | },
112 | "source": "openmaptiles",
113 | "source-layer": "landcover",
114 | "type": "fill"
115 | }, {
116 | "filter": ["==", "subclass", "glacier"],
117 | "id": "landcover-glacier",
118 | "layout": {
119 | "visibility": "visible"
120 | },
121 | "paint": {
122 | "fill-color": "hsl(47, 22%, 94%)",
123 | "fill-opacity": {
124 | "base": 1,
125 | "stops": [
126 | [0, 1],
127 | [8, 0.5]
128 | ]
129 | }
130 | },
131 | "source": "openmaptiles",
132 | "source-layer": "landcover",
133 | "type": "fill"
134 | }, {
135 | "filter": ["all", ["in", "class", "sand"]],
136 | "id": "landcover_sand",
137 | "metadata": {},
138 | "paint": {
139 | "fill-antialias": false,
140 | "fill-color": "rgba(232, 214, 38, 1)",
141 | "fill-opacity": 0.3
142 | },
143 | "source": "openmaptiles",
144 | "source-layer": "landcover",
145 | "type": "fill"
146 | }, {
147 | "filter": ["==", "class", "agriculture"],
148 | "id": "landuse",
149 | "layout": {
150 | "visibility": "visible"
151 | },
152 | "paint": {
153 | "fill-color": "#eae0d0"
154 | },
155 | "source": "openmaptiles",
156 | "source-layer": "landuse",
157 | "type": "fill"
158 | }, {
159 | "filter": ["==", "class", "national_park"],
160 | "id": "landuse_overlay_national_park",
161 | "paint": {
162 | "fill-color": "#E1EBB0",
163 | "fill-opacity": {
164 | "base": 1,
165 | "stops": [
166 | [5, 0],
167 | [9, 0.75]
168 | ]
169 | }
170 | },
171 | "source": "openmaptiles",
172 | "source-layer": "landcover",
173 | "type": "fill"
174 | }, {
175 | "filter": ["all", ["==", "$type", "LineString"],
176 | ["==", "brunnel", "tunnel"]
177 | ],
178 | "id": "waterway-tunnel",
179 | "paint": {
180 | "line-color": "hsl(205, 56%, 73%)",
181 | "line-dasharray": [3, 3],
182 | "line-gap-width": {
183 | "stops": [
184 | [12, 0],
185 | [20, 6]
186 | ]
187 | },
188 | "line-opacity": 1,
189 | "line-width": {
190 | "base": 1.4,
191 | "stops": [
192 | [8, 1],
193 | [20, 2]
194 | ]
195 | }
196 | },
197 | "source": "openmaptiles",
198 | "source-layer": "waterway",
199 | "type": "line",
200 | "layout": {
201 | "visibility": "visible"
202 | }
203 | }, {
204 | "filter": ["all", ["==", "$type", "LineString"],
205 | ["!in", "brunnel", "tunnel", "bridge"],
206 | ["!=", "intermittent", 1]
207 | ],
208 | "id": "waterway",
209 | "paint": {
210 | "line-color": "hsl(205, 56%, 73%)",
211 | "line-opacity": 1,
212 | "line-width": {
213 | "base": 1.4,
214 | "stops": [
215 | [8, 1],
216 | [20, 8]
217 | ]
218 | }
219 | },
220 | "source": "openmaptiles",
221 | "source-layer": "waterway",
222 | "type": "line",
223 | "layout": {
224 | "visibility": "visible"
225 | }
226 | }, {
227 | "filter": ["all", ["==", "$type", "LineString"],
228 | ["!in", "brunnel", "tunnel", "bridge"],
229 | ["==", "intermittent", 1]
230 | ],
231 | "id": "waterway_intermittent",
232 | "paint": {
233 | "line-color": "hsl(205, 56%, 73%)",
234 | "line-opacity": 1,
235 | "line-width": {
236 | "base": 1.4,
237 | "stops": [
238 | [8, 1],
239 | [20, 8]
240 | ]
241 | },
242 | "line-dasharray": [2, 1]
243 | },
244 | "source": "openmaptiles",
245 | "source-layer": "waterway",
246 | "type": "line",
247 | "layout": {
248 | "visibility": "visible"
249 | }
250 | }, {
251 | "filter": ["all", ["==", "$type", "LineString"],
252 | ["==", "brunnel", "tunnel"],
253 | ["==", "class", "transit"]
254 | ],
255 | "id": "tunnel_railway_transit",
256 | "layout": {
257 | "line-cap": "butt",
258 | "line-join": "miter"
259 | },
260 | "minzoom": 0,
261 | "paint": {
262 | "line-color": "hsl(34, 12%, 66%)",
263 | "line-dasharray": [3, 3],
264 | "line-opacity": {
265 | "base": 1,
266 | "stops": [
267 | [11, 0],
268 | [16, 1]
269 | ]
270 | }
271 | },
272 | "source": "openmaptiles",
273 | "source-layer": "transportation",
274 | "type": "line"
275 | }, {
276 | "id": "building",
277 | "paint": {
278 | "fill-antialias": true,
279 | "fill-color": "rgba(222, 211, 190, 1)",
280 | "fill-opacity": {
281 | "base": 1,
282 | "stops": [
283 | [13, 0],
284 | [15, 1]
285 | ]
286 | },
287 | "fill-outline-color": {
288 | "stops": [
289 | [15, "rgba(212, 177, 146, 0)"],
290 | [16, "rgba(212, 177, 146, 0.5)"]
291 | ]
292 | }
293 | },
294 | "source": "openmaptiles",
295 | "source-layer": "building",
296 | "type": "fill"
297 | }, {
298 | "filter": ["==", "$type", "Point"],
299 | "id": "housenumber",
300 | "layout": {
301 | "text-field": "{housenumber}",
302 | "text-font": ["Noto Sans Regular"],
303 | "text-size": 10
304 | },
305 | "minzoom": 17,
306 | "paint": {
307 | "text-color": "rgba(212, 177, 146, 1)"
308 | },
309 | "source": "openmaptiles",
310 | "source-layer": "housenumber",
311 | "type": "symbol"
312 | }, {
313 | "id": "road_area_pier",
314 | "type": "fill",
315 | "metadata": {},
316 | "source": "openmaptiles",
317 | "source-layer": "transportation",
318 | "filter": ["all", ["==", "$type", "Polygon"],
319 | ["==", "class", "pier"]
320 | ],
321 | "layout": {
322 | "visibility": "visible"
323 | },
324 | "paint": {
325 | "fill-color": "hsl(47, 26%, 88%)",
326 | "fill-antialias": true
327 | }
328 | }, {
329 | "id": "road_pier",
330 | "type": "line",
331 | "metadata": {},
332 | "source": "openmaptiles",
333 | "source-layer": "transportation",
334 | "filter": ["all", ["==", "$type", "LineString"],
335 | ["in", "class", "pier"]
336 | ],
337 | "layout": {
338 | "line-cap": "round",
339 | "line-join": "round"
340 | },
341 | "paint": {
342 | "line-color": "hsl(47, 26%, 88%)",
343 | "line-width": {
344 | "base": 1.2,
345 | "stops": [
346 | [15, 1],
347 | [17, 4]
348 | ]
349 | }
350 | }
351 | }, {
352 | "filter": ["all", ["==", "$type", "Polygon"],
353 | ["in", "brunnel", "bridge"]
354 | ],
355 | "id": "road_bridge_area",
356 | "layout": {},
357 | "paint": {
358 | "fill-color": "hsl(47, 26%, 88%)",
359 | "fill-opacity": 0.5
360 | },
361 | "source": "openmaptiles",
362 | "source-layer": "transportation",
363 | "type": "fill"
364 | }, {
365 | "filter": ["all", ["==", "$type", "LineString"],
366 | ["in", "class", "path", "track"]
367 | ],
368 | "id": "road_path",
369 | "layout": {
370 | "line-cap": "square",
371 | "line-join": "bevel"
372 | },
373 | "paint": {
374 | "line-color": "hsl(0, 0%, 97%)",
375 | "line-dasharray": [1, 1],
376 | "line-width": {
377 | "base": 1.55,
378 | "stops": [
379 | [4, 0.25],
380 | [20, 10]
381 | ]
382 | }
383 | },
384 | "source": "openmaptiles",
385 | "source-layer": "transportation",
386 | "type": "line"
387 | }, {
388 | "filter": ["all", ["==", "$type", "LineString"],
389 | ["in", "class", "minor", "service"]
390 | ],
391 | "id": "road_minor",
392 | "layout": {
393 | "line-cap": "round",
394 | "line-join": "round"
395 | },
396 | "paint": {
397 | "line-color": "hsl(0, 0%, 97%)",
398 | "line-width": {
399 | "base": 1.55,
400 | "stops": [
401 | [4, 0.25],
402 | [20, 30]
403 | ]
404 | }
405 | },
406 | "source": "openmaptiles",
407 | "source-layer": "transportation",
408 | "type": "line",
409 | "minzoom": 13
410 | }, {
411 | "filter": ["all", ["==", "$type", "LineString"],
412 | ["==", "brunnel", "tunnel"],
413 | ["==", "class", "minor_road"]
414 | ],
415 | "id": "tunnel_minor",
416 | "layout": {
417 | "line-cap": "butt",
418 | "line-join": "miter"
419 | },
420 | "paint": {
421 | "line-color": "#efefef",
422 | "line-dasharray": [0.36, 0.18],
423 | "line-width": {
424 | "base": 1.55,
425 | "stops": [
426 | [4, 0.25],
427 | [20, 30]
428 | ]
429 | }
430 | },
431 | "source": "openmaptiles",
432 | "source-layer": "transportation",
433 | "type": "line"
434 | }, {
435 | "filter": ["all", ["==", "$type", "LineString"],
436 | ["==", "brunnel", "tunnel"],
437 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
438 | ],
439 | "id": "tunnel_major",
440 | "layout": {
441 | "line-cap": "butt",
442 | "line-join": "miter"
443 | },
444 | "paint": {
445 | "line-color": "#fff",
446 | "line-dasharray": [0.28, 0.14],
447 | "line-width": {
448 | "base": 1.4,
449 | "stops": [
450 | [6, 0.5],
451 | [20, 30]
452 | ]
453 | }
454 | },
455 | "source": "openmaptiles",
456 | "source-layer": "transportation",
457 | "type": "line"
458 | }, {
459 | "filter": ["all", ["==", "$type", "Polygon"],
460 | ["in", "class", "runway", "taxiway"]
461 | ],
462 | "id": "aeroway-area",
463 | "layout": {
464 | "visibility": "visible"
465 | },
466 | "metadata": {
467 | "mapbox:group": "1444849345966.4436"
468 | },
469 | "minzoom": 4,
470 | "paint": {
471 | "fill-color": "rgba(255, 255, 255, 1)",
472 | "fill-opacity": {
473 | "base": 1,
474 | "stops": [
475 | [13, 0],
476 | [14, 1]
477 | ]
478 | }
479 | },
480 | "source": "openmaptiles",
481 | "source-layer": "aeroway",
482 | "type": "fill"
483 | }, {
484 | "filter": ["all", ["in", "class", "taxiway"],
485 | ["==", "$type", "LineString"]
486 | ],
487 | "id": "aeroway-taxiway",
488 | "layout": {
489 | "line-cap": "round",
490 | "line-join": "round",
491 | "visibility": "visible"
492 | },
493 | "metadata": {
494 | "mapbox:group": "1444849345966.4436"
495 | },
496 | "minzoom": 12,
497 | "paint": {
498 | "line-color": "rgba(255, 255, 255, 1)",
499 | "line-opacity": 1,
500 | "line-width": {
501 | "base": 1.5,
502 | "stops": [
503 | [12, 1],
504 | [17, 10]
505 | ]
506 | }
507 | },
508 | "source": "openmaptiles",
509 | "source-layer": "aeroway",
510 | "type": "line"
511 | }, {
512 | "filter": ["all", ["in", "class", "runway"],
513 | ["==", "$type", "LineString"]
514 | ],
515 | "id": "aeroway-runway",
516 | "layout": {
517 | "line-cap": "round",
518 | "line-join": "round",
519 | "visibility": "visible"
520 | },
521 | "metadata": {
522 | "mapbox:group": "1444849345966.4436"
523 | },
524 | "minzoom": 4,
525 | "paint": {
526 | "line-color": "rgba(255, 255, 255, 1)",
527 | "line-opacity": 1,
528 | "line-width": {
529 | "base": 1.5,
530 | "stops": [
531 | [11, 4],
532 | [17, 50]
533 | ]
534 | }
535 | },
536 | "source": "openmaptiles",
537 | "source-layer": "aeroway",
538 | "type": "line"
539 | }, {
540 | "filter": ["all", ["==", "$type", "LineString"],
541 | ["in", "class", "trunk", "primary"]
542 | ],
543 | "id": "road_trunk_primary",
544 | "layout": {
545 | "line-cap": "round",
546 | "line-join": "round"
547 | },
548 | "paint": {
549 | "line-color": "#fff",
550 | "line-width": {
551 | "base": 1.4,
552 | "stops": [
553 | [6, 0.5],
554 | [20, 30]
555 | ]
556 | }
557 | },
558 | "source": "openmaptiles",
559 | "source-layer": "transportation",
560 | "type": "line"
561 | }, {
562 | "filter": ["all", ["==", "$type", "LineString"],
563 | ["in", "class", "secondary", "tertiary"]
564 | ],
565 | "id": "road_secondary_tertiary",
566 | "layout": {
567 | "line-cap": "round",
568 | "line-join": "round"
569 | },
570 | "paint": {
571 | "line-color": "#fff",
572 | "line-width": {
573 | "base": 1.4,
574 | "stops": [
575 | [6, 0.5],
576 | [20, 20]
577 | ]
578 | }
579 | },
580 | "source": "openmaptiles",
581 | "source-layer": "transportation",
582 | "type": "line"
583 | }, {
584 | "filter": ["all", ["==", "$type", "LineString"],
585 | ["==", "class", "motorway"]
586 | ],
587 | "id": "road_major_motorway",
588 | "layout": {
589 | "line-cap": "round",
590 | "line-join": "round"
591 | },
592 | "paint": {
593 | "line-color": "hsl(0, 0%, 100%)",
594 | "line-offset": 0,
595 | "line-width": {
596 | "base": 1.4,
597 | "stops": [
598 | [8, 1],
599 | [16, 10]
600 | ]
601 | }
602 | },
603 | "source": "openmaptiles",
604 | "source-layer": "transportation",
605 | "type": "line"
606 | }, {
607 | "filter": ["all", ["==", "class", "transit"],
608 | ["!=", "brunnel", "tunnel"]
609 | ],
610 | "id": "railway-transit",
611 | "layout": {
612 | "visibility": "visible"
613 | },
614 | "paint": {
615 | "line-color": "hsl(34, 12%, 66%)",
616 | "line-opacity": {
617 | "base": 1,
618 | "stops": [
619 | [11, 0],
620 | [16, 1]
621 | ]
622 | }
623 | },
624 | "source": "openmaptiles",
625 | "source-layer": "transportation",
626 | "type": "line"
627 | }, {
628 | "filter": ["==", "class", "rail"],
629 | "id": "railway",
630 | "layout": {
631 | "visibility": "visible"
632 | },
633 | "paint": {
634 | "line-color": "hsl(34, 12%, 66%)",
635 | "line-opacity": {
636 | "base": 1,
637 | "stops": [
638 | [11, 0],
639 | [16, 1]
640 | ]
641 | }
642 | },
643 | "source": "openmaptiles",
644 | "source-layer": "transportation",
645 | "type": "line"
646 | }, {
647 | "filter": ["all", ["==", "$type", "LineString"],
648 | ["==", "brunnel", "bridge"]
649 | ],
650 | "id": "waterway-bridge-case",
651 | "layout": {
652 | "line-cap": "butt",
653 | "line-join": "miter"
654 | },
655 | "paint": {
656 | "line-color": "#bbbbbb",
657 | "line-gap-width": {
658 | "base": 1.55,
659 | "stops": [
660 | [4, 0.25],
661 | [20, 30]
662 | ]
663 | },
664 | "line-width": {
665 | "base": 1.6,
666 | "stops": [
667 | [12, 0.5],
668 | [20, 10]
669 | ]
670 | }
671 | },
672 | "source": "openmaptiles",
673 | "source-layer": "waterway",
674 | "type": "line"
675 | }, {
676 | "filter": ["all", ["==", "$type", "LineString"],
677 | ["==", "brunnel", "bridge"]
678 | ],
679 | "id": "waterway-bridge",
680 | "layout": {
681 | "line-cap": "round",
682 | "line-join": "round"
683 | },
684 | "paint": {
685 | "line-color": "hsl(205, 56%, 73%)",
686 | "line-width": {
687 | "base": 1.55,
688 | "stops": [
689 | [4, 0.25],
690 | [20, 30]
691 | ]
692 | }
693 | },
694 | "source": "openmaptiles",
695 | "source-layer": "waterway",
696 | "type": "line"
697 | }, {
698 | "filter": ["all", ["==", "$type", "LineString"],
699 | ["==", "brunnel", "bridge"],
700 | ["==", "class", "minor_road"]
701 | ],
702 | "id": "bridge_minor case",
703 | "layout": {
704 | "line-cap": "butt",
705 | "line-join": "miter"
706 | },
707 | "paint": {
708 | "line-color": "#dedede",
709 | "line-gap-width": {
710 | "base": 1.55,
711 | "stops": [
712 | [4, 0.25],
713 | [20, 30]
714 | ]
715 | },
716 | "line-width": {
717 | "base": 1.6,
718 | "stops": [
719 | [12, 0.5],
720 | [20, 10]
721 | ]
722 | }
723 | },
724 | "source": "openmaptiles",
725 | "source-layer": "transportation",
726 | "type": "line"
727 | }, {
728 | "filter": ["all", ["==", "$type", "LineString"],
729 | ["==", "brunnel", "bridge"],
730 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
731 | ],
732 | "id": "bridge_major case",
733 | "layout": {
734 | "line-cap": "butt",
735 | "line-join": "miter"
736 | },
737 | "paint": {
738 | "line-color": "#dedede",
739 | "line-gap-width": {
740 | "base": 1.55,
741 | "stops": [
742 | [4, 0.25],
743 | [20, 30]
744 | ]
745 | },
746 | "line-width": {
747 | "base": 1.6,
748 | "stops": [
749 | [12, 0.5],
750 | [20, 10]
751 | ]
752 | }
753 | },
754 | "source": "openmaptiles",
755 | "source-layer": "transportation",
756 | "type": "line"
757 | }, {
758 | "filter": ["all", ["==", "$type", "LineString"],
759 | ["==", "brunnel", "bridge"],
760 | ["==", "class", "minor_road"]
761 | ],
762 | "id": "bridge_minor",
763 | "layout": {
764 | "line-cap": "round",
765 | "line-join": "round"
766 | },
767 | "paint": {
768 | "line-color": "#efefef",
769 | "line-width": {
770 | "base": 1.55,
771 | "stops": [
772 | [4, 0.25],
773 | [20, 30]
774 | ]
775 | }
776 | },
777 | "source": "openmaptiles",
778 | "source-layer": "transportation",
779 | "type": "line"
780 | }, {
781 | "filter": ["all", ["==", "$type", "LineString"],
782 | ["==", "brunnel", "bridge"],
783 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
784 | ],
785 | "id": "bridge_major",
786 | "layout": {
787 | "line-cap": "round",
788 | "line-join": "round"
789 | },
790 | "paint": {
791 | "line-color": "#fff",
792 | "line-width": {
793 | "base": 1.4,
794 | "stops": [
795 | [6, 0.5],
796 | [20, 30]
797 | ]
798 | }
799 | },
800 | "source": "openmaptiles",
801 | "source-layer": "transportation",
802 | "type": "line"
803 | }, {
804 | "filter": ["in", "admin_level", 4, 6, 8],
805 | "id": "admin_sub",
806 | "layout": {
807 | "visibility": "visible"
808 | },
809 | "paint": {
810 | "line-color": "hsla(0, 0%, 60%, 0.5)",
811 | "line-dasharray": [2, 1]
812 | },
813 | "source": "openmaptiles",
814 | "source-layer": "boundary",
815 | "type": "line"
816 | }, {
817 | "filter": ["all", ["<=", "admin_level", 2],
818 | ["==", "$type", "LineString"]
819 | ],
820 | "id": "admin_country",
821 | "layout": {
822 | "line-cap": "round",
823 | "line-join": "round"
824 | },
825 | "paint": {
826 | "line-color": "hsl(0, 0%, 60%)",
827 | "line-width": {
828 | "base": 1.3,
829 | "stops": [
830 | [3, 0.5],
831 | [22, 15]
832 | ]
833 | }
834 | },
835 | "source": "openmaptiles",
836 | "source-layer": "boundary",
837 | "type": "line"
838 | }, {
839 | "filter": ["all", ["==", "$type", "Point"],
840 | ["==", "rank", 1]
841 | ],
842 | "id": "poi_label",
843 | "layout": {
844 | "icon-size": 1,
845 | "text-anchor": "top",
846 | "text-field": "{name:latin}\n{name:nonlatin}",
847 | "text-font": ["Noto Sans Regular"],
848 | "text-max-width": 8,
849 | "text-offset": [0, 0.5],
850 | "text-size": 11,
851 | "visibility": "visible"
852 | },
853 | "minzoom": 14,
854 | "paint": {
855 | "text-color": "#666",
856 | "text-halo-blur": 1,
857 | "text-halo-color": "rgba(255,255,255,0.75)",
858 | "text-halo-width": 1
859 | },
860 | "source": "openmaptiles",
861 | "source-layer": "poi",
862 | "type": "symbol"
863 | }, {
864 | "filter": ["all", ["has", "iata"]],
865 | "id": "airport-label",
866 | "layout": {
867 | "icon-size": 1,
868 | "text-anchor": "top",
869 | "text-field": "{name:latin}\n{name:nonlatin}",
870 | "text-font": ["Noto Sans Regular"],
871 | "text-max-width": 8,
872 | "text-offset": [0, 0.5],
873 | "text-size": 11,
874 | "visibility": "visible"
875 | },
876 | "minzoom": 10,
877 | "paint": {
878 | "text-color": "#666",
879 | "text-halo-blur": 1,
880 | "text-halo-color": "rgba(255,255,255,0.75)",
881 | "text-halo-width": 1
882 | },
883 | "source": "openmaptiles",
884 | "source-layer": "aerodrome_label",
885 | "type": "symbol"
886 | }, {
887 | "filter": ["==", "$type", "LineString"],
888 | "id": "road_major_label",
889 | "layout": {
890 | "symbol-placement": "line",
891 | "text-field": "{name:latin} {name:nonlatin}",
892 | "text-font": ["Noto Sans Regular"],
893 | "text-letter-spacing": 0.1,
894 | "text-rotation-alignment": "map",
895 | "text-size": {
896 | "base": 1.4,
897 | "stops": [
898 | [10, 8],
899 | [20, 14]
900 | ]
901 | },
902 | "text-transform": "uppercase"
903 | },
904 | "paint": {
905 | "text-color": "#000",
906 | "text-halo-color": "hsl(0, 0%, 100%)",
907 | "text-halo-width": 2
908 | },
909 | "source": "openmaptiles",
910 | "source-layer": "transportation_name",
911 | "type": "symbol"
912 | }, {
913 | "filter": ["all", ["==", "$type", "Point"],
914 | ["!in", "class", "city", "state", "country", "continent"]
915 | ],
916 | "id": "place_label_other",
917 | "layout": {
918 | "text-anchor": "center",
919 | "text-field": "{name:latin}\n{name:nonlatin}",
920 | "text-font": ["Noto Sans Regular"],
921 | "text-max-width": 6,
922 | "text-size": {
923 | "stops": [
924 | [6, 10],
925 | [12, 14]
926 | ]
927 | },
928 | "visibility": "visible"
929 | },
930 | "minzoom": 8,
931 | "paint": {
932 | "text-color": "hsl(0, 0%, 25%)",
933 | "text-halo-blur": 0,
934 | "text-halo-color": "hsl(0, 0%, 100%)",
935 | "text-halo-width": 2
936 | },
937 | "source": "openmaptiles",
938 | "source-layer": "place",
939 | "type": "symbol"
940 | }, {
941 | "filter": ["all", ["==", "$type", "Point"],
942 | ["==", "class", "city"]
943 | ],
944 | "id": "place_label_city",
945 | "layout": {
946 | "text-field": "{name:latin}\n{name:nonlatin}",
947 | "text-font": ["Noto Sans Regular"],
948 | "text-max-width": 10,
949 | "text-size": {
950 | "stops": [
951 | [3, 12],
952 | [8, 16]
953 | ]
954 | }
955 | },
956 | "maxzoom": 16,
957 | "paint": {
958 | "text-color": "hsl(0, 0%, 0%)",
959 | "text-halo-blur": 0,
960 | "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
961 | "text-halo-width": 2
962 | },
963 | "source": "openmaptiles",
964 | "source-layer": "place",
965 | "type": "symbol"
966 | }, {
967 | "filter": ["all", ["==", "$type", "Point"],
968 | ["==", "class", "country"],
969 | ["!has", "iso_a2"]
970 | ],
971 | "id": "country_label-other",
972 | "layout": {
973 | "text-field": "{name:latin}",
974 | "text-font": ["Noto Sans Regular"],
975 | "text-max-width": 10,
976 | "text-size": {
977 | "stops": [
978 | [3, 12],
979 | [8, 22]
980 | ]
981 | },
982 | "visibility": "visible"
983 | },
984 | "maxzoom": 12,
985 | "paint": {
986 | "text-color": "hsl(0, 0%, 13%)",
987 | "text-halo-blur": 0,
988 | "text-halo-color": "rgba(255,255,255,0.75)",
989 | "text-halo-width": 2
990 | },
991 | "source": "openmaptiles",
992 | "source-layer": "place",
993 | "type": "symbol"
994 | }, {
995 | "filter": ["all", ["==", "$type", "Point"],
996 | ["==", "class", "country"],
997 | ["has", "iso_a2"]
998 | ],
999 | "id": "country_label",
1000 | "layout": {
1001 | "text-field": "{name:latin}",
1002 | "text-font": ["Noto Sans Bold"],
1003 | "text-max-width": 10,
1004 | "text-size": {
1005 | "stops": [
1006 | [3, 12],
1007 | [8, 22]
1008 | ]
1009 | },
1010 | "visibility": "visible"
1011 | },
1012 | "maxzoom": 12,
1013 | "paint": {
1014 | "text-color": "hsl(0, 0%, 13%)",
1015 | "text-halo-blur": 0,
1016 | "text-halo-color": "rgba(255,255,255,0.75)",
1017 | "text-halo-width": 2
1018 | },
1019 | "source": "openmaptiles",
1020 | "source-layer": "place",
1021 | "type": "symbol"
1022 | },{
1023 | "id": "states",
1024 | "type": "line",
1025 | "source": "states",
1026 | "source-layer": "states",
1027 | "layout": {
1028 | "visibility": "visible"
1029 | },
1030 | "paint": {
1031 | "line-width": 2,
1032 | "line-color": "red",
1033 | "line-opacity": 1
1034 | }
1035 | }],
1036 | "id": "basic"
1037 | }
1038 |
--------------------------------------------------------------------------------
/examples/geojson/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as d3 from "d3";
3 | import * as tileMap from "../../";
4 |
5 | export function main() {
6 | const canvas = document.getElementById("mapCanvas");
7 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
8 | const context = yawgl.initContext(canvas);
9 |
10 | tileMap.init({
11 | context,
12 | center: [0, 30],
13 | zoom: 2,
14 | style: "klokantech-basic-style-geojson-sampler.json",
15 | }).promise.then(api => setup(api, canvas))
16 | .catch(console.log);
17 | }
18 |
19 | function setup(api, canvas) {
20 | const viewport = api.getViewport();
21 |
22 | const { k, x, y } = api.getTransform();
23 | let transform = d3.zoomIdentity
24 | .translate(x, y)
25 | .scale(k);
26 |
27 | const zoomer = d3.zoom()
28 | .scaleExtent([1 << 10, 1 << 26])
29 | .extent([[0, 0], viewport])
30 | .translateExtent([[-Infinity, -0.5], [Infinity, 0.5]])
31 | .on("zoom", (event) => {
32 | transform = event.transform;
33 | });
34 |
35 | d3.select(canvas)
36 | .call(zoomer)
37 | .call(zoomer.transform, transform);
38 |
39 | const loadStatus = document.getElementById("loadStatus");
40 |
41 | requestAnimationFrame(animate);
42 | function animate() {
43 | const pixRatio = window.devicePixelRatio;
44 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
45 | api.setTransform(transform);
46 | const percent = api.draw({ pixRatio }) * 100;
47 | loadStatus.innerHTML = (percent < 100)
48 | ? "Loading: " + percent.toFixed(0) + "%"
49 | : "Complete! " + percent.toFixed(0) + "%";
50 |
51 | requestAnimationFrame(animate);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/examples/geojson/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | #main {
11 | width: 100%;
12 | height: 100vh;
13 | position: relative;
14 | }
15 | #mapCanvas {
16 | width: 100%;
17 | height: 100%;
18 | display: block;
19 | background-color: gray;
20 | position: relative;
21 | }
22 | .attribution {
23 | background: rgba(255, 255, 255, 0.8);
24 | position: absolute;
25 | bottom: 0;
26 | right: 0;
27 | padding: 0 4px 0 4px;
28 | }
29 | #loadStatus {
30 | position: absolute;
31 | top: 0;
32 | right: 0;
33 | width: 15ch;
34 | text-align: right;
35 | background: rgba(60, 60, 60, 0.5);
36 | color: white;
37 | padding: 0 4px 0 4px;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/klokan-basic/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/klokan-basic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
tile-setter - beta
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/klokan-basic/klokan-fill-line.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Basic",
4 | "metadata": {
5 | "mapbox:autocomposite": false,
6 | "mapbox:type": "template",
7 | "maputnik:renderer": "mbgljs",
8 | "openmaptiles:version": "3.x",
9 | "openmaptiles:mapbox:owner": "openmaptiles",
10 | "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
11 | },
12 | "sources": {
13 | "openmaptiles": {
14 | "type": "vector",
15 | "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=mrAq6zQEFxOkanukNbGm"
16 | }
17 | },
18 | "glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=mrAq6zQEFxOkanukNbGm",
19 | "layers": [{
20 | "id": "background",
21 | "paint": {
22 | "background-color": "hsl(47, 26%, 88%)"
23 | },
24 | "type": "background"
25 | }, {
26 | "filter": ["all", ["==", "$type", "Polygon"],
27 | ["in", "class", "residential", "suburb", "neighbourhood"]
28 | ],
29 | "id": "landuse-residential",
30 | "layout": {
31 | "visibility": "visible"
32 | },
33 | "paint": {
34 | "fill-color": "hsl(47, 13%, 86%)",
35 | "fill-opacity": 0.7
36 | },
37 | "source": "openmaptiles",
38 | "source-layer": "landuse",
39 | "type": "fill"
40 | }, {
41 | "filter": ["==", "class", "grass"],
42 | "id": "landcover_grass",
43 | "paint": {
44 | "fill-color": "hsl(82, 46%, 72%)",
45 | "fill-opacity": 0.45
46 | },
47 | "source": "openmaptiles",
48 | "source-layer": "landcover",
49 | "type": "fill"
50 | }, {
51 | "filter": ["==", "class", "wood"],
52 | "id": "landcover_wood",
53 | "paint": {
54 | "fill-color": "hsl(82, 46%, 72%)",
55 | "fill-opacity": {
56 | "base": 1,
57 | "stops": [
58 | [8, 0.6],
59 | [22, 1]
60 | ]
61 | }
62 | },
63 | "source": "openmaptiles",
64 | "source-layer": "landcover",
65 | "type": "fill"
66 | }, {
67 | "filter": ["all", ["==", "$type", "Polygon"],
68 | ["!=", "intermittent", 1]
69 | ],
70 | "id": "water",
71 | "paint": {
72 | "fill-color": "hsl(205, 56%, 73%)"
73 | },
74 | "source": "openmaptiles",
75 | "source-layer": "water",
76 | "type": "fill",
77 | "layout": {
78 | "visibility": "visible"
79 | }
80 | }, {
81 | "filter": ["all", ["==", "$type", "Polygon"],
82 | ["==", "intermittent", 1]
83 | ],
84 | "id": "water_intermittent",
85 | "paint": {
86 | "fill-color": "hsl(205, 56%, 73%)",
87 | "fill-opacity": 0.7
88 | },
89 | "source": "openmaptiles",
90 | "source-layer": "water",
91 | "type": "fill",
92 | "layout": {
93 | "visibility": "visible"
94 | }
95 | }, {
96 | "filter": ["==", "subclass", "ice_shelf"],
97 | "id": "landcover-ice-shelf",
98 | "layout": {
99 | "visibility": "visible"
100 | },
101 | "paint": {
102 | "fill-color": "hsl(47, 26%, 88%)",
103 | "fill-opacity": 0.8
104 | },
105 | "source": "openmaptiles",
106 | "source-layer": "landcover",
107 | "type": "fill"
108 | }, {
109 | "filter": ["==", "subclass", "glacier"],
110 | "id": "landcover-glacier",
111 | "layout": {
112 | "visibility": "visible"
113 | },
114 | "paint": {
115 | "fill-color": "hsl(47, 22%, 94%)",
116 | "fill-opacity": {
117 | "base": 1,
118 | "stops": [
119 | [0, 1],
120 | [8, 0.5]
121 | ]
122 | }
123 | },
124 | "source": "openmaptiles",
125 | "source-layer": "landcover",
126 | "type": "fill"
127 | }, {
128 | "filter": ["all", ["in", "class", "sand"]],
129 | "id": "landcover_sand",
130 | "metadata": {},
131 | "paint": {
132 | "fill-antialias": false,
133 | "fill-color": "rgba(232, 214, 38, 1)",
134 | "fill-opacity": 0.3
135 | },
136 | "source": "openmaptiles",
137 | "source-layer": "landcover",
138 | "type": "fill"
139 | }, {
140 | "filter": ["==", "class", "agriculture"],
141 | "id": "landuse",
142 | "layout": {
143 | "visibility": "visible"
144 | },
145 | "paint": {
146 | "fill-color": "#eae0d0"
147 | },
148 | "source": "openmaptiles",
149 | "source-layer": "landuse",
150 | "type": "fill"
151 | }, {
152 | "filter": ["==", "class", "national_park"],
153 | "id": "landuse_overlay_national_park",
154 | "paint": {
155 | "fill-color": "#E1EBB0",
156 | "fill-opacity": {
157 | "base": 1,
158 | "stops": [
159 | [5, 0],
160 | [9, 0.75]
161 | ]
162 | }
163 | },
164 | "source": "openmaptiles",
165 | "source-layer": "landcover",
166 | "type": "fill"
167 | }, {
168 | "filter": ["all", ["==", "$type", "LineString"],
169 | ["==", "brunnel", "tunnel"]
170 | ],
171 | "id": "waterway-tunnel",
172 | "paint": {
173 | "line-color": "hsl(205, 56%, 73%)",
174 | "line-dasharray": [3, 3],
175 | "line-gap-width": {
176 | "stops": [
177 | [12, 0],
178 | [20, 6]
179 | ]
180 | },
181 | "line-opacity": 1,
182 | "line-width": {
183 | "base": 1.4,
184 | "stops": [
185 | [8, 1],
186 | [20, 2]
187 | ]
188 | }
189 | },
190 | "source": "openmaptiles",
191 | "source-layer": "waterway",
192 | "type": "line",
193 | "layout": {
194 | "visibility": "visible"
195 | }
196 | }, {
197 | "filter": ["all", ["==", "$type", "LineString"],
198 | ["!in", "brunnel", "tunnel", "bridge"],
199 | ["!=", "intermittent", 1]
200 | ],
201 | "id": "waterway",
202 | "paint": {
203 | "line-color": "hsl(205, 56%, 73%)",
204 | "line-opacity": 1,
205 | "line-width": {
206 | "base": 1.4,
207 | "stops": [
208 | [8, 1],
209 | [20, 8]
210 | ]
211 | }
212 | },
213 | "source": "openmaptiles",
214 | "source-layer": "waterway",
215 | "type": "line",
216 | "layout": {
217 | "visibility": "visible"
218 | }
219 | }, {
220 | "filter": ["all", ["==", "$type", "LineString"],
221 | ["!in", "brunnel", "tunnel", "bridge"],
222 | ["==", "intermittent", 1]
223 | ],
224 | "id": "waterway_intermittent",
225 | "paint": {
226 | "line-color": "hsl(205, 56%, 73%)",
227 | "line-opacity": 1,
228 | "line-width": {
229 | "base": 1.4,
230 | "stops": [
231 | [8, 1],
232 | [20, 8]
233 | ]
234 | },
235 | "line-dasharray": [2, 1]
236 | },
237 | "source": "openmaptiles",
238 | "source-layer": "waterway",
239 | "type": "line",
240 | "layout": {
241 | "visibility": "visible"
242 | }
243 | }, {
244 | "filter": ["all", ["==", "$type", "LineString"],
245 | ["==", "brunnel", "tunnel"],
246 | ["==", "class", "transit"]
247 | ],
248 | "id": "tunnel_railway_transit",
249 | "layout": {
250 | "line-cap": "butt",
251 | "line-join": "miter"
252 | },
253 | "minzoom": 0,
254 | "paint": {
255 | "line-color": "hsl(34, 12%, 66%)",
256 | "line-dasharray": [3, 3],
257 | "line-opacity": {
258 | "base": 1,
259 | "stops": [
260 | [11, 0],
261 | [16, 1]
262 | ]
263 | }
264 | },
265 | "source": "openmaptiles",
266 | "source-layer": "transportation",
267 | "type": "line"
268 | }, {
269 | "id": "building",
270 | "paint": {
271 | "fill-antialias": true,
272 | "fill-color": "rgba(222, 211, 190, 1)",
273 | "fill-opacity": {
274 | "base": 1,
275 | "stops": [
276 | [13, 0],
277 | [15, 1]
278 | ]
279 | },
280 | "fill-outline-color": {
281 | "stops": [
282 | [15, "rgba(212, 177, 146, 0)"],
283 | [16, "rgba(212, 177, 146, 0.5)"]
284 | ]
285 | }
286 | },
287 | "source": "openmaptiles",
288 | "source-layer": "building",
289 | "type": "fill"
290 | }, {
291 | "id": "road_area_pier",
292 | "type": "fill",
293 | "metadata": {},
294 | "source": "openmaptiles",
295 | "source-layer": "transportation",
296 | "filter": ["all", ["==", "$type", "Polygon"],
297 | ["==", "class", "pier"]
298 | ],
299 | "layout": {
300 | "visibility": "visible"
301 | },
302 | "paint": {
303 | "fill-color": "hsl(47, 26%, 88%)",
304 | "fill-antialias": true
305 | }
306 | }, {
307 | "id": "road_pier",
308 | "type": "line",
309 | "metadata": {},
310 | "source": "openmaptiles",
311 | "source-layer": "transportation",
312 | "filter": ["all", ["==", "$type", "LineString"],
313 | ["in", "class", "pier"]
314 | ],
315 | "layout": {
316 | "line-cap": "round",
317 | "line-join": "round"
318 | },
319 | "paint": {
320 | "line-color": "hsl(47, 26%, 88%)",
321 | "line-width": {
322 | "base": 1.2,
323 | "stops": [
324 | [15, 1],
325 | [17, 4]
326 | ]
327 | }
328 | }
329 | }, {
330 | "filter": ["all", ["==", "$type", "Polygon"],
331 | ["in", "brunnel", "bridge"]
332 | ],
333 | "id": "road_bridge_area",
334 | "layout": {},
335 | "paint": {
336 | "fill-color": "hsl(47, 26%, 88%)",
337 | "fill-opacity": 0.5
338 | },
339 | "source": "openmaptiles",
340 | "source-layer": "transportation",
341 | "type": "fill"
342 | }, {
343 | "filter": ["all", ["==", "$type", "LineString"],
344 | ["in", "class", "path", "track"]
345 | ],
346 | "id": "road_path",
347 | "layout": {
348 | "line-cap": "square",
349 | "line-join": "bevel"
350 | },
351 | "paint": {
352 | "line-color": "hsl(0, 0%, 97%)",
353 | "line-dasharray": [1, 1],
354 | "line-width": {
355 | "base": 1.55,
356 | "stops": [
357 | [4, 0.25],
358 | [20, 10]
359 | ]
360 | }
361 | },
362 | "source": "openmaptiles",
363 | "source-layer": "transportation",
364 | "type": "line"
365 | }, {
366 | "filter": ["all", ["==", "$type", "LineString"],
367 | ["in", "class", "minor", "service"]
368 | ],
369 | "id": "road_minor",
370 | "layout": {
371 | "line-cap": "round",
372 | "line-join": "round"
373 | },
374 | "paint": {
375 | "line-color": "hsl(0, 0%, 97%)",
376 | "line-width": {
377 | "base": 1.55,
378 | "stops": [
379 | [4, 0.25],
380 | [20, 30]
381 | ]
382 | }
383 | },
384 | "source": "openmaptiles",
385 | "source-layer": "transportation",
386 | "type": "line",
387 | "minzoom": 13
388 | }, {
389 | "filter": ["all", ["==", "$type", "LineString"],
390 | ["==", "brunnel", "tunnel"],
391 | ["==", "class", "minor_road"]
392 | ],
393 | "id": "tunnel_minor",
394 | "layout": {
395 | "line-cap": "butt",
396 | "line-join": "miter"
397 | },
398 | "paint": {
399 | "line-color": "#efefef",
400 | "line-dasharray": [0.36, 0.18],
401 | "line-width": {
402 | "base": 1.55,
403 | "stops": [
404 | [4, 0.25],
405 | [20, 30]
406 | ]
407 | }
408 | },
409 | "source": "openmaptiles",
410 | "source-layer": "transportation",
411 | "type": "line"
412 | }, {
413 | "filter": ["all", ["==", "$type", "LineString"],
414 | ["==", "brunnel", "tunnel"],
415 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
416 | ],
417 | "id": "tunnel_major",
418 | "layout": {
419 | "line-cap": "butt",
420 | "line-join": "miter"
421 | },
422 | "paint": {
423 | "line-color": "#fff",
424 | "line-dasharray": [0.28, 0.14],
425 | "line-width": {
426 | "base": 1.4,
427 | "stops": [
428 | [6, 0.5],
429 | [20, 30]
430 | ]
431 | }
432 | },
433 | "source": "openmaptiles",
434 | "source-layer": "transportation",
435 | "type": "line"
436 | }, {
437 | "filter": ["all", ["==", "$type", "Polygon"],
438 | ["in", "class", "runway", "taxiway"]
439 | ],
440 | "id": "aeroway-area",
441 | "layout": {
442 | "visibility": "visible"
443 | },
444 | "metadata": {
445 | "mapbox:group": "1444849345966.4436"
446 | },
447 | "minzoom": 4,
448 | "paint": {
449 | "fill-color": "rgba(255, 255, 255, 1)",
450 | "fill-opacity": {
451 | "base": 1,
452 | "stops": [
453 | [13, 0],
454 | [14, 1]
455 | ]
456 | }
457 | },
458 | "source": "openmaptiles",
459 | "source-layer": "aeroway",
460 | "type": "fill"
461 | }, {
462 | "filter": ["all", ["in", "class", "taxiway"],
463 | ["==", "$type", "LineString"]
464 | ],
465 | "id": "aeroway-taxiway",
466 | "layout": {
467 | "line-cap": "round",
468 | "line-join": "round",
469 | "visibility": "visible"
470 | },
471 | "metadata": {
472 | "mapbox:group": "1444849345966.4436"
473 | },
474 | "minzoom": 12,
475 | "paint": {
476 | "line-color": "rgba(255, 255, 255, 1)",
477 | "line-opacity": 1,
478 | "line-width": {
479 | "base": 1.5,
480 | "stops": [
481 | [12, 1],
482 | [17, 10]
483 | ]
484 | }
485 | },
486 | "source": "openmaptiles",
487 | "source-layer": "aeroway",
488 | "type": "line"
489 | }, {
490 | "filter": ["all", ["in", "class", "runway"],
491 | ["==", "$type", "LineString"]
492 | ],
493 | "id": "aeroway-runway",
494 | "layout": {
495 | "line-cap": "round",
496 | "line-join": "round",
497 | "visibility": "visible"
498 | },
499 | "metadata": {
500 | "mapbox:group": "1444849345966.4436"
501 | },
502 | "minzoom": 4,
503 | "paint": {
504 | "line-color": "rgba(255, 255, 255, 1)",
505 | "line-opacity": 1,
506 | "line-width": {
507 | "base": 1.5,
508 | "stops": [
509 | [11, 4],
510 | [17, 50]
511 | ]
512 | }
513 | },
514 | "source": "openmaptiles",
515 | "source-layer": "aeroway",
516 | "type": "line"
517 | }, {
518 | "filter": ["all", ["==", "$type", "LineString"],
519 | ["in", "class", "trunk", "primary"]
520 | ],
521 | "id": "road_trunk_primary",
522 | "layout": {
523 | "line-cap": "round",
524 | "line-join": "round"
525 | },
526 | "paint": {
527 | "line-color": "#fff",
528 | "line-width": {
529 | "base": 1.4,
530 | "stops": [
531 | [6, 0.5],
532 | [20, 30]
533 | ]
534 | }
535 | },
536 | "source": "openmaptiles",
537 | "source-layer": "transportation",
538 | "type": "line"
539 | }, {
540 | "filter": ["all", ["==", "$type", "LineString"],
541 | ["in", "class", "secondary", "tertiary"]
542 | ],
543 | "id": "road_secondary_tertiary",
544 | "layout": {
545 | "line-cap": "round",
546 | "line-join": "round"
547 | },
548 | "paint": {
549 | "line-color": "#fff",
550 | "line-width": {
551 | "base": 1.4,
552 | "stops": [
553 | [6, 0.5],
554 | [20, 20]
555 | ]
556 | }
557 | },
558 | "source": "openmaptiles",
559 | "source-layer": "transportation",
560 | "type": "line"
561 | }, {
562 | "filter": ["all", ["==", "$type", "LineString"],
563 | ["==", "class", "motorway"]
564 | ],
565 | "id": "road_major_motorway",
566 | "layout": {
567 | "line-cap": "round",
568 | "line-join": "round"
569 | },
570 | "paint": {
571 | "line-color": "hsl(0, 0%, 100%)",
572 | "line-offset": 0,
573 | "line-width": {
574 | "base": 1.4,
575 | "stops": [
576 | [8, 1],
577 | [16, 10]
578 | ]
579 | }
580 | },
581 | "source": "openmaptiles",
582 | "source-layer": "transportation",
583 | "type": "line"
584 | }, {
585 | "filter": ["all", ["==", "class", "transit"],
586 | ["!=", "brunnel", "tunnel"]
587 | ],
588 | "id": "railway-transit",
589 | "layout": {
590 | "visibility": "visible"
591 | },
592 | "paint": {
593 | "line-color": "hsl(34, 12%, 66%)",
594 | "line-opacity": {
595 | "base": 1,
596 | "stops": [
597 | [11, 0],
598 | [16, 1]
599 | ]
600 | }
601 | },
602 | "source": "openmaptiles",
603 | "source-layer": "transportation",
604 | "type": "line"
605 | }, {
606 | "filter": ["==", "class", "rail"],
607 | "id": "railway",
608 | "layout": {
609 | "visibility": "visible"
610 | },
611 | "paint": {
612 | "line-color": "hsl(34, 12%, 66%)",
613 | "line-opacity": {
614 | "base": 1,
615 | "stops": [
616 | [11, 0],
617 | [16, 1]
618 | ]
619 | }
620 | },
621 | "source": "openmaptiles",
622 | "source-layer": "transportation",
623 | "type": "line"
624 | }, {
625 | "filter": ["all", ["==", "$type", "LineString"],
626 | ["==", "brunnel", "bridge"]
627 | ],
628 | "id": "waterway-bridge-case",
629 | "layout": {
630 | "line-cap": "butt",
631 | "line-join": "miter"
632 | },
633 | "paint": {
634 | "line-color": "#bbbbbb",
635 | "line-gap-width": {
636 | "base": 1.55,
637 | "stops": [
638 | [4, 0.25],
639 | [20, 30]
640 | ]
641 | },
642 | "line-width": {
643 | "base": 1.6,
644 | "stops": [
645 | [12, 0.5],
646 | [20, 10]
647 | ]
648 | }
649 | },
650 | "source": "openmaptiles",
651 | "source-layer": "waterway",
652 | "type": "line"
653 | }, {
654 | "filter": ["all", ["==", "$type", "LineString"],
655 | ["==", "brunnel", "bridge"]
656 | ],
657 | "id": "waterway-bridge",
658 | "layout": {
659 | "line-cap": "round",
660 | "line-join": "round"
661 | },
662 | "paint": {
663 | "line-color": "hsl(205, 56%, 73%)",
664 | "line-width": {
665 | "base": 1.55,
666 | "stops": [
667 | [4, 0.25],
668 | [20, 30]
669 | ]
670 | }
671 | },
672 | "source": "openmaptiles",
673 | "source-layer": "waterway",
674 | "type": "line"
675 | }, {
676 | "filter": ["all", ["==", "$type", "LineString"],
677 | ["==", "brunnel", "bridge"],
678 | ["==", "class", "minor_road"]
679 | ],
680 | "id": "bridge_minor case",
681 | "layout": {
682 | "line-cap": "butt",
683 | "line-join": "miter"
684 | },
685 | "paint": {
686 | "line-color": "#dedede",
687 | "line-gap-width": {
688 | "base": 1.55,
689 | "stops": [
690 | [4, 0.25],
691 | [20, 30]
692 | ]
693 | },
694 | "line-width": {
695 | "base": 1.6,
696 | "stops": [
697 | [12, 0.5],
698 | [20, 10]
699 | ]
700 | }
701 | },
702 | "source": "openmaptiles",
703 | "source-layer": "transportation",
704 | "type": "line"
705 | }, {
706 | "filter": ["all", ["==", "$type", "LineString"],
707 | ["==", "brunnel", "bridge"],
708 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
709 | ],
710 | "id": "bridge_major case",
711 | "layout": {
712 | "line-cap": "butt",
713 | "line-join": "miter"
714 | },
715 | "paint": {
716 | "line-color": "#dedede",
717 | "line-gap-width": {
718 | "base": 1.55,
719 | "stops": [
720 | [4, 0.25],
721 | [20, 30]
722 | ]
723 | },
724 | "line-width": {
725 | "base": 1.6,
726 | "stops": [
727 | [12, 0.5],
728 | [20, 10]
729 | ]
730 | }
731 | },
732 | "source": "openmaptiles",
733 | "source-layer": "transportation",
734 | "type": "line"
735 | }, {
736 | "filter": ["all", ["==", "$type", "LineString"],
737 | ["==", "brunnel", "bridge"],
738 | ["==", "class", "minor_road"]
739 | ],
740 | "id": "bridge_minor",
741 | "layout": {
742 | "line-cap": "round",
743 | "line-join": "round"
744 | },
745 | "paint": {
746 | "line-color": "#efefef",
747 | "line-width": {
748 | "base": 1.55,
749 | "stops": [
750 | [4, 0.25],
751 | [20, 30]
752 | ]
753 | }
754 | },
755 | "source": "openmaptiles",
756 | "source-layer": "transportation",
757 | "type": "line"
758 | }, {
759 | "filter": ["all", ["==", "$type", "LineString"],
760 | ["==", "brunnel", "bridge"],
761 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
762 | ],
763 | "id": "bridge_major",
764 | "layout": {
765 | "line-cap": "round",
766 | "line-join": "round"
767 | },
768 | "paint": {
769 | "line-color": "#fff",
770 | "line-width": {
771 | "base": 1.4,
772 | "stops": [
773 | [6, 0.5],
774 | [20, 30]
775 | ]
776 | }
777 | },
778 | "source": "openmaptiles",
779 | "source-layer": "transportation",
780 | "type": "line"
781 | }, {
782 | "filter": ["in", "admin_level", 4, 6, 8],
783 | "id": "admin_sub",
784 | "layout": {
785 | "visibility": "visible"
786 | },
787 | "paint": {
788 | "line-color": "hsla(0, 0%, 60%, 0.5)",
789 | "line-dasharray": [2, 1]
790 | },
791 | "source": "openmaptiles",
792 | "source-layer": "boundary",
793 | "type": "line"
794 | }, {
795 | "filter": ["all", ["<=", "admin_level", 2],
796 | ["==", "$type", "LineString"]
797 | ],
798 | "id": "admin_country",
799 | "layout": {
800 | "line-cap": "round",
801 | "line-join": "round"
802 | },
803 | "paint": {
804 | "line-color": "hsl(0, 0%, 60%)",
805 | "line-width": {
806 | "base": 1.3,
807 | "stops": [
808 | [3, 0.5],
809 | [22, 15]
810 | ]
811 | }
812 | },
813 | "source": "openmaptiles",
814 | "source-layer": "boundary",
815 | "type": "line"
816 | }],
817 | "id": "basic"
818 | }
819 |
--------------------------------------------------------------------------------
/examples/klokan-basic/klokantech-basic-style.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Basic",
4 | "metadata": {
5 | "mapbox:autocomposite": false,
6 | "mapbox:type": "template",
7 | "maputnik:renderer": "mbgljs",
8 | "openmaptiles:version": "3.x",
9 | "openmaptiles:mapbox:owner": "openmaptiles",
10 | "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
11 | },
12 | "sources": {
13 | "openmaptiles": {
14 | "type": "vector",
15 | "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=mrAq6zQEFxOkanukNbGm"
16 | }
17 | },
18 | "glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=mrAq6zQEFxOkanukNbGm",
19 | "layers": [{
20 | "id": "background",
21 | "paint": {
22 | "background-color": "hsl(47, 26%, 88%)"
23 | },
24 | "type": "background"
25 | }, {
26 | "filter": ["all", ["==", "$type", "Polygon"],
27 | ["in", "class", "residential", "suburb", "neighbourhood"]
28 | ],
29 | "id": "landuse-residential",
30 | "layout": {
31 | "visibility": "visible"
32 | },
33 | "paint": {
34 | "fill-color": "hsl(47, 13%, 86%)",
35 | "fill-opacity": 0.7
36 | },
37 | "source": "openmaptiles",
38 | "source-layer": "landuse",
39 | "type": "fill"
40 | }, {
41 | "filter": ["==", "class", "grass"],
42 | "id": "landcover_grass",
43 | "paint": {
44 | "fill-color": "hsl(82, 46%, 72%)",
45 | "fill-opacity": 0.45
46 | },
47 | "source": "openmaptiles",
48 | "source-layer": "landcover",
49 | "type": "fill"
50 | }, {
51 | "filter": ["==", "class", "wood"],
52 | "id": "landcover_wood",
53 | "paint": {
54 | "fill-color": "hsl(82, 46%, 72%)",
55 | "fill-opacity": {
56 | "base": 1,
57 | "stops": [
58 | [8, 0.6],
59 | [22, 1]
60 | ]
61 | }
62 | },
63 | "source": "openmaptiles",
64 | "source-layer": "landcover",
65 | "type": "fill"
66 | }, {
67 | "filter": ["all", ["==", "$type", "Polygon"],
68 | ["!=", "intermittent", 1]
69 | ],
70 | "id": "water",
71 | "paint": {
72 | "fill-color": "hsl(205, 56%, 73%)"
73 | },
74 | "source": "openmaptiles",
75 | "source-layer": "water",
76 | "type": "fill",
77 | "layout": {
78 | "visibility": "visible"
79 | }
80 | }, {
81 | "filter": ["all", ["==", "$type", "Polygon"],
82 | ["==", "intermittent", 1]
83 | ],
84 | "id": "water_intermittent",
85 | "paint": {
86 | "fill-color": "hsl(205, 56%, 73%)",
87 | "fill-opacity": 0.7
88 | },
89 | "source": "openmaptiles",
90 | "source-layer": "water",
91 | "type": "fill",
92 | "layout": {
93 | "visibility": "visible"
94 | }
95 | }, {
96 | "filter": ["==", "subclass", "ice_shelf"],
97 | "id": "landcover-ice-shelf",
98 | "layout": {
99 | "visibility": "visible"
100 | },
101 | "paint": {
102 | "fill-color": "hsl(47, 26%, 88%)",
103 | "fill-opacity": 0.8
104 | },
105 | "source": "openmaptiles",
106 | "source-layer": "landcover",
107 | "type": "fill"
108 | }, {
109 | "filter": ["==", "subclass", "glacier"],
110 | "id": "landcover-glacier",
111 | "layout": {
112 | "visibility": "visible"
113 | },
114 | "paint": {
115 | "fill-color": "hsl(47, 22%, 94%)",
116 | "fill-opacity": {
117 | "base": 1,
118 | "stops": [
119 | [0, 1],
120 | [8, 0.5]
121 | ]
122 | }
123 | },
124 | "source": "openmaptiles",
125 | "source-layer": "landcover",
126 | "type": "fill"
127 | }, {
128 | "filter": ["all", ["in", "class", "sand"]],
129 | "id": "landcover_sand",
130 | "metadata": {},
131 | "paint": {
132 | "fill-antialias": false,
133 | "fill-color": "rgba(232, 214, 38, 1)",
134 | "fill-opacity": 0.3
135 | },
136 | "source": "openmaptiles",
137 | "source-layer": "landcover",
138 | "type": "fill"
139 | }, {
140 | "filter": ["==", "class", "agriculture"],
141 | "id": "landuse",
142 | "layout": {
143 | "visibility": "visible"
144 | },
145 | "paint": {
146 | "fill-color": "#eae0d0"
147 | },
148 | "source": "openmaptiles",
149 | "source-layer": "landuse",
150 | "type": "fill"
151 | }, {
152 | "filter": ["==", "class", "national_park"],
153 | "id": "landuse_overlay_national_park",
154 | "paint": {
155 | "fill-color": "#E1EBB0",
156 | "fill-opacity": {
157 | "base": 1,
158 | "stops": [
159 | [5, 0],
160 | [9, 0.75]
161 | ]
162 | }
163 | },
164 | "source": "openmaptiles",
165 | "source-layer": "landcover",
166 | "type": "fill"
167 | }, {
168 | "filter": ["all", ["==", "$type", "LineString"],
169 | ["==", "brunnel", "tunnel"]
170 | ],
171 | "id": "waterway-tunnel",
172 | "paint": {
173 | "line-color": "hsl(205, 56%, 73%)",
174 | "line-dasharray": [3, 3],
175 | "line-gap-width": {
176 | "stops": [
177 | [12, 0],
178 | [20, 6]
179 | ]
180 | },
181 | "line-opacity": 1,
182 | "line-width": {
183 | "base": 1.4,
184 | "stops": [
185 | [8, 1],
186 | [20, 2]
187 | ]
188 | }
189 | },
190 | "source": "openmaptiles",
191 | "source-layer": "waterway",
192 | "type": "line",
193 | "layout": {
194 | "visibility": "visible"
195 | }
196 | }, {
197 | "filter": ["all", ["==", "$type", "LineString"],
198 | ["!in", "brunnel", "tunnel", "bridge"],
199 | ["!=", "intermittent", 1]
200 | ],
201 | "id": "waterway",
202 | "paint": {
203 | "line-color": "hsl(205, 56%, 73%)",
204 | "line-opacity": 1,
205 | "line-width": {
206 | "base": 1.4,
207 | "stops": [
208 | [8, 1],
209 | [20, 8]
210 | ]
211 | }
212 | },
213 | "source": "openmaptiles",
214 | "source-layer": "waterway",
215 | "type": "line",
216 | "layout": {
217 | "visibility": "visible"
218 | }
219 | }, {
220 | "filter": ["all", ["==", "$type", "LineString"],
221 | ["!in", "brunnel", "tunnel", "bridge"],
222 | ["==", "intermittent", 1]
223 | ],
224 | "id": "waterway_intermittent",
225 | "paint": {
226 | "line-color": "hsl(205, 56%, 73%)",
227 | "line-opacity": 1,
228 | "line-width": {
229 | "base": 1.4,
230 | "stops": [
231 | [8, 1],
232 | [20, 8]
233 | ]
234 | },
235 | "line-dasharray": [2, 1]
236 | },
237 | "source": "openmaptiles",
238 | "source-layer": "waterway",
239 | "type": "line",
240 | "layout": {
241 | "visibility": "visible"
242 | }
243 | }, {
244 | "filter": ["all", ["==", "$type", "LineString"],
245 | ["==", "brunnel", "tunnel"],
246 | ["==", "class", "transit"]
247 | ],
248 | "id": "tunnel_railway_transit",
249 | "layout": {
250 | "line-cap": "butt",
251 | "line-join": "miter"
252 | },
253 | "minzoom": 0,
254 | "paint": {
255 | "line-color": "hsl(34, 12%, 66%)",
256 | "line-dasharray": [3, 3],
257 | "line-opacity": {
258 | "base": 1,
259 | "stops": [
260 | [11, 0],
261 | [16, 1]
262 | ]
263 | }
264 | },
265 | "source": "openmaptiles",
266 | "source-layer": "transportation",
267 | "type": "line"
268 | }, {
269 | "id": "building",
270 | "paint": {
271 | "fill-antialias": true,
272 | "fill-color": "rgba(222, 211, 190, 1)",
273 | "fill-opacity": {
274 | "base": 1,
275 | "stops": [
276 | [13, 0],
277 | [15, 1]
278 | ]
279 | },
280 | "fill-outline-color": {
281 | "stops": [
282 | [15, "rgba(212, 177, 146, 0)"],
283 | [16, "rgba(212, 177, 146, 0.5)"]
284 | ]
285 | }
286 | },
287 | "source": "openmaptiles",
288 | "source-layer": "building",
289 | "type": "fill"
290 | }, {
291 | "filter": ["==", "$type", "Point"],
292 | "id": "housenumber",
293 | "layout": {
294 | "text-field": "{housenumber}",
295 | "text-font": ["Noto Sans Regular"],
296 | "text-size": 10
297 | },
298 | "minzoom": 17,
299 | "paint": {
300 | "text-color": "rgba(212, 177, 146, 1)"
301 | },
302 | "source": "openmaptiles",
303 | "source-layer": "housenumber",
304 | "type": "symbol"
305 | }, {
306 | "id": "road_area_pier",
307 | "type": "fill",
308 | "metadata": {},
309 | "source": "openmaptiles",
310 | "source-layer": "transportation",
311 | "filter": ["all", ["==", "$type", "Polygon"],
312 | ["==", "class", "pier"]
313 | ],
314 | "layout": {
315 | "visibility": "visible"
316 | },
317 | "paint": {
318 | "fill-color": "hsl(47, 26%, 88%)",
319 | "fill-antialias": true
320 | }
321 | }, {
322 | "id": "road_pier",
323 | "type": "line",
324 | "metadata": {},
325 | "source": "openmaptiles",
326 | "source-layer": "transportation",
327 | "filter": ["all", ["==", "$type", "LineString"],
328 | ["in", "class", "pier"]
329 | ],
330 | "layout": {
331 | "line-cap": "round",
332 | "line-join": "round"
333 | },
334 | "paint": {
335 | "line-color": "hsl(47, 26%, 88%)",
336 | "line-width": {
337 | "base": 1.2,
338 | "stops": [
339 | [15, 1],
340 | [17, 4]
341 | ]
342 | }
343 | }
344 | }, {
345 | "filter": ["all", ["==", "$type", "Polygon"],
346 | ["in", "brunnel", "bridge"]
347 | ],
348 | "id": "road_bridge_area",
349 | "layout": {},
350 | "paint": {
351 | "fill-color": "hsl(47, 26%, 88%)",
352 | "fill-opacity": 0.5
353 | },
354 | "source": "openmaptiles",
355 | "source-layer": "transportation",
356 | "type": "fill"
357 | }, {
358 | "filter": ["all", ["==", "$type", "LineString"],
359 | ["in", "class", "path", "track"]
360 | ],
361 | "id": "road_path",
362 | "layout": {
363 | "line-cap": "square",
364 | "line-join": "bevel"
365 | },
366 | "paint": {
367 | "line-color": "hsl(0, 0%, 97%)",
368 | "line-dasharray": [1, 1],
369 | "line-width": {
370 | "base": 1.55,
371 | "stops": [
372 | [4, 0.25],
373 | [20, 10]
374 | ]
375 | }
376 | },
377 | "source": "openmaptiles",
378 | "source-layer": "transportation",
379 | "type": "line"
380 | }, {
381 | "filter": ["all", ["==", "$type", "LineString"],
382 | ["in", "class", "minor", "service"]
383 | ],
384 | "id": "road_minor",
385 | "layout": {
386 | "line-cap": "round",
387 | "line-join": "round"
388 | },
389 | "paint": {
390 | "line-color": "hsl(0, 0%, 97%)",
391 | "line-width": {
392 | "base": 1.55,
393 | "stops": [
394 | [4, 0.25],
395 | [20, 30]
396 | ]
397 | }
398 | },
399 | "source": "openmaptiles",
400 | "source-layer": "transportation",
401 | "type": "line",
402 | "minzoom": 13
403 | }, {
404 | "filter": ["all", ["==", "$type", "LineString"],
405 | ["==", "brunnel", "tunnel"],
406 | ["==", "class", "minor_road"]
407 | ],
408 | "id": "tunnel_minor",
409 | "layout": {
410 | "line-cap": "butt",
411 | "line-join": "miter"
412 | },
413 | "paint": {
414 | "line-color": "#efefef",
415 | "line-dasharray": [0.36, 0.18],
416 | "line-width": {
417 | "base": 1.55,
418 | "stops": [
419 | [4, 0.25],
420 | [20, 30]
421 | ]
422 | }
423 | },
424 | "source": "openmaptiles",
425 | "source-layer": "transportation",
426 | "type": "line"
427 | }, {
428 | "filter": ["all", ["==", "$type", "LineString"],
429 | ["==", "brunnel", "tunnel"],
430 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
431 | ],
432 | "id": "tunnel_major",
433 | "layout": {
434 | "line-cap": "butt",
435 | "line-join": "miter"
436 | },
437 | "paint": {
438 | "line-color": "#fff",
439 | "line-dasharray": [0.28, 0.14],
440 | "line-width": {
441 | "base": 1.4,
442 | "stops": [
443 | [6, 0.5],
444 | [20, 30]
445 | ]
446 | }
447 | },
448 | "source": "openmaptiles",
449 | "source-layer": "transportation",
450 | "type": "line"
451 | }, {
452 | "filter": ["all", ["==", "$type", "Polygon"],
453 | ["in", "class", "runway", "taxiway"]
454 | ],
455 | "id": "aeroway-area",
456 | "layout": {
457 | "visibility": "visible"
458 | },
459 | "metadata": {
460 | "mapbox:group": "1444849345966.4436"
461 | },
462 | "minzoom": 4,
463 | "paint": {
464 | "fill-color": "rgba(255, 255, 255, 1)",
465 | "fill-opacity": {
466 | "base": 1,
467 | "stops": [
468 | [13, 0],
469 | [14, 1]
470 | ]
471 | }
472 | },
473 | "source": "openmaptiles",
474 | "source-layer": "aeroway",
475 | "type": "fill"
476 | }, {
477 | "filter": ["all", ["in", "class", "taxiway"],
478 | ["==", "$type", "LineString"]
479 | ],
480 | "id": "aeroway-taxiway",
481 | "layout": {
482 | "line-cap": "round",
483 | "line-join": "round",
484 | "visibility": "visible"
485 | },
486 | "metadata": {
487 | "mapbox:group": "1444849345966.4436"
488 | },
489 | "minzoom": 12,
490 | "paint": {
491 | "line-color": "rgba(255, 255, 255, 1)",
492 | "line-opacity": 1,
493 | "line-width": {
494 | "base": 1.5,
495 | "stops": [
496 | [12, 1],
497 | [17, 10]
498 | ]
499 | }
500 | },
501 | "source": "openmaptiles",
502 | "source-layer": "aeroway",
503 | "type": "line"
504 | }, {
505 | "filter": ["all", ["in", "class", "runway"],
506 | ["==", "$type", "LineString"]
507 | ],
508 | "id": "aeroway-runway",
509 | "layout": {
510 | "line-cap": "round",
511 | "line-join": "round",
512 | "visibility": "visible"
513 | },
514 | "metadata": {
515 | "mapbox:group": "1444849345966.4436"
516 | },
517 | "minzoom": 4,
518 | "paint": {
519 | "line-color": "rgba(255, 255, 255, 1)",
520 | "line-opacity": 1,
521 | "line-width": {
522 | "base": 1.5,
523 | "stops": [
524 | [11, 4],
525 | [17, 50]
526 | ]
527 | }
528 | },
529 | "source": "openmaptiles",
530 | "source-layer": "aeroway",
531 | "type": "line"
532 | }, {
533 | "filter": ["all", ["==", "$type", "LineString"],
534 | ["in", "class", "trunk", "primary"]
535 | ],
536 | "id": "road_trunk_primary",
537 | "layout": {
538 | "line-cap": "round",
539 | "line-join": "round"
540 | },
541 | "paint": {
542 | "line-color": "#fff",
543 | "line-width": {
544 | "base": 1.4,
545 | "stops": [
546 | [6, 0.5],
547 | [20, 30]
548 | ]
549 | }
550 | },
551 | "source": "openmaptiles",
552 | "source-layer": "transportation",
553 | "type": "line"
554 | }, {
555 | "filter": ["all", ["==", "$type", "LineString"],
556 | ["in", "class", "secondary", "tertiary"]
557 | ],
558 | "id": "road_secondary_tertiary",
559 | "layout": {
560 | "line-cap": "round",
561 | "line-join": "round"
562 | },
563 | "paint": {
564 | "line-color": "#fff",
565 | "line-width": {
566 | "base": 1.4,
567 | "stops": [
568 | [6, 0.5],
569 | [20, 20]
570 | ]
571 | }
572 | },
573 | "source": "openmaptiles",
574 | "source-layer": "transportation",
575 | "type": "line"
576 | }, {
577 | "filter": ["all", ["==", "$type", "LineString"],
578 | ["==", "class", "motorway"]
579 | ],
580 | "id": "road_major_motorway",
581 | "layout": {
582 | "line-cap": "round",
583 | "line-join": "round"
584 | },
585 | "paint": {
586 | "line-color": "hsl(0, 0%, 100%)",
587 | "line-offset": 0,
588 | "line-width": {
589 | "base": 1.4,
590 | "stops": [
591 | [8, 1],
592 | [16, 10]
593 | ]
594 | }
595 | },
596 | "source": "openmaptiles",
597 | "source-layer": "transportation",
598 | "type": "line"
599 | }, {
600 | "filter": ["all", ["==", "class", "transit"],
601 | ["!=", "brunnel", "tunnel"]
602 | ],
603 | "id": "railway-transit",
604 | "layout": {
605 | "visibility": "visible"
606 | },
607 | "paint": {
608 | "line-color": "hsl(34, 12%, 66%)",
609 | "line-opacity": {
610 | "base": 1,
611 | "stops": [
612 | [11, 0],
613 | [16, 1]
614 | ]
615 | }
616 | },
617 | "source": "openmaptiles",
618 | "source-layer": "transportation",
619 | "type": "line"
620 | }, {
621 | "filter": ["==", "class", "rail"],
622 | "id": "railway",
623 | "layout": {
624 | "visibility": "visible"
625 | },
626 | "paint": {
627 | "line-color": "hsl(34, 12%, 66%)",
628 | "line-opacity": {
629 | "base": 1,
630 | "stops": [
631 | [11, 0],
632 | [16, 1]
633 | ]
634 | }
635 | },
636 | "source": "openmaptiles",
637 | "source-layer": "transportation",
638 | "type": "line"
639 | }, {
640 | "filter": ["all", ["==", "$type", "LineString"],
641 | ["==", "brunnel", "bridge"]
642 | ],
643 | "id": "waterway-bridge-case",
644 | "layout": {
645 | "line-cap": "butt",
646 | "line-join": "miter"
647 | },
648 | "paint": {
649 | "line-color": "#bbbbbb",
650 | "line-gap-width": {
651 | "base": 1.55,
652 | "stops": [
653 | [4, 0.25],
654 | [20, 30]
655 | ]
656 | },
657 | "line-width": {
658 | "base": 1.6,
659 | "stops": [
660 | [12, 0.5],
661 | [20, 10]
662 | ]
663 | }
664 | },
665 | "source": "openmaptiles",
666 | "source-layer": "waterway",
667 | "type": "line"
668 | }, {
669 | "filter": ["all", ["==", "$type", "LineString"],
670 | ["==", "brunnel", "bridge"]
671 | ],
672 | "id": "waterway-bridge",
673 | "layout": {
674 | "line-cap": "round",
675 | "line-join": "round"
676 | },
677 | "paint": {
678 | "line-color": "hsl(205, 56%, 73%)",
679 | "line-width": {
680 | "base": 1.55,
681 | "stops": [
682 | [4, 0.25],
683 | [20, 30]
684 | ]
685 | }
686 | },
687 | "source": "openmaptiles",
688 | "source-layer": "waterway",
689 | "type": "line"
690 | }, {
691 | "filter": ["all", ["==", "$type", "LineString"],
692 | ["==", "brunnel", "bridge"],
693 | ["==", "class", "minor_road"]
694 | ],
695 | "id": "bridge_minor case",
696 | "layout": {
697 | "line-cap": "butt",
698 | "line-join": "miter"
699 | },
700 | "paint": {
701 | "line-color": "#dedede",
702 | "line-gap-width": {
703 | "base": 1.55,
704 | "stops": [
705 | [4, 0.25],
706 | [20, 30]
707 | ]
708 | },
709 | "line-width": {
710 | "base": 1.6,
711 | "stops": [
712 | [12, 0.5],
713 | [20, 10]
714 | ]
715 | }
716 | },
717 | "source": "openmaptiles",
718 | "source-layer": "transportation",
719 | "type": "line"
720 | }, {
721 | "filter": ["all", ["==", "$type", "LineString"],
722 | ["==", "brunnel", "bridge"],
723 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
724 | ],
725 | "id": "bridge_major case",
726 | "layout": {
727 | "line-cap": "butt",
728 | "line-join": "miter"
729 | },
730 | "paint": {
731 | "line-color": "#dedede",
732 | "line-gap-width": {
733 | "base": 1.55,
734 | "stops": [
735 | [4, 0.25],
736 | [20, 30]
737 | ]
738 | },
739 | "line-width": {
740 | "base": 1.6,
741 | "stops": [
742 | [12, 0.5],
743 | [20, 10]
744 | ]
745 | }
746 | },
747 | "source": "openmaptiles",
748 | "source-layer": "transportation",
749 | "type": "line"
750 | }, {
751 | "filter": ["all", ["==", "$type", "LineString"],
752 | ["==", "brunnel", "bridge"],
753 | ["==", "class", "minor_road"]
754 | ],
755 | "id": "bridge_minor",
756 | "layout": {
757 | "line-cap": "round",
758 | "line-join": "round"
759 | },
760 | "paint": {
761 | "line-color": "#efefef",
762 | "line-width": {
763 | "base": 1.55,
764 | "stops": [
765 | [4, 0.25],
766 | [20, 30]
767 | ]
768 | }
769 | },
770 | "source": "openmaptiles",
771 | "source-layer": "transportation",
772 | "type": "line"
773 | }, {
774 | "filter": ["all", ["==", "$type", "LineString"],
775 | ["==", "brunnel", "bridge"],
776 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
777 | ],
778 | "id": "bridge_major",
779 | "layout": {
780 | "line-cap": "round",
781 | "line-join": "round"
782 | },
783 | "paint": {
784 | "line-color": "#fff",
785 | "line-width": {
786 | "base": 1.4,
787 | "stops": [
788 | [6, 0.5],
789 | [20, 30]
790 | ]
791 | }
792 | },
793 | "source": "openmaptiles",
794 | "source-layer": "transportation",
795 | "type": "line"
796 | }, {
797 | "filter": ["in", "admin_level", 4, 6, 8],
798 | "id": "admin_sub",
799 | "layout": {
800 | "visibility": "visible"
801 | },
802 | "paint": {
803 | "line-color": "hsla(0, 0%, 60%, 0.5)",
804 | "line-dasharray": [2, 1]
805 | },
806 | "source": "openmaptiles",
807 | "source-layer": "boundary",
808 | "type": "line"
809 | }, {
810 | "filter": ["all", ["<=", "admin_level", 2],
811 | ["==", "$type", "LineString"]
812 | ],
813 | "id": "admin_country",
814 | "layout": {
815 | "line-cap": "round",
816 | "line-join": "round"
817 | },
818 | "paint": {
819 | "line-color": "hsl(0, 0%, 60%)",
820 | "line-width": {
821 | "base": 1.3,
822 | "stops": [
823 | [3, 0.5],
824 | [22, 15]
825 | ]
826 | }
827 | },
828 | "source": "openmaptiles",
829 | "source-layer": "boundary",
830 | "type": "line"
831 | }, {
832 | "filter": ["all", ["==", "$type", "Point"],
833 | ["==", "rank", 1]
834 | ],
835 | "id": "poi_label",
836 | "layout": {
837 | "icon-size": 1,
838 | "text-anchor": "top",
839 | "text-field": "{name:latin}\n{name:nonlatin}",
840 | "text-font": ["Noto Sans Regular"],
841 | "text-max-width": 8,
842 | "text-offset": [0, 0.5],
843 | "text-size": 11,
844 | "visibility": "visible"
845 | },
846 | "minzoom": 14,
847 | "paint": {
848 | "text-color": "#666",
849 | "text-halo-blur": 1,
850 | "text-halo-color": "rgba(255,255,255,0.75)",
851 | "text-halo-width": 1
852 | },
853 | "source": "openmaptiles",
854 | "source-layer": "poi",
855 | "type": "symbol"
856 | }, {
857 | "filter": ["all", ["has", "iata"]],
858 | "id": "airport-label",
859 | "layout": {
860 | "icon-size": 1,
861 | "text-anchor": "top",
862 | "text-field": "{name:latin}\n{name:nonlatin}",
863 | "text-font": ["Noto Sans Regular"],
864 | "text-max-width": 8,
865 | "text-offset": [0, 0.5],
866 | "text-size": 11,
867 | "visibility": "visible"
868 | },
869 | "minzoom": 10,
870 | "paint": {
871 | "text-color": "#666",
872 | "text-halo-blur": 1,
873 | "text-halo-color": "rgba(255,255,255,0.75)",
874 | "text-halo-width": 1
875 | },
876 | "source": "openmaptiles",
877 | "source-layer": "aerodrome_label",
878 | "type": "symbol"
879 | }, {
880 | "filter": ["==", "$type", "LineString"],
881 | "id": "road_major_label",
882 | "layout": {
883 | "symbol-placement": "line",
884 | "text-field": "{name:latin} {name:nonlatin}",
885 | "text-font": ["Noto Sans Regular"],
886 | "text-letter-spacing": 0.1,
887 | "text-rotation-alignment": "map",
888 | "text-size": {
889 | "base": 1.4,
890 | "stops": [
891 | [10, 8],
892 | [20, 14]
893 | ]
894 | },
895 | "text-transform": "uppercase"
896 | },
897 | "paint": {
898 | "text-color": "#000",
899 | "text-halo-color": "hsl(0, 0%, 100%)",
900 | "text-halo-width": 2
901 | },
902 | "source": "openmaptiles",
903 | "source-layer": "transportation_name",
904 | "type": "symbol"
905 | }, {
906 | "filter": ["all", ["==", "$type", "Point"],
907 | ["!in", "class", "city", "state", "country", "continent"]
908 | ],
909 | "id": "place_label_other",
910 | "layout": {
911 | "text-anchor": "center",
912 | "text-field": "{name:latin}\n{name:nonlatin}",
913 | "text-font": ["Noto Sans Regular"],
914 | "text-max-width": 6,
915 | "text-size": {
916 | "stops": [
917 | [6, 10],
918 | [12, 14]
919 | ]
920 | },
921 | "visibility": "visible"
922 | },
923 | "minzoom": 8,
924 | "paint": {
925 | "text-color": "hsl(0, 0%, 25%)",
926 | "text-halo-blur": 0,
927 | "text-halo-color": "hsl(0, 0%, 100%)",
928 | "text-halo-width": 2
929 | },
930 | "source": "openmaptiles",
931 | "source-layer": "place",
932 | "type": "symbol"
933 | }, {
934 | "filter": ["all", ["==", "$type", "Point"],
935 | ["==", "class", "city"]
936 | ],
937 | "id": "place_label_city",
938 | "layout": {
939 | "text-field": "{name:latin}\n{name:nonlatin}",
940 | "text-font": ["Noto Sans Regular"],
941 | "text-max-width": 10,
942 | "text-size": {
943 | "stops": [
944 | [3, 12],
945 | [8, 16]
946 | ]
947 | }
948 | },
949 | "maxzoom": 16,
950 | "paint": {
951 | "text-color": "hsl(0, 0%, 0%)",
952 | "text-halo-blur": 0,
953 | "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
954 | "text-halo-width": 2
955 | },
956 | "source": "openmaptiles",
957 | "source-layer": "place",
958 | "type": "symbol"
959 | }, {
960 | "filter": ["all", ["==", "$type", "Point"],
961 | ["==", "class", "country"],
962 | ["!has", "iso_a2"]
963 | ],
964 | "id": "country_label-other",
965 | "layout": {
966 | "text-field": "{name:latin}",
967 | "text-font": ["Noto Sans Regular"],
968 | "text-max-width": 10,
969 | "text-size": {
970 | "stops": [
971 | [3, 12],
972 | [8, 22]
973 | ]
974 | },
975 | "visibility": "visible"
976 | },
977 | "maxzoom": 12,
978 | "paint": {
979 | "text-color": "hsl(0, 0%, 13%)",
980 | "text-halo-blur": 0,
981 | "text-halo-color": "rgba(255,255,255,0.75)",
982 | "text-halo-width": 2
983 | },
984 | "source": "openmaptiles",
985 | "source-layer": "place",
986 | "type": "symbol"
987 | }, {
988 | "filter": ["all", ["==", "$type", "Point"],
989 | ["==", "class", "country"],
990 | ["has", "iso_a2"]
991 | ],
992 | "id": "country_label",
993 | "layout": {
994 | "text-field": "{name:latin}",
995 | "text-font": ["Noto Sans Bold"],
996 | "text-max-width": 10,
997 | "text-size": {
998 | "stops": [
999 | [3, 12],
1000 | [8, 22]
1001 | ]
1002 | },
1003 | "visibility": "visible"
1004 | },
1005 | "maxzoom": 12,
1006 | "paint": {
1007 | "text-color": "hsl(0, 0%, 13%)",
1008 | "text-halo-blur": 0,
1009 | "text-halo-color": "rgba(255,255,255,0.75)",
1010 | "text-halo-width": 2
1011 | },
1012 | "source": "openmaptiles",
1013 | "source-layer": "place",
1014 | "type": "symbol"
1015 | }],
1016 | "id": "basic"
1017 | }
1018 |
--------------------------------------------------------------------------------
/examples/klokan-basic/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as d3 from "d3";
3 | import * as tileMap from "../../";
4 |
5 | export function main() {
6 | const canvas = document.getElementById("mapCanvas");
7 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
8 | const context = yawgl.initContext(canvas);
9 |
10 | tileMap.init({
11 | context,
12 | center: [-73.885, 40.745],
13 | zoom: 9,
14 | style: "./klokantech-basic-style.json",
15 | }).promise.then(api => setup(api, canvas))
16 | .catch(console.log);
17 | }
18 |
19 | function setup(api, canvas) {
20 | const viewport = api.getViewport();
21 |
22 | const { k, x, y } = api.getTransform();
23 | let transform = d3.zoomIdentity
24 | .translate(x, y)
25 | .scale(k);
26 |
27 | const zoomer = d3.zoom()
28 | .scaleExtent([1 << 10, 1 << 26])
29 | .extent([[0, 0], viewport])
30 | .translateExtent([[-Infinity, -0.5], [Infinity, 0.5]])
31 | .on("zoom", (event) => {
32 | transform = event.transform;
33 | });
34 |
35 | d3.select(canvas)
36 | .call(zoomer)
37 | .call(zoomer.transform, transform);
38 |
39 | requestAnimationFrame(animate);
40 | function animate() {
41 | const pixRatio = window.devicePixelRatio;
42 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
43 | api.setTransform(transform);
44 | api.draw({ pixRatio });
45 | requestAnimationFrame(animate);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/klokan-basic/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | #main {
11 | width: 100%;
12 | height: 100vh;
13 | position: relative;
14 | }
15 | #mapCanvas {
16 | width: 100%;
17 | height: 100%;
18 | background-color: gray;
19 | position: relative;
20 | }
21 | .attribution {
22 | background: rgba(255, 255, 255, 0.8);
23 | position: absolute;
24 | bottom: 0;
25 | right: 0;
26 | padding: 0 4px 0 4px;
27 | }
28 | .loadStatus {
29 | background: rgba(255, 255, 255, 0.8);
30 | position: absolute;
31 | top: 0;
32 | right: 0;
33 | padding: 0 4px 0 4px;
34 | }
35 |
--------------------------------------------------------------------------------
/examples/macrostrat/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/macrostrat/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
tile-setter - beta
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/macrostrat/macrostrat-only.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Mapbox Light",
4 | "sources": {
5 | "burwell": {
6 | "type": "vector",
7 | "tiles": ["https://tiles.macrostrat.org/carto/{z}/{x}/{y}.mvt"],
8 | "tileSize": 512
9 | }
10 | },
11 | "sprite": "mapbox://sprites/mapbox/light-v9",
12 | "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
13 | "visibility": "public",
14 | "layers": [
15 | {
16 | "id": "background",
17 | "type": "background",
18 | "layout": { },
19 | "paint": { "background-color": "hsl(55, 11%, 96%)" }
20 | },
21 | {
22 | "id": "burwell_fill",
23 | "type": "fill",
24 | "source": "burwell",
25 | "source-layer": "units",
26 | "filter": ["!=", "color", ""],
27 | "minzoom": 0,
28 | "maxzoom": 16,
29 | "paint": {
30 | "fill-color": {
31 | "property": "color",
32 | "type": "identity"
33 | },
34 | "fill-opacity": {
35 | "stops": [
36 | [0, 0.5],
37 | [12, 0.3]
38 | ]
39 | },
40 | "fill-outline-color": {
41 | "property": "color",
42 | "type": "identity"
43 | },
44 | "fill-outline-width": {
45 | "stops": [
46 | [0, 0.15],
47 | [1, 0.15],
48 | [2, 0.15],
49 | [3, 0.15],
50 | [4, 0.2],
51 | [5, 0.4],
52 | [6, 0.05],
53 | [7, 0.1],
54 | [8, 0.4],
55 | [9, 0.5],
56 | [10, 0.35],
57 | [11, 0.4],
58 | [12, 1],
59 | [13, 1.25],
60 | [14, 1.5],
61 | [15, 1.75],
62 | [16, 2]
63 | ]
64 | }
65 | }
66 | },
67 | {
68 | "id": "namedFaults",
69 | "type": "line",
70 | "source": "burwell",
71 | "source-layer": "lines",
72 | "filter": [
73 | "all",
74 | ["!=", "name", ""],
75 | ["in", "type", "fault", "normal fault", "thrust fault", "strike-slip fault", "reverse fault", "growth fault", "fault zone", "zone"]
76 | ],
77 | "minzoom": 0,
78 | "maxzoom": 16,
79 | "paint": {
80 | "line-color": "#000000",
81 | "line-width": {
82 | "stops": [
83 | [0, 0.6],
84 | [3, 0.6],
85 | [4, 1.0],
86 | [5, 1.2],
87 | [6, 0.9],
88 | [7, 0.8],
89 | [8, 1.4],
90 | [9, 1.6],
91 | [10, 1.4],
92 | [11, 2.2],
93 | [12, 2.6],
94 | [13, 3.0],
95 | [14, 3.2],
96 | [15, 3.5],
97 | [16, 4.4]
98 | ]
99 | },
100 | "line-opacity": 1
101 | },
102 | "layout": {
103 | "line-join": "round",
104 | "line-cap": "round"
105 | }
106 | },
107 | {
108 | "id": "faults",
109 | "type": "line",
110 | "source": "burwell",
111 | "source-layer": "lines",
112 | "filter": [
113 | "all",
114 | ["==", "name", ""],
115 | ["in", "type", "fault", "normal fault", "thrust fault", "strike-slip fault", "reverse fault", "growth fault", "fault zone", "zone"]
116 | ],
117 | "minzoom": 0,
118 | "maxzoom": 16,
119 | "paint": {
120 | "line-color": "#000000",
121 | "line-width": {
122 | "stops": [
123 | [0, 0.3],
124 | [3, 0.3],
125 | [4, 0.5],
126 | [5, 0.6],
127 | [6, 0.45],
128 | [7, 0.4],
129 | [8, 0.7],
130 | [9, 0.8],
131 | [10, 0.7],
132 | [11, 1.1],
133 | [12, 1.3],
134 | [13, 1.5],
135 | [14, 1.6],
136 | [15, 1.75],
137 | [16, 2.2]
138 | ]
139 | },
140 | "line-opacity": 1
141 | },
142 | "layout": {
143 | "line-join": "round",
144 | "line-cap": "round"
145 | }
146 | },
147 | {
148 | "id": "moraines",
149 | "type": "line",
150 | "source": "burwell",
151 | "source-layer": "lines",
152 | "filter": ["==", "type", "moraine"],
153 | "minzoom": 12,
154 | "maxzoom": 16,
155 | "layout": {
156 | "line-join": "round",
157 | "line-cap": "round"
158 | },
159 | "paint": {
160 | "line-color": "#3498DB",
161 | "line-dasharray": [1, 2],
162 | "line-width": {
163 | "stops": [
164 | [ 10, 1 ],
165 | [ 11, 2 ],
166 | [ 12, 2 ],
167 | [ 13, 2.5 ],
168 | [ 14, 3 ],
169 | [ 15, 3 ]
170 | ]
171 | },
172 | "line-opacity": {
173 | "stops": [
174 | [ 10, 0.2 ],
175 | [ 13, 1 ]
176 | ]
177 | }
178 | }
179 | },
180 | {
181 | "id": "eskers",
182 | "type": "line",
183 | "source": "burwell",
184 | "source-layer": "lines",
185 | "filter": ["==", "type", "esker"],
186 | "minzoom": 12,
187 | "maxzoom": 16,
188 | "layout": {
189 | "line-join": "round",
190 | "line-cap": "round"
191 | },
192 | "paint": {
193 | "line-color": "#00FFFF",
194 | "line-dasharray": [1, 4],
195 | "line-width": {
196 | "stops": [
197 | [ 10, 1 ],
198 | [ 11, 2 ],
199 | [ 12, 2 ],
200 | [ 13, 2.5 ],
201 | [ 14, 3 ],
202 | [ 15, 3 ]
203 | ]
204 | },
205 | "line-opacity": {
206 | "stops": [
207 | [ 10, 0.2 ],
208 | [ 13, 1 ]
209 | ]
210 | }
211 | }
212 | },
213 | {
214 | "id": "lineaments",
215 | "type": "line",
216 | "source": "burwell",
217 | "source-layer": "lines",
218 | "filter": ["==", "type", "lineament"],
219 | "minzoom": 0,
220 | "maxzoom": 16,
221 | "layout": {
222 | "line-join": "round",
223 | "line-cap": "round"
224 | },
225 | "paint": {
226 | "line-color": "#000000",
227 | "line-dasharray": [2, 2, 7, 2],
228 | "line-width": {
229 | "stops": [
230 | [ 9, 1],
231 | [ 10, 1 ],
232 | [ 11, 2 ],
233 | [ 12, 2 ],
234 | [ 13, 2.5 ],
235 | [ 14, 3 ],
236 | [ 15, 3 ]
237 | ]
238 | },
239 | "line-opacity": 1
240 | }
241 | },
242 | {
243 | "id": "synclines",
244 | "type": "line",
245 | "source": "burwell",
246 | "source-layer": "lines",
247 | "filter": ["==", "type", "syncline"],
248 | "minzoom": 0,
249 | "maxzoom": 16,
250 | "layout": {
251 | "line-join": "round",
252 | "line-cap": "round"
253 | },
254 | "paint": {
255 | "line-color": "#F012BE",
256 | "line-width": {
257 | "stops": [
258 | [0, 1],
259 | [7, 0.25],
260 | [8, 0.4],
261 | [9, 0.45],
262 | [10, 0.45],
263 | [11, 0.6],
264 | [12, 0.7],
265 | [13, 0.9],
266 | [14, 1.4],
267 | [15, 1.75],
268 | [16, 2.2]
269 | ]
270 | },
271 | "line-opacity": 1
272 | }
273 | },
274 | {
275 | "id": "monoclines",
276 | "type": "line",
277 | "source": "burwell",
278 | "source-layer": "lines",
279 | "filter": ["==", "type", "monocline"],
280 | "minzoom": 0,
281 | "maxzoom": 16,
282 | "layout": {
283 | "line-join": "round",
284 | "line-cap": "round"
285 | },
286 | "paint": {
287 | "line-color": "#F012BE",
288 | "line-width": {
289 | "stops": [
290 | [0, 1],
291 | [7, 0.25],
292 | [8, 0.4],
293 | [9, 0.45],
294 | [10, 0.45],
295 | [11, 0.6],
296 | [12, 0.7],
297 | [13, 0.9],
298 | [14, 1.4],
299 | [15, 1.75],
300 | [16, 2.2]
301 | ]
302 | },
303 | "line-opacity": 1
304 | }
305 | },
306 | {
307 | "id": "folds",
308 | "type": "line",
309 | "source": "burwell",
310 | "source-layer": "lines",
311 | "filter": ["==", "type", "fold"],
312 | "minzoom": 0,
313 | "maxzoom": 16,
314 | "layout": {
315 | "line-join": "round",
316 | "line-cap": "round"
317 | },
318 | "paint": {
319 | "line-color": "#F012BE",
320 | "line-width": {
321 | "stops": [
322 | [0, 1],
323 | [7, 0.25],
324 | [8, 0.4],
325 | [9, 0.45],
326 | [10, 0.45],
327 | [11, 0.6],
328 | [12, 0.7],
329 | [13, 0.9],
330 | [14, 1.4],
331 | [15, 1.75],
332 | [16, 2.2]
333 | ]
334 | },
335 | "line-opacity": 1
336 | }
337 | },
338 | {
339 | "id": "dikes",
340 | "type": "line",
341 | "source": "burwell",
342 | "source-layer": "lines",
343 | "filter": ["==", "type", "dike"],
344 | "minzoom": 6,
345 | "maxzoom": 16,
346 | "layout": {
347 | "line-join": "round",
348 | "line-cap": "round"
349 | },
350 | "paint": {
351 | "line-color": "#FF4136",
352 | "line-width": {
353 | "stops": [
354 | [0, 1],
355 | [7, 0.25],
356 | [8, 0.4],
357 | [9, 0.45],
358 | [10, 0.45],
359 | [11, 0.6],
360 | [12, 0.7],
361 | [13, 0.9],
362 | [14, 1.4],
363 | [15, 1.75],
364 | [16, 2.2]
365 | ]
366 | },
367 | "line-opacity": {
368 | "stops": [
369 | [ 6, 0.2 ],
370 | [ 10, 1 ]
371 | ]
372 | }
373 | }
374 | },
375 | {
376 | "id": "anticlines",
377 | "type": "line",
378 | "source": "burwell",
379 | "source-layer": "lines",
380 | "filter": ["==", "type", "anticline"],
381 | "minzoom": 0,
382 | "maxzoom": 16,
383 | "layout": {
384 | "line-join": "round",
385 | "line-cap": "round"
386 | },
387 | "paint": {
388 | "line-color": "#F012BE",
389 | "line-width": {
390 | "stops": [
391 | [0, 1],
392 | [7, 0.25],
393 | [8, 0.4],
394 | [9, 0.45],
395 | [10, 0.45],
396 | [11, 0.6],
397 | [12, 0.7],
398 | [13, 0.9],
399 | [14, 1.4],
400 | [15, 1.75],
401 | [16, 2.2]
402 | ]
403 | },
404 | "line-opacity": 1
405 | }
406 | },
407 | {
408 | "id": "flows",
409 | "type": "line",
410 | "source": "burwell",
411 | "source-layer": "lines",
412 | "filter": ["==", "type", "flow"],
413 | "minzoom": 0,
414 | "maxzoom": 16,
415 | "layout": {
416 | "line-join": "round",
417 | "line-cap": "round"
418 | },
419 | "paint": {
420 | "line-color": "#FF4136",
421 | "line-width": {
422 | "stops": [
423 | [0, 1],
424 | [7, 0.25],
425 | [8, 0.4],
426 | [9, 0.45],
427 | [10, 0.45],
428 | [11, 0.6],
429 | [12, 0.7],
430 | [13, 0.9],
431 | [14, 1.4],
432 | [15, 1.75],
433 | [16, 2.2]
434 | ]
435 | },
436 | "line-opacity": 1
437 | }
438 | },
439 | {
440 | "id": "sills",
441 | "type": "line",
442 | "source": "burwell",
443 | "source-layer": "lines",
444 | "filter": ["==", "type", "sill"],
445 | "minzoom": 0,
446 | "maxzoom": 16,
447 | "layout": {
448 | "line-join": "round",
449 | "line-cap": "round"
450 | },
451 | "paint": {
452 | "line-color": "#FF4136",
453 | "line-width": {
454 | "stops": [
455 | [0, 1],
456 | [7, 0.25],
457 | [8, 0.4],
458 | [9, 0.45],
459 | [10, 0.45],
460 | [11, 0.6],
461 | [12, 0.7],
462 | [13, 0.9],
463 | [14, 1.4],
464 | [15, 1.75],
465 | [16, 2.2]
466 | ]
467 | },
468 | "line-opacity": 1
469 | }
470 | },
471 | {
472 | "id": "veins",
473 | "type": "line",
474 | "source": "burwell",
475 | "source-layer": "lines",
476 | "filter": ["==", "type", "vein"],
477 | "minzoom": 0,
478 | "maxzoom": 16,
479 | "layout": {
480 | "line-join": "round",
481 | "line-cap": "round"
482 | },
483 | "paint": {
484 | "line-color": "#FF4136",
485 | "line-width": {
486 | "stops": [
487 | [0, 1],
488 | [7, 0.25],
489 | [8, 0.4],
490 | [9, 0.45],
491 | [10, 0.45],
492 | [11, 0.6],
493 | [12, 0.7],
494 | [13, 0.9],
495 | [14, 1.4],
496 | [15, 1.75],
497 | [16, 2.2]
498 | ]
499 | },
500 | "line-opacity": {
501 | "stops": [
502 | [ 6, 0.2 ],
503 | [ 10, 1 ]
504 | ]
505 | }
506 | }
507 | },
508 | {
509 | "id": "marker_beds",
510 | "type": "line",
511 | "source": "burwell",
512 | "source-layer": "lines",
513 | "filter": ["in", "type", "marker bed", "bed"],
514 | "minzoom": 12,
515 | "maxzoom": 16,
516 | "layout": {
517 | "line-join": "round",
518 | "line-cap": "round"
519 | },
520 | "paint": {
521 | "line-color": "#333333",
522 | "line-width": {
523 | "stops": [
524 | [10, 0.8],
525 | [11, 0.8],
526 | [12, 0.9],
527 | [13, 0.9],
528 | [14, 1.4],
529 | [15, 1.75],
530 | [16, 2.2]
531 | ]
532 | },
533 | "line-opacity": 1
534 | }
535 | },
536 | {
537 | "id": "craters",
538 | "type": "line",
539 | "source": "burwell",
540 | "source-layer": "lines",
541 | "filter": ["in", "type", "crater", "impact structure"],
542 | "minzoom": 10,
543 | "maxzoom": 16,
544 | "paint": {
545 | "line-dasharray": [6, 6],
546 | "line-color": "#000000",
547 | "line-width": {
548 | "stops": [
549 | [10, 0.6],
550 | [11, 0.6],
551 | [12, 0.72],
552 | [13, 0.72],
553 | [14, 1],
554 | [15, 1.3],
555 | [16, 1.8]
556 | ]
557 | },
558 | "line-opacity": 1
559 | }
560 | }
561 | ],
562 | "created": "1970-01-01T00:00:00.000Z",
563 | "modified": "1970-01-01T00:00:00.000Z",
564 | "owner": "mapbox",
565 | "id": "light-v9",
566 | "draft": false
567 | }
568 |
--------------------------------------------------------------------------------
/examples/macrostrat/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as d3 from "d3";
3 | import * as tileMap from "../../";
4 |
5 | export function main() {
6 | const canvas = document.getElementById("mapCanvas");
7 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
8 | const context = yawgl.initContext(canvas);
9 |
10 | tileMap.init({
11 | context,
12 | center: [-85.0, 36.0],
13 | zoom: 7,
14 | style: "./light-macrostrat.json",
15 | // eslint-disable-next-line max-len
16 | mapboxToken: "pk.eyJ1IjoiamhlbWJkIiwiYSI6ImNqcHpueHpyZjBlMjAzeG9kNG9oNzI2NTYifQ.K7fqhk2Z2YZ8NIV94M-5nA",
17 | }).promise.then(api => setup(api, canvas))
18 | .catch(console.log);
19 | }
20 |
21 | function setup(api, canvas) {
22 | const viewport = api.getViewport();
23 |
24 | const { k, x, y } = api.getTransform();
25 | let transform = d3.zoomIdentity
26 | .translate(x, y)
27 | .scale(k);
28 |
29 | const zoomer = d3.zoom()
30 | .scaleExtent([1 << 10, 1 << 26])
31 | .extent([[0, 0], viewport])
32 | .translateExtent([[-Infinity, -0.5], [Infinity, 0.5]])
33 | .on("zoom", (event) => {
34 | transform = event.transform;
35 | });
36 |
37 | d3.select(canvas)
38 | .call(zoomer)
39 | .call(zoomer.transform, transform);
40 |
41 | const loadStatus = document.getElementById("loadStatus");
42 |
43 | requestAnimationFrame(animate);
44 | function animate() {
45 | const pixRatio = window.devicePixelRatio;
46 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
47 | api.setTransform(transform);
48 | const percent = api.draw({ pixRatio }) * 100;
49 | loadStatus.innerHTML = (percent < 100)
50 | ? "Loading: " + percent.toFixed(0) + "%"
51 | : "Complete! " + percent.toFixed(0) + "%";
52 |
53 | requestAnimationFrame(animate);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/examples/macrostrat/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | #main {
11 | width: 100%;
12 | height: 100vh;
13 | position: relative;
14 | }
15 | #mapCanvas {
16 | width: 100%;
17 | height: 100%;
18 | display: block;
19 | background-color: gray;
20 | position: relative;
21 | }
22 | .attribution {
23 | background: rgba(255, 255, 255, 0.8);
24 | position: absolute;
25 | bottom: 0;
26 | right: 0;
27 | padding: 0 4px 0 4px;
28 | }
29 | #loadStatus {
30 | position: absolute;
31 | top: 0;
32 | right: 0;
33 | width: 15ch;
34 | text-align: right;
35 | background: rgba(60, 60, 60, 0.5);
36 | color: white;
37 | padding: 0 4px 0 4px;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/mapbox-streets/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/mapbox-streets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
tile-setter - beta
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/mapbox-streets/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as d3 from "d3";
3 | import * as tileMap from "../../";
4 |
5 | export function main() {
6 | const canvas = document.getElementById("mapCanvas");
7 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
8 | const context = yawgl.initContext(canvas);
9 |
10 | tileMap.init({
11 | context,
12 | center: [-73.885, 40.745],
13 | zoom: 9,
14 | // style: "mapbox://styles/mapbox/streets-v8",
15 | style: "./streets-v8-noInteractive.json",
16 | // eslint-disable-next-line max-len
17 | mapboxToken: "pk.eyJ1IjoiamhlbWJkIiwiYSI6ImNqcHpueHpyZjBlMjAzeG9kNG9oNzI2NTYifQ.K7fqhk2Z2YZ8NIV94M-5nA",
18 | }).promise.then(api => setup(api, canvas))
19 | .catch(console.log);
20 | }
21 |
22 | function setup(api, canvas) {
23 | const viewport = api.getViewport();
24 |
25 | const { k, x, y } = api.getTransform();
26 | let transform = d3.zoomIdentity
27 | .translate(x, y)
28 | .scale(k);
29 |
30 | const zoomer = d3.zoom()
31 | .scaleExtent([1 << 10, 1 << 26])
32 | .extent([[0, 0], viewport])
33 | .translateExtent([[-Infinity, -0.5], [Infinity, 0.5]])
34 | .on("zoom", (event) => {
35 | transform = event.transform;
36 | });
37 |
38 | d3.select(canvas)
39 | .call(zoomer)
40 | .call(zoomer.transform, transform);
41 |
42 | const loadStatus = document.getElementById("loadStatus");
43 |
44 | requestAnimationFrame(animate);
45 | function animate() {
46 | const pixRatio = window.devicePixelRatio;
47 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
48 | api.setTransform(transform);
49 | const percent = api.draw({ pixRatio }) * 100;
50 | loadStatus.innerHTML = (percent < 100)
51 | ? "Loading: " + percent.toFixed(0) + "%"
52 | : "Complete! " + percent.toFixed(0) + "%";
53 |
54 | requestAnimationFrame(animate);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/mapbox-streets/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | #main {
11 | width: 100%;
12 | height: 100vh;
13 | position: relative;
14 | }
15 | #mapCanvas {
16 | width: 100%;
17 | height: 100%;
18 | display: block;
19 | background-color: gray;
20 | position: relative;
21 | }
22 | .attribution {
23 | background: rgba(255, 255, 255, 0.8);
24 | position: absolute;
25 | bottom: 0;
26 | right: 0;
27 | padding: 0 4px 0 4px;
28 | }
29 | #loadStatus {
30 | position: absolute;
31 | top: 0;
32 | right: 0;
33 | width: 15ch;
34 | text-align: right;
35 | background: rgba(60, 60, 60, 0.5);
36 | color: white;
37 | padding: 0 4px 0 4px;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/rollup.config.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | import resolve from '@rollup/plugin-node-resolve';
3 |
4 | // Get a list of the directory names
5 | const dirNames = fs
6 | .readdirSync('./', { withFileTypes: true })
7 | .filter(d => d.isDirectory())
8 | .map(d => d.name);
9 |
10 | // Function to make a rollup config object from a directory name
11 | function makeConfig(dir) {
12 | return {
13 | input: dir + '/main.js',
14 | plugins: [
15 | resolve(),
16 | ],
17 | output: {
18 | file: dir + '/main.min.js',
19 | format: 'iife',
20 | name: 'app',
21 | }
22 | };
23 | }
24 |
25 | // Export an array of config objects
26 | export default dirNames.map(makeConfig);
27 |
--------------------------------------------------------------------------------
/examples/set-center-zoom/globe.svg:
--------------------------------------------------------------------------------
1 |
2 | 🌎
3 |
4 |
--------------------------------------------------------------------------------
/examples/set-center-zoom/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
tile-setter - beta
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
23 |
24 |
25 |
26 |
27 |
28 |
Camera Position:
29 |
Adjusted Zoom:
30 |
31 |
32 |
--------------------------------------------------------------------------------
/examples/set-center-zoom/klokantech-basic-style.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 8,
3 | "name": "Basic",
4 | "metadata": {
5 | "mapbox:autocomposite": false,
6 | "mapbox:type": "template",
7 | "maputnik:renderer": "mbgljs",
8 | "openmaptiles:version": "3.x",
9 | "openmaptiles:mapbox:owner": "openmaptiles",
10 | "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t"
11 | },
12 | "sources": {
13 | "openmaptiles": {
14 | "type": "vector",
15 | "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=mrAq6zQEFxOkanukNbGm"
16 | }
17 | },
18 | "glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=mrAq6zQEFxOkanukNbGm",
19 | "layers": [{
20 | "id": "background",
21 | "paint": {
22 | "background-color": "hsl(47, 26%, 88%)"
23 | },
24 | "type": "background"
25 | }, {
26 | "filter": ["all", ["==", "$type", "Polygon"],
27 | ["in", "class", "residential", "suburb", "neighbourhood"]
28 | ],
29 | "id": "landuse-residential",
30 | "layout": {
31 | "visibility": "visible"
32 | },
33 | "paint": {
34 | "fill-color": "hsl(47, 13%, 86%)",
35 | "fill-opacity": 0.7
36 | },
37 | "source": "openmaptiles",
38 | "source-layer": "landuse",
39 | "type": "fill"
40 | }, {
41 | "filter": ["==", "class", "grass"],
42 | "id": "landcover_grass",
43 | "paint": {
44 | "fill-color": "hsl(82, 46%, 72%)",
45 | "fill-opacity": 0.45
46 | },
47 | "source": "openmaptiles",
48 | "source-layer": "landcover",
49 | "type": "fill"
50 | }, {
51 | "filter": ["==", "class", "wood"],
52 | "id": "landcover_wood",
53 | "paint": {
54 | "fill-color": "hsl(82, 46%, 72%)",
55 | "fill-opacity": {
56 | "base": 1,
57 | "stops": [
58 | [8, 0.6],
59 | [22, 1]
60 | ]
61 | }
62 | },
63 | "source": "openmaptiles",
64 | "source-layer": "landcover",
65 | "type": "fill"
66 | }, {
67 | "filter": ["all", ["==", "$type", "Polygon"],
68 | ["!=", "intermittent", 1]
69 | ],
70 | "id": "water",
71 | "paint": {
72 | "fill-color": "hsl(205, 56%, 73%)"
73 | },
74 | "source": "openmaptiles",
75 | "source-layer": "water",
76 | "type": "fill",
77 | "layout": {
78 | "visibility": "visible"
79 | }
80 | }, {
81 | "filter": ["all", ["==", "$type", "Polygon"],
82 | ["==", "intermittent", 1]
83 | ],
84 | "id": "water_intermittent",
85 | "paint": {
86 | "fill-color": "hsl(205, 56%, 73%)",
87 | "fill-opacity": 0.7
88 | },
89 | "source": "openmaptiles",
90 | "source-layer": "water",
91 | "type": "fill",
92 | "layout": {
93 | "visibility": "visible"
94 | }
95 | }, {
96 | "filter": ["==", "subclass", "ice_shelf"],
97 | "id": "landcover-ice-shelf",
98 | "layout": {
99 | "visibility": "visible"
100 | },
101 | "paint": {
102 | "fill-color": "hsl(47, 26%, 88%)",
103 | "fill-opacity": 0.8
104 | },
105 | "source": "openmaptiles",
106 | "source-layer": "landcover",
107 | "type": "fill"
108 | }, {
109 | "filter": ["==", "subclass", "glacier"],
110 | "id": "landcover-glacier",
111 | "layout": {
112 | "visibility": "visible"
113 | },
114 | "paint": {
115 | "fill-color": "hsl(47, 22%, 94%)",
116 | "fill-opacity": {
117 | "base": 1,
118 | "stops": [
119 | [0, 1],
120 | [8, 0.5]
121 | ]
122 | }
123 | },
124 | "source": "openmaptiles",
125 | "source-layer": "landcover",
126 | "type": "fill"
127 | }, {
128 | "filter": ["all", ["in", "class", "sand"]],
129 | "id": "landcover_sand",
130 | "metadata": {},
131 | "paint": {
132 | "fill-antialias": false,
133 | "fill-color": "rgba(232, 214, 38, 1)",
134 | "fill-opacity": 0.3
135 | },
136 | "source": "openmaptiles",
137 | "source-layer": "landcover",
138 | "type": "fill"
139 | }, {
140 | "filter": ["==", "class", "agriculture"],
141 | "id": "landuse",
142 | "layout": {
143 | "visibility": "visible"
144 | },
145 | "paint": {
146 | "fill-color": "#eae0d0"
147 | },
148 | "source": "openmaptiles",
149 | "source-layer": "landuse",
150 | "type": "fill"
151 | }, {
152 | "filter": ["==", "class", "national_park"],
153 | "id": "landuse_overlay_national_park",
154 | "paint": {
155 | "fill-color": "#E1EBB0",
156 | "fill-opacity": {
157 | "base": 1,
158 | "stops": [
159 | [5, 0],
160 | [9, 0.75]
161 | ]
162 | }
163 | },
164 | "source": "openmaptiles",
165 | "source-layer": "landcover",
166 | "type": "fill"
167 | }, {
168 | "filter": ["all", ["==", "$type", "LineString"],
169 | ["==", "brunnel", "tunnel"]
170 | ],
171 | "id": "waterway-tunnel",
172 | "paint": {
173 | "line-color": "hsl(205, 56%, 73%)",
174 | "line-dasharray": [3, 3],
175 | "line-gap-width": {
176 | "stops": [
177 | [12, 0],
178 | [20, 6]
179 | ]
180 | },
181 | "line-opacity": 1,
182 | "line-width": {
183 | "base": 1.4,
184 | "stops": [
185 | [8, 1],
186 | [20, 2]
187 | ]
188 | }
189 | },
190 | "source": "openmaptiles",
191 | "source-layer": "waterway",
192 | "type": "line",
193 | "layout": {
194 | "visibility": "visible"
195 | }
196 | }, {
197 | "filter": ["all", ["==", "$type", "LineString"],
198 | ["!in", "brunnel", "tunnel", "bridge"],
199 | ["!=", "intermittent", 1]
200 | ],
201 | "id": "waterway",
202 | "paint": {
203 | "line-color": "hsl(205, 56%, 73%)",
204 | "line-opacity": 1,
205 | "line-width": {
206 | "base": 1.4,
207 | "stops": [
208 | [8, 1],
209 | [20, 8]
210 | ]
211 | }
212 | },
213 | "source": "openmaptiles",
214 | "source-layer": "waterway",
215 | "type": "line",
216 | "layout": {
217 | "visibility": "visible"
218 | }
219 | }, {
220 | "filter": ["all", ["==", "$type", "LineString"],
221 | ["!in", "brunnel", "tunnel", "bridge"],
222 | ["==", "intermittent", 1]
223 | ],
224 | "id": "waterway_intermittent",
225 | "paint": {
226 | "line-color": "hsl(205, 56%, 73%)",
227 | "line-opacity": 1,
228 | "line-width": {
229 | "base": 1.4,
230 | "stops": [
231 | [8, 1],
232 | [20, 8]
233 | ]
234 | },
235 | "line-dasharray": [2, 1]
236 | },
237 | "source": "openmaptiles",
238 | "source-layer": "waterway",
239 | "type": "line",
240 | "layout": {
241 | "visibility": "visible"
242 | }
243 | }, {
244 | "filter": ["all", ["==", "$type", "LineString"],
245 | ["==", "brunnel", "tunnel"],
246 | ["==", "class", "transit"]
247 | ],
248 | "id": "tunnel_railway_transit",
249 | "layout": {
250 | "line-cap": "butt",
251 | "line-join": "miter"
252 | },
253 | "minzoom": 0,
254 | "paint": {
255 | "line-color": "hsl(34, 12%, 66%)",
256 | "line-dasharray": [3, 3],
257 | "line-opacity": {
258 | "base": 1,
259 | "stops": [
260 | [11, 0],
261 | [16, 1]
262 | ]
263 | }
264 | },
265 | "source": "openmaptiles",
266 | "source-layer": "transportation",
267 | "type": "line"
268 | }, {
269 | "id": "building",
270 | "paint": {
271 | "fill-antialias": true,
272 | "fill-color": "rgba(222, 211, 190, 1)",
273 | "fill-opacity": {
274 | "base": 1,
275 | "stops": [
276 | [13, 0],
277 | [15, 1]
278 | ]
279 | },
280 | "fill-outline-color": {
281 | "stops": [
282 | [15, "rgba(212, 177, 146, 0)"],
283 | [16, "rgba(212, 177, 146, 0.5)"]
284 | ]
285 | }
286 | },
287 | "source": "openmaptiles",
288 | "source-layer": "building",
289 | "type": "fill"
290 | }, {
291 | "filter": ["==", "$type", "Point"],
292 | "id": "housenumber",
293 | "layout": {
294 | "text-field": "{housenumber}",
295 | "text-font": ["Noto Sans Regular"],
296 | "text-size": 10
297 | },
298 | "minzoom": 17,
299 | "paint": {
300 | "text-color": "rgba(212, 177, 146, 1)"
301 | },
302 | "source": "openmaptiles",
303 | "source-layer": "housenumber",
304 | "type": "symbol"
305 | }, {
306 | "id": "road_area_pier",
307 | "type": "fill",
308 | "metadata": {},
309 | "source": "openmaptiles",
310 | "source-layer": "transportation",
311 | "filter": ["all", ["==", "$type", "Polygon"],
312 | ["==", "class", "pier"]
313 | ],
314 | "layout": {
315 | "visibility": "visible"
316 | },
317 | "paint": {
318 | "fill-color": "hsl(47, 26%, 88%)",
319 | "fill-antialias": true
320 | }
321 | }, {
322 | "id": "road_pier",
323 | "type": "line",
324 | "metadata": {},
325 | "source": "openmaptiles",
326 | "source-layer": "transportation",
327 | "filter": ["all", ["==", "$type", "LineString"],
328 | ["in", "class", "pier"]
329 | ],
330 | "layout": {
331 | "line-cap": "round",
332 | "line-join": "round"
333 | },
334 | "paint": {
335 | "line-color": "hsl(47, 26%, 88%)",
336 | "line-width": {
337 | "base": 1.2,
338 | "stops": [
339 | [15, 1],
340 | [17, 4]
341 | ]
342 | }
343 | }
344 | }, {
345 | "filter": ["all", ["==", "$type", "Polygon"],
346 | ["in", "brunnel", "bridge"]
347 | ],
348 | "id": "road_bridge_area",
349 | "layout": {},
350 | "paint": {
351 | "fill-color": "hsl(47, 26%, 88%)",
352 | "fill-opacity": 0.5
353 | },
354 | "source": "openmaptiles",
355 | "source-layer": "transportation",
356 | "type": "fill"
357 | }, {
358 | "filter": ["all", ["==", "$type", "LineString"],
359 | ["in", "class", "path", "track"]
360 | ],
361 | "id": "road_path",
362 | "layout": {
363 | "line-cap": "square",
364 | "line-join": "bevel"
365 | },
366 | "paint": {
367 | "line-color": "hsl(0, 0%, 97%)",
368 | "line-dasharray": [1, 1],
369 | "line-width": {
370 | "base": 1.55,
371 | "stops": [
372 | [4, 0.25],
373 | [20, 10]
374 | ]
375 | }
376 | },
377 | "source": "openmaptiles",
378 | "source-layer": "transportation",
379 | "type": "line"
380 | }, {
381 | "filter": ["all", ["==", "$type", "LineString"],
382 | ["in", "class", "minor", "service"]
383 | ],
384 | "id": "road_minor",
385 | "layout": {
386 | "line-cap": "round",
387 | "line-join": "round"
388 | },
389 | "paint": {
390 | "line-color": "hsl(0, 0%, 97%)",
391 | "line-width": {
392 | "base": 1.55,
393 | "stops": [
394 | [4, 0.25],
395 | [20, 30]
396 | ]
397 | }
398 | },
399 | "source": "openmaptiles",
400 | "source-layer": "transportation",
401 | "type": "line",
402 | "minzoom": 13
403 | }, {
404 | "filter": ["all", ["==", "$type", "LineString"],
405 | ["==", "brunnel", "tunnel"],
406 | ["==", "class", "minor_road"]
407 | ],
408 | "id": "tunnel_minor",
409 | "layout": {
410 | "line-cap": "butt",
411 | "line-join": "miter"
412 | },
413 | "paint": {
414 | "line-color": "#efefef",
415 | "line-dasharray": [0.36, 0.18],
416 | "line-width": {
417 | "base": 1.55,
418 | "stops": [
419 | [4, 0.25],
420 | [20, 30]
421 | ]
422 | }
423 | },
424 | "source": "openmaptiles",
425 | "source-layer": "transportation",
426 | "type": "line"
427 | }, {
428 | "filter": ["all", ["==", "$type", "LineString"],
429 | ["==", "brunnel", "tunnel"],
430 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
431 | ],
432 | "id": "tunnel_major",
433 | "layout": {
434 | "line-cap": "butt",
435 | "line-join": "miter"
436 | },
437 | "paint": {
438 | "line-color": "#fff",
439 | "line-dasharray": [0.28, 0.14],
440 | "line-width": {
441 | "base": 1.4,
442 | "stops": [
443 | [6, 0.5],
444 | [20, 30]
445 | ]
446 | }
447 | },
448 | "source": "openmaptiles",
449 | "source-layer": "transportation",
450 | "type": "line"
451 | }, {
452 | "filter": ["all", ["==", "$type", "Polygon"],
453 | ["in", "class", "runway", "taxiway"]
454 | ],
455 | "id": "aeroway-area",
456 | "layout": {
457 | "visibility": "visible"
458 | },
459 | "metadata": {
460 | "mapbox:group": "1444849345966.4436"
461 | },
462 | "minzoom": 4,
463 | "paint": {
464 | "fill-color": "rgba(255, 255, 255, 1)",
465 | "fill-opacity": {
466 | "base": 1,
467 | "stops": [
468 | [13, 0],
469 | [14, 1]
470 | ]
471 | }
472 | },
473 | "source": "openmaptiles",
474 | "source-layer": "aeroway",
475 | "type": "fill"
476 | }, {
477 | "filter": ["all", ["in", "class", "taxiway"],
478 | ["==", "$type", "LineString"]
479 | ],
480 | "id": "aeroway-taxiway",
481 | "layout": {
482 | "line-cap": "round",
483 | "line-join": "round",
484 | "visibility": "visible"
485 | },
486 | "metadata": {
487 | "mapbox:group": "1444849345966.4436"
488 | },
489 | "minzoom": 12,
490 | "paint": {
491 | "line-color": "rgba(255, 255, 255, 1)",
492 | "line-opacity": 1,
493 | "line-width": {
494 | "base": 1.5,
495 | "stops": [
496 | [12, 1],
497 | [17, 10]
498 | ]
499 | }
500 | },
501 | "source": "openmaptiles",
502 | "source-layer": "aeroway",
503 | "type": "line"
504 | }, {
505 | "filter": ["all", ["in", "class", "runway"],
506 | ["==", "$type", "LineString"]
507 | ],
508 | "id": "aeroway-runway",
509 | "layout": {
510 | "line-cap": "round",
511 | "line-join": "round",
512 | "visibility": "visible"
513 | },
514 | "metadata": {
515 | "mapbox:group": "1444849345966.4436"
516 | },
517 | "minzoom": 4,
518 | "paint": {
519 | "line-color": "rgba(255, 255, 255, 1)",
520 | "line-opacity": 1,
521 | "line-width": {
522 | "base": 1.5,
523 | "stops": [
524 | [11, 4],
525 | [17, 50]
526 | ]
527 | }
528 | },
529 | "source": "openmaptiles",
530 | "source-layer": "aeroway",
531 | "type": "line"
532 | }, {
533 | "filter": ["all", ["==", "$type", "LineString"],
534 | ["in", "class", "trunk", "primary"]
535 | ],
536 | "id": "road_trunk_primary",
537 | "layout": {
538 | "line-cap": "round",
539 | "line-join": "round"
540 | },
541 | "paint": {
542 | "line-color": "#fff",
543 | "line-width": {
544 | "base": 1.4,
545 | "stops": [
546 | [6, 0.5],
547 | [20, 30]
548 | ]
549 | }
550 | },
551 | "source": "openmaptiles",
552 | "source-layer": "transportation",
553 | "type": "line"
554 | }, {
555 | "filter": ["all", ["==", "$type", "LineString"],
556 | ["in", "class", "secondary", "tertiary"]
557 | ],
558 | "id": "road_secondary_tertiary",
559 | "layout": {
560 | "line-cap": "round",
561 | "line-join": "round"
562 | },
563 | "paint": {
564 | "line-color": "#fff",
565 | "line-width": {
566 | "base": 1.4,
567 | "stops": [
568 | [6, 0.5],
569 | [20, 20]
570 | ]
571 | }
572 | },
573 | "source": "openmaptiles",
574 | "source-layer": "transportation",
575 | "type": "line"
576 | }, {
577 | "filter": ["all", ["==", "$type", "LineString"],
578 | ["==", "class", "motorway"]
579 | ],
580 | "id": "road_major_motorway",
581 | "layout": {
582 | "line-cap": "round",
583 | "line-join": "round"
584 | },
585 | "paint": {
586 | "line-color": "hsl(0, 0%, 100%)",
587 | "line-offset": 0,
588 | "line-width": {
589 | "base": 1.4,
590 | "stops": [
591 | [8, 1],
592 | [16, 10]
593 | ]
594 | }
595 | },
596 | "source": "openmaptiles",
597 | "source-layer": "transportation",
598 | "type": "line"
599 | }, {
600 | "filter": ["all", ["==", "class", "transit"],
601 | ["!=", "brunnel", "tunnel"]
602 | ],
603 | "id": "railway-transit",
604 | "layout": {
605 | "visibility": "visible"
606 | },
607 | "paint": {
608 | "line-color": "hsl(34, 12%, 66%)",
609 | "line-opacity": {
610 | "base": 1,
611 | "stops": [
612 | [11, 0],
613 | [16, 1]
614 | ]
615 | }
616 | },
617 | "source": "openmaptiles",
618 | "source-layer": "transportation",
619 | "type": "line"
620 | }, {
621 | "filter": ["==", "class", "rail"],
622 | "id": "railway",
623 | "layout": {
624 | "visibility": "visible"
625 | },
626 | "paint": {
627 | "line-color": "hsl(34, 12%, 66%)",
628 | "line-opacity": {
629 | "base": 1,
630 | "stops": [
631 | [11, 0],
632 | [16, 1]
633 | ]
634 | }
635 | },
636 | "source": "openmaptiles",
637 | "source-layer": "transportation",
638 | "type": "line"
639 | }, {
640 | "filter": ["all", ["==", "$type", "LineString"],
641 | ["==", "brunnel", "bridge"]
642 | ],
643 | "id": "waterway-bridge-case",
644 | "layout": {
645 | "line-cap": "butt",
646 | "line-join": "miter"
647 | },
648 | "paint": {
649 | "line-color": "#bbbbbb",
650 | "line-gap-width": {
651 | "base": 1.55,
652 | "stops": [
653 | [4, 0.25],
654 | [20, 30]
655 | ]
656 | },
657 | "line-width": {
658 | "base": 1.6,
659 | "stops": [
660 | [12, 0.5],
661 | [20, 10]
662 | ]
663 | }
664 | },
665 | "source": "openmaptiles",
666 | "source-layer": "waterway",
667 | "type": "line"
668 | }, {
669 | "filter": ["all", ["==", "$type", "LineString"],
670 | ["==", "brunnel", "bridge"]
671 | ],
672 | "id": "waterway-bridge",
673 | "layout": {
674 | "line-cap": "round",
675 | "line-join": "round"
676 | },
677 | "paint": {
678 | "line-color": "hsl(205, 56%, 73%)",
679 | "line-width": {
680 | "base": 1.55,
681 | "stops": [
682 | [4, 0.25],
683 | [20, 30]
684 | ]
685 | }
686 | },
687 | "source": "openmaptiles",
688 | "source-layer": "waterway",
689 | "type": "line"
690 | }, {
691 | "filter": ["all", ["==", "$type", "LineString"],
692 | ["==", "brunnel", "bridge"],
693 | ["==", "class", "minor_road"]
694 | ],
695 | "id": "bridge_minor case",
696 | "layout": {
697 | "line-cap": "butt",
698 | "line-join": "miter"
699 | },
700 | "paint": {
701 | "line-color": "#dedede",
702 | "line-gap-width": {
703 | "base": 1.55,
704 | "stops": [
705 | [4, 0.25],
706 | [20, 30]
707 | ]
708 | },
709 | "line-width": {
710 | "base": 1.6,
711 | "stops": [
712 | [12, 0.5],
713 | [20, 10]
714 | ]
715 | }
716 | },
717 | "source": "openmaptiles",
718 | "source-layer": "transportation",
719 | "type": "line"
720 | }, {
721 | "filter": ["all", ["==", "$type", "LineString"],
722 | ["==", "brunnel", "bridge"],
723 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
724 | ],
725 | "id": "bridge_major case",
726 | "layout": {
727 | "line-cap": "butt",
728 | "line-join": "miter"
729 | },
730 | "paint": {
731 | "line-color": "#dedede",
732 | "line-gap-width": {
733 | "base": 1.55,
734 | "stops": [
735 | [4, 0.25],
736 | [20, 30]
737 | ]
738 | },
739 | "line-width": {
740 | "base": 1.6,
741 | "stops": [
742 | [12, 0.5],
743 | [20, 10]
744 | ]
745 | }
746 | },
747 | "source": "openmaptiles",
748 | "source-layer": "transportation",
749 | "type": "line"
750 | }, {
751 | "filter": ["all", ["==", "$type", "LineString"],
752 | ["==", "brunnel", "bridge"],
753 | ["==", "class", "minor_road"]
754 | ],
755 | "id": "bridge_minor",
756 | "layout": {
757 | "line-cap": "round",
758 | "line-join": "round"
759 | },
760 | "paint": {
761 | "line-color": "#efefef",
762 | "line-width": {
763 | "base": 1.55,
764 | "stops": [
765 | [4, 0.25],
766 | [20, 30]
767 | ]
768 | }
769 | },
770 | "source": "openmaptiles",
771 | "source-layer": "transportation",
772 | "type": "line"
773 | }, {
774 | "filter": ["all", ["==", "$type", "LineString"],
775 | ["==", "brunnel", "bridge"],
776 | ["in", "class", "primary", "secondary", "tertiary", "trunk"]
777 | ],
778 | "id": "bridge_major",
779 | "layout": {
780 | "line-cap": "round",
781 | "line-join": "round"
782 | },
783 | "paint": {
784 | "line-color": "#fff",
785 | "line-width": {
786 | "base": 1.4,
787 | "stops": [
788 | [6, 0.5],
789 | [20, 30]
790 | ]
791 | }
792 | },
793 | "source": "openmaptiles",
794 | "source-layer": "transportation",
795 | "type": "line"
796 | }, {
797 | "filter": ["in", "admin_level", 4, 6, 8],
798 | "id": "admin_sub",
799 | "layout": {
800 | "visibility": "visible"
801 | },
802 | "paint": {
803 | "line-color": "hsla(0, 0%, 60%, 0.5)",
804 | "line-dasharray": [2, 1]
805 | },
806 | "source": "openmaptiles",
807 | "source-layer": "boundary",
808 | "type": "line"
809 | }, {
810 | "filter": ["all", ["<=", "admin_level", 2],
811 | ["==", "$type", "LineString"]
812 | ],
813 | "id": "admin_country",
814 | "layout": {
815 | "line-cap": "round",
816 | "line-join": "round"
817 | },
818 | "paint": {
819 | "line-color": "hsl(0, 0%, 60%)",
820 | "line-width": {
821 | "base": 1.3,
822 | "stops": [
823 | [3, 0.5],
824 | [22, 15]
825 | ]
826 | }
827 | },
828 | "source": "openmaptiles",
829 | "source-layer": "boundary",
830 | "type": "line"
831 | }, {
832 | "filter": ["all", ["==", "$type", "Point"],
833 | ["==", "rank", 1]
834 | ],
835 | "id": "poi_label",
836 | "layout": {
837 | "icon-size": 1,
838 | "text-anchor": "top",
839 | "text-field": "{name:latin}\n{name:nonlatin}",
840 | "text-font": ["Noto Sans Regular"],
841 | "text-max-width": 8,
842 | "text-offset": [0, 0.5],
843 | "text-size": 11,
844 | "visibility": "visible"
845 | },
846 | "minzoom": 14,
847 | "paint": {
848 | "text-color": "#666",
849 | "text-halo-blur": 1,
850 | "text-halo-color": "rgba(255,255,255,0.75)",
851 | "text-halo-width": 1
852 | },
853 | "source": "openmaptiles",
854 | "source-layer": "poi",
855 | "type": "symbol"
856 | }, {
857 | "filter": ["all", ["has", "iata"]],
858 | "id": "airport-label",
859 | "layout": {
860 | "icon-size": 1,
861 | "text-anchor": "top",
862 | "text-field": "{name:latin}\n{name:nonlatin}",
863 | "text-font": ["Noto Sans Regular"],
864 | "text-max-width": 8,
865 | "text-offset": [0, 0.5],
866 | "text-size": 11,
867 | "visibility": "visible"
868 | },
869 | "minzoom": 10,
870 | "paint": {
871 | "text-color": "#666",
872 | "text-halo-blur": 1,
873 | "text-halo-color": "rgba(255,255,255,0.75)",
874 | "text-halo-width": 1
875 | },
876 | "source": "openmaptiles",
877 | "source-layer": "aerodrome_label",
878 | "type": "symbol"
879 | }, {
880 | "filter": ["==", "$type", "LineString"],
881 | "id": "road_major_label",
882 | "layout": {
883 | "symbol-placement": "line",
884 | "text-field": "{name:latin} {name:nonlatin}",
885 | "text-font": ["Noto Sans Regular"],
886 | "text-letter-spacing": 0.1,
887 | "text-rotation-alignment": "map",
888 | "text-size": {
889 | "base": 1.4,
890 | "stops": [
891 | [10, 8],
892 | [20, 14]
893 | ]
894 | },
895 | "text-transform": "uppercase"
896 | },
897 | "paint": {
898 | "text-color": "#000",
899 | "text-halo-color": "hsl(0, 0%, 100%)",
900 | "text-halo-width": 2
901 | },
902 | "source": "openmaptiles",
903 | "source-layer": "transportation_name",
904 | "type": "symbol"
905 | }, {
906 | "filter": ["all", ["==", "$type", "Point"],
907 | ["!in", "class", "city", "state", "country", "continent"]
908 | ],
909 | "id": "place_label_other",
910 | "layout": {
911 | "text-anchor": "center",
912 | "text-field": "{name:latin}\n{name:nonlatin}",
913 | "text-font": ["Noto Sans Regular"],
914 | "text-max-width": 6,
915 | "text-size": {
916 | "stops": [
917 | [6, 10],
918 | [12, 14]
919 | ]
920 | },
921 | "visibility": "visible"
922 | },
923 | "minzoom": 8,
924 | "paint": {
925 | "text-color": "hsl(0, 0%, 25%)",
926 | "text-halo-blur": 0,
927 | "text-halo-color": "hsl(0, 0%, 100%)",
928 | "text-halo-width": 2
929 | },
930 | "source": "openmaptiles",
931 | "source-layer": "place",
932 | "type": "symbol"
933 | }, {
934 | "filter": ["all", ["==", "$type", "Point"],
935 | ["==", "class", "city"]
936 | ],
937 | "id": "place_label_city",
938 | "layout": {
939 | "text-field": "{name:latin}\n{name:nonlatin}",
940 | "text-font": ["Noto Sans Regular"],
941 | "text-max-width": 10,
942 | "text-size": {
943 | "stops": [
944 | [3, 12],
945 | [8, 16]
946 | ]
947 | }
948 | },
949 | "maxzoom": 16,
950 | "paint": {
951 | "text-color": "hsl(0, 0%, 0%)",
952 | "text-halo-blur": 0,
953 | "text-halo-color": "hsla(0, 0%, 100%, 0.75)",
954 | "text-halo-width": 2
955 | },
956 | "source": "openmaptiles",
957 | "source-layer": "place",
958 | "type": "symbol"
959 | }, {
960 | "filter": ["all", ["==", "$type", "Point"],
961 | ["==", "class", "country"],
962 | ["!has", "iso_a2"]
963 | ],
964 | "id": "country_label-other",
965 | "layout": {
966 | "text-field": "{name:latin}",
967 | "text-font": ["Noto Sans Regular"],
968 | "text-max-width": 10,
969 | "text-size": {
970 | "stops": [
971 | [3, 12],
972 | [8, 22]
973 | ]
974 | },
975 | "visibility": "visible"
976 | },
977 | "maxzoom": 12,
978 | "paint": {
979 | "text-color": "hsl(0, 0%, 13%)",
980 | "text-halo-blur": 0,
981 | "text-halo-color": "rgba(255,255,255,0.75)",
982 | "text-halo-width": 2
983 | },
984 | "source": "openmaptiles",
985 | "source-layer": "place",
986 | "type": "symbol"
987 | }, {
988 | "filter": ["all", ["==", "$type", "Point"],
989 | ["==", "class", "country"],
990 | ["has", "iso_a2"]
991 | ],
992 | "id": "country_label",
993 | "layout": {
994 | "text-field": "{name:latin}",
995 | "text-font": ["Noto Sans Bold"],
996 | "text-max-width": 10,
997 | "text-size": {
998 | "stops": [
999 | [3, 12],
1000 | [8, 22]
1001 | ]
1002 | },
1003 | "visibility": "visible"
1004 | },
1005 | "maxzoom": 12,
1006 | "paint": {
1007 | "text-color": "hsl(0, 0%, 13%)",
1008 | "text-halo-blur": 0,
1009 | "text-halo-color": "rgba(255,255,255,0.75)",
1010 | "text-halo-width": 2
1011 | },
1012 | "source": "openmaptiles",
1013 | "source-layer": "place",
1014 | "type": "symbol"
1015 | }],
1016 | "id": "basic"
1017 | }
1018 |
--------------------------------------------------------------------------------
/examples/set-center-zoom/main.js:
--------------------------------------------------------------------------------
1 | import * as yawgl from "yawgl";
2 | import * as tileMap from "../../";
3 |
4 | export function main() {
5 | const canvas = document.getElementById("mapCanvas");
6 | yawgl.resizeCanvasToDisplaySize(canvas, window.devicePixelRatio);
7 | const context = yawgl.initContext(canvas);
8 |
9 | tileMap.init({ context, style: "./klokantech-basic-style.json" })
10 | .promise.then(api => setup(api, canvas))
11 | .catch(console.log);
12 | }
13 |
14 | function setup(api, canvas) {
15 | const loadStatus = document.getElementById("loadStatus");
16 | const control = {
17 | longitude: document.getElementById("longitude"),
18 | latitude: document.getElementById("latitude"),
19 | zoom: document.getElementById("zoom"),
20 | };
21 | const camPos = document.getElementById("camPos");
22 | const actualZoom = document.getElementById("actualZoom");
23 |
24 | requestAnimationFrame(animate);
25 | function animate() {
26 | const pixRatio = window.devicePixelRatio;
27 | yawgl.resizeCanvasToDisplaySize(canvas, pixRatio);
28 |
29 | const [longitude, latitude, zoom] = Object.values(control)
30 | .map(v => v.valueAsNumber);
31 | api.setCenterZoom([longitude, latitude], zoom);
32 |
33 | const percent = api.draw({ pixRatio }) * 100;
34 | loadStatus.innerHTML = (percent < 100)
35 | ? "Loading: " + percent.toFixed(0) + "%"
36 | : "Complete! " + percent.toFixed(0) + "%";
37 |
38 | camPos.innerHTML = api.getCamPos().join(", ");
39 | actualZoom.innerHTML = Math.log2(api.getTransform().k) - 9;
40 |
41 | requestAnimationFrame(animate);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/examples/set-center-zoom/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | body {
5 | border: 0;
6 | margin: 0;
7 | font-family: "Noto Sans";
8 | font-size: 14px;
9 | }
10 | #main {
11 | width: 900px;
12 | height: 600px;
13 | position: relative;
14 | }
15 | #mapCanvas {
16 | width: 100%;
17 | height: 100%;
18 | display: block;
19 | background-color: gray;
20 | position: relative;
21 | }
22 | .attribution {
23 | background: rgba(255, 255, 255, 0.8);
24 | position: absolute;
25 | bottom: 0;
26 | right: 0;
27 | padding: 0 4px 0 4px;
28 | }
29 | #loadStatus {
30 | position: absolute;
31 | top: 0;
32 | right: 0;
33 | width: 15ch;
34 | text-align: right;
35 | background: rgba(60, 60, 60, 0.5);
36 | color: white;
37 | padding: 0 4px 0 4px;
38 | }
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tile-setter",
3 | "version": "0.1.12",
4 | "description": "Tiled vector map powered by a lightweight WebGL renderer",
5 | "main": "dist/tile-setter.js",
6 | "directories": {},
7 | "files": [
8 | "dist"
9 | ],
10 | "scripts": {
11 | "lint": "eslint src",
12 | "build": "npm run build-module && npm run build-examples",
13 | "build-module": "rollup -c build/rollup.config.js",
14 | "build-examples": "cd examples && rollup -c",
15 | "test": "npm run lint",
16 | "postversion": "git push && git push --tags"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/GlobeletJS/tile-setter.git"
21 | },
22 | "keywords": [
23 | "tiled",
24 | "vector",
25 | "map",
26 | "interactive"
27 | ],
28 | "author": "Jeshurun Hembd",
29 | "license": "MIT",
30 | "bugs": {
31 | "url": "https://github.com/GlobeletJS/tile-setter/issues"
32 | },
33 | "homepage": "https://github.com/GlobeletJS/tile-setter#readme",
34 | "devDependencies": {
35 | "@rollup/plugin-commonjs": "^21.0.1",
36 | "@rollup/plugin-node-resolve": "^13.1.3",
37 | "@turf/boolean-point-in-polygon": "^6.0.1",
38 | "d3": "^6.2.0",
39 | "eslint": "^8.12.0",
40 | "eslint-config-globeletjs": "^0.0.6",
41 | "rollup": "^2.70.1",
42 | "yawgl": "^0.4.2"
43 | },
44 | "dependencies": {
45 | "chunked-queue": "^0.1.4",
46 | "d3-tile": "github:GlobeletJS/d3-tile",
47 | "tile-batch": "^0.0.3",
48 | "tile-rack": "^1.0.4",
49 | "tile-stencil": "^0.4.12",
50 | "tile-worker": "^0.1.8"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/bounds.js:
--------------------------------------------------------------------------------
1 | import { forward } from "./projection.js";
2 |
3 | export function initBoundsCheck(source) {
4 | const {
5 | minzoom = 0,
6 | maxzoom = 30,
7 | bounds = [-180, -90, 180, 90],
8 | scheme = "xyz",
9 | } = source;
10 |
11 | // Convert bounds to Web Mercator (the projection ASSUMED by tilejson-spec)
12 | const radianBounds = bounds.map(c => c * Math.PI / 180.0);
13 | let [xmin, ymax] = forward(radianBounds.slice(0, 2));
14 | let [xmax, ymin] = forward(radianBounds.slice(2, 4));
15 | // TODO: this looks weird? min/max is mathematical, regardless of scheme
16 | if (scheme === "tms") [ymin, ymax] = [ymax, ymin];
17 |
18 | return function(z, x, y) {
19 | // Return true if out of bounds
20 | if (z < minzoom || maxzoom < z) return true;
21 |
22 | const zFac = 1 / 2 ** z;
23 | if ((x + 1) * zFac < xmin || xmax < x * zFac) return true;
24 | if ((y + 1) * zFac < ymin || ymax < y * zFac) return true;
25 |
26 | return false;
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/src/caches.js:
--------------------------------------------------------------------------------
1 | import * as chunkedQueue from "chunked-queue";
2 | import * as tileWorker from "tile-worker";
3 | import { initCache } from "tile-rack";
4 |
5 | export function initCaches({ context, glyphs, spriteData }) {
6 | const queue = chunkedQueue.init();
7 |
8 | function addSource({ source, layers }) {
9 | const loader = initLoader(source, layers);
10 | const factory = buildFactory(loader);
11 | return initCache({ create: factory, size: 1.0 });
12 | }
13 |
14 | function initLoader(source, layers) {
15 | switch (source.type) {
16 | case "vector":
17 | case "geojson":
18 | return tileWorker.init({
19 | context, queue, source, glyphs, spriteData, layers,
20 | threads: (source.type === "geojson") ? 1 : 2,
21 | });
22 | case "raster":
23 | return; // initRasterLoader(source, layers);
24 | default: return;
25 | }
26 | }
27 |
28 | return {
29 | addSource,
30 | sortTasks: queue.sortTasks,
31 | queuedTasks: queue.countTasks,
32 | };
33 | }
34 |
35 | function buildFactory(loader) {
36 | return function(z, x, y) {
37 | const id = [z, x, y].join("/");
38 | const tile = { z, x, y, id, priority: 0 };
39 |
40 | function callback(err, data) {
41 | if (err) return; // console.log(err);
42 | tile.data = data;
43 | tile.ready = true;
44 | }
45 |
46 | const getPriority = () => tile.priority;
47 | const loadTask = loader.request({ z, x, y, getPriority, callback });
48 |
49 | tile.cancel = () => {
50 | loadTask.abort();
51 | tile.canceled = true;
52 | };
53 |
54 | return tile;
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/src/coords.js:
--------------------------------------------------------------------------------
1 | export function initCoords({ getViewport, center, zoom, clampY, projection }) {
2 | const { log2, min, max, round, floor } = Math;
3 | const minTileSize = 256;
4 | const logTileSize = log2(minTileSize);
5 |
6 | const transform = {
7 | k: 1, // Size of the world map, in pixels
8 | x: 0, // Rightward shift of lon = 0 from left edge of viewport, in pixels
9 | y: 0, // Downward shift of lat = 0 from top edge of viewport, in pixels
10 | };
11 | const camPos = new Float64Array([0.5, 0.5]);
12 | const scale = new Float64Array([1.0, 1.0]);
13 |
14 | setCenterZoom(center, zoom);
15 |
16 | return {
17 | getViewport,
18 | getTransform: () => Object.assign({}, transform),
19 | getZoom: () => max(0, log2(transform.k) - 9),
20 | getCamPos: () => camPos.slice(),
21 | getScale: () => scale.slice(),
22 |
23 | setTransform,
24 | setCenterZoom,
25 |
26 | localToGlobal,
27 | };
28 |
29 | function setTransform({ k, x, y }) {
30 | // Input transforms map coordinates [x, y] into viewport coordinates
31 | const [width, height] = getViewport();
32 |
33 | // Round k to ensure tile pixels align with screen pixels
34 | const z = log2(k) - logTileSize;
35 | const z0 = floor(z);
36 | const tileScale = round(2 ** (z - z0) * minTileSize);
37 | const kNew = clampY
38 | ? max(2 ** z0 * tileScale, height)
39 | : 2 ** z0 * tileScale;
40 |
41 | // Adjust translation for the change in scale, and snap to pixel grid
42 | const kScale = kNew / k;
43 | // Keep the same map pixel at the center of the viewport
44 | const sx = kScale * x + (1 - kScale) * width / 2;
45 | const sy = kScale * y + (1 - kScale) * height / 2;
46 | // Limit Y so the map doesn't cross a pole
47 | const yLim = clampY
48 | ? min(max(-kNew / 2 + height, sy), kNew / 2)
49 | : sy;
50 | const [xNew, yNew] = [sx, yLim].map(round);
51 |
52 | // Make sure camera is still pointing at the original location: shift from
53 | // the center [0.5, 0.5] by the change in the translation due to rounding
54 | camPos[0] = 0.5 + (xNew - sx) / width;
55 | camPos[1] = 0.5 + (yNew - sy) / height;
56 |
57 | // Store the scale of the current map relative to the entire world
58 | scale[0] = kNew / width;
59 | scale[1] = kNew / height;
60 |
61 | // Return a flag indicating whether the transform changed
62 | const { k: kOld, x: xOld, y: yOld } = transform;
63 | if (kNew == kOld && xNew == xOld && yNew == yOld) return false;
64 | Object.assign(transform, { k: kNew, x: xNew, y: yNew });
65 | return true;
66 | }
67 |
68 | function setCenterZoom(center, zoom) {
69 | const [width, height] = getViewport();
70 |
71 | const k = 512 * 2 ** zoom;
72 | const [xr, yr] = projection.forward(center);
73 | const x = (0.5 - xr) * k + width / 2;
74 | const y = (0.5 - yr) * k + height / 2;
75 |
76 | return setTransform({ k, x, y });
77 | }
78 |
79 | function localToGlobal([xl, yl]) {
80 | // Convert local map pixels to global XY
81 | const { x: tx, y: ty, k } = transform;
82 | // tx, ty is the shift of the map center (in pixels)
83 | // relative to the viewport origin (top left corner)
84 | const xg = (xl - tx) / k + 0.5;
85 | const yg = (yl - ty) / k + 0.5;
86 | // Global XY are in the range [0.0, 1.0]. Wrap values outside
87 | return [xg - floor(xg), yg - floor(yg)];
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/feature-coords.js:
--------------------------------------------------------------------------------
1 | export function transformFeatureCoords(feature, transform) {
2 | const { type, properties, geometry } = feature;
3 |
4 | return {
5 | type, properties,
6 | geometry: transformGeometry(geometry, transform),
7 | };
8 | }
9 |
10 | function transformGeometry(geometry, transform) {
11 | const { type, coordinates } = geometry;
12 |
13 | return {
14 | type,
15 | coordinates: transformCoords(type, coordinates, transform),
16 | };
17 | }
18 |
19 | function transformCoords(type, coordinates, transform) {
20 | switch (type) {
21 | case "Point":
22 | return transform(coordinates);
23 |
24 | case "MultiPoint":
25 | case "LineString":
26 | return coordinates.map(transform);
27 |
28 | case "MultiLineString":
29 | case "Polygon":
30 | return coordinates.map(ring => ring.map(transform));
31 |
32 | case "MultiPolygon":
33 | return coordinates.map(polygon => {
34 | return polygon.map(ring => ring.map(transform));
35 | });
36 |
37 | default:
38 | throw Error("transformCoords: unknown geometry type!");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/grid.js:
--------------------------------------------------------------------------------
1 | import { initBoundsCheck } from "./bounds.js";
2 | import * as d3 from "d3-tile";
3 | import { getTileMetric } from "./metric.js";
4 |
5 | export function initTileGrid({ key, source, tileCache }) {
6 | const { tileSize = 512, maxzoom = 30 } = source;
7 | const outOfBounds = initBoundsCheck(source);
8 |
9 | let numTiles = 0;
10 |
11 | // Set up the tile layout
12 | const layout = d3.tile()
13 | .tileSize(tileSize * Math.sqrt(2)) // Don't let d3-tile squeeze the tiles
14 | .maxZoom(maxzoom)
15 | .clampX(false); // Allow panning across the antimeridian
16 |
17 | function getTiles(viewport, transform) {
18 | // Get the grid of tiles needed for the current viewport
19 | layout.size(viewport);
20 | const tiles = layout(transform);
21 |
22 | // Update tile priorities based on the new grid
23 | const metric = getTileMetric(layout, tiles, 1.0);
24 | tileCache.process(tile => { tile.priority = metric(tile); });
25 | numTiles = tileCache.drop(tile => tile.priority > 0.8);
26 | const stopCondition = ([z, x, y]) => {
27 | return outOfBounds(z, x, y) || metric({ z, x, y }) > 0.8;
28 | };
29 |
30 | // Retrieve a tile box for every tile in the grid
31 | let tilesDone = 0;
32 | const grid = tiles.map(([x, y, z]) => {
33 | const [xw, yw, zw] = d3.tileWrap([x, y, z]);
34 |
35 | if (outOfBounds(zw, xw, yw)) {
36 | tilesDone += 1; // Count it as complete
37 | return;
38 | }
39 |
40 | const box = tileCache.retrieve([zw, xw, yw], stopCondition);
41 | if (!box) return;
42 |
43 | tilesDone += box.sw ** 2;
44 | return Object.assign(box, { x, xw, y, yw, z });
45 | }).filter(t => t !== undefined);
46 |
47 | grid.loaded = tilesDone / tiles.length;
48 | grid.scale = tiles.scale;
49 | grid.translate = tiles.translate.slice();
50 |
51 | return grid;
52 | }
53 |
54 | return { key, getTiles, numTiles: () => numTiles };
55 | }
56 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { setParams } from "./params.js";
2 | import { loadStyle } from "tile-stencil";
3 | import { initSources } from "./sources.js";
4 | import { initRenderer } from "./renderer.js";
5 | import { initSelector } from "./selection.js";
6 |
7 | export function init(userParams) {
8 | const params = setParams(userParams);
9 |
10 | // Set up dummy API
11 | const api = {
12 | gl: params.gl,
13 | projection: params.projection,
14 | draw: () => null,
15 | select: () => null,
16 | };
17 |
18 | // Extend with coordinate methods (SEE coords.js for API)
19 | Object.assign(api, params.coords);
20 |
21 | // Get style document, parse
22 | api.promise = loadStyle(params.style, params.mapboxToken)
23 | .then( styleDoc => setup(styleDoc, params, api) );
24 |
25 | return api;
26 | }
27 |
28 | function setup(styleDoc, params, api) {
29 | const { context, coords, projection } = params;
30 | const sources = initSources(styleDoc, context, api);
31 |
32 | // Set up interactive toggling of layer visibility
33 | styleDoc.layers.forEach(l => {
34 | // TODO: use functionalized visibility from tile-stencil?
35 | const visibility = l.layout ? l.layout.visibility : false;
36 | l.visible = (!visibility || visibility === "visible");
37 | });
38 |
39 | function setLayerVisibility(id, visibility) {
40 | const layer = styleDoc.layers.find(l => l.id === id);
41 | if (layer) layer.visible = visibility;
42 | }
43 | api.hideLayer = (id) => setLayerVisibility(id, false);
44 | api.showLayer = (id) => setLayerVisibility(id, true);
45 |
46 | const render = initRenderer(context, coords, styleDoc);
47 |
48 | api.draw = function({ pixRatio = 1, dzScale = 1 } = {}) {
49 | const loadStatus = sources.loadTilesets();
50 | render(sources.tilesets, pixRatio, dzScale);
51 | return loadStatus;
52 | };
53 |
54 | api.select = initSelector(sources, projection);
55 |
56 | return api;
57 | }
58 |
--------------------------------------------------------------------------------
/src/metric.js:
--------------------------------------------------------------------------------
1 | export function getTileMetric(layout, tileset, padding = 0.595) {
2 | const { min, max, sqrt } = Math;
3 | const zoom = tileset[0][2];
4 | const nTiles = 2 ** zoom;
5 | const scaleFac = layout.tileSize() / tileset.scale;
6 | const mapResolution = min(max(1.0 / sqrt(2), scaleFac), sqrt(2));
7 |
8 | function wrap(x, xmax) {
9 | while (x < 0) x += xmax;
10 | while (x >= xmax) x -= xmax;
11 | return x;
12 | }
13 |
14 | // Map is viewport + padding. Store the map cornerpoints in tile units
15 | const [vpWidth, vpHeight] = layout.size();
16 | const pad = padding * mapResolution; // In tile units
17 | const x0 = wrap(-tileset.translate[0] - pad, nTiles);
18 | const x1 = x0 + vpWidth / tileset.scale + 2 * pad; // May cross antimeridian
19 | const y0 = -tileset.translate[1] - pad;
20 | const y1 = y0 + vpHeight / tileset.scale + 2 * pad;
21 |
22 | return function(tile) {
23 | const zoomFac = 2 ** (zoom - tile.z);
24 | const tileResolution = min(1, mapResolution / zoomFac);
25 |
26 | // Convert the tile cornerpoints to tile units at MAP zoom level
27 | const tb = {
28 | x0: tile.x * zoomFac,
29 | x1: (tile.x + 1) * zoomFac,
30 | y0: tile.y * zoomFac,
31 | y1: (tile.y + 1) * zoomFac
32 | };
33 |
34 | // Find intersections of map and tile. Be careful with the antimeridian
35 | const xOverlap = max(
36 | // Test for intersection with the tile in its raw position
37 | min(x1, tb.x1) - max(x0, tb.x0),
38 | // Test with the tile shifted across the antimeridian
39 | min(x1, tb.x1 + nTiles) - max(x0, tb.x0 + nTiles)
40 | );
41 | const yOverlap = min(y1, tb.y1) - max(y0, tb.y0);
42 | const overlapArea = max(0, xOverlap) * max(0, yOverlap);
43 | const visibleArea = overlapArea / mapResolution ** 2;
44 |
45 | // Flip sign to put most valuable tiles at the minimum. TODO: unnecessary?
46 | return 1.0 - visibleArea * tileResolution;
47 | };
48 | }
49 |
--------------------------------------------------------------------------------
/src/params.js:
--------------------------------------------------------------------------------
1 | import { getProjection } from "./projection.js";
2 | import { initCoords } from "./coords.js";
3 | import { initGL as initGLpaint } from "tile-batch";
4 |
5 | export function setParams(userParams) {
6 | const gl = userParams.context.gl;
7 | if (!(gl instanceof WebGL2RenderingContext)) fail("no valid WebGL context");
8 |
9 | const {
10 | context,
11 | framebuffer = { buffer: null, size: gl.canvas },
12 | center = [0.0, 0.0], // ASSUMED to be in degrees!
13 | zoom = 4,
14 | style,
15 | mapboxToken,
16 | clampY = true,
17 | units = "degrees",
18 | projScale = false,
19 | } = userParams;
20 |
21 | const { buffer, size } = framebuffer;
22 | if (!(buffer instanceof WebGLFramebuffer) && buffer !== null) {
23 | fail("no valid framebuffer");
24 | }
25 |
26 | const sizeType =
27 | (size && allPosInts(size.clientWidth, size.clientHeight)) ? "client" :
28 | (size && allPosInts(size.width, size.height)) ? "raw" :
29 | null;
30 | if (!sizeType) fail("invalid size object in framebuffer");
31 | const getViewport = (sizeType === "client")
32 | ? () => ([size.clientWidth, size.clientHeight])
33 | : () => ([size.width, size.height]);
34 |
35 | const validUnits = ["degrees", "radians", "xy"];
36 | if (!validUnits.includes(units)) fail("invalid units");
37 | const projection = getProjection(units);
38 |
39 | // Convert initial center position from degrees to the specified units
40 | if (!checkCoords(center, 2)) fail("invalid center coordinates");
41 | const projCenter = getProjection("degrees").forward(center);
42 | if (!all0to1(...projCenter)) fail ("invalid center coordinates");
43 | const invCenter = projection.inverse(projCenter);
44 |
45 | if (!Number.isFinite(zoom)) fail("invalid zoom value");
46 |
47 | const coords = initCoords({
48 | getViewport, projection,
49 | center: invCenter,
50 | zoom, clampY,
51 | });
52 |
53 | return {
54 | gl, framebuffer,
55 | projection, coords,
56 | style, mapboxToken,
57 | context: initGLpaint({ context, framebuffer, projScale }),
58 | };
59 | }
60 |
61 | function fail(message) {
62 | throw Error("tile-setter parameter check: " + message + "!");
63 | }
64 |
65 | function allPosInts(...vals) {
66 | return vals.every(v => Number.isInteger(v) && v > 0);
67 | }
68 |
69 | function all0to1(...vals) {
70 | return vals.every(v => Number.isFinite(v) && v >= 0 && v <= 1);
71 | }
72 |
73 | function checkCoords(p, n) {
74 | const isArray = Array.isArray(p) ||
75 | (ArrayBuffer.isView(p) && !(p instanceof DataView));
76 | return isArray && p.length >= n &&
77 | p.slice(0, n).every(Number.isFinite);
78 | }
79 |
--------------------------------------------------------------------------------
/src/projection.js:
--------------------------------------------------------------------------------
1 | const { cos, tan, atan, exp, log, PI, min, max } = Math;
2 | // Maximum latitude for Web Mercator: 85.0113 degrees. Beware rounding!
3 | const maxMercLat = 2.0 * atan(exp(PI)) - PI / 2.0;
4 | const clipLat = (lat) => min(max(-maxMercLat, lat), maxMercLat);
5 | const degrees = 180.0 / PI;
6 |
7 | export function getProjection(units) {
8 | switch (units) {
9 | case "xy":
10 | return { // Input coordinates already projected to XY
11 | forward: p => p,
12 | inverse: p => p,
13 | scale: () => 1.0,
14 | };
15 | case "radians":
16 | return {
17 | forward,
18 | inverse,
19 | scale,
20 | };
21 | case "degrees":
22 | return {
23 | forward: (pt) => forward(pt.map(c => c / degrees)),
24 | inverse: (pt) => inverse(pt).map(c => c * degrees),
25 | scale: (pt) => scale(pt.map(c => c / degrees)),
26 | };
27 | default:
28 | throw Error("getProjection: unknown units = " + units);
29 | }
30 | }
31 |
32 | export function forward([lon, lat]) {
33 | // Convert input longitude in radians to a Web Mercator x-coordinate
34 | // where x = 0 at lon = -PI, x = 1 at lon = +PI
35 | const x = 0.5 + 0.5 * lon / PI;
36 |
37 | // Convert input latitude in radians to a Web Mercator y-coordinate
38 | // where y = 0 at lat = maxMercLat, y = 1 at lat = -maxMercLat
39 | const y = 0.5 - 0.5 / PI *
40 | log(tan(PI / 4.0 + clipLat(lat) / 2.0));
41 |
42 | // Clip y to the range [0, 1] (it does not wrap around)
43 | return [x, min(max(0.0, y), 1.0)];
44 | }
45 |
46 | export function inverse([x, y]) {
47 | const lon = 2.0 * (x - 0.5) * PI;
48 | const lat = 2.0 * atan(exp(PI * (1.0 - 2.0 * y))) - PI / 2;
49 |
50 | return [lon, lat];
51 | }
52 |
53 | export function scale(point) {
54 | const lat = clipLat(point[1]);
55 | // Return value scales a (differential) distance along the plane tangent to
56 | // the sphere at [lon, lat] to a distance in map coordinates.
57 | // NOTE: ASSUMES a sphere of radius 1! Input distances should be
58 | // pre-normalized by the appropriate radius
59 | return 1 / (2 * PI * cos(lat));
60 | }
61 |
--------------------------------------------------------------------------------
/src/raster.js:
--------------------------------------------------------------------------------
1 | export function initRasterLoader(source) {
2 | const getURL = initUrlFunc(source.tiles);
3 |
4 | function request({ z, x, y, callback }) {
5 | const href = getURL(z, x, y);
6 | const errMsg = "ERROR in loadImage for href " + href;
7 |
8 | const img = new Image();
9 | img.onerror = () => callback(errMsg);
10 | img.onload = () => {
11 | return img.complete && img.naturalWidth !== 0
12 | ? callback(null, img)
13 | : callback(errMsg);
14 | };
15 | img.crossOrigin = "anonymous";
16 | img.src = href;
17 |
18 | function abort() {
19 | img.src = "";
20 | }
21 |
22 | return { abort };
23 | }
24 |
25 | return { request };
26 | }
27 |
28 | function initUrlFunc(endpoints) {
29 | if (!endpoints || !endpoints.length) {
30 | throw Error("ERROR in initUrlFunc: no valid tile endpoints!");
31 | }
32 |
33 | // Use a different endpoint for each request
34 | let index = 0;
35 |
36 | return function(z, x, y) {
37 | index = (index + 1) % endpoints.length;
38 | const endpoint = endpoints[index];
39 | return endpoint
40 | .replace(/{z}/, z)
41 | .replace(/{x}/, x)
42 | .replace(/{y}/, y);
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/src/renderer.js:
--------------------------------------------------------------------------------
1 | import { getStyleFuncs } from "tile-stencil";
2 |
3 | export function initRenderer(context, coords, style) {
4 | const { PI, cosh } = Math;
5 | const { layers, spriteData } = style;
6 |
7 | if (spriteData) context.loadSprite(spriteData.image);
8 |
9 | const painters = layers.map(layer => {
10 | const painter = context.initPainter(getStyleFuncs(layer));
11 | return Object.assign(painter, { visible: () => layer.visible });
12 | });
13 |
14 | return function(tilesets, pixRatio = 1, dzScale = 1) {
15 | context.prep();
16 | const zoom = coords.getZoom();
17 |
18 | const localCamY = coords.getCamPos()[1] * coords.getViewport()[1];
19 | const globalCamY = coords.localToGlobal([0.0, localCamY])[1];
20 | const cameraScale = cosh(2 * PI * (0.5 - globalCamY)) * dzScale;
21 |
22 | painters.forEach(painter => {
23 | if (zoom < painter.minzoom || painter.maxzoom < zoom) return;
24 | if (!painter.visible()) return;
25 | const tileset = tilesets[painter.source];
26 | painter({ tileset, zoom, pixRatio, cameraScale });
27 | });
28 | };
29 | }
30 |
--------------------------------------------------------------------------------
/src/selection.js:
--------------------------------------------------------------------------------
1 | import { getTileTransform } from "./tile-coords.js";
2 | import { transformFeatureCoords } from "./feature-coords.js";
3 | import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
4 |
5 | export function initSelector(sources, projection) {
6 | const tileSize = 512; // TODO: don't assume this
7 |
8 | return function({ layer, point, radius = 5 }) {
9 | const tileset = sources.getLayerTiles(layer);
10 | if (!tileset || !tileset.length) return;
11 |
12 | // Find the tile, and get the layer features
13 | const nTiles = 2 ** tileset[0].z;
14 | const [ix, iy] = projection.forward(point)
15 | .map(c => Math.floor(c * nTiles));
16 | const tileBox = tileset.find(({ xw, yw }) => xw == ix && yw == iy);
17 | if (!tileBox) return;
18 | const dataLayer = tileBox.tile.data.layers[layer];
19 | if (!dataLayer) return;
20 | // const { features, extent = tileSize } = dataLayer;
21 | const { features } = dataLayer;
22 | const extent = tileSize; // TODO: use data extent
23 | if (!features || !features.length) return;
24 |
25 | // Convert point to tile coordinates
26 | const transform = getTileTransform(tileBox.tile, extent, projection);
27 | const tileXY = transform.forward(point);
28 |
29 | // Find the nearest feature
30 | const { distance, feature } = features.reduce((nearest, feature) => {
31 | const distance = measureDistance(tileXY, feature.geometry);
32 | if (distance < nearest.distance) nearest = { distance, feature };
33 | return nearest;
34 | }, { distance: Infinity });
35 |
36 | // Threshold distance should be in units of screen pixels
37 | const threshold = radius * extent / tileset.scale * tileBox.sw;
38 | if (distance > threshold) return;
39 |
40 | // Convert feature coordinates from tile XY units back to input units
41 | return transformFeatureCoords(feature, transform.inverse);
42 | };
43 | }
44 |
45 | export function measureDistance(pt, geometry) {
46 | const { type, coordinates } = geometry;
47 |
48 | switch (type) {
49 | case "Point":
50 | return distToPoint(coordinates, pt);
51 | case "Polygon":
52 | case "MultiPolygon":
53 | return booleanPointInPolygon(pt, geometry) ? 0 : Infinity;
54 | default:
55 | return; // Unknown feature type!
56 | }
57 | }
58 |
59 | function distToPoint(coords, pt) {
60 | const [x, y] = coords;
61 | return Math.sqrt((x - pt[0]) ** 2 + (y - pt[1]) ** 2);
62 | }
63 |
--------------------------------------------------------------------------------
/src/sources.js:
--------------------------------------------------------------------------------
1 | import { initCaches } from "./caches.js";
2 | import { initTileGrid } from "./grid.js";
3 |
4 | export function initSources(style, context, coords) {
5 | const { sources: sourceDescriptions, glyphs, spriteData, layers } = style;
6 |
7 | const caches = initCaches({ context, glyphs, spriteData });
8 | const tilesets = {};
9 | const layerSources = layers.reduce((d, l) => (d[l.id] = l.source, d), {});
10 |
11 | const grids = Object.entries(sourceDescriptions).map(([key, source]) => {
12 | const subset = layers.filter(l => l.source === key);
13 | if (!subset.length) return;
14 |
15 | const tileCache = caches.addSource({ source, layers: subset });
16 | if (!tileCache) return;
17 | const grid = initTileGrid({ key, source, tileCache });
18 |
19 | grid.layers = subset;
20 | return grid;
21 | }).filter(s => s !== undefined);
22 |
23 | function loadTilesets() {
24 | const viewport = coords.getViewport();
25 | const transform = coords.getTransform();
26 | grids.forEach(grid => {
27 | if (!grid.layers.some(l => l.visible)) return;
28 | tilesets[grid.key] = grid.getTiles(viewport, transform);
29 | });
30 | caches.sortTasks();
31 | const loadStatus = Object.values(tilesets).map(t => t.loaded)
32 | .reduce((s, l) => s + l) / grids.length;
33 | return loadStatus;
34 | }
35 |
36 | return {
37 | tilesets,
38 | getLayerTiles: (layer) => tilesets[layerSources[layer]],
39 | loadTilesets,
40 | queuedTasks: caches.queuedTasks,
41 | };
42 | }
43 |
--------------------------------------------------------------------------------
/src/tile-coords.js:
--------------------------------------------------------------------------------
1 | export function getTileTransform(tile, extent, projection) {
2 | const { z, x, y } = tile;
3 | const nTiles = 2 ** z;
4 | const translate = [x, y];
5 |
6 | const transform = {
7 | // Global XY to local tile XY
8 | forward: (pt) => pt.map((g, i) => (g * nTiles - translate[i]) * extent),
9 |
10 | // Local tile XY to global XY
11 | inverse: (pt) => pt.map((l, i) => (l / extent + translate[i]) / nTiles),
12 | };
13 |
14 | return {
15 | forward: (pt) => transform.forward(projection.forward(pt)),
16 | inverse: (pt) => projection.inverse(transform.inverse(pt)),
17 | };
18 | }
19 |
--------------------------------------------------------------------------------