diff --git a/.eslintrc b/.eslintrc index e9e4b7b8166..4be3a92223f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,18 +6,12 @@ ], "parser": "babel-eslint", "parserOptions": { - "sourceType": "script" + "sourceType": "module" }, "plugins": [ "flowtype", "import" ], - "settings": { - "import/ignore": [ - "@mapbox/shelf-pack", - "@mapbox/whoots-js" - ] - }, "rules": { "array-bracket-spacing": "off", "block-scoped-var": "error", diff --git a/.flowconfig b/.flowconfig index 6a02582fad3..566114ad8a2 100644 --- a/.flowconfig +++ b/.flowconfig @@ -8,8 +8,11 @@ .*/node_modules/htmltojsx/.* .*/node_modules/documentation/.* .*/node_modules/module-deps/.* +.*/node_modules/bcryptjs/.* +.*/node_modules/@mapbox/geojson-types/fixtures/.* .*/test/unit/style-spec/fixture/invalidjson.input.json .*/test/integration/render-tests/.* +.*/test/build/downstream-flow-fixture/.* [version] -0.69.0 +0.77.0 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 90c277784af..f03a3be8564 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,8 @@ + + - [ ] briefly describe the changes in this PR - [ ] write tests for all new functionality - [ ] document any changes to public APIs diff --git a/.topissuesrc b/.topissuesrc index f1ca5418e96..d48d7eaaf94 100644 --- a/.topissuesrc +++ b/.topissuesrc @@ -1,7 +1,7 @@ { "labels": { "release blocker :no_entry:": 25, - "high priority :exclamation:": 7, + "high priority": 7, "medium priority": 5, "bug :beetle:": 2 } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dc88602870..4854949ff7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,33 @@ -## 0.47.0 - -### ⚠️ Breaking changes +## 0.48.0 ### ✨ Features and improvements * Add `Map#fitScreenCoordinates`: fits viewport to two points, similar to `Map#fitBounds` but uses screen coordinates and supports non-zero map bearings. ([#6894](https://github.com/mapbox/mapbox-gl-js/pull/6894)) -### 🐛 Bug fixes +## 0.47.0 + +## ✨ Features and improvements +* Add configurable drag pan threshold ([#6809](https://github.com/mapbox/mapbox-gl-js/pull/6809)) (h/t [msbarry](https://github.com/msbarry)) +* Add `raster-resampling` raster paint property ([#6411](https://github.com/mapbox/mapbox-gl-js/pull/6411)) (h/t [andrewharvey](https://github.com/andrewharvey)) +* Add `symbol-placement: line-center` ([#6821](https://github.com/mapbox/mapbox-gl-js/pull/6821)) +* Add methods for inspecting GeoJSON clusters ([#3318](https://github.com/mapbox/mapbox-gl-js/issues/3318), fixed by [#6829](https://github.com/mapbox/mapbox-gl-js/pull/6829)) +* Add warning to geolocate control when unsupported ([#6923](https://github.com/mapbox/mapbox-gl-js/pull/6923)) (h/t [aendrew](https://github.com/aendrew)) +* Upgrade geojson-vt to 3.1.4 ([#6942](https://github.com/mapbox/mapbox-gl-js/pull/6942)) +* Include link to license in compiled bundle ([#6975](https://github.com/mapbox/mapbox-gl-js/pull/6975)) + +## 🐛 Bug fixes +* Use updateData instead of re-creating buffers for repopulated paint arrays ([#6853](https://github.com/mapbox/mapbox-gl-js/pull/6853)) +* Fix ScrollZoom handler setting tr.zoom = NaN ([#6924](https://github.com/mapbox/mapbox-gl-js/pull/6924)) + - Failed to invert matrix error ([#6486](https://github.com/mapbox/mapbox-gl-js/issues/6486), fixed by [#6924](https://github.com/mapbox/mapbox-gl-js/pull/6924)) + - Fixing matrix errors ([#6782](https://github.com/mapbox/mapbox-gl-js/issues/6782), fixed by [#6924](https://github.com/mapbox/mapbox-gl-js/pull/6924)) +* Fix heatmap tile clipping when layers are ordered above it ([#6806](https://github.com/mapbox/mapbox-gl-js/issues/6806), fixed by [#6807](https://github.com/mapbox/mapbox-gl-js/pull/6807)) +* Fix video source in safari (macOS and iOS) ([#6443](https://github.com/mapbox/mapbox-gl-js/issues/6443), fixed by [#6811](https://github.com/mapbox/mapbox-gl-js/pull/6811)) +* Do not reload errored tiles ([#6813](https://github.com/mapbox/mapbox-gl-js/pull/6813)) +* Fix send / remove timing bug in Dispatcher ([#6756](https://github.com/mapbox/mapbox-gl-js/pull/6756), fixed by [#6826](https://github.com/mapbox/mapbox-gl-js/pull/6826)) +* Fix flyTo not zooming to exact given zoom ([#6828](https://github.com/mapbox/mapbox-gl-js/pull/6828)) +* Don't stop animation on map resize ([#6636](https://github.com/mapbox/mapbox-gl-js/pull/6636)) +* Fix map.getBounds() with rotated map ([#6875](https://github.com/mapbox/mapbox-gl-js/pull/6875)) (h/t [zoltan-mihalyi](https://github.com/zoltan-mihalyi)) +* Support collators in feature filter expressions. ([#6929](https://github.com/mapbox/mapbox-gl-js/pull/6929)) +* Fix Webpack production mode compatibility ([#6981](https://github.com/mapbox/mapbox-gl-js/pull/6981)) ## 0.46.0 diff --git a/batfish.config.js b/batfish.config.js index 2c12a095581..67ab9fa94ac 100644 --- a/batfish.config.js +++ b/batfish.config.js @@ -42,9 +42,9 @@ module.exports = () => { // Local builds treat the `dist` directory as static assets, allowing you to test examples against the // local branch build. Non-local builds ignore the `dist` directory, and examples load assets from the CDN. - config.unprocessedPageFiles = ['dist/**/*.*']; + config.unprocessedPageFiles = ['**/dist/**/*.*']; if (process.env.DEPLOY_ENV !== 'local') { - config.ignoreWithinPagesDirectory.push('dist/**/*.*'); + config.ignoreWithinPagesDirectory.push('**/dist/**/*.*'); } return config; diff --git a/bench/.eslintrc b/bench/.eslintrc index 3c7a66abf20..5c0422e49f4 100644 --- a/bench/.eslintrc +++ b/bench/.eslintrc @@ -1,6 +1,5 @@ { "parserOptions": { - "sourceType": "module", "ecmaFeatures": { "jsx": true } diff --git a/bench/benchmarks.js b/bench/benchmarks.js index 83ee21fd21b..048dc6502e3 100644 --- a/bench/benchmarks.js +++ b/bench/benchmarks.js @@ -17,6 +17,7 @@ function register(Benchmark) { import Layout from './benchmarks/layout'; import LayoutDDS from './benchmarks/layout_dds'; +import WorkerTransfer from './benchmarks/worker_transfer'; import Paint from './benchmarks/paint'; import PaintStates from './benchmarks/paint_states'; import LayerBenchmarks from './benchmarks/layers'; @@ -31,6 +32,7 @@ import FilterEvaluate from './benchmarks/filter_evaluate'; register(Layout); register(LayoutDDS); +register(WorkerTransfer); register(Paint); register(PaintStates); LayerBenchmarks.forEach(register); diff --git a/bench/benchmarks/layout.js b/bench/benchmarks/layout.js index b8ac7bbdaf3..6763b296f0d 100644 --- a/bench/benchmarks/layout.js +++ b/bench/benchmarks/layout.js @@ -1,133 +1,44 @@ // @flow import Benchmark from '../lib/benchmark'; - -import createStyle from '../lib/create_style'; -import VT from '@mapbox/vector-tile'; -import Protobuf from 'pbf'; -import assert from 'assert'; -import promisify from 'pify'; -import WorkerTile from '../../src/source/worker_tile'; -import StyleLayerIndex from '../../src/style/style_layer_index'; -import deref from '../../src/style-spec/deref'; +import fetchStyle from '../lib/fetch_style'; +import TileParser from '../lib/tile_parser'; import { OverscaledTileID } from '../../src/source/tile_id'; -import { normalizeStyleURL, normalizeSourceURL, normalizeTileURL } from '../../src/util/mapbox'; - -import type {TileJSON} from '../../src/types/tilejson'; -// Note: this class is extended in turn by the LayoutDDS benchmark. export default class Layout extends Benchmark { - glyphs: Object; - icons: Object; - workerTile: WorkerTile; - layerIndex: StyleLayerIndex; tiles: Array<{tileID: OverscaledTileID, buffer: ArrayBuffer}>; + parser: TileParser; - tileIDs(): Array { - return [ + setup(): Promise { + const tileIDs = [ new OverscaledTileID(12, 0, 12, 655, 1583), new OverscaledTileID(8, 0, 8, 40, 98), new OverscaledTileID(4, 0, 4, 3, 6), new OverscaledTileID(0, 0, 0, 0, 0) ]; - } - - sourceID(): string { - return 'composite'; - } - - fetchStyle(): Promise { - return fetch(normalizeStyleURL(`mapbox://styles/mapbox/streets-v9`)) - .then(response => response.json()); - } - - fetchTiles(styleJSON: StyleSpecification): Promise> { - const sourceURL: string = (styleJSON.sources[this.sourceID()]: any).url; - return fetch(normalizeSourceURL(sourceURL)) - .then(response => response.json()) - .then((tileJSON: TileJSON) => { - return Promise.all(this.tileIDs().map(tileID => { - return fetch((normalizeTileURL(tileID.canonical.url(tileJSON.tiles)))) - .then(response => response.arrayBuffer()) - .then(buffer => ({tileID, buffer})); - })); - }); - } - - setup(): Promise { - return this.fetchStyle() + return fetchStyle(`mapbox://styles/mapbox/streets-v9`) .then((styleJSON) => { - this.layerIndex = new StyleLayerIndex(deref(styleJSON.layers)); - return Promise.all([createStyle(styleJSON), this.fetchTiles(styleJSON)]); + this.parser = new TileParser(styleJSON, 'composite'); + return this.parser.setup(); }) - .then(([style, tiles]) => { + .then(() => { + return Promise.all(tileIDs.map(tileID => this.parser.fetchTile(tileID))); + }) + .then((tiles) => { this.tiles = tiles; - this.glyphs = {}; - this.icons = {}; - - const preloadGlyphs = (params, callback) => { - style.getGlyphs('', params, (err, glyphs) => { - this.glyphs[JSON.stringify(params)] = glyphs; - callback(err, glyphs); - }); - }; - - const preloadImages = (params, callback) => { - style.getImages('', params, (err, icons) => { - this.icons[JSON.stringify(params)] = icons; - callback(err, icons); - }); - }; - - return this.bench(preloadGlyphs, preloadImages); - }); + // parse tiles once to populate glyph/icon cache + return Promise.all(tiles.map(tile => this.parser.parseTile(tile))); + }) + .then(() => {}); } - bench(getGlyphs: Function = (params, callback) => callback(null, this.glyphs[JSON.stringify(params)]), - getImages: Function = (params, callback) => callback(null, this.icons[JSON.stringify(params)])) { - - const actor = { - send(action, params, callback) { - setTimeout(() => { - if (action === 'getImages') { - getImages(params, callback); - } else if (action === 'getGlyphs') { - getGlyphs(params, callback); - } else assert(false); - }, 0); - } - }; - - let promise: Promise = Promise.resolve(); - - for (const {tileID, buffer} of this.tiles) { + bench() { + let promise = Promise.resolve(); + for (const tile of this.tiles) { promise = promise.then(() => { - const workerTile = new WorkerTile({ - tileID: tileID, - zoom: tileID.overscaledZ, - tileSize: 512, - overscaling: 1, - showCollisionBoxes: false, - source: this.sourceID(), - uid: '0', - maxZoom: 22, - pixelRatio: 1, - request: { - url: '' - }, - angle: 0, - pitch: 0, - cameraToCenterDistance: 0, - cameraToTileDistance: 0 - }); - - const tile = new VT.VectorTile(new Protobuf(buffer)); - const parse = promisify(workerTile.parse.bind(workerTile)); - - return parse(tile, this.layerIndex, actor); + return this.parser.parseTile(tile).then(() => {}); }); } - return promise; } } diff --git a/bench/benchmarks/layout_dds.js b/bench/benchmarks/layout_dds.js index af3812c50ad..27979d4e36f 100644 --- a/bench/benchmarks/layout_dds.js +++ b/bench/benchmarks/layout_dds.js @@ -1,24 +1,21 @@ // @flow -import Layout from './layout'; - +import Benchmark from '../lib/benchmark'; +import TileParser from '../lib/tile_parser'; import { OverscaledTileID } from '../../src/source/tile_id'; const LAYER_COUNT = 2; -export default class LayoutDDS extends Layout { - tileIDs(): Array { - return [ +export default class LayoutDDS extends Benchmark { + tiles: Array<{tileID: OverscaledTileID, buffer: ArrayBuffer}>; + parser: TileParser; + + setup(): Promise { + const tileIDs = [ new OverscaledTileID(15, 0, 15, 9373, 12535) ]; - } - - sourceID(): string { - return 'mapbox'; - } - fetchStyle(): Promise { - const style = { + const styleJSON = { "version": 8, "sources": { "mapbox": { "type": "vector", "url": "mapbox://mapbox.mapbox-streets-v7" } @@ -83,14 +80,34 @@ export default class LayoutDDS extends Layout { } ]; - while (style.layers.length < LAYER_COUNT) { + while (styleJSON.layers.length < LAYER_COUNT) { for (const layer of layers) { - style.layers.push(Object.assign(({}: any), layer, { - id: layer.id + style.layers.length + styleJSON.layers.push(Object.assign(({}: any), layer, { + id: layer.id + styleJSON.layers.length })); } } - return Promise.resolve(style); + this.parser = new TileParser(styleJSON, 'mapbox'); + return this.parser.setup() + .then(() => { + return Promise.all(tileIDs.map(tileID => this.parser.fetchTile(tileID))); + }) + .then((tiles) => { + this.tiles = tiles; + // parse tiles once to populate glyph/icon cache + return Promise.all(tiles.map(tile => this.parser.parseTile(tile))); + }) + .then(() => {}); + } + + bench() { + let promise = Promise.resolve(); + for (const tile of this.tiles) { + promise = promise.then(() => { + return this.parser.parseTile(tile).then(() => {}); + }); + } + return promise; } } diff --git a/bench/benchmarks/worker_transfer.js b/bench/benchmarks/worker_transfer.js new file mode 100644 index 00000000000..ecaa3894590 --- /dev/null +++ b/bench/benchmarks/worker_transfer.js @@ -0,0 +1,81 @@ +// @flow + +import Benchmark from '../lib/benchmark'; +import fetchStyle from '../lib/fetch_style'; +import TileParser from '../lib/tile_parser'; +import { OverscaledTileID } from '../../src/source/tile_id'; +import { serialize, deserialize } from '../../src/util/web_worker_transfer'; +import { values } from '../../src/util/util'; + +export default class WorkerTransfer extends Benchmark { + parser: TileParser; + payloadTiles: Array; + payloadJSON: Array; + worker: Worker; + + setup(): Promise { + const src = ` + onmessage = (e) => { + postMessage(e.data); + }; + `; + const url = window.URL.createObjectURL(new Blob([src], {type: 'text/javascript'})); + this.worker = new Worker(url); + + const tileIDs = [ + new OverscaledTileID(8, 0, 8, 73, 97), + new OverscaledTileID(11, 0, 11, 585, 783), + new OverscaledTileID(11, 0, 11, 596, 775), + new OverscaledTileID(13, 0, 13, 2412, 3079) + ]; + + return fetchStyle(`mapbox://styles/mapbox/streets-v9`) + .then((styleJSON) => { + this.parser = new TileParser(styleJSON, 'composite'); + return this.parser.setup(); + }) + .then(() => { + return Promise.all(tileIDs.map(tileID => this.parser.fetchTile(tileID))); + }) + .then((tiles) => { + return Promise.all(tiles.map(tile => this.parser.parseTile(tile))); + }).then((tileResults) => { + const payload = tileResults + .concat(values(this.parser.icons)) + .concat(values(this.parser.glyphs)).map((obj) => serialize(obj, [])); + this.payloadJSON = payload.map(barePayload); + this.payloadTiles = payload.slice(0, tileResults.length); + }); + } + + sendPayload(obj: any) { + return new Promise((resolve) => { + this.worker.onmessage = () => resolve(); + this.worker.postMessage(obj); + }); + } + + bench(): Promise { + let promise: Promise = Promise.resolve(); + + // benchmark sending raw JSON payload + for (const obj of this.payloadJSON) { + promise = promise.then(() => { + return this.sendPayload(obj); + }); + } + + return promise.then(() => { + // benchmark deserializing full tile payload because it happens on the main thread + for (const obj of this.payloadTiles) { + deserialize(obj); + } + }); + } +} + +function barePayload(obj) { + // strip all transferables from a worker payload, because we can't transfer them repeatedly in the bench: + // as soon as it's transfered once, it's no longer available on the main thread + return JSON.parse(JSON.stringify(obj, (key, value) => ArrayBuffer.isView(value) ? {} : value)); +} diff --git a/bench/lib/create_style.js b/bench/lib/create_style.js deleted file mode 100644 index 95c0ea85a79..00000000000 --- a/bench/lib/create_style.js +++ /dev/null @@ -1,22 +0,0 @@ -// @flow - -import Style from '../../src/style/style'; - -import { Evented } from '../../src/util/evented'; - -class StubMap extends Evented { - _transformRequest(url) { - return { url }; - } -} - -export default function (styleJSON: StyleSpecification): Promise + + + +
+ + + + + + diff --git a/debug/csp.html b/debug/csp.html index 6f13f833396..3cb47672d54 100644 --- a/debug/csp.html +++ b/debug/csp.html @@ -27,7 +27,7 @@ hash: true }); -mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.1.2/mapbox-gl-rtl-text.js'); +mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.0/mapbox-gl-rtl-text.js'); diff --git a/docs/.eslintrc b/docs/.eslintrc index a4453a0b07f..fdbdf881515 100644 --- a/docs/.eslintrc +++ b/docs/.eslintrc @@ -1,6 +1,5 @@ { "parserOptions": { - "sourceType": "module", "ecmaFeatures": { "jsx": true } diff --git a/docs/components/example.js b/docs/components/example.js index ed41289d6df..9d023090b76 100644 --- a/docs/components/example.js +++ b/docs/components/example.js @@ -30,7 +30,7 @@ export default function (html) { this.state = { filter: '', copied: false, - token: '' + token: undefined }; } @@ -53,7 +53,7 @@ export default function (html) { -${html.replace(" diff --git a/docs/pages/example/color-switcher.js b/docs/pages/example/color-switcher.js index 15c0c02811b..7f37ef87f15 100644 --- a/docs/pages/example/color-switcher.js +++ b/docs/pages/example/color-switcher.js @@ -1,6 +1,6 @@ /*--- title: Change a layer's color with buttons -description: Using setPaintProperty to change a layer's fill color +description: Using [`setPaintProperty`](/mapbox-gl-js/api#map#setpaintproperty) to change a layer's fill color tags: - layers - user-interaction diff --git a/docs/pages/example/custom-marker-icons.js b/docs/pages/example/custom-marker-icons.js index 1acca169771..db6216a78e2 100644 --- a/docs/pages/example/custom-marker-icons.js +++ b/docs/pages/example/custom-marker-icons.js @@ -1,6 +1,6 @@ /*--- title: Add custom icons with Markers -description: Use Markers to add custom icons to your map. +description: Use [`Marker`](/mapbox-gl-js/api/#marker) to add custom icons to your map. tags: - controls-and-overlays pathname: /mapbox-gl-js/example/custom-marker-icons/ diff --git a/docs/pages/example/data-driven-circle-colors.js b/docs/pages/example/data-driven-circle-colors.js index 45107bfe72b..599c85fe099 100644 --- a/docs/pages/example/data-driven-circle-colors.js +++ b/docs/pages/example/data-driven-circle-colors.js @@ -1,6 +1,6 @@ /*--- title: Style circles with a data-driven property -description: Creating a visualization with a data expression for circle-color +description: Creating a visualization with a data expression for [`circle-color`](/mapbox-gl-js/style-spec#paint-circle-circle-color) tags: - layers pathname: /mapbox-gl-js/example/data-driven-circle-colors/ diff --git a/docs/pages/example/data-driven-lines.js b/docs/pages/example/data-driven-lines.js index e0334db9450..c49a7463987 100644 --- a/docs/pages/example/data-driven-lines.js +++ b/docs/pages/example/data-driven-lines.js @@ -1,6 +1,6 @@ /*--- title: Style lines with a data-driven property -description: Creating a visualization with a data expression for line-color +description: Creating a visualization with a data expression for [`line-color`](/mapbox-gl-js/style-spec#paint-line-line-color) tags: - layers pathname: /mapbox-gl-js/example/data-driven-lines/ diff --git a/docs/pages/example/data-join.html b/docs/pages/example/data-join.html index 819f643b8c7..71b8cfe3f85 100644 --- a/docs/pages/example/data-join.html +++ b/docs/pages/example/data-join.html @@ -12,58 +12,58 @@ // Join local JSON data with vector tile geometry // USA unemployment rate in 2009 // Source https://data.bls.gov/timeseries/LNS14000000 -var maxValue = 14; +var maxValue = 13; var data = [ - {"STATE_ID": 1, "unemployment": 13.17}, - {"STATE_ID": 2, "unemployment": 9.5}, - {"STATE_ID": 4, "unemployment": 12.15}, - {"STATE_ID": 5, "unemployment": 8.99}, - {"STATE_ID": 6, "unemployment": 11.83}, - {"STATE_ID": 8, "unemployment": 7.52}, - {"STATE_ID": 9, "unemployment": 6.44}, - {"STATE_ID": 10, "unemployment": 5.17}, - {"STATE_ID": 12, "unemployment": 9.67}, - {"STATE_ID": 13, "unemployment": 10.64}, - {"STATE_ID": 15, "unemployment": 12.38}, - {"STATE_ID": 16, "unemployment": 10.13}, - {"STATE_ID": 17, "unemployment": 9.58}, - {"STATE_ID": 18, "unemployment": 10.63}, - {"STATE_ID": 19, "unemployment": 8.09}, - {"STATE_ID": 20, "unemployment": 5.93}, - {"STATE_ID": 21, "unemployment": 9.86}, - {"STATE_ID": 22, "unemployment": 9.81}, - {"STATE_ID": 23, "unemployment": 7.82}, - {"STATE_ID": 24, "unemployment": 8.35}, - {"STATE_ID": 25, "unemployment": 9.1}, - {"STATE_ID": 26, "unemployment": 10.69}, - {"STATE_ID": 27, "unemployment": 11.53}, - {"STATE_ID": 28, "unemployment": 9.29}, - {"STATE_ID": 29, "unemployment": 9.94}, - {"STATE_ID": 30, "unemployment": 9.29}, - {"STATE_ID": 31, "unemployment": 5.45}, - {"STATE_ID": 32, "unemployment": 4.21}, - {"STATE_ID": 33, "unemployment": 4.27}, - {"STATE_ID": 34, "unemployment": 4.09}, - {"STATE_ID": 35, "unemployment": 7.83}, - {"STATE_ID": 36, "unemployment": 8.01}, - {"STATE_ID": 37, "unemployment": 9.34}, - {"STATE_ID": 38, "unemployment": 11.23}, - {"STATE_ID": 39, "unemployment": 7.08}, - {"STATE_ID": 40, "unemployment": 11.22}, - {"STATE_ID": 41, "unemployment": 6.2}, - {"STATE_ID": 42, "unemployment": 9.11}, - {"STATE_ID": 44, "unemployment": 10.42}, - {"STATE_ID": 45, "unemployment": 8.89}, - {"STATE_ID": 46, "unemployment": 11.03}, - {"STATE_ID": 47, "unemployment": 7.35}, - {"STATE_ID": 48, "unemployment": 8.92}, - {"STATE_ID": 49, "unemployment": 7.65}, - {"STATE_ID": 50, "unemployment": 8.01}, - {"STATE_ID": 51, "unemployment": 7.62}, - {"STATE_ID": 53, "unemployment": 7.77}, - {"STATE_ID": 54, "unemployment": 8.49}, - {"STATE_ID": 55, "unemployment": 9.42}, - {"STATE_ID": 56, "unemployment": 7.59} + {"STATE_ID": "01", "unemployment": 13.17}, + {"STATE_ID": "02", "unemployment": 9.5}, + {"STATE_ID": "04", "unemployment": 12.15}, + {"STATE_ID": "05", "unemployment": 8.99}, + {"STATE_ID": "06", "unemployment": 11.83}, + {"STATE_ID": "08", "unemployment": 7.52}, + {"STATE_ID": "09", "unemployment": 6.44}, + {"STATE_ID": "10", "unemployment": 5.17}, + {"STATE_ID": "12", "unemployment": 9.67}, + {"STATE_ID": "13", "unemployment": 10.64}, + {"STATE_ID": "15", "unemployment": 12.38}, + {"STATE_ID": "16", "unemployment": 10.13}, + {"STATE_ID": "17", "unemployment": 9.58}, + {"STATE_ID": "18", "unemployment": 10.63}, + {"STATE_ID": "19", "unemployment": 8.09}, + {"STATE_ID": "20", "unemployment": 5.93}, + {"STATE_ID": "21", "unemployment": 9.86}, + {"STATE_ID": "22", "unemployment": 9.81}, + {"STATE_ID": "23", "unemployment": 7.82}, + {"STATE_ID": "24", "unemployment": 8.35}, + {"STATE_ID": "25", "unemployment": 9.1}, + {"STATE_ID": "26", "unemployment": 10.69}, + {"STATE_ID": "27", "unemployment": 11.53}, + {"STATE_ID": "28", "unemployment": 9.29}, + {"STATE_ID": "29", "unemployment": 9.94}, + {"STATE_ID": "30", "unemployment": 9.29}, + {"STATE_ID": "31", "unemployment": 5.45}, + {"STATE_ID": "32", "unemployment": 4.21}, + {"STATE_ID": "33", "unemployment": 4.27}, + {"STATE_ID": "34", "unemployment": 4.09}, + {"STATE_ID": "35", "unemployment": 7.83}, + {"STATE_ID": "36", "unemployment": 8.01}, + {"STATE_ID": "37", "unemployment": 9.34}, + {"STATE_ID": "38", "unemployment": 11.23}, + {"STATE_ID": "39", "unemployment": 7.08}, + {"STATE_ID": "40", "unemployment": 11.22}, + {"STATE_ID": "41", "unemployment": 6.2}, + {"STATE_ID": "42", "unemployment": 9.11}, + {"STATE_ID": "44", "unemployment": 10.42}, + {"STATE_ID": "45", "unemployment": 8.89}, + {"STATE_ID": "46", "unemployment": 11.03}, + {"STATE_ID": "47", "unemployment": 7.35}, + {"STATE_ID": "48", "unemployment": 8.92}, + {"STATE_ID": "49", "unemployment": 7.65}, + {"STATE_ID": "50", "unemployment": 8.01}, + {"STATE_ID": "51", "unemployment": 7.62}, + {"STATE_ID": "53", "unemployment": 7.77}, + {"STATE_ID": "54", "unemployment": 8.49}, + {"STATE_ID": "55", "unemployment": 9.42}, + {"STATE_ID": "56", "unemployment": 7.59} ]; map.on('load', function() { @@ -75,38 +75,27 @@ url: "mapbox://mapbox.us_census_states_2015" }); + var expression = ["match", ["get", "STATE_ID"]]; + + // Calculate color for each state based on the unemployment rate + data.forEach(function(row) { + var green = (row["unemployment"] / maxValue) * 255; + var color = "rgba(" + 0 + ", " + green + ", " + 0 + ", 1)"; + expression.push(row["STATE_ID"], color); + }); + + // Last value is the default, used where there is no data + expression.push("rgba(0,0,0,0)"); + // Add layer from the vector tile source with data-driven style - // Use a feature-state dependent expression to compute the the green color band based on - // the unemployment percentage map.addLayer({ "id": "states-join", "type": "fill", "source": "states", "source-layer": "states", "paint": { - "fill-color": ["rgba", - 0, - [ "*", [ "/", ["to-number", ["feature-state", "unemployment"]], maxValue], 255], - 0, - 0.9] + "fill-color": expression } }, 'waterway-label'); - - // Join the JSON unemployment data with the corresponding vector features where - // feautre.id == STATE_ID - function setStates(e) { - if (e.sourceId === 'states' && e.isSourceLoaded) { - map.off('sourcedata', setStates); - data.forEach(function(row) { - map.setFeatureState({source: 'states', sourceLayer: 'states', id: row["STATE_ID"]}, row); - }); - } - } - - if (map.isSourceLoaded('states')) { - setStates({ sourceId: 'states', isSourceLoaded: true}); - } else { - map.on('sourcedata', setStates); - } }); diff --git a/docs/pages/example/drag-a-marker.js b/docs/pages/example/drag-a-marker.js index fdfddcd1d90..8809ee1d6ea 100644 --- a/docs/pages/example/drag-a-marker.js +++ b/docs/pages/example/drag-a-marker.js @@ -1,8 +1,8 @@ /*--- -title: Create a draggable marker +title: Create a draggable Marker description: >- - Drag the marker to a new location on a map and populates its coordinates in a - display. + Drag the [`Marker`](/mapbox-gl-js/api/#marker) to a new location on a map and + populates its coordinates in a display. tags: - user-interaction pathname: /mapbox-gl-js/example/drag-a-marker/ diff --git a/docs/pages/example/filter-markers-by-input.js b/docs/pages/example/filter-markers-by-input.js index f5f50e5787b..7cc5ba66abe 100644 --- a/docs/pages/example/filter-markers-by-input.js +++ b/docs/pages/example/filter-markers-by-input.js @@ -1,6 +1,6 @@ /*--- title: Filter symbols by text input -description: Filter symbols by icon name by typing in a text input. +description: Filter [symbols](/mapbox-gl-js/style-spec#layers-symbol) by icon name by typing in a text input. tags: - user-interaction pathname: /mapbox-gl-js/example/filter-markers-by-input/ diff --git a/docs/pages/example/filter-markers.js b/docs/pages/example/filter-markers.js index 05f36d2ea51..65446dbc3e5 100644 --- a/docs/pages/example/filter-markers.js +++ b/docs/pages/example/filter-markers.js @@ -1,6 +1,6 @@ /*--- title: Filter symbols by toggling a list -description: Filter a set of symbols based on a property value in the data. +description: Filter a set of [symbols](/mapbox-gl-js/style-spec#layers-symbol) based on a property value in the data. tags: - user-interaction pathname: /mapbox-gl-js/example/filter-markers/ diff --git a/docs/pages/example/fitbounds.js b/docs/pages/example/fitbounds.js index 4f392ce5352..4b79f26ff59 100644 --- a/docs/pages/example/fitbounds.js +++ b/docs/pages/example/fitbounds.js @@ -1,8 +1,8 @@ /*--- title: Fit a map to a bounding box description: >- - Use fitBounds to show a specific area of the map in view, regardless of the - pixel size of the map. + Use [`fitBounds`](/mapbox-gl-js/api/#map#fitbounds) to show a specific area + of the map in view, regardless of the pixel size of the map. tags: - camera pathname: /mapbox-gl-js/example/fitbounds/ diff --git a/docs/pages/example/flyto-options.js b/docs/pages/example/flyto-options.js index 827250a57bd..64cfeac01be 100644 --- a/docs/pages/example/flyto-options.js +++ b/docs/pages/example/flyto-options.js @@ -1,6 +1,6 @@ /*--- title: Slowly fly to a location -description: Using .flyTo with flyOptions +description: Using [`flyTo`](/mapbox-gl-js/api/#map#flyto) with flyOptions tags: - camera pathname: /mapbox-gl-js/example/flyto-options/ diff --git a/docs/pages/example/flyto.js b/docs/pages/example/flyto.js index 6aeaa881962..9250f2a5e37 100644 --- a/docs/pages/example/flyto.js +++ b/docs/pages/example/flyto.js @@ -1,6 +1,6 @@ /*--- title: Fly to a location -description: Using .flyTo to smoothly interpolate between locations +description: Using [`flyTo`](/mapbox-gl-js/api/#map#flyto) to smoothly interpolate between locations tags: - camera pathname: /mapbox-gl-js/example/flyto/ diff --git a/docs/pages/example/forward-geocode-custom-data.html b/docs/pages/example/forward-geocode-custom-data.html new file mode 100644 index 00000000000..3949b8ac903 --- /dev/null +++ b/docs/pages/example/forward-geocode-custom-data.html @@ -0,0 +1,168 @@ + + +
+ + diff --git a/docs/pages/example/forward-geocode-custom-data.js b/docs/pages/example/forward-geocode-custom-data.js new file mode 100644 index 00000000000..f244339745b --- /dev/null +++ b/docs/pages/example/forward-geocode-custom-data.js @@ -0,0 +1,14 @@ +/*--- +title: Supplement forward geocoding search results from another data source +description: >- + Use the [mapbox-gl-geocoder](https://github.com/mapbox/mapbox-gl-geocoder) + control to search for places using Mapbox Geocoding API, supplementing + results from a local data source or function, in this case to match + Chicago Park names with text input. +tags: + - geocoder +pathname: /mapbox-gl-js/example/forward-geocode-custom-data/ +---*/ +import Example from '../../components/example'; +import html from './forward-geocode-custom-data.html'; +export default Example(html); diff --git a/docs/pages/example/geojson-layer-in-stack.js b/docs/pages/example/geojson-layer-in-stack.js index 75375956fc3..655aaac6558 100644 --- a/docs/pages/example/geojson-layer-in-stack.js +++ b/docs/pages/example/geojson-layer-in-stack.js @@ -1,6 +1,6 @@ /*--- title: Add a new layer below labels -description: 'Using the second argument of addLayer, you can be more precise' +description: 'Using the second argument of [`addLayer`](/mapbox-gl-js/api/#map#addlayer), you can be more precise' tags: - layers pathname: /mapbox-gl-js/example/geojson-layer-in-stack/ diff --git a/docs/pages/example/geojson-polygon.js b/docs/pages/example/geojson-polygon.js index c58c4810ec2..dced259d7b3 100644 --- a/docs/pages/example/geojson-polygon.js +++ b/docs/pages/example/geojson-polygon.js @@ -1,6 +1,6 @@ /*--- title: Add a GeoJSON polygon -description: Style a polygon with the fill layer type +description: Style a polygon with the [fill layer](/mapbox-gl-js/style-spec#layers-fill) type tags: - layers pathname: /mapbox-gl-js/example/geojson-polygon/ diff --git a/docs/pages/example/heatmap-layer.html b/docs/pages/example/heatmap-layer.html index e99a7a1d196..1cc08eafe7e 100644 --- a/docs/pages/example/heatmap-layer.html +++ b/docs/pages/example/heatmap-layer.html @@ -14,7 +14,7 @@ // Heatmap layers also work with a vector tile source. map.addSource('earthquakes', { "type": "geojson", - "data": "/mapbox-gl-js/assets/earthquakes.geojson" + "data": "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson" }); map.addLayer({ diff --git a/docs/pages/example/heatmap-layer.js b/docs/pages/example/heatmap-layer.js index 596cf7d0f9c..d598d26fdb5 100644 --- a/docs/pages/example/heatmap-layer.js +++ b/docs/pages/example/heatmap-layer.js @@ -1,6 +1,6 @@ /*--- title: Create a heatmap layer -description: Visualize earthquake frequency by location using a heatmap layer. +description: Visualize earthquake frequency by location using a [heatmap layer](/mapbox-gl-js/style-spec#layers-heatmap). tags: - layers pathname: /mapbox-gl-js/example/heatmap-layer/ diff --git a/docs/pages/example/hover-styles.html b/docs/pages/example/hover-styles.html index 7b8ecbfae3c..e9f7ba1d99d 100644 --- a/docs/pages/example/hover-styles.html +++ b/docs/pages/example/hover-styles.html @@ -15,7 +15,7 @@ }); // The feature-state dependent fill-opacity expression will render the hover effect - // when a feature's hover state is set to true. + // when a feature's hover state is set to true. map.addLayer({ "id": "state-fills", "type": "fill", @@ -42,7 +42,7 @@ } }); - // When the user moves their mouse over the states-fill layer, we'll update the + // When the user moves their mouse over the state-fill layer, we'll update the // feature state for the feature under the mouse. map.on("mousemove", "state-fills", function(e) { if (e.features.length > 0) { @@ -54,7 +54,8 @@ } }); - // Reset the state-fills-hover layer's filter when the mouse leaves the layer. + // When the mouse leaves the state-fill layer, update the feature state of the + // previously hovered feature. map.on("mouseleave", "state-fills", function() { if (hoveredStateId) { map.setFeatureState({source: 'states', id: hoveredStateId}, { hover: false}); diff --git a/docs/pages/example/hover-styles.js b/docs/pages/example/hover-styles.js index aa879af4eae..4cec0c238cd 100644 --- a/docs/pages/example/hover-styles.js +++ b/docs/pages/example/hover-styles.js @@ -1,6 +1,6 @@ /*--- title: Create a hover effect -description: Using events and a filter to change hover styles +description: Using events and [feature states](/mapbox-gl-js/api/#map#setfeaturestate) to create a per feature hover effect tags: - user-interaction pathname: /mapbox-gl-js/example/hover-styles/ diff --git a/docs/pages/example/image-on-a-map.html b/docs/pages/example/image-on-a-map.html index be96f208de9..74c9c79390c 100644 --- a/docs/pages/example/image-on-a-map.html +++ b/docs/pages/example/image-on-a-map.html @@ -10,7 +10,7 @@ }, "overlay": { "type": "image", - "url": "/mapbox-gl-js/assets/radar.gif", + "url": "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif", "coordinates": [ [-80.425, 46.437], [-71.516, 46.437], diff --git a/docs/pages/example/language-switch.js b/docs/pages/example/language-switch.js index 79732706d18..ad28815f0ca 100644 --- a/docs/pages/example/language-switch.js +++ b/docs/pages/example/language-switch.js @@ -1,6 +1,6 @@ /*--- title: Change a map's language -description: Using .setLayoutProperty to switch languages dynamically. +description: Using [`setLayoutProperty`](/mapbox-gl-js/api/#map#setlayoutproperty) to switch languages dynamically. For a more complete solution see the [mapbox-gl-language](https://github.com/mapbox/mapbox-gl-language/) plugin. tags: - user-interaction pathname: /mapbox-gl-js/example/language-switch/ diff --git a/docs/pages/example/line-gradient.js b/docs/pages/example/line-gradient.js index 36297934330..805f52ad543 100644 --- a/docs/pages/example/line-gradient.js +++ b/docs/pages/example/line-gradient.js @@ -1,7 +1,9 @@ /*--- title: Create a gradient line using an expression description: >- - Use the line-gradient paint property and an expression to visualize distance from the starting point of a line. + Use the [`line-gradient`](/mapbox-gl-js/style-spec#paint-line-line-gradient) + paint property and an expression to visualize distance from the starting + point of a line. tags: - layers pathname: /mapbox-gl-js/example/line-gradient/ diff --git a/docs/pages/example/live-geojson.js b/docs/pages/example/live-geojson.js index 5f800ee0e6b..cb7f1748c75 100644 --- a/docs/pages/example/live-geojson.js +++ b/docs/pages/example/live-geojson.js @@ -1,6 +1,6 @@ /*--- title: Add live realtime data -description: Use realtime GeoJSON data streams to move a symbol on your map +description: Use realtime GeoJSON data streams to move a [`symbol`](/mapbox-gl-js/style-spec#layers-symbol) on your map tags: - sources pathname: /mapbox-gl-js/example/live-geojson/ diff --git a/docs/pages/example/live-update-feature.html b/docs/pages/example/live-update-feature.html index 004d844a09b..d188ca08fb9 100644 --- a/docs/pages/example/live-update-feature.html +++ b/docs/pages/example/live-update-feature.html @@ -12,7 +12,7 @@ // We use D3 to fetch the JSON here so that we can parse and use it separately // from GL JS's use in the added source. You can use any request method (library // or otherwise) that you want. - d3.json('/mapbox-gl-js/assets/hike.geojson', function(err, data) { + d3.json('https://www.mapbox.com/mapbox-gl-js/assets/hike.geojson', function(err, data) { if (err) throw err; // save full coordinate list for later diff --git a/docs/pages/example/local-ideographs.js b/docs/pages/example/local-ideographs.js index 3b14f5144af..0357d6c6574 100644 --- a/docs/pages/example/local-ideographs.js +++ b/docs/pages/example/local-ideographs.js @@ -3,7 +3,7 @@ title: Use locally generated ideographs description: >- Rendering Chinese/Japanese/Korean (CJK) ideographs and precomposed Hangul Syllables requires downloading large amounts of font data, which can - significantly slow map load times. Use the 'localIdeographFontFamily' setting + significantly slow map load times. Use the `localIdeographFontFamily` setting to speed up map load times by using locally available fonts instead of font data fetched from the server. This setting defines a CSS 'font-family' for locally overriding generation of glyphs in the 'CJK Unified Ideographs' and diff --git a/docs/pages/example/locate-user.js b/docs/pages/example/locate-user.js index 1428fba4c16..c8c7dc6a170 100644 --- a/docs/pages/example/locate-user.js +++ b/docs/pages/example/locate-user.js @@ -1,6 +1,6 @@ /*--- title: Locate the user -description: Geolocate the user and then track their current location on the map +description: Geolocate the user and then track their current location on the map using the [`GeolocateControl`](/mapbox-gl-js/api/#geolocatecontrol) tags: - controls-and-overlays pathname: /mapbox-gl-js/example/locate-user/ diff --git a/docs/pages/example/mapbox-gl-draw.js b/docs/pages/example/mapbox-gl-draw.js index 207b6c31055..42cd5f5fe29 100644 --- a/docs/pages/example/mapbox-gl-draw.js +++ b/docs/pages/example/mapbox-gl-draw.js @@ -1,7 +1,7 @@ /*--- title: Show drawn polygon area description: >- - Use GL draw to draw a polygon and turf.js to calculate its area in square + Use [mapbox-gl-draw](https://github.com/mapbox/mapbox-gl-draw) to draw a polygon and [Turf.js](http://turfjs.org/) to calculate its area in square meters. tags: - controls-and-overlays diff --git a/docs/pages/example/mapbox-gl-geocoder-limit-region.html b/docs/pages/example/mapbox-gl-geocoder-limit-region.html index 34b7522494f..ceae8104657 100644 --- a/docs/pages/example/mapbox-gl-geocoder-limit-region.html +++ b/docs/pages/example/mapbox-gl-geocoder-limit-region.html @@ -1,5 +1,5 @@ - - + +
- + +
- + +