Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mapbox-gl

Package Overview
Dependencies
Maintainers
28
Versions
228
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mapbox-gl - npm Package Compare versions

Comparing version 2.12.0 to 2.15.0

flow-typed/kdbush.js

8

build/generate-struct-arrays.js

@@ -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}&nbsp;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}&nbsp;${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}&nbsp;${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 = '&#215;';
// $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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc