mapbox-gl
Advanced tools
Comparing version 2.12.0 to 2.15.0
@@ -17,3 +17,3 @@ // @flow | ||
import {createLayout, viewTypes} from '../src/util/struct_array.js'; | ||
import type {ViewType, StructArrayLayout} from '../src/util/struct_array.js'; | ||
import type {ViewType, StructArrayLayout, StructArrayMember} from '../src/util/struct_array.js'; | ||
@@ -37,3 +37,3 @@ const structArrayLayoutJs = ejs.compile(fs.readFileSync('src/util/struct_array_layout.js.ejs', 'utf8'), {strict: true}); | ||
function normalizeMembers(members, usedTypes) { | ||
function normalizeMembers(members: Array<StructArrayMember>, usedTypes: Set<string | ViewType>) { | ||
return members.map((member) => { | ||
@@ -75,3 +75,3 @@ if (usedTypes && !usedTypes.has(member.type)) { | ||
function createStructArrayLayoutType({members, size, alignment}) { | ||
function createStructArrayLayoutType({members, size, alignment}: StructArrayLayout) { | ||
const usedTypes = new Set(['Uint8']); | ||
@@ -112,3 +112,3 @@ members = normalizeMembers(members, usedTypes); | ||
function camelize (str) { | ||
function camelize (str: string) { | ||
return str.replace(/(?:^|[-_])(.)/g, (_, x) => { | ||
@@ -115,0 +115,0 @@ return /^[0-9]$/.test(x) ? _ : x.toUpperCase(); |
@@ -7,27 +7,34 @@ import flowRemoveTypes from '@mapbox/flow-remove-types'; | ||
export function resolve(specifier, context, defaultResolve) { | ||
export async function resolve(specifier, context, nextResolve) { | ||
if (glslRe.test(specifier)) { | ||
const url = new URL(specifier, context.parentURL).href; | ||
return {url}; | ||
return {url, shortCircuit: true}; | ||
} | ||
return defaultResolve(specifier, context, defaultResolve); | ||
return nextResolve(specifier); | ||
} | ||
export function getFormat(url, context, defaultGetFormat) { | ||
if (glslRe.test(url) || jsonRe.test(url)) { | ||
return {format: 'module'}; | ||
export async function load(url, context, nextLoad) { | ||
if (context.format === 'module') { | ||
const {source: rawSource} = await nextLoad(url, context); | ||
const source = rawSource.toString(); | ||
if (source.indexOf('@flow') >= 0) { | ||
const transformedSource = flowRemoveTypes(source).toString(); | ||
return {format: 'module', source: transformedSource, shortCircuit: true}; | ||
} | ||
} | ||
return defaultGetFormat(url, context, defaultGetFormat); | ||
} | ||
export function transformSource(source, context, defaultTransformSource) { | ||
if (source.indexOf('@flow') >= 0) { | ||
source = flowRemoveTypes(source.toString()).toString(); | ||
return {source}; | ||
if (glslRe.test(url)) { | ||
const {source: rawSource} = await nextLoad(url, {...context, format: 'module'}); | ||
const source = `export default \`${rawSource.toString()}\``; | ||
return {format: 'module', source, shortCircuit: true}; | ||
} | ||
if (glslRe.test(context.url)) { | ||
return {source: `export default \`${source}\``}; | ||
} | ||
if (jsonRe.test(context.url)) { | ||
source = dataToEsm(JSON.parse(source), { | ||
if (jsonRe.test(url)) { | ||
const {source: rawSource} = await nextLoad(url, {...context, | ||
// Force import assertions as "assert { type: 'json' }" | ||
importAssertions: {type: 'json'} | ||
}); | ||
const source = dataToEsm(JSON.parse(rawSource.toString()), { | ||
preferConst: true, | ||
@@ -37,5 +44,7 @@ namedExports: true, | ||
}); | ||
return {source}; | ||
return {format: 'module', source, shortCircuit: true}; | ||
} | ||
return defaultTransformSource(source, context, defaultTransformSource); | ||
return nextLoad(url); | ||
} |
@@ -7,3 +7,3 @@ | ||
import json from '@rollup/plugin-json'; | ||
import {terser} from 'rollup-plugin-terser'; | ||
import terser from '@rollup/plugin-terser'; | ||
import minifyStyleSpec from './rollup_plugin_minify_style_spec.js'; | ||
@@ -30,3 +30,4 @@ import {createFilter} from '@rollup/pluginutils'; | ||
'process.env.CI': JSON.stringify(process.env.CI), | ||
'process.env.UPDATE': JSON.stringify(process.env.UPDATE) | ||
'process.env.UPDATE': JSON.stringify(process.env.UPDATE), | ||
'process.env.USE_WEBGL2': JSON.stringify(process.env.USE_WEBGL2) | ||
}) : false, | ||
@@ -33,0 +34,0 @@ glsl('./src/shaders/*.glsl', production), |
// @flow strict | ||
type GeoJSONPosition = [number, number] | [number, number, number]; | ||
type Geometry<T, C> = { type: T, coordinates: C } | ||
declare module "@mapbox/geojson-types" { | ||
declare export type GeoJSONPosition = [number, number] | [number, number, number]; | ||
declare export type GeoJSONPoint = Geometry<'Point', GeoJSONPosition>; | ||
@@ -30,8 +31,8 @@ declare export type GeoJSONMultiPoint = Geometry<'MultiPoint', Array<GeoJSONPosition>>; | ||
declare export type GeoJSONFeature = { | ||
type: 'Feature', | ||
geometry: ?GeoJSONGeometry, | ||
properties: ?{}, | ||
id?: number | string | ||
}; | ||
declare export interface GeoJSONFeature { | ||
type: 'Feature'; | ||
geometry: ?GeoJSONGeometry; | ||
properties: ?{}; | ||
id?: number | string; | ||
} | ||
@@ -38,0 +39,0 @@ declare export type GeoJSONFeatureCollection = { |
@@ -5,19 +5,19 @@ mapbox-gl-js v2.0 | ||
Copyright (c) 2020, Mapbox | ||
Copyright © 2021 - 2023 Mapbox, Inc. All rights reserved. | ||
All rights reserved. | ||
The software and files in this repository (collectively, "Software") are | ||
licensed under the Mapbox TOS for use only with the relevant Mapbox product(s) | ||
listed at www.mapbox.com/pricing. This license allows developers with a | ||
current active Mapbox account to use and modify the authorized portions of the | ||
Software as needed for use only with the relevant Mapbox product(s) through | ||
their Mapbox account in accordance with the Mapbox TOS. This license | ||
terminates automatically if a developer no longer has a Mapbox account in good | ||
standing or breaches the Mapbox TOS. For the license terms, please see the | ||
Mapbox TOS at https://www.mapbox.com/legal/tos/ which incorporates the Mapbox | ||
Product Terms at www.mapbox.com/legal/service-terms. If this Software is a | ||
SDK, modifications that change or interfere with marked portions of the code | ||
related to billing, accounting, or data collection are not authorized and the | ||
SDK sends limited de-identified location and usage data which is used in | ||
accordance with the Mapbox TOS. [Updated 2023-01] | ||
Mapbox gl-js version 2.0 or higher (“Mapbox Web SDK”) must be used according to | ||
the Mapbox Terms of Service. This license allows developers with a current active | ||
Mapbox account to use and modify the Mapbox Web SDK. Developers may modify the | ||
Mapbox Web SDK code so long as the modifications do not change or interfere with | ||
marked portions of the code related to billing, accounting, and anonymized data | ||
collection. The Mapbox Web SDK only sends anonymized usage data, which Mapbox uses | ||
for fixing bugs and errors, accounting, and generating aggregated anonymized | ||
statistics. This license terminates automatically if a user no longer has an | ||
active Mapbox account. | ||
For the full license terms, please see the Mapbox Terms of Service at | ||
https://www.mapbox.com/legal/tos/. | ||
------------------------------------------------------------------------------- | ||
@@ -24,0 +24,0 @@ |
{ | ||
"name": "mapbox-gl", | ||
"description": "A WebGL interactive maps library", | ||
"version": "2.12.0", | ||
"version": "2.15.0", | ||
"main": "dist/mapbox-gl.js", | ||
@@ -18,3 +18,3 @@ "style": "dist/mapbox-gl.css", | ||
"@mapbox/point-geometry": "^0.1.0", | ||
"@mapbox/tiny-sdf": "^2.0.5", | ||
"@mapbox/tiny-sdf": "^2.0.6", | ||
"@mapbox/unitbezier": "^0.0.1", | ||
@@ -28,2 +28,3 @@ "@mapbox/vector-tile": "^1.3.1", | ||
"grid-index": "^1.1.0", | ||
"kdbush": "^4.0.1", | ||
"murmurhash-js": "^1.0.0", | ||
@@ -34,3 +35,3 @@ "pbf": "^3.2.1", | ||
"rw": "^1.3.3", | ||
"supercluster": "^7.1.5", | ||
"supercluster": "^8.0.0", | ||
"tinyqueue": "^2.0.3", | ||
@@ -42,11 +43,11 @@ "vt-pbf": "^3.1.3" | ||
"@babel/eslint-parser": "^7.18.9", | ||
"@babel/preset-flow": "^7.18.6", | ||
"@mapbox/flow-remove-types": "^2.0.0", | ||
"@mapbox/mvt-fixtures": "^3.10.0", | ||
"@octokit/rest": "^19.0.4", | ||
"@rollup/plugin-commonjs": "^23.0.3", | ||
"@rollup/plugin-json": "^5.0.2", | ||
"@rollup/plugin-commonjs": "^25.0.0", | ||
"@rollup/plugin-json": "^6.0.0", | ||
"@rollup/plugin-node-resolve": "^15.0.0", | ||
"@rollup/plugin-replace": "^5.0.0", | ||
"@rollup/plugin-strip": "^3.0.0", | ||
"@rollup/plugin-terser": "^0.4.1", | ||
"address": "^1.2.0", | ||
@@ -57,3 +58,3 @@ "browserify": "^17.0.0", | ||
"cross-env": "^7.0.3", | ||
"cssnano": "^5.1.13", | ||
"cssnano": "^6.0.0", | ||
"d3": "^7.6.1", | ||
@@ -70,5 +71,5 @@ "d3-queue": "^3.0.7", | ||
"eslint-plugin-jsdoc": "^39.6.4", | ||
"flow-bin": "0.145.0", | ||
"gl": "6.0.1", | ||
"glob": "^8.0.3", | ||
"flow-bin": "0.191.0", | ||
"gl": "6.0.2", | ||
"glob": "^10.0.0", | ||
"is-builtin-module": "^3.2.0", | ||
@@ -88,11 +89,11 @@ "jsdom": "^15.2.1", | ||
"postcss-cli": "^10.1.0", | ||
"postcss-inline-svg": "^5.0.0", | ||
"postcss-inline-svg": "^6.0.0", | ||
"pretty-bytes": "^6.0.0", | ||
"puppeteer-core": "^19.3.0", | ||
"puppeteer-core": "^19.7.0", | ||
"qrcode-terminal": "^0.12.0", | ||
"rollup": "^2.78.1", | ||
"rollup": "^3.21.7", | ||
"rollup-plugin-sourcemaps": "^0.6.3", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"rollup-plugin-unassert": "^0.5.0", | ||
"selenium-webdriver": "^4.4.0", | ||
"rollup-plugin-unassert": "^0.6.0", | ||
"selenium-webdriver": "^4.8.0", | ||
"serve-static": "^1.15.0", | ||
"shuffle-seed": "^1.1.6", | ||
@@ -106,3 +107,3 @@ "sinon": "^15.0.0", | ||
"tape-filter": "^1.0.4", | ||
"testem": "^3.10.0" | ||
"testem": "^3.10.1" | ||
}, | ||
@@ -146,2 +147,3 @@ "browser": { | ||
"test-render-firefox": "cross-env BROWSER=Firefox SUITE_NAME=render testem ci -f test/integration/testem/testem.js", | ||
"test-render-safari": "cross-env BROWSER=Safari SUITE_NAME=render testem ci -f test/integration/testem/testem.js", | ||
"test-render-prod": "BUILD=production SUITE_NAME=render testem ci -f test/integration/testem/testem.js", | ||
@@ -156,2 +158,3 @@ "test-render-csp": "BUILD=csp SUITE_NAME=render testem ci -f test/integration/testem/testem.js", | ||
"print-release-url": "node build/print-release-url.js", | ||
"check-bundle-size": "node build/check-bundle-size.js", | ||
"codegen": "build/run-node build/generate-style-code.js && build/run-node build/generate-struct-arrays.js" | ||
@@ -158,0 +161,0 @@ }, |
@@ -33,8 +33,6 @@ [<img width="300" alt="Mapbox logo" src="https://static-assets.mapbox.com/www/logos/mapbox-logo-black.png">](https://www.mapbox.com/) | ||
Copyright © 2021 Mapbox | ||
Mapbox Web SDK | ||
All rights reserved. | ||
Copyright © 2021 - 2023 Mapbox, Inc. All rights reserved. | ||
Mapbox GL JS version 2.0 or higher (“Mapbox Web SDK”) must be used according to the Mapbox Terms of Service. This license allows developers with a current active Mapbox account to use and modify the Mapbox Web SDK. Developers may modify the Mapbox Web SDK code so long as the modifications do not change or interfere with marked portions of the code related to billing, accounting, and anonymized data collection. The Mapbox Web SDK sends only anonymized usage data, which Mapbox uses for fixing bugs and errors, accounting, and generating aggregated anonymized statistics. This license terminates automatically if a user no longer has an active Mapbox account. | ||
For the full license terms, please see the [Mapbox Terms of Service](https://www.mapbox.com/legal/tos/). | ||
The software and files in this repository (collectively, “Software”) are licensed under the Mapbox TOS for use only with the relevant Mapbox product(s) listed at www.mapbox.com/pricing. This license allows developers with a current active Mapbox account to use and modify the authorized portions of the Software as needed for use only with the relevant Mapbox product(s) through their Mapbox account in accordance with the Mapbox TOS. This license terminates automatically if a developer no longer has a Mapbox account in good standing or breaches the Mapbox TOS. For the license terms, please see the Mapbox TOS at https://www.mapbox.com/legal/tos/ which incorporates the Mapbox Product Terms at www.mapbox.com/legal/service-terms. If this Software is a SDK, modifications that change or interfere with marked portions of the code related to billing, accounting, or data collection are not authorized and the SDK sends limited de-identified location and usage data which is used in accordance with the Mapbox TOS. [Updated 2023-01] |
@@ -37,3 +37,3 @@ // @flow | ||
function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) { | ||
function addCircleVertex(layoutVertexArray: CircleLayoutArray, x: number, y: number, extrudeX: number, extrudeY: number) { | ||
layoutVertexArray.emplaceBack( | ||
@@ -111,2 +111,3 @@ (x * 2) + ((extrudeX + 1) / 2), | ||
// $FlowFixMe[method-unbinding] | ||
if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue; | ||
@@ -113,0 +114,0 @@ |
@@ -92,2 +92,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue; | ||
@@ -94,0 +95,0 @@ |
@@ -56,3 +56,3 @@ // @flow | ||
function addVertex(vertexArray, x, y, nxRatio, nySign, normalUp, top, e) { | ||
function addVertex(vertexArray: FillExtrusionLayoutArray, x: number, y: number, nxRatio: number, nySign: number, normalUp: number, top: number, e: number) { | ||
vertexArray.emplaceBack( | ||
@@ -77,3 +77,3 @@ // a_pos_normal_ed: | ||
class PartMetadata { | ||
export class PartMetadata { | ||
acc: Point; | ||
@@ -248,2 +248,3 @@ min: Point; | ||
// $FlowFixMe[method-unbinding] | ||
if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue; | ||
@@ -666,3 +667,3 @@ | ||
function getCosHalfAngle(na, nb) { | ||
function getCosHalfAngle(na: Point, nb: Point) { | ||
const nm = na.add(nb)._unit(); | ||
@@ -673,3 +674,3 @@ const cosHalfAngle = na.x * nm.x + na.y * nm.y; | ||
function getRoundedEdgeOffset(p0, p1, p2, edgeRadius) { | ||
function getRoundedEdgeOffset(p0: Point, p1: Point, p2: Point, edgeRadius: number) { | ||
const na = p1.sub(p0)._perp()._unit(); | ||
@@ -681,3 +682,3 @@ const nb = p2.sub(p1)._perp()._unit(); | ||
function _getRoundedEdgeOffset(p0, p1, p2, cosHalfAngle, edgeRadius) { | ||
function _getRoundedEdgeOffset(p0: Point, p1: Point, p2: Point, cosHalfAngle: number, edgeRadius: number) { | ||
const sinHalfAngle = Math.sqrt(1 - cosHalfAngle * cosHalfAngle); | ||
@@ -696,3 +697,3 @@ return Math.min(p0.dist(p1) / 3, p1.dist(p2) / 3, edgeRadius * sinHalfAngle / cosHalfAngle); | ||
// discard edges that have the both endpoints outside the same bound. | ||
function isEdgeOutsideBounds(p1, p2, bounds) { | ||
function isEdgeOutsideBounds(p1: Point, p2: Point, bounds: [Point, Point]) { | ||
return (p1.x < bounds[0].x && p2.x < bounds[0].x) || | ||
@@ -704,3 +705,3 @@ (p1.x > bounds[1].x && p2.x > bounds[1].x) || | ||
function isEntirelyOutside(ring) { | ||
function isEntirelyOutside(ring: Array<Point>) { | ||
// Discard rings with corners on border if all other vertices are outside: they get defined | ||
@@ -723,3 +724,3 @@ // also in the tile across the border. Eventual zero area rings at border are discarded by classifyRings | ||
function isAOConcaveAngle(p2, p1, p3) { | ||
function isAOConcaveAngle(p2: Point, p1: Point, p3: Point) { | ||
if (p2.x < 0 || p2.x >= EXTENT || p1.x < 0 || p1.x >= EXTENT || p3.x < 0 || p3.x >= EXTENT) { | ||
@@ -739,3 +740,3 @@ return false; // angles are not processed for edges that extend over tile borders | ||
function encodeAOToEdgeDistance(edgeDistance, isConcaveCorner, edgeStart) { | ||
function encodeAOToEdgeDistance(edgeDistance: number, isConcaveCorner: boolean, edgeStart: boolean) { | ||
// Encode concavity and edge start/end using the least significant bits. | ||
@@ -770,3 +771,3 @@ // Second least significant bit 1 encodes concavity. | ||
const splitFn = (axis, min, max) => { | ||
const splitFn = (axis: number, min: number, max: number) => { | ||
if (axis === 0) { | ||
@@ -773,0 +774,0 @@ return 0.5 * (min + max); |
@@ -149,2 +149,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) continue; | ||
@@ -151,0 +152,0 @@ |
@@ -135,3 +135,3 @@ // @flow | ||
function addVertex(array, tileAnchorX, tileAnchorY, ox, oy, tx, ty, sizeVertex, isSDF: boolean, pixelOffsetX, pixelOffsetY, minFontScaleX, minFontScaleY) { | ||
function addVertex(array: SymbolLayoutArray, tileAnchorX: number, tileAnchorY: number, ox: number, oy: number, tx: number, ty: number, sizeVertex: any, isSDF: boolean, pixelOffsetX: number, pixelOffsetY: number, minFontScaleX: number, minFontScaleY: number) { | ||
const aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0; | ||
@@ -159,3 +159,3 @@ const aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0; | ||
function addGlobeVertex(array, projAnchorX, projAnchorY, projAnchorZ, normX, normY, normZ) { | ||
function addGlobeVertex(array: SymbolGlobeExtArray, projAnchorX: number, projAnchorY: number, projAnchorZ: number, normX: number, normY: number, normZ: number) { | ||
array.emplaceBack( | ||
@@ -511,2 +511,3 @@ // a_globe_anchor | ||
const evaluationFeature = toEvaluationFeature(feature, needGeometry); | ||
// $FlowFixMe[method-unbinding] | ||
if (!layer._featureFilter.filter(globalProperties, evaluationFeature, canonical)) { | ||
@@ -526,3 +527,3 @@ continue; | ||
const cosAngleThreshold = 0.98078528056; | ||
const predicate = (a, b) => { | ||
const predicate = (a: Point, b: Point) => { | ||
const v0 = tileCoordToECEF(a.x, a.y, canonical, 1); | ||
@@ -529,0 +530,0 @@ const v1 = tileCoordToECEF(b.x, b.y, canonical, 1); |
@@ -26,2 +26,14 @@ // @flow | ||
function unpackMapbox(r: number, g: number, b: number): number { | ||
// unpacking formula for mapbox.terrain-rgb: | ||
// https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb | ||
return ((r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0); | ||
} | ||
function unpackTerrarium(r: number, g: number, b: number): number { | ||
// unpacking formula for mapzen terrarium: | ||
// https://aws.amazon.com/public-datasets/terrain/ | ||
return ((r * 256 + g + b / 256) - 32768.0); | ||
} | ||
export default class DEMData { | ||
@@ -90,3 +102,3 @@ uid: number; | ||
const index = this._idx(x, y) * 4; | ||
const unpack = this.encoding === "terrarium" ? this._unpackTerrarium : this._unpackMapbox; | ||
const unpack = this.encoding === "terrarium" ? unpackTerrarium : unpackMapbox; | ||
return unpack(this.pixels[index], this.pixels[index + 1], this.pixels[index + 2]); | ||
@@ -108,14 +120,2 @@ } | ||
_unpackMapbox(r: number, g: number, b: number): number { | ||
// unpacking formula for mapbox.terrain-rgb: | ||
// https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb | ||
return ((r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0); | ||
} | ||
_unpackTerrarium(r: number, g: number, b: number): number { | ||
// unpacking formula for mapzen terrarium: | ||
// https://aws.amazon.com/public-datasets/terrain/ | ||
return ((r * 256 + g + b / 256) - 32768.0); | ||
} | ||
static pack(altitude: number, encoding: DEMEncoding): [number, number, number, number] { | ||
@@ -137,3 +137,3 @@ const color = [0, 0, 0, 0]; | ||
backfillBorder(borderTile: DEMData, dx: number, dy: number) { | ||
backfillBorder(borderTile: DEMData, dx: number, dy: number): void { | ||
if (this.dim !== borderTile.dim) throw new Error('dem dimension mismatch'); | ||
@@ -140,0 +140,0 @@ |
@@ -72,3 +72,3 @@ // @flow | ||
function triangleRayIntersect(ax, ay, az, bx, by, bz, cx, cy, cz, pos: Vec3, dir: Vec3): ?number { | ||
function triangleRayIntersect(ax: number, ay: number, az: number, bx: number, by: number, bz: number, cx: number, cy: number, cz: number, pos: Vec3, dir: Vec3): ?number { | ||
// Compute barycentric coordinates u and v to find the intersection | ||
@@ -113,7 +113,7 @@ const abX = bx - ax; | ||
function frac(v, lo, hi) { | ||
function frac(v: number, lo: number, hi: number) { | ||
return (v - lo) / (hi - lo); | ||
} | ||
function decodeBounds(x, y, depth, boundsMinx, boundsMiny, boundsMaxx, boundsMaxy, outMin, outMax) { | ||
function decodeBounds(x: number, y: number, depth: number, boundsMinx: number, boundsMiny: number, boundsMaxx: number, boundsMaxy: number, outMin: Array<number>, outMax: Array<number>) { | ||
const scale = 1 << depth; | ||
@@ -399,3 +399,3 @@ const rangex = boundsMaxx - boundsMinx; | ||
const blockSamples = (x, y, size, exclusive, outBounds) => { | ||
const blockSamples = (x: number, y: number, size: number, exclusive: boolean, outBounds: Array<number>) => { | ||
const padding = exclusive ? 1 : 0; | ||
@@ -402,0 +402,0 @@ const minx = x * size; |
@@ -26,2 +26,3 @@ // @flow | ||
import type {QueryFeature} from '../util/vectortile_to_geojson.js'; | ||
import type {FeatureStates} from "../source/source_state"; | ||
import type {FeatureFilter} from '../style-spec/feature_filter/index.js'; | ||
@@ -130,3 +131,3 @@ import type Transform from '../geo/transform.js'; | ||
const bounds = tilespaceGeometry.bufferedTilespaceBounds; | ||
const queryPredicate = (bx1, by1, bx2, by2) => { | ||
const queryPredicate = (bx1: number, by1: number, bx2: number, by2: number) => { | ||
return polygonIntersectsBox(tilespaceGeometry.bufferedTilespaceGeometry, bx1, by1, bx2, by2); | ||
@@ -197,5 +198,7 @@ }; | ||
const evaluationFeature = toEvaluationFeature(feature, true); | ||
// $FlowFixMe[method-unbinding] | ||
if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) { | ||
return; | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
} else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) { | ||
@@ -311,4 +314,5 @@ return; | ||
const propName = typeof this.promoteId === 'string' ? this.promoteId : this.promoteId[sourceLayerId]; | ||
// $FlowFixMe[incompatible-type] - Flow can't narrow the id type from IVectorTileFeature.id | ||
if (propName != null) id = feature.properties[propName]; | ||
if (typeof id === 'boolean') id = Number(id); | ||
if (typeof id === 'boolean') id = Number(id); | ||
} | ||
@@ -323,3 +327,3 @@ return id; | ||
function evaluateProperties(serializedProperties, styleLayerProperties, feature, featureState, availableImages) { | ||
function evaluateProperties(serializedProperties: mixed, styleLayerProperties: mixed, feature: IVectorTileFeature, featureState: FeatureStates, availableImages: Array<string>) { | ||
return mapObject(serializedProperties, (property, key) => { | ||
@@ -331,4 +335,4 @@ const prop = styleLayerProperties instanceof PossiblyEvaluated ? styleLayerProperties.get(key) : null; | ||
function topDownFeatureComparator(a, b) { | ||
function topDownFeatureComparator(a: number, b: number) { | ||
return b - a; | ||
} |
@@ -97,3 +97,3 @@ // @flow | ||
// uses Hoare partitioning & manual tail call optimization to avoid worst case scenarios | ||
function sort(ids, positions, left, right) { | ||
function sort(ids: Float64Array, positions: Uint32Array, left: number, right: number) { | ||
while (left < right) { | ||
@@ -124,3 +124,3 @@ const pivot = ids[(left + right) >> 1]; | ||
function swap(arr, i, j) { | ||
function swap(arr: Uint32Array | Float64Array, i: number, j: number) { | ||
const tmp = arr[i]; | ||
@@ -127,0 +127,0 @@ arr[i] = arr[j]; |
@@ -35,3 +35,3 @@ // @flow | ||
// a subset of VectorTileGeometry | ||
type FeatureWithGeometry = { | ||
interface FeatureWithGeometry { | ||
extent: number; | ||
@@ -57,3 +57,3 @@ type: 1 | 2 | 3; | ||
const reproject = (p) => { | ||
const reproject = (p: Point) => { | ||
const lng = lngFromMercatorX((canonical.x + p.x / extent) / z2); | ||
@@ -60,0 +60,0 @@ const lat = latFromMercatorY((canonical.y + p.y / extent) / z2); |
@@ -109,3 +109,5 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
getBinding(context: Context, _: string): $Shape<Uniform<any>> { | ||
// $FlowFixMe[method-unbinding] | ||
return (this.type === 'color') ? | ||
@@ -140,3 +142,5 @@ new UniformColor(context) : | ||
// $FlowFixMe[method-unbinding] | ||
getBinding(context: Context, name: string): $Shape<Uniform<any>> { | ||
// $FlowFixMe[method-unbinding] | ||
return name === 'u_pattern' || name === 'u_dash' ? | ||
@@ -173,2 +177,3 @@ new Uniform4f(context) : | ||
assert(Array.isArray(availableImages)); | ||
// $FlowFixMe[method-unbinding] | ||
const value = this.expression.evaluate(new EvaluationParameters(0), feature, {}, canonical, availableImages, formattedSection); | ||
@@ -184,3 +189,3 @@ this.paintVertexArray.resize(newLength); | ||
_setPaintValue(start, end, value) { | ||
_setPaintValue(start: number, end: number, value: any) { | ||
if (this.type === 'color') { | ||
@@ -245,3 +250,5 @@ const color = packColor(value); | ||
populatePaintArray(newLength: number, feature: Feature, imagePositions: SpritePositions, availableImages: Array<string>, canonical?: CanonicalTileID, formattedSection?: FormattedSection) { | ||
// $FlowFixMe[method-unbinding] | ||
const min = this.expression.evaluate(new EvaluationParameters(this.zoom), feature, {}, canonical, availableImages, formattedSection); | ||
// $FlowFixMe[method-unbinding] | ||
const max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1), feature, {}, canonical, availableImages, formattedSection); | ||
@@ -259,3 +266,3 @@ const start = this.paintVertexArray.length; | ||
_setPaintValue(start, end, min, max) { | ||
_setPaintValue(start: number, end: number, min: any, max: any) { | ||
if (this.type === 'color') { | ||
@@ -297,2 +304,3 @@ const minColor = packColor(min); | ||
// $FlowFixMe[method-unbinding] | ||
getBinding(context: Context, _: string): Uniform1f { | ||
@@ -333,3 +341,3 @@ return new Uniform1f(context); | ||
_setPaintValues(start, end, patterns, positions) { | ||
_setPaintValues(start: number, end: number, patterns: ?string, positions: SpritePositions) { | ||
if (!positions || !patterns) return; | ||
@@ -398,3 +406,3 @@ | ||
const type = value.property.specification.type; | ||
const useIntegerZoom = value.property.useIntegerZoom; | ||
const useIntegerZoom = !!value.property.useIntegerZoom; | ||
const isPattern = property === 'line-dasharray' || property.endsWith('pattern'); | ||
@@ -412,4 +420,9 @@ const sourceException = property === 'line-dasharray' && (layer.layout: any).get('line-cap').value.kind !== 'constant'; | ||
this.binders[property] = isPattern ? | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[incompatible-call] - expression can be a `composite` or `constant` kind expression | ||
new PatternCompositeBinder(expression, names, type, StructArrayLayout, layer.id) : | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[incompatible-call] - expression can be a `composite` or `constant` kind expression | ||
new SourceExpressionBinder(expression, names, type, StructArrayLayout); | ||
keys.push(`/a_${property}`); | ||
@@ -419,2 +432,4 @@ | ||
const StructArrayLayout = layoutType(property, type, 'composite'); | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[incompatible-call] — expression can be a `constant` kind expression | ||
this.binders[property] = new CompositeExpressionBinder(expression, names, type, useIntegerZoom, zoom, StructArrayLayout); | ||
@@ -638,3 +653,3 @@ keys.push(`/z_${property}`); | ||
function paintAttributeNames(property, type) { | ||
function paintAttributeNames(property: string, type: string) { | ||
return attributeNameExceptions[property] || [property.replace(`${type}-`, '').replace(/-/g, '_')]; | ||
@@ -673,4 +688,7 @@ } | ||
function layoutType(property, type, binderType) { | ||
type LayoutType = 'array' | 'boolean' | 'color' | 'enum' | 'number' | 'resolvedImage' | 'string'; | ||
function layoutType(property: string, type: LayoutType, binderType: string) { | ||
const layoutException = propertyExceptions[property]; | ||
// $FlowFixMe[prop-missing] - we don't cover all types in defaultLayouts for some reason | ||
return (layoutException && layoutException[binderType]) || defaultLayouts[type][binderType]; | ||
@@ -677,0 +695,0 @@ } |
@@ -100,2 +100,3 @@ // @flow | ||
} else if (Array.isArray(obj)) { | ||
// $FlowFixMe[method-unbinding] | ||
if (obj.length === 4 || obj.every(Array.isArray)) { | ||
@@ -108,3 +109,3 @@ const lngLatBoundsObj = ((obj: any): LngLatBoundsLike); | ||
} | ||
} else if (typeof obj === 'object' && obj !== null && obj.hasOwnProperty("lat") && obj.hasOwnProperty("lon")) { | ||
} else if (typeof obj === 'object' && obj !== null && obj.hasOwnProperty("lat") && (obj.hasOwnProperty("lon") || obj.hasOwnProperty("lng"))) { | ||
return this.extend(LngLat.convert(obj)); | ||
@@ -111,0 +112,0 @@ } else { |
@@ -5,2 +5,3 @@ // @flow | ||
import LngLatBounds from './lng_lat_bounds.js'; | ||
import {GLOBE_RADIUS, globeMetersToEcef, latLngToECEF} from '../geo/projection/globe_util.js'; | ||
@@ -14,2 +15,7 @@ /* | ||
/* | ||
* The average circumference of the earth in meters. | ||
*/ | ||
export const earthCircumference = 2 * Math.PI * earthRadius; | ||
/** | ||
@@ -126,2 +132,8 @@ * A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees. | ||
toEcef(altitude: number): [number, number, number] { | ||
const altInEcef = globeMetersToEcef(altitude); | ||
const radius = GLOBE_RADIUS + altInEcef; | ||
return (latLngToECEF(this.lat, this.lng, radius): any); | ||
} | ||
/** | ||
@@ -128,0 +140,0 @@ * Converts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties |
// @flow | ||
import LngLat, {earthRadius} from '../geo/lng_lat.js'; | ||
import LngLat, {earthCircumference} from '../geo/lng_lat.js'; | ||
import type {LngLatLike} from '../geo/lng_lat.js'; | ||
/* | ||
* The average circumference of the world in meters. | ||
*/ | ||
const earthCircumference = 2 * Math.PI * earthRadius; // meters | ||
/* | ||
* The circumference at a line of latitude in meters. | ||
@@ -13,0 +8,0 @@ */ |
@@ -81,3 +81,3 @@ // @flow | ||
function getShearAdjustment(projection, zoom, loc, interpT, withoutRotation?: boolean) { | ||
function getShearAdjustment(projection: Projection, zoom: number, loc: LngLat, interpT: number, withoutRotation?: boolean) { | ||
@@ -145,3 +145,3 @@ // create two locations a tiny amount (~1km) east and west of the given location | ||
function rotate(x, y, angle) { | ||
function rotate(x: number, y: number, angle: number) { | ||
const cos = Math.cos(angle); | ||
@@ -148,0 +148,0 @@ const sin = Math.sin(angle); |
@@ -19,3 +19,3 @@ // @flow | ||
import {Aabb, Ray} from '../../util/primitives.js'; | ||
import LngLat from '../lng_lat.js'; | ||
import LngLat, {earthRadius} from '../lng_lat.js'; | ||
import LngLatBounds from '../lng_lat_bounds.js'; | ||
@@ -52,3 +52,2 @@ | ||
export const GLOBE_RADIUS = EXTENT / Math.PI / 2.0; | ||
export const GLOBE_METERS_TO_ECEF = mercatorZfromAltitude(1, 0.0) * 2.0 * GLOBE_RADIUS * Math.PI; | ||
const GLOBE_NORMALIZATION_BIT_RANGE = 15; | ||
@@ -73,2 +72,6 @@ const GLOBE_NORMALIZATION_MASK = (1 << (GLOBE_NORMALIZATION_BIT_RANGE - 1)) - 1; | ||
export function globeMetersToEcef(d: number): number { | ||
return d * GLOBE_RADIUS / earthRadius; | ||
} | ||
export function globePointCoordinate(tr: Transform, x: number, y: number, clampToHorizon: boolean = true): ?MercatorCoordinate { | ||
@@ -384,3 +387,3 @@ const point0 = vec3.scale([], tr._camera.position, tr.worldSize); | ||
let wrap = 0; | ||
const tileCenterXFromCamera = (w + e) / 2 - camX; | ||
const tileCenterXFromCamera = (w + e) / 2 - camX; | ||
if (tileCenterXFromCamera > .5) { | ||
@@ -396,6 +399,6 @@ wrap = -1; | ||
// Transform Mercator coordinates to points on the plane tangent to the globe at cameraCenter. | ||
w = ((w + wrap) * numTiles - camX) * mercatorScale + camX; | ||
e = ((e + wrap) * numTiles - camX) * mercatorScale + camX; | ||
n = (n * numTiles - camY) * mercatorScale + camY; | ||
s = (s * numTiles - camY) * mercatorScale + camY; | ||
w = ((w + wrap) * numTiles - camX) * mercatorScale + camX; | ||
e = ((e + wrap) * numTiles - camX) * mercatorScale + camX; | ||
n = (n * numTiles - camY) * mercatorScale + camY; | ||
s = (s * numTiles - camY) * mercatorScale + camY; | ||
@@ -501,3 +504,3 @@ return [[w, s, 0], | ||
function calculateGlobePosMatrix(x, y, worldSize, lng, lat): Float64Array { | ||
function calculateGlobePosMatrix(x: number, y: number, worldSize: number, lng: number, lat: number): Float64Array { | ||
// transform the globe from reference coordinate space to world space | ||
@@ -644,3 +647,3 @@ const scale = globeECEFUnitsToPixelScale(worldSize); | ||
const pivotToCamera = vec3.normalize([], centerToPivot); | ||
vec3.scale(pivotToCamera, pivotToCamera, tr.cameraToCenterDistance / tr.pixelsPerMeter * GLOBE_METERS_TO_ECEF); | ||
vec3.scale(pivotToCamera, pivotToCamera, globeMetersToEcef(tr.cameraToCenterDistance / tr.pixelsPerMeter)); | ||
vec3.transformMat4(pivotToCamera, pivotToCamera, rotation); | ||
@@ -701,2 +704,16 @@ | ||
// Generate terrain grid with embedded skirts | ||
const EMBED_SKIRTS = true; | ||
type GridLodSegments = { | ||
withoutSkirts: SegmentVector, | ||
withSkirts: SegmentVector | ||
}; | ||
type GridWithLods = { | ||
vertices: PosArray, | ||
indices: TriangleIndexArray, | ||
segments: Array<GridLodSegments> | ||
}; | ||
export class GlobeSharedBuffers { | ||
@@ -710,3 +727,3 @@ _poleNorthVertexBuffer: VertexBuffer; | ||
_gridIndexBuffer: IndexBuffer; | ||
_gridSegments: Array<SegmentVector>; | ||
_gridSegments: Array<GridLodSegments>; | ||
@@ -728,3 +745,6 @@ _wireframeIndexBuffer: IndexBuffer; | ||
for (const segments of this._poleSegments) segments.destroy(); | ||
for (const segments of this._gridSegments) segments.destroy(); | ||
for (const segments of this._gridSegments) { | ||
segments.withSkirts.destroy(); | ||
segments.withoutSkirts.destroy(); | ||
} | ||
@@ -737,35 +757,132 @@ if (this._wireframeIndexBuffer) { | ||
_createGrid(context: Context) { | ||
const gridVertices = new PosArray(); | ||
const gridIndices = new TriangleIndexArray(); | ||
// Generate terrain grid vertices and indices for all LOD's | ||
// | ||
// Grid vertices memory layout: | ||
// | ||
// First line Skirt | ||
// ┌───────────────┐ | ||
// │┌─────────────┐│ | ||
// Left ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ Right | ||
// Border ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ Border | ||
// Skirt │├─────────────┤│ Skirt | ||
// ││ Main Grid ││ | ||
// │├─────────────┤│ | ||
// ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ | ||
// ││┼┼┼┼┼┼┼┼┼┼┼┼┼││ | ||
// │└─────────────┘│ | ||
// ├───────────────┤ | ||
// ├───────────────┤ | ||
// └───────────────┘ | ||
// Bottom Skirt = Number of LOD's | ||
// | ||
_fillGridMeshWithLods(longitudinalCellsCount: number, latitudinalLods: number[]): GridWithLods { | ||
const vertices = new PosArray(); | ||
const indices = new TriangleIndexArray(); | ||
const segments: Array<GridLodSegments> = []; | ||
const quadExt = GLOBE_VERTEX_GRID_SIZE; | ||
const vertexExt = quadExt + 1; | ||
const xVertices = longitudinalCellsCount + 1 + 2 * (EMBED_SKIRTS ? 1 : 0); | ||
const yVerticesHighLodNoStrip = latitudinalLods[0] + 1; | ||
const yVerticesHighLodWithStrip = latitudinalLods[0] + 1 + (EMBED_SKIRTS ? 1 + latitudinalLods.length : 0); | ||
for (let j = 0; j < vertexExt; j++) | ||
for (let i = 0; i < vertexExt; i++) | ||
gridVertices.emplaceBack(i, j); | ||
// Index adjustment, used to make strip (x, y) vertex input attribute data | ||
// to match same data on ordinary grid edges | ||
const prepareVertex = (x: number, y: number, isSkirt: boolean) => { | ||
if (!EMBED_SKIRTS) return [x, y]; | ||
this._gridSegments = []; | ||
for (let k = 0, primitiveOffset = 0; k < GLOBE_LATITUDINAL_GRID_LOD_TABLE.length; k++) { | ||
const latitudinalLod = GLOBE_LATITUDINAL_GRID_LOD_TABLE[k]; | ||
for (let j = 0; j < latitudinalLod; j++) { | ||
for (let i = 0; i < quadExt; i++) { | ||
const index = j * vertexExt + i; | ||
gridIndices.emplaceBack(index + 1, index, index + vertexExt); | ||
gridIndices.emplaceBack(index + vertexExt, index + vertexExt + 1, index + 1); | ||
let adjustedX = (() => { | ||
if (x === xVertices - 1) { | ||
return x - 2; | ||
} else if (x === 0) { | ||
return x; | ||
} else { | ||
return x - 1; | ||
} | ||
})(); | ||
// Skirt factor is introduces as an offset to the .x coordinate, similar to how it's done for mercator grids | ||
const skirtOffset = 24575; | ||
adjustedX += isSkirt ? skirtOffset : 0; | ||
return [adjustedX, y]; | ||
}; | ||
// Add first horizontal strip if present | ||
if (EMBED_SKIRTS) { | ||
for (let x = 0; x < xVertices; ++x) { | ||
vertices.emplaceBack(...prepareVertex(x, 0, true)); | ||
} | ||
} | ||
const numVertices = (latitudinalLod + 1) * vertexExt; | ||
const numPrimitives = latitudinalLod * quadExt * 2; | ||
// Add main grid part with vertices strips embedded | ||
for (let y = 0; y < yVerticesHighLodNoStrip; ++y) { | ||
for (let x = 0; x < xVertices; ++x) { | ||
const isSideBorder = (x === 0 || x === xVertices - 1); | ||
this._gridSegments.push(SegmentVector.simpleSegment(0, primitiveOffset, numVertices, numPrimitives)); | ||
primitiveOffset += numPrimitives; | ||
vertices.emplaceBack(...prepareVertex(x, y, isSideBorder && EMBED_SKIRTS)); | ||
} | ||
} | ||
this._gridBuffer = context.createVertexBuffer(gridVertices, posAttributes.members); | ||
this._gridIndexBuffer = context.createIndexBuffer(gridIndices, true); | ||
// Add bottom strips for each LOD | ||
if (EMBED_SKIRTS) { | ||
for (let lodIdx = 0; lodIdx < latitudinalLods.length; ++lodIdx) { | ||
const lastYRowForLod = latitudinalLods[lodIdx]; | ||
for (let x = 0; x < xVertices; ++x) { | ||
vertices.emplaceBack(...prepareVertex(x, lastYRowForLod, true)); | ||
} | ||
} | ||
} | ||
// Fill triangles | ||
for (let lodIdx = 0; lodIdx < latitudinalLods.length; ++lodIdx) { | ||
const indexOffset = indices.length; | ||
const yVerticesLod = latitudinalLods[lodIdx] + 1 + 2 * (EMBED_SKIRTS ? 1 : 0); | ||
const skirtsOnlyIndices = new TriangleIndexArray(); | ||
for (let y = 0; y < yVerticesLod - 1; y++) { | ||
const isLastLine = (y === yVerticesLod - 2); | ||
const offsetToNextRow = | ||
(isLastLine && EMBED_SKIRTS ? | ||
(xVertices * (yVerticesHighLodWithStrip - latitudinalLods.length + lodIdx - y)) : | ||
xVertices); | ||
for (let x = 0; x < xVertices - 1; x++) { | ||
const idx = y * xVertices + x; | ||
const isSkirt = EMBED_SKIRTS && (y === 0 || isLastLine || x === 0 || x === xVertices - 2); | ||
if (isSkirt) { | ||
skirtsOnlyIndices.emplaceBack(idx + 1, idx, idx + offsetToNextRow); | ||
skirtsOnlyIndices.emplaceBack(idx + offsetToNextRow, idx + offsetToNextRow + 1, idx + 1); | ||
} else { | ||
indices.emplaceBack(idx + 1, idx, idx + offsetToNextRow); | ||
indices.emplaceBack(idx + offsetToNextRow, idx + offsetToNextRow + 1, idx + 1); | ||
} | ||
} | ||
} | ||
// Segments grid only | ||
const withoutSkirts = SegmentVector.simpleSegment(0, indexOffset, vertices.length, indices.length - indexOffset); | ||
for (let i = 0; i < skirtsOnlyIndices.uint16.length; i += 3) { | ||
indices.emplaceBack(skirtsOnlyIndices.uint16[i], skirtsOnlyIndices.uint16[i + 1], skirtsOnlyIndices.uint16[i + 2]); | ||
} | ||
// Segments grid + skirts only | ||
const withSkirts = SegmentVector.simpleSegment(0, indexOffset, vertices.length, indices.length - indexOffset); | ||
segments.push({withoutSkirts, withSkirts}); | ||
} | ||
return {vertices, indices, segments}; | ||
} | ||
_createGrid(context: Context) { | ||
const gridWithLods = this._fillGridMeshWithLods(GLOBE_VERTEX_GRID_SIZE, GLOBE_LATITUDINAL_GRID_LOD_TABLE); | ||
this._gridSegments = gridWithLods.segments; | ||
this._gridBuffer = context.createVertexBuffer(gridWithLods.vertices, posAttributes.members); | ||
this._gridIndexBuffer = context.createIndexBuffer(gridWithLods.indices, true); | ||
} | ||
_createPoles(context: Context) { | ||
@@ -808,4 +925,4 @@ const poleIndices = new TriangleIndexArray(); | ||
getGridBuffers(latitudinalLod: number): [VertexBuffer, IndexBuffer, SegmentVector] { | ||
return [this._gridBuffer, this._gridIndexBuffer, this._gridSegments[latitudinalLod]]; | ||
getGridBuffers(latitudinalLod: number, withSkirts: boolean): [VertexBuffer, IndexBuffer, SegmentVector] { | ||
return [this._gridBuffer, this._gridIndexBuffer, withSkirts ? this._gridSegments[latitudinalLod].withSkirts : this._gridSegments[latitudinalLod].withoutSkirts]; | ||
} | ||
@@ -821,9 +938,11 @@ | ||
const quadExt = GLOBE_VERTEX_GRID_SIZE; | ||
const vertexExt = quadExt + 1; | ||
const vertexExt = quadExt + 1 + (EMBED_SKIRTS ? 2 : 0); | ||
const iterOffset = EMBED_SKIRTS ? 1 : 0; | ||
this._wireframeSegments = []; | ||
for (let k = 0, primitiveOffset = 0; k < GLOBE_LATITUDINAL_GRID_LOD_TABLE.length; k++) { | ||
const latitudinalLod = GLOBE_LATITUDINAL_GRID_LOD_TABLE[k]; | ||
for (let j = 0; j < latitudinalLod; j++) { | ||
for (let i = 0; i < quadExt; i++) { | ||
for (let j = iterOffset; j < latitudinalLod + iterOffset; j++) { | ||
for (let i = iterOffset; i < quadExt + iterOffset; i++) { | ||
const index = j * vertexExt + i; | ||
@@ -830,0 +949,0 @@ wireframeIndices.emplaceBack(index, index + 1); |
@@ -14,3 +14,2 @@ // @flow | ||
import { | ||
GLOBE_METERS_TO_ECEF, | ||
GLOBE_SCALE_MATCH_LATITUDE, | ||
@@ -24,3 +23,4 @@ latLngToECEF, | ||
globePointCoordinate, | ||
tileCoordToECEF | ||
tileCoordToECEF, | ||
globeMetersToEcef | ||
} from './globe_util.js'; | ||
@@ -42,3 +42,3 @@ | ||
this.zAxisUnit = "pixels"; | ||
this.unsupportedLayers = ['debug', 'custom']; | ||
this.unsupportedLayers = ['debug']; | ||
this.range = [3, 5]; | ||
@@ -146,4 +146,4 @@ } | ||
upVectorScale(id: CanonicalTileID): ElevationScale { | ||
return {metersToTile: GLOBE_METERS_TO_ECEF * globeECEFNormalizationScale(globeTileBounds(id))}; | ||
return {metersToTile: globeMetersToEcef(globeECEFNormalizationScale(globeTileBounds(id)))}; | ||
} | ||
} |
@@ -12,3 +12,3 @@ // @flow | ||
function tany(y) { | ||
function tany(y: number) { | ||
return Math.tan((halfPi + y) / 2); | ||
@@ -15,0 +15,0 @@ } |
@@ -5,3 +5,3 @@ // @flow | ||
function pointToLineDist(px, py, ax, ay, bx, by) { | ||
function pointToLineDist(px: number, py: number, ax: number, ay: number, bx: number, by: number) { | ||
const dx = ax - bx; | ||
@@ -12,3 +12,3 @@ const dy = ay - by; | ||
function addResampled(resampled, mx0, my0, mx2, my2, start, end, reproject, tolerance) { | ||
function addResampled(resampled: Array<Point>, mx0: number, my0: number, mx2: number, my2: number, start: Point, end: Point, reproject: ((Point) => void), tolerance: number) { | ||
const mx1 = (mx0 + mx2) / 2; | ||
@@ -54,3 +54,3 @@ const my1 = (my0 + my2) / 2; | ||
function addResampledPred(resampled: Point[], a: Point, b: Point, pred) { | ||
function addResampledPred(resampled: Point[], a: Point, b: Point, pred: ((Point, Point) => boolean)) { | ||
const split = pred(a, b); | ||
@@ -57,0 +57,0 @@ |
@@ -12,3 +12,3 @@ // @flow | ||
import type {Vec3} from 'gl-matrix'; | ||
import type Projection from './projection.js'; | ||
import type Projection, {ProjectedPoint} from './projection.js'; | ||
import type Transform from '../transform.js'; | ||
@@ -55,3 +55,3 @@ | ||
function processSegment(pa, pb, ax, ay, bx, by) { | ||
function processSegment(pa: ProjectedPoint, pb: ProjectedPoint, ax: number, ay: number, bx: number, by: number) { | ||
const mx = (ax + bx) / 2; | ||
@@ -119,3 +119,3 @@ const my = (ay + by) / 2; | ||
export function getTilePoint(tileTransform: TileTransform, {x, y}: {x: number, y: number}, wrap: number = 0): Point { | ||
export function getTilePoint(tileTransform: TileTransform, {x, y}: interface { x: number, y: number }, wrap: number = 0): Point { | ||
return new Point( | ||
@@ -122,0 +122,0 @@ ((x - wrap) * tileTransform.scale - tileTransform.x) * EXTENT, |
@@ -28,2 +28,3 @@ // @flow | ||
gl: WebGLRenderingContext; | ||
isWebGL2: boolean; | ||
extVertexArrayObject: any; | ||
@@ -78,6 +79,17 @@ currentNumAttributes: ?number; | ||
constructor(gl: WebGLRenderingContext) { | ||
constructor(gl: WebGLRenderingContext, isWebGL2: boolean = false) { | ||
this.gl = gl; | ||
this.isWebGL2 = isWebGL2; | ||
this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object'); | ||
if (isWebGL2) { | ||
/* $FlowFixMe[cannot-resolve-name] */ // Not adding dependency to webgl2 yet. | ||
const gl2 = (gl: WebGL2RenderingContext); | ||
this.extVertexArrayObject = { | ||
createVertexArrayOES: gl2.createVertexArray.bind(gl), | ||
deleteVertexArrayOES: gl2.deleteVertexArray.bind(gl), | ||
bindVertexArrayOES: gl2.bindVertexArray.bind(gl) | ||
}; | ||
} | ||
this.clearColor = new ClearColor(this); | ||
@@ -132,8 +144,7 @@ this.clearDepth = new ClearDepth(this); | ||
this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float'); | ||
if (this.extTextureHalfFloat) { | ||
gl.getExtension('OES_texture_half_float_linear'); | ||
if (!isWebGL2) this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float'); | ||
if (isWebGL2 || (this.extTextureHalfFloat && gl.getExtension('OES_texture_half_float_linear'))) { | ||
this.extRenderToTextureHalfFloat = gl.getExtension('EXT_color_buffer_half_float'); | ||
} | ||
this.extStandardDerivatives = gl.getExtension('OES_standard_derivatives'); | ||
this.extStandardDerivatives = isWebGL2 || gl.getExtension('OES_standard_derivatives'); | ||
@@ -140,0 +151,0 @@ this.extTimerQuery = gl.getExtension('EXT_disjoint_timer_query'); |
@@ -20,3 +20,3 @@ // @flow | ||
const gl = context.gl; | ||
const fbo = this.framebuffer = gl.createFramebuffer(); | ||
const fbo = this.framebuffer = ((gl.createFramebuffer(): any): WebGLFramebuffer); | ||
@@ -23,0 +23,0 @@ this.colorAttachment = new ColorAttachment(context, fbo); |
@@ -10,3 +10,3 @@ // @flow | ||
context: Context; | ||
buffer: WebGLBuffer; | ||
buffer: ?WebGLBuffer; | ||
dynamicDraw: boolean; | ||
@@ -13,0 +13,0 @@ |
@@ -324,3 +324,3 @@ // @flow | ||
export class Program extends BaseValue<?WebGLProgram> { | ||
getDefault(): WebGLProgram { | ||
getDefault(): WebGLProgram | null { | ||
return null; | ||
@@ -363,3 +363,3 @@ } | ||
export class BindFramebuffer extends BaseValue<?WebGLFramebuffer> { | ||
getDefault(): WebGLFramebuffer { | ||
getDefault(): WebGLFramebuffer | null { | ||
return null; | ||
@@ -377,3 +377,3 @@ } | ||
export class BindRenderbuffer extends BaseValue<?WebGLRenderbuffer> { | ||
getDefault(): WebGLRenderbuffer { | ||
getDefault(): WebGLRenderbuffer | null { | ||
return null; | ||
@@ -391,3 +391,3 @@ } | ||
export class BindTexture extends BaseValue<?WebGLTexture> { | ||
getDefault(): WebGLTexture { | ||
getDefault(): WebGLTexture | null { | ||
return null; | ||
@@ -405,3 +405,3 @@ } | ||
export class BindVertexBuffer extends BaseValue<?WebGLBuffer> { | ||
getDefault(): WebGLBuffer { | ||
getDefault(): WebGLBuffer | null { | ||
return null; | ||
@@ -419,3 +419,3 @@ } | ||
export class BindElementBuffer extends BaseValue<?WebGLBuffer> { | ||
getDefault(): WebGLBuffer { | ||
getDefault(): WebGLBuffer | null { | ||
return null; | ||
@@ -422,0 +422,0 @@ } |
@@ -39,3 +39,3 @@ // @flow | ||
context: Context; | ||
buffer: WebGLBuffer; | ||
buffer: ?WebGLBuffer; | ||
@@ -42,0 +42,0 @@ /** |
@@ -8,8 +8,12 @@ // @flow | ||
import {warnOnce} from '../util/util.js'; | ||
import {globeToMercatorTransition} from './../geo/projection/globe_util.js'; | ||
import type Painter from './painter.js'; | ||
import type {OverscaledTileID} from '../source/tile_id.js'; | ||
import type SourceCache from '../source/source_cache.js'; | ||
import type CustomStyleLayer from '../style/style_layer/custom_style_layer.js'; | ||
import MercatorCoordinate from '../geo/mercator_coordinate.js'; | ||
import assert from 'assert'; | ||
function drawCustom(painter: Painter, sourceCache: SourceCache, layer: CustomStyleLayer) { | ||
function drawCustom(painter: Painter, sourceCache: SourceCache, layer: CustomStyleLayer, coords: Array<OverscaledTileID>) { | ||
@@ -19,4 +23,5 @@ const context = painter.context; | ||
if (painter.transform.projection.unsupportedLayers && painter.transform.projection.unsupportedLayers.includes("custom")) { | ||
warnOnce('Custom layers are not yet supported with non-mercator projections. Use mercator to enable custom layers.'); | ||
if (painter.transform.projection.unsupportedLayers && painter.transform.projection.unsupportedLayers.includes("custom") && | ||
!(painter.terrain && (painter.terrain.renderingToTexture || painter.renderPass === 'offscreen') && layer.isLayerDraped())) { | ||
warnOnce('Custom layers are not yet supported with this projection. Use mercator or globe to enable usage of custom layers.'); | ||
return; | ||
@@ -32,3 +37,8 @@ } | ||
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix()); | ||
if (painter.transform.projection.name === "globe") { | ||
const center = painter.transform.pointMerc; | ||
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio); | ||
} else { | ||
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix()); | ||
} | ||
@@ -41,2 +51,22 @@ context.setDirty(); | ||
if (painter.terrain && painter.terrain.renderingToTexture) { | ||
assert(implementation.renderToTile); | ||
assert(coords.length === 1); | ||
const renderToTile = implementation.renderToTile; | ||
if (renderToTile) { | ||
const c = coords[0].canonical; | ||
const unwrapped = new MercatorCoordinate(c.x + coords[0].wrap * (1 << c.z), c.y, c.z); | ||
context.setDepthMode(DepthMode.disabled); | ||
context.setStencilMode(StencilMode.disabled); | ||
context.setColorMode(painter.colorModeForRenderPass()); | ||
painter.setCustomLayerDefaults(); | ||
renderToTile.call(implementation, context.gl, unwrapped); | ||
context.setDirty(); | ||
painter.setBaseState(); | ||
} | ||
return; | ||
} | ||
painter.setCustomLayerDefaults(); | ||
@@ -53,3 +83,8 @@ | ||
implementation.render(context.gl, painter.transform.customLayerMatrix()); | ||
if (painter.transform.projection.name === "globe") { | ||
const center = painter.transform.pointMerc; | ||
implementation.render(context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio); | ||
} else { | ||
implementation.render(context.gl, painter.transform.customLayerMatrix()); | ||
} | ||
@@ -56,0 +91,0 @@ context.setDirty(); |
@@ -148,3 +148,3 @@ // @flow | ||
function drawTileQueryGeometry(painter, sourceCache, coord: OverscaledTileID) { | ||
function drawTileQueryGeometry(painter: Painter, sourceCache: SourceCache, coord: OverscaledTileID) { | ||
const context = painter.context; | ||
@@ -151,0 +151,0 @@ const gl = context.gl; |
@@ -18,5 +18,8 @@ // @flow | ||
import {globeToMercatorTransition} from '../geo/projection/globe_util.js'; | ||
import Context from '../gl/context.js'; | ||
import {Terrain} from '../terrain/terrain.js'; | ||
import type Painter from './painter.js'; | ||
import type SourceCache from '../source/source_cache.js'; | ||
import type {PartMetadata} from '../data/bucket/fill_extrusion_bucket.js'; | ||
import type FillExtrusionStyleLayer from '../style/style_layer/fill_extrusion_style_layer.js'; | ||
@@ -58,3 +61,3 @@ | ||
function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode) { | ||
function drawExtrusionTiles(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLayer, coords: Array<OverscaledTileID>, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { | ||
const context = painter.context; | ||
@@ -68,2 +71,4 @@ const gl = context.gl; | ||
const edgeRadius = layer.layout.get('fill-extrusion-edge-radius'); | ||
const zeroRoofRadius = edgeRadius > 0 && !layer.paint.get('fill-extrusion-rounded-roof'); | ||
const roofEdgeRadius = zeroRoofRadius ? 0.0 : edgeRadius; | ||
const heightLift = tr.projection.name === 'globe' ? fillExtrusionHeightLift() : 0; | ||
@@ -76,5 +81,2 @@ const isGlobeProjection = tr.projection.name === 'globe'; | ||
baseDefines.push('PROJECTION_GLOBE_VIEW'); | ||
if (painter.style.terrainSetForDrapingOnly()) { | ||
baseDefines.push('TERRAIN'); | ||
} | ||
} | ||
@@ -84,2 +86,5 @@ if (ao[0] > 0) { // intensity | ||
} | ||
if (zeroRoofRadius) { | ||
baseDefines.push('ZERO_ROOF_RADIUS'); | ||
} | ||
@@ -131,5 +136,5 @@ for (const coord of coords) { | ||
const uniformValues = image ? | ||
fillExtrusionPatternUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, edgeRadius, coord, | ||
fillExtrusionPatternUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, roofEdgeRadius, coord, | ||
tile, heightLift, globeToMercator, mercatorCenter, invMatrix) : | ||
fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, edgeRadius, coord, | ||
fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, ao, roofEdgeRadius, coord, | ||
heightLift, globeToMercator, mercatorCenter, invMatrix); | ||
@@ -154,6 +159,6 @@ | ||
// For them, join pieces, calculate joined size here, and then upload data. | ||
function flatRoofsUpdate(context, source, coord, bucket, layer, terrain) { | ||
function flatRoofsUpdate(context: Context, source: SourceCache, coord: OverscaledTileID, bucket: FillExtrusionBucket, layer: FillExtrusionStyleLayer, terrain: Terrain) { | ||
// For all four borders: 0 - left, 1, right, 2 - top, 3 - bottom | ||
const neighborCoord = [ | ||
coord => { | ||
(coord: OverscaledTileID) => { | ||
let x = coord.canonical.x - 1; | ||
@@ -167,3 +172,3 @@ let w = coord.wrap; | ||
}, | ||
coord => { | ||
(coord: OverscaledTileID) => { | ||
let x = coord.canonical.x + 1; | ||
@@ -177,11 +182,11 @@ let w = coord.wrap; | ||
}, | ||
coord => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, | ||
(coord: OverscaledTileID) => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, | ||
(coord.canonical.y === 0 ? 1 << coord.canonical.z : coord.canonical.y) - 1), | ||
coord => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, | ||
(coord: OverscaledTileID) => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, | ||
coord.canonical.y === (1 << coord.canonical.z) - 1 ? 0 : coord.canonical.y + 1) | ||
]; | ||
const getLoadedBucket = (nid) => { | ||
const getLoadedBucket = (nid: OverscaledTileID) => { | ||
const minzoom = source.getSource().minzoom; | ||
const getBucket = (key) => { | ||
const getBucket = (key: number) => { | ||
const n = source.getTileByID(key); | ||
@@ -208,3 +213,3 @@ if (n && n.hasData()) { | ||
const projectedToBorder = [0, 0, 0]; // [min, max, maxOffsetFromBorder] | ||
const xjoin = (a, b) => { | ||
const xjoin = (a: PartMetadata, b: PartMetadata) => { | ||
projectedToBorder[0] = Math.min(a.min.y, b.min.y); | ||
@@ -215,3 +220,3 @@ projectedToBorder[1] = Math.max(a.max.y, b.max.y); | ||
}; | ||
const yjoin = (a, b) => { | ||
const yjoin = (a: PartMetadata, b: PartMetadata) => { | ||
projectedToBorder[0] = Math.min(a.min.x, b.min.x); | ||
@@ -223,6 +228,6 @@ projectedToBorder[1] = Math.max(a.max.x, b.max.x); | ||
const projectCombinedSpanToBorder = [ | ||
(a, b) => xjoin(a, b), | ||
(a, b) => xjoin(b, a), | ||
(a, b) => yjoin(a, b), | ||
(a, b) => yjoin(b, a) | ||
(a: PartMetadata, b: PartMetadata) => xjoin(a, b), | ||
(a: PartMetadata, b: PartMetadata) => xjoin(b, a), | ||
(a: PartMetadata, b: PartMetadata) => yjoin(a, b), | ||
(a: PartMetadata, b: PartMetadata) => yjoin(b, a) | ||
]; | ||
@@ -235,3 +240,3 @@ | ||
const flatBase = (min, max, edge, verticalEdge, maxOffsetFromBorder) => { | ||
const flatBase = (min: number, max: number, edge: number, verticalEdge: boolean, maxOffsetFromBorder: number) => { | ||
const points = [[verticalEdge ? edge : min, verticalEdge ? min : edge, 0], [verticalEdge ? edge : max, verticalEdge ? max : edge, 0]]; | ||
@@ -238,0 +243,0 @@ |
@@ -17,2 +17,3 @@ // @flow | ||
import type FillBucket from '../data/bucket/fill_bucket.js'; | ||
import type ColorMode from '../gl/color_mode.js'; | ||
import type {OverscaledTileID} from '../source/tile_id.js'; | ||
@@ -62,3 +63,3 @@ | ||
function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, isOutline) { | ||
function drawFillTiles(painter: Painter, sourceCache: SourceCache, layer: FillStyleLayer, coords: Array<OverscaledTileID>, depthMode: DepthMode, colorMode: ColorMode, isOutline: boolean) { | ||
const gl = painter.context.gl; | ||
@@ -65,0 +66,0 @@ |
@@ -16,2 +16,4 @@ // @flow | ||
import type Painter from './painter.js'; | ||
import type Context from '../gl/context.js'; | ||
import type Framebuffer from '../gl/framebuffer.js'; | ||
import type SourceCache from '../source/source_cache.js'; | ||
@@ -90,3 +92,3 @@ import type HeatmapStyleLayer from '../style/style_layer/heatmap_style_layer.js'; | ||
function bindFramebuffer(context, painter, layer, scaling) { | ||
function bindFramebuffer(context: Context, painter: Painter, layer: HeatmapStyleLayer, scaling: number) { | ||
const gl = context.gl; | ||
@@ -121,12 +123,14 @@ const width = painter.width * scaling; | ||
function bindTextureToFramebuffer(context, painter, texture, fbo, width, height) { | ||
function bindTextureToFramebuffer(context: Context, painter: Painter, texture: ?WebGLTexture, fbo: Framebuffer, width: number, height: number) { | ||
const gl = context.gl; | ||
// Use the higher precision half-float texture where available (producing much smoother looking heatmaps); | ||
// Otherwise, fall back to a low precision texture | ||
const internalFormat = context.extRenderToTextureHalfFloat ? context.extTextureHalfFloat.HALF_FLOAT_OES : gl.UNSIGNED_BYTE; | ||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, internalFormat, null); | ||
/* $FlowFixMe[prop-missing] WebGL2 */ | ||
const type = context.extRenderToTextureHalfFloat ? (context.isWebGL2 ? gl.HALF_FLOAT : context.extTextureHalfFloat.HALF_FLOAT_OES) : gl.UNSIGNED_BYTE; | ||
/* $FlowFixMe[prop-missing] WebGL2 */ | ||
gl.texImage2D(gl.TEXTURE_2D, 0, (context.isWebGL2 && context.extRenderToTextureHalfFloat) ? gl.RGBA16F : gl.RGBA, width, height, 0, gl.RGBA, type, null); | ||
fbo.colorAttachment.set(texture); | ||
} | ||
function renderTextureToMap(painter, layer) { | ||
function renderTextureToMap(painter: Painter, layer: HeatmapStyleLayer) { | ||
const context = painter.context; | ||
@@ -133,0 +137,0 @@ const gl = context.gl; |
@@ -16,2 +16,3 @@ // @flow | ||
import type HillshadeStyleLayer from '../style/style_layer/hillshade_style_layer.js'; | ||
import type ColorMode from '../gl/color_mode.js'; | ||
import type {OverscaledTileID} from '../source/tile_id.js'; | ||
@@ -53,3 +54,3 @@ import assert from 'assert'; | ||
function renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, colorMode) { | ||
function renderHillshade(painter: Painter, coord: OverscaledTileID, tile: Tile, layer: HillshadeStyleLayer, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { | ||
const context = painter.context; | ||
@@ -97,3 +98,3 @@ const gl = context.gl; | ||
// directions for each pixel, and saves those values to a framebuffer texture in the r and g channels. | ||
function prepareHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { | ||
function prepareHillshade(painter: Painter, tile: Tile, layer: HillshadeStyleLayer, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { | ||
const context = painter.context; | ||
@@ -100,0 +101,0 @@ const gl = context.gl; |
@@ -150,3 +150,3 @@ // @flow | ||
const renderLine = (stencilMode) => { | ||
const renderLine = (stencilMode: StencilMode) => { | ||
program.draw(context, gl.TRIANGLES, depthMode, | ||
@@ -153,0 +153,0 @@ stencilMode, colorMode, CullFaceMode.disabled, uniformValues, |
@@ -65,3 +65,3 @@ // @flow | ||
const textureFilter = layer.paint.get('raster-resampling') === 'nearest' ? gl.NEAREST : gl.LINEAR; | ||
const textureFilter = layer.paint.get('raster-resampling') === 'nearest' ? gl.NEAREST : gl.LINEAR; | ||
@@ -82,2 +82,8 @@ context.activeTexture.set(gl.TEXTURE0); | ||
// Enable trilinear filtering on tiles only beyond 20 degrees pitch, | ||
// to prevent it from compromising image crispness on flat or low tilted maps. | ||
if (tile.texture.useMipmap && context.extTextureFilterAnisotropic && painter.transform.pitch > 20) { | ||
gl.texParameterf(gl.TEXTURE_2D, context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, context.extTextureFilterAnisotropicMax); | ||
} | ||
const perspectiveTransform = source instanceof ImageSource ? source.perspectiveTransform : [0, 0]; | ||
@@ -84,0 +90,0 @@ const uniformValues = rasterUniformValues(projMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer, perspectiveTransform); |
@@ -37,2 +37,3 @@ // @flow | ||
import type Texture from '../render/texture.js'; | ||
import type ColorMode from '../gl/color_mode.js'; | ||
import {OverscaledTileID} from '../source/tile_id.js'; | ||
@@ -42,2 +43,3 @@ import type {UniformValues} from './uniform_binding.js'; | ||
import type {CrossTileID, VariableOffset} from '../symbol/placement.js'; | ||
import type {InterpolatedSize} from '../symbol/symbol_size'; | ||
@@ -64,2 +66,4 @@ export default drawSymbols; | ||
type Alignment = 'auto' | 'map' | 'viewport'; | ||
function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array<OverscaledTileID>, variableOffsets: {[_: CrossTileID]: VariableOffset}) { | ||
@@ -129,3 +133,3 @@ if (painter.renderPass !== 'translucent') return; | ||
function calculateVariableRenderShift({width, height, anchor, textOffset, textScale}, renderTextSize): Point { | ||
function calculateVariableRenderShift({width, height, anchor, textOffset, textScale}: VariableOffset, renderTextSize: number): Point { | ||
const {horizontalAlign, verticalAlign} = getAnchorAlignment(anchor); | ||
@@ -141,3 +145,3 @@ const shiftX = -(horizontalAlign - 0.5) * width; | ||
function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlignment, pitchAlignment, variableOffsets) { | ||
function updateVariableAnchors(coords: Array<OverscaledTileID>, painter: Painter, layer: SymbolStyleLayer, sourceCache: SourceCache, rotationAlignment: Alignment, pitchAlignment: Alignment, variableOffsets: { [_: CrossTileID]: VariableOffset }) { | ||
const tr = painter.transform; | ||
@@ -170,4 +174,3 @@ const rotateWithMap = rotationAlignment === 'map'; | ||
function updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, | ||
transform, labelPlaneMatrix, coord, tileScale, size, updateTextFitIcon) { | ||
function updateVariableAnchorsForBucket(bucket: SymbolBucket, rotateWithMap: boolean, pitchWithMap: boolean, variableOffsets: { [_: CrossTileID]: VariableOffset }, symbolSize: typeof symbolSize, transform: Transform, labelPlaneMatrix: Float32Array, coord: OverscaledTileID, tileScale: number, size: InterpolatedSize, updateTextFitIcon: boolean) { | ||
const placedSymbols = bucket.text.placedSymbolArray; | ||
@@ -275,4 +278,3 @@ const dynamicTextLayoutVertexArray = bucket.text.dynamicLayoutVertexArray; | ||
function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, | ||
rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode) { | ||
function drawLayerSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array<OverscaledTileID>, isText: boolean, translate: [number, number], translateAnchor: 'map' | 'viewport', rotationAlignment: Alignment, pitchAlignment: Alignment, keepUpright: boolean, stencilMode: StencilMode, colorMode: ColorMode) { | ||
const context = painter.context; | ||
@@ -305,3 +307,3 @@ const gl = context.gl; | ||
let globeCameraUp = mercatorCameraUp; | ||
let globeCameraUp: [number, number, number] = mercatorCameraUp; | ||
if ((isGlobeProjection || tr.mercatorFromTransition) && !rotateWithMap) { | ||
@@ -486,3 +488,3 @@ // Each symbol rotating with the viewport requires per-instance information about | ||
function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { | ||
function drawSymbolElements(buffers: SymbolBuffers, segments: SegmentVector, layer: SymbolStyleLayer, painter: Painter, program: any, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode, uniformValues: UniformValues<SymbolSDFUniformsType>) { | ||
const context = painter.context; | ||
@@ -489,0 +491,0 @@ const gl = context.gl; |
@@ -255,2 +255,3 @@ // @flow | ||
if (!this.atlasTexture) return; // Flow can't infer that atlasTexture is defined here | ||
this.atlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); | ||
@@ -257,0 +258,0 @@ } |
@@ -17,3 +17,2 @@ // @flow | ||
import ProgramConfiguration from '../data/program_configuration.js'; | ||
import CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index.js'; | ||
import shaders from '../shaders/shaders.js'; | ||
@@ -151,3 +150,2 @@ import Program from './program.js'; | ||
cache: {[_: string]: Program<*> }; | ||
crossTileSymbolIndex: CrossTileSymbolIndex; | ||
symbolFadeChange: number; | ||
@@ -168,4 +166,4 @@ gpuTimers: GPUTimers; | ||
constructor(gl: WebGLRenderingContext, transform: Transform) { | ||
this.context = new Context(gl); | ||
constructor(gl: WebGLRenderingContext, transform: Transform, isWebGL2: boolean = false) { | ||
this.context = new Context(gl, isWebGL2); | ||
this.transform = transform; | ||
@@ -183,4 +181,2 @@ this._tileTextures = {}; | ||
this.crossTileSymbolIndex = new CrossTileSymbolIndex(); | ||
this.deferredRenderGpuTimeQueries = []; | ||
@@ -561,4 +557,5 @@ this.gpuTimers = {}; | ||
// This texture is used for occlusion testing (labels) | ||
if (this.terrain && (this.style.hasSymbolLayers() || this.style.hasCircleLayers())) { | ||
this.terrain.drawDepth(); | ||
const terrain = this.terrain; | ||
if (terrain && (this.style.hasSymbolLayers() || this.style.hasCircleLayers())) { | ||
terrain.drawDepth(); | ||
} | ||
@@ -711,3 +708,4 @@ | ||
this.gpuTimingStart(layer); | ||
if (!painter.transform.projection.unsupportedLayers || !painter.transform.projection.unsupportedLayers.includes(layer.type)) { | ||
if (!painter.transform.projection.unsupportedLayers || !painter.transform.projection.unsupportedLayers.includes(layer.type) || | ||
(painter.terrain && layer.type === 'custom')) { | ||
draw[layer.type](painter, sourceCache, layer, coords, this.style.placement.variableOffsets, this.options.isInitialLoad); | ||
@@ -996,3 +994,5 @@ } | ||
saveCanvasCopy() { | ||
this.frameCopies.push(this.canvasCopy()); | ||
const canvas = this.canvasCopy(); | ||
if (!canvas) return; | ||
this.frameCopies.push(canvas); | ||
this.tileLoaded = false; | ||
@@ -999,0 +999,0 @@ } |
@@ -82,3 +82,3 @@ // @flow | ||
const gl = context.gl; | ||
this.program = gl.createProgram(); | ||
this.program = ((gl.createProgram(): any): WebGLProgram); | ||
@@ -91,5 +91,6 @@ const staticAttrInfo = getTokenizedAttributes(source.staticAttributes); | ||
defines = defines.concat(fixedDefines.map((define) => `#define ${define}`)); | ||
const version = context.isWebGL2 ? '#version 300 es\n' : ''; | ||
const fragmentSource = defines.concat( | ||
context.extStandardDerivatives ? standardDerivativesExt.concat(preludeFragPrecisionQualifiers) : preludeFragPrecisionQualifiers, | ||
const fragmentSource = version + defines.concat( | ||
context.extStandardDerivatives && version.length === 0 ? standardDerivativesExt.concat(preludeFragPrecisionQualifiers) : preludeFragPrecisionQualifiers, | ||
preludeFragPrecisionQualifiers, | ||
@@ -100,3 +101,3 @@ preludeCommonSource, | ||
source.fragmentSource).join('\n'); | ||
const vertexSource = defines.concat( | ||
const vertexSource = version + defines.concat( | ||
preludeVertPrecisionQualifiers, | ||
@@ -109,3 +110,3 @@ preludeCommonSource, | ||
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); | ||
const fragmentShader = ((gl.createShader(gl.FRAGMENT_SHADER): any): WebGLShader); | ||
if (gl.isContextLost()) { | ||
@@ -120,3 +121,3 @@ this.failedToCreate = true; | ||
const vertexShader = gl.createShader(gl.VERTEX_SHADER); | ||
const vertexShader = ((gl.createShader(gl.VERTEX_SHADER): any): WebGLShader); | ||
if (gl.isContextLost()) { | ||
@@ -123,0 +124,0 @@ this.failedToCreate = true; |
@@ -128,3 +128,3 @@ // @flow | ||
function calculateMatrix(painter, tile, layer, matrix) { | ||
function calculateMatrix(painter: Painter, tile: Tile, layer: LineStyleLayer, matrix: ?Float32Array) { | ||
return painter.translatePosMatrix( | ||
@@ -156,3 +156,3 @@ matrix ? matrix : tile.tileID.projMatrix, | ||
function hasDash(layer) { | ||
function hasDash(layer: LineStyleLayer) { | ||
const dashPropertyValue = layer.paint.get('line-dasharray').value; | ||
@@ -159,0 +159,0 @@ return dashPropertyValue.value || dashPropertyValue.kind !== "constant"; |
@@ -70,3 +70,3 @@ // @flow | ||
function spinWeights(angle) { | ||
function spinWeights(angle: number) { | ||
angle *= Math.PI / 180; | ||
@@ -82,3 +82,3 @@ const s = Math.sin(angle); | ||
function contrastFactor(contrast) { | ||
function contrastFactor(contrast: number) { | ||
return contrast > 0 ? | ||
@@ -89,3 +89,3 @@ 1 / (1 - contrast) : | ||
function saturationFactor(saturation) { | ||
function saturationFactor(saturation: number) { | ||
return saturation > 0 ? | ||
@@ -92,0 +92,0 @@ 1 - 1 / (1.001 - saturation) : |
@@ -10,3 +10,3 @@ // @flow | ||
function addVertex(vertexArray, x, y, z) { | ||
function addVertex(vertexArray: SkyboxVertexArray, x: number, y: number, z: number) { | ||
vertexArray.emplaceBack( | ||
@@ -13,0 +13,0 @@ // a_pos |
@@ -48,3 +48,3 @@ // @flow | ||
this.format = format; | ||
this.texture = context.gl.createTexture(); | ||
this.texture = ((context.gl.createTexture(): any): WebGLTexture); | ||
this.update(image, options); | ||
@@ -51,0 +51,0 @@ } |
@@ -37,2 +37,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: number): void { | ||
@@ -53,2 +54,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: number): void { | ||
@@ -69,2 +71,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: [number, number]): void { | ||
@@ -85,2 +88,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: [number, number, number]): void { | ||
@@ -101,2 +105,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: [number, number, number, number]): void { | ||
@@ -118,2 +123,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: Color): void { | ||
@@ -136,2 +142,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: Float32Array): void { | ||
@@ -164,2 +171,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: Float32Array): void { | ||
@@ -184,2 +192,3 @@ if (!this.fetchUniformLocation(program, name)) return; | ||
// $FlowFixMe[method-unbinding] | ||
set(program: WebGLProgram, name: string, v: Float32Array): void { | ||
@@ -186,0 +195,0 @@ if (!this.fetchUniformLocation(program, name)) return; |
@@ -127,2 +127,3 @@ // @flow | ||
// $FlowFixMe[missing-this-annot] | ||
this.play = function() { | ||
@@ -133,2 +134,3 @@ this._playing = true; | ||
// $FlowFixMe[missing-this-annot] | ||
this.pause = function() { | ||
@@ -167,2 +169,3 @@ if (this._playing) { | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -176,2 +179,3 @@ this.map = map; | ||
// $FlowFixMe[method-unbinding] | ||
onRemove() { | ||
@@ -196,2 +200,3 @@ this.pause(); | ||
// $FlowFixMe[method-unbinding] | ||
prepare() { | ||
@@ -198,0 +203,0 @@ let resize = false; |
@@ -158,5 +158,5 @@ // @flow | ||
tileSize: number; | ||
attribution: string; | ||
attribution: string | void; | ||
roundZoom: boolean; | ||
roundZoom: boolean | void; | ||
tileBounds: ?TileBounds; | ||
@@ -202,8 +202,11 @@ minTileCacheSize: ?number; | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[method-unbinding] | ||
implementation.update = this._update.bind(this); | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[method-unbinding] | ||
implementation.clearTiles = this._clearTiles.bind(this); | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[method-unbinding] | ||
implementation.coveringTiles = this._coveringTiles.bind(this); | ||
@@ -228,2 +231,3 @@ | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map): void { | ||
@@ -237,2 +241,3 @@ this._map = map; | ||
// $FlowFixMe[method-unbinding] | ||
onRemove(map: Map): void { | ||
@@ -244,2 +249,3 @@ if (this._implementation.onRemove) { | ||
// $FlowFixMe[method-unbinding] | ||
hasTile(tileID: OverscaledTileID): boolean { | ||
@@ -273,3 +279,4 @@ if (this._implementation.hasTile) { | ||
function tileLoaded(data) { | ||
// $FlowFixMe[missing-this-annot] | ||
function tileLoaded(data: ?T) { | ||
delete tile.request; | ||
@@ -321,2 +328,3 @@ | ||
// $FlowFixMe[method-unbinding] | ||
unloadTile(tile: Tile, callback: Callback<void>): void { | ||
@@ -332,2 +340,3 @@ this.unloadTileData(tile); | ||
// $FlowFixMe[method-unbinding] | ||
abortTile(tile: Tile, callback: Callback<void>): void { | ||
@@ -334,0 +343,0 @@ if (tile.request && tile.request.cancel) { |
@@ -73,7 +73,7 @@ // @flow | ||
tileSize: number; | ||
attribution: string; | ||
attribution: string | void; | ||
promoteId: ?PromoteIdSpecification; | ||
isTileClipped: boolean; | ||
reparseOverscaled: boolean; | ||
isTileClipped: boolean | void; | ||
reparseOverscaled: boolean | void; | ||
_data: GeoJSON | string; | ||
@@ -152,2 +152,3 @@ _options: GeoJSONSourceSpecification; | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -200,2 +201,3 @@ this.map = map; | ||
* // The following creates a camera animation on cluster feature click | ||
* // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']` | ||
* map.on('click', 'clusters', (e) => { | ||
@@ -235,2 +237,3 @@ * const features = map.queryRenderedFeatures(e.point, { | ||
* // Retrieve cluster children on click | ||
* // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']` | ||
* map.on('click', 'clusters', (e) => { | ||
@@ -266,2 +269,3 @@ * const features = map.queryRenderedFeatures(e.point, { | ||
* // Retrieve cluster leaves on click | ||
* // the clicked layer should be filtered to only include clusters, e.g. `filter: ['has', 'point_count']` | ||
* map.on('click', 'clusters', (e) => { | ||
@@ -383,2 +387,3 @@ * const features = map.queryRenderedFeatures(e.point, { | ||
// $FlowFixMe[method-unbinding] | ||
abortTile(tile: Tile) { | ||
@@ -392,2 +397,3 @@ if (tile.request) { | ||
// $FlowFixMe[method-unbinding] | ||
unloadTile(tile: Tile) { | ||
@@ -398,2 +404,3 @@ tile.unloadVectorData(); | ||
// $FlowFixMe[method-unbinding] | ||
onRemove() { | ||
@@ -400,0 +407,0 @@ if (this._pendingLoad) { |
@@ -54,2 +54,3 @@ // @flow | ||
// $FlowFixMe[missing-this-annot] | ||
function loadGeoJSONTile(params: RequestedTileParameters, callback: LoadVectorDataCallback) { | ||
@@ -207,2 +208,3 @@ const canonical = params.tileID.canonical; | ||
*/ | ||
// $FlowFixMe[duplicate-class-member] | ||
loadGeoJSON(params: LoadGeoJSONParameters, callback: ResponseCallback<Object>): void { | ||
@@ -251,3 +253,3 @@ // Because of same origin issues, urls must either include an explicit | ||
function getSuperclusterOptions({superclusterOptions, clusterProperties}) { | ||
function getSuperclusterOptions({superclusterOptions, clusterProperties}: LoadGeoJSONParameters) { | ||
if (!clusterProperties || !superclusterOptions) return superclusterOptions; | ||
@@ -254,0 +256,0 @@ |
@@ -6,5 +6,7 @@ // @flow | ||
import {VectorTileFeature} from '@mapbox/vector-tile'; | ||
// $FlowFixMe[method-unbinding] | ||
const toGeoJSON = VectorTileFeature.prototype.toGeoJSON; | ||
import EXTENT from '../data/extent.js'; | ||
import type {GeoJSONFeature} from '@mapbox/geojson-types'; | ||
import type {IVectorTile, IVectorTileLayer, IVectorTileFeature} from '@mapbox/vector-tile'; | ||
@@ -52,3 +54,3 @@ | ||
loadGeometry() { | ||
loadGeometry(): Array<Array<Point>> { | ||
if (this._feature.type === 1) { | ||
@@ -73,3 +75,3 @@ const geometry = []; | ||
toGeoJSON(x: number, y: number, z: number) { | ||
toGeoJSON(x: number, y: number, z: number): GeoJSONFeature { | ||
return toGeoJSON.call(this, x, y, z); | ||
@@ -76,0 +78,0 @@ } |
@@ -36,3 +36,3 @@ // @flow | ||
function basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4) { | ||
function basisToPoints(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number) { | ||
const m = [x1, x2, x3, y1, y2, y3, 1, 1, 1]; | ||
@@ -45,3 +45,3 @@ const s = [x4, y4, 1]; | ||
function getPerspectiveTransform(w, h, x1, y1, x2, y2, x3, y3, x4, y4) { | ||
function getPerspectiveTransform(w: number, h: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number) { | ||
const s = basisToPoints(0, 0, w, 0, 0, h, w, h); | ||
@@ -114,2 +114,3 @@ const m = basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4); | ||
image: HTMLImageElement | ImageBitmap | ImageData; | ||
// $FlowFixMe | ||
tileID: CanonicalTileID; | ||
@@ -233,2 +234,3 @@ _boundsArray: ?RasterBoundsArray; | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -239,2 +241,3 @@ this.map = map; | ||
// $FlowFixMe[method-unbinding] | ||
onRemove() { | ||
@@ -285,2 +288,3 @@ if (this._imageRequest) { | ||
// transform the geo coordinates into (zoom 0) tile space coordinates | ||
// $FlowFixMe[method-unbinding] | ||
const cornerCoords = coordinates.map(MercatorCoordinate.fromLngLat); | ||
@@ -301,2 +305,3 @@ | ||
// $FlowFixMe[method-unbinding] | ||
_clear() { | ||
@@ -341,2 +346,3 @@ this._boundsArray = undefined; | ||
// $FlowFixMe[method-unbinding] | ||
prepare() { | ||
@@ -343,0 +349,0 @@ if (Object.keys(this.tiles).length === 0 || !this.image) return; |
@@ -23,7 +23,7 @@ // @flow | ||
*/ | ||
export default function(tile: {tileID: OverscaledTileID, tileSize: number}, pixelValue: number, z: number): number { | ||
export default function(tile: interface {tileID: OverscaledTileID, tileSize: number}, pixelValue: number, z: number): number { | ||
return pixelValue * (EXTENT / (tile.tileSize * Math.pow(2, z - tile.tileID.overscaledZ))); | ||
} | ||
export function getPixelsToTileUnitsMatrix(tile: {tileID: OverscaledTileID, tileSize: number, +tileTransform: TileTransform}, transform: Transform): Float32Array { | ||
export function getPixelsToTileUnitsMatrix(tile: interface {tileID: OverscaledTileID, tileSize: number, +tileTransform: TileTransform}, transform: Transform): Float32Array { | ||
const {scale} = tile.tileTransform; | ||
@@ -30,0 +30,0 @@ const s = scale * EXTENT / (tile.tileSize * Math.pow(2, transform.zoom - tile.tileID.overscaledZ + tile.tileID.canonical.z)); |
// @flow | ||
import type {OverscaledTileID} from './tile_id.js'; | ||
import type SourceCache from './source_cache.js'; | ||
@@ -9,3 +10,3 @@ import type StyleLayer from '../style/style_layer.js'; | ||
import type {FilterSpecification} from '../style-spec/types.js'; | ||
import type {QueryGeometry} from '../style/query_geometry.js'; | ||
import type {QueryGeometry, TilespaceQueryGeometry} from '../style/query_geometry.js'; | ||
import assert from 'assert'; | ||
@@ -26,3 +27,3 @@ import {mat4} from 'gl-matrix'; | ||
*/ | ||
function getPixelPosMatrix(transform, tileID) { | ||
function getPixelPosMatrix(transform: Transform, tileID: OverscaledTileID) { | ||
const t = mat4.identity([]); | ||
@@ -83,3 +84,3 @@ mat4.scale(t, t, [transform.width * 0.5, -transform.height * 0.5, 1]); | ||
serializedLayers: {[_: string]: StyleLayer}, | ||
getLayerSourceCache: (layer: StyleLayer) => SourceCache, | ||
getLayerSourceCache: (layer: StyleLayer) => SourceCache | void, | ||
queryGeometry: Array<Point>, | ||
@@ -143,2 +144,4 @@ params: { filter: FilterSpecification, layers: Array<string>, availableImages: Array<string> }, | ||
const sourceCache = getLayerSourceCache(layer); | ||
if (!sourceCache) return; | ||
const state = sourceCache.getFeatureState(feature.layer['source-layer'], feature.id); | ||
@@ -175,3 +178,3 @@ feature.source = feature.layer.source; | ||
function sortTilesIn(a, b) { | ||
function sortTilesIn(a: TilespaceQueryGeometry | RetainedQueryData, b: TilespaceQueryGeometry | RetainedQueryData) { | ||
const idA = a.tileID; | ||
@@ -178,0 +181,0 @@ const idB = b.tileID; |
@@ -12,3 +12,3 @@ // @flow | ||
// ensure DEMData is registered for worker transfer on main thread: | ||
import '../data/dem_data.js'; | ||
import DEMData from '../data/dem_data.js'; | ||
@@ -19,4 +19,6 @@ import type {Source} from './source.js'; | ||
import type {Callback} from '../types/callback.js'; | ||
import type {TextureImage} from '../render/texture.js'; | ||
import type {RasterDEMSourceSpecification} from '../style-spec/types.js'; | ||
// $FlowFixMe[method-unbinding] | ||
class RasterDEMTileSource extends RasterTileSource implements Source { | ||
@@ -37,3 +39,4 @@ encoding: "mapbox" | "terrarium"; | ||
function imageLoaded(err, img, cacheControl, expires) { | ||
// $FlowFixMe[missing-this-annot] | ||
function imageLoaded(err: ?Error, img: ?TextureImage, cacheControl: ?string, expires: ?string) { | ||
delete tile.request; | ||
@@ -58,2 +61,4 @@ if (tile.aborted) { | ||
} | ||
// $FlowFixMe[incompatible-call] | ||
const rawImageData = transfer ? img : browser.getImageData(img, padding); | ||
@@ -76,3 +81,4 @@ const params = { | ||
function done(err, dem) { | ||
// $FlowFixMe[missing-this-annot] | ||
function done(err: ?Error, dem: ?DEMData) { | ||
if (err) { | ||
@@ -124,2 +130,3 @@ tile.state = 'errored'; | ||
// $FlowFixMe[method-unbinding] | ||
unloadTile(tile: Tile) { | ||
@@ -126,0 +133,0 @@ if (tile.demTexture) this.map.painter.saveTileTexture(tile.demTexture); |
@@ -28,2 +28,23 @@ // @flow | ||
/** | ||
* A source containing raster tiles. | ||
* See the [Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#raster) for detailed documentation of options. | ||
* | ||
* @example | ||
* map.addSource('some id', { | ||
* type: 'raster', | ||
* url: 'mapbox://mapbox.satellite', | ||
* tileSize: 256 | ||
* }); | ||
* | ||
* @example | ||
* map.addSource('some id', { | ||
* type: 'raster', | ||
* tiles: ['https://img.nj.gov/imagerywms/Natural2015?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&layers=Natural2015'], | ||
* tileSize: 256 | ||
* }); | ||
* | ||
* @see [Example: Add a raster tile source](https://docs.mapbox.com/mapbox-gl-js/example/map-tiles/) | ||
* @see [Example: Add a WMS source](https://docs.mapbox.com/mapbox-gl-js/example/wms/) | ||
*/ | ||
class RasterTileSource extends Evented implements Source { | ||
@@ -40,3 +61,3 @@ type: 'raster' | 'raster-dem'; | ||
tileBounds: TileBounds; | ||
roundZoom: boolean; | ||
roundZoom: boolean | void; | ||
dispatcher: Dispatcher; | ||
@@ -68,3 +89,3 @@ map: Map; | ||
load() { | ||
load(callback?: Callback<void>) { | ||
this._loaded = false; | ||
@@ -89,2 +110,4 @@ this.fire(new Event('dataloading', {dataType: 'source'})); | ||
} | ||
if (callback) callback(err); | ||
}); | ||
@@ -97,2 +120,3 @@ } | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -103,7 +127,61 @@ this.map = map; | ||
/** | ||
* Reloads the source data and re-renders the map. | ||
* | ||
* @example | ||
* map.getSource('source-id').reload(); | ||
*/ | ||
// $FlowFixMe[method-unbinding] | ||
reload() { | ||
this.cancelTileJSONRequest(); | ||
this.load(() => this.map.style._clearSource(this.id)); | ||
} | ||
/** | ||
* Sets the source `tiles` property and re-renders the map. | ||
* | ||
* @param {string[]} tiles An array of one or more tile source URLs, as in the TileJSON spec. | ||
* @returns {RasterTileSource} Returns itself to allow for method chaining. | ||
* @example | ||
* map.addSource('source-id', { | ||
* type: 'raster', | ||
* tiles: ['https://some_end_point.net/{z}/{x}/{y}.png'], | ||
* tileSize: 256 | ||
* }); | ||
* | ||
* // Set the endpoint associated with a raster tile source. | ||
* map.getSource('source-id').setTiles(['https://another_end_point.net/{z}/{x}/{y}.png']); | ||
*/ | ||
setTiles(tiles: Array<string>): this { | ||
this._options.tiles = tiles; | ||
this.reload(); | ||
return this; | ||
} | ||
/** | ||
* Sets the source `url` property and re-renders the map. | ||
* | ||
* @param {string} url A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://<Tileset ID>`. | ||
* @returns {RasterTileSource} Returns itself to allow for method chaining. | ||
* @example | ||
* map.addSource('source-id', { | ||
* type: 'raster', | ||
* url: 'mapbox://mapbox.satellite' | ||
* }); | ||
* | ||
* // Update raster tile source to a new URL endpoint | ||
* map.getSource('source-id').setUrl('mapbox://mapbox.satellite'); | ||
*/ | ||
setUrl(url: string): this { | ||
this.url = url; | ||
this._options.url = url; | ||
this.reload(); | ||
return this; | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
onRemove() { | ||
if (this._tileJSONRequest) { | ||
this._tileJSONRequest.cancel(); | ||
this._tileJSONRequest = null; | ||
} | ||
this.cancelTileJSONRequest(); | ||
} | ||
@@ -115,2 +193,3 @@ | ||
// $FlowFixMe[method-unbinding] | ||
hasTile(tileID: OverscaledTileID): boolean { | ||
@@ -157,2 +236,3 @@ return !this.tileBounds || this.tileBounds.contains(tileID.canonical); | ||
// $FlowFixMe[method-unbinding] | ||
abortTile(tile: Tile, callback: Callback<void>) { | ||
@@ -166,2 +246,3 @@ if (tile.request) { | ||
// $FlowFixMe[method-unbinding] | ||
unloadTile(tile: Tile, callback: Callback<void>) { | ||
@@ -175,4 +256,10 @@ if (tile.texture) this.map.painter.saveTileTexture(tile.texture); | ||
} | ||
cancelTileJSONRequest() { | ||
if (!this._tileJSONRequest) return; | ||
this._tileJSONRequest.cancel(); | ||
this._tileJSONRequest = null; | ||
} | ||
} | ||
export default RasterTileSource; |
@@ -28,3 +28,3 @@ // @flow | ||
let pluginStatus = status.unavailable; | ||
let pluginURL = null; | ||
let pluginURL: ?string = null; | ||
@@ -31,0 +31,0 @@ export const triggerPluginCompletionEvent = function(error: ?Error) { |
@@ -56,3 +56,2 @@ // @flow | ||
transform: Transform; | ||
_isIdRenderable: (id: number, symbolLayer?: boolean) => boolean; | ||
used: boolean; | ||
@@ -94,2 +93,3 @@ usedForTerrain: boolean; | ||
this._tiles = {}; | ||
// $FlowFixMe[method-unbinding] | ||
this._cache = new TileCache(0, this._unloadTile.bind(this)); | ||
@@ -251,2 +251,3 @@ this._timers = {}; | ||
// $FlowFixMe[method-unbinding] | ||
this._loadTile(tile, this._tileLoaded.bind(this, tile, id, state)); | ||
@@ -297,3 +298,3 @@ } | ||
function fillBorder(tile, borderTile) { | ||
function fillBorder(tile: Tile, borderTile: Tile) { | ||
if (!tile.dem || tile.dem.borderReady) return; | ||
@@ -750,3 +751,3 @@ tile.needsHillshadePrepare = true; | ||
_addTile(tileID: OverscaledTileID): Tile { | ||
let tile = this._tiles[tileID.key]; | ||
let tile: ?Tile = this._tiles[tileID.key]; | ||
if (tile) return tile; | ||
@@ -771,2 +772,3 @@ | ||
tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor(), this.transform.tileZoom, painter, this._isRaster); | ||
// $FlowFixMe[method-unbinding] | ||
this._loadTile(tile, this._tileLoaded.bind(this, tile, tileID.key, tile.state)); | ||
@@ -1001,2 +1003,13 @@ } | ||
_preloadTiles(transform: Transform | Array<Transform>, callback: Callback<any>) { | ||
if (!this._sourceLoaded) { | ||
const waitUntilSourceLoaded = () => { | ||
if (!this._sourceLoaded) return; | ||
this._source.off('data', waitUntilSourceLoaded); | ||
this._preloadTiles(transform, callback); | ||
}; | ||
this._source.on('data', waitUntilSourceLoaded); | ||
return; | ||
} | ||
const coveringTilesIDs: Map<number, OverscaledTileID> = new Map(); | ||
@@ -1051,3 +1064,3 @@ const transforms = Array.isArray(transform) ? transform : [transform]; | ||
function isRasterType(type): boolean { | ||
function isRasterType(type: string): boolean { | ||
return type === 'raster' || type === 'image' || type === 'video' || type === 'custom'; | ||
@@ -1054,0 +1067,0 @@ } |
@@ -134,3 +134,3 @@ // @flow | ||
if (deleteWholeFeatureState) this.state[sourceLayer][feature] = {}; | ||
else { | ||
else if (this.state[sourceLayer][feature]) { | ||
for (const key of Object.keys(this.deletedStates[sourceLayer][feature])) { | ||
@@ -137,0 +137,0 @@ delete this.state[sourceLayer][feature][key]; |
@@ -11,2 +11,3 @@ // @flow | ||
import type {Callback} from '../types/callback.js'; | ||
import type {MapEvent} from '../ui/events.js'; | ||
import {CanonicalTileID} from './tile_id.js'; | ||
@@ -62,3 +63,4 @@ | ||
fire(event: Event): mixed; | ||
on(type: *, listener: (Object) => any): Evented; | ||
on(type: MapEvent, listener: (Object) => any): Evented; | ||
off(type: MapEvent, listener: (Object) => any): Evented; | ||
setEventedParent(parent: ?Evented, data?: Object | () => Object): Evented; | ||
@@ -110,3 +112,3 @@ | ||
const sourceTypes = { | ||
const sourceTypes: {[string]: Class<Source>} = { | ||
vector, | ||
@@ -133,2 +135,3 @@ raster, | ||
export const create = function(id: string, specification: SourceSpecification, dispatcher: Dispatcher, eventedParent: Evented): Source { | ||
// $FlowFixMe[prop-missing] | ||
const source = new sourceTypes[specification.type](id, (specification: any), dispatcher, eventedParent); | ||
@@ -135,0 +138,0 @@ |
@@ -185,3 +185,3 @@ // @flow | ||
function getQuadkey(z, x, y) { | ||
function getQuadkey(z: number, x: number, y: number) { | ||
let quadkey = '', mask; | ||
@@ -188,0 +188,0 @@ for (let i = z; i > 0; i--) { |
@@ -70,3 +70,3 @@ // @flow | ||
const paddingSize = meshSize / commonRasterTileSize / 4; | ||
function seamPadding(n) { | ||
function seamPadding(n: number) { | ||
if (n === 0) return -paddingSize; | ||
@@ -136,3 +136,3 @@ else if (n === gridSize - 1) return paddingSize; | ||
function addVertex(x, y) { | ||
function addVertex(x: number, y: number) { | ||
const k = y * gridSize + x; | ||
@@ -154,3 +154,3 @@ | ||
function addTriangles(ax, ay, bx, by, cx, cy) { | ||
function addTriangles(ax: number, ay: number, bx: number, by: number, cx: number, cy: number) { | ||
const mx = (ax + bx) >> 1; | ||
@@ -157,0 +157,0 @@ const my = (ay + by) >> 1; |
@@ -389,3 +389,3 @@ // @flow | ||
this.imageAtlasTexture = new Texture(context, this.imageAtlas.image, gl.RGBA); | ||
this.imageAtlas.uploaded = true; | ||
((this.imageAtlas: any): ImageAtlas).uploaded = true; | ||
} | ||
@@ -400,3 +400,3 @@ | ||
this.lineAtlasTexture = new Texture(context, this.lineAtlas.image, gl.ALPHA); | ||
this.lineAtlas.uploaded = true; | ||
((this.lineAtlas: any): LineAtlas).uploaded = true; | ||
} | ||
@@ -468,3 +468,5 @@ } | ||
const evaluationFeature = toEvaluationFeature(feature, true); | ||
// $FlowFixMe[method-unbinding] | ||
if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) continue; | ||
// $FlowFixMe[method-unbinding] | ||
} else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) { | ||
@@ -611,6 +613,2 @@ continue; | ||
this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); | ||
if (context.extTextureFilterAnisotropic) { | ||
gl.texParameterf(gl.TEXTURE_2D, context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, context.extTextureFilterAnisotropicMax); | ||
} | ||
} | ||
@@ -617,0 +615,0 @@ } |
@@ -24,2 +24,3 @@ // @flow | ||
import type {LoadVectorTileResult} from './vector_tile_worker_source.js'; | ||
import type {WorkerTileResult} from './worker_source.js'; | ||
@@ -69,4 +70,4 @@ /** | ||
tileBounds: TileBounds; | ||
reparseOverscaled: boolean; | ||
isTileClipped: boolean; | ||
reparseOverscaled: boolean | void; | ||
isTileClipped: boolean | void; | ||
_tileJSONRequest: ?Cancelable; | ||
@@ -139,2 +140,3 @@ _loaded: boolean; | ||
// $FlowFixMe[method-unbinding] | ||
hasTile(tileID: OverscaledTileID): boolean { | ||
@@ -144,2 +146,3 @@ return !this.tileBounds || this.tileBounds.contains(tileID.canonical); | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -150,20 +153,14 @@ this.map = map; | ||
/** | ||
* Reloads the source data and re-renders the map. | ||
* | ||
* @example | ||
* map.getSource('source-id').reload(); | ||
*/ | ||
// $FlowFixMe[method-unbinding] | ||
reload() { | ||
this.cancelTileJSONRequest(); | ||
const clearTiles = () => { | ||
const sourceCaches = this.map.style._getSourceCaches(this.id); | ||
for (const sourceCache of sourceCaches) { | ||
sourceCache.clearTiles(); | ||
} | ||
}; | ||
this.load(clearTiles); | ||
this.load(() => this.map.style._clearSource(this.id)); | ||
} | ||
setSourceProperty(callback: Function) { | ||
callback(); | ||
this.reload(); | ||
} | ||
/** | ||
@@ -175,3 +172,3 @@ * Sets the source `tiles` property and re-renders the map. | ||
* @example | ||
* map.addSource('vector_source_id', { | ||
* map.addSource('source-id', { | ||
* type: 'vector', | ||
@@ -183,6 +180,4 @@ * tiles: ['https://some_end_point.net/{z}/{x}/{y}.mvt'], | ||
* | ||
* const vectorTileSource = map.getSource('vector_source_id'); | ||
* | ||
* // Set the endpoint associated with a vector tile source. | ||
* vectorTileSource.setTiles(['https://another_end_point.net/{z}/{x}/{y}.mvt']); | ||
* map.getSource('source-id').setTiles(['https://another_end_point.net/{z}/{x}/{y}.mvt']); | ||
*/ | ||
@@ -202,3 +197,3 @@ setTiles(tiles: Array<string>): this { | ||
* @example | ||
* map.addSource('vector_source_id', { | ||
* map.addSource('source-id', { | ||
* type: 'vector', | ||
@@ -208,6 +203,4 @@ * url: 'mapbox://mapbox.mapbox-streets-v7' | ||
* | ||
* const vectorTileSource = map.getSource('vector_source_id'); | ||
* | ||
* // Update vector tile source to a new URL endpoint | ||
* vectorTileSource.setUrl("mapbox://mapbox.mapbox-streets-v8"); | ||
* map.getSource('source-id').setUrl("mapbox://mapbox.mapbox-streets-v8"); | ||
*/ | ||
@@ -222,2 +215,3 @@ setUrl(url: string): this { | ||
// $FlowFixMe[method-unbinding] | ||
onRemove() { | ||
@@ -285,3 +279,4 @@ this.cancelTileJSONRequest(); | ||
function done(err, data) { | ||
// $FlowFixMe[missing-this-annot] | ||
function done(err: ?Error, data: ?WorkerTileResult) { | ||
delete tile.request; | ||
@@ -292,2 +287,3 @@ | ||
// $FlowFixMe[prop-missing] - generic Error type doesn't have status | ||
if (err && err.status !== 404) { | ||
@@ -314,2 +310,3 @@ return callback(err); | ||
// $FlowFixMe[method-unbinding] | ||
abortTile(tile: Tile) { | ||
@@ -325,2 +322,3 @@ if (tile.request) { | ||
// $FlowFixMe[method-unbinding] | ||
unloadTile(tile: Tile) { | ||
@@ -337,2 +335,3 @@ tile.unloadVectorData(); | ||
// $FlowFixMe[method-unbinding] | ||
afterUpdate() { | ||
@@ -339,0 +338,0 @@ this._tileWorkers = {}; |
@@ -15,2 +15,3 @@ // @flow | ||
WorkerSource, | ||
WorkerTileResult, | ||
WorkerTileParameters, | ||
@@ -102,6 +103,7 @@ RequestedTileParameters, | ||
*/ | ||
// $FlowFixMe[missing-this-annot] | ||
export function loadVectorTile(params: RequestedTileParameters, callback: LoadVectorDataCallback, skipParse?: boolean): (() => void) { | ||
const key = JSON.stringify(params.request); | ||
const makeRequest = (callback) => { | ||
const makeRequest = (callback: LoadVectorDataCallback) => { | ||
const request = getArrayBuffer(params.request, (err: ?Error, data: ?ArrayBuffer, cacheControl: ?string, expires: ?string) => { | ||
@@ -258,3 +260,3 @@ if (err) { | ||
const done = (err, data) => { | ||
const done = (err: ?Error, data: ?WorkerTileResult) => { | ||
const reloadCallback = workerTile.reloadCallback; | ||
@@ -261,0 +263,0 @@ if (reloadCallback) { |
@@ -158,2 +158,3 @@ // @flow | ||
index: featureIndex.bucketLayerIDs.length, | ||
// $FlowFixMe[incompatible-call] - Flow can't infer proper `family` type from `layer` above | ||
layers: family, | ||
@@ -181,51 +182,8 @@ zoom: this.zoom, | ||
let error: ?Error; | ||
let glyphMap: ?{[_: string]: {glyphs: {[_: number]: ?StyleGlyph}, ascender?: number, descender?: number}}; | ||
let iconMap: ?{[_: string]: StyleImage}; | ||
let patternMap: ?{[_: string]: StyleImage}; | ||
let glyphMap: {[_: string]: {glyphs: {[_: number]: ?StyleGlyph}, ascender?: number, descender?: number}}; | ||
let iconMap: {[_: string]: StyleImage}; | ||
let patternMap: {[_: string]: StyleImage}; | ||
const taskMetadata = {type: 'maybePrepare', isSymbolTile: this.isSymbolTile, zoom: this.zoom}; | ||
const stacks = mapObject(options.glyphDependencies, (glyphs) => Object.keys(glyphs).map(Number)); | ||
if (Object.keys(stacks).length) { | ||
actor.send('getGlyphs', {uid: this.uid, stacks}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
glyphMap = result; | ||
maybePrepare.call(this); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
glyphMap = {}; | ||
} | ||
const icons = Object.keys(options.iconDependencies); | ||
if (icons.length) { | ||
actor.send('getImages', {icons, source: this.source, tileID: this.tileID, type: 'icons'}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
iconMap = result; | ||
maybePrepare.call(this); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
iconMap = {}; | ||
} | ||
const patterns = Object.keys(options.patternDependencies); | ||
if (patterns.length) { | ||
actor.send('getImages', {icons: patterns, source: this.source, tileID: this.tileID, type: 'patterns'}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
patternMap = result; | ||
maybePrepare.call(this); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
patternMap = {}; | ||
} | ||
PerformanceUtils.endMeasure(m); | ||
maybePrepare.call(this); | ||
function maybePrepare() { | ||
const maybePrepare = () => { | ||
if (error) { | ||
@@ -278,3 +236,46 @@ return callback(error); | ||
} | ||
}; | ||
const stacks = mapObject(options.glyphDependencies, (glyphs) => Object.keys(glyphs).map(Number)); | ||
if (Object.keys(stacks).length) { | ||
actor.send('getGlyphs', {uid: this.uid, stacks}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
glyphMap = result; | ||
maybePrepare(); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
glyphMap = {}; | ||
} | ||
const icons = Object.keys(options.iconDependencies); | ||
if (icons.length) { | ||
actor.send('getImages', {icons, source: this.source, tileID: this.tileID, type: 'icons'}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
iconMap = result; | ||
maybePrepare(); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
iconMap = {}; | ||
} | ||
const patterns = Object.keys(options.patternDependencies); | ||
if (patterns.length) { | ||
actor.send('getImages', {icons: patterns, source: this.source, tileID: this.tileID, type: 'patterns'}, (err, result) => { | ||
if (!error) { | ||
error = err; | ||
patternMap = result; | ||
maybePrepare(); | ||
} | ||
}, undefined, false, taskMetadata); | ||
} else { | ||
patternMap = {}; | ||
} | ||
PerformanceUtils.endMeasure(m); | ||
maybePrepare(); | ||
} | ||
@@ -281,0 +282,0 @@ } |
@@ -150,2 +150,3 @@ // @flow | ||
assert(params.type); | ||
// $FlowFixMe[method-unbinding] | ||
const p = this.enableTerrain ? extend({enableTerrain: this.terrain}, params) : params; | ||
@@ -157,2 +158,3 @@ p.projection = this.projections[mapId] || this.defaultProjection; | ||
loadDEMTile(mapId: string, params: WorkerDEMTileParameters, callback: WorkerDEMTileCallback) { | ||
// $FlowFixMe[method-unbinding] | ||
const p = this.enableTerrain ? extend({buildQuadTree: this.terrain}, params) : params; | ||
@@ -164,2 +166,3 @@ this.getDEMWorkerSource(mapId, params.source).loadTile(p, callback); | ||
assert(params.type); | ||
// $FlowFixMe[method-unbinding] | ||
const p = this.enableTerrain ? extend({enableTerrain: this.terrain}, params) : params; | ||
@@ -262,3 +265,3 @@ p.projection = this.projections[mapId] || this.defaultProjection; | ||
const actor = { | ||
send: (type, data, callback, _, mustQueue, metadata) => { | ||
send: (type: string, data: mixed, callback: any, _: any, mustQueue: boolean, metadata: any) => { | ||
this.actor.send(type, data, callback, mapId, mustQueue, metadata); | ||
@@ -298,3 +301,4 @@ }, | ||
self instanceof WorkerGlobalScope) { | ||
// $FlowFixMe[prop-missing] | ||
self.worker = new Worker(self); | ||
} |
@@ -41,3 +41,3 @@ // @flow | ||
const map = Object.create(null); | ||
const map: Object = Object.create(null); | ||
for (let i = 0; i < layers.length; i++) { | ||
@@ -44,0 +44,0 @@ map[layers[i].id] = layers[i]; |
@@ -5,4 +5,6 @@ // @flow | ||
import type {StyleSpecification} from './types.js'; | ||
import type {StyleSpecification, SourceSpecification, LayerSpecification} from './types.js'; | ||
type Sources = { [string]: SourceSpecification }; | ||
type Command = { | ||
@@ -126,7 +128,7 @@ command: string; | ||
function addSource(sourceId, after, commands) { | ||
function addSource(sourceId: string, after: Sources, commands: Array<Command>) { | ||
commands.push({command: operations.addSource, args: [sourceId, after[sourceId]]}); | ||
} | ||
function removeSource(sourceId, commands, sourcesRemoved) { | ||
function removeSource(sourceId: string, commands: Array<Command>, sourcesRemoved: {[string]: true}) { | ||
commands.push({command: operations.removeSource, args: [sourceId]}); | ||
@@ -136,3 +138,3 @@ sourcesRemoved[sourceId] = true; | ||
function updateSource(sourceId, after, commands, sourcesRemoved) { | ||
function updateSource(sourceId: string, after: Sources, commands: Array<Command>, sourcesRemoved: {[string]: true}) { | ||
removeSource(sourceId, commands, sourcesRemoved); | ||
@@ -142,3 +144,3 @@ addSource(sourceId, after, commands); | ||
function canUpdateGeoJSON(before, after, sourceId) { | ||
function canUpdateGeoJSON(before: Sources, after: Sources, sourceId: string) { | ||
let prop; | ||
@@ -160,3 +162,3 @@ for (prop in before[sourceId]) { | ||
function diffSources(before, after, commands, sourcesRemoved) { | ||
function diffSources(before: Sources, after: Sources, commands: Array<Command>, sourcesRemoved: {[string]: true}) { | ||
before = before || {}; | ||
@@ -178,7 +180,8 @@ after = after || {}; | ||
if (!after.hasOwnProperty(sourceId)) continue; | ||
const source = after[sourceId]; | ||
if (!before.hasOwnProperty(sourceId)) { | ||
addSource(sourceId, after, commands); | ||
} else if (!isEqual(before[sourceId], after[sourceId])) { | ||
if (before[sourceId].type === 'geojson' && after[sourceId].type === 'geojson' && canUpdateGeoJSON(before, after, sourceId)) { | ||
commands.push({command: operations.setGeoJSONSourceData, args: [sourceId, after[sourceId].data]}); | ||
} else if (!isEqual(before[sourceId], source)) { | ||
if (before[sourceId].type === 'geojson' && source.type === 'geojson' && canUpdateGeoJSON(before, after, sourceId)) { | ||
commands.push({command: operations.setGeoJSONSourceData, args: [sourceId, source.data]}); | ||
} else { | ||
@@ -192,3 +195,3 @@ // no update command, must remove then add | ||
function diffLayerPropertyChanges(before, after, commands, layerId, klass, command) { | ||
function diffLayerPropertyChanges(before: any, after: any, commands: Array<Command>, layerId: string, klass: ?string, command: string) { | ||
before = before || {}; | ||
@@ -213,6 +216,7 @@ after = after || {}; | ||
function pluckId(layer) { | ||
function pluckId(layer: LayerSpecification) { | ||
return layer.id; | ||
} | ||
function indexById(group, layer) { | ||
function indexById(group: {[string]: LayerSpecification}, layer: LayerSpecification) { | ||
group[layer.id] = layer; | ||
@@ -222,3 +226,3 @@ return group; | ||
function diffLayers(before, after, commands) { | ||
function diffLayers(before: Array<LayerSpecification>, after: Array<LayerSpecification>, commands: Array<Command>) { | ||
before = before || []; | ||
@@ -239,5 +243,5 @@ after = after || []; | ||
// layers that have been added do not need to be diffed | ||
const clean = Object.create(null); | ||
const clean: Object = Object.create(null); | ||
let i, d, layerId, beforeLayer, afterLayer, insertBeforeLayerId, prop; | ||
let i, d, layerId, beforeLayer: LayerSpecification, afterLayer: LayerSpecification, insertBeforeLayerId, prop; | ||
@@ -290,2 +294,3 @@ // remove layers | ||
// and add it back 'from scratch'. | ||
// $FlowFixMe[prop-missing] - there is no `source-layer` in background and sky layers | ||
if (!isEqual(beforeLayer.source, afterLayer.source) || !isEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !isEqual(beforeLayer.type, afterLayer.type)) { | ||
@@ -292,0 +297,0 @@ commands.push({command: operations.removeLayer, args: [layerId]}); |
@@ -149,2 +149,3 @@ // @flow | ||
for (const name in definitions) { | ||
// $FlowFixMe[method-unbinding] | ||
registry[name] = CompoundExpression; | ||
@@ -151,0 +152,0 @@ } |
@@ -59,3 +59,3 @@ // @flow | ||
let N; | ||
let N: ?number; | ||
if (args.length > 3) { | ||
@@ -69,3 +69,3 @@ if (args[2] !== null && | ||
} | ||
N = args[2]; | ||
N = ((args[2]: any): number); | ||
i++; | ||
@@ -72,0 +72,0 @@ } |
@@ -65,2 +65,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
return class Comparison implements Expression { | ||
@@ -81,2 +82,3 @@ type: Type; | ||
// $FlowFixMe[method-unbinding] | ||
static parse(args: $ReadOnlyArray<mixed>, context: ParsingContext): ?Expression { | ||
@@ -83,0 +85,0 @@ if (args.length !== 3 && args.length !== 4) |
@@ -12,3 +12,3 @@ // @flow | ||
type FormattedSectionExpression = { | ||
export type FormattedSectionExpression = { | ||
// Content of a section may be Image expression or other | ||
@@ -88,3 +88,3 @@ // type of expression that is coercable to 'string'. | ||
evaluate(ctx: EvaluationContext): Formatted { | ||
const evaluateSection = section => { | ||
const evaluateSection = (section: FormattedSectionExpression) => { | ||
const evaluatedContent = section.content.evaluate(ctx); | ||
@@ -91,0 +91,0 @@ if (typeOf(evaluatedContent) === ResolvedImageType) { |
@@ -49,4 +49,5 @@ // @flow | ||
import type EvaluationContext from '../evaluation_context.js'; | ||
import type {Varargs} from '../compound_expression.js'; | ||
import type {ExpressionRegistry} from '../expression.js'; | ||
import type {Expression, ExpressionRegistry} from '../expression.js'; | ||
@@ -61,25 +62,43 @@ const expressions: ExpressionRegistry = { | ||
'<=': LessThanOrEqual, | ||
// $FlowFixMe[method-unbinding] | ||
'array': Assertion, | ||
// $FlowFixMe[method-unbinding] | ||
'at': At, | ||
'boolean': Assertion, | ||
// $FlowFixMe[method-unbinding] | ||
'case': Case, | ||
// $FlowFixMe[method-unbinding] | ||
'coalesce': Coalesce, | ||
// $FlowFixMe[method-unbinding] | ||
'collator': CollatorExpression, | ||
// $FlowFixMe[method-unbinding] | ||
'format': FormatExpression, | ||
// $FlowFixMe[method-unbinding] | ||
'image': ImageExpression, | ||
// $FlowFixMe[method-unbinding] | ||
'in': In, | ||
// $FlowFixMe[method-unbinding] | ||
'index-of': IndexOf, | ||
// $FlowFixMe[method-unbinding] | ||
'interpolate': Interpolate, | ||
'interpolate-hcl': Interpolate, | ||
'interpolate-lab': Interpolate, | ||
// $FlowFixMe[method-unbinding] | ||
'length': Length, | ||
// $FlowFixMe[method-unbinding] | ||
'let': Let, | ||
// $FlowFixMe[method-unbinding] | ||
'literal': Literal, | ||
// $FlowFixMe[method-unbinding] | ||
'match': Match, | ||
'number': Assertion, | ||
// $FlowFixMe[method-unbinding] | ||
'number-format': NumberFormat, | ||
'object': Assertion, | ||
// $FlowFixMe[method-unbinding] | ||
'slice': Slice, | ||
// $FlowFixMe[method-unbinding] | ||
'step': Step, | ||
'string': Assertion, | ||
// $FlowFixMe[method-unbinding] | ||
'to-boolean': Coercion, | ||
@@ -89,7 +108,9 @@ 'to-color': Coercion, | ||
'to-string': Coercion, | ||
// $FlowFixMe[method-unbinding] | ||
'var': Var, | ||
// $FlowFixMe[method-unbinding] | ||
'within': Within | ||
}; | ||
function rgba(ctx, [r, g, b, a]) { | ||
function rgba(ctx: EvaluationContext, [r, g, b, a]: Array<Expression>) { | ||
r = r.evaluate(ctx); | ||
@@ -104,7 +125,7 @@ g = g.evaluate(ctx); | ||
function has(key, obj) { | ||
function has(key: string, obj: {[string]: any}): boolean { | ||
return key in obj; | ||
} | ||
function get(key, obj) { | ||
function get(key: string, obj: {[string]: any}) { | ||
const v = obj[key]; | ||
@@ -114,3 +135,3 @@ return typeof v === 'undefined' ? null : v; | ||
function binarySearch(v, a, i, j) { | ||
function binarySearch(v: any, a: {[number]: any}, i: number, j: number) { | ||
while (i <= j) { | ||
@@ -117,0 +138,0 @@ const m = (i + j) >> 1; |
@@ -255,3 +255,3 @@ // @flow | ||
*/ | ||
function exponentialInterpolation(input, base, lowerValue, upperValue) { | ||
function exponentialInterpolation(input: number, base: number, lowerValue: number, upperValue: number) { | ||
const difference = upperValue - lowerValue; | ||
@@ -258,0 +258,0 @@ const progress = input - lowerValue; |
@@ -40,3 +40,3 @@ // @flow | ||
let inputType; | ||
let outputType; | ||
let outputType: ?Type; | ||
if (context.expectedType && context.expectedType.kind !== 'value') { | ||
@@ -142,3 +142,3 @@ outputType = context.expectedType; | ||
const coerceLabel = (label) => this.inputType.kind === 'number' ? Number(label) : label; | ||
const coerceLabel = (label: number | string) => this.inputType.kind === 'number' ? Number(label) : label; | ||
@@ -145,0 +145,0 @@ for (const [outputIndex, labels] of groupedByOutput) { |
@@ -9,3 +9,4 @@ // @flow | ||
import type EvaluationContext from '../evaluation_context.js'; | ||
import type {GeoJSON, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types'; | ||
import type Point from '@mapbox/point-geometry'; | ||
import type {GeoJSON, GeoJSONPosition, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types'; | ||
import type {CanonicalTileID} from '../../../source/tile_id.js'; | ||
@@ -19,3 +20,3 @@ | ||
function updateBBox(bbox: BBox, coord: [number, number]) { | ||
function updateBBox(bbox: BBox, coord: GeoJSONPosition) { | ||
bbox[0] = Math.min(bbox[0], coord[0]); | ||
@@ -43,3 +44,3 @@ bbox[1] = Math.min(bbox[1], coord[1]); | ||
function getTileCoordinates(p, canonical: CanonicalTileID) { | ||
function getTileCoordinates(p: GeoJSONPosition, canonical: CanonicalTileID) { | ||
const x = mercatorXfromLng(p[0]); | ||
@@ -51,3 +52,3 @@ const y = mercatorYfromLat(p[1]); | ||
function onBoundary(p, p1, p2) { | ||
function onBoundary(p: GeoJSONPosition, p1: GeoJSONPosition, p2: GeoJSONPosition) { | ||
const x1 = p[0] - p1[0]; | ||
@@ -60,3 +61,3 @@ const y1 = p[1] - p1[1]; | ||
function rayIntersect(p, p1, p2) { | ||
function rayIntersect(p: GeoJSONPosition, p1: GeoJSONPosition, p2: GeoJSONPosition) { | ||
return ((p1[1] > p[1]) !== (p2[1] > p[1])) && (p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0]); | ||
@@ -66,3 +67,3 @@ } | ||
// ray casting algorithm for detecting if point is in polygon | ||
function pointWithinPolygon(point, rings) { | ||
function pointWithinPolygon(point: GeoJSONPosition, rings: Array<Array<GeoJSONPosition>>) { | ||
let inside = false; | ||
@@ -79,3 +80,3 @@ for (let i = 0, len = rings.length; i < len; i++) { | ||
function pointWithinPolygons(point, polygons) { | ||
function pointWithinPolygons(point: GeoJSONPosition, polygons: Array<Array<Array<GeoJSONPosition>>>) { | ||
for (let i = 0; i < polygons.length; i++) { | ||
@@ -87,3 +88,3 @@ if (pointWithinPolygon(point, polygons[i])) return true; | ||
function perp(v1, v2) { | ||
function perp(v1: GeoJSONPosition, v2: GeoJSONPosition) { | ||
return (v1[0] * v2[1] - v1[1] * v2[0]); | ||
@@ -93,3 +94,3 @@ } | ||
// check if p1 and p2 are in different sides of line segment q1->q2 | ||
function twoSided(p1, p2, q1, q2) { | ||
function twoSided(p1: GeoJSONPosition, p2: GeoJSONPosition, q1: GeoJSONPosition, q2: GeoJSONPosition) { | ||
// q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3) | ||
@@ -108,3 +109,3 @@ const x1 = p1[0] - q1[0]; | ||
// a, b are end points for line segment1, c and d are end points for line segment2 | ||
function lineIntersectLine(a, b, c, d) { | ||
function lineIntersectLine(a: GeoJSONPosition, b: GeoJSONPosition, c: GeoJSONPosition, d: GeoJSONPosition) { | ||
// check if two segments are parallel or not | ||
@@ -124,3 +125,3 @@ // precondition is end point a, b is inside polygon, if line a->b is | ||
function lineIntersectPolygon(p1, p2, polygon) { | ||
function lineIntersectPolygon(p1: GeoJSONPosition, p2: GeoJSONPosition, polygon: Array<Array<GeoJSONPosition>>) { | ||
for (const ring of polygon) { | ||
@@ -137,3 +138,3 @@ // loop through every edge of the ring | ||
function lineStringWithinPolygon(line, polygon) { | ||
function lineStringWithinPolygon(line: Array<GeoJSONPosition>, polygon: Array<Array<GeoJSONPosition>>) { | ||
// First, check if geometry points of line segments are all inside polygon | ||
@@ -155,3 +156,3 @@ for (let i = 0; i < line.length; ++i) { | ||
function lineStringWithinPolygons(line, polygons) { | ||
function lineStringWithinPolygons(line: Array<GeoJSONPosition>, polygons: Array<Array<Array<GeoJSONPosition>>>) { | ||
for (let i = 0; i < polygons.length; i++) { | ||
@@ -163,3 +164,3 @@ if (lineStringWithinPolygon(line, polygons[i])) return true; | ||
function getTilePolygon(coordinates, bbox: BBox, canonical: CanonicalTileID) { | ||
function getTilePolygon(coordinates: Array<Array<GeoJSONPosition>>, bbox: BBox, canonical: CanonicalTileID) { | ||
const polygon = []; | ||
@@ -178,3 +179,3 @@ for (let i = 0; i < coordinates.length; i++) { | ||
function getTilePolygons(coordinates, bbox, canonical: CanonicalTileID) { | ||
function getTilePolygons(coordinates: Array<Array<Array<GeoJSONPosition>>>, bbox: BBox, canonical: CanonicalTileID) { | ||
const polygons = []; | ||
@@ -188,3 +189,3 @@ for (let i = 0; i < coordinates.length; i++) { | ||
function updatePoint(p, bbox, polyBBox, worldSize) { | ||
function updatePoint(p: GeoJSONPosition, bbox: BBox, polyBBox: Array<number>, worldSize: number) { | ||
if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) { | ||
@@ -201,3 +202,3 @@ const halfWorldSize = worldSize * 0.5; | ||
function resetBBox(bbox) { | ||
function resetBBox(bbox: BBox) { | ||
bbox[0] = bbox[1] = Infinity; | ||
@@ -207,3 +208,3 @@ bbox[2] = bbox[3] = -Infinity; | ||
function getTilePoints(geometry, pointBBox, polyBBox, canonical: CanonicalTileID) { | ||
function getTilePoints(geometry: ?Array<Array<Point>>, pointBBox: BBox, polyBBox: Array<number>, canonical: CanonicalTileID) { | ||
const worldSize = Math.pow(2, canonical.z) * EXTENT; | ||
@@ -223,6 +224,6 @@ const shifts = [canonical.x * EXTENT, canonical.y * EXTENT]; | ||
function getTileLines(geometry, lineBBox, polyBBox, canonical: CanonicalTileID) { | ||
function getTileLines(geometry: ?Array<Array<Point>>, lineBBox: BBox, polyBBox: Array<number>, canonical: CanonicalTileID) { | ||
const worldSize = Math.pow(2, canonical.z) * EXTENT; | ||
const shifts = [canonical.x * EXTENT, canonical.y * EXTENT]; | ||
const tileLines = []; | ||
const tileLines: Array<Array<GeoJSONPosition>> = []; | ||
if (!geometry) return tileLines; | ||
@@ -232,3 +233,3 @@ for (const line of geometry) { | ||
for (const point of line) { | ||
const p = [point.x + shifts[0], point.y + shifts[1]]; | ||
const p: GeoJSONPosition = [point.x + shifts[0], point.y + shifts[1]]; | ||
updateBBox(lineBBox, p); | ||
@@ -235,0 +236,0 @@ tileLine.push(p); |
@@ -32,21 +32,21 @@ // @flow | ||
export type Feature = { | ||
+type: 1 | 2 | 3 | 'Unknown' | 'Point' | 'LineString' | 'Polygon', | ||
+id?: number | null, | ||
+properties: {[_: string]: any}, | ||
+patterns?: {[_: string]: string}, | ||
+geometry?: Array<Array<Point>> | ||
}; | ||
export interface Feature { | ||
+type: 1 | 2 | 3 | 'Unknown' | 'Point' | 'LineString' | 'Polygon'; | ||
+id?: number | null; | ||
+properties: {[_: string]: any}; | ||
+patterns?: {[_: string]: string}; | ||
+geometry?: Array<Array<Point>>; | ||
} | ||
export type FeatureState = {[_: string]: any}; | ||
export type GlobalProperties = $ReadOnly<{ | ||
zoom: number, | ||
pitch?: number, | ||
heatmapDensity?: number, | ||
lineProgress?: number, | ||
skyRadialProgress?: number, | ||
isSupportedScript?: (_: string) => boolean, | ||
accumulated?: Value | ||
}>; | ||
export interface GlobalProperties { | ||
+zoom: number; | ||
+pitch?: number; | ||
+heatmapDensity?: number; | ||
+lineProgress?: number; | ||
+skyRadialProgress?: number; | ||
+isSupportedScript?: (_: string) => boolean; | ||
+accumulated?: Value; | ||
} | ||
@@ -196,3 +196,3 @@ export class StyleExpression { | ||
export type ConstantExpression = { | ||
export type ConstantExpression = interface { | ||
kind: 'constant', | ||
@@ -202,3 +202,3 @@ +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array<string>) => any, | ||
export type SourceExpression = { | ||
export type SourceExpression = interface { | ||
kind: 'source', | ||
@@ -209,3 +209,3 @@ isStateDependent: boolean, | ||
export type CameraExpression = { | ||
export type CameraExpression = interface { | ||
kind: 'camera', | ||
@@ -218,10 +218,10 @@ +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array<string>) => any, | ||
export type CompositeExpression = { | ||
kind: 'composite', | ||
isStateDependent: boolean, | ||
+evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array<string>, formattedSection?: FormattedSection) => any, | ||
+interpolationFactor: (input: number, lower: number, upper: number) => number, | ||
zoomStops: Array<number>, | ||
interpolationType: ?InterpolationType | ||
}; | ||
export interface CompositeExpression { | ||
kind: 'composite'; | ||
isStateDependent: boolean; | ||
+evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array<string>, formattedSection?: FormattedSection) => any; | ||
+interpolationFactor: (input: number, lower: number, upper: number) => number; | ||
zoomStops: Array<number>; | ||
interpolationType: ?InterpolationType; | ||
} | ||
@@ -263,3 +263,5 @@ export type StylePropertyExpression = | ||
return success(isFeatureConstant ? | ||
// $FlowFixMe[method-unbinding] | ||
(new ZoomConstantExpression('constant', expression.value): ConstantExpression) : | ||
// $FlowFixMe[method-unbinding] | ||
(new ZoomConstantExpression('source', expression.value): SourceExpression)); | ||
@@ -271,3 +273,5 @@ } | ||
return success(isFeatureConstant ? | ||
// $FlowFixMe[method-unbinding] | ||
(new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType): CameraExpression) : | ||
// $FlowFixMe[method-unbinding] | ||
(new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType): CompositeExpression)); | ||
@@ -274,0 +278,0 @@ } |
@@ -76,3 +76,3 @@ // @flow | ||
function annotate(parsed, type, typeAnnotation: 'assert' | 'coerce' | 'omit') { | ||
function annotate(parsed: Expression, type: Type, typeAnnotation: 'assert' | 'coerce' | 'omit') { | ||
if (typeAnnotation === 'assert') { | ||
@@ -79,0 +79,0 @@ return new Assertion(type, [parsed]); |
@@ -164,3 +164,3 @@ // @flow | ||
function convertInOp(property: string, values: Array<any>, negate = false) { | ||
function convertInOp(property: string, values: Array<any>, negate: boolean = false) { | ||
if (values.length === 0) return negate; | ||
@@ -167,0 +167,0 @@ |
@@ -76,2 +76,3 @@ // @flow | ||
if (!isExpressionFilter(filter)) { | ||
// $FlowFixMe[incompatible-call] | ||
filter = convertFilter(filter); | ||
@@ -257,7 +258,7 @@ } | ||
// Comparison function to sort numbers and strings | ||
function compare(a, b) { | ||
function compare(a: number, b: number) { | ||
return a < b ? -1 : a > b ? 1 : 0; | ||
} | ||
function geometryNeeded(filter) { | ||
function geometryNeeded(filter: Array<any> | boolean) { | ||
if (!Array.isArray(filter)) return false; | ||
@@ -264,0 +265,0 @@ if (filter[0] === 'within') return true; |
@@ -8,7 +8,18 @@ // @flow | ||
function convertLiteral(value) { | ||
type Stop = [{zoom: number, value: string | number | boolean}, mixed]; | ||
type FunctionParameters = { | ||
stops: Array<Stop>; | ||
base: number; | ||
property: string; | ||
type: 'identity' | 'exponential' | 'interval' | 'categorical'; | ||
colorSpace: 'rgb' | 'lab' | 'hcl'; | ||
default: mixed; | ||
}; | ||
function convertLiteral(value: mixed) { | ||
return typeof value === 'object' ? ['literal', value] : value; | ||
} | ||
export default function convertFunction(parameters: any, propertySpec: StylePropertySpecification): ExpressionSpecification { | ||
export default function convertFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification): ExpressionSpecification { | ||
let stops = parameters.stops; | ||
@@ -40,3 +51,3 @@ if (!stops) { | ||
function convertIdentityFunction(parameters, propertySpec): Array<mixed> { | ||
function convertIdentityFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification): Array<mixed> { | ||
const get = ['get', parameters.property]; | ||
@@ -65,3 +76,3 @@ | ||
function getInterpolateOperator(parameters) { | ||
function getInterpolateOperator(parameters: FunctionParameters) { | ||
switch (parameters.colorSpace) { | ||
@@ -74,3 +85,3 @@ case 'hcl': return 'interpolate-hcl'; | ||
function convertZoomAndPropertyFunction(parameters, propertySpec, stops) { | ||
function convertZoomAndPropertyFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array<Stop>) { | ||
const featureFunctionParameters = {}; | ||
@@ -123,3 +134,3 @@ const featureFunctionStops = {}; | ||
function coalesce(a, b) { | ||
function coalesce(a: mixed, b: mixed) { | ||
if (a !== undefined) return a; | ||
@@ -129,3 +140,3 @@ if (b !== undefined) return b; | ||
function getFallback(parameters, propertySpec) { | ||
function getFallback(parameters: FunctionParameters, propertySpec: StylePropertySpecification) { | ||
const defaultValue = convertLiteral(coalesce(parameters.default, propertySpec.default)); | ||
@@ -145,3 +156,3 @@ | ||
function convertPropertyFunction(parameters, propertySpec, stops) { | ||
function convertPropertyFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array<Stop>) { | ||
const type = getFunctionType(parameters, propertySpec); | ||
@@ -199,3 +210,3 @@ const get = ['get', parameters.property]; | ||
function convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) { | ||
function convertZoomFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array<Stop>, input: Array<string> = ['zoom']) { | ||
const type = getFunctionType(parameters, propertySpec); | ||
@@ -224,3 +235,3 @@ let expression; | ||
function fixupDegenerateStepCurve(expression) { | ||
function fixupDegenerateStepCurve(expression: ExpressionSpecification) { | ||
// degenerate step curve (i.e. a constant function): add a noop stop | ||
@@ -233,3 +244,3 @@ if (expression[0] === 'step' && expression.length === 3) { | ||
function appendStopPair(curve, input, output, isStep) { | ||
function appendStopPair(curve: ExpressionSpecification, input: mixed, output: mixed, isStep: boolean) { | ||
// Skip duplicate stop values. They were not validated for functions, but they are for expressions. | ||
@@ -247,3 +258,3 @@ // https://github.com/mapbox/mapbox-gl-js/issues/4107 | ||
function getFunctionType(parameters, propertySpec) { | ||
function getFunctionType(parameters: FunctionParameters, propertySpec: StylePropertySpecification): string { | ||
if (parameters.type) { | ||
@@ -250,0 +261,0 @@ return parameters.type; |
@@ -7,3 +7,3 @@ // @flow | ||
function stringify(obj) { | ||
function stringify(obj: any) { | ||
if (typeof obj === 'number' || typeof obj === 'boolean' || typeof obj === 'string' || obj === undefined || obj === null) | ||
@@ -27,3 +27,3 @@ return JSON.stringify(obj); | ||
function getKey(layer) { | ||
function getKey(layer: LayerSpecification) { | ||
let key = ''; | ||
@@ -30,0 +30,0 @@ for (const k of refProperties) { |
@@ -30,2 +30,5 @@ // @flow | ||
if (typeof value === 'object' && !Array.isArray(value)) { | ||
// $FlowFixMe[prop-missing] | ||
// $FlowFixMe[incompatible-call] | ||
// $FlowFixMe[incompatible-variance] | ||
set(convertFunction(value, reference)); | ||
@@ -32,0 +35,0 @@ converted.push(path.join('.')); |
{ | ||
"name": "@mapbox/mapbox-gl-style-spec", | ||
"description": "a specification for mapbox gl styles", | ||
"version": "13.28.0", | ||
"version": "13.29.0-dev", | ||
"author": "Mapbox", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
@@ -383,3 +383,4 @@ // @flow | ||
"fill-extrusion-ambient-occlusion-intensity"?: PropertyValueSpecification<number>, | ||
"fill-extrusion-ambient-occlusion-radius"?: PropertyValueSpecification<number> | ||
"fill-extrusion-ambient-occlusion-radius"?: PropertyValueSpecification<number>, | ||
"fill-extrusion-rounded-roof"?: PropertyValueSpecification<boolean> | ||
|} | ||
@@ -386,0 +387,0 @@ |} |
@@ -17,6 +17,6 @@ // @flow | ||
export type ValidationError = { | ||
message: string; | ||
identifier?: ?string; | ||
line?: ?number; | ||
export type ValidationError = interface { | ||
message: string, | ||
identifier?: ?string, | ||
line?: ?number, | ||
}; | ||
@@ -66,4 +66,4 @@ export type ValidationErrors = $ReadOnlyArray<ValidationError>; | ||
function sortErrors(errors) { | ||
function sortErrors(errors: ValidationErrors) { | ||
return errors.slice().sort((a, b) => a.line && b.line ? a.line - b.line : 0); | ||
} |
@@ -14,3 +14,3 @@ // @flow | ||
type Options = ValidationOptions & { | ||
layerType: string; | ||
layerType?: string; | ||
} | ||
@@ -32,3 +32,3 @@ | ||
function validateNonExpressionFilter(options) { | ||
function validateNonExpressionFilter(options: Options) { | ||
const value = options.value; | ||
@@ -101,3 +101,3 @@ const key = options.key; | ||
for (let i = 1; i < value.length; i++) { | ||
errors = errors.concat(validateNonExpressionFilter({ | ||
errors = errors.concat(validateNonExpressionFilter(({ | ||
key: `${key}[${i}]`, | ||
@@ -107,3 +107,3 @@ value: value[i], | ||
styleSpec: options.styleSpec | ||
})); | ||
}: any))); | ||
} | ||
@@ -110,0 +110,0 @@ break; |
@@ -24,3 +24,3 @@ // @flow | ||
let stopDomainValues: {[string | number]: boolean} = {}; | ||
let previousStopDomainValue; | ||
let previousStopDomainValue: ?mixed; | ||
let previousStopDomainZoom; | ||
@@ -165,3 +165,3 @@ | ||
function validateStopDomainValue(options: ValidationOptions, stop) { | ||
function validateStopDomainValue(options: ValidationOptions, stop: any) { | ||
const type = getType(options.value); | ||
@@ -168,0 +168,0 @@ const value = unbundle(options.value); |
@@ -61,2 +61,3 @@ // @flow | ||
errors.push(new ValidationError(key, layer.ref, `ref layer "${ref}" not found`)); | ||
// $FlowFixMe[prop-missing] - ref is not defined on the LayerSpecification subtypes | ||
} else if (parent.ref) { | ||
@@ -63,0 +64,0 @@ errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer')); |
@@ -43,8 +43,9 @@ // @flow | ||
let tokenMatch; | ||
let tokenMatch: ?RegExp$matchResult; | ||
if (getType(value) === 'string' && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) { | ||
const example = `\`{ "type": "identity", "property": ${tokenMatch ? JSON.stringify(tokenMatch[1]) : '"_"'} }\``; | ||
return [new ValidationError( | ||
key, value, | ||
`"${propertyKey}" does not support interpolation syntax\n` + | ||
`Use an identity property function instead: \`{ "type": "identity", "property": ${JSON.stringify(tokenMatch[1])} }\`.`)]; | ||
`Use an identity property function instead: ${example}.`)]; | ||
} | ||
@@ -51,0 +52,0 @@ |
@@ -11,2 +11,3 @@ // @flow | ||
import type {StyleReference} from '../reference/latest.js'; | ||
import type {ValidationOptions} from './validate.js'; | ||
@@ -105,3 +106,3 @@ | ||
function getSourceTypeValues(styleSpec) { | ||
function getSourceTypeValues(styleSpec: StyleReference) { | ||
return styleSpec.source.reduce((memo, source) => { | ||
@@ -116,3 +117,3 @@ const sourceType = styleSpec[source]; | ||
function validatePromoteId({key, value}) { | ||
function validatePromoteId({key, value}: $Shape<ValidationOptions>) { | ||
if (getType(value) === 'string') { | ||
@@ -119,0 +120,0 @@ return validateString({key, value}); |
@@ -13,3 +13,3 @@ // @flow | ||
function getPropertyReference(propertyName): StylePropertySpecification { | ||
function getPropertyReference(propertyName: string): StylePropertySpecification { | ||
for (let i = 0; i < Reference.layout.length; i++) { | ||
@@ -54,3 +54,3 @@ for (const key in Reference[Reference.layout[i]]) { | ||
) { | ||
function inner(layer, propertyType: 'paint' | 'layout') { | ||
function inner(layer: LayerSpecification, propertyType: 'paint' | 'layout') { | ||
const properties = (layer[propertyType]: any); | ||
@@ -57,0 +57,0 @@ if (!properties) return; |
@@ -16,3 +16,3 @@ // @flow | ||
// "options" may also be another EvaluationParameters to copy | ||
constructor(zoom: number, options?: *) { | ||
constructor(zoom: number, options?: any) { | ||
this.zoom = zoom; | ||
@@ -19,0 +19,0 @@ |
@@ -85,2 +85,3 @@ // @flow | ||
if (fog && fog[name] === undefined) { | ||
// $FlowFixMe[prop-missing] | ||
fog[name] = styleSpec.fog[name].default; | ||
@@ -87,0 +88,0 @@ } |
@@ -63,2 +63,3 @@ // @flow | ||
possiblyEvaluate(value: PropertyValue<[number, number, number], LightPosition>, parameters: EvaluationParameters): LightPosition { | ||
// $FlowFixMe[method-unbinding] | ||
return sphericalToCartesian(value.expression.evaluate(parameters)); | ||
@@ -65,0 +66,0 @@ } |
@@ -19,3 +19,3 @@ // @flow | ||
let jsonRequest = getJSON(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.json'), ResourceType.SpriteJSON), (err: ?Error, data: ?Object) => { | ||
let jsonRequest: ?Cancelable = getJSON(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.json'), ResourceType.SpriteJSON), (err: ?Error, data: ?Object) => { | ||
jsonRequest = null; | ||
@@ -29,3 +29,3 @@ if (!error) { | ||
let imageRequest = getImage(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.png'), ResourceType.SpriteImage), (err, img) => { | ||
let imageRequest: ?Cancelable = getImage(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.png'), ResourceType.SpriteImage), (err, img) => { | ||
imageRequest = null; | ||
@@ -32,0 +32,0 @@ if (!error) { |
@@ -19,3 +19,3 @@ // @flow | ||
_currentPartIndex: number; | ||
_seenCrossTileIDs: { [string | number]: boolean }; | ||
_seenCrossTileIDs: Set<number>; | ||
_bucketParts: Array<BucketPart>; | ||
@@ -29,3 +29,3 @@ | ||
this._currentPartIndex = 0; | ||
this._seenCrossTileIDs = {}; | ||
this._seenCrossTileIDs = new Set(); | ||
this._bucketParts = []; | ||
@@ -32,0 +32,0 @@ } |
@@ -109,5 +109,5 @@ // @flow | ||
export type TransitionParameters = { | ||
export type TransitionParameters = interface { | ||
now: TimePoint, | ||
transition: TransitionSpecification | ||
transition: TransitionSpecification, | ||
}; | ||
@@ -380,3 +380,3 @@ | ||
setValue<S: string>(name: S, value: *) { | ||
setValue<S: string>(name: S, value: any) { | ||
this._values[name] = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value)); | ||
@@ -428,3 +428,3 @@ } | ||
*/ | ||
type PossiblyEvaluatedValue<T> = | ||
export type PossiblyEvaluatedValue<T> = | ||
| {kind: 'constant', value: T} | ||
@@ -523,2 +523,3 @@ | SourceExpression | ||
assert(!value.isDataDriven()); | ||
// $FlowFixMe[method-unbinding] | ||
return value.expression.evaluate(parameters); | ||
@@ -547,2 +548,3 @@ } | ||
overrides: ?Object; | ||
useIntegerZoom: ?boolean; | ||
@@ -556,2 +558,3 @@ constructor(specification: StylePropertySpecification, overrides?: Object) { | ||
if (value.expression.kind === 'constant' || value.expression.kind === 'camera') { | ||
// $FlowFixMe[method-unbinding] | ||
return new PossiblyEvaluatedPropertyValue(this, {kind: 'constant', value: value.expression.evaluate(parameters, (null: any), {}, canonical, availableImages)}, parameters); | ||
@@ -594,2 +597,3 @@ } else { | ||
} else { | ||
// $FlowFixMe[method-unbinding] | ||
return value.evaluate(parameters, feature, featureState, canonical, availableImages); | ||
@@ -615,2 +619,3 @@ } | ||
possiblyEvaluate(value: PropertyValue<Color, boolean>, parameters: EvaluationParameters, canonical?: CanonicalTileID, availableImages?: Array<string>): boolean { | ||
// $FlowFixMe[method-unbinding] | ||
return !!value.expression.evaluate(parameters, (null: any), {}, canonical, availableImages); | ||
@@ -617,0 +622,0 @@ } |
@@ -39,6 +39,7 @@ // @flow | ||
createBucket(parameters: BucketParameters<*>): CircleBucket<CircleStyleLayer> { | ||
createBucket(parameters: BucketParameters<CircleStyleLayer>): CircleBucket<CircleStyleLayer> { | ||
return new CircleBucket(parameters); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(bucket: Bucket): number { | ||
@@ -51,2 +52,3 @@ const circleBucket: CircleBucket<CircleStyleLayer> = (bucket: any); | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(queryGeometry: TilespaceQueryGeometry, | ||
@@ -53,0 +55,0 @@ feature: IVectorTileFeature, |
// @flow | ||
import StyleLayer from '../style_layer.js'; | ||
import MercatorCoordinate from '../../geo/mercator_coordinate.js'; | ||
import type Map from '../../ui/map.js'; | ||
import assert from 'assert'; | ||
import type {ValidationErrors} from '../validate_style.js'; | ||
import type {ProjectionSpecification} from '../../style-spec/types.js'; | ||
type CustomRenderMethod = (gl: WebGLRenderingContext, matrix: Array<number>) => void; | ||
type CustomRenderMethod = (gl: WebGLRenderingContext, matrix: Array<number>, projection: ?ProjectionSpecification, projectionToMercatorMatrix: ?Array<number>, projectionToMercatorTransition: ?number, centerInMercator: ?Array<number>, pixelsPerMeterRatio: ?number) => void; | ||
@@ -157,2 +159,4 @@ /** | ||
prerender: ?CustomRenderMethod, | ||
renderToTile: ?(gl: WebGLRenderingContext, tileId: MercatorCoordinate) => void, | ||
shouldRerenderTiles: ?() => boolean, | ||
onAdd: ?(map: Map, gl: WebGLRenderingContext) => void, | ||
@@ -206,2 +210,10 @@ onRemove: ?(map: Map, gl: WebGLRenderingContext) => void | ||
isLayerDraped(): boolean { | ||
return this.implementation.renderToTile !== undefined; | ||
} | ||
shouldRedrape(): boolean { | ||
return !!this.implementation.shouldRerenderTiles && this.implementation.shouldRerenderTiles(); | ||
} | ||
recalculate() {} | ||
@@ -218,2 +230,3 @@ updateTransitions() {} | ||
// $FlowFixMe[method-unbinding] | ||
onAdd(map: Map) { | ||
@@ -225,2 +238,3 @@ if (this.implementation.onAdd) { | ||
// $FlowFixMe[method-unbinding] | ||
onRemove(map: Map) { | ||
@@ -227,0 +241,0 @@ if (this.implementation.onRemove) { |
@@ -39,2 +39,3 @@ // This file is generated. Edit build/generate-style-code.js, then run `yarn run codegen`. | ||
"fill-extrusion-ambient-occlusion-radius": DataConstantProperty<number>, | ||
"fill-extrusion-rounded-roof": DataConstantProperty<boolean>, | ||
|}; | ||
@@ -53,2 +54,3 @@ | ||
"fill-extrusion-ambient-occlusion-radius": new DataConstantProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-ambient-occlusion-radius"]), | ||
"fill-extrusion-rounded-roof": new DataConstantProperty(styleSpec["paint_fill-extrusion"]["fill-extrusion-rounded-roof"]), | ||
}); | ||
@@ -55,0 +57,0 @@ |
@@ -48,2 +48,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(): number { | ||
@@ -67,2 +68,3 @@ return translateDistance(this.paint.get('fill-extrusion-translate')); | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(queryGeometry: TilespaceQueryGeometry, | ||
@@ -121,3 +123,3 @@ feature: IVectorTileFeature, | ||
function dot(a, b) { | ||
function dot(a: Point, b: Point) { | ||
return a.x * b.x + a.y * b.y; | ||
@@ -233,3 +235,3 @@ } | ||
const setPoint = (point, x, y, z) => { | ||
const setPoint = (point: Array<number>, x: number, y: number, z: number) => { | ||
point[0] = x; | ||
@@ -236,0 +238,0 @@ point[1] = y; |
@@ -60,6 +60,7 @@ // @flow | ||
createBucket(parameters: BucketParameters<*>): FillBucket { | ||
createBucket(parameters: BucketParameters<FillStyleLayer>): FillBucket { | ||
return new FillBucket(parameters); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(): number { | ||
@@ -69,2 +70,3 @@ return translateDistance(this.paint.get('fill-translate')); | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(queryGeometry: TilespaceQueryGeometry, | ||
@@ -71,0 +73,0 @@ feature: IVectorTileFeature, |
@@ -37,3 +37,3 @@ // @flow | ||
createBucket(parameters: BucketParameters<*>): HeatmapBucket { | ||
createBucket(parameters: BucketParameters<HeatmapStyleLayer>): HeatmapBucket { | ||
return new HeatmapBucket(parameters); | ||
@@ -72,2 +72,3 @@ } | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(bucket: Bucket): number { | ||
@@ -77,2 +78,3 @@ return getMaximumPaintValue('heatmap-radius', this, ((bucket: any): CircleBucket<*>)); | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(queryGeometry: TilespaceQueryGeometry, | ||
@@ -79,0 +81,0 @@ feature: IVectorTileFeature, |
@@ -16,3 +16,4 @@ // @flow | ||
import Step from '../../style-spec/expression/definitions/step.js'; | ||
import type {FeatureState, ZoomConstantExpression, StylePropertyExpression} from '../../style-spec/expression/index.js'; | ||
import type {PossiblyEvaluatedValue, PropertyValue, PossiblyEvaluatedPropertyValue} from '../properties.js'; | ||
import type {Feature, FeatureState, ZoomConstantExpression, StylePropertyExpression} from '../../style-spec/expression/index.js'; | ||
import type {Bucket, BucketParameters} from '../../data/bucket.js'; | ||
@@ -26,5 +27,5 @@ import type {LayoutProps, PaintProps} from './line_style_layer_properties.js'; | ||
class LineFloorwidthProperty extends DataDrivenProperty<number> { | ||
useIntegerZoom: true; | ||
useIntegerZoom: ?boolean; | ||
possiblyEvaluate(value, parameters) { | ||
possiblyEvaluate(value: PropertyValue<number, PossiblyEvaluatedPropertyValue<number>>, parameters: EvaluationParameters): PossiblyEvaluatedPropertyValue<number> { | ||
parameters = new EvaluationParameters(Math.floor(parameters.zoom), { | ||
@@ -38,3 +39,3 @@ now: parameters.now, | ||
evaluate(value, globals, feature, featureState) { | ||
evaluate(value: PossiblyEvaluatedValue<number>, globals: EvaluationParameters, feature: Feature, featureState: FeatureState): number { | ||
globals = extend({}, globals, {zoom: Math.floor(globals.zoom)}); | ||
@@ -76,2 +77,6 @@ return super.evaluate(value, globals, feature, featureState); | ||
widthExpression(): StylePropertyExpression { | ||
return this._transitionablePaint._values['line-width'].value.expression; | ||
} | ||
recalculate(parameters: EvaluationParameters, availableImages: Array<string>) { | ||
@@ -84,3 +89,3 @@ super.recalculate(parameters, availableImages); | ||
createBucket(parameters: BucketParameters<*>): LineBucket { | ||
createBucket(parameters: BucketParameters<LineStyleLayer>): LineBucket { | ||
return new LineBucket(parameters); | ||
@@ -100,2 +105,3 @@ } | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(bucket: Bucket): number { | ||
@@ -110,2 +116,3 @@ const lineBucket: LineBucket = (bucket: any); | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(queryGeometry: TilespaceQueryGeometry, | ||
@@ -141,3 +148,3 @@ feature: IVectorTileFeature, | ||
function getLineWidth(lineWidth, lineGapWidth) { | ||
function getLineWidth(lineWidth: number, lineGapWidth: number) { | ||
if (lineGapWidth > 0) { | ||
@@ -150,3 +157,3 @@ return lineGapWidth + 2 * lineWidth; | ||
function offsetLine(rings, offset) { | ||
function offsetLine(rings: Array<Array<Point>>, offset: number) { | ||
const newRings = []; | ||
@@ -153,0 +160,0 @@ const zero = new Point(0, 0); |
@@ -9,2 +9,4 @@ // @flow | ||
import properties from './symbol_style_layer_properties.js'; | ||
import type {FormattedSection} from '../../style-spec/expression/types/formatted.js'; | ||
import type {FormattedSectionExpression} from '../../style-spec/expression/definitions/format.js'; | ||
@@ -100,3 +102,3 @@ import { | ||
getValueAndResolveTokens(name: *, feature: Feature, canonical: CanonicalTileID, availableImages: Array<string>): string { | ||
getValueAndResolveTokens(name: any, feature: Feature, canonical: CanonicalTileID, availableImages: Array<string>): string { | ||
const value = this.layout.get(name).evaluate(feature, {}, canonical, availableImages); | ||
@@ -111,6 +113,7 @@ const unevaluated = this._unevaluatedLayout._values[name]; | ||
createBucket(parameters: BucketParameters<*>): SymbolBucket { | ||
createBucket(parameters: BucketParameters<SymbolStyleLayer>): SymbolBucket { | ||
return new SymbolBucket(parameters); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
queryRadius(): number { | ||
@@ -120,2 +123,3 @@ return 0; | ||
// $FlowFixMe[method-unbinding] | ||
queryIntersectsFeature(): boolean { | ||
@@ -136,4 +140,6 @@ assert(false); // Should take a different path in FeatureIndex | ||
if (overriden.value.kind === 'constant' || overriden.value.kind === 'source') { | ||
// $FlowFixMe[method-unbinding] | ||
expression = (new ZoomConstantExpression('source', styleExpression): SourceExpression); | ||
} else { | ||
// $FlowFixMe[method-unbinding] | ||
expression = (new ZoomDependentExpression('composite', | ||
@@ -144,2 +150,3 @@ styleExpression, | ||
} | ||
// $FlowFixMe[prop-missing] | ||
this.paint._values[overridable] = new PossiblyEvaluatedPropertyValue(overriden.property, | ||
@@ -163,3 +170,3 @@ expression, | ||
const checkSections = (sections) => { | ||
const checkSections = (sections: Array<FormattedSection> | Array<FormattedSectionExpression>) => { | ||
for (const section of sections) { | ||
@@ -166,0 +173,0 @@ if (property.overrides && property.overrides.hasOverride(section)) { |
@@ -26,3 +26,3 @@ // @flow | ||
let p = anchor; | ||
let p: Point = anchor; | ||
let index = anchor.segment + 1; | ||
@@ -29,0 +29,0 @@ let anchorDistance = 0; |
@@ -22,3 +22,3 @@ // @flow | ||
type PlacedCollisionBox = {| | ||
export type PlacedCollisionBox = {| | ||
box: Array<number>, | ||
@@ -25,0 +25,0 @@ offscreen: boolean, |
@@ -6,4 +6,5 @@ // @flow | ||
import {SymbolInstanceArray} from '../data/array_types.js'; | ||
import KDBush from 'kdbush'; | ||
import type Projection from '../geo/projection/projection.js'; | ||
import type {SymbolInstance} from '../data/array_types.js'; | ||
import type {OverscaledTileID} from '../source/tile_id.js'; | ||
@@ -33,48 +34,43 @@ import type SymbolBucket from '../data/bucket/symbol_bucket.js'; | ||
tileID: OverscaledTileID; | ||
indexedSymbolInstances: {[_: number]: Array<{ | ||
crossTileID: number, | ||
coord: { | ||
x: number, | ||
y: number | ||
} | ||
}>}; | ||
bucketInstanceId: number; | ||
index: KDBush; | ||
keys: Array<number>; | ||
crossTileIDs: Array<number>; | ||
constructor(tileID: OverscaledTileID, symbolInstances: SymbolInstanceArray, bucketInstanceId: number) { | ||
this.tileID = tileID; | ||
this.indexedSymbolInstances = {}; | ||
this.bucketInstanceId = bucketInstanceId; | ||
// create a spatial index for deduplicating symbol instances; | ||
// use a low nodeSize because we're optimizing for search performance, not indexing | ||
this.index = new KDBush(symbolInstances.length, 16, Int32Array); | ||
this.keys = []; | ||
this.crossTileIDs = []; | ||
const tx = tileID.canonical.x * EXTENT; | ||
const ty = tileID.canonical.y * EXTENT; | ||
for (let i = 0; i < symbolInstances.length; i++) { | ||
const symbolInstance = symbolInstances.get(i); | ||
const key = symbolInstance.key; | ||
if (!this.indexedSymbolInstances[key]) { | ||
this.indexedSymbolInstances[key] = []; | ||
} | ||
// This tile may have multiple symbol instances with the same key | ||
// Store each one along with its coordinates | ||
this.indexedSymbolInstances[key].push({ | ||
crossTileID: symbolInstance.crossTileID, | ||
coord: this.getScaledCoordinates(symbolInstance, tileID) | ||
}); | ||
const {key, crossTileID, tileAnchorX, tileAnchorY} = symbolInstances.get(i); | ||
// Converts the coordinates of the input symbol instance into coordinates that be can compared | ||
// against other symbols in this index. Coordinates are: | ||
// (1) world-based (so after conversion the source tile is irrelevant) | ||
// (2) converted to the z-scale of this TileLayerIndex | ||
// (3) down-sampled by "roundingFactor" from tile coordinate precision in order to be | ||
// more tolerant of small differences between tiles. | ||
const x = Math.floor((tx + tileAnchorX) * roundingFactor); | ||
const y = Math.floor((ty + tileAnchorY) * roundingFactor); | ||
this.index.add(x, y); | ||
this.keys.push(key); | ||
this.crossTileIDs.push(crossTileID); | ||
} | ||
this.index.finish(); | ||
} | ||
// Converts the coordinates of the input symbol instance into coordinates that be can compared | ||
// against other symbols in this index. Coordinates are: | ||
// (1) world-based (so after conversion the source tile is irrelevant) | ||
// (2) converted to the z-scale of this TileLayerIndex | ||
// (3) down-sampled by "roundingFactor" from tile coordinate precision in order to be | ||
// more tolerant of small differences between tiles. | ||
getScaledCoordinates(symbolInstance: SymbolInstance, childTileID: OverscaledTileID): {|x: number, y: number|} { | ||
const zDifference = childTileID.canonical.z - this.tileID.canonical.z; | ||
const scale = roundingFactor / Math.pow(2, zDifference); | ||
return { | ||
x: Math.floor((childTileID.canonical.x * EXTENT + symbolInstance.tileAnchorX) * scale), | ||
y: Math.floor((childTileID.canonical.y * EXTENT + symbolInstance.tileAnchorY) * scale) | ||
}; | ||
} | ||
findMatches(symbolInstances: SymbolInstanceArray, newTileID: OverscaledTileID, zoomCrossTileIDs: {[crossTileID: number]: boolean}) { | ||
findMatches(symbolInstances: SymbolInstanceArray, newTileID: OverscaledTileID, zoomCrossTileIDs: Set<number>) { | ||
const tolerance = this.tileID.canonical.z < newTileID.canonical.z ? 1 : Math.pow(2, this.tileID.canonical.z - newTileID.canonical.z); | ||
const scale = roundingFactor / Math.pow(2, newTileID.canonical.z - this.tileID.canonical.z); | ||
const tx = newTileID.canonical.x * EXTENT; | ||
const ty = newTileID.canonical.y * EXTENT; | ||
@@ -87,22 +83,17 @@ for (let i = 0; i < symbolInstances.length; i++) { | ||
} | ||
const {key, tileAnchorX, tileAnchorY} = symbolInstance; | ||
const x = Math.floor((tx + tileAnchorX) * scale); | ||
const y = Math.floor((ty + tileAnchorY) * scale); | ||
const indexedInstances = this.indexedSymbolInstances[symbolInstance.key]; | ||
if (!indexedInstances) { | ||
// No symbol with this key in this bucket | ||
continue; | ||
} | ||
const scaledSymbolCoord = this.getScaledCoordinates(symbolInstance, newTileID); | ||
for (const thisTileSymbol of indexedInstances) { | ||
// Return any symbol with the same keys whose coordinates are within 1 | ||
// grid unit. (with a 4px grid, this covers a 12px by 12px area) | ||
if (Math.abs(thisTileSymbol.coord.x - scaledSymbolCoord.x) <= tolerance && | ||
Math.abs(thisTileSymbol.coord.y - scaledSymbolCoord.y) <= tolerance && | ||
!zoomCrossTileIDs[thisTileSymbol.crossTileID]) { | ||
// Return any symbol with the same keys whose coordinates are within 1 | ||
// grid unit. (with a 4px grid, this covers a 12px by 12px area) | ||
const matchedIds = this.index.range(x - tolerance, y - tolerance, x + tolerance, y + tolerance); | ||
for (const id of matchedIds) { | ||
const crossTileID = this.crossTileIDs[id]; | ||
if (this.keys[id] === key && !zoomCrossTileIDs.has(crossTileID)) { | ||
// Once we've marked ourselves duplicate against this parent symbol, | ||
// don't let any other symbols at the same zoom level duplicate against | ||
// the same parent (see issue #5993) | ||
zoomCrossTileIDs[thisTileSymbol.crossTileID] = true; | ||
symbolInstance.crossTileID = thisTileSymbol.crossTileID; | ||
zoomCrossTileIDs.add(crossTileID); | ||
symbolInstance.crossTileID = crossTileID; | ||
break; | ||
@@ -127,3 +118,3 @@ } | ||
indexes: {[zoom: string | number]: {[tileId: string | number]: TileLayerIndex}}; | ||
usedCrossTileIDs: {[zoom: string | number]: {[crossTileID: number]: boolean}}; | ||
usedCrossTileIDs: {[zoom: string | number]: Set<number>}; | ||
lng: number; | ||
@@ -183,3 +174,3 @@ | ||
if (!this.usedCrossTileIDs[tileID.overscaledZ]) { | ||
this.usedCrossTileIDs[tileID.overscaledZ] = {}; | ||
this.usedCrossTileIDs[tileID.overscaledZ] = new Set(); | ||
} | ||
@@ -211,3 +202,3 @@ const zoomCrossTileIDs = this.usedCrossTileIDs[tileID.overscaledZ]; | ||
symbolInstance.crossTileID = crossTileIDs.generate(); | ||
zoomCrossTileIDs[symbolInstance.crossTileID] = true; | ||
zoomCrossTileIDs.add(symbolInstance.crossTileID); | ||
} | ||
@@ -225,6 +216,4 @@ } | ||
removeBucketCrossTileIDs(zoom: string | number, removedBucket: TileLayerIndex) { | ||
for (const key in removedBucket.indexedSymbolInstances) { | ||
for (const symbolInstance of removedBucket.indexedSymbolInstances[(key: any)]) { | ||
delete this.usedCrossTileIDs[zoom][symbolInstance.crossTileID]; | ||
} | ||
for (const crossTileID of removedBucket.crossTileIDs) { | ||
this.usedCrossTileIDs[zoom].delete(crossTileID); | ||
} | ||
@@ -231,0 +220,0 @@ } |
@@ -113,3 +113,3 @@ // @flow | ||
function resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, placeAtMiddle, tileExtent) { | ||
function resample(line: Array<Point>, offset: number, spacing: number, angleWindowSize: number, maxAngle: number, labelLength: number, isLineContinued: boolean, placeAtMiddle: boolean, tileExtent: number) { | ||
@@ -116,0 +116,0 @@ const halfLabelLength = labelLength / 2; |
@@ -72,2 +72,3 @@ // @flow | ||
insert(key: any, x1: number, y1: number, x2: number, y2: number) { | ||
// $FlowFixMe[method-unbinding] | ||
this._forEachCell(x1, y1, x2, y2, this._insertBoxCell, this.boxUid++); | ||
@@ -84,2 +85,3 @@ this.boxKeys.push(key); | ||
// It's more than necessary (by a factor of 4/PI), but fast to insert | ||
// $FlowFixMe[method-unbinding] | ||
this._forEachCell(x - radius, y - radius, x + radius, y + radius, this._insertCircleCell, this.circleUid++); | ||
@@ -136,2 +138,3 @@ this.circleKeys.push(key); | ||
}; | ||
// $FlowFixMe[method-unbinding] | ||
this._forEachCell(x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate); | ||
@@ -162,2 +165,3 @@ return hitTest ? result.length > 0 : result; | ||
}; | ||
// $FlowFixMe[method-unbinding] | ||
this._forEachCell(x1, y1, x2, y2, this._queryCellCircle, result, queryArgs, predicate); | ||
@@ -164,0 +168,0 @@ return hitTest ? result.length > 0 : result; |
// @flow | ||
import type Point from '@mapbox/point-geometry'; | ||
import type {SymbolFeature} from '../data/bucket/symbol_bucket.js'; | ||
@@ -11,3 +12,3 @@ | ||
function add(k) { | ||
function add(k: number) { | ||
mergedFeatures.push(features[k]); | ||
@@ -17,3 +18,3 @@ mergedIndex++; | ||
function mergeFromRight(leftKey: string, rightKey: string, geom) { | ||
function mergeFromRight(leftKey: string, rightKey: string, geom: Array<Array<Point>>) { | ||
const i = rightIndex[leftKey]; | ||
@@ -28,3 +29,3 @@ delete rightIndex[leftKey]; | ||
function mergeFromLeft(leftKey: string, rightKey: string, geom) { | ||
function mergeFromLeft(leftKey: string, rightKey: string, geom: Array<Array<Point>>) { | ||
const i = leftIndex[rightKey]; | ||
@@ -39,3 +40,3 @@ delete leftIndex[rightKey]; | ||
function getKey(text, geom, onRight) { | ||
function getKey(text: string, geom: Array<Array<Point>>, onRight: ?boolean) { | ||
const point = onRight ? geom[0][geom[0].length - 1] : geom[0][0]; | ||
@@ -42,0 +43,0 @@ return `${text}:${point.x}:${point.y}`; |
@@ -16,3 +16,3 @@ // @flow | ||
import type Tile from '../source/tile.js'; | ||
import type SymbolBucket, {CollisionArrays, SingleCollisionBox} from '../data/bucket/symbol_bucket.js'; | ||
import type SymbolBucket, {SymbolBuffers, CollisionArrays, SingleCollisionBox} from '../data/bucket/symbol_bucket.js'; | ||
import type {CollisionBoxArray, CollisionVertexArray, SymbolInstance} from '../data/array_types.js'; | ||
@@ -25,3 +25,7 @@ import type FeatureIndex from '../data/feature_index.js'; | ||
import type {Mat4} from 'gl-matrix'; | ||
import type {PlacedCollisionBox} from './collision_index.js'; | ||
// PlacedCollisionBox with all fields optional | ||
type PartialPlacedCollisionBox = $ObjMap<PlacedCollisionBox, <V>() => ?V>; | ||
class OpacityState { | ||
@@ -341,3 +345,3 @@ opacity: number; | ||
symbolInstance: SymbolInstance, boxIndex: number, bucket: SymbolBucket, | ||
orientation: number, iconBox: ?SingleCollisionBox, textSize: any, iconSize: any): ?{ shift: Point, placedGlyphBoxes: { box: Array<number>, offscreen: boolean, occluded: boolean } } { | ||
orientation: number, iconBox: ?SingleCollisionBox, textSize: any, iconSize: any): ?{ shift: Point, placedGlyphBoxes: PlacedCollisionBox } { | ||
@@ -390,3 +394,3 @@ const {textOffset0, textOffset1, crossTileID} = symbolInstance; | ||
placeLayerBucketPart(bucketPart: Object, seenCrossTileIDs: { [string | number]: boolean }, showCollisionBoxes: boolean, updateCollisionBoxIfNecessary: boolean) { | ||
placeLayerBucketPart(bucketPart: Object, seenCrossTileIDs: Set<number>, showCollisionBoxes: boolean, updateCollisionBoxIfNecessary: boolean) { | ||
@@ -473,3 +477,3 @@ const { | ||
this.placements[crossTileID] = new JointPlacement(false, false, false, true); | ||
seenCrossTileIDs[crossTileID] = true; | ||
seenCrossTileIDs.add(crossTileID); | ||
return; | ||
@@ -479,3 +483,3 @@ } | ||
if (seenCrossTileIDs[crossTileID]) return; | ||
if (seenCrossTileIDs.has(crossTileID)) return; | ||
if (holdingForFade) { | ||
@@ -487,11 +491,11 @@ // Mark all symbols from this tile as "not placed", but don't add to seenCrossTileIDs, because we don't | ||
} | ||
let placeText = false; | ||
let placeIcon = false; | ||
let offscreen = true; | ||
let textOccluded = false; | ||
let placeText: ?boolean = false; | ||
let placeIcon: ?boolean = false; | ||
let offscreen: ?boolean = true; | ||
let textOccluded: ?boolean = false; | ||
let iconOccluded = false; | ||
let shift = null; | ||
let placed = {box: null, offscreen: null, occluded: null}; | ||
let placedVerticalText = {box: null, offscreen: null, occluded: null}; | ||
let placed: PartialPlacedCollisionBox = {box: null, offscreen: null, occluded: null}; | ||
let placedVerticalText: PartialPlacedCollisionBox = {box: null, offscreen: null, occluded: null}; | ||
@@ -524,3 +528,3 @@ let placedGlyphBoxes = null; | ||
updateBoxData(textBox); | ||
const updatePreviousOrientationIfNotPlaced = (isPlaced) => { | ||
const updatePreviousOrientationIfNotPlaced = (isPlaced: boolean) => { | ||
let previousOrientation = WritingMode.horizontal; | ||
@@ -538,3 +542,3 @@ if (bucket.allowVerticalPlacement && !isPlaced && this.prevPlacement) { | ||
const placeTextForPlacementModes = (placeHorizontalFn, placeVerticalFn) => { | ||
const placeTextForPlacementModes = (placeHorizontalFn: () => PartialPlacedCollisionBox, placeVerticalFn: () => PartialPlacedCollisionBox) => { | ||
if (bucket.allowVerticalPlacement && numVerticalGlyphVertices > 0 && collisionArrays.verticalTextBox) { | ||
@@ -556,3 +560,3 @@ for (const placementMode of bucket.writingModes) { | ||
if (!layout.get('text-variable-anchor')) { | ||
const placeBox = (collisionTextBox, orientation) => { | ||
const placeBox = (collisionTextBox: SingleCollisionBox, orientation: number) => { | ||
const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex); | ||
@@ -568,7 +572,7 @@ const placedFeature = this.collisionIndex.placeCollisionBox(bucket, textScale, collisionTextBox, | ||
const placeHorizontal = () => { | ||
const placeHorizontal: () => PlacedCollisionBox = () => { | ||
return placeBox(textBox, WritingMode.horizontal); | ||
}; | ||
const placeVertical = () => { | ||
const placeVertical: () => PlacedCollisionBox | PartialPlacedCollisionBox = () => { | ||
const verticalTextBox = collisionArrays.verticalTextBox; | ||
@@ -582,5 +586,10 @@ if (bucket.allowVerticalPlacement && numVerticalGlyphVertices > 0 && verticalTextBox) { | ||
placeTextForPlacementModes(placeHorizontal, placeVertical); | ||
updatePreviousOrientationIfNotPlaced(placed && placed.box && placed.box.length); | ||
placeTextForPlacementModes( | ||
((placeHorizontal: any): () => PartialPlacedCollisionBox), | ||
((placeVertical: any): () => PartialPlacedCollisionBox), | ||
); | ||
const isPlaced = placed && placed.box && placed.box.length; | ||
updatePreviousOrientationIfNotPlaced(!!isPlaced); | ||
} else { | ||
@@ -600,3 +609,3 @@ let anchors = layout.get('text-variable-anchor'); | ||
const placeBoxForVariableAnchors = (collisionTextBox, collisionIconBox, orientation) => { | ||
const placeBoxForVariableAnchors = (collisionTextBox: SingleCollisionBox, collisionIconBox: ?SingleCollisionBox, orientation: number) => { | ||
const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex); | ||
@@ -609,3 +618,3 @@ const width = (collisionTextBox.x2 - collisionTextBox.x1) * textScale + 2.0 * collisionTextBox.padding; | ||
let placedBox: ?{ box: Array<number>, offscreen: boolean, occluded: boolean } = {box: [], offscreen: false, occluded: false}; | ||
let placedBox: PartialPlacedCollisionBox = {box: [], offscreen: false, occluded: false}; | ||
const placementAttempts = textAllowOverlap ? anchors.length * 2 : anchors.length; | ||
@@ -622,3 +631,3 @@ for (let i = 0; i < placementAttempts; ++i) { | ||
if (result) { | ||
placedBox = result.placedGlyphBoxes; | ||
placedBox = ((result.placedGlyphBoxes: any): PartialPlacedCollisionBox); | ||
if (placedBox && placedBox.box && placedBox.box.length) { | ||
@@ -657,3 +666,4 @@ placeText = true; | ||
const prevOrientation = updatePreviousOrientationIfNotPlaced(placed && placed.box); | ||
const isPlaced = placed && placed.box; | ||
const prevOrientation = updatePreviousOrientationIfNotPlaced(!!isPlaced); | ||
@@ -721,3 +731,3 @@ // If we didn't get placed, we still need to copy our position from the last placement for | ||
const placeIconFeature = iconBox => { | ||
const placeIconFeature = (iconBox: SingleCollisionBox) => { | ||
updateBoxData(iconBox); | ||
@@ -802,3 +812,3 @@ const shiftPoint: Point = hasIconTextFit && shift ? | ||
this.placements[crossTileID] = new JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded); | ||
seenCrossTileIDs[crossTileID] = true; | ||
seenCrossTileIDs.add(crossTileID); | ||
}; | ||
@@ -930,3 +940,3 @@ | ||
updateLayerOpacities(styleLayer: StyleLayer, tiles: Array<Tile>) { | ||
const seenCrossTileIDs = {}; | ||
const seenCrossTileIDs = new Set(); | ||
for (const tile of tiles) { | ||
@@ -940,3 +950,3 @@ const symbolBucket = ((tile.getBucket(styleLayer): any): SymbolBucket); | ||
updateBucketOpacities(bucket: SymbolBucket, seenCrossTileIDs: { [string | number]: boolean }, collisionBoxArray: ?CollisionBoxArray) { | ||
updateBucketOpacities(bucket: SymbolBucket, seenCrossTileIDs: Set<number>, collisionBoxArray: ?CollisionBoxArray) { | ||
if (bucket.hasTextData()) bucket.text.opacityVertexArray.clear(); | ||
@@ -969,3 +979,3 @@ if (bucket.hasIconData()) bucket.icon.opacityVertexArray.clear(); | ||
const addOpacities = (iconOrText, numVertices: number, opacity: number) => { | ||
const addOpacities = (iconOrText: SymbolBuffers, numVertices: number, opacity: number) => { | ||
for (let i = 0; i < numVertices / 4; i++) { | ||
@@ -987,3 +997,3 @@ iconOrText.opacityVertexArray.emplaceBack(opacity); | ||
const isDuplicate = seenCrossTileIDs[crossTileID]; | ||
const isDuplicate = seenCrossTileIDs.has(crossTileID); | ||
@@ -999,3 +1009,3 @@ let opacityState = this.opacities[crossTileID]; | ||
seenCrossTileIDs[crossTileID] = true; | ||
seenCrossTileIDs.add(crossTileID); | ||
@@ -1002,0 +1012,0 @@ const hasText = numHorizontalGlyphVertices > 0 || numVerticalGlyphVertices > 0; |
@@ -272,3 +272,3 @@ // @flow | ||
let useVertical = false; | ||
let useVertical: ?boolean = false; | ||
let prevWritingMode; | ||
@@ -399,7 +399,7 @@ | ||
// If the angle if less or equal to 5 degree, then keep the text glyphs unflipped even if it is required. | ||
function isInFlipRetainRange(dx, dy) { | ||
function isInFlipRetainRange(dx: number, dy: number) { | ||
return dx === 0 || Math.abs(dy / dx) > maxTangent; | ||
} | ||
function requiresOrientationChange(writingMode, flipState, dx, dy) { | ||
function requiresOrientationChange(writingMode: number, flipState: number, dx: number, dy: number) { | ||
if (writingMode === WritingMode.horizontal && Math.abs(dy) > Math.abs(dx)) { | ||
@@ -427,3 +427,3 @@ // On top of choosing whether to flip, choose whether to render this version of the glyphs or the alternate | ||
function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, globeExtVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevation, projection, tileID, pitchWithMap): PlacementStatus { | ||
function placeGlyphsAlongLine(symbol: PlacedSymbol, fontSize: number, flip: boolean, keepUpright: boolean, posMatrix: Float32Array, labelPlaneMatrix: Float32Array, glCoordMatrix: Float32Array, glyphOffsetArray: GlyphOffsetArray, lineVertexArray: SymbolLineVertexArray, dynamicLayoutVertexArray: SymbolDynamicLayoutArray, globeExtVertexArray: ?SymbolGlobeExtArray, anchorPoint: VecType, tileAnchorPoint: Point, projectionCache: ProjectionCache, aspectRatio: number, getElevation: ?((p: Point) => Array<number>), projection: Projection, tileID: OverscaledTileID, pitchWithMap: boolean): PlacementStatus { | ||
const fontScale = fontSize / 24; | ||
@@ -634,3 +634,3 @@ const lineOffsetX = symbol.lineOffsetX * fontScale; | ||
let axisZ = [0, 0, 1]; | ||
let axisZ: Vec3 = [0, 0, 1]; | ||
let diffX = prevToCurrent[0]; | ||
@@ -637,0 +637,0 @@ let diffY = prevToCurrent[1]; |
@@ -18,2 +18,4 @@ // @flow | ||
type Size = {| fixed: number, stretch: number |}; | ||
/** | ||
@@ -80,3 +82,3 @@ * A textured quad for rendering a single icon or glyph. | ||
const reduceRanges = (sum, range) => sum + range[1] - range[0]; | ||
const reduceRanges = (sum: number, range: [number, number]) => sum + range[1] - range[0]; | ||
const stretchWidth = stretchX.reduce(reduceRanges, 0); | ||
@@ -108,3 +110,3 @@ const stretchHeight = stretchY.reduce(reduceRanges, 0); | ||
const makeBox = (left, top, right, bottom) => { | ||
const makeBox = (left: Size, top: Size, right: Size, bottom: Size) => { | ||
@@ -186,3 +188,3 @@ const leftEm = getEmOffset(left.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); | ||
function sumWithinRange(ranges, min, max) { | ||
function sumWithinRange(ranges: Array<[number, number]>, min: number, max: number) { | ||
let sum = 0; | ||
@@ -195,3 +197,3 @@ for (const range of ranges) { | ||
function stretchZonesToCuts(stretchZones, fixedSize, stretchSize) { | ||
function stretchZonesToCuts(stretchZones: Array<[number, number]>, fixedSize: number, stretchSize: number) { | ||
const cuts = [{fixed: -border, stretch: 0}]; | ||
@@ -217,7 +219,7 @@ | ||
function getEmOffset(stretchOffset, stretchSize, iconSize, iconOffset) { | ||
function getEmOffset(stretchOffset: number, stretchSize: number, iconSize: number, iconOffset: number) { | ||
return stretchOffset / stretchSize * iconSize + iconOffset; | ||
} | ||
function getPxOffset(fixedOffset, fixedSize, stretchOffset, stretchSize) { | ||
function getPxOffset(fixedOffset: number, fixedSize: number, stretchOffset: number, stretchSize: number) { | ||
return fixedOffset - fixedSize * stretchOffset / stretchSize; | ||
@@ -240,3 +242,3 @@ } | ||
function getMidlineOffset(shaping, lineHeight, previousOffset, lineIndex) { | ||
function getMidlineOffset(shaping: Shaping, lineHeight: number, previousOffset: number, lineIndex: number) { | ||
const currentLineHeight = (lineHeight + shaping.positionedLines[lineIndex].lineOffset); | ||
@@ -243,0 +245,0 @@ if (lineIndex === 0) { |
@@ -99,3 +99,3 @@ // @flow | ||
static forText(scale: number | null, fontStack: string) { | ||
static forText(scale: ?number, fontStack: string): SectionOptions { | ||
const textOptions = new SectionOptions(); | ||
@@ -107,3 +107,3 @@ textOptions.scale = scale || 1; | ||
static forImage(imageName: string) { | ||
static forImage(imageName: string): SectionOptions { | ||
const imageOptions = new SectionOptions(); | ||
@@ -129,3 +129,3 @@ imageOptions.imageName = imageName; | ||
static fromFeature(text: Formatted, defaultFontStack: string) { | ||
static fromFeature(text: Formatted, defaultFontStack: string): TaggedString { | ||
const result = new TaggedString(); | ||
@@ -196,3 +196,3 @@ for (let i = 0; i < text.sections.length; i++) { | ||
getMaxScale() { | ||
getMaxScale(): number { | ||
return this.sectionIndex.reduce((max, index) => Math.max(max, this.sections[index].scale), 0); | ||
@@ -199,0 +199,0 @@ } |
@@ -234,3 +234,3 @@ // @flow | ||
const addVerticalShapingIfNeeded = (textJustify) => { | ||
const addVerticalShapingIfNeeded = (textJustify: TextJustify) => { | ||
if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) { | ||
@@ -346,3 +346,3 @@ // Vertical POI label placement is meant to be used for scripts that support vertical | ||
*/ | ||
function tilePixelRatioForSymbolSpacing(overscaleFactor, overscaledZ) { | ||
function tilePixelRatioForSymbolSpacing(overscaleFactor: number, overscaledZ: number) { | ||
if (overscaledZ > 18 && overscaleFactor > 2) { | ||
@@ -416,3 +416,3 @@ overscaleFactor >>= 1; | ||
const addSymbolAtAnchor = (line, anchor, canonicalId) => { | ||
const addSymbolAtAnchor = (line: Array<Point>, anchor: Anchor, canonicalId: CanonicalTileID) => { | ||
if (anchor.x < 0 || anchor.x >= EXTENT || anchor.y < 0 || anchor.y >= EXTENT) { | ||
@@ -419,0 +419,0 @@ // Symbol layers are drawn across tile boundaries, We filter out symbols |
@@ -45,2 +45,3 @@ // @flow | ||
if (expression.kind === 'constant') { | ||
// $FlowFixMe[method-unbinding] | ||
const layoutSize = expression.evaluate(new EvaluationParameters(tileZoom + 1)); | ||
@@ -75,3 +76,5 @@ return {kind: 'constant', layoutSize}; | ||
// evaluated at the covering zoom levels | ||
// $FlowFixMe[method-unbinding] | ||
const minSize = expression.evaluate(new EvaluationParameters(minZoom)); | ||
// $FlowFixMe[method-unbinding] | ||
const maxSize = expression.evaluate(new EvaluationParameters(maxZoom)); | ||
@@ -85,3 +88,3 @@ | ||
{uSize, uSizeT}: InterpolatedSize, | ||
{lowerSize, upperSize}: {+lowerSize: number, +upperSize: number}): number { | ||
{lowerSize, upperSize}: interface {+lowerSize: number, +upperSize: number}): number { | ||
if (sizeData.kind === 'source') { | ||
@@ -88,0 +91,0 @@ return lowerSize / SIZE_PACK_FACTOR; |
@@ -31,2 +31,4 @@ // @flow | ||
import extend from '../style-spec/util/extend.js'; | ||
import type Program from '../render/program.js'; | ||
import type VertexBuffer from "../gl/vertex_buffer.js"; | ||
@@ -152,3 +154,3 @@ export { | ||
const setShaderMode = (mode, isWireframe) => { | ||
const setShaderMode = (mode: number, isWireframe: boolean) => { | ||
if (programMode === mode) return; | ||
@@ -176,2 +178,5 @@ const defines = [shaderDefines[mode], 'PROJECTION_GLOBE_VIEW']; | ||
batches.forEach(isWireframe => { | ||
const tr = painter.transform; | ||
const skirtHeightValue = skirtHeight(tr.zoom) * terrain.exaggeration(); | ||
// This code assumes the rendering is batched into mesh terrain and then wireframe | ||
@@ -213,3 +218,3 @@ // terrain (if applicable) so that this is enough to ensure the correct program is | ||
mercatorCenter, tr.frustumCorners.TL, tr.frustumCorners.TR, tr.frustumCorners.BR, | ||
tr.frustumCorners.BL, tr.globeCenterInViewSpace, tr.globeRadius, viewport, gridMatrix); | ||
tr.frustumCorners.BL, tr.globeCenterInViewSpace, tr.globeRadius, viewport, skirtHeightValue, gridMatrix); | ||
@@ -225,3 +230,3 @@ setShaderMode(shaderMode, isWireframe); | ||
sharedBuffers.getWirefameBuffers(painter.context, latitudinalLod) : | ||
sharedBuffers.getGridBuffers(latitudinalLod); | ||
sharedBuffers.getGridBuffers(latitudinalLod, skirtHeightValue !== 0); | ||
@@ -258,7 +263,7 @@ program.draw(context, primitive, depthMode, stencilMode, colorMode, CullFaceMode.backCCW, | ||
const drawPole = (program, vertexBuffer) => program.draw( | ||
const drawPole = (program: Program<any>, vertexBuffer: VertexBuffer) => program.draw( | ||
context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.disabled, | ||
globeRasterUniformValues(tr.projMatrix, poleMatrix, poleMatrix, normalizeMatrix, 0.0, mercatorCenter, | ||
tr.frustumCorners.TL, tr.frustumCorners.TR, tr.frustumCorners.BR, tr.frustumCorners.BL, | ||
tr.globeCenterInViewSpace, tr.globeRadius, viewport), "globe_pole_raster", vertexBuffer, | ||
tr.globeCenterInViewSpace, tr.globeRadius, viewport, 0), "globe_pole_raster", vertexBuffer, | ||
indexBuffer, segment); | ||
@@ -292,3 +297,3 @@ | ||
const setShaderMode = (mode, isWireframe) => { | ||
const setShaderMode = (mode: number, isWireframe: boolean) => { | ||
if (programMode === mode) | ||
@@ -380,3 +385,3 @@ return; | ||
function skirtHeight(zoom) { | ||
function skirtHeight(zoom: number) { | ||
// Skirt height calculation is heuristic: provided value hides | ||
@@ -383,0 +388,0 @@ // seams between tiles and it is not too large: 9 at zoom 22, ~20000m at zoom 0. |
@@ -76,3 +76,3 @@ // @flow | ||
*/ | ||
getAtPoint(point: MercatorCoordinate, defaultIfNotLoaded: ?number, exaggerated: boolean = true): number | null { | ||
getAtPoint(point: MercatorCoordinate, defaultIfNotLoaded: ?number, exaggerated: boolean = true): ?number { | ||
if (this.isUsingMockSource()) { | ||
@@ -79,0 +79,0 @@ return null; |
@@ -27,2 +27,3 @@ // @flow | ||
'u_grid_matrix': UniformMatrix3f, | ||
'u_skirt_height': Uniform1f, | ||
'u_frustum_tl': Uniform3f, | ||
@@ -65,2 +66,3 @@ 'u_frustum_tr': Uniform3f, | ||
'u_grid_matrix': new UniformMatrix3f(context), | ||
'u_skirt_height': new Uniform1f(context), | ||
'u_frustum_tl': new Uniform3f(context), | ||
@@ -108,2 +110,3 @@ 'u_frustum_tr': new Uniform3f(context), | ||
viewport: [number, number], | ||
skirtHeight: number, | ||
gridMatrix: ?Mat4 | ||
@@ -125,3 +128,4 @@ ): UniformValues<GlobeRasterUniformsType> => ({ | ||
'u_viewport': viewport, | ||
'u_grid_matrix': gridMatrix ? Float32Array.from(gridMatrix) : new Float32Array(9) | ||
'u_grid_matrix': gridMatrix ? Float32Array.from(gridMatrix) : new Float32Array(9), | ||
'u_skirt_height': skirtHeight | ||
}); | ||
@@ -128,0 +132,0 @@ |
// @flow strict | ||
export type Cancelable = { cancel: () => void }; | ||
export type Cancelable = interface { cancel: () => void }; |
@@ -63,2 +63,3 @@ // @flow | ||
this._compactButton.type = 'button'; | ||
// $FlowFixMe[method-unbinding] | ||
this._compactButton.addEventListener('click', this._toggleAttribution); | ||
@@ -76,7 +77,11 @@ this._setElementTitle(this._compactButton, 'ToggleAttribution'); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('styledata', this._updateData); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('sourcedata', this._updateData); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('moveend', this._updateEditLink); | ||
if (compact === undefined) { | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('resize', this._updateCompact); | ||
@@ -92,5 +97,9 @@ this._updateCompact(); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('styledata', this._updateData); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('sourcedata', this._updateData); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('moveend', this._updateEditLink); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('resize', this._updateCompact); | ||
@@ -167,2 +176,3 @@ | ||
if (source.attribution && attributions.indexOf(source.attribution) < 0) { | ||
// $FlowFixMe[incompatible-call] - Flow can't infer that attribution is a string | ||
attributions.push(source.attribution); | ||
@@ -169,0 +179,0 @@ } |
@@ -71,2 +71,3 @@ // @flow | ||
this._map = (null: any); | ||
// $FlowFixMe[method-unbinding] | ||
window.document.removeEventListener(this._fullscreenchange, this._changeIcon); | ||
@@ -87,3 +88,5 @@ } | ||
this._updateTitle(); | ||
// $FlowFixMe[method-unbinding] | ||
this._fullscreenButton.addEventListener('click', this._onClickFullscreen); | ||
// $FlowFixMe[method-unbinding] | ||
window.document.addEventListener(this._fullscreenchange, this._changeIcon); | ||
@@ -126,2 +129,3 @@ } | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
} else if (this._container.requestFullscreen) { | ||
@@ -128,0 +132,0 @@ this._container.requestFullscreen(); |
@@ -129,2 +129,3 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
this._updateMarkerRotationThrottled = throttle(this._updateMarkerRotation, 20); | ||
@@ -137,2 +138,3 @@ this._numberOfWatches = 0; | ||
this._container = DOM.create('div', `mapboxgl-ctrl mapboxgl-ctrl-group`); | ||
// $FlowFixMe[method-unbinding] | ||
this._checkGeolocationSupport(this._setupUI); | ||
@@ -158,2 +160,3 @@ return this._container; | ||
this._container.remove(); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('zoom', this._onZoom); | ||
@@ -166,3 +169,3 @@ this._map = (undefined: any); | ||
_checkGeolocationSupport(callback: boolean => void) { | ||
const updateSupport = (supported = !!this.options.geolocation) => { | ||
const updateSupport = (supported: boolean = !!this.options.geolocation) => { | ||
this._supportsGeolocation = supported; | ||
@@ -469,7 +472,8 @@ callback(supported); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('zoom', this._onZoom); | ||
} | ||
this._geolocateButton.addEventListener('click', | ||
this.trigger.bind(this)); | ||
// $FlowFixMe[method-unbinding] | ||
this._geolocateButton.addEventListener('click', this.trigger.bind(this)); | ||
@@ -644,7 +648,8 @@ this._setup = true; | ||
} else { | ||
this.options.geolocation.getCurrentPosition( | ||
this._onSuccess, this._onError, this.options.positionOptions); | ||
// $FlowFixMe[method-unbinding] | ||
this.options.geolocation.getCurrentPosition(this._onSuccess, this._onError, this.options.positionOptions); | ||
// This timeout ensures that we still call finish() even if | ||
// the user declines to share their location in Firefox | ||
// $FlowFixMe[method-unbinding] | ||
this._timeoutId = setTimeout(this._finish, 10000 /* 10sec */); | ||
@@ -659,4 +664,6 @@ } | ||
if ('ondeviceorientationabsolute' in window) { | ||
// $FlowFixMe[method-unbinding] | ||
window.addEventListener('deviceorientationabsolute', this._onDeviceOrientation); | ||
} else { | ||
// $FlowFixMe[method-unbinding] | ||
window.addEventListener('deviceorientation', this._onDeviceOrientation); | ||
@@ -684,3 +691,5 @@ } | ||
// $FlowFixMe[method-unbinding] | ||
window.removeEventListener('deviceorientation', this._onDeviceOrientation); | ||
// $FlowFixMe[method-unbinding] | ||
window.removeEventListener('deviceorientationabsolute', this._onDeviceOrientation); | ||
@@ -687,0 +696,0 @@ |
@@ -38,5 +38,7 @@ // @flow | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('sourcedata', this._updateLogo); | ||
this._updateLogo(); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('resize', this._updateCompact); | ||
@@ -50,3 +52,5 @@ this._updateCompact(); | ||
this._container.remove(); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('sourcedata', this._updateLogo); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('resize', this._updateCompact); | ||
@@ -53,0 +57,0 @@ } |
@@ -120,2 +120,3 @@ // @flow | ||
this._setButtonTitle(this._zoomOutButton, 'ZoomOut'); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('zoom', this._updateZoomButtons); | ||
@@ -127,4 +128,6 @@ this._updateZoomButtons(); | ||
if (this.options.visualizePitch) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('pitch', this._rotateCompassArrow); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
map.on('rotate', this._rotateCompassArrow); | ||
@@ -142,2 +145,3 @@ this._rotateCompassArrow(); | ||
if (this.options.showZoom) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('zoom', this._updateZoomButtons); | ||
@@ -147,4 +151,6 @@ } | ||
if (this.options.visualizePitch) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('pitch', this._rotateCompassArrow); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
map.off('rotate', this._rotateCompassArrow); | ||
@@ -190,6 +196,11 @@ if (this._handler) this._handler.off(); | ||
bindAll(['mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend', 'reset'], this); | ||
// $FlowFixMe[method-unbinding] | ||
element.addEventListener('mousedown', this.mousedown); | ||
// $FlowFixMe[method-unbinding] | ||
element.addEventListener('touchstart', this.touchstart, {passive: false}); | ||
// $FlowFixMe[method-unbinding] | ||
element.addEventListener('touchmove', this.touchmove); | ||
// $FlowFixMe[method-unbinding] | ||
element.addEventListener('touchend', this.touchend); | ||
// $FlowFixMe[method-unbinding] | ||
element.addEventListener('touchcancel', this.reset); | ||
@@ -218,6 +229,11 @@ } | ||
const element = this.element; | ||
// $FlowFixMe[method-unbinding] | ||
element.removeEventListener('mousedown', this.mousedown); | ||
// $FlowFixMe[method-unbinding] | ||
element.removeEventListener('touchstart', this.touchstart, {passive: false}); | ||
// $FlowFixMe[method-unbinding] | ||
element.removeEventListener('touchmove', this.touchmove); | ||
// $FlowFixMe[method-unbinding] | ||
element.removeEventListener('touchend', this.touchend); | ||
// $FlowFixMe[method-unbinding] | ||
element.removeEventListener('touchcancel', this.reset); | ||
@@ -229,3 +245,5 @@ this.offTemp(); | ||
DOM.enableDrag(); | ||
// $FlowFixMe[method-unbinding] | ||
window.removeEventListener('mousemove', this.mousemove); | ||
// $FlowFixMe[method-unbinding] | ||
window.removeEventListener('mouseup', this.mouseup); | ||
@@ -236,3 +254,5 @@ } | ||
this.down(extend({}, e, {ctrlKey: true, preventDefault: () => e.preventDefault()}), DOM.mousePos(this.element, e)); | ||
// $FlowFixMe[method-unbinding] | ||
window.addEventListener('mousemove', this.mousemove); | ||
// $FlowFixMe[method-unbinding] | ||
window.addEventListener('mouseup', this.mouseup); | ||
@@ -239,0 +259,0 @@ } |
@@ -20,2 +20,10 @@ // @flow | ||
const unitAbbr = { | ||
kilometer: 'km', | ||
meter: 'm', | ||
mile: 'mi', | ||
foot: 'ft', | ||
'nautical-mile': 'nm', | ||
}; | ||
/** | ||
@@ -42,2 +50,3 @@ * A `ScaleControl` control displays the ratio of a distance on the map to the corresponding distance on the ground. | ||
_language: ?string | ?string[]; | ||
_isNumberFormatSupported: boolean; | ||
options: Options; | ||
@@ -48,8 +57,5 @@ | ||
// Some old browsers (e.g., Safari < 14.1) don't support the "unit" style. | ||
// Some old browsers (e.g., Safari < 14.1) don't support the "unit" style in NumberFormat. | ||
// This is a workaround to display the scale without proper internationalization support. | ||
if (!isNumberFormatSupported()) { | ||
// $FlowIgnore[cannot-write] | ||
this._setScale = legacySetScale.bind(this); | ||
} | ||
this._isNumberFormatSupported = isNumberFormatSupported(); | ||
@@ -102,17 +108,14 @@ bindAll([ | ||
_setScale(maxWidth: number, maxDistance: number, unit: string) { | ||
const distance = getRoundNum(maxDistance); | ||
const ratio = distance / maxDistance; | ||
this._map._requestDomTask(() => { | ||
this._container.style.width = `${maxWidth * ratio}px`; | ||
const distance = getRoundNum(maxDistance); | ||
const ratio = distance / maxDistance; | ||
// Intl.NumberFormat doesn't support nautical-mile as a unit, | ||
// so we are hardcoding `nm` as a unit symbol for all locales | ||
if (unit === 'nautical-mile') { | ||
this._container.innerHTML = `${distance} nm`; | ||
return; | ||
if (this._isNumberFormatSupported && unit !== 'nautical-mile') { | ||
// $FlowFixMe[incompatible-call] — flow v0.190.1 doesn't support optional `locales` argument and `unit` style option | ||
this._container.innerHTML = new Intl.NumberFormat(this._language, {style: 'unit', unitDisplay: 'short', unit}).format(distance); | ||
} else { | ||
this._container.innerHTML = `${distance} ${unitAbbr[unit]}`; | ||
} | ||
// $FlowFixMe — flow v0.142.0 doesn't support optional `locales` argument and `unit` style option | ||
this._container.innerHTML = new Intl.NumberFormat(this._language, {style: 'unit', unitDisplay: 'narrow', unit}).format(distance); | ||
this._container.style.width = `${maxWidth * ratio}px`; | ||
}); | ||
@@ -127,2 +130,3 @@ } | ||
// $FlowFixMe[method-unbinding] | ||
this._map.on('move', this._update); | ||
@@ -136,2 +140,3 @@ this._update(); | ||
this._container.remove(); | ||
// $FlowFixMe[method-unbinding] | ||
this._map.off('move', this._update); | ||
@@ -162,3 +167,3 @@ this._map = (undefined: any); | ||
// $FlowIgnore | ||
new Intl.NumberFormat('en', {style: 'unit', unitDisplay: 'narrow', unit: 'meter'}); | ||
new Intl.NumberFormat('en', {style: 'unit', unitDisplay: 'short', unit: 'meter'}); | ||
return true; | ||
@@ -170,21 +175,3 @@ } catch (_) { | ||
function legacySetScale(maxWidth: number, maxDistance: number, unit: string) { | ||
const distance = getRoundNum(maxDistance); | ||
const ratio = distance / maxDistance; | ||
const unitAbbr = { | ||
kilometer: 'km', | ||
meter: 'm', | ||
mile: 'mi', | ||
foot: 'ft', | ||
'nautical-mile': 'nm', | ||
}[unit]; | ||
this._map._requestDomTask(() => { | ||
this._container.style.width = `${maxWidth * ratio}px`; | ||
this._container.innerHTML = `${distance} ${unitAbbr}`; | ||
}); | ||
} | ||
function getDecimalRoundNum(d) { | ||
function getDecimalRoundNum(d: number) { | ||
const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10)); | ||
@@ -194,3 +181,3 @@ return Math.round(d * multiplier) / multiplier; | ||
function getRoundNum(num) { | ||
function getRoundNum(num: number) { | ||
const pow10 = Math.pow(10, (`${Math.floor(num)}`).length - 1); | ||
@@ -197,0 +184,0 @@ let d = num / pow10; |
@@ -1488,6 +1488,17 @@ // @flow | ||
/** | ||
* Fired immediately after all style resources have been downloaded | ||
* and the first visually complete rendering of the base style has occurred. | ||
* | ||
* @event style.load | ||
* @memberof Map | ||
* @instance | ||
* @private | ||
* @example | ||
* // Initialize the map | ||
* const map = new mapboxgl.Map({}); | ||
* // Set an event listener that fires | ||
* // when the map has finished loading. | ||
* map.on('style.load', () => { | ||
* console.log('A style load event occurred.'); | ||
* }); | ||
* @see [Example: Persist layers when switching base style](https://www.mapbox.com/mapbox-gl-js/example/style-switch) | ||
*/ | ||
@@ -1514,2 +1525,29 @@ | 'style.load' | ||
| 'speedindexcompleted' | ||
/** | ||
* Fired after RTL text plugin state changes. | ||
* | ||
* @event pluginStateChange | ||
* @instance | ||
* @private | ||
*/ | ||
| 'pluginStateChange' | ||
/** | ||
* Fired in worker.js after sprite loaded. | ||
* | ||
* @event pluginStateChange | ||
* @instance | ||
* @private | ||
*/ | ||
| 'isSpriteLoaded' | ||
/** | ||
* Fired in style.js after layer order changed. | ||
* | ||
* @event pluginStateChange | ||
* @instance | ||
* @private | ||
*/ | ||
| 'neworder' | ||
; |
@@ -147,4 +147,4 @@ // @flow | ||
const pos: MercatorCoordinate = this.position; | ||
const altitude = this._elevation ? this._elevation.getAtPointOrZero(MercatorCoordinate.fromLngLat(location)) : 0; | ||
const pos: MercatorCoordinate = this.position; | ||
const target = MercatorCoordinate.fromLngLat(location, altitude); | ||
@@ -151,0 +151,0 @@ const forward = [target.x - pos.x, target.y - pos.y, target.z - pos.z]; |
@@ -73,2 +73,6 @@ // @flow | ||
_onMoveEnd(panInertiaOptions?: DragPanOptions): ?(EasingOptions & {easeId?: string}) { | ||
if (this._map._prefersReducedMotion()) { | ||
return; | ||
} | ||
this._drainInertiaBuffer(); | ||
@@ -140,3 +144,3 @@ if (this._inertiaBuffer.length < 2) { | ||
// we need to choose one. We use the longest duration and it's corresponding easing. | ||
function extendDuration(easeOptions, result) { | ||
function extendDuration(easeOptions: EasingOptions, result: {| amount: number, duration: number, easing: (t: number) => number |}) { | ||
if (!easeOptions.duration || easeOptions.duration < result.duration) { | ||
@@ -148,3 +152,3 @@ easeOptions.duration = result.duration; | ||
function calculateEasing(amount, inertiaDuration: number, inertiaOptions) { | ||
function calculateEasing(amount: number, inertiaDuration: number, inertiaOptions: InertiaOptions) { | ||
const {maxSpeed, linearity, deceleration} = inertiaOptions; | ||
@@ -151,0 +155,0 @@ const speed = clamp( |
@@ -32,3 +32,3 @@ // @flow | ||
const isMoving = p => p.zoom || p.drag || p.pitch || p.rotate; | ||
const isMoving = (p: { [string]: any }) => p.zoom || p.drag || p.pitch || p.rotate; | ||
@@ -225,2 +225,3 @@ class RenderFrameEvent extends Event { | ||
for (const [target, type, listenerOptions] of this._listeners) { | ||
// $FlowFixMe[method-unbinding] | ||
const listener = target === window.document ? this.handleWindowEvent : this.handleEvent; | ||
@@ -233,2 +234,3 @@ target.addEventListener((type: any), (listener: any), listenerOptions); | ||
for (const [target, type, listenerOptions] of this._listeners) { | ||
// $FlowFixMe[method-unbinding] | ||
const listener = target === window.document ? this.handleWindowEvent : this.handleEvent; | ||
@@ -242,5 +244,7 @@ target.removeEventListener((type: any), (listener: any), listenerOptions); | ||
const el = map.getCanvasContainer(); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('mapEvent', new MapEventHandler(map, options)); | ||
const boxZoom = map.boxZoom = new BoxZoomHandler(map, options); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('boxZoom', boxZoom); | ||
@@ -251,9 +255,13 @@ | ||
map.doubleClickZoom = new DoubleClickZoomHandler(clickZoom, tapZoom); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('tapZoom', tapZoom); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('clickZoom', clickZoom); | ||
const tapDragZoom = new TapDragZoomHandler(); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('tapDragZoom', tapDragZoom); | ||
const touchPitch = map.touchPitch = new TouchPitchHandler(map); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('touchPitch', touchPitch); | ||
@@ -264,3 +272,5 @@ | ||
map.dragRotate = new DragRotateHandler(options, mouseRotate, mousePitch); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('mouseRotate', mouseRotate, ['mousePitch']); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('mousePitch', mousePitch, ['mouseRotate']); | ||
@@ -271,3 +281,5 @@ | ||
map.dragPan = new DragPanHandler(el, mousePan, touchPan); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('mousePan', mousePan); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('touchPan', touchPan, ['touchZoom', 'touchRotate']); | ||
@@ -278,11 +290,16 @@ | ||
map.touchZoomRotate = new TouchZoomRotateHandler(el, touchZoom, touchRotate, tapDragZoom); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('touchRotate', touchRotate, ['touchPan', 'touchZoom']); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('touchZoom', touchZoom, ['touchPan', 'touchRotate']); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('blockableMapEvent', new BlockableMapEventHandler(map)); | ||
const scrollZoom = map.scrollZoom = new ScrollZoomHandler(map, this); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('scrollZoom', scrollZoom, ['mousePan']); | ||
const keyboard = map.keyboard = new KeyboardHandler(); | ||
// $FlowFixMe[method-unbinding] | ||
this._add('keyboard', keyboard); | ||
@@ -485,3 +502,3 @@ | ||
const eventStarted = (type) => { | ||
const eventStarted = (type: string) => { | ||
const newEvent = combinedEventsInProgress[type]; | ||
@@ -491,3 +508,3 @@ return newEvent && !this._eventsInProgress[type]; | ||
const eventEnded = (type) => { | ||
const eventEnded = (type: string) => { | ||
const event = this._eventsInProgress[type]; | ||
@@ -528,5 +545,5 @@ return event && !this._handlersById[event.handlerName].isActive(); | ||
if (eventStarted("drag") && around) { | ||
if ((zoomDelta || eventStarted("drag")) && around) { | ||
this._dragOrigin = toVec3(tr.pointCoordinate3D(around)); | ||
// Construct the tracking ellipsoid every time user changes the drag origin. | ||
// Construct the tracking ellipsoid every time user changes the zoom or drag origin. | ||
// Direction of the ray will define size of the shape and hence defining the available range of movement | ||
@@ -666,3 +683,3 @@ this._trackingEllipsoid.setup(tr._camera.position, this._dragOrigin); | ||
const shouldSnapToNorth = bearing => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap; | ||
const shouldSnapToNorth = (bearing: number) => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap; | ||
@@ -685,3 +702,3 @@ if (inertialEase) { | ||
_fireEvent(type: string, e: *) { | ||
_fireEvent(type: string, e: any) { | ||
this._map.fire(new Event(type, e ? {originalEvent: e} : {})); | ||
@@ -688,0 +705,0 @@ } |
@@ -178,3 +178,3 @@ // @flow | ||
_fireEvent(type: string, e: *): Map { | ||
_fireEvent(type: string, e: any): Map { | ||
return this._map.fire(new Event(type, {originalEvent: e})); | ||
@@ -181,0 +181,0 @@ } |
@@ -199,2 +199,3 @@ // @flow | ||
// Start a timeout in case this was a singular event, and delay it by up to 40ms. | ||
// $FlowFixMe[method-unbinding] | ||
this._timeout = setTimeout(this._onTimeout, 40, e); | ||
@@ -201,0 +202,0 @@ |
@@ -107,3 +107,3 @@ // @flow | ||
function getZoomDelta(distance, lastDistance) { | ||
function getZoomDelta(distance: number, lastDistance: number) { | ||
return Math.log(distance / lastDistance) / Math.LN2; | ||
@@ -143,3 +143,3 @@ } | ||
function getBearingDelta(a, b) { | ||
function getBearingDelta(a: Point, b: Point) { | ||
return a.angleWith(b) * 180 / Math.PI; | ||
@@ -171,2 +171,3 @@ } | ||
return { | ||
// $FlowFixMe[incompatible-call] - Flow doesn't infer that this._vectoris not null | ||
bearingDelta: getBearingDelta(this._vector, lastVector), | ||
@@ -202,3 +203,3 @@ pinchAround | ||
function isVertical(vector) { | ||
function isVertical(vector: Point) { | ||
return Math.abs(vector.y) > Math.abs(vector.x); | ||
@@ -205,0 +206,0 @@ } |
@@ -29,2 +29,3 @@ // @flow | ||
// Mobile Safari doesn't allow updating the hash more than 100 times per 30 seconds. | ||
// $FlowFixMe[method-unbinding] | ||
this._updateHash = throttle(this._updateHashUnthrottled.bind(this), 30 * 1000 / 100); | ||
@@ -41,2 +42,3 @@ } | ||
this._map = map; | ||
// $FlowFixMe[method-unbinding] | ||
window.addEventListener('hashchange', this._onHashChange, false); | ||
@@ -56,2 +58,3 @@ map.on('moveend', this._updateHash); | ||
this._map.off('moveend', this._updateHash); | ||
// $FlowFixMe[method-unbinding] | ||
window.removeEventListener('hashchange', this._onHashChange, false); | ||
@@ -58,0 +61,0 @@ clearTimeout(this._updateHash()); |
@@ -202,3 +202,5 @@ // @flow | ||
map.on('move', this._updateMoving); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('moveend', this._update); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('remove', this._clearFadeTimer); | ||
@@ -212,2 +214,3 @@ map._addMarker(this); | ||
// `Popup#_onClickClose` listener. | ||
// $FlowFixMe[method-unbinding] | ||
map.on('click', this._onMapClick); | ||
@@ -229,11 +232,20 @@ | ||
if (map) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('click', this._onMapClick); | ||
map.off('move', this._updateMoving); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('moveend', this._update); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousedown', this._addDragHandler); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('touchstart', this._addDragHandler); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mouseup', this._onUp); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('touchend', this._onUp); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousemove', this._onMove); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('touchmove', this._onMove); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('remove', this._clearFadeTimer); | ||
@@ -319,2 +331,3 @@ map._removeMarker(this); | ||
this._element.removeAttribute('role'); | ||
// $FlowFixMe[method-unbinding] | ||
this._element.removeEventListener('keypress', this._onKeyPress); | ||
@@ -352,2 +365,3 @@ | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
this._element.addEventListener('keypress', this._onKeyPress); | ||
@@ -586,2 +600,3 @@ this._element.setAttribute('aria-expanded', 'false'); | ||
if ((map._showingGlobe() || map.getTerrain() || map.getFog()) && !this._fadeTimer) { | ||
// $FlowFixMe[method-unbinding] | ||
this._fadeTimer = setTimeout(this._evaluateOpacity.bind(this), 60); | ||
@@ -676,3 +691,5 @@ } | ||
if (map) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousemove', this._onMove); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('touchmove', this._onMove); | ||
@@ -716,5 +733,9 @@ } | ||
this._state = 'pending'; | ||
// $FlowFixMe[method-unbinding] | ||
map.on('mousemove', this._onMove); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('touchmove', this._onMove); | ||
// $FlowFixMe[method-unbinding] | ||
map.once('mouseup', this._onUp); | ||
// $FlowFixMe[method-unbinding] | ||
map.once('touchend', this._onUp); | ||
@@ -740,6 +761,10 @@ } | ||
if (shouldBeDraggable) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('mousedown', this._addDragHandler); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('touchstart', this._addDragHandler); | ||
} else { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousedown', this._addDragHandler); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('touchstart', this._addDragHandler); | ||
@@ -746,0 +771,0 @@ } |
@@ -146,2 +146,3 @@ // @flow | ||
if (this.options.closeOnClick) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('preclick', this._onClose); | ||
@@ -151,5 +152,7 @@ } | ||
if (this.options.closeOnMove) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('move', this._onClose); | ||
} | ||
// $FlowFixMe[method-unbinding] | ||
map.on('remove', this.remove); | ||
@@ -161,6 +164,9 @@ this._update(); | ||
if (this._trackPointer) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('mousemove', this._onMouseEvent); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('mouseup', this._onMouseEvent); | ||
map._canvasContainer.classList.add('mapboxgl-track-pointer'); | ||
} else { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('move', this._update); | ||
@@ -224,9 +230,17 @@ } | ||
if (map) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('move', this._update); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('move', this._onClose); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('preclick', this._onClose); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('click', this._onClose); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('remove', this.remove); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousemove', this._onMouseEvent); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mouseup', this._onMouseEvent); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('drag', this._onMouseEvent); | ||
@@ -297,3 +311,5 @@ if (map._canvasContainer) { | ||
if (map) { | ||
// $FlowFixMe[method-unbinding] | ||
map.on('move', this._update); | ||
// $FlowFixMe[method-unbinding] | ||
map.off('mousemove', this._onMouseEvent); | ||
@@ -323,4 +339,7 @@ map._canvasContainer.classList.remove('mapboxgl-track-pointer'); | ||
if (map) { | ||
// $FlowFixMe[method-unbinding] | ||
map.off('move', this._update); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('mousemove', this._onMouseEvent); | ||
// $FlowFixMe[method-unbinding] | ||
map.on('drag', this._onMouseEvent); | ||
@@ -465,2 +484,3 @@ map._canvasContainer.classList.add('mapboxgl-track-pointer'); | ||
button.innerHTML = '×'; | ||
// $FlowFixMe[method-unbinding] | ||
button.addEventListener('click', this._onClose); | ||
@@ -467,0 +487,0 @@ } |
@@ -39,2 +39,3 @@ // @flow | ||
bindAll(['receive'], this); | ||
// $FlowFixMe[method-unbinding] | ||
this.target.addEventListener('message', this.receive, false); | ||
@@ -144,3 +145,3 @@ this.globalScope = isWorker() ? target : window; | ||
const buffers: ?Array<Transferable> = isSafari(this.globalScope) ? undefined : []; | ||
const done = task.hasCallback ? (err, data) => { | ||
const done = task.hasCallback ? (err: ?Error, data: mixed) => { | ||
delete this.cancelCallbacks[id]; | ||
@@ -175,2 +176,3 @@ this.target.postMessage({ | ||
this.scheduler.remove(); | ||
// $FlowFixMe[method-unbinding] | ||
this.target.removeEventListener('message', this.receive, false); | ||
@@ -177,0 +179,0 @@ } |
@@ -46,2 +46,3 @@ // @flow | ||
* @property {boolean} collectResourceTiming If true, Resource Timing API information will be collected for these transformed requests and returned in a resourceTiming property of relevant data events. | ||
* @property {string} referrerPolicy A string representing the request's referrerPolicy. For more information and possible values, see the [Referrer-Policy HTTP header page](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy). | ||
* @example | ||
@@ -71,4 +72,5 @@ * // use transformRequest to modify requests that begin with `http://myHost` | ||
credentials?: 'same-origin' | 'include', | ||
collectResourceTiming?: boolean | ||
}; | ||
collectResourceTiming?: boolean, | ||
referrerPolicy?: ReferrerPolicyType | ||
} | ||
@@ -106,3 +108,3 @@ export type ResponseCallback<T> = (error: ?Error, data: ?T, cacheControl: ?string, expires: ?string) => void; | ||
// via a file:// URL. | ||
const isFileURL = url => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\w+:/.test(url)); | ||
const isFileURL = (url: string) => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\w+:/.test(url)); | ||
@@ -117,2 +119,3 @@ function makeFetchRequest(requestParameters: RequestParameters, callback: ResponseCallback<any>): Cancelable { | ||
referrer: getReferrer(), | ||
referrerPolicy: requestParameters.referrerPolicy, | ||
signal: controller.signal | ||
@@ -129,3 +132,3 @@ }); | ||
const validateOrFetch = (err, cachedResponse, responseIsFresh) => { | ||
const validateOrFetch = (err: ?Error, cachedResponse: ?Response, responseIsFresh: ?boolean) => { | ||
if (aborted) return; | ||
@@ -137,3 +140,3 @@ | ||
if (err.message !== 'SecurityError') { | ||
warnOnce(err); | ||
warnOnce(err.toString()); | ||
} | ||
@@ -157,3 +160,2 @@ } | ||
return finishRequest(response, cacheableResponse, requestTime); | ||
} else { | ||
@@ -163,11 +165,11 @@ return callback(new AJAXError(response.statusText, response.status, requestParameters.url)); | ||
}).catch(error => { | ||
if (error.code === 20) { | ||
if (error.name === 'AbortError') { | ||
// silence expected AbortError | ||
return; | ||
} | ||
callback(new Error(error.message)); | ||
callback(new Error(`${error.message} ${requestParameters.url}`)); | ||
}); | ||
}; | ||
const finishRequest = (response, cacheableResponse, requestTime) => { | ||
const finishRequest = (response: Response, cacheableResponse: ?Response, requestTime: ?number) => { | ||
( | ||
@@ -279,3 +281,3 @@ requestParameters.type === 'arrayBuffer' ? response.arrayBuffer() : | ||
function sameOrigin(url) { | ||
function sameOrigin(url: string) { | ||
const a: HTMLAnchorElement = window.document.createElement('a'); | ||
@@ -335,2 +337,3 @@ a.href = url; | ||
cancelled: false, | ||
// $FlowFixMe[object-this-reference] | ||
cancel() { this.cancelled = true; } | ||
@@ -353,2 +356,3 @@ }; | ||
if (!cancelled) { | ||
// $FlowFixMe[cannot-write] - Flow can't infer that cancel is a writable property | ||
request.cancel = getImage(requestParameters, callback).cancel; | ||
@@ -355,0 +359,0 @@ } |
@@ -10,3 +10,3 @@ // @flow strict | ||
let stubTime; | ||
let stubTime: number | void; | ||
@@ -13,0 +13,0 @@ let canvas; |
@@ -50,4 +50,4 @@ // @flow | ||
function compareAreas(a, b) { | ||
function compareAreas(a: {area: number}, b: {area: number}) { | ||
return b.area - a.area; | ||
} |
@@ -31,3 +31,3 @@ // @flow | ||
const renderPixel = (stride, index, progress) => { | ||
const renderPixel = (stride: number, index: number, progress: number) => { | ||
evaluationGlobals[params.evaluationKey] = progress; | ||
@@ -34,0 +34,0 @@ const pxColor = params.expression.evaluate((evaluationGlobals: any)); |
@@ -57,8 +57,13 @@ // @flow strict | ||
get EVENTS_URL() { | ||
if (!this.API_URL) { return null; } | ||
if (this.API_URL.indexOf('https://api.mapbox.cn') === 0) { | ||
return 'https://events.mapbox.cn/events/v2'; | ||
} else if (this.API_URL.indexOf('https://api.mapbox.com') === 0) { | ||
return 'https://events.mapbox.com/events/v2'; | ||
} else { | ||
if (!config.API_URL) { return null; } | ||
try { | ||
const url = new URL(config.API_URL); | ||
if (url.hostname === 'api.mapbox.cn') { | ||
return 'https://events.mapbox.cn/events/v2'; | ||
} else if (url.hostname === 'api.mapbox.com') { | ||
return 'https://events.mapbox.com/events/v2'; | ||
} else { | ||
return null; | ||
} | ||
} catch (e) { | ||
return null; | ||
@@ -65,0 +70,0 @@ } |
@@ -26,3 +26,7 @@ // @flow | ||
drawAabbs: Function, | ||
clearAabbs: Function | ||
clearAabbs: Function, | ||
_drawBox: Function, | ||
_drawLine: Function, | ||
_drawQuad: Function, | ||
_initializeCanvas: Function, | ||
} = | ||
@@ -51,14 +55,17 @@ { | ||
_initializeCanvas(tr: Transform) { | ||
if (!this.debugCanvas) { | ||
this.debugCanvas = window.document.createElement('canvas'); | ||
window.document.body.appendChild(this.debugCanvas); | ||
this.debugCanvas.style.position = 'absolute'; | ||
this.debugCanvas.style.left = 0; | ||
this.debugCanvas.style.top = 0; | ||
this.debugCanvas.style.pointerEvents = 'none'; | ||
if (!Debug.debugCanvas) { | ||
Debug.debugCanvas = window.document.createElement('canvas'); | ||
window.document.body.appendChild(Debug.debugCanvas); | ||
// Supress Flow check because we're checking for null above | ||
if (!Debug.debugCanvas) return; | ||
Debug.debugCanvas.style.position = 'absolute'; | ||
Debug.debugCanvas.style.left = '0'; | ||
Debug.debugCanvas.style.top = '0'; | ||
Debug.debugCanvas.style.pointerEvents = 'none'; | ||
const resize = () => { | ||
if (!this.debugCanvas) { return; } | ||
this.debugCanvas.width = tr.width; | ||
this.debugCanvas.height = tr.height; | ||
if (!Debug.debugCanvas) { return; } | ||
Debug.debugCanvas.width = tr.width; | ||
Debug.debugCanvas.height = tr.height; | ||
}; | ||
@@ -69,3 +76,3 @@ resize(); | ||
} | ||
return this.debugCanvas; | ||
return Debug.debugCanvas; | ||
}, | ||
@@ -80,6 +87,6 @@ | ||
_drawQuad(ctx: CanvasRenderingContext2D, corners: Array<?Vec2>) { | ||
this._drawLine(ctx, corners[0], corners[1]); | ||
this._drawLine(ctx, corners[1], corners[2]); | ||
this._drawLine(ctx, corners[2], corners[3]); | ||
this._drawLine(ctx, corners[3], corners[0]); | ||
Debug._drawLine(ctx, corners[0], corners[1]); | ||
Debug._drawLine(ctx, corners[1], corners[2]); | ||
Debug._drawLine(ctx, corners[2], corners[3]); | ||
Debug._drawLine(ctx, corners[3], corners[0]); | ||
}, | ||
@@ -90,8 +97,8 @@ | ||
ctx.beginPath(); | ||
this._drawQuad(ctx, corners.slice(0, 4)); | ||
this._drawQuad(ctx, corners.slice(4)); | ||
this._drawLine(ctx, corners[0], corners[4]); | ||
this._drawLine(ctx, corners[1], corners[5]); | ||
this._drawLine(ctx, corners[2], corners[6]); | ||
this._drawLine(ctx, corners[3], corners[7]); | ||
Debug._drawQuad(ctx, corners.slice(0, 4)); | ||
Debug._drawQuad(ctx, corners.slice(4)); | ||
Debug._drawLine(ctx, corners[0], corners[4]); | ||
Debug._drawLine(ctx, corners[1], corners[5]); | ||
Debug._drawLine(ctx, corners[2], corners[6]); | ||
Debug._drawLine(ctx, corners[3], corners[7]); | ||
ctx.stroke(); | ||
@@ -108,3 +115,3 @@ }, | ||
if (!tr.freezeTileCoverage) { | ||
this.aabbCorners = coords.map(coord => { | ||
Debug.aabbCorners = coords.map(coord => { | ||
// Get tile AABBs in world/pixel space scaled by worldSize | ||
@@ -118,2 +125,3 @@ const aabb = aabbForTileOnGlobe(tr, tr.worldSize, coord.canonical); | ||
} | ||
// $FlowFixMe[incompatible-type] | ||
return corners; | ||
@@ -123,7 +131,7 @@ }); | ||
const canvas = this._initializeCanvas(tr); | ||
const canvas = Debug._initializeCanvas(tr); | ||
const ctx = canvas.getContext('2d'); | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
const tileCount = this.aabbCorners.length; | ||
const tileCount = Debug.aabbCorners.length; | ||
ctx.shadowColor = '#000'; | ||
@@ -134,3 +142,3 @@ ctx.shadowBlur = 2; | ||
for (let i = 0; i < tileCount; i++) { | ||
const pixelCorners = this.aabbCorners[i].map(ecef => { | ||
const pixelCorners = Debug.aabbCorners[i].map(ecef => { | ||
// Clipping to prevent visual artifacts. | ||
@@ -141,8 +149,13 @@ // We don't draw any lines if one of their points is behind the camera. | ||
// Full AABBs can be viewed by enabling `map.transform.freezeTileCoverage` and panning. | ||
// $FlowFixMe[incompatible-call] | ||
const cameraPos = vec3.transformMat4([], ecef, ecefToCameraMatrix); | ||
// $FlowFixMe[incompatible-call] | ||
if (cameraPos[2] > 0) { return null; } | ||
// $FlowFixMe[incompatible-call] | ||
return vec3.transformMat4([], ecef, ecefToPixelMatrix); | ||
}); | ||
ctx.strokeStyle = `hsl(${360 * i / tileCount}, 100%, 50%)`; | ||
this._drawBox(ctx, pixelCorners); | ||
Debug._drawBox(ctx, pixelCorners); | ||
} | ||
@@ -152,7 +165,7 @@ }, | ||
clearAabbs() { | ||
if (!this.debugCanvas) { return; } | ||
this.debugCanvas.getContext('2d').clearRect(0, 0, this.debugCanvas.width, this.debugCanvas.height); | ||
this.aabbCorners = []; | ||
if (!Debug.debugCanvas) return; | ||
// $FlowFixMe[incompatible-use] - Flow doesn't know that debugCanvas is non-null here | ||
Debug.debugCanvas.getContext('2d').clearRect(0, 0, Debug.debugCanvas.width, Debug.debugCanvas.height); | ||
Debug.aabbCorners = []; | ||
} | ||
}; |
@@ -9,2 +9,3 @@ // @flow strict | ||
// refine the return type based on tagName, e.g. 'button' -> HTMLButtonElement | ||
// $FlowFixMe[method-unbinding] | ||
export function create<T: string>(tagName: T, className: ?string, container?: HTMLElement): $Call<typeof document.createElement, T> { | ||
@@ -44,3 +45,3 @@ const el = window.document.createElement(tagName); | ||
// Suppress the next click, but only if it's immediate. | ||
function suppressClickListener(e) { | ||
function suppressClickListener(e: Event) { | ||
e.preventDefault(); | ||
@@ -47,0 +48,0 @@ e.stopPropagation(); |
// @flow | ||
import {extend} from './util.js'; | ||
import type {MapEvent} from '../ui/events.js'; | ||
@@ -70,3 +71,3 @@ type Listener = (Object) => any; | ||
*/ | ||
on(type: *, listener: Listener): this { | ||
on(type: MapEvent, listener: Listener): this { | ||
this._listeners = this._listeners || {}; | ||
@@ -85,3 +86,3 @@ _addEventListener(type, listener, this._listeners); | ||
*/ | ||
off(type: *, listener: Listener): this { | ||
off(type: MapEvent, listener: Listener): this { | ||
_removeEventListener(type, listener, this._listeners); | ||
@@ -103,3 +104,3 @@ _removeEventListener(type, listener, this._oneTimeListeners); | ||
*/ | ||
once(type: *, listener?: Listener): this | Promise<Event> { | ||
once(type: MapEvent, listener?: Listener): this | Promise<Event> { | ||
if (!listener) { | ||
@@ -106,0 +107,0 @@ return new Promise(resolve => this.once(type, resolve)); |
@@ -81,15 +81,22 @@ // @flow | ||
function compareMax(a, b) { | ||
function compareMax(a: Cell, b: Cell) { | ||
return b.max - a.max; | ||
} | ||
function Cell(x, y, h, polygon) { | ||
this.p = new Point(x, y); | ||
this.h = h; // half the cell size | ||
this.d = pointToPolygonDist(this.p, polygon); // distance from cell center to polygon | ||
this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell | ||
class Cell { | ||
p: Point; | ||
h: number; | ||
d: number; | ||
max: number; | ||
constructor(x: number, y: number, h: number, polygon: Array<Array<Point>>) { | ||
this.p = new Point(x, y); | ||
this.h = h; // half the cell size | ||
this.d = pointToPolygonDist(this.p, polygon); // distance from cell center to polygon | ||
this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell | ||
} | ||
} | ||
// signed distance from point to polygon outline (negative if point is outside) | ||
function pointToPolygonDist(p, polygon) { | ||
function pointToPolygonDist(p: Point, polygon: Array<Array<Point>>) { | ||
let inside = false; | ||
@@ -116,3 +123,3 @@ let minDistSq = Infinity; | ||
// get polygon centroid | ||
function getCentroidCell(polygon) { | ||
function getCentroidCell(polygon: Array<Array<Point>>) { | ||
let area = 0; | ||
@@ -119,0 +126,0 @@ let x = 0; |
@@ -5,3 +5,3 @@ // @flow | ||
let globalWorkerPool; | ||
let globalWorkerPool: ?WorkerPool; | ||
@@ -8,0 +8,0 @@ /** |
@@ -7,5 +7,5 @@ // @flow | ||
export type Size = { | ||
export type Size = interface { | ||
width: number, | ||
height: number | ||
height: number, | ||
}; | ||
@@ -12,0 +12,0 @@ |
@@ -47,3 +47,3 @@ // @flow | ||
function categorize(arr, fn) { | ||
function categorize(arr: Array<PerformanceResourceTiming>, fn: (entry: PerformanceResourceTiming) => string): {[string]: Array<PerformanceResourceTiming>} { | ||
const obj = {}; | ||
@@ -62,3 +62,3 @@ if (arr) { | ||
function getCountersPerResourceType(resourceTimers) { | ||
function getCountersPerResourceType(resourceTimers: { [string]: Array<PerformanceResourceTiming> }) { | ||
const obj = {}; | ||
@@ -79,3 +79,3 @@ if (resourceTimers) { | ||
const increment = (key) => { | ||
const increment = (key: string) => { | ||
if (obj[key] === undefined) { | ||
@@ -140,3 +140,3 @@ obj[key] = 0; | ||
// https://github.com/mapbox/gl-js-team/blob/main/docs/live_performance_metrics.md | ||
const addMetric = (arr, name, value) => { | ||
const addMetric = (arr: Array<{| name: string, value: string |}>, name: string, value: ?(number | string)) => { | ||
if (value !== undefined && value !== null) { | ||
@@ -143,0 +143,0 @@ arr.push({name, value: value.toString()}); |
@@ -644,11 +644,15 @@ // @flow | ||
const turnstileEvent_ = new TurnstileEvent(); | ||
// $FlowFixMe[method-unbinding] | ||
export const postTurnstileEvent: (tileUrls: Array<string>, customAccessToken?: ?string) => void = turnstileEvent_.postTurnstileEvent.bind(turnstileEvent_); | ||
const mapLoadEvent_ = new MapLoadEvent(); | ||
// $FlowFixMe[method-unbinding] | ||
export const postMapLoadEvent: (number, string, ?string, EventCallback) => void = mapLoadEvent_.postMapLoadEvent.bind(mapLoadEvent_); | ||
export const performanceEvent_: PerformanceEvent = new PerformanceEvent(); | ||
// $FlowFixMe[method-unbinding] | ||
export const postPerformanceEvent: (?string, LivePerformanceData) => void = performanceEvent_.postPerformanceEvent.bind(performanceEvent_); | ||
const mapSessionAPI_ = new MapSessionAPI(); | ||
// $FlowFixMe[method-unbinding] | ||
export const getMapSessionAPI: (number, string, ?string, EventCallback) => void = mapSessionAPI_.getSessionAPI.bind(mapSessionAPI_); | ||
@@ -655,0 +659,0 @@ |
@@ -14,6 +14,6 @@ // @flow | ||
function clipPolygon(polygons: PolygonArray, clipAxis1: number, clipAxis2: number, axis: number): PolygonArray { | ||
const intersectX = (ring, ax, ay, bx, by, x) => { | ||
const intersectX = (ring: Array<Point>, ax: number, ay: number, bx: number, by: number, x: number) => { | ||
ring.push(new Point(x, ay + (by - ay) * ((x - ax) / (bx - ax)))); | ||
}; | ||
const intersectY = (ring, ax, ay, bx, by, y) => { | ||
const intersectY = (ring: Array<Point>, ax: number, ay: number, bx: number, by: number, y: number) => { | ||
ring.push(new Point(ax + (bx - ax) * ((y - ay) / (by - ay)), y)); | ||
@@ -86,3 +86,3 @@ }; | ||
const addResult = (clipped, bounds) => { | ||
const addResult = (clipped: PolygonArray, bounds: [Point, Point]) => { | ||
for (const polygon of clipped) { | ||
@@ -89,0 +89,0 @@ outPolygons.push({polygon, bounds}); |
@@ -35,2 +35,3 @@ // @flow | ||
bindAll(['process'], this); | ||
// $FlowFixMe[method-unbinding] | ||
this.invoker = new ThrottledInvoker(this.process); | ||
@@ -37,0 +38,0 @@ |
@@ -138,3 +138,3 @@ // @flow | ||
// $FlowFixMe not-an-object - newer Flow doesn't understand this pattern, silence for now | ||
const structArray = Object.create(this.prototype); | ||
const structArray: {[_: string]: any} = Object.create(this.prototype); | ||
structArray.arrayBuffer = input.arrayBuffer; | ||
@@ -196,3 +196,3 @@ structArray.length = input.length; | ||
*/ | ||
_refreshViews() { | ||
_refreshViews(): void { | ||
throw new Error('_refreshViews() must be implemented by each concrete StructArray layout'); | ||
@@ -199,0 +199,0 @@ } |
@@ -49,3 +49,3 @@ // @flow | ||
let responseConstructorSupportsReadableStream; | ||
function prepareBody(response: Response, callback) { | ||
function prepareBody(response: Response, callback: ((body: ?(Blob | ReadableStream)) => void)) { | ||
if (responseConstructorSupportsReadableStream === undefined) { | ||
@@ -132,3 +132,3 @@ try { | ||
sharedCache | ||
((sharedCache: any): Promise<Cache>) | ||
.then(cache => { | ||
@@ -156,3 +156,3 @@ // manually strip URL instead of `ignoreSearch: true` because of a known | ||
function isFresh(response) { | ||
function isFresh(response: Response) { | ||
if (!response) return false; | ||
@@ -159,0 +159,0 @@ const expires = new Date(response.headers.get('Expires') || 0); |
@@ -378,3 +378,3 @@ // @flow | ||
export function uuid(): string { | ||
function b(a) { | ||
function b(a: void) { | ||
return a ? (a ^ Math.random() * (16 >> a / 4)).toString(16) : | ||
@@ -466,2 +466,3 @@ //$FlowFixMe: Flow doesn't like the implied array literal conversion here | ||
*/ | ||
// $FlowFixMe[missing-this-annot] | ||
export function mapObject(input: Object, iterator: Function, context?: Object): Object { | ||
@@ -480,2 +481,3 @@ const output = {}; | ||
*/ | ||
// $FlowFixMe[missing-this-annot] | ||
export function filterObject(input: Object, iterator: Function, context?: Object): Object { | ||
@@ -482,0 +484,0 @@ const output = {}; |
// @flow | ||
import type {LayerSpecification} from '../style-spec/types.js'; | ||
import type {LayerSpecification, SourceSpecification} from '../style-spec/types.js'; | ||
import type {GeoJSONGeometry, GeoJSONFeature} from '@mapbox/geojson-types'; | ||
@@ -7,6 +7,9 @@ import type {IVectorTileFeature} from '@mapbox/vector-tile'; | ||
// we augment GeoJSON with custom properties in query*Features results | ||
export type QueryFeature = $ReadOnly<GeoJSONFeature> & { | ||
export interface QueryFeature extends GeoJSONFeature { | ||
layer?: ?LayerSpecification; | ||
source?: ?SourceSpecification | ?mixed; | ||
sourceLayer?: ?string | ?mixed; | ||
state: ?mixed; | ||
[key: string]: mixed; | ||
}; | ||
} | ||
@@ -18,3 +21,3 @@ const customProps = ['tile', 'layer', 'source', 'sourceLayer', 'state']; | ||
_geometry: ?GeoJSONGeometry; | ||
properties: {}; | ||
properties: ?{}; | ||
id: number | string | void; | ||
@@ -58,2 +61,3 @@ _vectorTileFeature: IVectorTileFeature; | ||
type: 'Feature', | ||
state: undefined, | ||
geometry: this.geometry, | ||
@@ -60,0 +64,0 @@ properties: this.properties |
@@ -88,3 +88,5 @@ // @flow | ||
'「': '﹁', | ||
'」': '﹂' | ||
'」': '﹂', | ||
'←': '↑', | ||
'→': '↓' | ||
}; | ||
@@ -91,0 +93,0 @@ |
@@ -16,3 +16,3 @@ // @flow | ||
type SerializedObject = {[_: string]: Serialized }; // eslint-disable-line | ||
type SerializedObject = interface { [_: string]: Serialized }; | ||
export type Serialized = | ||
@@ -198,3 +198,3 @@ | null | ||
if (input instanceof Error) { | ||
properties.message = input.message; | ||
properties['message'] = input.message; | ||
} | ||
@@ -206,7 +206,7 @@ } else { | ||
if (properties.$name) { | ||
if (properties['$name']) { | ||
throw new Error('$name property is reserved for worker serialization logic.'); | ||
} | ||
if (name !== 'Object') { | ||
properties.$name = name; | ||
properties['$name'] = name; | ||
} | ||
@@ -254,5 +254,6 @@ | ||
const result = Object.create(klass.prototype); | ||
const result: {[_: string]: any} = Object.create(klass.prototype); | ||
for (const key of Object.keys(input)) { | ||
// $FlowFixMe[incompatible-type] | ||
if (key === '$name') continue; | ||
@@ -259,0 +260,0 @@ const value = (input: SerializedObject)[key]; |
@@ -27,4 +27,4 @@ // @flow | ||
registerWorkerSource: (string, Class<WorkerSource>) => void, | ||
registerRTLTextPlugin: (_: any) => void | ||
registerWorkerSource?: (string, Class<WorkerSource>) => void, | ||
registerRTLTextPlugin?: (_: any) => void | ||
} | ||
@@ -36,4 +36,4 @@ | ||
target: MessageBus; | ||
registerWorkerSource: *; | ||
registerRTLTextPlugin: *; | ||
registerWorkerSource: any; | ||
registerRTLTextPlugin: any; | ||
@@ -40,0 +40,0 @@ constructor(addListeners: Array<MessageListener>, postListeners: Array<MessageListener>) { |
@@ -58,2 +58,3 @@ // @flow strict | ||
const originalGetContext = window.HTMLCanvasElement.prototype.getContext; | ||
// $FlowFixMe[missing-this-annot] | ||
window.HTMLCanvasElement.prototype.getContext = function (type, attributes) { | ||
@@ -70,2 +71,3 @@ if (type === 'webgl') { | ||
// $FlowFixMe[missing-this-annot] | ||
window.useFakeHTMLCanvasGetContext = function() { | ||
@@ -75,2 +77,3 @@ this.HTMLCanvasElement.prototype.getContext = function() { return '2d'; }; | ||
// $FlowFixMe[missing-this-annot] | ||
window.useFakeXMLHttpRequest = function() { | ||
@@ -86,2 +89,3 @@ sinon.xhr.supportsCORS = true; | ||
global.WorkerGlobalScope = function() {}; | ||
// $FlowFixMe[invalid-constructor] | ||
global.self = new global.WorkerGlobalScope(); | ||
@@ -88,0 +92,0 @@ }; |
@@ -17,3 +17,3 @@ // @flow | ||
const metrics = PerformanceUtils.getPerformanceMetrics(); | ||
const dispatcher = new Dispatcher(getWorkerPool(), this); | ||
const dispatcher = new Dispatcher(getWorkerPool(), WorkerPerformanceUtils); | ||
@@ -20,0 +20,0 @@ const createTime = performance.getEntriesByName('create', 'mark')[0].startTime; |
@@ -28,2 +28,3 @@ // @flow | ||
while (this.workers.length < WorkerPool.workerCount) { | ||
// $FlowFixMe[invalid-constructor] | ||
this.workers.push(new WebWorker()); | ||
@@ -30,0 +31,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42793006
536
217424
228
2
1
22
37
24
+ Addedkdbush@^4.0.1
+ Addedkdbush@4.0.2(transitive)
+ Addedsupercluster@8.0.1(transitive)
- Removedkdbush@3.0.0(transitive)
- Removedsupercluster@7.1.5(transitive)
Updated@mapbox/tiny-sdf@^2.0.6
Updatedsupercluster@^8.0.0