/* Mapbox GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/mapbox/mapbox-gl-js/blob/v1.13.3/LICENSE.txt */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.mapboxgl = factory()); }(this, (function () { 'use strict'; /* eslint-disable */ var shared, worker, mapboxgl; // define gets called three times: one for each chunk. we rely on the order // they're imported to know which is which function define(_, chunk) { if (!shared) { shared = chunk; } else if (!worker) { worker = chunk; } else { var workerBundleString = 'var sharedChunk = {}; (' + shared + ')(sharedChunk); (' + worker + ')(sharedChunk);' var sharedChunk = {}; shared(sharedChunk); mapboxgl = chunk(sharedChunk); if (typeof window !== 'undefined') { mapboxgl.workerUrl = window.URL.createObjectURL(new Blob([workerBundleString], { type: 'text/javascript' })); } } } define(['exports'], function (exports) { 'use strict'; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var version = "1.13.3"; var unitbezier = UnitBezier; function UnitBezier(p1x, p1y, p2x, p2y) { this.cx = 3 * p1x; this.bx = 3 * (p2x - p1x) - this.cx; this.ax = 1 - this.cx - this.bx; this.cy = 3 * p1y; this.by = 3 * (p2y - p1y) - this.cy; this.ay = 1 - this.cy - this.by; this.p1x = p1x; this.p1y = p2y; this.p2x = p2x; this.p2y = p2y; } UnitBezier.prototype.sampleCurveX = function (t) { return ((this.ax * t + this.bx) * t + this.cx) * t; }; UnitBezier.prototype.sampleCurveY = function (t) { return ((this.ay * t + this.by) * t + this.cy) * t; }; UnitBezier.prototype.sampleCurveDerivativeX = function (t) { return (3 * this.ax * t + 2 * this.bx) * t + this.cx; }; UnitBezier.prototype.solveCurveX = function (x, epsilon) { if (typeof epsilon === 'undefined') { epsilon = 0.000001; } var t0, t1, t2, x2, i; for (t2 = x, i = 0; i < 8; i++) { x2 = this.sampleCurveX(t2) - x; if (Math.abs(x2) < epsilon) { return t2; } var d2 = this.sampleCurveDerivativeX(t2); if (Math.abs(d2) < 0.000001) { break; } t2 = t2 - x2 / d2; } t0 = 0; t1 = 1; t2 = x; if (t2 < t0) { return t0; } if (t2 > t1) { return t1; } while (t0 < t1) { x2 = this.sampleCurveX(t2); if (Math.abs(x2 - x) < epsilon) { return t2; } if (x > x2) { t0 = t2; } else { t1 = t2; } t2 = (t1 - t0) * 0.5 + t0; } return t2; }; UnitBezier.prototype.solve = function (x, epsilon) { return this.sampleCurveY(this.solveCurveX(x, epsilon)); }; var pointGeometry = Point; function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { clone: function () { return new Point(this.x, this.y); }, add: function (p) { return this.clone()._add(p); }, sub: function (p) { return this.clone()._sub(p); }, multByPoint: function (p) { return this.clone()._multByPoint(p); }, divByPoint: function (p) { return this.clone()._divByPoint(p); }, mult: function (k) { return this.clone()._mult(k); }, div: function (k) { return this.clone()._div(k); }, rotate: function (a) { return this.clone()._rotate(a); }, rotateAround: function (a, p) { return this.clone()._rotateAround(a, p); }, matMult: function (m) { return this.clone()._matMult(m); }, unit: function () { return this.clone()._unit(); }, perp: function () { return this.clone()._perp(); }, round: function () { return this.clone()._round(); }, mag: function () { return Math.sqrt(this.x * this.x + this.y * this.y); }, equals: function (other) { return this.x === other.x && this.y === other.y; }, dist: function (p) { return Math.sqrt(this.distSqr(p)); }, distSqr: function (p) { var dx = p.x - this.x, dy = p.y - this.y; return dx * dx + dy * dy; }, angle: function () { return Math.atan2(this.y, this.x); }, angleTo: function (b) { return Math.atan2(this.y - b.y, this.x - b.x); }, angleWith: function (b) { return this.angleWithSep(b.x, b.y); }, angleWithSep: function (x, y) { return Math.atan2(this.x * y - this.y * x, this.x * x + this.y * y); }, _matMult: function (m) { var x = m[0] * this.x + m[1] * this.y, y = m[2] * this.x + m[3] * this.y; this.x = x; this.y = y; return this; }, _add: function (p) { this.x += p.x; this.y += p.y; return this; }, _sub: function (p) { this.x -= p.x; this.y -= p.y; return this; }, _mult: function (k) { this.x *= k; this.y *= k; return this; }, _div: function (k) { this.x /= k; this.y /= k; return this; }, _multByPoint: function (p) { this.x *= p.x; this.y *= p.y; return this; }, _divByPoint: function (p) { this.x /= p.x; this.y /= p.y; return this; }, _unit: function () { this._div(this.mag()); return this; }, _perp: function () { var y = this.y; this.y = this.x; this.x = -y; return this; }, _rotate: function (angle) { var cos = Math.cos(angle), sin = Math.sin(angle), x = cos * this.x - sin * this.y, y = sin * this.x + cos * this.y; this.x = x; this.y = y; return this; }, _rotateAround: function (angle, p) { var cos = Math.cos(angle), sin = Math.sin(angle), x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y), y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y); this.x = x; this.y = y; return this; }, _round: function () { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } }; Point.convert = function (a) { if (a instanceof Point) { return a; } if (Array.isArray(a)) { return new Point(a[0], a[1]); } return a; }; var window$1 = typeof self !== 'undefined' ? self : {}; function deepEqual(a, b) { if (Array.isArray(a)) { if (!Array.isArray(b) || a.length !== b.length) { return false; } for (var i = 0; i < a.length; i++) { if (!deepEqual(a[i], b[i])) { return false; } } return true; } if (typeof a === 'object' && a !== null && b !== null) { if (!(typeof b === 'object')) { return false; } var keys = Object.keys(a); if (keys.length !== Object.keys(b).length) { return false; } for (var key in a) { if (!deepEqual(a[key], b[key])) { return false; } } return true; } return a === b; } var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; function easeCubicInOut(t) { if (t <= 0) { return 0; } if (t >= 1) { return 1; } var t2 = t * t, t3 = t2 * t; return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75); } function bezier(p1x, p1y, p2x, p2y) { var bezier = new unitbezier(p1x, p1y, p2x, p2y); return function (t) { return bezier.solve(t); }; } var ease = bezier(0.25, 0.1, 0.25, 1); function clamp(n, min, max) { return Math.min(max, Math.max(min, n)); } function wrap(n, min, max) { var d = max - min; var w = ((n - min) % d + d) % d + min; return w === min ? max : w; } function asyncAll(array, fn, callback) { if (!array.length) { return callback(null, []); } var remaining = array.length; var results = new Array(array.length); var error = null; array.forEach(function (item, i) { fn(item, function (err, result) { if (err) { error = err; } results[i] = result; if (--remaining === 0) { callback(error, results); } }); }); } function values(obj) { var result = []; for (var k in obj) { result.push(obj[k]); } return result; } function keysDifference(obj, other) { var difference = []; for (var i in obj) { if (!(i in other)) { difference.push(i); } } return difference; } function extend(dest) { var sources = [], len = arguments.length - 1; while (len-- > 0) sources[len] = arguments[len + 1]; for (var i = 0, list = sources; i < list.length; i += 1) { var src = list[i]; for (var k in src) { dest[k] = src[k]; } } return dest; } function pick(src, properties) { var result = {}; for (var i = 0; i < properties.length; i++) { var k = properties[i]; if (k in src) { result[k] = src[k]; } } return result; } var id = 1; function uniqueId() { return id++; } function uuid() { function b(a) { return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([10000000] + -[1000] + -4000 + -8000 + -100000000000).replace(/[018]/g, b); } return b(); } function nextPowerOfTwo(value) { if (value <= 1) { return 1; } return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); } function validateUuid(str) { return str ? /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(str) : false; } function bindAll(fns, context) { fns.forEach(function (fn) { if (!context[fn]) { return; } context[fn] = context[fn].bind(context); }); } function endsWith(string, suffix) { return string.indexOf(suffix, string.length - suffix.length) !== -1; } function mapObject(input, iterator, context) { var output = {}; for (var key in input) { output[key] = iterator.call(context || this, input[key], key, input); } return output; } function filterObject(input, iterator, context) { var output = {}; for (var key in input) { if (iterator.call(context || this, input[key], key, input)) { output[key] = input[key]; } } return output; } function clone(input) { if (Array.isArray(input)) { return input.map(clone); } else if (typeof input === 'object' && input) { return mapObject(input, clone); } else { return input; } } function arraysIntersect(a, b) { for (var l = 0; l < a.length; l++) { if (b.indexOf(a[l]) >= 0) { return true; } } return false; } var warnOnceHistory = {}; function warnOnce(message) { if (!warnOnceHistory[message]) { if (typeof console !== 'undefined') { console.warn(message); } warnOnceHistory[message] = true; } } function isCounterClockwise(a, b, c) { return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x); } function calculateSignedArea(ring) { var sum = 0; for (var i = 0, len = ring.length, j = len - 1, p1 = void 0, p2 = void 0; i < len; j = i++) { p1 = ring[i]; p2 = ring[j]; sum += (p2.x - p1.x) * (p1.y + p2.y); } return sum; } function sphericalToCartesian(ref) { var r = ref[0]; var azimuthal = ref[1]; var polar = ref[2]; azimuthal += 90; azimuthal *= Math.PI / 180; polar *= Math.PI / 180; return { x: r * Math.cos(azimuthal) * Math.sin(polar), y: r * Math.sin(azimuthal) * Math.sin(polar), z: r * Math.cos(polar) }; } function isWorker() { return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope; } function parseCacheControl(cacheControl) { var re = /(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g; var header = {}; cacheControl.replace(re, function ($0, $1, $2, $3) { var value = $2 || $3; header[$1] = value ? value.toLowerCase() : true; return ''; }); if (header['max-age']) { var maxAge = parseInt(header['max-age'], 10); if (isNaN(maxAge)) { delete header['max-age']; } else { header['max-age'] = maxAge; } } return header; } var _isSafari = null; function isSafari(scope) { if (_isSafari == null) { var userAgent = scope.navigator ? scope.navigator.userAgent : null; _isSafari = !!scope.safari || !!(userAgent && (/\b(iPad|iPhone|iPod)\b/.test(userAgent) || !!userAgent.match('Safari') && !userAgent.match('Chrome'))); } return _isSafari; } function storageAvailable(type) { try { var storage = window$1[type]; storage.setItem('_mapbox_test_', 1); storage.removeItem('_mapbox_test_'); return true; } catch (e) { return false; } } function b64EncodeUnicode(str) { return window$1.btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { return String.fromCharCode(Number('0x' + p1)); })); } function b64DecodeUnicode(str) { return decodeURIComponent(window$1.atob(str).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } var now = window$1.performance && window$1.performance.now ? window$1.performance.now.bind(window$1.performance) : Date.now.bind(Date); var raf = window$1.requestAnimationFrame || window$1.mozRequestAnimationFrame || window$1.webkitRequestAnimationFrame || window$1.msRequestAnimationFrame; var cancel = window$1.cancelAnimationFrame || window$1.mozCancelAnimationFrame || window$1.webkitCancelAnimationFrame || window$1.msCancelAnimationFrame; var linkEl; var reducedMotionQuery; var exported = { now: now, frame: function frame(fn) { var frame = raf(fn); return { cancel: function () { return cancel(frame); } }; }, getImageData: function getImageData(img, padding) { if (padding === void 0) padding = 0; var canvas = window$1.document.createElement('canvas'); var context = canvas.getContext('2d'); if (!context) { throw new Error('failed to create canvas 2d context'); } canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0, img.width, img.height); return context.getImageData(-padding, -padding, img.width + 2 * padding, img.height + 2 * padding); }, resolveURL: function resolveURL(path) { if (!linkEl) { linkEl = window$1.document.createElement('a'); } linkEl.href = path; return linkEl.href; }, hardwareConcurrency: window$1.navigator && window$1.navigator.hardwareConcurrency || 4, get devicePixelRatio() { return window$1.devicePixelRatio; }, get prefersReducedMotion() { if (!window$1.matchMedia) { return false; } if (reducedMotionQuery == null) { reducedMotionQuery = window$1.matchMedia('(prefers-reduced-motion: reduce)'); } return reducedMotionQuery.matches; } }; var config = { API_URL: 'https://api.mapbox.com', 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 { return null; } }, FEEDBACK_URL: 'https://apps.mapbox.com/feedback', REQUIRE_ACCESS_TOKEN: true, ACCESS_TOKEN: null, MAX_PARALLEL_IMAGE_REQUESTS: 16 }; var exported$1 = { supported: false, testSupport: testSupport }; var glForTesting; var webpCheckComplete = false; var webpImgTest; var webpImgTestOnloadComplete = false; if (window$1.document) { webpImgTest = window$1.document.createElement('img'); webpImgTest.onload = function () { if (glForTesting) { testWebpTextureUpload(glForTesting); } glForTesting = null; webpImgTestOnloadComplete = true; }; webpImgTest.onerror = function () { webpCheckComplete = true; glForTesting = null; }; webpImgTest.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA='; } function testSupport(gl) { if (webpCheckComplete || !webpImgTest) { return; } if (webpImgTestOnloadComplete) { testWebpTextureUpload(gl); } else { glForTesting = gl; } } function testWebpTextureUpload(gl) { var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); try { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, webpImgTest); if (gl.isContextLost()) { return; } exported$1.supported = true; } catch (e) { } gl.deleteTexture(texture); webpCheckComplete = true; } var SKU_ID = '01'; function createSkuToken() { var TOKEN_VERSION = '1'; var base62chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; var sessionRandomizer = ''; for (var i = 0; i < 10; i++) { sessionRandomizer += base62chars[Math.floor(Math.random() * 62)]; } var expiration = 12 * 60 * 60 * 1000; var token = [ TOKEN_VERSION, SKU_ID, sessionRandomizer ].join(''); var tokenExpiresAt = Date.now() + expiration; return { token: token, tokenExpiresAt: tokenExpiresAt }; } var RequestManager = function RequestManager(transformRequestFn, customAccessToken) { this._transformRequestFn = transformRequestFn; this._customAccessToken = customAccessToken; this._createSkuToken(); }; RequestManager.prototype._createSkuToken = function _createSkuToken() { var skuToken = createSkuToken(); this._skuToken = skuToken.token; this._skuTokenExpiresAt = skuToken.tokenExpiresAt; }; RequestManager.prototype._isSkuTokenExpired = function _isSkuTokenExpired() { return Date.now() > this._skuTokenExpiresAt; }; RequestManager.prototype.transformRequest = function transformRequest(url, type) { if (this._transformRequestFn) { return this._transformRequestFn(url, type) || { url: url }; } return { url: url }; }; RequestManager.prototype.normalizeStyleURL = function normalizeStyleURL(url, accessToken) { if (!isMapboxURL(url)) { return url; } var urlObject = parseUrl(url); urlObject.path = '/styles/v1' + urlObject.path; return this._makeAPIURL(urlObject, this._customAccessToken || accessToken); }; RequestManager.prototype.normalizeGlyphsURL = function normalizeGlyphsURL(url, accessToken) { if (!isMapboxURL(url)) { return url; } var urlObject = parseUrl(url); urlObject.path = '/fonts/v1' + urlObject.path; return this._makeAPIURL(urlObject, this._customAccessToken || accessToken); }; RequestManager.prototype.normalizeSourceURL = function normalizeSourceURL(url, accessToken) { if (!isMapboxURL(url)) { return url; } var urlObject = parseUrl(url); urlObject.path = '/v4/' + urlObject.authority + '.json'; urlObject.params.push('secure'); return this._makeAPIURL(urlObject, this._customAccessToken || accessToken); }; RequestManager.prototype.normalizeSpriteURL = function normalizeSpriteURL(url, format, extension, accessToken) { var urlObject = parseUrl(url); if (!isMapboxURL(url)) { urlObject.path += '' + format + extension; return formatUrl(urlObject); } urlObject.path = '/styles/v1' + urlObject.path + '/sprite' + format + extension; return this._makeAPIURL(urlObject, this._customAccessToken || accessToken); }; RequestManager.prototype.normalizeTileURL = function normalizeTileURL(tileURL, tileSize) { if (this._isSkuTokenExpired()) { this._createSkuToken(); } if (tileURL && !isMapboxURL(tileURL)) { return tileURL; } var urlObject = parseUrl(tileURL); var imageExtensionRe = /(\.(png|jpg)\d*)(?=$)/; var tileURLAPIPrefixRe = /^.+\/v4\//; var suffix = exported.devicePixelRatio >= 2 || tileSize === 512 ? '@2x' : ''; var extension = exported$1.supported ? '.webp' : '$1'; urlObject.path = urlObject.path.replace(imageExtensionRe, '' + suffix + extension); urlObject.path = urlObject.path.replace(tileURLAPIPrefixRe, '/'); urlObject.path = '/v4' + urlObject.path; var accessToken = this._customAccessToken || getAccessToken(urlObject.params) || config.ACCESS_TOKEN; if (config.REQUIRE_ACCESS_TOKEN && accessToken && this._skuToken) { urlObject.params.push('sku=' + this._skuToken); } return this._makeAPIURL(urlObject, accessToken); }; RequestManager.prototype.canonicalizeTileURL = function canonicalizeTileURL(url, removeAccessToken) { var version = '/v4/'; var extensionRe = /\.[\w]+$/; var urlObject = parseUrl(url); if (!urlObject.path.match(/(^\/v4\/)/) || !urlObject.path.match(extensionRe)) { return url; } var result = 'mapbox://tiles/'; result += urlObject.path.replace(version, ''); var params = urlObject.params; if (removeAccessToken) { params = params.filter(function (p) { return !p.match(/^access_token=/); }); } if (params.length) { result += '?' + params.join('&'); } return result; }; RequestManager.prototype.canonicalizeTileset = function canonicalizeTileset(tileJSON, sourceURL) { var removeAccessToken = sourceURL ? isMapboxURL(sourceURL) : false; var canonical = []; for (var i = 0, list = tileJSON.tiles || []; i < list.length; i += 1) { var url = list[i]; if (isMapboxHTTPURL(url)) { canonical.push(this.canonicalizeTileURL(url, removeAccessToken)); } else { canonical.push(url); } } return canonical; }; RequestManager.prototype._makeAPIURL = function _makeAPIURL(urlObject, accessToken) { var help = 'See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes'; var apiUrlObject = parseUrl(config.API_URL); urlObject.protocol = apiUrlObject.protocol; urlObject.authority = apiUrlObject.authority; if (urlObject.protocol === 'http') { var i = urlObject.params.indexOf('secure'); if (i >= 0) { urlObject.params.splice(i, 1); } } if (apiUrlObject.path !== '/') { urlObject.path = '' + apiUrlObject.path + urlObject.path; } if (!config.REQUIRE_ACCESS_TOKEN) { return formatUrl(urlObject); } accessToken = accessToken || config.ACCESS_TOKEN; if (!accessToken) { throw new Error('An API access token is required to use Mapbox GL. ' + help); } if (accessToken[0] === 's') { throw new Error('Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). ' + help); } urlObject.params = urlObject.params.filter(function (d) { return d.indexOf('access_token') === -1; }); urlObject.params.push('access_token=' + accessToken); return formatUrl(urlObject); }; function isMapboxURL(url) { return url.indexOf('mapbox:') === 0; } var mapboxHTTPURLRe = /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/|\?|$)/i; function isMapboxHTTPURL(url) { return mapboxHTTPURLRe.test(url); } function hasCacheDefeatingSku(url) { return url.indexOf('sku=') > 0 && isMapboxHTTPURL(url); } function getAccessToken(params) { for (var i = 0, list = params; i < list.length; i += 1) { var param = list[i]; var match = param.match(/^access_token=(.*)$/); if (match) { return match[1]; } } return null; } var urlRe = /^(\w+):\/\/([^/?]*)(\/[^?]+)?\??(.+)?/; function parseUrl(url) { var parts = url.match(urlRe); if (!parts) { throw new Error('Unable to parse URL object'); } return { protocol: parts[1], authority: parts[2], path: parts[3] || '/', params: parts[4] ? parts[4].split('&') : [] }; } function formatUrl(obj) { var params = obj.params.length ? '?' + obj.params.join('&') : ''; return obj.protocol + '://' + obj.authority + obj.path + params; } var telemEventKey = 'mapbox.eventData'; function parseAccessToken(accessToken) { if (!accessToken) { return null; } var parts = accessToken.split('.'); if (!parts || parts.length !== 3) { return null; } try { var jsonData = JSON.parse(b64DecodeUnicode(parts[1])); return jsonData; } catch (e) { return null; } } var TelemetryEvent = function TelemetryEvent(type) { this.type = type; this.anonId = null; this.eventData = {}; this.queue = []; this.pendingRequest = null; }; TelemetryEvent.prototype.getStorageKey = function getStorageKey(domain) { var tokenData = parseAccessToken(config.ACCESS_TOKEN); var u = ''; if (tokenData && tokenData['u']) { u = b64EncodeUnicode(tokenData['u']); } else { u = config.ACCESS_TOKEN || ''; } return domain ? telemEventKey + '.' + domain + ':' + u : telemEventKey + ':' + u; }; TelemetryEvent.prototype.fetchEventData = function fetchEventData() { var isLocalStorageAvailable = storageAvailable('localStorage'); var storageKey = this.getStorageKey(); var uuidKey = this.getStorageKey('uuid'); if (isLocalStorageAvailable) { try { var data = window$1.localStorage.getItem(storageKey); if (data) { this.eventData = JSON.parse(data); } var uuid = window$1.localStorage.getItem(uuidKey); if (uuid) { this.anonId = uuid; } } catch (e) { warnOnce('Unable to read from LocalStorage'); } } }; TelemetryEvent.prototype.saveEventData = function saveEventData() { var isLocalStorageAvailable = storageAvailable('localStorage'); var storageKey = this.getStorageKey(); var uuidKey = this.getStorageKey('uuid'); if (isLocalStorageAvailable) { try { window$1.localStorage.setItem(uuidKey, this.anonId); if (Object.keys(this.eventData).length >= 1) { window$1.localStorage.setItem(storageKey, JSON.stringify(this.eventData)); } } catch (e) { warnOnce('Unable to write to LocalStorage'); } } }; TelemetryEvent.prototype.processRequests = function processRequests(_) { }; TelemetryEvent.prototype.postEvent = function postEvent(timestamp, additionalPayload, callback, customAccessToken) { var this$1 = this; if (!config.EVENTS_URL) { return; } var eventsUrlObject = parseUrl(config.EVENTS_URL); eventsUrlObject.params.push('access_token=' + (customAccessToken || config.ACCESS_TOKEN || '')); var payload = { event: this.type, created: new Date(timestamp).toISOString(), sdkIdentifier: 'mapbox-gl-js', sdkVersion: version, skuId: SKU_ID, userId: this.anonId }; var finalPayload = additionalPayload ? extend(payload, additionalPayload) : payload; var request = { url: formatUrl(eventsUrlObject), headers: { 'Content-Type': 'text/plain' }, body: JSON.stringify([finalPayload]) }; this.pendingRequest = postData(request, function (error) { this$1.pendingRequest = null; callback(error); this$1.saveEventData(); this$1.processRequests(customAccessToken); }); }; TelemetryEvent.prototype.queueRequest = function queueRequest(event, customAccessToken) { this.queue.push(event); this.processRequests(customAccessToken); }; var MapLoadEvent = function (TelemetryEvent) { function MapLoadEvent() { TelemetryEvent.call(this, 'map.load'); this.success = {}; this.skuToken = ''; } if (TelemetryEvent) MapLoadEvent.__proto__ = TelemetryEvent; MapLoadEvent.prototype = Object.create(TelemetryEvent && TelemetryEvent.prototype); MapLoadEvent.prototype.constructor = MapLoadEvent; MapLoadEvent.prototype.postMapLoadEvent = function postMapLoadEvent(tileUrls, mapId, skuToken, customAccessToken) { this.skuToken = skuToken; var accessTokenIsSet = !!(customAccessToken || config.ACCESS_TOKEN); var usesMapboxTiles = Array.isArray(tileUrls) && tileUrls.some(function (url) { return isMapboxURL(url) || isMapboxHTTPURL(url); }); if (config.EVENTS_URL && accessTokenIsSet && usesMapboxTiles) { this.queueRequest({ id: mapId, timestamp: Date.now() }, customAccessToken); } }; MapLoadEvent.prototype.processRequests = function processRequests(customAccessToken) { var this$1 = this; if (this.pendingRequest || this.queue.length === 0) { return; } var ref = this.queue.shift(); var id = ref.id; var timestamp = ref.timestamp; if (id && this.success[id]) { return; } if (!this.anonId) { this.fetchEventData(); } if (!validateUuid(this.anonId)) { this.anonId = uuid(); } this.postEvent(timestamp, { skuToken: this.skuToken }, function (err) { if (!err) { if (id) { this$1.success[id] = true; } } }, customAccessToken); }; return MapLoadEvent; }(TelemetryEvent); var TurnstileEvent = function (TelemetryEvent) { function TurnstileEvent(customAccessToken) { TelemetryEvent.call(this, 'appUserTurnstile'); this._customAccessToken = customAccessToken; } if (TelemetryEvent) TurnstileEvent.__proto__ = TelemetryEvent; TurnstileEvent.prototype = Object.create(TelemetryEvent && TelemetryEvent.prototype); TurnstileEvent.prototype.constructor = TurnstileEvent; TurnstileEvent.prototype.postTurnstileEvent = function postTurnstileEvent(tileUrls, customAccessToken) { if (config.EVENTS_URL && config.ACCESS_TOKEN && Array.isArray(tileUrls) && tileUrls.some(function (url) { return isMapboxURL(url) || isMapboxHTTPURL(url); })) { this.queueRequest(Date.now(), customAccessToken); } }; TurnstileEvent.prototype.processRequests = function processRequests(customAccessToken) { var this$1 = this; if (this.pendingRequest || this.queue.length === 0) { return; } if (!this.anonId || !this.eventData.lastSuccess || !this.eventData.tokenU) { this.fetchEventData(); } var tokenData = parseAccessToken(config.ACCESS_TOKEN); var tokenU = tokenData ? tokenData['u'] : config.ACCESS_TOKEN; var dueForEvent = tokenU !== this.eventData.tokenU; if (!validateUuid(this.anonId)) { this.anonId = uuid(); dueForEvent = true; } var nextUpdate = this.queue.shift(); if (this.eventData.lastSuccess) { var lastUpdate = new Date(this.eventData.lastSuccess); var nextDate = new Date(nextUpdate); var daysElapsed = (nextUpdate - this.eventData.lastSuccess) / (24 * 60 * 60 * 1000); dueForEvent = dueForEvent || daysElapsed >= 1 || daysElapsed < -1 || lastUpdate.getDate() !== nextDate.getDate(); } else { dueForEvent = true; } if (!dueForEvent) { return this.processRequests(); } this.postEvent(nextUpdate, { 'enabled.telemetry': false }, function (err) { if (!err) { this$1.eventData.lastSuccess = nextUpdate; this$1.eventData.tokenU = tokenU; } }, customAccessToken); }; return TurnstileEvent; }(TelemetryEvent); var turnstileEvent_ = new TurnstileEvent(); var postTurnstileEvent = turnstileEvent_.postTurnstileEvent.bind(turnstileEvent_); var mapLoadEvent_ = new MapLoadEvent(); var postMapLoadEvent = mapLoadEvent_.postMapLoadEvent.bind(mapLoadEvent_); var CACHE_NAME = 'mapbox-tiles'; var cacheLimit = 500; var cacheCheckThreshold = 50; var MIN_TIME_UNTIL_EXPIRY = 1000 * 60 * 7; var sharedCache; function cacheOpen() { if (window$1.caches && !sharedCache) { sharedCache = window$1.caches.open(CACHE_NAME); } } var responseConstructorSupportsReadableStream; function prepareBody(response, callback) { if (responseConstructorSupportsReadableStream === undefined) { try { new Response(new ReadableStream()); responseConstructorSupportsReadableStream = true; } catch (e) { responseConstructorSupportsReadableStream = false; } } if (responseConstructorSupportsReadableStream) { callback(response.body); } else { response.blob().then(callback); } } function cachePut(request, response, requestTime) { cacheOpen(); if (!sharedCache) { return; } var options = { status: response.status, statusText: response.statusText, headers: new window$1.Headers() }; response.headers.forEach(function (v, k) { return options.headers.set(k, v); }); var cacheControl = parseCacheControl(response.headers.get('Cache-Control') || ''); if (cacheControl['no-store']) { return; } if (cacheControl['max-age']) { options.headers.set('Expires', new Date(requestTime + cacheControl['max-age'] * 1000).toUTCString()); } var timeUntilExpiry = new Date(options.headers.get('Expires')).getTime() - requestTime; if (timeUntilExpiry < MIN_TIME_UNTIL_EXPIRY) { return; } prepareBody(response, function (body) { var clonedResponse = new window$1.Response(body, options); cacheOpen(); if (!sharedCache) { return; } sharedCache.then(function (cache) { return cache.put(stripQueryParameters(request.url), clonedResponse); }).catch(function (e) { return warnOnce(e.message); }); }); } function stripQueryParameters(url) { var start = url.indexOf('?'); return start < 0 ? url : url.slice(0, start); } function cacheGet(request, callback) { cacheOpen(); if (!sharedCache) { return callback(null); } var strippedURL = stripQueryParameters(request.url); sharedCache.then(function (cache) { cache.match(strippedURL).then(function (response) { var fresh = isFresh(response); cache.delete(strippedURL); if (fresh) { cache.put(strippedURL, response.clone()); } callback(null, response, fresh); }).catch(callback); }).catch(callback); } function isFresh(response) { if (!response) { return false; } var expires = new Date(response.headers.get('Expires') || 0); var cacheControl = parseCacheControl(response.headers.get('Cache-Control') || ''); return expires > Date.now() && !cacheControl['no-cache']; } var globalEntryCounter = Infinity; function cacheEntryPossiblyAdded(dispatcher) { globalEntryCounter++; if (globalEntryCounter > cacheCheckThreshold) { dispatcher.getActor().send('enforceCacheSizeLimit', cacheLimit); globalEntryCounter = 0; } } function enforceCacheSizeLimit(limit) { cacheOpen(); if (!sharedCache) { return; } sharedCache.then(function (cache) { cache.keys().then(function (keys) { for (var i = 0; i < keys.length - limit; i++) { cache.delete(keys[i]); } }); }); } function clearTileCache(callback) { var promise = window$1.caches.delete(CACHE_NAME); if (callback) { promise.catch(callback).then(function () { return callback(); }); } } function setCacheLimits(limit, checkThreshold) { cacheLimit = limit; cacheCheckThreshold = checkThreshold; } var supportsOffscreenCanvas; function offscreenCanvasSupported() { if (supportsOffscreenCanvas == null) { supportsOffscreenCanvas = window$1.OffscreenCanvas && new window$1.OffscreenCanvas(1, 1).getContext('2d') && typeof window$1.createImageBitmap === 'function'; } return supportsOffscreenCanvas; } var ResourceType = { Unknown: 'Unknown', Style: 'Style', Source: 'Source', Tile: 'Tile', Glyphs: 'Glyphs', SpriteImage: 'SpriteImage', SpriteJSON: 'SpriteJSON', Image: 'Image' }; if (typeof Object.freeze == 'function') { Object.freeze(ResourceType); } var AJAXError = function (Error) { function AJAXError(message, status, url) { if (status === 401 && isMapboxHTTPURL(url)) { message += ': you may have provided an invalid Mapbox access token. See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes'; } Error.call(this, message); this.status = status; this.url = url; this.name = this.constructor.name; this.message = message; } if (Error) AJAXError.__proto__ = Error; AJAXError.prototype = Object.create(Error && Error.prototype); AJAXError.prototype.constructor = AJAXError; AJAXError.prototype.toString = function toString() { return this.name + ': ' + this.message + ' (' + this.status + '): ' + this.url; }; return AJAXError; }(Error); var getReferrer = isWorker() ? function () { return self.worker && self.worker.referrer; } : function () { return (window$1.location.protocol === 'blob:' ? window$1.parent : window$1).location.href; }; var isFileURL = function (url) { return /^file:/.test(url) || /^file:/.test(getReferrer()) && !/^\w+:/.test(url); }; function makeFetchRequest(requestParameters, callback) { var controller = new window$1.AbortController(); var request = new window$1.Request(requestParameters.url, { method: requestParameters.method || 'GET', body: requestParameters.body, credentials: requestParameters.credentials, headers: requestParameters.headers, referrer: getReferrer(), signal: controller.signal }); var complete = false; var aborted = false; var cacheIgnoringSearch = hasCacheDefeatingSku(request.url); if (requestParameters.type === 'json') { request.headers.set('Accept', 'application/json'); } var validateOrFetch = function (err, cachedResponse, responseIsFresh) { if (aborted) { return; } if (err) { if (err.message !== 'SecurityError') { warnOnce(err); } } if (cachedResponse && responseIsFresh) { return finishRequest(cachedResponse); } var requestTime = Date.now(); window$1.fetch(request).then(function (response) { if (response.ok) { var cacheableResponse = cacheIgnoringSearch ? response.clone() : null; return finishRequest(response, cacheableResponse, requestTime); } else { return callback(new AJAXError(response.statusText, response.status, requestParameters.url)); } }).catch(function (error) { if (error.code === 20) { return; } callback(new Error(error.message)); }); }; var finishRequest = function (response, cacheableResponse, requestTime) { (requestParameters.type === 'arrayBuffer' ? response.arrayBuffer() : requestParameters.type === 'json' ? response.json() : response.text()).then(function (result) { if (aborted) { return; } if (cacheableResponse && requestTime) { cachePut(request, cacheableResponse, requestTime); } complete = true; callback(null, result, response.headers.get('Cache-Control'), response.headers.get('Expires')); }).catch(function (err) { if (!aborted) { callback(new Error(err.message)); } }); }; if (cacheIgnoringSearch) { cacheGet(request, validateOrFetch); } else { validateOrFetch(null, null); } return { cancel: function () { aborted = true; if (!complete) { controller.abort(); } } }; } function makeXMLHttpRequest(requestParameters, callback) { var xhr = new window$1.XMLHttpRequest(); xhr.open(requestParameters.method || 'GET', requestParameters.url, true); if (requestParameters.type === 'arrayBuffer') { xhr.responseType = 'arraybuffer'; } for (var k in requestParameters.headers) { xhr.setRequestHeader(k, requestParameters.headers[k]); } if (requestParameters.type === 'json') { xhr.responseType = 'text'; xhr.setRequestHeader('Accept', 'application/json'); } xhr.withCredentials = requestParameters.credentials === 'include'; xhr.onerror = function () { callback(new Error(xhr.statusText)); }; xhr.onload = function () { if ((xhr.status >= 200 && xhr.status < 300 || xhr.status === 0) && xhr.response !== null) { var data = xhr.response; if (requestParameters.type === 'json') { try { data = JSON.parse(xhr.response); } catch (err) { return callback(err); } } callback(null, data, xhr.getResponseHeader('Cache-Control'), xhr.getResponseHeader('Expires')); } else { callback(new AJAXError(xhr.statusText, xhr.status, requestParameters.url)); } }; xhr.send(requestParameters.body); return { cancel: function () { return xhr.abort(); } }; } var makeRequest = function (requestParameters, callback) { if (!isFileURL(requestParameters.url)) { if (window$1.fetch && window$1.Request && window$1.AbortController && window$1.Request.prototype.hasOwnProperty('signal')) { return makeFetchRequest(requestParameters, callback); } if (isWorker() && self.worker && self.worker.actor) { var queueOnMainThread = true; return self.worker.actor.send('getResource', requestParameters, callback, undefined, queueOnMainThread); } } return makeXMLHttpRequest(requestParameters, callback); }; var getJSON = function (requestParameters, callback) { return makeRequest(extend(requestParameters, { type: 'json' }), callback); }; var getArrayBuffer = function (requestParameters, callback) { return makeRequest(extend(requestParameters, { type: 'arrayBuffer' }), callback); }; var postData = function (requestParameters, callback) { return makeRequest(extend(requestParameters, { method: 'POST' }), callback); }; function sameOrigin(url) { var a = window$1.document.createElement('a'); a.href = url; return a.protocol === window$1.document.location.protocol && a.host === window$1.document.location.host; } var transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; function arrayBufferToImage(data, callback, cacheControl, expires) { var img = new window$1.Image(); var URL = window$1.URL; img.onload = function () { callback(null, img); URL.revokeObjectURL(img.src); img.onload = null; window$1.requestAnimationFrame(function () { img.src = transparentPngUrl; }); }; img.onerror = function () { return callback(new Error('Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.')); }; var blob = new window$1.Blob([new Uint8Array(data)], { type: 'image/png' }); img.cacheControl = cacheControl; img.expires = expires; img.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl; } function arrayBufferToImageBitmap(data, callback) { var blob = new window$1.Blob([new Uint8Array(data)], { type: 'image/png' }); window$1.createImageBitmap(blob).then(function (imgBitmap) { callback(null, imgBitmap); }).catch(function (e) { callback(new Error('Could not load image because of ' + e.message + '. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.')); }); } var imageQueue, numImageRequests; var resetImageRequestQueue = function () { imageQueue = []; numImageRequests = 0; }; resetImageRequestQueue(); var getImage = function (requestParameters, callback) { if (exported$1.supported) { if (!requestParameters.headers) { requestParameters.headers = {}; } requestParameters.headers.accept = 'image/webp,*/*'; } if (numImageRequests >= config.MAX_PARALLEL_IMAGE_REQUESTS) { var queued = { requestParameters: requestParameters, callback: callback, cancelled: false, cancel: function cancel() { this.cancelled = true; } }; imageQueue.push(queued); return queued; } numImageRequests++; var advanced = false; var advanceImageRequestQueue = function () { if (advanced) { return; } advanced = true; numImageRequests--; while (imageQueue.length && numImageRequests < config.MAX_PARALLEL_IMAGE_REQUESTS) { var request = imageQueue.shift(); var requestParameters = request.requestParameters; var callback = request.callback; var cancelled = request.cancelled; if (!cancelled) { request.cancel = getImage(requestParameters, callback).cancel; } } }; var request = getArrayBuffer(requestParameters, function (err, data, cacheControl, expires) { advanceImageRequestQueue(); if (err) { callback(err); } else if (data) { if (offscreenCanvasSupported()) { arrayBufferToImageBitmap(data, callback); } else { arrayBufferToImage(data, callback, cacheControl, expires); } } }); return { cancel: function () { request.cancel(); advanceImageRequestQueue(); } }; }; var getVideo = function (urls, callback) { var video = window$1.document.createElement('video'); video.muted = true; video.onloadstart = function () { callback(null, video); }; for (var i = 0; i < urls.length; i++) { var s = window$1.document.createElement('source'); if (!sameOrigin(urls[i])) { video.crossOrigin = 'Anonymous'; } s.src = urls[i]; video.appendChild(s); } return { cancel: function () { } }; }; function _addEventListener(type, listener, listenerList) { var listenerExists = listenerList[type] && listenerList[type].indexOf(listener) !== -1; if (!listenerExists) { listenerList[type] = listenerList[type] || []; listenerList[type].push(listener); } } function _removeEventListener(type, listener, listenerList) { if (listenerList && listenerList[type]) { var index = listenerList[type].indexOf(listener); if (index !== -1) { listenerList[type].splice(index, 1); } } } var Event = function Event(type, data) { if (data === void 0) data = {}; extend(this, data); this.type = type; }; var ErrorEvent = function (Event) { function ErrorEvent(error, data) { if (data === void 0) data = {}; Event.call(this, 'error', extend({ error: error }, data)); } if (Event) ErrorEvent.__proto__ = Event; ErrorEvent.prototype = Object.create(Event && Event.prototype); ErrorEvent.prototype.constructor = ErrorEvent; return ErrorEvent; }(Event); var Evented = function Evented() { }; Evented.prototype.on = function on(type, listener) { this._listeners = this._listeners || {}; _addEventListener(type, listener, this._listeners); return this; }; Evented.prototype.off = function off(type, listener) { _removeEventListener(type, listener, this._listeners); _removeEventListener(type, listener, this._oneTimeListeners); return this; }; Evented.prototype.once = function once(type, listener) { this._oneTimeListeners = this._oneTimeListeners || {}; _addEventListener(type, listener, this._oneTimeListeners); return this; }; Evented.prototype.fire = function fire(event, properties) { if (typeof event === 'string') { event = new Event(event, properties || {}); } var type = event.type; if (this.listens(type)) { event.target = this; var listeners = this._listeners && this._listeners[type] ? this._listeners[type].slice() : []; for (var i = 0, list = listeners; i < list.length; i += 1) { var listener = list[i]; listener.call(this, event); } var oneTimeListeners = this._oneTimeListeners && this._oneTimeListeners[type] ? this._oneTimeListeners[type].slice() : []; for (var i$1 = 0, list$1 = oneTimeListeners; i$1 < list$1.length; i$1 += 1) { var listener$1 = list$1[i$1]; _removeEventListener(type, listener$1, this._oneTimeListeners); listener$1.call(this, event); } var parent = this._eventedParent; if (parent) { extend(event, typeof this._eventedParentData === 'function' ? this._eventedParentData() : this._eventedParentData); parent.fire(event); } } else if (event instanceof ErrorEvent) { console.error(event.error); } return this; }; Evented.prototype.listens = function listens(type) { return this._listeners && this._listeners[type] && this._listeners[type].length > 0 || this._oneTimeListeners && this._oneTimeListeners[type] && this._oneTimeListeners[type].length > 0 || this._eventedParent && this._eventedParent.listens(type); }; Evented.prototype.setEventedParent = function setEventedParent(parent, data) { this._eventedParent = parent; this._eventedParentData = data; return this; }; var $version = 8; var $root = { version: { required: true, type: "enum", values: [ 8 ] }, name: { type: "string" }, metadata: { type: "*" }, center: { type: "array", value: "number" }, zoom: { type: "number" }, bearing: { type: "number", "default": 0, period: 360, units: "degrees" }, pitch: { type: "number", "default": 0, units: "degrees" }, light: { type: "light" }, sources: { required: true, type: "sources" }, sprite: { type: "string" }, glyphs: { type: "string" }, transition: { type: "transition" }, layers: { required: true, type: "array", value: "layer" } }; var sources = { "*": { type: "source" } }; var source = [ "source_vector", "source_raster", "source_raster_dem", "source_geojson", "source_video", "source_image" ]; var source_vector = { type: { required: true, type: "enum", values: { vector: { } } }, url: { type: "string" }, tiles: { type: "array", value: "string" }, bounds: { type: "array", value: "number", length: 4, "default": [ -180, -85.051129, 180, 85.051129 ] }, scheme: { type: "enum", values: { xyz: { }, tms: { } }, "default": "xyz" }, minzoom: { type: "number", "default": 0 }, maxzoom: { type: "number", "default": 22 }, attribution: { type: "string" }, promoteId: { type: "promoteId" }, volatile: { type: "boolean", "default": false }, "*": { type: "*" } }; var source_raster = { type: { required: true, type: "enum", values: { raster: { } } }, url: { type: "string" }, tiles: { type: "array", value: "string" }, bounds: { type: "array", value: "number", length: 4, "default": [ -180, -85.051129, 180, 85.051129 ] }, minzoom: { type: "number", "default": 0 }, maxzoom: { type: "number", "default": 22 }, tileSize: { type: "number", "default": 512, units: "pixels" }, scheme: { type: "enum", values: { xyz: { }, tms: { } }, "default": "xyz" }, attribution: { type: "string" }, volatile: { type: "boolean", "default": false }, "*": { type: "*" } }; var source_raster_dem = { type: { required: true, type: "enum", values: { "raster-dem": { } } }, url: { type: "string" }, tiles: { type: "array", value: "string" }, bounds: { type: "array", value: "number", length: 4, "default": [ -180, -85.051129, 180, 85.051129 ] }, minzoom: { type: "number", "default": 0 }, maxzoom: { type: "number", "default": 22 }, tileSize: { type: "number", "default": 512, units: "pixels" }, attribution: { type: "string" }, encoding: { type: "enum", values: { terrarium: { }, mapbox: { } }, "default": "mapbox" }, volatile: { type: "boolean", "default": false }, "*": { type: "*" } }; var source_geojson = { type: { required: true, type: "enum", values: { geojson: { } } }, data: { type: "*" }, maxzoom: { type: "number", "default": 18 }, attribution: { type: "string" }, buffer: { type: "number", "default": 128, maximum: 512, minimum: 0 }, filter: { type: "*" }, tolerance: { type: "number", "default": 0.375 }, cluster: { type: "boolean", "default": false }, clusterRadius: { type: "number", "default": 50, minimum: 0 }, clusterMaxZoom: { type: "number" }, clusterMinPoints: { type: "number" }, clusterProperties: { type: "*" }, lineMetrics: { type: "boolean", "default": false }, generateId: { type: "boolean", "default": false }, promoteId: { type: "promoteId" } }; var source_video = { type: { required: true, type: "enum", values: { video: { } } }, urls: { required: true, type: "array", value: "string" }, coordinates: { required: true, type: "array", length: 4, value: { type: "array", length: 2, value: "number" } } }; var source_image = { type: { required: true, type: "enum", values: { image: { } } }, url: { required: true, type: "string" }, coordinates: { required: true, type: "array", length: 4, value: { type: "array", length: 2, value: "number" } } }; var layer = { id: { type: "string", required: true }, type: { type: "enum", values: { fill: { }, line: { }, symbol: { }, circle: { }, heatmap: { }, "fill-extrusion": { }, raster: { }, hillshade: { }, background: { } }, required: true }, metadata: { type: "*" }, source: { type: "string" }, "source-layer": { type: "string" }, minzoom: { type: "number", minimum: 0, maximum: 24 }, maxzoom: { type: "number", minimum: 0, maximum: 24 }, filter: { type: "filter" }, layout: { type: "layout" }, paint: { type: "paint" } }; var layout = [ "layout_fill", "layout_line", "layout_circle", "layout_heatmap", "layout_fill-extrusion", "layout_symbol", "layout_raster", "layout_hillshade", "layout_background" ]; var layout_background = { visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_fill = { "fill-sort-key": { type: "number", expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_circle = { "circle-sort-key": { type: "number", expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_heatmap = { visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_line = { "line-cap": { type: "enum", values: { butt: { }, round: { }, square: { } }, "default": "butt", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "line-join": { type: "enum", values: { bevel: { }, round: { }, miter: { } }, "default": "miter", expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "line-miter-limit": { type: "number", "default": 2, requires: [ { "line-join": "miter" } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "line-round-limit": { type: "number", "default": 1.05, requires: [ { "line-join": "round" } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "line-sort-key": { type: "number", expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_symbol = { "symbol-placement": { type: "enum", values: { point: { }, line: { }, "line-center": { } }, "default": "point", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "symbol-spacing": { type: "number", "default": 250, minimum: 1, units: "pixels", requires: [ { "symbol-placement": "line" } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "symbol-avoid-edges": { type: "boolean", "default": false, expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "symbol-sort-key": { type: "number", expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "symbol-z-order": { type: "enum", values: { auto: { }, "viewport-y": { }, source: { } }, "default": "auto", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-allow-overlap": { type: "boolean", "default": false, requires: [ "icon-image" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-ignore-placement": { type: "boolean", "default": false, requires: [ "icon-image" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-optional": { type: "boolean", "default": false, requires: [ "icon-image", "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-rotation-alignment": { type: "enum", values: { map: { }, viewport: { }, auto: { } }, "default": "auto", requires: [ "icon-image" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-size": { type: "number", "default": 1, minimum: 0, units: "factor of the original icon size", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "icon-text-fit": { type: "enum", values: { none: { }, width: { }, height: { }, both: { } }, "default": "none", requires: [ "icon-image", "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-text-fit-padding": { type: "array", value: "number", length: 4, "default": [ 0, 0, 0, 0 ], units: "pixels", requires: [ "icon-image", "text-field", { "icon-text-fit": [ "both", "width", "height" ] } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-image": { type: "resolvedImage", tokens: true, expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "icon-rotate": { type: "number", "default": 0, period: 360, units: "degrees", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "icon-padding": { type: "number", "default": 2, minimum: 0, units: "pixels", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-keep-upright": { type: "boolean", "default": false, requires: [ "icon-image", { "icon-rotation-alignment": "map" }, { "symbol-placement": [ "line", "line-center" ] } ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-offset": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "icon-anchor": { type: "enum", values: { center: { }, left: { }, right: { }, top: { }, bottom: { }, "top-left": { }, "top-right": { }, "bottom-left": { }, "bottom-right": { } }, "default": "center", requires: [ "icon-image" ], expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "icon-pitch-alignment": { type: "enum", values: { map: { }, viewport: { }, auto: { } }, "default": "auto", requires: [ "icon-image" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-pitch-alignment": { type: "enum", values: { map: { }, viewport: { }, auto: { } }, "default": "auto", requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-rotation-alignment": { type: "enum", values: { map: { }, viewport: { }, auto: { } }, "default": "auto", requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-field": { type: "formatted", "default": "", tokens: true, expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-font": { type: "array", value: "string", "default": [ "Open Sans Regular", "Arial Unicode MS Regular" ], requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-size": { type: "number", "default": 16, minimum: 0, units: "pixels", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-max-width": { type: "number", "default": 10, minimum: 0, units: "ems", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-line-height": { type: "number", "default": 1.2, units: "ems", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-letter-spacing": { type: "number", "default": 0, units: "ems", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-justify": { type: "enum", values: { auto: { }, left: { }, center: { }, right: { } }, "default": "center", requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-radial-offset": { type: "number", units: "ems", "default": 0, requires: [ "text-field" ], "property-type": "data-driven", expression: { interpolated: true, parameters: [ "zoom", "feature" ] } }, "text-variable-anchor": { type: "array", value: "enum", values: { center: { }, left: { }, right: { }, top: { }, bottom: { }, "top-left": { }, "top-right": { }, "bottom-left": { }, "bottom-right": { } }, requires: [ "text-field", { "symbol-placement": [ "point" ] } ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-anchor": { type: "enum", values: { center: { }, left: { }, right: { }, top: { }, bottom: { }, "top-left": { }, "top-right": { }, "bottom-left": { }, "bottom-right": { } }, "default": "center", requires: [ "text-field", { "!": "text-variable-anchor" } ], expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-max-angle": { type: "number", "default": 45, units: "degrees", requires: [ "text-field", { "symbol-placement": [ "line", "line-center" ] } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-writing-mode": { type: "array", value: "enum", values: { horizontal: { }, vertical: { } }, requires: [ "text-field", { "symbol-placement": [ "point" ] } ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-rotate": { type: "number", "default": 0, period: 360, units: "degrees", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-padding": { type: "number", "default": 2, minimum: 0, units: "pixels", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-keep-upright": { type: "boolean", "default": true, requires: [ "text-field", { "text-rotation-alignment": "map" }, { "symbol-placement": [ "line", "line-center" ] } ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-transform": { type: "enum", values: { none: { }, uppercase: { }, lowercase: { } }, "default": "none", requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-offset": { type: "array", value: "number", units: "ems", length: 2, "default": [ 0, 0 ], requires: [ "text-field", { "!": "text-radial-offset" } ], expression: { interpolated: true, parameters: [ "zoom", "feature" ] }, "property-type": "data-driven" }, "text-allow-overlap": { type: "boolean", "default": false, requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-ignore-placement": { type: "boolean", "default": false, requires: [ "text-field" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-optional": { type: "boolean", "default": false, requires: [ "text-field", "icon-image" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_raster = { visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var layout_hillshade = { visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }; var filter = { type: "array", value: "*" }; var filter_operator = { type: "enum", values: { "==": { }, "!=": { }, ">": { }, ">=": { }, "<": { }, "<=": { }, "in": { }, "!in": { }, all: { }, any: { }, none: { }, has: { }, "!has": { }, within: { } } }; var geometry_type = { type: "enum", values: { Point: { }, LineString: { }, Polygon: { } } }; var function_stop = { type: "array", minimum: 0, maximum: 24, value: [ "number", "color" ], length: 2 }; var expression = { type: "array", value: "*", minimum: 1 }; var light = { anchor: { type: "enum", "default": "viewport", values: { map: { }, viewport: { } }, "property-type": "data-constant", transition: false, expression: { interpolated: false, parameters: [ "zoom" ] } }, position: { type: "array", "default": [ 1.15, 210, 30 ], length: 3, value: "number", "property-type": "data-constant", transition: true, expression: { interpolated: true, parameters: [ "zoom" ] } }, color: { type: "color", "property-type": "data-constant", "default": "#ffffff", expression: { interpolated: true, parameters: [ "zoom" ] }, transition: true }, intensity: { type: "number", "property-type": "data-constant", "default": 0.5, minimum: 0, maximum: 1, expression: { interpolated: true, parameters: [ "zoom" ] }, transition: true } }; var paint = [ "paint_fill", "paint_line", "paint_circle", "paint_heatmap", "paint_fill-extrusion", "paint_symbol", "paint_raster", "paint_hillshade", "paint_background" ]; var paint_fill = { "fill-antialias": { type: "boolean", "default": true, expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-color": { type: "color", "default": "#000000", transition: true, requires: [ { "!": "fill-pattern" } ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-outline-color": { type: "color", transition: true, requires: [ { "!": "fill-pattern" }, { "fill-antialias": true } ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "fill-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-pattern": { type: "resolvedImage", transition: true, expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "cross-faded-data-driven" } }; var paint_line = { "line-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-color": { type: "color", "default": "#000000", transition: true, requires: [ { "!": "line-pattern" } ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "line-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "line-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "line-width": { type: "number", "default": 1, minimum: 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-gap-width": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-offset": { type: "number", "default": 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-blur": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "line-dasharray": { type: "array", value: "number", minimum: 0, transition: true, units: "line widths", requires: [ { "!": "line-pattern" } ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "cross-faded" }, "line-pattern": { type: "resolvedImage", transition: true, expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "cross-faded-data-driven" }, "line-gradient": { type: "color", transition: false, requires: [ { "!": "line-dasharray" }, { "!": "line-pattern" }, { source: "geojson", has: { lineMetrics: true } } ], expression: { interpolated: true, parameters: [ "line-progress" ] }, "property-type": "color-ramp" } }; var paint_circle = { "circle-radius": { type: "number", "default": 5, minimum: 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-color": { type: "color", "default": "#000000", transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-blur": { type: "number", "default": 0, transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "circle-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "circle-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "circle-pitch-scale": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "circle-pitch-alignment": { type: "enum", values: { map: { }, viewport: { } }, "default": "viewport", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "circle-stroke-width": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-stroke-color": { type: "color", "default": "#000000", transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "circle-stroke-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" } }; var paint_heatmap = { "heatmap-radius": { type: "number", "default": 30, minimum: 1, transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "heatmap-weight": { type: "number", "default": 1, minimum: 0, transition: false, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "heatmap-intensity": { type: "number", "default": 1, minimum: 0, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "heatmap-color": { type: "color", "default": [ "interpolate", [ "linear" ], [ "heatmap-density" ], 0, "rgba(0, 0, 255, 0)", 0.1, "royalblue", 0.3, "cyan", 0.5, "lime", 0.7, "yellow", 1, "red" ], transition: false, expression: { interpolated: true, parameters: [ "heatmap-density" ] }, "property-type": "color-ramp" }, "heatmap-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" } }; var paint_symbol = { "icon-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "icon-color": { type: "color", "default": "#000000", transition: true, requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "icon-halo-color": { type: "color", "default": "rgba(0, 0, 0, 0)", transition: true, requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "icon-halo-width": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "icon-halo-blur": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "icon-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", requires: [ "icon-image" ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "icon-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "icon-image", "icon-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "text-color": { type: "color", "default": "#000000", transition: true, overridable: true, requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "text-halo-color": { type: "color", "default": "rgba(0, 0, 0, 0)", transition: true, requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "text-halo-width": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "text-halo-blur": { type: "number", "default": 0, minimum: 0, transition: true, units: "pixels", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "text-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", requires: [ "text-field" ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "text-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "text-field", "text-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" } }; var paint_raster = { "raster-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-hue-rotate": { type: "number", "default": 0, period: 360, transition: true, units: "degrees", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-brightness-min": { type: "number", "default": 0, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-brightness-max": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-saturation": { type: "number", "default": 0, minimum: -1, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-contrast": { type: "number", "default": 0, minimum: -1, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-resampling": { type: "enum", values: { linear: { }, nearest: { } }, "default": "linear", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "raster-fade-duration": { type: "number", "default": 300, minimum: 0, transition: false, units: "milliseconds", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" } }; var paint_hillshade = { "hillshade-illumination-direction": { type: "number", "default": 335, minimum: 0, maximum: 359, transition: false, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "hillshade-illumination-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "viewport", expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "hillshade-exaggeration": { type: "number", "default": 0.5, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "hillshade-shadow-color": { type: "color", "default": "#000000", transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "hillshade-highlight-color": { type: "color", "default": "#FFFFFF", transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "hillshade-accent-color": { type: "color", "default": "#000000", transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" } }; var paint_background = { "background-color": { type: "color", "default": "#000000", transition: true, requires: [ { "!": "background-pattern" } ], expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "background-pattern": { type: "resolvedImage", transition: true, expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "cross-faded" }, "background-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" } }; var transition = { duration: { type: "number", "default": 300, minimum: 0, units: "milliseconds" }, delay: { type: "number", "default": 0, minimum: 0, units: "milliseconds" } }; var promoteId = { "*": { type: "string" } }; var spec = { $version: $version, $root: $root, sources: sources, source: source, source_vector: source_vector, source_raster: source_raster, source_raster_dem: source_raster_dem, source_geojson: source_geojson, source_video: source_video, source_image: source_image, layer: layer, layout: layout, layout_background: layout_background, layout_fill: layout_fill, layout_circle: layout_circle, layout_heatmap: layout_heatmap, "layout_fill-extrusion": { visibility: { type: "enum", values: { visible: { }, none: { } }, "default": "visible", "property-type": "constant" } }, layout_line: layout_line, layout_symbol: layout_symbol, layout_raster: layout_raster, layout_hillshade: layout_hillshade, filter: filter, filter_operator: filter_operator, geometry_type: geometry_type, "function": { expression: { type: "expression" }, stops: { type: "array", value: "function_stop" }, base: { type: "number", "default": 1, minimum: 0 }, property: { type: "string", "default": "$zoom" }, type: { type: "enum", values: { identity: { }, exponential: { }, interval: { }, categorical: { } }, "default": "exponential" }, colorSpace: { type: "enum", values: { rgb: { }, lab: { }, hcl: { } }, "default": "rgb" }, "default": { type: "*", required: false } }, function_stop: function_stop, expression: expression, light: light, paint: paint, paint_fill: paint_fill, "paint_fill-extrusion": { "fill-extrusion-opacity": { type: "number", "default": 1, minimum: 0, maximum: 1, transition: true, expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-extrusion-color": { type: "color", "default": "#000000", transition: true, requires: [ { "!": "fill-extrusion-pattern" } ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-extrusion-translate": { type: "array", value: "number", length: 2, "default": [ 0, 0 ], transition: true, units: "pixels", expression: { interpolated: true, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-extrusion-translate-anchor": { type: "enum", values: { map: { }, viewport: { } }, "default": "map", requires: [ "fill-extrusion-translate" ], expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" }, "fill-extrusion-pattern": { type: "resolvedImage", transition: true, expression: { interpolated: false, parameters: [ "zoom", "feature" ] }, "property-type": "cross-faded-data-driven" }, "fill-extrusion-height": { type: "number", "default": 0, minimum: 0, units: "meters", transition: true, expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-extrusion-base": { type: "number", "default": 0, minimum: 0, units: "meters", transition: true, requires: [ "fill-extrusion-height" ], expression: { interpolated: true, parameters: [ "zoom", "feature", "feature-state" ] }, "property-type": "data-driven" }, "fill-extrusion-vertical-gradient": { type: "boolean", "default": true, transition: false, expression: { interpolated: false, parameters: [ "zoom" ] }, "property-type": "data-constant" } }, paint_line: paint_line, paint_circle: paint_circle, paint_heatmap: paint_heatmap, paint_symbol: paint_symbol, paint_raster: paint_raster, paint_hillshade: paint_hillshade, paint_background: paint_background, transition: transition, "property-type": { "data-driven": { type: "property-type" }, "cross-faded": { type: "property-type" }, "cross-faded-data-driven": { type: "property-type" }, "color-ramp": { type: "property-type" }, "data-constant": { type: "property-type" }, constant: { type: "property-type" } }, promoteId: promoteId }; var ValidationError = function ValidationError(key, value, message, identifier) { this.message = (key ? key + ': ' : '') + message; if (identifier) { this.identifier = identifier; } if (value !== null && value !== undefined && value.__line__) { this.line = value.__line__; } }; function validateConstants(options) { var key = options.key; var constants = options.value; if (constants) { return [new ValidationError(key, constants, 'constants have been deprecated as of v8')]; } else { return []; } } function extend$1 (output) { var inputs = [], len = arguments.length - 1; while (len-- > 0) inputs[len] = arguments[len + 1]; for (var i = 0, list = inputs; i < list.length; i += 1) { var input = list[i]; for (var k in input) { output[k] = input[k]; } } return output; } function unbundle(value) { if (value instanceof Number || value instanceof String || value instanceof Boolean) { return value.valueOf(); } else { return value; } } function deepUnbundle(value) { if (Array.isArray(value)) { return value.map(deepUnbundle); } else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) { var unbundledValue = {}; for (var key in value) { unbundledValue[key] = deepUnbundle(value[key]); } return unbundledValue; } return unbundle(value); } var ParsingError = function (Error) { function ParsingError(key, message) { Error.call(this, message); this.message = message; this.key = key; } if (Error) ParsingError.__proto__ = Error; ParsingError.prototype = Object.create(Error && Error.prototype); ParsingError.prototype.constructor = ParsingError; return ParsingError; }(Error); var Scope = function Scope(parent, bindings) { if (bindings === void 0) bindings = []; this.parent = parent; this.bindings = {}; for (var i = 0, list = bindings; i < list.length; i += 1) { var ref = list[i]; var name = ref[0]; var expression = ref[1]; this.bindings[name] = expression; } }; Scope.prototype.concat = function concat(bindings) { return new Scope(this, bindings); }; Scope.prototype.get = function get(name) { if (this.bindings[name]) { return this.bindings[name]; } if (this.parent) { return this.parent.get(name); } throw new Error(name + ' not found in scope.'); }; Scope.prototype.has = function has(name) { if (this.bindings[name]) { return true; } return this.parent ? this.parent.has(name) : false; }; var NullType = { kind: 'null' }; var NumberType = { kind: 'number' }; var StringType = { kind: 'string' }; var BooleanType = { kind: 'boolean' }; var ColorType = { kind: 'color' }; var ObjectType = { kind: 'object' }; var ValueType = { kind: 'value' }; var ErrorType = { kind: 'error' }; var CollatorType = { kind: 'collator' }; var FormattedType = { kind: 'formatted' }; var ResolvedImageType = { kind: 'resolvedImage' }; function array(itemType, N) { return { kind: 'array', itemType: itemType, N: N }; } function toString(type) { if (type.kind === 'array') { var itemType = toString(type.itemType); return typeof type.N === 'number' ? 'array<' + itemType + ', ' + type.N + '>' : type.itemType.kind === 'value' ? 'array' : 'array<' + itemType + '>'; } else { return type.kind; } } var valueMemberTypes = [ NullType, NumberType, StringType, BooleanType, ColorType, FormattedType, ObjectType, array(ValueType), ResolvedImageType ]; function checkSubtype(expected, t) { if (t.kind === 'error') { return null; } else if (expected.kind === 'array') { if (t.kind === 'array' && (t.N === 0 && t.itemType.kind === 'value' || !checkSubtype(expected.itemType, t.itemType)) && (typeof expected.N !== 'number' || expected.N === t.N)) { return null; } } else if (expected.kind === t.kind) { return null; } else if (expected.kind === 'value') { for (var i = 0, list = valueMemberTypes; i < list.length; i += 1) { var memberType = list[i]; if (!checkSubtype(memberType, t)) { return null; } } } return 'Expected ' + toString(expected) + ' but found ' + toString(t) + ' instead.'; } function isValidType(provided, allowedTypes) { return allowedTypes.some(function (t) { return t.kind === provided.kind; }); } function isValidNativeType(provided, allowedTypes) { return allowedTypes.some(function (t) { if (t === 'null') { return provided === null; } else if (t === 'array') { return Array.isArray(provided); } else if (t === 'object') { return provided && !Array.isArray(provided) && typeof provided === 'object'; } else { return t === typeof provided; } }); } var csscolorparser = createCommonjsModule(function (module, exports) { var kCSSColorTable = { 'transparent': [ 0, 0, 0, 0 ], 'aliceblue': [ 240, 248, 255, 1 ], 'antiquewhite': [ 250, 235, 215, 1 ], 'aqua': [ 0, 255, 255, 1 ], 'aquamarine': [ 127, 255, 212, 1 ], 'azure': [ 240, 255, 255, 1 ], 'beige': [ 245, 245, 220, 1 ], 'bisque': [ 255, 228, 196, 1 ], 'black': [ 0, 0, 0, 1 ], 'blanchedalmond': [ 255, 235, 205, 1 ], 'blue': [ 0, 0, 255, 1 ], 'blueviolet': [ 138, 43, 226, 1 ], 'brown': [ 165, 42, 42, 1 ], 'burlywood': [ 222, 184, 135, 1 ], 'cadetblue': [ 95, 158, 160, 1 ], 'chartreuse': [ 127, 255, 0, 1 ], 'chocolate': [ 210, 105, 30, 1 ], 'coral': [ 255, 127, 80, 1 ], 'cornflowerblue': [ 100, 149, 237, 1 ], 'cornsilk': [ 255, 248, 220, 1 ], 'crimson': [ 220, 20, 60, 1 ], 'cyan': [ 0, 255, 255, 1 ], 'darkblue': [ 0, 0, 139, 1 ], 'darkcyan': [ 0, 139, 139, 1 ], 'darkgoldenrod': [ 184, 134, 11, 1 ], 'darkgray': [ 169, 169, 169, 1 ], 'darkgreen': [ 0, 100, 0, 1 ], 'darkgrey': [ 169, 169, 169, 1 ], 'darkkhaki': [ 189, 183, 107, 1 ], 'darkmagenta': [ 139, 0, 139, 1 ], 'darkolivegreen': [ 85, 107, 47, 1 ], 'darkorange': [ 255, 140, 0, 1 ], 'darkorchid': [ 153, 50, 204, 1 ], 'darkred': [ 139, 0, 0, 1 ], 'darksalmon': [ 233, 150, 122, 1 ], 'darkseagreen': [ 143, 188, 143, 1 ], 'darkslateblue': [ 72, 61, 139, 1 ], 'darkslategray': [ 47, 79, 79, 1 ], 'darkslategrey': [ 47, 79, 79, 1 ], 'darkturquoise': [ 0, 206, 209, 1 ], 'darkviolet': [ 148, 0, 211, 1 ], 'deeppink': [ 255, 20, 147, 1 ], 'deepskyblue': [ 0, 191, 255, 1 ], 'dimgray': [ 105, 105, 105, 1 ], 'dimgrey': [ 105, 105, 105, 1 ], 'dodgerblue': [ 30, 144, 255, 1 ], 'firebrick': [ 178, 34, 34, 1 ], 'floralwhite': [ 255, 250, 240, 1 ], 'forestgreen': [ 34, 139, 34, 1 ], 'fuchsia': [ 255, 0, 255, 1 ], 'gainsboro': [ 220, 220, 220, 1 ], 'ghostwhite': [ 248, 248, 255, 1 ], 'gold': [ 255, 215, 0, 1 ], 'goldenrod': [ 218, 165, 32, 1 ], 'gray': [ 128, 128, 128, 1 ], 'green': [ 0, 128, 0, 1 ], 'greenyellow': [ 173, 255, 47, 1 ], 'grey': [ 128, 128, 128, 1 ], 'honeydew': [ 240, 255, 240, 1 ], 'hotpink': [ 255, 105, 180, 1 ], 'indianred': [ 205, 92, 92, 1 ], 'indigo': [ 75, 0, 130, 1 ], 'ivory': [ 255, 255, 240, 1 ], 'khaki': [ 240, 230, 140, 1 ], 'lavender': [ 230, 230, 250, 1 ], 'lavenderblush': [ 255, 240, 245, 1 ], 'lawngreen': [ 124, 252, 0, 1 ], 'lemonchiffon': [ 255, 250, 205, 1 ], 'lightblue': [ 173, 216, 230, 1 ], 'lightcoral': [ 240, 128, 128, 1 ], 'lightcyan': [ 224, 255, 255, 1 ], 'lightgoldenrodyellow': [ 250, 250, 210, 1 ], 'lightgray': [ 211, 211, 211, 1 ], 'lightgreen': [ 144, 238, 144, 1 ], 'lightgrey': [ 211, 211, 211, 1 ], 'lightpink': [ 255, 182, 193, 1 ], 'lightsalmon': [ 255, 160, 122, 1 ], 'lightseagreen': [ 32, 178, 170, 1 ], 'lightskyblue': [ 135, 206, 250, 1 ], 'lightslategray': [ 119, 136, 153, 1 ], 'lightslategrey': [ 119, 136, 153, 1 ], 'lightsteelblue': [ 176, 196, 222, 1 ], 'lightyellow': [ 255, 255, 224, 1 ], 'lime': [ 0, 255, 0, 1 ], 'limegreen': [ 50, 205, 50, 1 ], 'linen': [ 250, 240, 230, 1 ], 'magenta': [ 255, 0, 255, 1 ], 'maroon': [ 128, 0, 0, 1 ], 'mediumaquamarine': [ 102, 205, 170, 1 ], 'mediumblue': [ 0, 0, 205, 1 ], 'mediumorchid': [ 186, 85, 211, 1 ], 'mediumpurple': [ 147, 112, 219, 1 ], 'mediumseagreen': [ 60, 179, 113, 1 ], 'mediumslateblue': [ 123, 104, 238, 1 ], 'mediumspringgreen': [ 0, 250, 154, 1 ], 'mediumturquoise': [ 72, 209, 204, 1 ], 'mediumvioletred': [ 199, 21, 133, 1 ], 'midnightblue': [ 25, 25, 112, 1 ], 'mintcream': [ 245, 255, 250, 1 ], 'mistyrose': [ 255, 228, 225, 1 ], 'moccasin': [ 255, 228, 181, 1 ], 'navajowhite': [ 255, 222, 173, 1 ], 'navy': [ 0, 0, 128, 1 ], 'oldlace': [ 253, 245, 230, 1 ], 'olive': [ 128, 128, 0, 1 ], 'olivedrab': [ 107, 142, 35, 1 ], 'orange': [ 255, 165, 0, 1 ], 'orangered': [ 255, 69, 0, 1 ], 'orchid': [ 218, 112, 214, 1 ], 'palegoldenrod': [ 238, 232, 170, 1 ], 'palegreen': [ 152, 251, 152, 1 ], 'paleturquoise': [ 175, 238, 238, 1 ], 'palevioletred': [ 219, 112, 147, 1 ], 'papayawhip': [ 255, 239, 213, 1 ], 'peachpuff': [ 255, 218, 185, 1 ], 'peru': [ 205, 133, 63, 1 ], 'pink': [ 255, 192, 203, 1 ], 'plum': [ 221, 160, 221, 1 ], 'powderblue': [ 176, 224, 230, 1 ], 'purple': [ 128, 0, 128, 1 ], 'rebeccapurple': [ 102, 51, 153, 1 ], 'red': [ 255, 0, 0, 1 ], 'rosybrown': [ 188, 143, 143, 1 ], 'royalblue': [ 65, 105, 225, 1 ], 'saddlebrown': [ 139, 69, 19, 1 ], 'salmon': [ 250, 128, 114, 1 ], 'sandybrown': [ 244, 164, 96, 1 ], 'seagreen': [ 46, 139, 87, 1 ], 'seashell': [ 255, 245, 238, 1 ], 'sienna': [ 160, 82, 45, 1 ], 'silver': [ 192, 192, 192, 1 ], 'skyblue': [ 135, 206, 235, 1 ], 'slateblue': [ 106, 90, 205, 1 ], 'slategray': [ 112, 128, 144, 1 ], 'slategrey': [ 112, 128, 144, 1 ], 'snow': [ 255, 250, 250, 1 ], 'springgreen': [ 0, 255, 127, 1 ], 'steelblue': [ 70, 130, 180, 1 ], 'tan': [ 210, 180, 140, 1 ], 'teal': [ 0, 128, 128, 1 ], 'thistle': [ 216, 191, 216, 1 ], 'tomato': [ 255, 99, 71, 1 ], 'turquoise': [ 64, 224, 208, 1 ], 'violet': [ 238, 130, 238, 1 ], 'wheat': [ 245, 222, 179, 1 ], 'white': [ 255, 255, 255, 1 ], 'whitesmoke': [ 245, 245, 245, 1 ], 'yellow': [ 255, 255, 0, 1 ], 'yellowgreen': [ 154, 205, 50, 1 ] }; function clamp_css_byte(i) { i = Math.round(i); return i < 0 ? 0 : i > 255 ? 255 : i; } function clamp_css_float(f) { return f < 0 ? 0 : f > 1 ? 1 : f; } function parse_css_int(str) { if (str[str.length - 1] === '%') { return clamp_css_byte(parseFloat(str) / 100 * 255); } return clamp_css_byte(parseInt(str)); } function parse_css_float(str) { if (str[str.length - 1] === '%') { return clamp_css_float(parseFloat(str) / 100); } return clamp_css_float(parseFloat(str)); } function css_hue_to_rgb(m1, m2, h) { if (h < 0) { h += 1; } else if (h > 1) { h -= 1; } if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } if (h * 2 < 1) { return m2; } if (h * 3 < 2) { return m1 + (m2 - m1) * (2 / 3 - h) * 6; } return m1; } function parseCSSColor(css_str) { var str = css_str.replace(/ /g, '').toLowerCase(); if (str in kCSSColorTable) { return kCSSColorTable[str].slice(); } if (str[0] === '#') { if (str.length === 4) { var iv = parseInt(str.substr(1), 16); if (!(iv >= 0 && iv <= 4095)) { return null; } return [ (iv & 3840) >> 4 | (iv & 3840) >> 8, iv & 240 | (iv & 240) >> 4, iv & 15 | (iv & 15) << 4, 1 ]; } else if (str.length === 7) { var iv = parseInt(str.substr(1), 16); if (!(iv >= 0 && iv <= 16777215)) { return null; } return [ (iv & 16711680) >> 16, (iv & 65280) >> 8, iv & 255, 1 ]; } return null; } var op = str.indexOf('('), ep = str.indexOf(')'); if (op !== -1 && ep + 1 === str.length) { var fname = str.substr(0, op); var params = str.substr(op + 1, ep - (op + 1)).split(','); var alpha = 1; switch (fname) { case 'rgba': if (params.length !== 4) { return null; } alpha = parse_css_float(params.pop()); case 'rgb': if (params.length !== 3) { return null; } return [ parse_css_int(params[0]), parse_css_int(params[1]), parse_css_int(params[2]), alpha ]; case 'hsla': if (params.length !== 4) { return null; } alpha = parse_css_float(params.pop()); case 'hsl': if (params.length !== 3) { return null; } var h = (parseFloat(params[0]) % 360 + 360) % 360 / 360; var s = parse_css_float(params[1]); var l = parse_css_float(params[2]); var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; var m1 = l * 2 - m2; return [ clamp_css_byte(css_hue_to_rgb(m1, m2, h + 1 / 3) * 255), clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255), clamp_css_byte(css_hue_to_rgb(m1, m2, h - 1 / 3) * 255), alpha ]; default: return null; } } return null; } try { exports.parseCSSColor = parseCSSColor; } catch (e) { } }); var csscolorparser_1 = csscolorparser.parseCSSColor; var Color = function Color(r, g, b, a) { if (a === void 0) a = 1; this.r = r; this.g = g; this.b = b; this.a = a; }; Color.parse = function parse(input) { if (!input) { return undefined; } if (input instanceof Color) { return input; } if (typeof input !== 'string') { return undefined; } var rgba = csscolorparser_1(input); if (!rgba) { return undefined; } return new Color(rgba[0] / 255 * rgba[3], rgba[1] / 255 * rgba[3], rgba[2] / 255 * rgba[3], rgba[3]); }; Color.prototype.toString = function toString() { var ref = this.toArray(); var r = ref[0]; var g = ref[1]; var b = ref[2]; var a = ref[3]; return 'rgba(' + Math.round(r) + ',' + Math.round(g) + ',' + Math.round(b) + ',' + a + ')'; }; Color.prototype.toArray = function toArray() { var ref = this; var r = ref.r; var g = ref.g; var b = ref.b; var a = ref.a; return a === 0 ? [ 0, 0, 0, 0 ] : [ r * 255 / a, g * 255 / a, b * 255 / a, a ]; }; Color.black = new Color(0, 0, 0, 1); Color.white = new Color(1, 1, 1, 1); Color.transparent = new Color(0, 0, 0, 0); Color.red = new Color(1, 0, 0, 1); var Collator = function Collator(caseSensitive, diacriticSensitive, locale) { if (caseSensitive) { this.sensitivity = diacriticSensitive ? 'variant' : 'case'; } else { this.sensitivity = diacriticSensitive ? 'accent' : 'base'; } this.locale = locale; this.collator = new Intl.Collator(this.locale ? this.locale : [], { sensitivity: this.sensitivity, usage: 'search' }); }; Collator.prototype.compare = function compare(lhs, rhs) { return this.collator.compare(lhs, rhs); }; Collator.prototype.resolvedLocale = function resolvedLocale() { return new Intl.Collator(this.locale ? this.locale : []).resolvedOptions().locale; }; var FormattedSection = function FormattedSection(text, image, scale, fontStack, textColor) { this.text = text; this.image = image; this.scale = scale; this.fontStack = fontStack; this.textColor = textColor; }; var Formatted = function Formatted(sections) { this.sections = sections; }; Formatted.fromString = function fromString(unformatted) { return new Formatted([new FormattedSection(unformatted, null, null, null, null)]); }; Formatted.prototype.isEmpty = function isEmpty() { if (this.sections.length === 0) { return true; } return !this.sections.some(function (section) { return section.text.length !== 0 || section.image && section.image.name.length !== 0; }); }; Formatted.factory = function factory(text) { if (text instanceof Formatted) { return text; } else { return Formatted.fromString(text); } }; Formatted.prototype.toString = function toString() { if (this.sections.length === 0) { return ''; } return this.sections.map(function (section) { return section.text; }).join(''); }; Formatted.prototype.serialize = function serialize() { var serialized = ['format']; for (var i = 0, list = this.sections; i < list.length; i += 1) { var section = list[i]; if (section.image) { serialized.push([ 'image', section.image.name ]); continue; } serialized.push(section.text); var options = {}; if (section.fontStack) { options['text-font'] = [ 'literal', section.fontStack.split(',') ]; } if (section.scale) { options['font-scale'] = section.scale; } if (section.textColor) { options['text-color'] = ['rgba'].concat(section.textColor.toArray()); } serialized.push(options); } return serialized; }; var ResolvedImage = function ResolvedImage(options) { this.name = options.name; this.available = options.available; }; ResolvedImage.prototype.toString = function toString() { return this.name; }; ResolvedImage.fromString = function fromString(name) { if (!name) { return null; } return new ResolvedImage({ name: name, available: false }); }; ResolvedImage.prototype.serialize = function serialize() { return [ 'image', this.name ]; }; function validateRGBA(r, g, b, a) { if (!(typeof r === 'number' && r >= 0 && r <= 255 && typeof g === 'number' && g >= 0 && g <= 255 && typeof b === 'number' && b >= 0 && b <= 255)) { var value = typeof a === 'number' ? [ r, g, b, a ] : [ r, g, b ]; return 'Invalid rgba value [' + value.join(', ') + ']: \'r\', \'g\', and \'b\' must be between 0 and 255.'; } if (!(typeof a === 'undefined' || typeof a === 'number' && a >= 0 && a <= 1)) { return 'Invalid rgba value [' + [ r, g, b, a ].join(', ') + ']: \'a\' must be between 0 and 1.'; } return null; } function isValue(mixed) { if (mixed === null) { return true; } else if (typeof mixed === 'string') { return true; } else if (typeof mixed === 'boolean') { return true; } else if (typeof mixed === 'number') { return true; } else if (mixed instanceof Color) { return true; } else if (mixed instanceof Collator) { return true; } else if (mixed instanceof Formatted) { return true; } else if (mixed instanceof ResolvedImage) { return true; } else if (Array.isArray(mixed)) { for (var i = 0, list = mixed; i < list.length; i += 1) { var item = list[i]; if (!isValue(item)) { return false; } } return true; } else if (typeof mixed === 'object') { for (var key in mixed) { if (!isValue(mixed[key])) { return false; } } return true; } else { return false; } } function typeOf(value) { if (value === null) { return NullType; } else if (typeof value === 'string') { return StringType; } else if (typeof value === 'boolean') { return BooleanType; } else if (typeof value === 'number') { return NumberType; } else if (value instanceof Color) { return ColorType; } else if (value instanceof Collator) { return CollatorType; } else if (value instanceof Formatted) { return FormattedType; } else if (value instanceof ResolvedImage) { return ResolvedImageType; } else if (Array.isArray(value)) { var length = value.length; var itemType; for (var i = 0, list = value; i < list.length; i += 1) { var item = list[i]; var t = typeOf(item); if (!itemType) { itemType = t; } else if (itemType === t) { continue; } else { itemType = ValueType; break; } } return array(itemType || ValueType, length); } else { return ObjectType; } } function toString$1(value) { var type = typeof value; if (value === null) { return ''; } else if (type === 'string' || type === 'number' || type === 'boolean') { return String(value); } else if (value instanceof Color || value instanceof Formatted || value instanceof ResolvedImage) { return value.toString(); } else { return JSON.stringify(value); } } var Literal = function Literal(type, value) { this.type = type; this.value = value; }; Literal.parse = function parse(args, context) { if (args.length !== 2) { return context.error('\'literal\' expression requires exactly one argument, but found ' + (args.length - 1) + ' instead.'); } if (!isValue(args[1])) { return context.error('invalid value'); } var value = args[1]; var type = typeOf(value); var expected = context.expectedType; if (type.kind === 'array' && type.N === 0 && expected && expected.kind === 'array' && (typeof expected.N !== 'number' || expected.N === 0)) { type = expected; } return new Literal(type, value); }; Literal.prototype.evaluate = function evaluate() { return this.value; }; Literal.prototype.eachChild = function eachChild() { }; Literal.prototype.outputDefined = function outputDefined() { return true; }; Literal.prototype.serialize = function serialize() { if (this.type.kind === 'array' || this.type.kind === 'object') { return [ 'literal', this.value ]; } else if (this.value instanceof Color) { return ['rgba'].concat(this.value.toArray()); } else if (this.value instanceof Formatted) { return this.value.serialize(); } else { return this.value; } }; var RuntimeError = function RuntimeError(message) { this.name = 'ExpressionEvaluationError'; this.message = message; }; RuntimeError.prototype.toJSON = function toJSON() { return this.message; }; var types = { string: StringType, number: NumberType, boolean: BooleanType, object: ObjectType }; var Assertion = function Assertion(type, args) { this.type = type; this.args = args; }; Assertion.parse = function parse(args, context) { if (args.length < 2) { return context.error('Expected at least one argument.'); } var i = 1; var type; var name = args[0]; if (name === 'array') { var itemType; if (args.length > 2) { var type$1 = args[1]; if (typeof type$1 !== 'string' || !(type$1 in types) || type$1 === 'object') { return context.error('The item type argument of "array" must be one of string, number, boolean', 1); } itemType = types[type$1]; i++; } else { itemType = ValueType; } var N; if (args.length > 3) { if (args[2] !== null && (typeof args[2] !== 'number' || args[2] < 0 || args[2] !== Math.floor(args[2]))) { return context.error('The length argument to "array" must be a positive integer literal', 2); } N = args[2]; i++; } type = array(itemType, N); } else { type = types[name]; } var parsed = []; for (; i < args.length; i++) { var input = context.parse(args[i], i, ValueType); if (!input) { return null; } parsed.push(input); } return new Assertion(type, parsed); }; Assertion.prototype.evaluate = function evaluate(ctx) { for (var i = 0; i < this.args.length; i++) { var value = this.args[i].evaluate(ctx); var error = checkSubtype(this.type, typeOf(value)); if (!error) { return value; } else if (i === this.args.length - 1) { throw new RuntimeError('Expected value to be of type ' + toString(this.type) + ', but found ' + toString(typeOf(value)) + ' instead.'); } } return null; }; Assertion.prototype.eachChild = function eachChild(fn) { this.args.forEach(fn); }; Assertion.prototype.outputDefined = function outputDefined() { return this.args.every(function (arg) { return arg.outputDefined(); }); }; Assertion.prototype.serialize = function serialize() { var type = this.type; var serialized = [type.kind]; if (type.kind === 'array') { var itemType = type.itemType; if (itemType.kind === 'string' || itemType.kind === 'number' || itemType.kind === 'boolean') { serialized.push(itemType.kind); var N = type.N; if (typeof N === 'number' || this.args.length > 1) { serialized.push(N); } } } return serialized.concat(this.args.map(function (arg) { return arg.serialize(); })); }; var FormatExpression = function FormatExpression(sections) { this.type = FormattedType; this.sections = sections; }; FormatExpression.parse = function parse(args, context) { if (args.length < 2) { return context.error('Expected at least one argument.'); } var firstArg = args[1]; if (!Array.isArray(firstArg) && typeof firstArg === 'object') { return context.error('First argument must be an image or text section.'); } var sections = []; var nextTokenMayBeObject = false; for (var i = 1; i <= args.length - 1; ++i) { var arg = args[i]; if (nextTokenMayBeObject && typeof arg === 'object' && !Array.isArray(arg)) { nextTokenMayBeObject = false; var scale = null; if (arg['font-scale']) { scale = context.parse(arg['font-scale'], 1, NumberType); if (!scale) { return null; } } var font = null; if (arg['text-font']) { font = context.parse(arg['text-font'], 1, array(StringType)); if (!font) { return null; } } var textColor = null; if (arg['text-color']) { textColor = context.parse(arg['text-color'], 1, ColorType); if (!textColor) { return null; } } var lastExpression = sections[sections.length - 1]; lastExpression.scale = scale; lastExpression.font = font; lastExpression.textColor = textColor; } else { var content = context.parse(args[i], 1, ValueType); if (!content) { return null; } var kind = content.type.kind; if (kind !== 'string' && kind !== 'value' && kind !== 'null' && kind !== 'resolvedImage') { return context.error('Formatted text type must be \'string\', \'value\', \'image\' or \'null\'.'); } nextTokenMayBeObject = true; sections.push({ content: content, scale: null, font: null, textColor: null }); } } return new FormatExpression(sections); }; FormatExpression.prototype.evaluate = function evaluate(ctx) { var evaluateSection = function (section) { var evaluatedContent = section.content.evaluate(ctx); if (typeOf(evaluatedContent) === ResolvedImageType) { return new FormattedSection('', evaluatedContent, null, null, null); } return new FormattedSection(toString$1(evaluatedContent), null, section.scale ? section.scale.evaluate(ctx) : null, section.font ? section.font.evaluate(ctx).join(',') : null, section.textColor ? section.textColor.evaluate(ctx) : null); }; return new Formatted(this.sections.map(evaluateSection)); }; FormatExpression.prototype.eachChild = function eachChild(fn) { for (var i = 0, list = this.sections; i < list.length; i += 1) { var section = list[i]; fn(section.content); if (section.scale) { fn(section.scale); } if (section.font) { fn(section.font); } if (section.textColor) { fn(section.textColor); } } }; FormatExpression.prototype.outputDefined = function outputDefined() { return false; }; FormatExpression.prototype.serialize = function serialize() { var serialized = ['format']; for (var i = 0, list = this.sections; i < list.length; i += 1) { var section = list[i]; serialized.push(section.content.serialize()); var options = {}; if (section.scale) { options['font-scale'] = section.scale.serialize(); } if (section.font) { options['text-font'] = section.font.serialize(); } if (section.textColor) { options['text-color'] = section.textColor.serialize(); } serialized.push(options); } return serialized; }; var ImageExpression = function ImageExpression(input) { this.type = ResolvedImageType; this.input = input; }; ImageExpression.parse = function parse(args, context) { if (args.length !== 2) { return context.error('Expected two arguments.'); } var name = context.parse(args[1], 1, StringType); if (!name) { return context.error('No image name provided.'); } return new ImageExpression(name); }; ImageExpression.prototype.evaluate = function evaluate(ctx) { var evaluatedImageName = this.input.evaluate(ctx); var value = ResolvedImage.fromString(evaluatedImageName); if (value && ctx.availableImages) { value.available = ctx.availableImages.indexOf(evaluatedImageName) > -1; } return value; }; ImageExpression.prototype.eachChild = function eachChild(fn) { fn(this.input); }; ImageExpression.prototype.outputDefined = function outputDefined() { return false; }; ImageExpression.prototype.serialize = function serialize() { return [ 'image', this.input.serialize() ]; }; var types$1 = { 'to-boolean': BooleanType, 'to-color': ColorType, 'to-number': NumberType, 'to-string': StringType }; var Coercion = function Coercion(type, args) { this.type = type; this.args = args; }; Coercion.parse = function parse(args, context) { if (args.length < 2) { return context.error('Expected at least one argument.'); } var name = args[0]; if ((name === 'to-boolean' || name === 'to-string') && args.length !== 2) { return context.error('Expected one argument.'); } var type = types$1[name]; var parsed = []; for (var i = 1; i < args.length; i++) { var input = context.parse(args[i], i, ValueType); if (!input) { return null; } parsed.push(input); } return new Coercion(type, parsed); }; Coercion.prototype.evaluate = function evaluate(ctx) { if (this.type.kind === 'boolean') { return Boolean(this.args[0].evaluate(ctx)); } else if (this.type.kind === 'color') { var input; var error; for (var i = 0, list = this.args; i < list.length; i += 1) { var arg = list[i]; input = arg.evaluate(ctx); error = null; if (input instanceof Color) { return input; } else if (typeof input === 'string') { var c = ctx.parseColor(input); if (c) { return c; } } else if (Array.isArray(input)) { if (input.length < 3 || input.length > 4) { error = 'Invalid rbga value ' + JSON.stringify(input) + ': expected an array containing either three or four numeric values.'; } else { error = validateRGBA(input[0], input[1], input[2], input[3]); } if (!error) { return new Color(input[0] / 255, input[1] / 255, input[2] / 255, input[3]); } } } throw new RuntimeError(error || 'Could not parse color from value \'' + (typeof input === 'string' ? input : String(JSON.stringify(input))) + '\''); } else if (this.type.kind === 'number') { var value = null; for (var i$1 = 0, list$1 = this.args; i$1 < list$1.length; i$1 += 1) { var arg$1 = list$1[i$1]; value = arg$1.evaluate(ctx); if (value === null) { return 0; } var num = Number(value); if (isNaN(num)) { continue; } return num; } throw new RuntimeError('Could not convert ' + JSON.stringify(value) + ' to number.'); } else if (this.type.kind === 'formatted') { return Formatted.fromString(toString$1(this.args[0].evaluate(ctx))); } else if (this.type.kind === 'resolvedImage') { return ResolvedImage.fromString(toString$1(this.args[0].evaluate(ctx))); } else { return toString$1(this.args[0].evaluate(ctx)); } }; Coercion.prototype.eachChild = function eachChild(fn) { this.args.forEach(fn); }; Coercion.prototype.outputDefined = function outputDefined() { return this.args.every(function (arg) { return arg.outputDefined(); }); }; Coercion.prototype.serialize = function serialize() { if (this.type.kind === 'formatted') { return new FormatExpression([{ content: this.args[0], scale: null, font: null, textColor: null }]).serialize(); } if (this.type.kind === 'resolvedImage') { return new ImageExpression(this.args[0]).serialize(); } var serialized = ['to-' + this.type.kind]; this.eachChild(function (child) { serialized.push(child.serialize()); }); return serialized; }; var geometryTypes = [ 'Unknown', 'Point', 'LineString', 'Polygon' ]; var EvaluationContext = function EvaluationContext() { this.globals = null; this.feature = null; this.featureState = null; this.formattedSection = null; this._parseColorCache = {}; this.availableImages = null; this.canonical = null; }; EvaluationContext.prototype.id = function id() { return this.feature && 'id' in this.feature ? this.feature.id : null; }; EvaluationContext.prototype.geometryType = function geometryType() { return this.feature ? typeof this.feature.type === 'number' ? geometryTypes[this.feature.type] : this.feature.type : null; }; EvaluationContext.prototype.geometry = function geometry() { return this.feature && 'geometry' in this.feature ? this.feature.geometry : null; }; EvaluationContext.prototype.canonicalID = function canonicalID() { return this.canonical; }; EvaluationContext.prototype.properties = function properties() { return this.feature && this.feature.properties || {}; }; EvaluationContext.prototype.parseColor = function parseColor(input) { var cached = this._parseColorCache[input]; if (!cached) { cached = this._parseColorCache[input] = Color.parse(input); } return cached; }; var CompoundExpression = function CompoundExpression(name, type, evaluate, args) { this.name = name; this.type = type; this._evaluate = evaluate; this.args = args; }; CompoundExpression.prototype.evaluate = function evaluate(ctx) { return this._evaluate(ctx, this.args); }; CompoundExpression.prototype.eachChild = function eachChild(fn) { this.args.forEach(fn); }; CompoundExpression.prototype.outputDefined = function outputDefined() { return false; }; CompoundExpression.prototype.serialize = function serialize() { return [this.name].concat(this.args.map(function (arg) { return arg.serialize(); })); }; CompoundExpression.parse = function parse(args, context) { var ref$1; var op = args[0]; var definition = CompoundExpression.definitions[op]; if (!definition) { return context.error('Unknown expression "' + op + '". If you wanted a literal array, use ["literal", [...]].', 0); } var type = Array.isArray(definition) ? definition[0] : definition.type; var availableOverloads = Array.isArray(definition) ? [[ definition[1], definition[2] ]] : definition.overloads; var overloads = availableOverloads.filter(function (ref) { var signature = ref[0]; return !Array.isArray(signature) || signature.length === args.length - 1; }); var signatureContext = null; for (var i$3 = 0, list = overloads; i$3 < list.length; i$3 += 1) { var ref = list[i$3]; var params = ref[0]; var evaluate = ref[1]; signatureContext = new ParsingContext(context.registry, context.path, null, context.scope); var parsedArgs = []; var argParseFailed = false; for (var i = 1; i < args.length; i++) { var arg = args[i]; var expectedType = Array.isArray(params) ? params[i - 1] : params.type; var parsed = signatureContext.parse(arg, 1 + parsedArgs.length, expectedType); if (!parsed) { argParseFailed = true; break; } parsedArgs.push(parsed); } if (argParseFailed) { continue; } if (Array.isArray(params)) { if (params.length !== parsedArgs.length) { signatureContext.error('Expected ' + params.length + ' arguments, but found ' + parsedArgs.length + ' instead.'); continue; } } for (var i$1 = 0; i$1 < parsedArgs.length; i$1++) { var expected = Array.isArray(params) ? params[i$1] : params.type; var arg$1 = parsedArgs[i$1]; signatureContext.concat(i$1 + 1).checkSubtype(expected, arg$1.type); } if (signatureContext.errors.length === 0) { return new CompoundExpression(op, type, evaluate, parsedArgs); } } if (overloads.length === 1) { (ref$1 = context.errors).push.apply(ref$1, signatureContext.errors); } else { var expected$1 = overloads.length ? overloads : availableOverloads; var signatures = expected$1.map(function (ref) { var params = ref[0]; return stringifySignature(params); }).join(' | '); var actualTypes = []; for (var i$2 = 1; i$2 < args.length; i$2++) { var parsed$1 = context.parse(args[i$2], 1 + actualTypes.length); if (!parsed$1) { return null; } actualTypes.push(toString(parsed$1.type)); } context.error('Expected arguments of type ' + signatures + ', but found (' + actualTypes.join(', ') + ') instead.'); } return null; }; CompoundExpression.register = function register(registry, definitions) { CompoundExpression.definitions = definitions; for (var name in definitions) { registry[name] = CompoundExpression; } }; function stringifySignature(signature) { if (Array.isArray(signature)) { return '(' + signature.map(toString).join(', ') + ')'; } else { return '(' + toString(signature.type) + '...)'; } } var CollatorExpression = function CollatorExpression(caseSensitive, diacriticSensitive, locale) { this.type = CollatorType; this.locale = locale; this.caseSensitive = caseSensitive; this.diacriticSensitive = diacriticSensitive; }; CollatorExpression.parse = function parse(args, context) { if (args.length !== 2) { return context.error('Expected one argument.'); } var options = args[1]; if (typeof options !== 'object' || Array.isArray(options)) { return context.error('Collator options argument must be an object.'); } var caseSensitive = context.parse(options['case-sensitive'] === undefined ? false : options['case-sensitive'], 1, BooleanType); if (!caseSensitive) { return null; } var diacriticSensitive = context.parse(options['diacritic-sensitive'] === undefined ? false : options['diacritic-sensitive'], 1, BooleanType); if (!diacriticSensitive) { return null; } var locale = null; if (options['locale']) { locale = context.parse(options['locale'], 1, StringType); if (!locale) { return null; } } return new CollatorExpression(caseSensitive, diacriticSensitive, locale); }; CollatorExpression.prototype.evaluate = function evaluate(ctx) { return new Collator(this.caseSensitive.evaluate(ctx), this.diacriticSensitive.evaluate(ctx), this.locale ? this.locale.evaluate(ctx) : null); }; CollatorExpression.prototype.eachChild = function eachChild(fn) { fn(this.caseSensitive); fn(this.diacriticSensitive); if (this.locale) { fn(this.locale); } }; CollatorExpression.prototype.outputDefined = function outputDefined() { return false; }; CollatorExpression.prototype.serialize = function serialize() { var options = {}; options['case-sensitive'] = this.caseSensitive.serialize(); options['diacritic-sensitive'] = this.diacriticSensitive.serialize(); if (this.locale) { options['locale'] = this.locale.serialize(); } return [ 'collator', options ]; }; var EXTENT = 8192; function updateBBox(bbox, coord) { bbox[0] = Math.min(bbox[0], coord[0]); bbox[1] = Math.min(bbox[1], coord[1]); bbox[2] = Math.max(bbox[2], coord[0]); bbox[3] = Math.max(bbox[3], coord[1]); } function mercatorXfromLng(lng) { return (180 + lng) / 360; } function mercatorYfromLat(lat) { return (180 - 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360))) / 360; } function boxWithinBox(bbox1, bbox2) { if (bbox1[0] <= bbox2[0]) { return false; } if (bbox1[2] >= bbox2[2]) { return false; } if (bbox1[1] <= bbox2[1]) { return false; } if (bbox1[3] >= bbox2[3]) { return false; } return true; } function getTileCoordinates(p, canonical) { var x = mercatorXfromLng(p[0]); var y = mercatorYfromLat(p[1]); var tilesAtZoom = Math.pow(2, canonical.z); return [ Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT) ]; } function onBoundary(p, p1, p2) { var x1 = p[0] - p1[0]; var y1 = p[1] - p1[1]; var x2 = p[0] - p2[0]; var y2 = p[1] - p2[1]; return x1 * y2 - x2 * y1 === 0 && x1 * x2 <= 0 && y1 * y2 <= 0; } function rayIntersect(p, p1, p2) { 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]; } function pointWithinPolygon(point, rings) { var inside = false; for (var i = 0, len = rings.length; i < len; i++) { var ring = rings[i]; for (var j = 0, len2 = ring.length; j < len2 - 1; j++) { if (onBoundary(point, ring[j], ring[j + 1])) { return false; } if (rayIntersect(point, ring[j], ring[j + 1])) { inside = !inside; } } } return inside; } function pointWithinPolygons(point, polygons) { for (var i = 0; i < polygons.length; i++) { if (pointWithinPolygon(point, polygons[i])) { return true; } } return false; } function perp(v1, v2) { return v1[0] * v2[1] - v1[1] * v2[0]; } function twoSided(p1, p2, q1, q2) { var x1 = p1[0] - q1[0]; var y1 = p1[1] - q1[1]; var x2 = p2[0] - q1[0]; var y2 = p2[1] - q1[1]; var x3 = q2[0] - q1[0]; var y3 = q2[1] - q1[1]; var det1 = x1 * y3 - x3 * y1; var det2 = x2 * y3 - x3 * y2; if (det1 > 0 && det2 < 0 || det1 < 0 && det2 > 0) { return true; } return false; } function lineIntersectLine(a, b, c, d) { var vectorP = [ b[0] - a[0], b[1] - a[1] ]; var vectorQ = [ d[0] - c[0], d[1] - c[1] ]; if (perp(vectorQ, vectorP) === 0) { return false; } if (twoSided(a, b, c, d) && twoSided(c, d, a, b)) { return true; } return false; } function lineIntersectPolygon(p1, p2, polygon) { for (var i = 0, list = polygon; i < list.length; i += 1) { var ring = list[i]; for (var j = 0; j < ring.length - 1; ++j) { if (lineIntersectLine(p1, p2, ring[j], ring[j + 1])) { return true; } } } return false; } function lineStringWithinPolygon(line, polygon) { for (var i = 0; i < line.length; ++i) { if (!pointWithinPolygon(line[i], polygon)) { return false; } } for (var i$1 = 0; i$1 < line.length - 1; ++i$1) { if (lineIntersectPolygon(line[i$1], line[i$1 + 1], polygon)) { return false; } } return true; } function lineStringWithinPolygons(line, polygons) { for (var i = 0; i < polygons.length; i++) { if (lineStringWithinPolygon(line, polygons[i])) { return true; } } return false; } function getTilePolygon(coordinates, bbox, canonical) { var polygon = []; for (var i = 0; i < coordinates.length; i++) { var ring = []; for (var j = 0; j < coordinates[i].length; j++) { var coord = getTileCoordinates(coordinates[i][j], canonical); updateBBox(bbox, coord); ring.push(coord); } polygon.push(ring); } return polygon; } function getTilePolygons(coordinates, bbox, canonical) { var polygons = []; for (var i = 0; i < coordinates.length; i++) { var polygon = getTilePolygon(coordinates[i], bbox, canonical); polygons.push(polygon); } return polygons; } function updatePoint(p, bbox, polyBBox, worldSize) { if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) { var halfWorldSize = worldSize * 0.5; var shift = p[0] - polyBBox[0] > halfWorldSize ? -worldSize : polyBBox[0] - p[0] > halfWorldSize ? worldSize : 0; if (shift === 0) { shift = p[0] - polyBBox[2] > halfWorldSize ? -worldSize : polyBBox[2] - p[0] > halfWorldSize ? worldSize : 0; } p[0] += shift; } updateBBox(bbox, p); } function resetBBox(bbox) { bbox[0] = bbox[1] = Infinity; bbox[2] = bbox[3] = -Infinity; } function getTilePoints(geometry, pointBBox, polyBBox, canonical) { var worldSize = Math.pow(2, canonical.z) * EXTENT; var shifts = [ canonical.x * EXTENT, canonical.y * EXTENT ]; var tilePoints = []; for (var i$1 = 0, list$1 = geometry; i$1 < list$1.length; i$1 += 1) { var points = list$1[i$1]; for (var i = 0, list = points; i < list.length; i += 1) { var point = list[i]; var p = [ point.x + shifts[0], point.y + shifts[1] ]; updatePoint(p, pointBBox, polyBBox, worldSize); tilePoints.push(p); } } return tilePoints; } function getTileLines(geometry, lineBBox, polyBBox, canonical) { var worldSize = Math.pow(2, canonical.z) * EXTENT; var shifts = [ canonical.x * EXTENT, canonical.y * EXTENT ]; var tileLines = []; for (var i$1 = 0, list$1 = geometry; i$1 < list$1.length; i$1 += 1) { var line = list$1[i$1]; var tileLine = []; for (var i = 0, list = line; i < list.length; i += 1) { var point = list[i]; var p = [ point.x + shifts[0], point.y + shifts[1] ]; updateBBox(lineBBox, p); tileLine.push(p); } tileLines.push(tileLine); } if (lineBBox[2] - lineBBox[0] <= worldSize / 2) { resetBBox(lineBBox); for (var i$3 = 0, list$3 = tileLines; i$3 < list$3.length; i$3 += 1) { var line$1 = list$3[i$3]; for (var i$2 = 0, list$2 = line$1; i$2 < list$2.length; i$2 += 1) { var p$1 = list$2[i$2]; updatePoint(p$1, lineBBox, polyBBox, worldSize); } } } return tileLines; } function pointsWithinPolygons(ctx, polygonGeometry) { var pointBBox = [ Infinity, Infinity, -Infinity, -Infinity ]; var polyBBox = [ Infinity, Infinity, -Infinity, -Infinity ]; var canonical = ctx.canonicalID(); if (polygonGeometry.type === 'Polygon') { var tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical); var tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical); if (!boxWithinBox(pointBBox, polyBBox)) { return false; } for (var i = 0, list = tilePoints; i < list.length; i += 1) { var point = list[i]; if (!pointWithinPolygon(point, tilePolygon)) { return false; } } } if (polygonGeometry.type === 'MultiPolygon') { var tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical); var tilePoints$1 = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical); if (!boxWithinBox(pointBBox, polyBBox)) { return false; } for (var i$1 = 0, list$1 = tilePoints$1; i$1 < list$1.length; i$1 += 1) { var point$1 = list$1[i$1]; if (!pointWithinPolygons(point$1, tilePolygons)) { return false; } } } return true; } function linesWithinPolygons(ctx, polygonGeometry) { var lineBBox = [ Infinity, Infinity, -Infinity, -Infinity ]; var polyBBox = [ Infinity, Infinity, -Infinity, -Infinity ]; var canonical = ctx.canonicalID(); if (polygonGeometry.type === 'Polygon') { var tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical); var tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical); if (!boxWithinBox(lineBBox, polyBBox)) { return false; } for (var i = 0, list = tileLines; i < list.length; i += 1) { var line = list[i]; if (!lineStringWithinPolygon(line, tilePolygon)) { return false; } } } if (polygonGeometry.type === 'MultiPolygon') { var tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical); var tileLines$1 = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical); if (!boxWithinBox(lineBBox, polyBBox)) { return false; } for (var i$1 = 0, list$1 = tileLines$1; i$1 < list$1.length; i$1 += 1) { var line$1 = list$1[i$1]; if (!lineStringWithinPolygons(line$1, tilePolygons)) { return false; } } } return true; } var Within = function Within(geojson, geometries) { this.type = BooleanType; this.geojson = geojson; this.geometries = geometries; }; Within.parse = function parse(args, context) { if (args.length !== 2) { return context.error('\'within\' expression requires exactly one argument, but found ' + (args.length - 1) + ' instead.'); } if (isValue(args[1])) { var geojson = args[1]; if (geojson.type === 'FeatureCollection') { for (var i = 0; i < geojson.features.length; ++i) { var type = geojson.features[i].geometry.type; if (type === 'Polygon' || type === 'MultiPolygon') { return new Within(geojson, geojson.features[i].geometry); } } } else if (geojson.type === 'Feature') { var type$1 = geojson.geometry.type; if (type$1 === 'Polygon' || type$1 === 'MultiPolygon') { return new Within(geojson, geojson.geometry); } } else if (geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') { return new Within(geojson, geojson); } } return context.error('\'within\' expression requires valid geojson object that contains polygon geometry type.'); }; Within.prototype.evaluate = function evaluate(ctx) { if (ctx.geometry() != null && ctx.canonicalID() != null) { if (ctx.geometryType() === 'Point') { return pointsWithinPolygons(ctx, this.geometries); } else if (ctx.geometryType() === 'LineString') { return linesWithinPolygons(ctx, this.geometries); } } return false; }; Within.prototype.eachChild = function eachChild() { }; Within.prototype.outputDefined = function outputDefined() { return true; }; Within.prototype.serialize = function serialize() { return [ 'within', this.geojson ]; }; function isFeatureConstant(e) { if (e instanceof CompoundExpression) { if (e.name === 'get' && e.args.length === 1) { return false; } else if (e.name === 'feature-state') { return false; } else if (e.name === 'has' && e.args.length === 1) { return false; } else if (e.name === 'properties' || e.name === 'geometry-type' || e.name === 'id') { return false; } else if (/^filter-/.test(e.name)) { return false; } } if (e instanceof Within) { return false; } var result = true; e.eachChild(function (arg) { if (result && !isFeatureConstant(arg)) { result = false; } }); return result; } function isStateConstant(e) { if (e instanceof CompoundExpression) { if (e.name === 'feature-state') { return false; } } var result = true; e.eachChild(function (arg) { if (result && !isStateConstant(arg)) { result = false; } }); return result; } function isGlobalPropertyConstant(e, properties) { if (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) { return false; } var result = true; e.eachChild(function (arg) { if (result && !isGlobalPropertyConstant(arg, properties)) { result = false; } }); return result; } var Var = function Var(name, boundExpression) { this.type = boundExpression.type; this.name = name; this.boundExpression = boundExpression; }; Var.parse = function parse(args, context) { if (args.length !== 2 || typeof args[1] !== 'string') { return context.error('\'var\' expression requires exactly one string literal argument.'); } var name = args[1]; if (!context.scope.has(name)) { return context.error('Unknown variable "' + name + '". Make sure "' + name + '" has been bound in an enclosing "let" expression before using it.', 1); } return new Var(name, context.scope.get(name)); }; Var.prototype.evaluate = function evaluate(ctx) { return this.boundExpression.evaluate(ctx); }; Var.prototype.eachChild = function eachChild() { }; Var.prototype.outputDefined = function outputDefined() { return false; }; Var.prototype.serialize = function serialize() { return [ 'var', this.name ]; }; var ParsingContext = function ParsingContext(registry, path, expectedType, scope, errors) { if (path === void 0) path = []; if (scope === void 0) scope = new Scope(); if (errors === void 0) errors = []; this.registry = registry; this.path = path; this.key = path.map(function (part) { return '[' + part + ']'; }).join(''); this.scope = scope; this.errors = errors; this.expectedType = expectedType; }; ParsingContext.prototype.parse = function parse(expr, index, expectedType, bindings, options) { if (options === void 0) options = {}; if (index) { return this.concat(index, expectedType, bindings)._parse(expr, options); } return this._parse(expr, options); }; ParsingContext.prototype._parse = function _parse(expr, options) { if (expr === null || typeof expr === 'string' || typeof expr === 'boolean' || typeof expr === 'number') { expr = [ 'literal', expr ]; } function annotate(parsed, type, typeAnnotation) { if (typeAnnotation === 'assert') { return new Assertion(type, [parsed]); } else if (typeAnnotation === 'coerce') { return new Coercion(type, [parsed]); } else { return parsed; } } if (Array.isArray(expr)) { if (expr.length === 0) { return this.error('Expected an array with at least one element. If you wanted a literal array, use ["literal", []].'); } var op = expr[0]; if (typeof op !== 'string') { this.error('Expression name must be a string, but found ' + typeof op + ' instead. If you wanted a literal array, use ["literal", [...]].', 0); return null; } var Expr = this.registry[op]; if (Expr) { var parsed = Expr.parse(expr, this); if (!parsed) { return null; } if (this.expectedType) { var expected = this.expectedType; var actual = parsed.type; if ((expected.kind === 'string' || expected.kind === 'number' || expected.kind === 'boolean' || expected.kind === 'object' || expected.kind === 'array') && actual.kind === 'value') { parsed = annotate(parsed, expected, options.typeAnnotation || 'assert'); } else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) { parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce'); } else if (this.checkSubtype(expected, actual)) { return null; } } if (!(parsed instanceof Literal) && parsed.type.kind !== 'resolvedImage' && isConstant(parsed)) { var ec = new EvaluationContext(); try { parsed = new Literal(parsed.type, parsed.evaluate(ec)); } catch (e) { this.error(e.message); return null; } } return parsed; } return this.error('Unknown expression "' + op + '". If you wanted a literal array, use ["literal", [...]].', 0); } else if (typeof expr === 'undefined') { return this.error('\'undefined\' value invalid. Use null instead.'); } else if (typeof expr === 'object') { return this.error('Bare objects invalid. Use ["literal", {...}] instead.'); } else { return this.error('Expected an array, but found ' + typeof expr + ' instead.'); } }; ParsingContext.prototype.concat = function concat(index, expectedType, bindings) { var path = typeof index === 'number' ? this.path.concat(index) : this.path; var scope = bindings ? this.scope.concat(bindings) : this.scope; return new ParsingContext(this.registry, path, expectedType || null, scope, this.errors); }; ParsingContext.prototype.error = function error(error$1) { var keys = [], len = arguments.length - 1; while (len-- > 0) keys[len] = arguments[len + 1]; var key = '' + this.key + keys.map(function (k) { return '[' + k + ']'; }).join(''); this.errors.push(new ParsingError(key, error$1)); }; ParsingContext.prototype.checkSubtype = function checkSubtype$1(expected, t) { var error = checkSubtype(expected, t); if (error) { this.error(error); } return error; }; function isConstant(expression) { if (expression instanceof Var) { return isConstant(expression.boundExpression); } else if (expression instanceof CompoundExpression && expression.name === 'error') { return false; } else if (expression instanceof CollatorExpression) { return false; } else if (expression instanceof Within) { return false; } var isTypeAnnotation = expression instanceof Coercion || expression instanceof Assertion; var childrenConstant = true; expression.eachChild(function (child) { if (isTypeAnnotation) { childrenConstant = childrenConstant && isConstant(child); } else { childrenConstant = childrenConstant && child instanceof Literal; } }); if (!childrenConstant) { return false; } return isFeatureConstant(expression) && isGlobalPropertyConstant(expression, [ 'zoom', 'heatmap-density', 'line-progress', 'accumulated', 'is-supported-script' ]); } function findStopLessThanOrEqualTo(stops, input) { var lastIndex = stops.length - 1; var lowerIndex = 0; var upperIndex = lastIndex; var currentIndex = 0; var currentValue, nextValue; while (lowerIndex <= upperIndex) { currentIndex = Math.floor((lowerIndex + upperIndex) / 2); currentValue = stops[currentIndex]; nextValue = stops[currentIndex + 1]; if (currentValue <= input) { if (currentIndex === lastIndex || input < nextValue) { return currentIndex; } lowerIndex = currentIndex + 1; } else if (currentValue > input) { upperIndex = currentIndex - 1; } else { throw new RuntimeError('Input is not a number.'); } } return 0; } var Step = function Step(type, input, stops) { this.type = type; this.input = input; this.labels = []; this.outputs = []; for (var i = 0, list = stops; i < list.length; i += 1) { var ref = list[i]; var label = ref[0]; var expression = ref[1]; this.labels.push(label); this.outputs.push(expression); } }; Step.parse = function parse(args, context) { if (args.length - 1 < 4) { return context.error('Expected at least 4 arguments, but found only ' + (args.length - 1) + '.'); } if ((args.length - 1) % 2 !== 0) { return context.error('Expected an even number of arguments.'); } var input = context.parse(args[1], 1, NumberType); if (!input) { return null; } var stops = []; var outputType = null; if (context.expectedType && context.expectedType.kind !== 'value') { outputType = context.expectedType; } for (var i = 1; i < args.length; i += 2) { var label = i === 1 ? -Infinity : args[i]; var value = args[i + 1]; var labelKey = i; var valueKey = i + 1; if (typeof label !== 'number') { return context.error('Input/output pairs for "step" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey); } if (stops.length && stops[stops.length - 1][0] >= label) { return context.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.', labelKey); } var parsed = context.parse(value, valueKey, outputType); if (!parsed) { return null; } outputType = outputType || parsed.type; stops.push([ label, parsed ]); } return new Step(outputType, input, stops); }; Step.prototype.evaluate = function evaluate(ctx) { var labels = this.labels; var outputs = this.outputs; if (labels.length === 1) { return outputs[0].evaluate(ctx); } var value = this.input.evaluate(ctx); if (value <= labels[0]) { return outputs[0].evaluate(ctx); } var stopCount = labels.length; if (value >= labels[stopCount - 1]) { return outputs[stopCount - 1].evaluate(ctx); } var index = findStopLessThanOrEqualTo(labels, value); return outputs[index].evaluate(ctx); }; Step.prototype.eachChild = function eachChild(fn) { fn(this.input); for (var i = 0, list = this.outputs; i < list.length; i += 1) { var expression = list[i]; fn(expression); } }; Step.prototype.outputDefined = function outputDefined() { return this.outputs.every(function (out) { return out.outputDefined(); }); }; Step.prototype.serialize = function serialize() { var serialized = [ 'step', this.input.serialize() ]; for (var i = 0; i < this.labels.length; i++) { if (i > 0) { serialized.push(this.labels[i]); } serialized.push(this.outputs[i].serialize()); } return serialized; }; function number(a, b, t) { return a * (1 - t) + b * t; } function color(from, to, t) { return new Color(number(from.r, to.r, t), number(from.g, to.g, t), number(from.b, to.b, t), number(from.a, to.a, t)); } function array$1(from, to, t) { return from.map(function (d, i) { return number(d, to[i], t); }); } var interpolate = /*#__PURE__*/Object.freeze({ __proto__: null, number: number, color: color, array: array$1 }); var Xn = 0.95047, Yn = 1, Zn = 1.08883, t0 = 4 / 29, t1 = 6 / 29, t2 = 3 * t1 * t1, t3 = t1 * t1 * t1, deg2rad = Math.PI / 180, rad2deg = 180 / Math.PI; function xyz2lab(t) { return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; } function lab2xyz(t) { return t > t1 ? t * t * t : t2 * (t - t0); } function xyz2rgb(x) { return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); } function rgb2xyz(x) { x /= 255; return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); } function rgbToLab(rgbColor) { var b = rgb2xyz(rgbColor.r), a = rgb2xyz(rgbColor.g), l = rgb2xyz(rgbColor.b), x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.072175 * l) / Yn), z = xyz2lab((0.0193339 * b + 0.119192 * a + 0.9503041 * l) / Zn); return { l: 116 * y - 16, a: 500 * (x - y), b: 200 * (y - z), alpha: rgbColor.a }; } function labToRgb(labColor) { var y = (labColor.l + 16) / 116, x = isNaN(labColor.a) ? y : y + labColor.a / 500, z = isNaN(labColor.b) ? y : y - labColor.b / 200; y = Yn * lab2xyz(y); x = Xn * lab2xyz(x); z = Zn * lab2xyz(z); return new Color(xyz2rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z), xyz2rgb(-0.969266 * x + 1.8760108 * y + 0.041556 * z), xyz2rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z), labColor.alpha); } function interpolateLab(from, to, t) { return { l: number(from.l, to.l, t), a: number(from.a, to.a, t), b: number(from.b, to.b, t), alpha: number(from.alpha, to.alpha, t) }; } function rgbToHcl(rgbColor) { var ref = rgbToLab(rgbColor); var l = ref.l; var a = ref.a; var b = ref.b; var h = Math.atan2(b, a) * rad2deg; return { h: h < 0 ? h + 360 : h, c: Math.sqrt(a * a + b * b), l: l, alpha: rgbColor.a }; } function hclToRgb(hclColor) { var h = hclColor.h * deg2rad, c = hclColor.c, l = hclColor.l; return labToRgb({ l: l, a: Math.cos(h) * c, b: Math.sin(h) * c, alpha: hclColor.alpha }); } function interpolateHue(a, b, t) { var d = b - a; return a + t * (d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d); } function interpolateHcl(from, to, t) { return { h: interpolateHue(from.h, to.h, t), c: number(from.c, to.c, t), l: number(from.l, to.l, t), alpha: number(from.alpha, to.alpha, t) }; } var lab = { forward: rgbToLab, reverse: labToRgb, interpolate: interpolateLab }; var hcl = { forward: rgbToHcl, reverse: hclToRgb, interpolate: interpolateHcl }; var colorSpaces = /*#__PURE__*/Object.freeze({ __proto__: null, lab: lab, hcl: hcl }); var Interpolate = function Interpolate(type, operator, interpolation, input, stops) { this.type = type; this.operator = operator; this.interpolation = interpolation; this.input = input; this.labels = []; this.outputs = []; for (var i = 0, list = stops; i < list.length; i += 1) { var ref = list[i]; var label = ref[0]; var expression = ref[1]; this.labels.push(label); this.outputs.push(expression); } }; Interpolate.interpolationFactor = function interpolationFactor(interpolation, input, lower, upper) { var t = 0; if (interpolation.name === 'exponential') { t = exponentialInterpolation(input, interpolation.base, lower, upper); } else if (interpolation.name === 'linear') { t = exponentialInterpolation(input, 1, lower, upper); } else if (interpolation.name === 'cubic-bezier') { var c = interpolation.controlPoints; var ub = new unitbezier(c[0], c[1], c[2], c[3]); t = ub.solve(exponentialInterpolation(input, 1, lower, upper)); } return t; }; Interpolate.parse = function parse(args, context) { var operator = args[0]; var interpolation = args[1]; var input = args[2]; var rest = args.slice(3); if (!Array.isArray(interpolation) || interpolation.length === 0) { return context.error('Expected an interpolation type expression.', 1); } if (interpolation[0] === 'linear') { interpolation = { name: 'linear' }; } else if (interpolation[0] === 'exponential') { var base = interpolation[1]; if (typeof base !== 'number') { return context.error('Exponential interpolation requires a numeric base.', 1, 1); } interpolation = { name: 'exponential', base: base }; } else if (interpolation[0] === 'cubic-bezier') { var controlPoints = interpolation.slice(1); if (controlPoints.length !== 4 || controlPoints.some(function (t) { return typeof t !== 'number' || t < 0 || t > 1; })) { return context.error('Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.', 1); } interpolation = { name: 'cubic-bezier', controlPoints: controlPoints }; } else { return context.error('Unknown interpolation type ' + String(interpolation[0]), 1, 0); } if (args.length - 1 < 4) { return context.error('Expected at least 4 arguments, but found only ' + (args.length - 1) + '.'); } if ((args.length - 1) % 2 !== 0) { return context.error('Expected an even number of arguments.'); } input = context.parse(input, 2, NumberType); if (!input) { return null; } var stops = []; var outputType = null; if (operator === 'interpolate-hcl' || operator === 'interpolate-lab') { outputType = ColorType; } else if (context.expectedType && context.expectedType.kind !== 'value') { outputType = context.expectedType; } for (var i = 0; i < rest.length; i += 2) { var label = rest[i]; var value = rest[i + 1]; var labelKey = i + 3; var valueKey = i + 4; if (typeof label !== 'number') { return context.error('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey); } if (stops.length && stops[stops.length - 1][0] >= label) { return context.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.', labelKey); } var parsed = context.parse(value, valueKey, outputType); if (!parsed) { return null; } outputType = outputType || parsed.type; stops.push([ label, parsed ]); } if (outputType.kind !== 'number' && outputType.kind !== 'color' && !(outputType.kind === 'array' && outputType.itemType.kind === 'number' && typeof outputType.N === 'number')) { return context.error('Type ' + toString(outputType) + ' is not interpolatable.'); } return new Interpolate(outputType, operator, interpolation, input, stops); }; Interpolate.prototype.evaluate = function evaluate(ctx) { var labels = this.labels; var outputs = this.outputs; if (labels.length === 1) { return outputs[0].evaluate(ctx); } var value = this.input.evaluate(ctx); if (value <= labels[0]) { return outputs[0].evaluate(ctx); } var stopCount = labels.length; if (value >= labels[stopCount - 1]) { return outputs[stopCount - 1].evaluate(ctx); } var index = findStopLessThanOrEqualTo(labels, value); var lower = labels[index]; var upper = labels[index + 1]; var t = Interpolate.interpolationFactor(this.interpolation, value, lower, upper); var outputLower = outputs[index].evaluate(ctx); var outputUpper = outputs[index + 1].evaluate(ctx); if (this.operator === 'interpolate') { return interpolate[this.type.kind.toLowerCase()](outputLower, outputUpper, t); } else if (this.operator === 'interpolate-hcl') { return hcl.reverse(hcl.interpolate(hcl.forward(outputLower), hcl.forward(outputUpper), t)); } else { return lab.reverse(lab.interpolate(lab.forward(outputLower), lab.forward(outputUpper), t)); } }; Interpolate.prototype.eachChild = function eachChild(fn) { fn(this.input); for (var i = 0, list = this.outputs; i < list.length; i += 1) { var expression = list[i]; fn(expression); } }; Interpolate.prototype.outputDefined = function outputDefined() { return this.outputs.every(function (out) { return out.outputDefined(); }); }; Interpolate.prototype.serialize = function serialize() { var interpolation; if (this.interpolation.name === 'linear') { interpolation = ['linear']; } else if (this.interpolation.name === 'exponential') { if (this.interpolation.base === 1) { interpolation = ['linear']; } else { interpolation = [ 'exponential', this.interpolation.base ]; } } else { interpolation = ['cubic-bezier'].concat(this.interpolation.controlPoints); } var serialized = [ this.operator, interpolation, this.input.serialize() ]; for (var i = 0; i < this.labels.length; i++) { serialized.push(this.labels[i], this.outputs[i].serialize()); } return serialized; }; function exponentialInterpolation(input, base, lowerValue, upperValue) { var difference = upperValue - lowerValue; var progress = input - lowerValue; if (difference === 0) { return 0; } else if (base === 1) { return progress / difference; } else { return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1); } } var Coalesce = function Coalesce(type, args) { this.type = type; this.args = args; }; Coalesce.parse = function parse(args, context) { if (args.length < 2) { return context.error('Expectected at least one argument.'); } var outputType = null; var expectedType = context.expectedType; if (expectedType && expectedType.kind !== 'value') { outputType = expectedType; } var parsedArgs = []; for (var i = 0, list = args.slice(1); i < list.length; i += 1) { var arg = list[i]; var parsed = context.parse(arg, 1 + parsedArgs.length, outputType, undefined, { typeAnnotation: 'omit' }); if (!parsed) { return null; } outputType = outputType || parsed.type; parsedArgs.push(parsed); } var needsAnnotation = expectedType && parsedArgs.some(function (arg) { return checkSubtype(expectedType, arg.type); }); return needsAnnotation ? new Coalesce(ValueType, parsedArgs) : new Coalesce(outputType, parsedArgs); }; Coalesce.prototype.evaluate = function evaluate(ctx) { var result = null; var argCount = 0; var requestedImageName; for (var i = 0, list = this.args; i < list.length; i += 1) { var arg = list[i]; argCount++; result = arg.evaluate(ctx); if (result && result instanceof ResolvedImage && !result.available) { if (!requestedImageName) { requestedImageName = result.name; } result = null; if (argCount === this.args.length) { result = requestedImageName; } } if (result !== null) { break; } } return result; }; Coalesce.prototype.eachChild = function eachChild(fn) { this.args.forEach(fn); }; Coalesce.prototype.outputDefined = function outputDefined() { return this.args.every(function (arg) { return arg.outputDefined(); }); }; Coalesce.prototype.serialize = function serialize() { var serialized = ['coalesce']; this.eachChild(function (child) { serialized.push(child.serialize()); }); return serialized; }; var Let = function Let(bindings, result) { this.type = result.type; this.bindings = [].concat(bindings); this.result = result; }; Let.prototype.evaluate = function evaluate(ctx) { return this.result.evaluate(ctx); }; Let.prototype.eachChild = function eachChild(fn) { for (var i = 0, list = this.bindings; i < list.length; i += 1) { var binding = list[i]; fn(binding[1]); } fn(this.result); }; Let.parse = function parse(args, context) { if (args.length < 4) { return context.error('Expected at least 3 arguments, but found ' + (args.length - 1) + ' instead.'); } var bindings = []; for (var i = 1; i < args.length - 1; i += 2) { var name = args[i]; if (typeof name !== 'string') { return context.error('Expected string, but found ' + typeof name + ' instead.', i); } if (/[^a-zA-Z0-9_]/.test(name)) { return context.error('Variable names must contain only alphanumeric characters or \'_\'.', i); } var value = context.parse(args[i + 1], i + 1); if (!value) { return null; } bindings.push([ name, value ]); } var result = context.parse(args[args.length - 1], args.length - 1, context.expectedType, bindings); if (!result) { return null; } return new Let(bindings, result); }; Let.prototype.outputDefined = function outputDefined() { return this.result.outputDefined(); }; Let.prototype.serialize = function serialize() { var serialized = ['let']; for (var i = 0, list = this.bindings; i < list.length; i += 1) { var ref = list[i]; var name = ref[0]; var expr = ref[1]; serialized.push(name, expr.serialize()); } serialized.push(this.result.serialize()); return serialized; }; var At = function At(type, index, input) { this.type = type; this.index = index; this.input = input; }; At.parse = function parse(args, context) { if (args.length !== 3) { return context.error('Expected 2 arguments, but found ' + (args.length - 1) + ' instead.'); } var index = context.parse(args[1], 1, NumberType); var input = context.parse(args[2], 2, array(context.expectedType || ValueType)); if (!index || !input) { return null; } var t = input.type; return new At(t.itemType, index, input); }; At.prototype.evaluate = function evaluate(ctx) { var index = this.index.evaluate(ctx); var array = this.input.evaluate(ctx); if (index < 0) { throw new RuntimeError('Array index out of bounds: ' + index + ' < 0.'); } if (index >= array.length) { throw new RuntimeError('Array index out of bounds: ' + index + ' > ' + (array.length - 1) + '.'); } if (index !== Math.floor(index)) { throw new RuntimeError('Array index must be an integer, but found ' + index + ' instead.'); } return array[index]; }; At.prototype.eachChild = function eachChild(fn) { fn(this.index); fn(this.input); }; At.prototype.outputDefined = function outputDefined() { return false; }; At.prototype.serialize = function serialize() { return [ 'at', this.index.serialize(), this.input.serialize() ]; }; var In = function In(needle, haystack) { this.type = BooleanType; this.needle = needle; this.haystack = haystack; }; In.parse = function parse(args, context) { if (args.length !== 3) { return context.error('Expected 2 arguments, but found ' + (args.length - 1) + ' instead.'); } var needle = context.parse(args[1], 1, ValueType); var haystack = context.parse(args[2], 2, ValueType); if (!needle || !haystack) { return null; } if (!isValidType(needle.type, [ BooleanType, StringType, NumberType, NullType, ValueType ])) { return context.error('Expected first argument to be of type boolean, string, number or null, but found ' + toString(needle.type) + ' instead'); } return new In(needle, haystack); }; In.prototype.evaluate = function evaluate(ctx) { var needle = this.needle.evaluate(ctx); var haystack = this.haystack.evaluate(ctx); if (!haystack) { return false; } if (!isValidNativeType(needle, [ 'boolean', 'string', 'number', 'null' ])) { throw new RuntimeError('Expected first argument to be of type boolean, string, number or null, but found ' + toString(typeOf(needle)) + ' instead.'); } if (!isValidNativeType(haystack, [ 'string', 'array' ])) { throw new RuntimeError('Expected second argument to be of type array or string, but found ' + toString(typeOf(haystack)) + ' instead.'); } return haystack.indexOf(needle) >= 0; }; In.prototype.eachChild = function eachChild(fn) { fn(this.needle); fn(this.haystack); }; In.prototype.outputDefined = function outputDefined() { return true; }; In.prototype.serialize = function serialize() { return [ 'in', this.needle.serialize(), this.haystack.serialize() ]; }; var IndexOf = function IndexOf(needle, haystack, fromIndex) { this.type = NumberType; this.needle = needle; this.haystack = haystack; this.fromIndex = fromIndex; }; IndexOf.parse = function parse(args, context) { if (args.length <= 2 || args.length >= 5) { return context.error('Expected 3 or 4 arguments, but found ' + (args.length - 1) + ' instead.'); } var needle = context.parse(args[1], 1, ValueType); var haystack = context.parse(args[2], 2, ValueType); if (!needle || !haystack) { return null; } if (!isValidType(needle.type, [ BooleanType, StringType, NumberType, NullType, ValueType ])) { return context.error('Expected first argument to be of type boolean, string, number or null, but found ' + toString(needle.type) + ' instead'); } if (args.length === 4) { var fromIndex = context.parse(args[3], 3, NumberType); if (!fromIndex) { return null; } return new IndexOf(needle, haystack, fromIndex); } else { return new IndexOf(needle, haystack); } }; IndexOf.prototype.evaluate = function evaluate(ctx) { var needle = this.needle.evaluate(ctx); var haystack = this.haystack.evaluate(ctx); if (!isValidNativeType(needle, [ 'boolean', 'string', 'number', 'null' ])) { throw new RuntimeError('Expected first argument to be of type boolean, string, number or null, but found ' + toString(typeOf(needle)) + ' instead.'); } if (!isValidNativeType(haystack, [ 'string', 'array' ])) { throw new RuntimeError('Expected second argument to be of type array or string, but found ' + toString(typeOf(haystack)) + ' instead.'); } if (this.fromIndex) { var fromIndex = this.fromIndex.evaluate(ctx); return haystack.indexOf(needle, fromIndex); } return haystack.indexOf(needle); }; IndexOf.prototype.eachChild = function eachChild(fn) { fn(this.needle); fn(this.haystack); if (this.fromIndex) { fn(this.fromIndex); } }; IndexOf.prototype.outputDefined = function outputDefined() { return false; }; IndexOf.prototype.serialize = function serialize() { if (this.fromIndex != null && this.fromIndex !== undefined) { var fromIndex = this.fromIndex.serialize(); return [ 'index-of', this.needle.serialize(), this.haystack.serialize(), fromIndex ]; } return [ 'index-of', this.needle.serialize(), this.haystack.serialize() ]; }; var Match = function Match(inputType, outputType, input, cases, outputs, otherwise) { this.inputType = inputType; this.type = outputType; this.input = input; this.cases = cases; this.outputs = outputs; this.otherwise = otherwise; }; Match.parse = function parse(args, context) { if (args.length < 5) { return context.error('Expected at least 4 arguments, but found only ' + (args.length - 1) + '.'); } if (args.length % 2 !== 1) { return context.error('Expected an even number of arguments.'); } var inputType; var outputType; if (context.expectedType && context.expectedType.kind !== 'value') { outputType = context.expectedType; } var cases = {}; var outputs = []; for (var i = 2; i < args.length - 1; i += 2) { var labels = args[i]; var value = args[i + 1]; if (!Array.isArray(labels)) { labels = [labels]; } var labelContext = context.concat(i); if (labels.length === 0) { return labelContext.error('Expected at least one branch label.'); } for (var i$1 = 0, list = labels; i$1 < list.length; i$1 += 1) { var label = list[i$1]; if (typeof label !== 'number' && typeof label !== 'string') { return labelContext.error('Branch labels must be numbers or strings.'); } else if (typeof label === 'number' && Math.abs(label) > Number.MAX_SAFE_INTEGER) { return labelContext.error('Branch labels must be integers no larger than ' + Number.MAX_SAFE_INTEGER + '.'); } else if (typeof label === 'number' && Math.floor(label) !== label) { return labelContext.error('Numeric branch labels must be integer values.'); } else if (!inputType) { inputType = typeOf(label); } else if (labelContext.checkSubtype(inputType, typeOf(label))) { return null; } if (typeof cases[String(label)] !== 'undefined') { return labelContext.error('Branch labels must be unique.'); } cases[String(label)] = outputs.length; } var result = context.parse(value, i, outputType); if (!result) { return null; } outputType = outputType || result.type; outputs.push(result); } var input = context.parse(args[1], 1, ValueType); if (!input) { return null; } var otherwise = context.parse(args[args.length - 1], args.length - 1, outputType); if (!otherwise) { return null; } if (input.type.kind !== 'value' && context.concat(1).checkSubtype(inputType, input.type)) { return null; } return new Match(inputType, outputType, input, cases, outputs, otherwise); }; Match.prototype.evaluate = function evaluate(ctx) { var input = this.input.evaluate(ctx); var output = typeOf(input) === this.inputType && this.outputs[this.cases[input]] || this.otherwise; return output.evaluate(ctx); }; Match.prototype.eachChild = function eachChild(fn) { fn(this.input); this.outputs.forEach(fn); fn(this.otherwise); }; Match.prototype.outputDefined = function outputDefined() { return this.outputs.every(function (out) { return out.outputDefined(); }) && this.otherwise.outputDefined(); }; Match.prototype.serialize = function serialize() { var this$1 = this; var serialized = [ 'match', this.input.serialize() ]; var sortedLabels = Object.keys(this.cases).sort(); var groupedByOutput = []; var outputLookup = {}; for (var i = 0, list = sortedLabels; i < list.length; i += 1) { var label = list[i]; var outputIndex = outputLookup[this.cases[label]]; if (outputIndex === undefined) { outputLookup[this.cases[label]] = groupedByOutput.length; groupedByOutput.push([ this.cases[label], [label] ]); } else { groupedByOutput[outputIndex][1].push(label); } } var coerceLabel = function (label) { return this$1.inputType.kind === 'number' ? Number(label) : label; }; for (var i$1 = 0, list$1 = groupedByOutput; i$1 < list$1.length; i$1 += 1) { var ref = list$1[i$1]; var outputIndex = ref[0]; var labels = ref[1]; if (labels.length === 1) { serialized.push(coerceLabel(labels[0])); } else { serialized.push(labels.map(coerceLabel)); } serialized.push(this.outputs[outputIndex$1].serialize()); } serialized.push(this.otherwise.serialize()); return serialized; }; var Case = function Case(type, branches, otherwise) { this.type = type; this.branches = branches; this.otherwise = otherwise; }; Case.parse = function parse(args, context) { if (args.length < 4) { return context.error('Expected at least 3 arguments, but found only ' + (args.length - 1) + '.'); } if (args.length % 2 !== 0) { return context.error('Expected an odd number of arguments.'); } var outputType; if (context.expectedType && context.expectedType.kind !== 'value') { outputType = context.expectedType; } var branches = []; for (var i = 1; i < args.length - 1; i += 2) { var test = context.parse(args[i], i, BooleanType); if (!test) { return null; } var result = context.parse(args[i + 1], i + 1, outputType); if (!result) { return null; } branches.push([ test, result ]); outputType = outputType || result.type; } var otherwise = context.parse(args[args.length - 1], args.length - 1, outputType); if (!otherwise) { return null; } return new Case(outputType, branches, otherwise); }; Case.prototype.evaluate = function evaluate(ctx) { for (var i = 0, list = this.branches; i < list.length; i += 1) { var ref = list[i]; var test = ref[0]; var expression = ref[1]; if (test.evaluate(ctx)) { return expression.evaluate(ctx); } } return this.otherwise.evaluate(ctx); }; Case.prototype.eachChild = function eachChild(fn) { for (var i = 0, list = this.branches; i < list.length; i += 1) { var ref = list[i]; var test = ref[0]; var expression = ref[1]; fn(test); fn(expression); } fn(this.otherwise); }; Case.prototype.outputDefined = function outputDefined() { return this.branches.every(function (ref) { var _ = ref[0]; var out = ref[1]; return out.outputDefined(); }) && this.otherwise.outputDefined(); }; Case.prototype.serialize = function serialize() { var serialized = ['case']; this.eachChild(function (child) { serialized.push(child.serialize()); }); return serialized; }; var Slice = function Slice(type, input, beginIndex, endIndex) { this.type = type; this.input = input; this.beginIndex = beginIndex; this.endIndex = endIndex; }; Slice.parse = function parse(args, context) { if (args.length <= 2 || args.length >= 5) { return context.error('Expected 3 or 4 arguments, but found ' + (args.length - 1) + ' instead.'); } var input = context.parse(args[1], 1, ValueType); var beginIndex = context.parse(args[2], 2, NumberType); if (!input || !beginIndex) { return null; } if (!isValidType(input.type, [ array(ValueType), StringType, ValueType ])) { return context.error('Expected first argument to be of type array or string, but found ' + toString(input.type) + ' instead'); } if (args.length === 4) { var endIndex = context.parse(args[3], 3, NumberType); if (!endIndex) { return null; } return new Slice(input.type, input, beginIndex, endIndex); } else { return new Slice(input.type, input, beginIndex); } }; Slice.prototype.evaluate = function evaluate(ctx) { var input = this.input.evaluate(ctx); var beginIndex = this.beginIndex.evaluate(ctx); if (!isValidNativeType(input, [ 'string', 'array' ])) { throw new RuntimeError('Expected first argument to be of type array or string, but found ' + toString(typeOf(input)) + ' instead.'); } if (this.endIndex) { var endIndex = this.endIndex.evaluate(ctx); return input.slice(beginIndex, endIndex); } return input.slice(beginIndex); }; Slice.prototype.eachChild = function eachChild(fn) { fn(this.input); fn(this.beginIndex); if (this.endIndex) { fn(this.endIndex); } }; Slice.prototype.outputDefined = function outputDefined() { return false; }; Slice.prototype.serialize = function serialize() { if (this.endIndex != null && this.endIndex !== undefined) { var endIndex = this.endIndex.serialize(); return [ 'slice', this.input.serialize(), this.beginIndex.serialize(), endIndex ]; } return [ 'slice', this.input.serialize(), this.beginIndex.serialize() ]; }; function isComparableType(op, type) { if (op === '==' || op === '!=') { return type.kind === 'boolean' || type.kind === 'string' || type.kind === 'number' || type.kind === 'null' || type.kind === 'value'; } else { return type.kind === 'string' || type.kind === 'number' || type.kind === 'value'; } } function eq(ctx, a, b) { return a === b; } function neq(ctx, a, b) { return a !== b; } function lt(ctx, a, b) { return a < b; } function gt(ctx, a, b) { return a > b; } function lteq(ctx, a, b) { return a <= b; } function gteq(ctx, a, b) { return a >= b; } function eqCollate(ctx, a, b, c) { return c.compare(a, b) === 0; } function neqCollate(ctx, a, b, c) { return !eqCollate(ctx, a, b, c); } function ltCollate(ctx, a, b, c) { return c.compare(a, b) < 0; } function gtCollate(ctx, a, b, c) { return c.compare(a, b) > 0; } function lteqCollate(ctx, a, b, c) { return c.compare(a, b) <= 0; } function gteqCollate(ctx, a, b, c) { return c.compare(a, b) >= 0; } function makeComparison(op, compareBasic, compareWithCollator) { var isOrderComparison = op !== '==' && op !== '!='; return function () { function Comparison(lhs, rhs, collator) { this.type = BooleanType; this.lhs = lhs; this.rhs = rhs; this.collator = collator; this.hasUntypedArgument = lhs.type.kind === 'value' || rhs.type.kind === 'value'; } Comparison.parse = function parse(args, context) { if (args.length !== 3 && args.length !== 4) { return context.error('Expected two or three arguments.'); } var op = args[0]; var lhs = context.parse(args[1], 1, ValueType); if (!lhs) { return null; } if (!isComparableType(op, lhs.type)) { return context.concat(1).error('"' + op + '" comparisons are not supported for type \'' + toString(lhs.type) + '\'.'); } var rhs = context.parse(args[2], 2, ValueType); if (!rhs) { return null; } if (!isComparableType(op, rhs.type)) { return context.concat(2).error('"' + op + '" comparisons are not supported for type \'' + toString(rhs.type) + '\'.'); } if (lhs.type.kind !== rhs.type.kind && lhs.type.kind !== 'value' && rhs.type.kind !== 'value') { return context.error('Cannot compare types \'' + toString(lhs.type) + '\' and \'' + toString(rhs.type) + '\'.'); } if (isOrderComparison) { if (lhs.type.kind === 'value' && rhs.type.kind !== 'value') { lhs = new Assertion(rhs.type, [lhs]); } else if (lhs.type.kind !== 'value' && rhs.type.kind === 'value') { rhs = new Assertion(lhs.type, [rhs]); } } var collator = null; if (args.length === 4) { if (lhs.type.kind !== 'string' && rhs.type.kind !== 'string' && lhs.type.kind !== 'value' && rhs.type.kind !== 'value') { return context.error('Cannot use collator to compare non-string types.'); } collator = context.parse(args[3], 3, CollatorType); if (!collator) { return null; } } return new Comparison(lhs, rhs, collator); }; Comparison.prototype.evaluate = function evaluate(ctx) { var lhs = this.lhs.evaluate(ctx); var rhs = this.rhs.evaluate(ctx); if (isOrderComparison && this.hasUntypedArgument) { var lt = typeOf(lhs); var rt = typeOf(rhs); if (lt.kind !== rt.kind || !(lt.kind === 'string' || lt.kind === 'number')) { throw new RuntimeError('Expected arguments for "' + op + '" to be (string, string) or (number, number), but found (' + lt.kind + ', ' + rt.kind + ') instead.'); } } if (this.collator && !isOrderComparison && this.hasUntypedArgument) { var lt$1 = typeOf(lhs); var rt$1 = typeOf(rhs); if (lt$1.kind !== 'string' || rt$1.kind !== 'string') { return compareBasic(ctx, lhs, rhs); } } return this.collator ? compareWithCollator(ctx, lhs, rhs, this.collator.evaluate(ctx)) : compareBasic(ctx, lhs, rhs); }; Comparison.prototype.eachChild = function eachChild(fn) { fn(this.lhs); fn(this.rhs); if (this.collator) { fn(this.collator); } }; Comparison.prototype.outputDefined = function outputDefined() { return true; }; Comparison.prototype.serialize = function serialize() { var serialized = [op]; this.eachChild(function (child) { serialized.push(child.serialize()); }); return serialized; }; return Comparison; }(); } var Equals = makeComparison('==', eq, eqCollate); var NotEquals = makeComparison('!=', neq, neqCollate); var LessThan = makeComparison('<', lt, ltCollate); var GreaterThan = makeComparison('>', gt, gtCollate); var LessThanOrEqual = makeComparison('<=', lteq, lteqCollate); var GreaterThanOrEqual = makeComparison('>=', gteq, gteqCollate); var NumberFormat = function NumberFormat(number, locale, currency, minFractionDigits, maxFractionDigits) { this.type = StringType; this.number = number; this.locale = locale; this.currency = currency; this.minFractionDigits = minFractionDigits; this.maxFractionDigits = maxFractionDigits; }; NumberFormat.parse = function parse(args, context) { if (args.length !== 3) { return context.error('Expected two arguments.'); } var number = context.parse(args[1], 1, NumberType); if (!number) { return null; } var options = args[2]; if (typeof options !== 'object' || Array.isArray(options)) { return context.error('NumberFormat options argument must be an object.'); } var locale = null; if (options['locale']) { locale = context.parse(options['locale'], 1, StringType); if (!locale) { return null; } } var currency = null; if (options['currency']) { currency = context.parse(options['currency'], 1, StringType); if (!currency) { return null; } } var minFractionDigits = null; if (options['min-fraction-digits']) { minFractionDigits = context.parse(options['min-fraction-digits'], 1, NumberType); if (!minFractionDigits) { return null; } } var maxFractionDigits = null; if (options['max-fraction-digits']) { maxFractionDigits = context.parse(options['max-fraction-digits'], 1, NumberType); if (!maxFractionDigits) { return null; } } return new NumberFormat(number, locale, currency, minFractionDigits, maxFractionDigits); }; NumberFormat.prototype.evaluate = function evaluate(ctx) { return new Intl.NumberFormat(this.locale ? this.locale.evaluate(ctx) : [], { style: this.currency ? 'currency' : 'decimal', currency: this.currency ? this.currency.evaluate(ctx) : undefined, minimumFractionDigits: this.minFractionDigits ? this.minFractionDigits.evaluate(ctx) : undefined, maximumFractionDigits: this.maxFractionDigits ? this.maxFractionDigits.evaluate(ctx) : undefined }).format(this.number.evaluate(ctx)); }; NumberFormat.prototype.eachChild = function eachChild(fn) { fn(this.number); if (this.locale) { fn(this.locale); } if (this.currency) { fn(this.currency); } if (this.minFractionDigits) { fn(this.minFractionDigits); } if (this.maxFractionDigits) { fn(this.maxFractionDigits); } }; NumberFormat.prototype.outputDefined = function outputDefined() { return false; }; NumberFormat.prototype.serialize = function serialize() { var options = {}; if (this.locale) { options['locale'] = this.locale.serialize(); } if (this.currency) { options['currency'] = this.currency.serialize(); } if (this.minFractionDigits) { options['min-fraction-digits'] = this.minFractionDigits.serialize(); } if (this.maxFractionDigits) { options['max-fraction-digits'] = this.maxFractionDigits.serialize(); } return [ 'number-format', this.number.serialize(), options ]; }; var Length = function Length(input) { this.type = NumberType; this.input = input; }; Length.parse = function parse(args, context) { if (args.length !== 2) { return context.error('Expected 1 argument, but found ' + (args.length - 1) + ' instead.'); } var input = context.parse(args[1], 1); if (!input) { return null; } if (input.type.kind !== 'array' && input.type.kind !== 'string' && input.type.kind !== 'value') { return context.error('Expected argument of type string or array, but found ' + toString(input.type) + ' instead.'); } return new Length(input); }; Length.prototype.evaluate = function evaluate(ctx) { var input = this.input.evaluate(ctx); if (typeof input === 'string') { return input.length; } else if (Array.isArray(input)) { return input.length; } else { throw new RuntimeError('Expected value to be of type string or array, but found ' + toString(typeOf(input)) + ' instead.'); } }; Length.prototype.eachChild = function eachChild(fn) { fn(this.input); }; Length.prototype.outputDefined = function outputDefined() { return false; }; Length.prototype.serialize = function serialize() { var serialized = ['length']; this.eachChild(function (child) { serialized.push(child.serialize()); }); return serialized; }; var expressions = { '==': Equals, '!=': NotEquals, '>': GreaterThan, '<': LessThan, '>=': GreaterThanOrEqual, '<=': LessThanOrEqual, 'array': Assertion, 'at': At, 'boolean': Assertion, 'case': Case, 'coalesce': Coalesce, 'collator': CollatorExpression, 'format': FormatExpression, 'image': ImageExpression, 'in': In, 'index-of': IndexOf, 'interpolate': Interpolate, 'interpolate-hcl': Interpolate, 'interpolate-lab': Interpolate, 'length': Length, 'let': Let, 'literal': Literal, 'match': Match, 'number': Assertion, 'number-format': NumberFormat, 'object': Assertion, 'slice': Slice, 'step': Step, 'string': Assertion, 'to-boolean': Coercion, 'to-color': Coercion, 'to-number': Coercion, 'to-string': Coercion, 'var': Var, 'within': Within }; function rgba(ctx, ref) { var r = ref[0]; var g = ref[1]; var b = ref[2]; var a = ref[3]; r = r.evaluate(ctx); g = g.evaluate(ctx); b = b.evaluate(ctx); var alpha = a ? a.evaluate(ctx) : 1; var error = validateRGBA(r, g, b, alpha); if (error) { throw new RuntimeError(error); } return new Color(r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha); } function has(key, obj) { return key in obj; } function get(key, obj) { var v = obj[key]; return typeof v === 'undefined' ? null : v; } function binarySearch(v, a, i, j) { while (i <= j) { var m = i + j >> 1; if (a[m] === v) { return true; } if (a[m] > v) { j = m - 1; } else { i = m + 1; } } return false; } function varargs(type) { return { type: type }; } CompoundExpression.register(expressions, { 'error': [ ErrorType, [StringType], function (ctx, ref) { var v = ref[0]; throw new RuntimeError(v.evaluate(ctx)); } ], 'typeof': [ StringType, [ValueType], function (ctx, ref) { var v = ref[0]; return toString(typeOf(v.evaluate(ctx))); } ], 'to-rgba': [ array(NumberType, 4), [ColorType], function (ctx, ref) { var v = ref[0]; return v.evaluate(ctx).toArray(); } ], 'rgb': [ ColorType, [ NumberType, NumberType, NumberType ], rgba ], 'rgba': [ ColorType, [ NumberType, NumberType, NumberType, NumberType ], rgba ], 'has': { type: BooleanType, overloads: [ [ [StringType], function (ctx, ref) { var key = ref[0]; return has(key.evaluate(ctx), ctx.properties()); } ], [ [ StringType, ObjectType ], function (ctx, ref) { var key = ref[0]; var obj = ref[1]; return has(key.evaluate(ctx), obj.evaluate(ctx)); } ] ] }, 'get': { type: ValueType, overloads: [ [ [StringType], function (ctx, ref) { var key = ref[0]; return get(key.evaluate(ctx), ctx.properties()); } ], [ [ StringType, ObjectType ], function (ctx, ref) { var key = ref[0]; var obj = ref[1]; return get(key.evaluate(ctx), obj.evaluate(ctx)); } ] ] }, 'feature-state': [ ValueType, [StringType], function (ctx, ref) { var key = ref[0]; return get(key.evaluate(ctx), ctx.featureState || {}); } ], 'properties': [ ObjectType, [], function (ctx) { return ctx.properties(); } ], 'geometry-type': [ StringType, [], function (ctx) { return ctx.geometryType(); } ], 'id': [ ValueType, [], function (ctx) { return ctx.id(); } ], 'zoom': [ NumberType, [], function (ctx) { return ctx.globals.zoom; } ], 'heatmap-density': [ NumberType, [], function (ctx) { return ctx.globals.heatmapDensity || 0; } ], 'line-progress': [ NumberType, [], function (ctx) { return ctx.globals.lineProgress || 0; } ], 'accumulated': [ ValueType, [], function (ctx) { return ctx.globals.accumulated === undefined ? null : ctx.globals.accumulated; } ], '+': [ NumberType, varargs(NumberType), function (ctx, args) { var result = 0; for (var i = 0, list = args; i < list.length; i += 1) { var arg = list[i]; result += arg.evaluate(ctx); } return result; } ], '*': [ NumberType, varargs(NumberType), function (ctx, args) { var result = 1; for (var i = 0, list = args; i < list.length; i += 1) { var arg = list[i]; result *= arg.evaluate(ctx); } return result; } ], '-': { type: NumberType, overloads: [ [ [ NumberType, NumberType ], function (ctx, ref) { var a = ref[0]; var b = ref[1]; return a.evaluate(ctx) - b.evaluate(ctx); } ], [ [NumberType], function (ctx, ref) { var a = ref[0]; return -a.evaluate(ctx); } ] ] }, '/': [ NumberType, [ NumberType, NumberType ], function (ctx, ref) { var a = ref[0]; var b = ref[1]; return a.evaluate(ctx) / b.evaluate(ctx); } ], '%': [ NumberType, [ NumberType, NumberType ], function (ctx, ref) { var a = ref[0]; var b = ref[1]; return a.evaluate(ctx) % b.evaluate(ctx); } ], 'ln2': [ NumberType, [], function () { return Math.LN2; } ], 'pi': [ NumberType, [], function () { return Math.PI; } ], 'e': [ NumberType, [], function () { return Math.E; } ], '^': [ NumberType, [ NumberType, NumberType ], function (ctx, ref) { var b = ref[0]; var e = ref[1]; return Math.pow(b.evaluate(ctx), e.evaluate(ctx)); } ], 'sqrt': [ NumberType, [NumberType], function (ctx, ref) { var x = ref[0]; return Math.sqrt(x.evaluate(ctx)); } ], 'log10': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.log(n.evaluate(ctx)) / Math.LN10; } ], 'ln': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.log(n.evaluate(ctx)); } ], 'log2': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.log(n.evaluate(ctx)) / Math.LN2; } ], 'sin': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.sin(n.evaluate(ctx)); } ], 'cos': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.cos(n.evaluate(ctx)); } ], 'tan': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.tan(n.evaluate(ctx)); } ], 'asin': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.asin(n.evaluate(ctx)); } ], 'acos': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.acos(n.evaluate(ctx)); } ], 'atan': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.atan(n.evaluate(ctx)); } ], 'min': [ NumberType, varargs(NumberType), function (ctx, args) { return Math.min.apply(Math, args.map(function (arg) { return arg.evaluate(ctx); })); } ], 'max': [ NumberType, varargs(NumberType), function (ctx, args) { return Math.max.apply(Math, args.map(function (arg) { return arg.evaluate(ctx); })); } ], 'abs': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.abs(n.evaluate(ctx)); } ], 'round': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; var v = n.evaluate(ctx); return v < 0 ? -Math.round(-v) : Math.round(v); } ], 'floor': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.floor(n.evaluate(ctx)); } ], 'ceil': [ NumberType, [NumberType], function (ctx, ref) { var n = ref[0]; return Math.ceil(n.evaluate(ctx)); } ], 'filter-==': [ BooleanType, [ StringType, ValueType ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; return ctx.properties()[k.value] === v.value; } ], 'filter-id-==': [ BooleanType, [ValueType], function (ctx, ref) { var v = ref[0]; return ctx.id() === v.value; } ], 'filter-type-==': [ BooleanType, [StringType], function (ctx, ref) { var v = ref[0]; return ctx.geometryType() === v.value; } ], 'filter-<': [ BooleanType, [ StringType, ValueType ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; var a = ctx.properties()[k.value]; var b = v.value; return typeof a === typeof b && a < b; } ], 'filter-id-<': [ BooleanType, [ValueType], function (ctx, ref) { var v = ref[0]; var a = ctx.id(); var b = v.value; return typeof a === typeof b && a < b; } ], 'filter->': [ BooleanType, [ StringType, ValueType ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; var a = ctx.properties()[k.value]; var b = v.value; return typeof a === typeof b && a > b; } ], 'filter-id->': [ BooleanType, [ValueType], function (ctx, ref) { var v = ref[0]; var a = ctx.id(); var b = v.value; return typeof a === typeof b && a > b; } ], 'filter-<=': [ BooleanType, [ StringType, ValueType ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; var a = ctx.properties()[k.value]; var b = v.value; return typeof a === typeof b && a <= b; } ], 'filter-id-<=': [ BooleanType, [ValueType], function (ctx, ref) { var v = ref[0]; var a = ctx.id(); var b = v.value; return typeof a === typeof b && a <= b; } ], 'filter->=': [ BooleanType, [ StringType, ValueType ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; var a = ctx.properties()[k.value]; var b = v.value; return typeof a === typeof b && a >= b; } ], 'filter-id->=': [ BooleanType, [ValueType], function (ctx, ref) { var v = ref[0]; var a = ctx.id(); var b = v.value; return typeof a === typeof b && a >= b; } ], 'filter-has': [ BooleanType, [ValueType], function (ctx, ref) { var k = ref[0]; return k.value in ctx.properties(); } ], 'filter-has-id': [ BooleanType, [], function (ctx) { return ctx.id() !== null && ctx.id() !== undefined; } ], 'filter-type-in': [ BooleanType, [array(StringType)], function (ctx, ref) { var v = ref[0]; return v.value.indexOf(ctx.geometryType()) >= 0; } ], 'filter-id-in': [ BooleanType, [array(ValueType)], function (ctx, ref) { var v = ref[0]; return v.value.indexOf(ctx.id()) >= 0; } ], 'filter-in-small': [ BooleanType, [ StringType, array(ValueType) ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; return v.value.indexOf(ctx.properties()[k.value]) >= 0; } ], 'filter-in-large': [ BooleanType, [ StringType, array(ValueType) ], function (ctx, ref) { var k = ref[0]; var v = ref[1]; return binarySearch(ctx.properties()[k.value], v.value, 0, v.value.length - 1); } ], 'all': { type: BooleanType, overloads: [ [ [ BooleanType, BooleanType ], function (ctx, ref) { var a = ref[0]; var b = ref[1]; return a.evaluate(ctx) && b.evaluate(ctx); } ], [ varargs(BooleanType), function (ctx, args) { for (var i = 0, list = args; i < list.length; i += 1) { var arg = list[i]; if (!arg.evaluate(ctx)) { return false; } } return true; } ] ] }, 'any': { type: BooleanType, overloads: [ [ [ BooleanType, BooleanType ], function (ctx, ref) { var a = ref[0]; var b = ref[1]; return a.evaluate(ctx) || b.evaluate(ctx); } ], [ varargs(BooleanType), function (ctx, args) { for (var i = 0, list = args; i < list.length; i += 1) { var arg = list[i]; if (arg.evaluate(ctx)) { return true; } } return false; } ] ] }, '!': [ BooleanType, [BooleanType], function (ctx, ref) { var b = ref[0]; return !b.evaluate(ctx); } ], 'is-supported-script': [ BooleanType, [StringType], function (ctx, ref) { var s = ref[0]; var isSupportedScript = ctx.globals && ctx.globals.isSupportedScript; if (isSupportedScript) { return isSupportedScript(s.evaluate(ctx)); } return true; } ], 'upcase': [ StringType, [StringType], function (ctx, ref) { var s = ref[0]; return s.evaluate(ctx).toUpperCase(); } ], 'downcase': [ StringType, [StringType], function (ctx, ref) { var s = ref[0]; return s.evaluate(ctx).toLowerCase(); } ], 'concat': [ StringType, varargs(ValueType), function (ctx, args) { return args.map(function (arg) { return toString$1(arg.evaluate(ctx)); }).join(''); } ], 'resolved-locale': [ StringType, [CollatorType], function (ctx, ref) { var collator = ref[0]; return collator.evaluate(ctx).resolvedLocale(); } ] }); function success(value) { return { result: 'success', value: value }; } function error(value) { return { result: 'error', value: value }; } function supportsPropertyExpression(spec) { return spec['property-type'] === 'data-driven' || spec['property-type'] === 'cross-faded-data-driven'; } function supportsZoomExpression(spec) { return !!spec.expression && spec.expression.parameters.indexOf('zoom') > -1; } function supportsInterpolation(spec) { return !!spec.expression && spec.expression.interpolated; } function getType(val) { if (val instanceof Number) { return 'number'; } else if (val instanceof String) { return 'string'; } else if (val instanceof Boolean) { return 'boolean'; } else if (Array.isArray(val)) { return 'array'; } else if (val === null) { return 'null'; } else { return typeof val; } } function isFunction(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); } function identityFunction(x) { return x; } function createFunction(parameters, propertySpec) { var isColor = propertySpec.type === 'color'; var zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === 'object'; var featureDependent = zoomAndFeatureDependent || parameters.property !== undefined; var zoomDependent = zoomAndFeatureDependent || !featureDependent; var type = parameters.type || (supportsInterpolation(propertySpec) ? 'exponential' : 'interval'); if (isColor) { parameters = extend$1({}, parameters); if (parameters.stops) { parameters.stops = parameters.stops.map(function (stop) { return [ stop[0], Color.parse(stop[1]) ]; }); } if (parameters.default) { parameters.default = Color.parse(parameters.default); } else { parameters.default = Color.parse(propertySpec.default); } } if (parameters.colorSpace && parameters.colorSpace !== 'rgb' && !colorSpaces[parameters.colorSpace]) { throw new Error('Unknown color space: ' + parameters.colorSpace); } var innerFun; var hashedStops; var categoricalKeyType; if (type === 'exponential') { innerFun = evaluateExponentialFunction; } else if (type === 'interval') { innerFun = evaluateIntervalFunction; } else if (type === 'categorical') { innerFun = evaluateCategoricalFunction; hashedStops = Object.create(null); for (var i = 0, list = parameters.stops; i < list.length; i += 1) { var stop = list[i]; hashedStops[stop[0]] = stop[1]; } categoricalKeyType = typeof parameters.stops[0][0]; } else if (type === 'identity') { innerFun = evaluateIdentityFunction; } else { throw new Error('Unknown function type "' + type + '"'); } if (zoomAndFeatureDependent) { var featureFunctions = {}; var zoomStops = []; for (var s = 0; s < parameters.stops.length; s++) { var stop$1 = parameters.stops[s]; var zoom = stop$1[0].zoom; if (featureFunctions[zoom] === undefined) { featureFunctions[zoom] = { zoom: zoom, type: parameters.type, property: parameters.property, default: parameters.default, stops: [] }; zoomStops.push(zoom); } featureFunctions[zoom].stops.push([ stop$1[0].value, stop$1[1] ]); } var featureFunctionStops = []; for (var i$1 = 0, list$1 = zoomStops; i$1 < list$1.length; i$1 += 1) { var z = list$1[i$1]; featureFunctionStops.push([ featureFunctions[z].zoom, createFunction(featureFunctions[z], propertySpec) ]); } var interpolationType = { name: 'linear' }; return { kind: 'composite', interpolationType: interpolationType, interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType), zoomStops: featureFunctionStops.map(function (s) { return s[0]; }), evaluate: function evaluate(ref, properties) { var zoom = ref.zoom; return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, propertySpec, zoom).evaluate(zoom, properties); } }; } else if (zoomDependent) { var interpolationType$1 = type === 'exponential' ? { name: 'exponential', base: parameters.base !== undefined ? parameters.base : 1 } : null; return { kind: 'camera', interpolationType: interpolationType$1, interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType$1), zoomStops: parameters.stops.map(function (s) { return s[0]; }), evaluate: function (ref) { var zoom = ref.zoom; return innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType); } }; } else { return { kind: 'source', evaluate: function evaluate(_, feature) { var value = feature && feature.properties ? feature.properties[parameters.property] : undefined; if (value === undefined) { return coalesce(parameters.default, propertySpec.default); } return innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType); } }; } } function coalesce(a, b, c) { if (a !== undefined) { return a; } if (b !== undefined) { return b; } if (c !== undefined) { return c; } } function evaluateCategoricalFunction(parameters, propertySpec, input, hashedStops, keyType) { var evaluated = typeof input === keyType ? hashedStops[input] : undefined; return coalesce(evaluated, parameters.default, propertySpec.default); } function evaluateIntervalFunction(parameters, propertySpec, input) { if (getType(input) !== 'number') { return coalesce(parameters.default, propertySpec.default); } var n = parameters.stops.length; if (n === 1) { return parameters.stops[0][1]; } if (input <= parameters.stops[0][0]) { return parameters.stops[0][1]; } if (input >= parameters.stops[n - 1][0]) { return parameters.stops[n - 1][1]; } var index = findStopLessThanOrEqualTo(parameters.stops.map(function (stop) { return stop[0]; }), input); return parameters.stops[index][1]; } function evaluateExponentialFunction(parameters, propertySpec, input) { var base = parameters.base !== undefined ? parameters.base : 1; if (getType(input) !== 'number') { return coalesce(parameters.default, propertySpec.default); } var n = parameters.stops.length; if (n === 1) { return parameters.stops[0][1]; } if (input <= parameters.stops[0][0]) { return parameters.stops[0][1]; } if (input >= parameters.stops[n - 1][0]) { return parameters.stops[n - 1][1]; } var index = findStopLessThanOrEqualTo(parameters.stops.map(function (stop) { return stop[0]; }), input); var t = interpolationFactor(input, base, parameters.stops[index][0], parameters.stops[index + 1][0]); var outputLower = parameters.stops[index][1]; var outputUpper = parameters.stops[index + 1][1]; var interp = interpolate[propertySpec.type] || identityFunction; if (parameters.colorSpace && parameters.colorSpace !== 'rgb') { var colorspace = colorSpaces[parameters.colorSpace]; interp = function (a, b) { return colorspace.reverse(colorspace.interpolate(colorspace.forward(a), colorspace.forward(b), t)); }; } if (typeof outputLower.evaluate === 'function') { return { evaluate: function evaluate() { var args = [], len = arguments.length; while (len--) args[len] = arguments[len]; var evaluatedLower = outputLower.evaluate.apply(undefined, args); var evaluatedUpper = outputUpper.evaluate.apply(undefined, args); if (evaluatedLower === undefined || evaluatedUpper === undefined) { return undefined; } return interp(evaluatedLower, evaluatedUpper, t); } }; } return interp(outputLower, outputUpper, t); } function evaluateIdentityFunction(parameters, propertySpec, input) { if (propertySpec.type === 'color') { input = Color.parse(input); } else if (propertySpec.type === 'formatted') { input = Formatted.fromString(input.toString()); } else if (propertySpec.type === 'resolvedImage') { input = ResolvedImage.fromString(input.toString()); } else if (getType(input) !== propertySpec.type && (propertySpec.type !== 'enum' || !propertySpec.values[input])) { input = undefined; } return coalesce(input, parameters.default, propertySpec.default); } function interpolationFactor(input, base, lowerValue, upperValue) { var difference = upperValue - lowerValue; var progress = input - lowerValue; if (difference === 0) { return 0; } else if (base === 1) { return progress / difference; } else { return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1); } } var StyleExpression = function StyleExpression(expression, propertySpec) { this.expression = expression; this._warningHistory = {}; this._evaluator = new EvaluationContext(); this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null; this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null; }; StyleExpression.prototype.evaluateWithoutErrorHandling = function evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) { this._evaluator.globals = globals; this._evaluator.feature = feature; this._evaluator.featureState = featureState; this._evaluator.canonical = canonical; this._evaluator.availableImages = availableImages || null; this._evaluator.formattedSection = formattedSection; return this.expression.evaluate(this._evaluator); }; StyleExpression.prototype.evaluate = function evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) { this._evaluator.globals = globals; this._evaluator.feature = feature || null; this._evaluator.featureState = featureState || null; this._evaluator.canonical = canonical; this._evaluator.availableImages = availableImages || null; this._evaluator.formattedSection = formattedSection || null; try { var val = this.expression.evaluate(this._evaluator); if (val === null || val === undefined || typeof val === 'number' && val !== val) { return this._defaultValue; } if (this._enumValues && !(val in this._enumValues)) { throw new RuntimeError('Expected value to be one of ' + Object.keys(this._enumValues).map(function (v) { return JSON.stringify(v); }).join(', ') + ', but found ' + JSON.stringify(val) + ' instead.'); } return val; } catch (e) { if (!this._warningHistory[e.message]) { this._warningHistory[e.message] = true; if (typeof console !== 'undefined') { console.warn(e.message); } } return this._defaultValue; } }; function isExpression(expression) { return Array.isArray(expression) && expression.length > 0 && typeof expression[0] === 'string' && expression[0] in expressions; } function createExpression(expression, propertySpec) { var parser = new ParsingContext(expressions, [], propertySpec ? getExpectedType(propertySpec) : undefined); var parsed = parser.parse(expression, undefined, undefined, undefined, propertySpec && propertySpec.type === 'string' ? { typeAnnotation: 'coerce' } : undefined); if (!parsed) { return error(parser.errors); } return success(new StyleExpression(parsed, propertySpec)); } var ZoomConstantExpression = function ZoomConstantExpression(kind, expression) { this.kind = kind; this._styleExpression = expression; this.isStateDependent = kind !== 'constant' && !isStateConstant(expression.expression); }; ZoomConstantExpression.prototype.evaluateWithoutErrorHandling = function evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) { return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection); }; ZoomConstantExpression.prototype.evaluate = function evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) { return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection); }; var ZoomDependentExpression = function ZoomDependentExpression(kind, expression, zoomStops, interpolationType) { this.kind = kind; this.zoomStops = zoomStops; this._styleExpression = expression; this.isStateDependent = kind !== 'camera' && !isStateConstant(expression.expression); this.interpolationType = interpolationType; }; ZoomDependentExpression.prototype.evaluateWithoutErrorHandling = function evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection) { return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection); }; ZoomDependentExpression.prototype.evaluate = function evaluate(globals, feature, featureState, canonical, availableImages, formattedSection) { return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection); }; ZoomDependentExpression.prototype.interpolationFactor = function interpolationFactor(input, lower, upper) { if (this.interpolationType) { return Interpolate.interpolationFactor(this.interpolationType, input, lower, upper); } else { return 0; } }; function createPropertyExpression(expression, propertySpec) { expression = createExpression(expression, propertySpec); if (expression.result === 'error') { return expression; } var parsed = expression.value.expression; var isFeatureConstant$1 = isFeatureConstant(parsed); if (!isFeatureConstant$1 && !supportsPropertyExpression(propertySpec)) { return error([new ParsingError('', 'data expressions not supported')]); } var isZoomConstant = isGlobalPropertyConstant(parsed, ['zoom']); if (!isZoomConstant && !supportsZoomExpression(propertySpec)) { return error([new ParsingError('', 'zoom expressions not supported')]); } var zoomCurve = findZoomCurve(parsed); if (!zoomCurve && !isZoomConstant) { return error([new ParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.')]); } else if (zoomCurve instanceof ParsingError) { return error([zoomCurve]); } else if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) { return error([new ParsingError('', '"interpolate" expressions cannot be used with this property')]); } if (!zoomCurve) { return success(isFeatureConstant$1 ? new ZoomConstantExpression('constant', expression.value) : new ZoomConstantExpression('source', expression.value)); } var interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : undefined; return success(isFeatureConstant$1 ? new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType) : new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType)); } var StylePropertyFunction = function StylePropertyFunction(parameters, specification) { this._parameters = parameters; this._specification = specification; extend$1(this, createFunction(this._parameters, this._specification)); }; StylePropertyFunction.deserialize = function deserialize(serialized) { return new StylePropertyFunction(serialized._parameters, serialized._specification); }; StylePropertyFunction.serialize = function serialize(input) { return { _parameters: input._parameters, _specification: input._specification }; }; function normalizePropertyExpression(value, specification) { if (isFunction(value)) { return new StylePropertyFunction(value, specification); } else if (isExpression(value)) { var expression = createPropertyExpression(value, specification); if (expression.result === 'error') { throw new Error(expression.value.map(function (err) { return err.key + ': ' + err.message; }).join(', ')); } return expression.value; } else { var constant = value; if (typeof value === 'string' && specification.type === 'color') { constant = Color.parse(value); } return { kind: 'constant', evaluate: function () { return constant; } }; } } function findZoomCurve(expression) { var result = null; if (expression instanceof Let) { result = findZoomCurve(expression.result); } else if (expression instanceof Coalesce) { for (var i = 0, list = expression.args; i < list.length; i += 1) { var arg = list[i]; result = findZoomCurve(arg); if (result) { break; } } } else if ((expression instanceof Step || expression instanceof Interpolate) && expression.input instanceof CompoundExpression && expression.input.name === 'zoom') { result = expression; } if (result instanceof ParsingError) { return result; } expression.eachChild(function (child) { var childResult = findZoomCurve(child); if (childResult instanceof ParsingError) { result = childResult; } else if (!result && childResult) { result = new ParsingError('', '"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.'); } else if (result && childResult && result !== childResult) { result = new ParsingError('', 'Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.'); } }); return result; } function getExpectedType(spec) { var types = { color: ColorType, string: StringType, number: NumberType, enum: StringType, boolean: BooleanType, formatted: FormattedType, resolvedImage: ResolvedImageType }; if (spec.type === 'array') { return array(types[spec.value] || ValueType, spec.length); } return types[spec.type]; } function getDefaultValue(spec) { if (spec.type === 'color' && isFunction(spec.default)) { return new Color(0, 0, 0, 0); } else if (spec.type === 'color') { return Color.parse(spec.default) || null; } else if (spec.default === undefined) { return null; } else { return spec.default; } } function validateObject(options) { var key = options.key; var object = options.value; var elementSpecs = options.valueSpec || {}; var elementValidators = options.objectElementValidators || {}; var style = options.style; var styleSpec = options.styleSpec; var errors = []; var type = getType(object); if (type !== 'object') { return [new ValidationError(key, object, 'object expected, ' + type + ' found')]; } for (var objectKey in object) { var elementSpecKey = objectKey.split('.')[0]; var elementSpec = elementSpecs[elementSpecKey] || elementSpecs['*']; var validateElement = void 0; if (elementValidators[elementSpecKey]) { validateElement = elementValidators[elementSpecKey]; } else if (elementSpecs[elementSpecKey]) { validateElement = validate; } else if (elementValidators['*']) { validateElement = elementValidators['*']; } else if (elementSpecs['*']) { validateElement = validate; } else { errors.push(new ValidationError(key, object[objectKey], 'unknown property "' + objectKey + '"')); continue; } errors = errors.concat(validateElement({ key: (key ? key + '.' : key) + objectKey, value: object[objectKey], valueSpec: elementSpec, style: style, styleSpec: styleSpec, object: object, objectKey: objectKey }, object)); } for (var elementSpecKey$1 in elementSpecs) { if (elementValidators[elementSpecKey$1]) { continue; } if (elementSpecs[elementSpecKey$1].required && elementSpecs[elementSpecKey$1]['default'] === undefined && object[elementSpecKey$1] === undefined) { errors.push(new ValidationError(key, object, 'missing required property "' + elementSpecKey$1 + '"')); } } return errors; } function validateArray(options) { var array = options.value; var arraySpec = options.valueSpec; var style = options.style; var styleSpec = options.styleSpec; var key = options.key; var validateArrayElement = options.arrayElementValidator || validate; if (getType(array) !== 'array') { return [new ValidationError(key, array, 'array expected, ' + getType(array) + ' found')]; } if (arraySpec.length && array.length !== arraySpec.length) { return [new ValidationError(key, array, 'array length ' + arraySpec.length + ' expected, length ' + array.length + ' found')]; } if (arraySpec['min-length'] && array.length < arraySpec['min-length']) { return [new ValidationError(key, array, 'array length at least ' + arraySpec['min-length'] + ' expected, length ' + array.length + ' found')]; } var arrayElementSpec = { 'type': arraySpec.value, 'values': arraySpec.values }; if (styleSpec.$version < 7) { arrayElementSpec.function = arraySpec.function; } if (getType(arraySpec.value) === 'object') { arrayElementSpec = arraySpec.value; } var errors = []; for (var i = 0; i < array.length; i++) { errors = errors.concat(validateArrayElement({ array: array, arrayIndex: i, value: array[i], valueSpec: arrayElementSpec, style: style, styleSpec: styleSpec, key: key + '[' + i + ']' })); } return errors; } function validateNumber(options) { var key = options.key; var value = options.value; var valueSpec = options.valueSpec; var type = getType(value); if (type === 'number' && value !== value) { type = 'NaN'; } if (type !== 'number') { return [new ValidationError(key, value, 'number expected, ' + type + ' found')]; } if ('minimum' in valueSpec && value < valueSpec.minimum) { return [new ValidationError(key, value, value + ' is less than the minimum value ' + valueSpec.minimum)]; } if ('maximum' in valueSpec && value > valueSpec.maximum) { return [new ValidationError(key, value, value + ' is greater than the maximum value ' + valueSpec.maximum)]; } return []; } function validateFunction(options) { var functionValueSpec = options.valueSpec; var functionType = unbundle(options.value.type); var stopKeyType; var stopDomainValues = {}; var previousStopDomainValue; var previousStopDomainZoom; var isZoomFunction = functionType !== 'categorical' && options.value.property === undefined; var isPropertyFunction = !isZoomFunction; var isZoomAndPropertyFunction = getType(options.value.stops) === 'array' && getType(options.value.stops[0]) === 'array' && getType(options.value.stops[0][0]) === 'object'; var errors = validateObject({ key: options.key, value: options.value, valueSpec: options.styleSpec.function, style: options.style, styleSpec: options.styleSpec, objectElementValidators: { stops: validateFunctionStops, default: validateFunctionDefault } }); if (functionType === 'identity' && isZoomFunction) { errors.push(new ValidationError(options.key, options.value, 'missing required property "property"')); } if (functionType !== 'identity' && !options.value.stops) { errors.push(new ValidationError(options.key, options.value, 'missing required property "stops"')); } if (functionType === 'exponential' && options.valueSpec.expression && !supportsInterpolation(options.valueSpec)) { errors.push(new ValidationError(options.key, options.value, 'exponential functions not supported')); } if (options.styleSpec.$version >= 8) { if (isPropertyFunction && !supportsPropertyExpression(options.valueSpec)) { errors.push(new ValidationError(options.key, options.value, 'property functions not supported')); } else if (isZoomFunction && !supportsZoomExpression(options.valueSpec)) { errors.push(new ValidationError(options.key, options.value, 'zoom functions not supported')); } } if ((functionType === 'categorical' || isZoomAndPropertyFunction) && options.value.property === undefined) { errors.push(new ValidationError(options.key, options.value, '"property" property is required')); } return errors; function validateFunctionStops(options) { if (functionType === 'identity') { return [new ValidationError(options.key, options.value, 'identity function may not have a "stops" property')]; } var errors = []; var value = options.value; errors = errors.concat(validateArray({ key: options.key, value: value, valueSpec: options.valueSpec, style: options.style, styleSpec: options.styleSpec, arrayElementValidator: validateFunctionStop })); if (getType(value) === 'array' && value.length === 0) { errors.push(new ValidationError(options.key, value, 'array must have at least one stop')); } return errors; } function validateFunctionStop(options) { var errors = []; var value = options.value; var key = options.key; if (getType(value) !== 'array') { return [new ValidationError(key, value, 'array expected, ' + getType(value) + ' found')]; } if (value.length !== 2) { return [new ValidationError(key, value, 'array length 2 expected, length ' + value.length + ' found')]; } if (isZoomAndPropertyFunction) { if (getType(value[0]) !== 'object') { return [new ValidationError(key, value, 'object expected, ' + getType(value[0]) + ' found')]; } if (value[0].zoom === undefined) { return [new ValidationError(key, value, 'object stop key must have zoom')]; } if (value[0].value === undefined) { return [new ValidationError(key, value, 'object stop key must have value')]; } if (previousStopDomainZoom && previousStopDomainZoom > unbundle(value[0].zoom)) { return [new ValidationError(key, value[0].zoom, 'stop zoom values must appear in ascending order')]; } if (unbundle(value[0].zoom) !== previousStopDomainZoom) { previousStopDomainZoom = unbundle(value[0].zoom); previousStopDomainValue = undefined; stopDomainValues = {}; } errors = errors.concat(validateObject({ key: key + '[0]', value: value[0], valueSpec: { zoom: {} }, style: options.style, styleSpec: options.styleSpec, objectElementValidators: { zoom: validateNumber, value: validateStopDomainValue } })); } else { errors = errors.concat(validateStopDomainValue({ key: key + '[0]', value: value[0], valueSpec: {}, style: options.style, styleSpec: options.styleSpec }, value)); } if (isExpression(deepUnbundle(value[1]))) { return errors.concat([new ValidationError(key + '[1]', value[1], 'expressions are not allowed in function stops.')]); } return errors.concat(validate({ key: key + '[1]', value: value[1], valueSpec: functionValueSpec, style: options.style, styleSpec: options.styleSpec })); } function validateStopDomainValue(options, stop) { var type = getType(options.value); var value = unbundle(options.value); var reportValue = options.value !== null ? options.value : stop; if (!stopKeyType) { stopKeyType = type; } else if (type !== stopKeyType) { return [new ValidationError(options.key, reportValue, type + ' stop domain type must match previous stop domain type ' + stopKeyType)]; } if (type !== 'number' && type !== 'string' && type !== 'boolean') { return [new ValidationError(options.key, reportValue, 'stop domain value must be a number, string, or boolean')]; } if (type !== 'number' && functionType !== 'categorical') { var message = 'number expected, ' + type + ' found'; if (supportsPropertyExpression(functionValueSpec) && functionType === undefined) { message += '\nIf you intended to use a categorical function, specify `"type": "categorical"`.'; } return [new ValidationError(options.key, reportValue, message)]; } if (functionType === 'categorical' && type === 'number' && (!isFinite(value) || Math.floor(value) !== value)) { return [new ValidationError(options.key, reportValue, 'integer expected, found ' + value)]; } if (functionType !== 'categorical' && type === 'number' && previousStopDomainValue !== undefined && value < previousStopDomainValue) { return [new ValidationError(options.key, reportValue, 'stop domain values must appear in ascending order')]; } else { previousStopDomainValue = value; } if (functionType === 'categorical' && value in stopDomainValues) { return [new ValidationError(options.key, reportValue, 'stop domain values must be unique')]; } else { stopDomainValues[value] = true; } return []; } function validateFunctionDefault(options) { return validate({ key: options.key, value: options.value, valueSpec: functionValueSpec, style: options.style, styleSpec: options.styleSpec }); } } function validateExpression(options) { var expression = (options.expressionContext === 'property' ? createPropertyExpression : createExpression)(deepUnbundle(options.value), options.valueSpec); if (expression.result === 'error') { return expression.value.map(function (error) { return new ValidationError('' + options.key + error.key, options.value, error.message); }); } var expressionObj = expression.value.expression || expression.value._styleExpression.expression; if (options.expressionContext === 'property' && options.propertyKey === 'text-font' && !expressionObj.outputDefined()) { return [new ValidationError(options.key, options.value, 'Invalid data expression for "' + options.propertyKey + '". Output values must be contained as literals within the expression.')]; } if (options.expressionContext === 'property' && options.propertyType === 'layout' && !isStateConstant(expressionObj)) { return [new ValidationError(options.key, options.value, '"feature-state" data expressions are not supported with layout properties.')]; } if (options.expressionContext === 'filter' && !isStateConstant(expressionObj)) { return [new ValidationError(options.key, options.value, '"feature-state" data expressions are not supported with filters.')]; } if (options.expressionContext && options.expressionContext.indexOf('cluster') === 0) { if (!isGlobalPropertyConstant(expressionObj, [ 'zoom', 'feature-state' ])) { return [new ValidationError(options.key, options.value, '"zoom" and "feature-state" expressions are not supported with cluster properties.')]; } if (options.expressionContext === 'cluster-initial' && !isFeatureConstant(expressionObj)) { return [new ValidationError(options.key, options.value, 'Feature data expressions are not supported with initial expression part of cluster properties.')]; } } return []; } function validateBoolean(options) { var value = options.value; var key = options.key; var type = getType(value); if (type !== 'boolean') { return [new ValidationError(key, value, 'boolean expected, ' + type + ' found')]; } return []; } function validateColor(options) { var key = options.key; var value = options.value; var type = getType(value); if (type !== 'string') { return [new ValidationError(key, value, 'color expected, ' + type + ' found')]; } if (csscolorparser_1(value) === null) { return [new ValidationError(key, value, 'color expected, "' + value + '" found')]; } return []; } function validateEnum(options) { var key = options.key; var value = options.value; var valueSpec = options.valueSpec; var errors = []; if (Array.isArray(valueSpec.values)) { if (valueSpec.values.indexOf(unbundle(value)) === -1) { errors.push(new ValidationError(key, value, 'expected one of [' + valueSpec.values.join(', ') + '], ' + JSON.stringify(value) + ' found')); } } else { if (Object.keys(valueSpec.values).indexOf(unbundle(value)) === -1) { errors.push(new ValidationError(key, value, 'expected one of [' + Object.keys(valueSpec.values).join(', ') + '], ' + JSON.stringify(value) + ' found')); } } return errors; } function isExpressionFilter(filter) { if (filter === true || filter === false) { return true; } if (!Array.isArray(filter) || filter.length === 0) { return false; } switch (filter[0]) { case 'has': return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type'; case 'in': return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2])); case '!in': case '!has': case 'none': return false; case '==': case '!=': case '>': case '>=': case '<': case '<=': return filter.length !== 3 || (Array.isArray(filter[1]) || Array.isArray(filter[2])); case 'any': case 'all': for (var i = 0, list = filter.slice(1); i < list.length; i += 1) { var f = list[i]; if (!isExpressionFilter(f) && typeof f !== 'boolean') { return false; } } return true; default: return true; } } var filterSpec = { 'type': 'boolean', 'default': false, 'transition': false, 'property-type': 'data-driven', 'expression': { 'interpolated': false, 'parameters': [ 'zoom', 'feature' ] } }; function createFilter(filter) { if (filter === null || filter === undefined) { return { filter: function () { return true; }, needGeometry: false }; } if (!isExpressionFilter(filter)) { filter = convertFilter(filter); } var compiled = createExpression(filter, filterSpec); if (compiled.result === 'error') { throw new Error(compiled.value.map(function (err) { return err.key + ': ' + err.message; }).join(', ')); } else { var needGeometry = geometryNeeded(filter); return { filter: function (globalProperties, feature, canonical) { return compiled.value.evaluate(globalProperties, feature, {}, canonical); }, needGeometry: needGeometry }; } } function compare(a, b) { return a < b ? -1 : a > b ? 1 : 0; } function geometryNeeded(filter) { if (!Array.isArray(filter)) { return false; } if (filter[0] === 'within') { return true; } for (var index = 1; index < filter.length; index++) { if (geometryNeeded(filter[index])) { return true; } } return false; } function convertFilter(filter) { if (!filter) { return true; } var op = filter[0]; if (filter.length <= 1) { return op !== 'any'; } var converted = op === '==' ? convertComparisonOp(filter[1], filter[2], '==') : op === '!=' ? convertNegation(convertComparisonOp(filter[1], filter[2], '==')) : op === '<' || op === '>' || op === '<=' || op === '>=' ? convertComparisonOp(filter[1], filter[2], op) : op === 'any' ? convertDisjunctionOp(filter.slice(1)) : op === 'all' ? ['all'].concat(filter.slice(1).map(convertFilter)) : op === 'none' ? ['all'].concat(filter.slice(1).map(convertFilter).map(convertNegation)) : op === 'in' ? convertInOp(filter[1], filter.slice(2)) : op === '!in' ? convertNegation(convertInOp(filter[1], filter.slice(2))) : op === 'has' ? convertHasOp(filter[1]) : op === '!has' ? convertNegation(convertHasOp(filter[1])) : op === 'within' ? filter : true; return converted; } function convertComparisonOp(property, value, op) { switch (property) { case '$type': return [ 'filter-type-' + op, value ]; case '$id': return [ 'filter-id-' + op, value ]; default: return [ 'filter-' + op, property, value ]; } } function convertDisjunctionOp(filters) { return ['any'].concat(filters.map(convertFilter)); } function convertInOp(property, values) { if (values.length === 0) { return false; } switch (property) { case '$type': return [ 'filter-type-in', [ 'literal', values ] ]; case '$id': return [ 'filter-id-in', [ 'literal', values ] ]; default: if (values.length > 200 && !values.some(function (v) { return typeof v !== typeof values[0]; })) { return [ 'filter-in-large', property, [ 'literal', values.sort(compare) ] ]; } else { return [ 'filter-in-small', property, [ 'literal', values ] ]; } } } function convertHasOp(property) { switch (property) { case '$type': return true; case '$id': return ['filter-has-id']; default: return [ 'filter-has', property ]; } } function convertNegation(filter) { return [ '!', filter ]; } function validateFilter(options) { if (isExpressionFilter(deepUnbundle(options.value))) { return validateExpression(extend$1({}, options, { expressionContext: 'filter', valueSpec: { value: 'boolean' } })); } else { return validateNonExpressionFilter(options); } } function validateNonExpressionFilter(options) { var value = options.value; var key = options.key; if (getType(value) !== 'array') { return [new ValidationError(key, value, 'array expected, ' + getType(value) + ' found')]; } var styleSpec = options.styleSpec; var type; var errors = []; if (value.length < 1) { return [new ValidationError(key, value, 'filter array must have at least 1 element')]; } errors = errors.concat(validateEnum({ key: key + '[0]', value: value[0], valueSpec: styleSpec.filter_operator, style: options.style, styleSpec: options.styleSpec })); switch (unbundle(value[0])) { case '<': case '<=': case '>': case '>=': if (value.length >= 2 && unbundle(value[1]) === '$type') { errors.push(new ValidationError(key, value, '"$type" cannot be use with operator "' + value[0] + '"')); } case '==': case '!=': if (value.length !== 3) { errors.push(new ValidationError(key, value, 'filter array for operator "' + value[0] + '" must have 3 elements')); } case 'in': case '!in': if (value.length >= 2) { type = getType(value[1]); if (type !== 'string') { errors.push(new ValidationError(key + '[1]', value[1], 'string expected, ' + type + ' found')); } } for (var i = 2; i < value.length; i++) { type = getType(value[i]); if (unbundle(value[1]) === '$type') { errors = errors.concat(validateEnum({ key: key + '[' + i + ']', value: value[i], valueSpec: styleSpec.geometry_type, style: options.style, styleSpec: options.styleSpec })); } else if (type !== 'string' && type !== 'number' && type !== 'boolean') { errors.push(new ValidationError(key + '[' + i + ']', value[i], 'string, number, or boolean expected, ' + type + ' found')); } } break; case 'any': case 'all': case 'none': for (var i$1 = 1; i$1 < value.length; i$1++) { errors = errors.concat(validateNonExpressionFilter({ key: key + '[' + i$1 + ']', value: value[i$1], style: options.style, styleSpec: options.styleSpec })); } break; case 'has': case '!has': type = getType(value[1]); if (value.length !== 2) { errors.push(new ValidationError(key, value, 'filter array for "' + value[0] + '" operator must have 2 elements')); } else if (type !== 'string') { errors.push(new ValidationError(key + '[1]', value[1], 'string expected, ' + type + ' found')); } break; case 'within': type = getType(value[1]); if (value.length !== 2) { errors.push(new ValidationError(key, value, 'filter array for "' + value[0] + '" operator must have 2 elements')); } else if (type !== 'object') { errors.push(new ValidationError(key + '[1]', value[1], 'object expected, ' + type + ' found')); } break; } return errors; } function validateProperty(options, propertyType) { var key = options.key; var style = options.style; var styleSpec = options.styleSpec; var value = options.value; var propertyKey = options.objectKey; var layerSpec = styleSpec[propertyType + '_' + options.layerType]; if (!layerSpec) { return []; } var transitionMatch = propertyKey.match(/^(.*)-transition$/); if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) { return validate({ key: key, value: value, valueSpec: styleSpec.transition, style: style, styleSpec: styleSpec }); } var valueSpec = options.valueSpec || layerSpec[propertyKey]; if (!valueSpec) { return [new ValidationError(key, value, 'unknown property "' + propertyKey + '"')]; } var tokenMatch; if (getType(value) === 'string' && supportsPropertyExpression(valueSpec) && !valueSpec.tokens && (tokenMatch = /^{([^}]+)}$/.exec(value))) { 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]) + ' }`.')]; } var errors = []; if (options.layerType === 'symbol') { if (propertyKey === 'text-field' && style && !style.glyphs) { errors.push(new ValidationError(key, value, 'use of "text-field" requires a style "glyphs" property')); } if (propertyKey === 'text-font' && isFunction(deepUnbundle(value)) && unbundle(value.type) === 'identity') { errors.push(new ValidationError(key, value, '"text-font" does not support identity functions')); } } return errors.concat(validate({ key: options.key, value: value, valueSpec: valueSpec, style: style, styleSpec: styleSpec, expressionContext: 'property', propertyType: propertyType, propertyKey: propertyKey })); } function validatePaintProperty(options) { return validateProperty(options, 'paint'); } function validateLayoutProperty(options) { return validateProperty(options, 'layout'); } function validateLayer(options) { var errors = []; var layer = options.value; var key = options.key; var style = options.style; var styleSpec = options.styleSpec; if (!layer.type && !layer.ref) { errors.push(new ValidationError(key, layer, 'either "type" or "ref" is required')); } var type = unbundle(layer.type); var ref = unbundle(layer.ref); if (layer.id) { var layerId = unbundle(layer.id); for (var i = 0; i < options.arrayIndex; i++) { var otherLayer = style.layers[i]; if (unbundle(otherLayer.id) === layerId) { errors.push(new ValidationError(key, layer.id, 'duplicate layer id "' + layer.id + '", previously used at line ' + otherLayer.id.__line__)); } } } if ('ref' in layer) { [ 'type', 'source', 'source-layer', 'filter', 'layout' ].forEach(function (p) { if (p in layer) { errors.push(new ValidationError(key, layer[p], '"' + p + '" is prohibited for ref layers')); } }); var parent; style.layers.forEach(function (layer) { if (unbundle(layer.id) === ref) { parent = layer; } }); if (!parent) { errors.push(new ValidationError(key, layer.ref, 'ref layer "' + ref + '" not found')); } else if (parent.ref) { errors.push(new ValidationError(key, layer.ref, 'ref cannot reference another ref layer')); } else { type = unbundle(parent.type); } } else if (type !== 'background') { if (!layer.source) { errors.push(new ValidationError(key, layer, 'missing required property "source"')); } else { var source = style.sources && style.sources[layer.source]; var sourceType = source && unbundle(source.type); if (!source) { errors.push(new ValidationError(key, layer.source, 'source "' + layer.source + '" not found')); } else if (sourceType === 'vector' && type === 'raster') { errors.push(new ValidationError(key, layer.source, 'layer "' + layer.id + '" requires a raster source')); } else if (sourceType === 'raster' && type !== 'raster') { errors.push(new ValidationError(key, layer.source, 'layer "' + layer.id + '" requires a vector source')); } else if (sourceType === 'vector' && !layer['source-layer']) { errors.push(new ValidationError(key, layer, 'layer "' + layer.id + '" must specify a "source-layer"')); } else if (sourceType === 'raster-dem' && type !== 'hillshade') { errors.push(new ValidationError(key, layer.source, 'raster-dem source can only be used with layer type \'hillshade\'.')); } else if (type === 'line' && layer.paint && layer.paint['line-gradient'] && (sourceType !== 'geojson' || !source.lineMetrics)) { errors.push(new ValidationError(key, layer, 'layer "' + layer.id + '" specifies a line-gradient, which requires a GeoJSON source with `lineMetrics` enabled.')); } } } errors = errors.concat(validateObject({ key: key, value: layer, valueSpec: styleSpec.layer, style: options.style, styleSpec: options.styleSpec, objectElementValidators: { '*': function _() { return []; }, type: function type() { return validate({ key: key + '.type', value: layer.type, valueSpec: styleSpec.layer.type, style: options.style, styleSpec: options.styleSpec, object: layer, objectKey: 'type' }); }, filter: validateFilter, layout: function layout(options) { return validateObject({ layer: layer, key: options.key, value: options.value, style: options.style, styleSpec: options.styleSpec, objectElementValidators: { '*': function _(options) { return validateLayoutProperty(extend$1({ layerType: type }, options)); } } }); }, paint: function paint(options) { return validateObject({ layer: layer, key: options.key, value: options.value, style: options.style, styleSpec: options.styleSpec, objectElementValidators: { '*': function _(options) { return validatePaintProperty(extend$1({ layerType: type }, options)); } } }); } } })); return errors; } function validateString(options) { var value = options.value; var key = options.key; var type = getType(value); if (type !== 'string') { return [new ValidationError(key, value, 'string expected, ' + type + ' found')]; } return []; } var objectElementValidators = { promoteId: validatePromoteId }; function validateSource(options) { var value = options.value; var key = options.key; var styleSpec = options.styleSpec; var style = options.style; if (!value.type) { return [new ValidationError(key, value, '"type" is required')]; } var type = unbundle(value.type); var errors; switch (type) { case 'vector': case 'raster': case 'raster-dem': errors = validateObject({ key: key, value: value, valueSpec: styleSpec['source_' + type.replace('-', '_')], style: options.style, styleSpec: styleSpec, objectElementValidators: objectElementValidators }); return errors; case 'geojson': errors = validateObject({ key: key, value: value, valueSpec: styleSpec.source_geojson, style: style, styleSpec: styleSpec, objectElementValidators: objectElementValidators }); if (value.cluster) { for (var prop in value.clusterProperties) { var ref = value.clusterProperties[prop]; var operator = ref[0]; var mapExpr = ref[1]; var reduceExpr = typeof operator === 'string' ? [ operator, ['accumulated'], [ 'get', prop ] ] : operator; errors.push.apply(errors, validateExpression({ key: key + '.' + prop + '.map', value: mapExpr, expressionContext: 'cluster-map' })); errors.push.apply(errors, validateExpression({ key: key + '.' + prop + '.reduce', value: reduceExpr, expressionContext: 'cluster-reduce' })); } } return errors; case 'video': return validateObject({ key: key, value: value, valueSpec: styleSpec.source_video, style: style, styleSpec: styleSpec }); case 'image': return validateObject({ key: key, value: value, valueSpec: styleSpec.source_image, style: style, styleSpec: styleSpec }); case 'canvas': return [new ValidationError(key, null, 'Please use runtime APIs to add canvas sources, rather than including them in stylesheets.', 'source.canvas')]; default: return validateEnum({ key: key + '.type', value: value.type, valueSpec: { values: [ 'vector', 'raster', 'raster-dem', 'geojson', 'video', 'image' ] }, style: style, styleSpec: styleSpec }); } } function validatePromoteId(ref) { var key = ref.key; var value = ref.value; if (getType(value) === 'string') { return validateString({ key: key, value: value }); } else { var errors = []; for (var prop in value) { errors.push.apply(errors, validateString({ key: key + '.' + prop, value: value[prop] })); } return errors; } } function validateLight(options) { var light = options.value; var styleSpec = options.styleSpec; var lightSpec = styleSpec.light; var style = options.style; var errors = []; var rootType = getType(light); if (light === undefined) { return errors; } else if (rootType !== 'object') { errors = errors.concat([new ValidationError('light', light, 'object expected, ' + rootType + ' found')]); return errors; } for (var key in light) { var transitionMatch = key.match(/^(.*)-transition$/); if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) { errors = errors.concat(validate({ key: key, value: light[key], valueSpec: styleSpec.transition, style: style, styleSpec: styleSpec })); } else if (lightSpec[key]) { errors = errors.concat(validate({ key: key, value: light[key], valueSpec: lightSpec[key], style: style, styleSpec: styleSpec })); } else { errors = errors.concat([new ValidationError(key, light[key], 'unknown property "' + key + '"')]); } } return errors; } function validateFormatted(options) { if (validateString(options).length === 0) { return []; } return validateExpression(options); } function validateImage(options) { if (validateString(options).length === 0) { return []; } return validateExpression(options); } var VALIDATORS = { '*': function _() { return []; }, 'array': validateArray, 'boolean': validateBoolean, 'number': validateNumber, 'color': validateColor, 'constants': validateConstants, 'enum': validateEnum, 'filter': validateFilter, 'function': validateFunction, 'layer': validateLayer, 'object': validateObject, 'source': validateSource, 'light': validateLight, 'string': validateString, 'formatted': validateFormatted, 'resolvedImage': validateImage }; function validate(options) { var value = options.value; var valueSpec = options.valueSpec; var styleSpec = options.styleSpec; if (valueSpec.expression && isFunction(unbundle(value))) { return validateFunction(options); } else if (valueSpec.expression && isExpression(deepUnbundle(value))) { return validateExpression(options); } else if (valueSpec.type && VALIDATORS[valueSpec.type]) { return VALIDATORS[valueSpec.type](options); } else { var valid = validateObject(extend$1({}, options, { valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec })); return valid; } } function validateGlyphsURL (options) { var value = options.value; var key = options.key; var errors = validateString(options); if (errors.length) { return errors; } if (value.indexOf('{fontstack}') === -1) { errors.push(new ValidationError(key, value, '"glyphs" url must include a "{fontstack}" token')); } if (value.indexOf('{range}') === -1) { errors.push(new ValidationError(key, value, '"glyphs" url must include a "{range}" token')); } return errors; } function validateStyleMin(style, styleSpec) { if (styleSpec === void 0) styleSpec = spec; var errors = []; errors = errors.concat(validate({ key: '', value: style, valueSpec: styleSpec.$root, styleSpec: styleSpec, style: style, objectElementValidators: { glyphs: validateGlyphsURL, '*': function _() { return []; } } })); if (style.constants) { errors = errors.concat(validateConstants({ key: 'constants', value: style.constants, style: style, styleSpec: styleSpec })); } return sortErrors(errors); } validateStyleMin.source = wrapCleanErrors(validateSource); validateStyleMin.light = wrapCleanErrors(validateLight); validateStyleMin.layer = wrapCleanErrors(validateLayer); validateStyleMin.filter = wrapCleanErrors(validateFilter); validateStyleMin.paintProperty = wrapCleanErrors(validatePaintProperty); validateStyleMin.layoutProperty = wrapCleanErrors(validateLayoutProperty); function sortErrors(errors) { return [].concat(errors).sort(function (a, b) { return a.line - b.line; }); } function wrapCleanErrors(inner) { return function () { var args = [], len = arguments.length; while (len--) args[len] = arguments[len]; return sortErrors(inner.apply(this, args)); }; } var validateStyle = validateStyleMin; var validateLight$1 = validateStyle.light; var validatePaintProperty$1 = validateStyle.paintProperty; var validateLayoutProperty$1 = validateStyle.layoutProperty; function emitValidationErrors(emitter, errors) { var hasErrors = false; if (errors && errors.length) { for (var i = 0, list = errors; i < list.length; i += 1) { var error = list[i]; emitter.fire(new ErrorEvent(new Error(error.message))); hasErrors = true; } } return hasErrors; } var gridIndex = GridIndex; var NUM_PARAMS = 3; function GridIndex(extent, n, padding) { var cells = this.cells = []; if (extent instanceof ArrayBuffer) { this.arrayBuffer = extent; var array = new Int32Array(this.arrayBuffer); extent = array[0]; n = array[1]; padding = array[2]; this.d = n + 2 * padding; for (var k = 0; k < this.d * this.d; k++) { var start = array[NUM_PARAMS + k]; var end = array[NUM_PARAMS + k + 1]; cells.push(start === end ? null : array.subarray(start, end)); } var keysOffset = array[NUM_PARAMS + cells.length]; var bboxesOffset = array[NUM_PARAMS + cells.length + 1]; this.keys = array.subarray(keysOffset, bboxesOffset); this.bboxes = array.subarray(bboxesOffset); this.insert = this._insertReadonly; } else { this.d = n + 2 * padding; for (var i = 0; i < this.d * this.d; i++) { cells.push([]); } this.keys = []; this.bboxes = []; } this.n = n; this.extent = extent; this.padding = padding; this.scale = n / extent; this.uid = 0; var p = padding / n * extent; this.min = -p; this.max = extent + p; } GridIndex.prototype.insert = function (key, x1, y1, x2, y2) { this._forEachCell(x1, y1, x2, y2, this._insertCell, this.uid++); this.keys.push(key); this.bboxes.push(x1); this.bboxes.push(y1); this.bboxes.push(x2); this.bboxes.push(y2); }; GridIndex.prototype._insertReadonly = function () { throw 'Cannot insert into a GridIndex created from an ArrayBuffer.'; }; GridIndex.prototype._insertCell = function (x1, y1, x2, y2, cellIndex, uid) { this.cells[cellIndex].push(uid); }; GridIndex.prototype.query = function (x1, y1, x2, y2, intersectionTest) { var min = this.min; var max = this.max; if (x1 <= min && y1 <= min && max <= x2 && max <= y2 && !intersectionTest) { return Array.prototype.slice.call(this.keys); } else { var result = []; var seenUids = {}; this._forEachCell(x1, y1, x2, y2, this._queryCell, result, seenUids, intersectionTest); return result; } }; GridIndex.prototype._queryCell = function (x1, y1, x2, y2, cellIndex, result, seenUids, intersectionTest) { var cell = this.cells[cellIndex]; if (cell !== null) { var keys = this.keys; var bboxes = this.bboxes; for (var u = 0; u < cell.length; u++) { var uid = cell[u]; if (seenUids[uid] === undefined) { var offset = uid * 4; if (intersectionTest ? intersectionTest(bboxes[offset + 0], bboxes[offset + 1], bboxes[offset + 2], bboxes[offset + 3]) : x1 <= bboxes[offset + 2] && y1 <= bboxes[offset + 3] && x2 >= bboxes[offset + 0] && y2 >= bboxes[offset + 1]) { seenUids[uid] = true; result.push(keys[uid]); } else { seenUids[uid] = false; } } } } }; GridIndex.prototype._forEachCell = function (x1, y1, x2, y2, fn, arg1, arg2, intersectionTest) { var cx1 = this._convertToCellCoord(x1); var cy1 = this._convertToCellCoord(y1); var cx2 = this._convertToCellCoord(x2); var cy2 = this._convertToCellCoord(y2); for (var x = cx1; x <= cx2; x++) { for (var y = cy1; y <= cy2; y++) { var cellIndex = this.d * y + x; if (intersectionTest && !intersectionTest(this._convertFromCellCoord(x), this._convertFromCellCoord(y), this._convertFromCellCoord(x + 1), this._convertFromCellCoord(y + 1))) { continue; } if (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2, intersectionTest)) { return; } } } }; GridIndex.prototype._convertFromCellCoord = function (x) { return (x - this.padding) / this.scale; }; GridIndex.prototype._convertToCellCoord = function (x) { return Math.max(0, Math.min(this.d - 1, Math.floor(x * this.scale) + this.padding)); }; GridIndex.prototype.toArrayBuffer = function () { if (this.arrayBuffer) { return this.arrayBuffer; } var cells = this.cells; var metadataLength = NUM_PARAMS + this.cells.length + 1 + 1; var totalCellLength = 0; for (var i = 0; i < this.cells.length; i++) { totalCellLength += this.cells[i].length; } var array = new Int32Array(metadataLength + totalCellLength + this.keys.length + this.bboxes.length); array[0] = this.extent; array[1] = this.n; array[2] = this.padding; var offset = metadataLength; for (var k = 0; k < cells.length; k++) { var cell = cells[k]; array[NUM_PARAMS + k] = offset; array.set(cell, offset); offset += cell.length; } array[NUM_PARAMS + cells.length] = offset; array.set(this.keys, offset); offset += this.keys.length; array[NUM_PARAMS + cells.length + 1] = offset; array.set(this.bboxes, offset); offset += this.bboxes.length; return array.buffer; }; var ImageData = window$1.ImageData; var ImageBitmap = window$1.ImageBitmap; var registry = {}; function register(name, klass, options) { if (options === void 0) options = {}; Object.defineProperty(klass, '_classRegistryKey', { value: name, writeable: false }); registry[name] = { klass: klass, omit: options.omit || [], shallow: options.shallow || [] }; } register('Object', Object); gridIndex.serialize = function serialize(grid, transferables) { var buffer = grid.toArrayBuffer(); if (transferables) { transferables.push(buffer); } return { buffer: buffer }; }; gridIndex.deserialize = function deserialize(serialized) { return new gridIndex(serialized.buffer); }; register('Grid', gridIndex); register('Color', Color); register('Error', Error); register('ResolvedImage', ResolvedImage); register('StylePropertyFunction', StylePropertyFunction); register('StyleExpression', StyleExpression, { omit: ['_evaluator'] }); register('ZoomDependentExpression', ZoomDependentExpression); register('ZoomConstantExpression', ZoomConstantExpression); register('CompoundExpression', CompoundExpression, { omit: ['_evaluate'] }); for (var name in expressions) { if (expressions[name]._classRegistryKey) { continue; } register('Expression_' + name, expressions[name]); } function isArrayBuffer(val) { return val && typeof ArrayBuffer !== 'undefined' && (val instanceof ArrayBuffer || val.constructor && val.constructor.name === 'ArrayBuffer'); } function isImageBitmap(val) { return ImageBitmap && val instanceof ImageBitmap; } function serialize(input, transferables) { if (input === null || input === undefined || typeof input === 'boolean' || typeof input === 'number' || typeof input === 'string' || input instanceof Boolean || input instanceof Number || input instanceof String || input instanceof Date || input instanceof RegExp) { return input; } if (isArrayBuffer(input) || isImageBitmap(input)) { if (transferables) { transferables.push(input); } return input; } if (ArrayBuffer.isView(input)) { var view = input; if (transferables) { transferables.push(view.buffer); } return view; } if (input instanceof ImageData) { if (transferables) { transferables.push(input.data.buffer); } return input; } if (Array.isArray(input)) { var serialized = []; for (var i = 0, list = input; i < list.length; i += 1) { var item = list[i]; serialized.push(serialize(item, transferables)); } return serialized; } if (typeof input === 'object') { var klass = input.constructor; var name = klass._classRegistryKey; if (!name) { throw new Error('can\'t serialize object of unregistered class'); } var properties = klass.serialize ? klass.serialize(input, transferables) : {}; if (!klass.serialize) { for (var key in input) { if (!input.hasOwnProperty(key)) { continue; } if (registry[name].omit.indexOf(key) >= 0) { continue; } var property = input[key]; properties[key] = registry[name].shallow.indexOf(key) >= 0 ? property : serialize(property, transferables); } if (input instanceof Error) { properties.message = input.message; } } if (properties.$name) { throw new Error('$name property is reserved for worker serialization logic.'); } if (name !== 'Object') { properties.$name = name; } return properties; } throw new Error('can\'t serialize object of type ' + typeof input); } function deserialize(input) { if (input === null || input === undefined || typeof input === 'boolean' || typeof input === 'number' || typeof input === 'string' || input instanceof Boolean || input instanceof Number || input instanceof String || input instanceof Date || input instanceof RegExp || isArrayBuffer(input) || isImageBitmap(input) || ArrayBuffer.isView(input) || input instanceof ImageData) { return input; } if (Array.isArray(input)) { return input.map(deserialize); } if (typeof input === 'object') { var name = input.$name || 'Object'; var ref = registry[name]; var klass = ref.klass; if (!klass) { throw new Error('can\'t deserialize unregistered class ' + name); } if (klass.deserialize) { return klass.deserialize(input); } var result = Object.create(klass.prototype); for (var i = 0, list = Object.keys(input); i < list.length; i += 1) { var key = list[i]; if (key === '$name') { continue; } var value = input[key]; result[key] = registry[name].shallow.indexOf(key) >= 0 ? value : deserialize(value); } return result; } throw new Error('can\'t deserialize object of type ' + typeof input); } var ZoomHistory = function ZoomHistory() { this.first = true; }; ZoomHistory.prototype.update = function update(z, now) { var floorZ = Math.floor(z); if (this.first) { this.first = false; this.lastIntegerZoom = floorZ; this.lastIntegerZoomTime = 0; this.lastZoom = z; this.lastFloorZoom = floorZ; return true; } if (this.lastFloorZoom > floorZ) { this.lastIntegerZoom = floorZ + 1; this.lastIntegerZoomTime = now; } else if (this.lastFloorZoom < floorZ) { this.lastIntegerZoom = floorZ; this.lastIntegerZoomTime = now; } if (z !== this.lastZoom) { this.lastZoom = z; this.lastFloorZoom = floorZ; return true; } return false; }; var unicodeBlockLookup = { 'Latin-1 Supplement': function (char) { return char >= 128 && char <= 255; }, 'Arabic': function (char) { return char >= 1536 && char <= 1791; }, 'Arabic Supplement': function (char) { return char >= 1872 && char <= 1919; }, 'Arabic Extended-A': function (char) { return char >= 2208 && char <= 2303; }, 'Hangul Jamo': function (char) { return char >= 4352 && char <= 4607; }, 'Unified Canadian Aboriginal Syllabics': function (char) { return char >= 5120 && char <= 5759; }, 'Khmer': function (char) { return char >= 6016 && char <= 6143; }, 'Unified Canadian Aboriginal Syllabics Extended': function (char) { return char >= 6320 && char <= 6399; }, 'General Punctuation': function (char) { return char >= 8192 && char <= 8303; }, 'Letterlike Symbols': function (char) { return char >= 8448 && char <= 8527; }, 'Number Forms': function (char) { return char >= 8528 && char <= 8591; }, 'Miscellaneous Technical': function (char) { return char >= 8960 && char <= 9215; }, 'Control Pictures': function (char) { return char >= 9216 && char <= 9279; }, 'Optical Character Recognition': function (char) { return char >= 9280 && char <= 9311; }, 'Enclosed Alphanumerics': function (char) { return char >= 9312 && char <= 9471; }, 'Geometric Shapes': function (char) { return char >= 9632 && char <= 9727; }, 'Miscellaneous Symbols': function (char) { return char >= 9728 && char <= 9983; }, 'Miscellaneous Symbols and Arrows': function (char) { return char >= 11008 && char <= 11263; }, 'CJK Radicals Supplement': function (char) { return char >= 11904 && char <= 12031; }, 'Kangxi Radicals': function (char) { return char >= 12032 && char <= 12255; }, 'Ideographic Description Characters': function (char) { return char >= 12272 && char <= 12287; }, 'CJK Symbols and Punctuation': function (char) { return char >= 12288 && char <= 12351; }, 'Hiragana': function (char) { return char >= 12352 && char <= 12447; }, 'Katakana': function (char) { return char >= 12448 && char <= 12543; }, 'Bopomofo': function (char) { return char >= 12544 && char <= 12591; }, 'Hangul Compatibility Jamo': function (char) { return char >= 12592 && char <= 12687; }, 'Kanbun': function (char) { return char >= 12688 && char <= 12703; }, 'Bopomofo Extended': function (char) { return char >= 12704 && char <= 12735; }, 'CJK Strokes': function (char) { return char >= 12736 && char <= 12783; }, 'Katakana Phonetic Extensions': function (char) { return char >= 12784 && char <= 12799; }, 'Enclosed CJK Letters and Months': function (char) { return char >= 12800 && char <= 13055; }, 'CJK Compatibility': function (char) { return char >= 13056 && char <= 13311; }, 'CJK Unified Ideographs Extension A': function (char) { return char >= 13312 && char <= 19903; }, 'Yijing Hexagram Symbols': function (char) { return char >= 19904 && char <= 19967; }, 'CJK Unified Ideographs': function (char) { return char >= 19968 && char <= 40959; }, 'Yi Syllables': function (char) { return char >= 40960 && char <= 42127; }, 'Yi Radicals': function (char) { return char >= 42128 && char <= 42191; }, 'Hangul Jamo Extended-A': function (char) { return char >= 43360 && char <= 43391; }, 'Hangul Syllables': function (char) { return char >= 44032 && char <= 55215; }, 'Hangul Jamo Extended-B': function (char) { return char >= 55216 && char <= 55295; }, 'Private Use Area': function (char) { return char >= 57344 && char <= 63743; }, 'CJK Compatibility Ideographs': function (char) { return char >= 63744 && char <= 64255; }, 'Arabic Presentation Forms-A': function (char) { return char >= 64336 && char <= 65023; }, 'Vertical Forms': function (char) { return char >= 65040 && char <= 65055; }, 'CJK Compatibility Forms': function (char) { return char >= 65072 && char <= 65103; }, 'Small Form Variants': function (char) { return char >= 65104 && char <= 65135; }, 'Arabic Presentation Forms-B': function (char) { return char >= 65136 && char <= 65279; }, 'Halfwidth and Fullwidth Forms': function (char) { return char >= 65280 && char <= 65519; } }; function allowsVerticalWritingMode(chars) { for (var i = 0, list = chars; i < list.length; i += 1) { var char = list[i]; if (charHasUprightVerticalOrientation(char.charCodeAt(0))) { return true; } } return false; } function allowsLetterSpacing(chars) { for (var i = 0, list = chars; i < list.length; i += 1) { var char = list[i]; if (!charAllowsLetterSpacing(char.charCodeAt(0))) { return false; } } return true; } function charAllowsLetterSpacing(char) { if (unicodeBlockLookup['Arabic'](char)) { return false; } if (unicodeBlockLookup['Arabic Supplement'](char)) { return false; } if (unicodeBlockLookup['Arabic Extended-A'](char)) { return false; } if (unicodeBlockLookup['Arabic Presentation Forms-A'](char)) { return false; } if (unicodeBlockLookup['Arabic Presentation Forms-B'](char)) { return false; } return true; } function charAllowsIdeographicBreaking(char) { if (char < 11904) { return false; } if (unicodeBlockLookup['Bopomofo Extended'](char)) { return true; } if (unicodeBlockLookup['Bopomofo'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility Forms'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility Ideographs'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility'](char)) { return true; } if (unicodeBlockLookup['CJK Radicals Supplement'](char)) { return true; } if (unicodeBlockLookup['CJK Strokes'](char)) { return true; } if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) { return true; } if (unicodeBlockLookup['CJK Unified Ideographs Extension A'](char)) { return true; } if (unicodeBlockLookup['CJK Unified Ideographs'](char)) { return true; } if (unicodeBlockLookup['Enclosed CJK Letters and Months'](char)) { return true; } if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) { return true; } if (unicodeBlockLookup['Hiragana'](char)) { return true; } if (unicodeBlockLookup['Ideographic Description Characters'](char)) { return true; } if (unicodeBlockLookup['Kangxi Radicals'](char)) { return true; } if (unicodeBlockLookup['Katakana Phonetic Extensions'](char)) { return true; } if (unicodeBlockLookup['Katakana'](char)) { return true; } if (unicodeBlockLookup['Vertical Forms'](char)) { return true; } if (unicodeBlockLookup['Yi Radicals'](char)) { return true; } if (unicodeBlockLookup['Yi Syllables'](char)) { return true; } return false; } function charHasUprightVerticalOrientation(char) { if (char === 746 || char === 747) { return true; } if (char < 4352) { return false; } if (unicodeBlockLookup['Bopomofo Extended'](char)) { return true; } if (unicodeBlockLookup['Bopomofo'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility Forms'](char)) { if (!(char >= 65097 && char <= 65103)) { return true; } } if (unicodeBlockLookup['CJK Compatibility Ideographs'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility'](char)) { return true; } if (unicodeBlockLookup['CJK Radicals Supplement'](char)) { return true; } if (unicodeBlockLookup['CJK Strokes'](char)) { return true; } if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) { if (!(char >= 12296 && char <= 12305) && !(char >= 12308 && char <= 12319) && char !== 12336) { return true; } } if (unicodeBlockLookup['CJK Unified Ideographs Extension A'](char)) { return true; } if (unicodeBlockLookup['CJK Unified Ideographs'](char)) { return true; } if (unicodeBlockLookup['Enclosed CJK Letters and Months'](char)) { return true; } if (unicodeBlockLookup['Hangul Compatibility Jamo'](char)) { return true; } if (unicodeBlockLookup['Hangul Jamo Extended-A'](char)) { return true; } if (unicodeBlockLookup['Hangul Jamo Extended-B'](char)) { return true; } if (unicodeBlockLookup['Hangul Jamo'](char)) { return true; } if (unicodeBlockLookup['Hangul Syllables'](char)) { return true; } if (unicodeBlockLookup['Hiragana'](char)) { return true; } if (unicodeBlockLookup['Ideographic Description Characters'](char)) { return true; } if (unicodeBlockLookup['Kanbun'](char)) { return true; } if (unicodeBlockLookup['Kangxi Radicals'](char)) { return true; } if (unicodeBlockLookup['Katakana Phonetic Extensions'](char)) { return true; } if (unicodeBlockLookup['Katakana'](char)) { if (char !== 12540) { return true; } } if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) { if (char !== 65288 && char !== 65289 && char !== 65293 && !(char >= 65306 && char <= 65310) && char !== 65339 && char !== 65341 && char !== 65343 && !(char >= 65371 && char <= 65503) && char !== 65507 && !(char >= 65512 && char <= 65519)) { return true; } } if (unicodeBlockLookup['Small Form Variants'](char)) { if (!(char >= 65112 && char <= 65118) && !(char >= 65123 && char <= 65126)) { return true; } } if (unicodeBlockLookup['Unified Canadian Aboriginal Syllabics'](char)) { return true; } if (unicodeBlockLookup['Unified Canadian Aboriginal Syllabics Extended'](char)) { return true; } if (unicodeBlockLookup['Vertical Forms'](char)) { return true; } if (unicodeBlockLookup['Yijing Hexagram Symbols'](char)) { return true; } if (unicodeBlockLookup['Yi Syllables'](char)) { return true; } if (unicodeBlockLookup['Yi Radicals'](char)) { return true; } return false; } function charHasNeutralVerticalOrientation(char) { if (unicodeBlockLookup['Latin-1 Supplement'](char)) { if (char === 167 || char === 169 || char === 174 || char === 177 || char === 188 || char === 189 || char === 190 || char === 215 || char === 247) { return true; } } if (unicodeBlockLookup['General Punctuation'](char)) { if (char === 8214 || char === 8224 || char === 8225 || char === 8240 || char === 8241 || char === 8251 || char === 8252 || char === 8258 || char === 8263 || char === 8264 || char === 8265 || char === 8273) { return true; } } if (unicodeBlockLookup['Letterlike Symbols'](char)) { return true; } if (unicodeBlockLookup['Number Forms'](char)) { return true; } if (unicodeBlockLookup['Miscellaneous Technical'](char)) { if (char >= 8960 && char <= 8967 || char >= 8972 && char <= 8991 || char >= 8996 && char <= 9000 || char === 9003 || char >= 9085 && char <= 9114 || char >= 9150 && char <= 9165 || char === 9167 || char >= 9169 && char <= 9179 || char >= 9186 && char <= 9215) { return true; } } if (unicodeBlockLookup['Control Pictures'](char) && char !== 9251) { return true; } if (unicodeBlockLookup['Optical Character Recognition'](char)) { return true; } if (unicodeBlockLookup['Enclosed Alphanumerics'](char)) { return true; } if (unicodeBlockLookup['Geometric Shapes'](char)) { return true; } if (unicodeBlockLookup['Miscellaneous Symbols'](char)) { if (!(char >= 9754 && char <= 9759)) { return true; } } if (unicodeBlockLookup['Miscellaneous Symbols and Arrows'](char)) { if (char >= 11026 && char <= 11055 || char >= 11088 && char <= 11097 || char >= 11192 && char <= 11243) { return true; } } if (unicodeBlockLookup['CJK Symbols and Punctuation'](char)) { return true; } if (unicodeBlockLookup['Katakana'](char)) { return true; } if (unicodeBlockLookup['Private Use Area'](char)) { return true; } if (unicodeBlockLookup['CJK Compatibility Forms'](char)) { return true; } if (unicodeBlockLookup['Small Form Variants'](char)) { return true; } if (unicodeBlockLookup['Halfwidth and Fullwidth Forms'](char)) { return true; } if (char === 8734 || char === 8756 || char === 8757 || char >= 9984 && char <= 10087 || char >= 10102 && char <= 10131 || char === 65532 || char === 65533) { return true; } return false; } function charHasRotatedVerticalOrientation(char) { return !(charHasUprightVerticalOrientation(char) || charHasNeutralVerticalOrientation(char)); } function charInComplexShapingScript(char) { return unicodeBlockLookup['Arabic'](char) || unicodeBlockLookup['Arabic Supplement'](char) || unicodeBlockLookup['Arabic Extended-A'](char) || unicodeBlockLookup['Arabic Presentation Forms-A'](char) || unicodeBlockLookup['Arabic Presentation Forms-B'](char); } function charInRTLScript(char) { return char >= 1424 && char <= 2303 || unicodeBlockLookup['Arabic Presentation Forms-A'](char) || unicodeBlockLookup['Arabic Presentation Forms-B'](char); } function charInSupportedScript(char, canRenderRTL) { if (!canRenderRTL && charInRTLScript(char)) { return false; } if (char >= 2304 && char <= 3583 || char >= 3840 && char <= 4255 || unicodeBlockLookup['Khmer'](char)) { return false; } return true; } function stringContainsRTLText(chars) { for (var i = 0, list = chars; i < list.length; i += 1) { var char = list[i]; if (charInRTLScript(char.charCodeAt(0))) { return true; } } return false; } function isStringInSupportedScript(chars, canRenderRTL) { for (var i = 0, list = chars; i < list.length; i += 1) { var char = list[i]; if (!charInSupportedScript(char.charCodeAt(0), canRenderRTL)) { return false; } } return true; } var status = { unavailable: 'unavailable', deferred: 'deferred', loading: 'loading', loaded: 'loaded', error: 'error' }; var _completionCallback = null; var pluginStatus = status.unavailable; var pluginURL = null; var triggerPluginCompletionEvent = function (error) { if (error && typeof error === 'string' && error.indexOf('NetworkError') > -1) { pluginStatus = status.error; } if (_completionCallback) { _completionCallback(error); } }; function sendPluginStateToWorker() { evented.fire(new Event('pluginStateChange', { pluginStatus: pluginStatus, pluginURL: pluginURL })); } var evented = new Evented(); var getRTLTextPluginStatus = function () { return pluginStatus; }; var registerForPluginStateChange = function (callback) { callback({ pluginStatus: pluginStatus, pluginURL: pluginURL }); evented.on('pluginStateChange', callback); return callback; }; var setRTLTextPlugin = function (url, callback, deferred) { if (deferred === void 0) deferred = false; if (pluginStatus === status.deferred || pluginStatus === status.loading || pluginStatus === status.loaded) { throw new Error('setRTLTextPlugin cannot be called multiple times.'); } pluginURL = exported.resolveURL(url); pluginStatus = status.deferred; _completionCallback = callback; sendPluginStateToWorker(); if (!deferred) { downloadRTLTextPlugin(); } }; var downloadRTLTextPlugin = function () { if (pluginStatus !== status.deferred || !pluginURL) { throw new Error('rtl-text-plugin cannot be downloaded unless a pluginURL is specified'); } pluginStatus = status.loading; sendPluginStateToWorker(); if (pluginURL) { getArrayBuffer({ url: pluginURL }, function (error) { if (error) { triggerPluginCompletionEvent(error); } else { pluginStatus = status.loaded; sendPluginStateToWorker(); } }); } }; var plugin = { applyArabicShaping: null, processBidirectionalText: null, processStyledBidirectionalText: null, isLoaded: function isLoaded() { return pluginStatus === status.loaded || plugin.applyArabicShaping != null; }, isLoading: function isLoading() { return pluginStatus === status.loading; }, setState: function setState(state) { pluginStatus = state.pluginStatus; pluginURL = state.pluginURL; }, isParsed: function isParsed() { return plugin.applyArabicShaping != null && plugin.processBidirectionalText != null && plugin.processStyledBidirectionalText != null; }, getPluginURL: function getPluginURL() { return pluginURL; } }; var lazyLoadRTLTextPlugin = function () { if (!plugin.isLoading() && !plugin.isLoaded() && getRTLTextPluginStatus() === 'deferred') { downloadRTLTextPlugin(); } }; var EvaluationParameters = function EvaluationParameters(zoom, options) { this.zoom = zoom; if (options) { this.now = options.now; this.fadeDuration = options.fadeDuration; this.zoomHistory = options.zoomHistory; this.transition = options.transition; } else { this.now = 0; this.fadeDuration = 0; this.zoomHistory = new ZoomHistory(); this.transition = {}; } }; EvaluationParameters.prototype.isSupportedScript = function isSupportedScript(str) { return isStringInSupportedScript(str, plugin.isLoaded()); }; EvaluationParameters.prototype.crossFadingFactor = function crossFadingFactor() { if (this.fadeDuration === 0) { return 1; } else { return Math.min((this.now - this.zoomHistory.lastIntegerZoomTime) / this.fadeDuration, 1); } }; EvaluationParameters.prototype.getCrossfadeParameters = function getCrossfadeParameters() { var z = this.zoom; var fraction = z - Math.floor(z); var t = this.crossFadingFactor(); return z > this.zoomHistory.lastIntegerZoom ? { fromScale: 2, toScale: 1, t: fraction + (1 - fraction) * t } : { fromScale: 0.5, toScale: 1, t: 1 - (1 - t) * fraction }; }; var PropertyValue = function PropertyValue(property, value) { this.property = property; this.value = value; this.expression = normalizePropertyExpression(value === undefined ? property.specification.default : value, property.specification); }; PropertyValue.prototype.isDataDriven = function isDataDriven() { return this.expression.kind === 'source' || this.expression.kind === 'composite'; }; PropertyValue.prototype.possiblyEvaluate = function possiblyEvaluate(parameters, canonical, availableImages) { return this.property.possiblyEvaluate(this, parameters, canonical, availableImages); }; var TransitionablePropertyValue = function TransitionablePropertyValue(property) { this.property = property; this.value = new PropertyValue(property, undefined); }; TransitionablePropertyValue.prototype.transitioned = function transitioned(parameters, prior) { return new TransitioningPropertyValue(this.property, this.value, prior, extend({}, parameters.transition, this.transition), parameters.now); }; TransitionablePropertyValue.prototype.untransitioned = function untransitioned() { return new TransitioningPropertyValue(this.property, this.value, null, {}, 0); }; var Transitionable = function Transitionable(properties) { this._properties = properties; this._values = Object.create(properties.defaultTransitionablePropertyValues); }; Transitionable.prototype.getValue = function getValue(name) { return clone(this._values[name].value.value); }; Transitionable.prototype.setValue = function setValue(name, value) { if (!this._values.hasOwnProperty(name)) { this._values[name] = new TransitionablePropertyValue(this._values[name].property); } this._values[name].value = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value)); }; Transitionable.prototype.getTransition = function getTransition(name) { return clone(this._values[name].transition); }; Transitionable.prototype.setTransition = function setTransition(name, value) { if (!this._values.hasOwnProperty(name)) { this._values[name] = new TransitionablePropertyValue(this._values[name].property); } this._values[name].transition = clone(value) || undefined; }; Transitionable.prototype.serialize = function serialize() { var result = {}; for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; var value = this.getValue(property); if (value !== undefined) { result[property] = value; } var transition = this.getTransition(property); if (transition !== undefined) { result[property + '-transition'] = transition; } } return result; }; Transitionable.prototype.transitioned = function transitioned(parameters, prior) { var result = new Transitioning(this._properties); for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; result._values[property] = this._values[property].transitioned(parameters, prior._values[property]); } return result; }; Transitionable.prototype.untransitioned = function untransitioned() { var result = new Transitioning(this._properties); for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; result._values[property] = this._values[property].untransitioned(); } return result; }; var TransitioningPropertyValue = function TransitioningPropertyValue(property, value, prior, transition, now) { this.property = property; this.value = value; this.begin = now + transition.delay || 0; this.end = this.begin + transition.duration || 0; if (property.specification.transition && (transition.delay || transition.duration)) { this.prior = prior; } }; TransitioningPropertyValue.prototype.possiblyEvaluate = function possiblyEvaluate(parameters, canonical, availableImages) { var now = parameters.now || 0; var finalValue = this.value.possiblyEvaluate(parameters, canonical, availableImages); var prior = this.prior; if (!prior) { return finalValue; } else if (now > this.end) { this.prior = null; return finalValue; } else if (this.value.isDataDriven()) { this.prior = null; return finalValue; } else if (now < this.begin) { return prior.possiblyEvaluate(parameters, canonical, availableImages); } else { var t = (now - this.begin) / (this.end - this.begin); return this.property.interpolate(prior.possiblyEvaluate(parameters, canonical, availableImages), finalValue, easeCubicInOut(t)); } }; var Transitioning = function Transitioning(properties) { this._properties = properties; this._values = Object.create(properties.defaultTransitioningPropertyValues); }; Transitioning.prototype.possiblyEvaluate = function possiblyEvaluate(parameters, canonical, availableImages) { var result = new PossiblyEvaluated(this._properties); for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages); } return result; }; Transitioning.prototype.hasTransition = function hasTransition() { for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; if (this._values[property].prior) { return true; } } return false; }; var Layout = function Layout(properties) { this._properties = properties; this._values = Object.create(properties.defaultPropertyValues); }; Layout.prototype.getValue = function getValue(name) { return clone(this._values[name].value); }; Layout.prototype.setValue = function setValue(name, value) { this._values[name] = new PropertyValue(this._values[name].property, value === null ? undefined : clone(value)); }; Layout.prototype.serialize = function serialize() { var result = {}; for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; var value = this.getValue(property); if (value !== undefined) { result[property] = value; } } return result; }; Layout.prototype.possiblyEvaluate = function possiblyEvaluate(parameters, canonical, availableImages) { var result = new PossiblyEvaluated(this._properties); for (var i = 0, list = Object.keys(this._values); i < list.length; i += 1) { var property = list[i]; result._values[property] = this._values[property].possiblyEvaluate(parameters, canonical, availableImages); } return result; }; var PossiblyEvaluatedPropertyValue = function PossiblyEvaluatedPropertyValue(property, value, parameters) { this.property = property; this.value = value; this.parameters = parameters; }; PossiblyEvaluatedPropertyValue.prototype.isConstant = function isConstant() { return this.value.kind === 'constant'; }; PossiblyEvaluatedPropertyValue.prototype.constantOr = function constantOr(value) { if (this.value.kind === 'constant') { return this.value.value; } else { return value; } }; PossiblyEvaluatedPropertyValue.prototype.evaluate = function evaluate(feature, featureState, canonical, availableImages) { return this.property.evaluate(this.value, this.parameters, feature, featureState, canonical, availableImages); }; var PossiblyEvaluated = function PossiblyEvaluated(properties) { this._properties = properties; this._values = Object.create(properties.defaultPossiblyEvaluatedValues); }; PossiblyEvaluated.prototype.get = function get(name) { return this._values[name]; }; var DataConstantProperty = function DataConstantProperty(specification) { this.specification = specification; }; DataConstantProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters) { return value.expression.evaluate(parameters); }; DataConstantProperty.prototype.interpolate = function interpolate$1(a, b, t) { var interp = interpolate[this.specification.type]; if (interp) { return interp(a, b, t); } else { return a; } }; var DataDrivenProperty = function DataDrivenProperty(specification, overrides) { this.specification = specification; this.overrides = overrides; }; DataDrivenProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters, canonical, availableImages) { if (value.expression.kind === 'constant' || value.expression.kind === 'camera') { return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: value.expression.evaluate(parameters, null, {}, canonical, availableImages) }, parameters); } else { return new PossiblyEvaluatedPropertyValue(this, value.expression, parameters); } }; DataDrivenProperty.prototype.interpolate = function interpolate$2(a, b, t) { if (a.value.kind !== 'constant' || b.value.kind !== 'constant') { return a; } if (a.value.value === undefined || b.value.value === undefined) { return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: undefined }, a.parameters); } var interp = interpolate[this.specification.type]; if (interp) { return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: interp(a.value.value, b.value.value, t) }, a.parameters); } else { return a; } }; DataDrivenProperty.prototype.evaluate = function evaluate(value, parameters, feature, featureState, canonical, availableImages) { if (value.kind === 'constant') { return value.value; } else { return value.evaluate(parameters, feature, featureState, canonical, availableImages); } }; var CrossFadedDataDrivenProperty = function (DataDrivenProperty) { function CrossFadedDataDrivenProperty() { DataDrivenProperty.apply(this, arguments); } if (DataDrivenProperty) CrossFadedDataDrivenProperty.__proto__ = DataDrivenProperty; CrossFadedDataDrivenProperty.prototype = Object.create(DataDrivenProperty && DataDrivenProperty.prototype); CrossFadedDataDrivenProperty.prototype.constructor = CrossFadedDataDrivenProperty; CrossFadedDataDrivenProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters, canonical, availableImages) { if (value.value === undefined) { return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: undefined }, parameters); } else if (value.expression.kind === 'constant') { var evaluatedValue = value.expression.evaluate(parameters, null, {}, canonical, availableImages); var isImageExpression = value.property.specification.type === 'resolvedImage'; var constantValue = isImageExpression && typeof evaluatedValue !== 'string' ? evaluatedValue.name : evaluatedValue; var constant = this._calculate(constantValue, constantValue, constantValue, parameters); return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: constant }, parameters); } else if (value.expression.kind === 'camera') { var cameraVal = this._calculate(value.expression.evaluate({ zoom: parameters.zoom - 1 }), value.expression.evaluate({ zoom: parameters.zoom }), value.expression.evaluate({ zoom: parameters.zoom + 1 }), parameters); return new PossiblyEvaluatedPropertyValue(this, { kind: 'constant', value: cameraVal }, parameters); } else { return new PossiblyEvaluatedPropertyValue(this, value.expression, parameters); } }; CrossFadedDataDrivenProperty.prototype.evaluate = function evaluate(value, globals, feature, featureState, canonical, availableImages) { if (value.kind === 'source') { var constant = value.evaluate(globals, feature, featureState, canonical, availableImages); return this._calculate(constant, constant, constant, globals); } else if (value.kind === 'composite') { return this._calculate(value.evaluate({ zoom: Math.floor(globals.zoom) - 1 }, feature, featureState), value.evaluate({ zoom: Math.floor(globals.zoom) }, feature, featureState), value.evaluate({ zoom: Math.floor(globals.zoom) + 1 }, feature, featureState), globals); } else { return value.value; } }; CrossFadedDataDrivenProperty.prototype._calculate = function _calculate(min, mid, max, parameters) { var z = parameters.zoom; return z > parameters.zoomHistory.lastIntegerZoom ? { from: min, to: mid } : { from: max, to: mid }; }; CrossFadedDataDrivenProperty.prototype.interpolate = function interpolate(a) { return a; }; return CrossFadedDataDrivenProperty; }(DataDrivenProperty); var CrossFadedProperty = function CrossFadedProperty(specification) { this.specification = specification; }; CrossFadedProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters, canonical, availableImages) { if (value.value === undefined) { return undefined; } else if (value.expression.kind === 'constant') { var constant = value.expression.evaluate(parameters, null, {}, canonical, availableImages); return this._calculate(constant, constant, constant, parameters); } else { return this._calculate(value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom - 1), parameters)), value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom), parameters)), value.expression.evaluate(new EvaluationParameters(Math.floor(parameters.zoom + 1), parameters)), parameters); } }; CrossFadedProperty.prototype._calculate = function _calculate(min, mid, max, parameters) { var z = parameters.zoom; return z > parameters.zoomHistory.lastIntegerZoom ? { from: min, to: mid } : { from: max, to: mid }; }; CrossFadedProperty.prototype.interpolate = function interpolate(a) { return a; }; var ColorRampProperty = function ColorRampProperty(specification) { this.specification = specification; }; ColorRampProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters, canonical, availableImages) { return !!value.expression.evaluate(parameters, null, {}, canonical, availableImages); }; ColorRampProperty.prototype.interpolate = function interpolate() { return false; }; var Properties = function Properties(properties) { this.properties = properties; this.defaultPropertyValues = {}; this.defaultTransitionablePropertyValues = {}; this.defaultTransitioningPropertyValues = {}; this.defaultPossiblyEvaluatedValues = {}; this.overridableProperties = []; for (var property in properties) { var prop = properties[property]; if (prop.specification.overridable) { this.overridableProperties.push(property); } var defaultPropertyValue = this.defaultPropertyValues[property] = new PropertyValue(prop, undefined); var defaultTransitionablePropertyValue = this.defaultTransitionablePropertyValues[property] = new TransitionablePropertyValue(prop); this.defaultTransitioningPropertyValues[property] = defaultTransitionablePropertyValue.untransitioned(); this.defaultPossiblyEvaluatedValues[property] = defaultPropertyValue.possiblyEvaluate({}); } }; register('DataDrivenProperty', DataDrivenProperty); register('DataConstantProperty', DataConstantProperty); register('CrossFadedDataDrivenProperty', CrossFadedDataDrivenProperty); register('CrossFadedProperty', CrossFadedProperty); register('ColorRampProperty', ColorRampProperty); var TRANSITION_SUFFIX = '-transition'; var StyleLayer = function (Evented) { function StyleLayer(layer, properties) { Evented.call(this); this.id = layer.id; this.type = layer.type; this._featureFilter = { filter: function () { return true; }, needGeometry: false }; if (layer.type === 'custom') { return; } layer = layer; this.metadata = layer.metadata; this.minzoom = layer.minzoom; this.maxzoom = layer.maxzoom; if (layer.type !== 'background') { this.source = layer.source; this.sourceLayer = layer['source-layer']; this.filter = layer.filter; } if (properties.layout) { this._unevaluatedLayout = new Layout(properties.layout); } if (properties.paint) { this._transitionablePaint = new Transitionable(properties.paint); for (var property in layer.paint) { this.setPaintProperty(property, layer.paint[property], { validate: false }); } for (var property$1 in layer.layout) { this.setLayoutProperty(property$1, layer.layout[property$1], { validate: false }); } this._transitioningPaint = this._transitionablePaint.untransitioned(); this.paint = new PossiblyEvaluated(properties.paint); } } if (Evented) StyleLayer.__proto__ = Evented; StyleLayer.prototype = Object.create(Evented && Evented.prototype); StyleLayer.prototype.constructor = StyleLayer; StyleLayer.prototype.getCrossfadeParameters = function getCrossfadeParameters() { return this._crossfadeParameters; }; StyleLayer.prototype.getLayoutProperty = function getLayoutProperty(name) { if (name === 'visibility') { return this.visibility; } return this._unevaluatedLayout.getValue(name); }; StyleLayer.prototype.setLayoutProperty = function setLayoutProperty(name, value, options) { if (options === void 0) options = {}; if (value !== null && value !== undefined) { var key = 'layers.' + this.id + '.layout.' + name; if (this._validate(validateLayoutProperty$1, key, name, value, options)) { return; } } if (name === 'visibility') { this.visibility = value; return; } this._unevaluatedLayout.setValue(name, value); }; StyleLayer.prototype.getPaintProperty = function getPaintProperty(name) { if (endsWith(name, TRANSITION_SUFFIX)) { return this._transitionablePaint.getTransition(name.slice(0, -TRANSITION_SUFFIX.length)); } else { return this._transitionablePaint.getValue(name); } }; StyleLayer.prototype.setPaintProperty = function setPaintProperty(name, value, options) { if (options === void 0) options = {}; if (value !== null && value !== undefined) { var key = 'layers.' + this.id + '.paint.' + name; if (this._validate(validatePaintProperty$1, key, name, value, options)) { return false; } } if (endsWith(name, TRANSITION_SUFFIX)) { this._transitionablePaint.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), value || undefined); return false; } else { var transitionable = this._transitionablePaint._values[name]; var isCrossFadedProperty = transitionable.property.specification['property-type'] === 'cross-faded-data-driven'; var wasDataDriven = transitionable.value.isDataDriven(); var oldValue = transitionable.value; this._transitionablePaint.setValue(name, value); this._handleSpecialPaintPropertyUpdate(name); var newValue = this._transitionablePaint._values[name].value; var isDataDriven = newValue.isDataDriven(); return isDataDriven || wasDataDriven || isCrossFadedProperty || this._handleOverridablePaintPropertyUpdate(name, oldValue, newValue); } }; StyleLayer.prototype._handleSpecialPaintPropertyUpdate = function _handleSpecialPaintPropertyUpdate(_) { }; StyleLayer.prototype._handleOverridablePaintPropertyUpdate = function _handleOverridablePaintPropertyUpdate(name, oldValue, newValue) { return false; }; StyleLayer.prototype.isHidden = function isHidden(zoom) { if (this.minzoom && zoom < this.minzoom) { return true; } if (this.maxzoom && zoom >= this.maxzoom) { return true; } return this.visibility === 'none'; }; StyleLayer.prototype.updateTransitions = function updateTransitions(parameters) { this._transitioningPaint = this._transitionablePaint.transitioned(parameters, this._transitioningPaint); }; StyleLayer.prototype.hasTransition = function hasTransition() { return this._transitioningPaint.hasTransition(); }; StyleLayer.prototype.recalculate = function recalculate(parameters, availableImages) { if (parameters.getCrossfadeParameters) { this._crossfadeParameters = parameters.getCrossfadeParameters(); } if (this._unevaluatedLayout) { this.layout = this._unevaluatedLayout.possiblyEvaluate(parameters, undefined, availableImages); } this.paint = this._transitioningPaint.possiblyEvaluate(parameters, undefined, availableImages); }; StyleLayer.prototype.serialize = function serialize() { var output = { 'id': this.id, 'type': this.type, 'source': this.source, 'source-layer': this.sourceLayer, 'metadata': this.metadata, 'minzoom': this.minzoom, 'maxzoom': this.maxzoom, 'filter': this.filter, 'layout': this._unevaluatedLayout && this._unevaluatedLayout.serialize(), 'paint': this._transitionablePaint && this._transitionablePaint.serialize() }; if (this.visibility) { output.layout = output.layout || {}; output.layout.visibility = this.visibility; } return filterObject(output, function (value, key) { return value !== undefined && !(key === 'layout' && !Object.keys(value).length) && !(key === 'paint' && !Object.keys(value).length); }); }; StyleLayer.prototype._validate = function _validate(validate, key, name, value, options) { if (options === void 0) options = {}; if (options && options.validate === false) { return false; } return emitValidationErrors(this, validate.call(validateStyle, { key: key, layerType: this.type, objectKey: name, value: value, styleSpec: spec, style: { glyphs: true, sprite: true } })); }; StyleLayer.prototype.is3D = function is3D() { return false; }; StyleLayer.prototype.isTileClipped = function isTileClipped() { return false; }; StyleLayer.prototype.hasOffscreenPass = function hasOffscreenPass() { return false; }; StyleLayer.prototype.resize = function resize() { }; StyleLayer.prototype.isStateDependent = function isStateDependent() { for (var property in this.paint._values) { var value = this.paint.get(property); if (!(value instanceof PossiblyEvaluatedPropertyValue) || !supportsPropertyExpression(value.property.specification)) { continue; } if ((value.value.kind === 'source' || value.value.kind === 'composite') && value.value.isStateDependent) { return true; } } return false; }; return StyleLayer; }(Evented); var viewTypes = { 'Int8': Int8Array, 'Uint8': Uint8Array, 'Int16': Int16Array, 'Uint16': Uint16Array, 'Int32': Int32Array, 'Uint32': Uint32Array, 'Float32': Float32Array }; var Struct = function Struct(structArray, index) { this._structArray = structArray; this._pos1 = index * this.size; this._pos2 = this._pos1 / 2; this._pos4 = this._pos1 / 4; this._pos8 = this._pos1 / 8; }; var DEFAULT_CAPACITY = 128; var RESIZE_MULTIPLIER = 5; var StructArray = function StructArray() { this.isTransferred = false; this.capacity = -1; this.resize(0); }; StructArray.serialize = function serialize(array, transferables) { array._trim(); if (transferables) { array.isTransferred = true; transferables.push(array.arrayBuffer); } return { length: array.length, arrayBuffer: array.arrayBuffer }; }; StructArray.deserialize = function deserialize(input) { var structArray = Object.create(this.prototype); structArray.arrayBuffer = input.arrayBuffer; structArray.length = input.length; structArray.capacity = input.arrayBuffer.byteLength / structArray.bytesPerElement; structArray._refreshViews(); return structArray; }; StructArray.prototype._trim = function _trim() { if (this.length !== this.capacity) { this.capacity = this.length; this.arrayBuffer = this.arrayBuffer.slice(0, this.length * this.bytesPerElement); this._refreshViews(); } }; StructArray.prototype.clear = function clear() { this.length = 0; }; StructArray.prototype.resize = function resize(n) { this.reserve(n); this.length = n; }; StructArray.prototype.reserve = function reserve(n) { if (n > this.capacity) { this.capacity = Math.max(n, Math.floor(this.capacity * RESIZE_MULTIPLIER), DEFAULT_CAPACITY); this.arrayBuffer = new ArrayBuffer(this.capacity * this.bytesPerElement); var oldUint8Array = this.uint8; this._refreshViews(); if (oldUint8Array) { this.uint8.set(oldUint8Array); } } }; StructArray.prototype._refreshViews = function _refreshViews() { throw new Error('_refreshViews() must be implemented by each concrete StructArray layout'); }; function createLayout(members, alignment) { if (alignment === void 0) alignment = 1; var offset = 0; var maxSize = 0; var layoutMembers = members.map(function (member) { var typeSize = sizeOf(member.type); var memberOffset = offset = align(offset, Math.max(alignment, typeSize)); var components = member.components || 1; maxSize = Math.max(maxSize, typeSize); offset += typeSize * components; return { name: member.name, type: member.type, components: components, offset: memberOffset }; }); var size = align(offset, Math.max(maxSize, alignment)); return { members: layoutMembers, size: size, alignment: alignment }; } function sizeOf(type) { return viewTypes[type].BYTES_PER_ELEMENT; } function align(offset, size) { return Math.ceil(offset / size) * size; } var StructArrayLayout2i4 = function (StructArray) { function StructArrayLayout2i4() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2i4.__proto__ = StructArray; StructArrayLayout2i4.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2i4.prototype.constructor = StructArrayLayout2i4; StructArrayLayout2i4.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout2i4.prototype.emplaceBack = function emplaceBack(v0, v1) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1); }; StructArrayLayout2i4.prototype.emplace = function emplace(i, v0, v1) { var o2 = i * 2; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; return i; }; return StructArrayLayout2i4; }(StructArray); StructArrayLayout2i4.prototype.bytesPerElement = 4; register('StructArrayLayout2i4', StructArrayLayout2i4); var StructArrayLayout4i8 = function (StructArray) { function StructArrayLayout4i8() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout4i8.__proto__ = StructArray; StructArrayLayout4i8.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout4i8.prototype.constructor = StructArrayLayout4i8; StructArrayLayout4i8.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout4i8.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3); }; StructArrayLayout4i8.prototype.emplace = function emplace(i, v0, v1, v2, v3) { var o2 = i * 4; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; return i; }; return StructArrayLayout4i8; }(StructArray); StructArrayLayout4i8.prototype.bytesPerElement = 8; register('StructArrayLayout4i8', StructArrayLayout4i8); var StructArrayLayout2i4i12 = function (StructArray) { function StructArrayLayout2i4i12() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2i4i12.__proto__ = StructArray; StructArrayLayout2i4i12.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2i4i12.prototype.constructor = StructArrayLayout2i4i12; StructArrayLayout2i4i12.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout2i4i12.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5); }; StructArrayLayout2i4i12.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5) { var o2 = i * 6; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; this.int16[o2 + 4] = v4; this.int16[o2 + 5] = v5; return i; }; return StructArrayLayout2i4i12; }(StructArray); StructArrayLayout2i4i12.prototype.bytesPerElement = 12; register('StructArrayLayout2i4i12', StructArrayLayout2i4i12); var StructArrayLayout2i4ub8 = function (StructArray) { function StructArrayLayout2i4ub8() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2i4ub8.__proto__ = StructArray; StructArrayLayout2i4ub8.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2i4ub8.prototype.constructor = StructArrayLayout2i4ub8; StructArrayLayout2i4ub8.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout2i4ub8.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5); }; StructArrayLayout2i4ub8.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5) { var o2 = i * 4; var o1 = i * 8; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.uint8[o1 + 4] = v2; this.uint8[o1 + 5] = v3; this.uint8[o1 + 6] = v4; this.uint8[o1 + 7] = v5; return i; }; return StructArrayLayout2i4ub8; }(StructArray); StructArrayLayout2i4ub8.prototype.bytesPerElement = 8; register('StructArrayLayout2i4ub8', StructArrayLayout2i4ub8); var StructArrayLayout2f8 = function (StructArray) { function StructArrayLayout2f8() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2f8.__proto__ = StructArray; StructArrayLayout2f8.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2f8.prototype.constructor = StructArrayLayout2f8; StructArrayLayout2f8.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout2f8.prototype.emplaceBack = function emplaceBack(v0, v1) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1); }; StructArrayLayout2f8.prototype.emplace = function emplace(i, v0, v1) { var o4 = i * 2; this.float32[o4 + 0] = v0; this.float32[o4 + 1] = v1; return i; }; return StructArrayLayout2f8; }(StructArray); StructArrayLayout2f8.prototype.bytesPerElement = 8; register('StructArrayLayout2f8', StructArrayLayout2f8); var StructArrayLayout10ui20 = function (StructArray) { function StructArrayLayout10ui20() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout10ui20.__proto__ = StructArray; StructArrayLayout10ui20.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout10ui20.prototype.constructor = StructArrayLayout10ui20; StructArrayLayout10ui20.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout10ui20.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); }; StructArrayLayout10ui20.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) { var o2 = i * 10; this.uint16[o2 + 0] = v0; this.uint16[o2 + 1] = v1; this.uint16[o2 + 2] = v2; this.uint16[o2 + 3] = v3; this.uint16[o2 + 4] = v4; this.uint16[o2 + 5] = v5; this.uint16[o2 + 6] = v6; this.uint16[o2 + 7] = v7; this.uint16[o2 + 8] = v8; this.uint16[o2 + 9] = v9; return i; }; return StructArrayLayout10ui20; }(StructArray); StructArrayLayout10ui20.prototype.bytesPerElement = 20; register('StructArrayLayout10ui20', StructArrayLayout10ui20); var StructArrayLayout4i4ui4i24 = function (StructArray) { function StructArrayLayout4i4ui4i24() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout4i4ui4i24.__proto__ = StructArray; StructArrayLayout4i4ui4i24.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout4i4ui4i24.prototype.constructor = StructArrayLayout4i4ui4i24; StructArrayLayout4i4ui4i24.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout4i4ui4i24.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); }; StructArrayLayout4i4ui4i24.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) { var o2 = i * 12; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; this.uint16[o2 + 4] = v4; this.uint16[o2 + 5] = v5; this.uint16[o2 + 6] = v6; this.uint16[o2 + 7] = v7; this.int16[o2 + 8] = v8; this.int16[o2 + 9] = v9; this.int16[o2 + 10] = v10; this.int16[o2 + 11] = v11; return i; }; return StructArrayLayout4i4ui4i24; }(StructArray); StructArrayLayout4i4ui4i24.prototype.bytesPerElement = 24; register('StructArrayLayout4i4ui4i24', StructArrayLayout4i4ui4i24); var StructArrayLayout3f12 = function (StructArray) { function StructArrayLayout3f12() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout3f12.__proto__ = StructArray; StructArrayLayout3f12.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout3f12.prototype.constructor = StructArrayLayout3f12; StructArrayLayout3f12.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout3f12.prototype.emplaceBack = function emplaceBack(v0, v1, v2) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2); }; StructArrayLayout3f12.prototype.emplace = function emplace(i, v0, v1, v2) { var o4 = i * 3; this.float32[o4 + 0] = v0; this.float32[o4 + 1] = v1; this.float32[o4 + 2] = v2; return i; }; return StructArrayLayout3f12; }(StructArray); StructArrayLayout3f12.prototype.bytesPerElement = 12; register('StructArrayLayout3f12', StructArrayLayout3f12); var StructArrayLayout1ul4 = function (StructArray) { function StructArrayLayout1ul4() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout1ul4.__proto__ = StructArray; StructArrayLayout1ul4.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout1ul4.prototype.constructor = StructArrayLayout1ul4; StructArrayLayout1ul4.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint32 = new Uint32Array(this.arrayBuffer); }; StructArrayLayout1ul4.prototype.emplaceBack = function emplaceBack(v0) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0); }; StructArrayLayout1ul4.prototype.emplace = function emplace(i, v0) { var o4 = i * 1; this.uint32[o4 + 0] = v0; return i; }; return StructArrayLayout1ul4; }(StructArray); StructArrayLayout1ul4.prototype.bytesPerElement = 4; register('StructArrayLayout1ul4', StructArrayLayout1ul4); var StructArrayLayout6i1ul2ui20 = function (StructArray) { function StructArrayLayout6i1ul2ui20() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout6i1ul2ui20.__proto__ = StructArray; StructArrayLayout6i1ul2ui20.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout6i1ul2ui20.prototype.constructor = StructArrayLayout6i1ul2ui20; StructArrayLayout6i1ul2ui20.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); this.uint32 = new Uint32Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout6i1ul2ui20.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8); }; StructArrayLayout6i1ul2ui20.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8) { var o2 = i * 10; var o4 = i * 5; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; this.int16[o2 + 4] = v4; this.int16[o2 + 5] = v5; this.uint32[o4 + 3] = v6; this.uint16[o2 + 8] = v7; this.uint16[o2 + 9] = v8; return i; }; return StructArrayLayout6i1ul2ui20; }(StructArray); StructArrayLayout6i1ul2ui20.prototype.bytesPerElement = 20; register('StructArrayLayout6i1ul2ui20', StructArrayLayout6i1ul2ui20); var StructArrayLayout2i2i2i12 = function (StructArray) { function StructArrayLayout2i2i2i12() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2i2i2i12.__proto__ = StructArray; StructArrayLayout2i2i2i12.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2i2i2i12.prototype.constructor = StructArrayLayout2i2i2i12; StructArrayLayout2i2i2i12.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout2i2i2i12.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5); }; StructArrayLayout2i2i2i12.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5) { var o2 = i * 6; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; this.int16[o2 + 4] = v4; this.int16[o2 + 5] = v5; return i; }; return StructArrayLayout2i2i2i12; }(StructArray); StructArrayLayout2i2i2i12.prototype.bytesPerElement = 12; register('StructArrayLayout2i2i2i12', StructArrayLayout2i2i2i12); var StructArrayLayout2f1f2i16 = function (StructArray) { function StructArrayLayout2f1f2i16() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2f1f2i16.__proto__ = StructArray; StructArrayLayout2f1f2i16.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2f1f2i16.prototype.constructor = StructArrayLayout2f1f2i16; StructArrayLayout2f1f2i16.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout2f1f2i16.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4); }; StructArrayLayout2f1f2i16.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4) { var o4 = i * 4; var o2 = i * 8; this.float32[o4 + 0] = v0; this.float32[o4 + 1] = v1; this.float32[o4 + 2] = v2; this.int16[o2 + 6] = v3; this.int16[o2 + 7] = v4; return i; }; return StructArrayLayout2f1f2i16; }(StructArray); StructArrayLayout2f1f2i16.prototype.bytesPerElement = 16; register('StructArrayLayout2f1f2i16', StructArrayLayout2f1f2i16); var StructArrayLayout2ub2f12 = function (StructArray) { function StructArrayLayout2ub2f12() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2ub2f12.__proto__ = StructArray; StructArrayLayout2ub2f12.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2ub2f12.prototype.constructor = StructArrayLayout2ub2f12; StructArrayLayout2ub2f12.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout2ub2f12.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3); }; StructArrayLayout2ub2f12.prototype.emplace = function emplace(i, v0, v1, v2, v3) { var o1 = i * 12; var o4 = i * 3; this.uint8[o1 + 0] = v0; this.uint8[o1 + 1] = v1; this.float32[o4 + 1] = v2; this.float32[o4 + 2] = v3; return i; }; return StructArrayLayout2ub2f12; }(StructArray); StructArrayLayout2ub2f12.prototype.bytesPerElement = 12; register('StructArrayLayout2ub2f12', StructArrayLayout2ub2f12); var StructArrayLayout3ui6 = function (StructArray) { function StructArrayLayout3ui6() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout3ui6.__proto__ = StructArray; StructArrayLayout3ui6.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout3ui6.prototype.constructor = StructArrayLayout3ui6; StructArrayLayout3ui6.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout3ui6.prototype.emplaceBack = function emplaceBack(v0, v1, v2) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2); }; StructArrayLayout3ui6.prototype.emplace = function emplace(i, v0, v1, v2) { var o2 = i * 3; this.uint16[o2 + 0] = v0; this.uint16[o2 + 1] = v1; this.uint16[o2 + 2] = v2; return i; }; return StructArrayLayout3ui6; }(StructArray); StructArrayLayout3ui6.prototype.bytesPerElement = 6; register('StructArrayLayout3ui6', StructArrayLayout3ui6); var StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48 = function (StructArray) { function StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.__proto__ = StructArray; StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype.constructor = StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48; StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); this.uint32 = new Uint32Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); }; StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) { var o2 = i * 24; var o4 = i * 12; var o1 = i * 48; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.uint16[o2 + 2] = v2; this.uint16[o2 + 3] = v3; this.uint32[o4 + 2] = v4; this.uint32[o4 + 3] = v5; this.uint32[o4 + 4] = v6; this.uint16[o2 + 10] = v7; this.uint16[o2 + 11] = v8; this.uint16[o2 + 12] = v9; this.float32[o4 + 7] = v10; this.float32[o4 + 8] = v11; this.uint8[o1 + 36] = v12; this.uint8[o1 + 37] = v13; this.uint8[o1 + 38] = v14; this.uint32[o4 + 10] = v15; this.int16[o2 + 22] = v16; return i; }; return StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48; }(StructArray); StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype.bytesPerElement = 48; register('StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48', StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48); var StructArrayLayout8i15ui1ul4f68 = function (StructArray) { function StructArrayLayout8i15ui1ul4f68() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout8i15ui1ul4f68.__proto__ = StructArray; StructArrayLayout8i15ui1ul4f68.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout8i15ui1ul4f68.prototype.constructor = StructArrayLayout8i15ui1ul4f68; StructArrayLayout8i15ui1ul4f68.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); this.uint32 = new Uint32Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout8i15ui1ul4f68.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); }; StructArrayLayout8i15ui1ul4f68.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) { var o2 = i * 34; var o4 = i * 17; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; this.int16[o2 + 3] = v3; this.int16[o2 + 4] = v4; this.int16[o2 + 5] = v5; this.int16[o2 + 6] = v6; this.int16[o2 + 7] = v7; this.uint16[o2 + 8] = v8; this.uint16[o2 + 9] = v9; this.uint16[o2 + 10] = v10; this.uint16[o2 + 11] = v11; this.uint16[o2 + 12] = v12; this.uint16[o2 + 13] = v13; this.uint16[o2 + 14] = v14; this.uint16[o2 + 15] = v15; this.uint16[o2 + 16] = v16; this.uint16[o2 + 17] = v17; this.uint16[o2 + 18] = v18; this.uint16[o2 + 19] = v19; this.uint16[o2 + 20] = v20; this.uint16[o2 + 21] = v21; this.uint16[o2 + 22] = v22; this.uint32[o4 + 12] = v23; this.float32[o4 + 13] = v24; this.float32[o4 + 14] = v25; this.float32[o4 + 15] = v26; this.float32[o4 + 16] = v27; return i; }; return StructArrayLayout8i15ui1ul4f68; }(StructArray); StructArrayLayout8i15ui1ul4f68.prototype.bytesPerElement = 68; register('StructArrayLayout8i15ui1ul4f68', StructArrayLayout8i15ui1ul4f68); var StructArrayLayout1f4 = function (StructArray) { function StructArrayLayout1f4() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout1f4.__proto__ = StructArray; StructArrayLayout1f4.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout1f4.prototype.constructor = StructArrayLayout1f4; StructArrayLayout1f4.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout1f4.prototype.emplaceBack = function emplaceBack(v0) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0); }; StructArrayLayout1f4.prototype.emplace = function emplace(i, v0) { var o4 = i * 1; this.float32[o4 + 0] = v0; return i; }; return StructArrayLayout1f4; }(StructArray); StructArrayLayout1f4.prototype.bytesPerElement = 4; register('StructArrayLayout1f4', StructArrayLayout1f4); var StructArrayLayout3i6 = function (StructArray) { function StructArrayLayout3i6() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout3i6.__proto__ = StructArray; StructArrayLayout3i6.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout3i6.prototype.constructor = StructArrayLayout3i6; StructArrayLayout3i6.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.int16 = new Int16Array(this.arrayBuffer); }; StructArrayLayout3i6.prototype.emplaceBack = function emplaceBack(v0, v1, v2) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2); }; StructArrayLayout3i6.prototype.emplace = function emplace(i, v0, v1, v2) { var o2 = i * 3; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; return i; }; return StructArrayLayout3i6; }(StructArray); StructArrayLayout3i6.prototype.bytesPerElement = 6; register('StructArrayLayout3i6', StructArrayLayout3i6); var StructArrayLayout1ul2ui8 = function (StructArray) { function StructArrayLayout1ul2ui8() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout1ul2ui8.__proto__ = StructArray; StructArrayLayout1ul2ui8.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout1ul2ui8.prototype.constructor = StructArrayLayout1ul2ui8; StructArrayLayout1ul2ui8.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint32 = new Uint32Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout1ul2ui8.prototype.emplaceBack = function emplaceBack(v0, v1, v2) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2); }; StructArrayLayout1ul2ui8.prototype.emplace = function emplace(i, v0, v1, v2) { var o4 = i * 2; var o2 = i * 4; this.uint32[o4 + 0] = v0; this.uint16[o2 + 2] = v1; this.uint16[o2 + 3] = v2; return i; }; return StructArrayLayout1ul2ui8; }(StructArray); StructArrayLayout1ul2ui8.prototype.bytesPerElement = 8; register('StructArrayLayout1ul2ui8', StructArrayLayout1ul2ui8); var StructArrayLayout2ui4 = function (StructArray) { function StructArrayLayout2ui4() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout2ui4.__proto__ = StructArray; StructArrayLayout2ui4.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout2ui4.prototype.constructor = StructArrayLayout2ui4; StructArrayLayout2ui4.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout2ui4.prototype.emplaceBack = function emplaceBack(v0, v1) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1); }; StructArrayLayout2ui4.prototype.emplace = function emplace(i, v0, v1) { var o2 = i * 2; this.uint16[o2 + 0] = v0; this.uint16[o2 + 1] = v1; return i; }; return StructArrayLayout2ui4; }(StructArray); StructArrayLayout2ui4.prototype.bytesPerElement = 4; register('StructArrayLayout2ui4', StructArrayLayout2ui4); var StructArrayLayout1ui2 = function (StructArray) { function StructArrayLayout1ui2() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout1ui2.__proto__ = StructArray; StructArrayLayout1ui2.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout1ui2.prototype.constructor = StructArrayLayout1ui2; StructArrayLayout1ui2.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.uint16 = new Uint16Array(this.arrayBuffer); }; StructArrayLayout1ui2.prototype.emplaceBack = function emplaceBack(v0) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0); }; StructArrayLayout1ui2.prototype.emplace = function emplace(i, v0) { var o2 = i * 1; this.uint16[o2 + 0] = v0; return i; }; return StructArrayLayout1ui2; }(StructArray); StructArrayLayout1ui2.prototype.bytesPerElement = 2; register('StructArrayLayout1ui2', StructArrayLayout1ui2); var StructArrayLayout4f16 = function (StructArray) { function StructArrayLayout4f16() { StructArray.apply(this, arguments); } if (StructArray) StructArrayLayout4f16.__proto__ = StructArray; StructArrayLayout4f16.prototype = Object.create(StructArray && StructArray.prototype); StructArrayLayout4f16.prototype.constructor = StructArrayLayout4f16; StructArrayLayout4f16.prototype._refreshViews = function _refreshViews() { this.uint8 = new Uint8Array(this.arrayBuffer); this.float32 = new Float32Array(this.arrayBuffer); }; StructArrayLayout4f16.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3) { var i = this.length; this.resize(i + 1); return this.emplace(i, v0, v1, v2, v3); }; StructArrayLayout4f16.prototype.emplace = function emplace(i, v0, v1, v2, v3) { var o4 = i * 4; this.float32[o4 + 0] = v0; this.float32[o4 + 1] = v1; this.float32[o4 + 2] = v2; this.float32[o4 + 3] = v3; return i; }; return StructArrayLayout4f16; }(StructArray); StructArrayLayout4f16.prototype.bytesPerElement = 16; register('StructArrayLayout4f16', StructArrayLayout4f16); var CollisionBoxStruct = function (Struct) { function CollisionBoxStruct() { Struct.apply(this, arguments); } if (Struct) CollisionBoxStruct.__proto__ = Struct; CollisionBoxStruct.prototype = Object.create(Struct && Struct.prototype); CollisionBoxStruct.prototype.constructor = CollisionBoxStruct; var prototypeAccessors = { anchorPointX: { configurable: true }, anchorPointY: { configurable: true }, x1: { configurable: true }, y1: { configurable: true }, x2: { configurable: true }, y2: { configurable: true }, featureIndex: { configurable: true }, sourceLayerIndex: { configurable: true }, bucketIndex: { configurable: true }, anchorPoint: { configurable: true } }; prototypeAccessors.anchorPointX.get = function () { return this._structArray.int16[this._pos2 + 0]; }; prototypeAccessors.anchorPointY.get = function () { return this._structArray.int16[this._pos2 + 1]; }; prototypeAccessors.x1.get = function () { return this._structArray.int16[this._pos2 + 2]; }; prototypeAccessors.y1.get = function () { return this._structArray.int16[this._pos2 + 3]; }; prototypeAccessors.x2.get = function () { return this._structArray.int16[this._pos2 + 4]; }; prototypeAccessors.y2.get = function () { return this._structArray.int16[this._pos2 + 5]; }; prototypeAccessors.featureIndex.get = function () { return this._structArray.uint32[this._pos4 + 3]; }; prototypeAccessors.sourceLayerIndex.get = function () { return this._structArray.uint16[this._pos2 + 8]; }; prototypeAccessors.bucketIndex.get = function () { return this._structArray.uint16[this._pos2 + 9]; }; prototypeAccessors.anchorPoint.get = function () { return new pointGeometry(this.anchorPointX, this.anchorPointY); }; Object.defineProperties(CollisionBoxStruct.prototype, prototypeAccessors); return CollisionBoxStruct; }(Struct); CollisionBoxStruct.prototype.size = 20; var CollisionBoxArray = function (StructArrayLayout6i1ul2ui20) { function CollisionBoxArray() { StructArrayLayout6i1ul2ui20.apply(this, arguments); } if (StructArrayLayout6i1ul2ui20) CollisionBoxArray.__proto__ = StructArrayLayout6i1ul2ui20; CollisionBoxArray.prototype = Object.create(StructArrayLayout6i1ul2ui20 && StructArrayLayout6i1ul2ui20.prototype); CollisionBoxArray.prototype.constructor = CollisionBoxArray; CollisionBoxArray.prototype.get = function get(index) { return new CollisionBoxStruct(this, index); }; return CollisionBoxArray; }(StructArrayLayout6i1ul2ui20); register('CollisionBoxArray', CollisionBoxArray); var PlacedSymbolStruct = function (Struct) { function PlacedSymbolStruct() { Struct.apply(this, arguments); } if (Struct) PlacedSymbolStruct.__proto__ = Struct; PlacedSymbolStruct.prototype = Object.create(Struct && Struct.prototype); PlacedSymbolStruct.prototype.constructor = PlacedSymbolStruct; var prototypeAccessors$1 = { anchorX: { configurable: true }, anchorY: { configurable: true }, glyphStartIndex: { configurable: true }, numGlyphs: { configurable: true }, vertexStartIndex: { configurable: true }, lineStartIndex: { configurable: true }, lineLength: { configurable: true }, segment: { configurable: true }, lowerSize: { configurable: true }, upperSize: { configurable: true }, lineOffsetX: { configurable: true }, lineOffsetY: { configurable: true }, writingMode: { configurable: true }, placedOrientation: { configurable: true }, hidden: { configurable: true }, crossTileID: { configurable: true }, associatedIconIndex: { configurable: true } }; prototypeAccessors$1.anchorX.get = function () { return this._structArray.int16[this._pos2 + 0]; }; prototypeAccessors$1.anchorY.get = function () { return this._structArray.int16[this._pos2 + 1]; }; prototypeAccessors$1.glyphStartIndex.get = function () { return this._structArray.uint16[this._pos2 + 2]; }; prototypeAccessors$1.numGlyphs.get = function () { return this._structArray.uint16[this._pos2 + 3]; }; prototypeAccessors$1.vertexStartIndex.get = function () { return this._structArray.uint32[this._pos4 + 2]; }; prototypeAccessors$1.lineStartIndex.get = function () { return this._structArray.uint32[this._pos4 + 3]; }; prototypeAccessors$1.lineLength.get = function () { return this._structArray.uint32[this._pos4 + 4]; }; prototypeAccessors$1.segment.get = function () { return this._structArray.uint16[this._pos2 + 10]; }; prototypeAccessors$1.lowerSize.get = function () { return this._structArray.uint16[this._pos2 + 11]; }; prototypeAccessors$1.upperSize.get = function () { return this._structArray.uint16[this._pos2 + 12]; }; prototypeAccessors$1.lineOffsetX.get = function () { return this._structArray.float32[this._pos4 + 7]; }; prototypeAccessors$1.lineOffsetY.get = function () { return this._structArray.float32[this._pos4 + 8]; }; prototypeAccessors$1.writingMode.get = function () { return this._structArray.uint8[this._pos1 + 36]; }; prototypeAccessors$1.placedOrientation.get = function () { return this._structArray.uint8[this._pos1 + 37]; }; prototypeAccessors$1.placedOrientation.set = function (x) { this._structArray.uint8[this._pos1 + 37] = x; }; prototypeAccessors$1.hidden.get = function () { return this._structArray.uint8[this._pos1 + 38]; }; prototypeAccessors$1.hidden.set = function (x) { this._structArray.uint8[this._pos1 + 38] = x; }; prototypeAccessors$1.crossTileID.get = function () { return this._structArray.uint32[this._pos4 + 10]; }; prototypeAccessors$1.crossTileID.set = function (x) { this._structArray.uint32[this._pos4 + 10] = x; }; prototypeAccessors$1.associatedIconIndex.get = function () { return this._structArray.int16[this._pos2 + 22]; }; Object.defineProperties(PlacedSymbolStruct.prototype, prototypeAccessors$1); return PlacedSymbolStruct; }(Struct); PlacedSymbolStruct.prototype.size = 48; var PlacedSymbolArray = function (StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48) { function PlacedSymbolArray() { StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.apply(this, arguments); } if (StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48) PlacedSymbolArray.__proto__ = StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48; PlacedSymbolArray.prototype = Object.create(StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48 && StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48.prototype); PlacedSymbolArray.prototype.constructor = PlacedSymbolArray; PlacedSymbolArray.prototype.get = function get(index) { return new PlacedSymbolStruct(this, index); }; return PlacedSymbolArray; }(StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48); register('PlacedSymbolArray', PlacedSymbolArray); var SymbolInstanceStruct = function (Struct) { function SymbolInstanceStruct() { Struct.apply(this, arguments); } if (Struct) SymbolInstanceStruct.__proto__ = Struct; SymbolInstanceStruct.prototype = Object.create(Struct && Struct.prototype); SymbolInstanceStruct.prototype.constructor = SymbolInstanceStruct; var prototypeAccessors$2 = { anchorX: { configurable: true }, anchorY: { configurable: true }, rightJustifiedTextSymbolIndex: { configurable: true }, centerJustifiedTextSymbolIndex: { configurable: true }, leftJustifiedTextSymbolIndex: { configurable: true }, verticalPlacedTextSymbolIndex: { configurable: true }, placedIconSymbolIndex: { configurable: true }, verticalPlacedIconSymbolIndex: { configurable: true }, key: { configurable: true }, textBoxStartIndex: { configurable: true }, textBoxEndIndex: { configurable: true }, verticalTextBoxStartIndex: { configurable: true }, verticalTextBoxEndIndex: { configurable: true }, iconBoxStartIndex: { configurable: true }, iconBoxEndIndex: { configurable: true }, verticalIconBoxStartIndex: { configurable: true }, verticalIconBoxEndIndex: { configurable: true }, featureIndex: { configurable: true }, numHorizontalGlyphVertices: { configurable: true }, numVerticalGlyphVertices: { configurable: true }, numIconVertices: { configurable: true }, numVerticalIconVertices: { configurable: true }, useRuntimeCollisionCircles: { configurable: true }, crossTileID: { configurable: true }, textBoxScale: { configurable: true }, textOffset0: { configurable: true }, textOffset1: { configurable: true }, collisionCircleDiameter: { configurable: true } }; prototypeAccessors$2.anchorX.get = function () { return this._structArray.int16[this._pos2 + 0]; }; prototypeAccessors$2.anchorY.get = function () { return this._structArray.int16[this._pos2 + 1]; }; prototypeAccessors$2.rightJustifiedTextSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 2]; }; prototypeAccessors$2.centerJustifiedTextSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 3]; }; prototypeAccessors$2.leftJustifiedTextSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 4]; }; prototypeAccessors$2.verticalPlacedTextSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 5]; }; prototypeAccessors$2.placedIconSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 6]; }; prototypeAccessors$2.verticalPlacedIconSymbolIndex.get = function () { return this._structArray.int16[this._pos2 + 7]; }; prototypeAccessors$2.key.get = function () { return this._structArray.uint16[this._pos2 + 8]; }; prototypeAccessors$2.textBoxStartIndex.get = function () { return this._structArray.uint16[this._pos2 + 9]; }; prototypeAccessors$2.textBoxEndIndex.get = function () { return this._structArray.uint16[this._pos2 + 10]; }; prototypeAccessors$2.verticalTextBoxStartIndex.get = function () { return this._structArray.uint16[this._pos2 + 11]; }; prototypeAccessors$2.verticalTextBoxEndIndex.get = function () { return this._structArray.uint16[this._pos2 + 12]; }; prototypeAccessors$2.iconBoxStartIndex.get = function () { return this._structArray.uint16[this._pos2 + 13]; }; prototypeAccessors$2.iconBoxEndIndex.get = function () { return this._structArray.uint16[this._pos2 + 14]; }; prototypeAccessors$2.verticalIconBoxStartIndex.get = function () { return this._structArray.uint16[this._pos2 + 15]; }; prototypeAccessors$2.verticalIconBoxEndIndex.get = function () { return this._structArray.uint16[this._pos2 + 16]; }; prototypeAccessors$2.featureIndex.get = function () { return this._structArray.uint16[this._pos2 + 17]; }; prototypeAccessors$2.numHorizontalGlyphVertices.get = function () { return this._structArray.uint16[this._pos2 + 18]; }; prototypeAccessors$2.numVerticalGlyphVertices.get = function () { return this._structArray.uint16[this._pos2 + 19]; }; prototypeAccessors$2.numIconVertices.get = function () { return this._structArray.uint16[this._pos2 + 20]; }; prototypeAccessors$2.numVerticalIconVertices.get = function () { return this._structArray.uint16[this._pos2 + 21]; }; prototypeAccessors$2.useRuntimeCollisionCircles.get = function () { return this._structArray.uint16[this._pos2 + 22]; }; prototypeAccessors$2.crossTileID.get = function () { return this._structArray.uint32[this._pos4 + 12]; }; prototypeAccessors$2.crossTileID.set = function (x) { this._structArray.uint32[this._pos4 + 12] = x; }; prototypeAccessors$2.textBoxScale.get = function () { return this._structArray.float32[this._pos4 + 13]; }; prototypeAccessors$2.textOffset0.get = function () { return this._structArray.float32[this._pos4 + 14]; }; prototypeAccessors$2.textOffset1.get = function () { return this._structArray.float32[this._pos4 + 15]; }; prototypeAccessors$2.collisionCircleDiameter.get = function () { return this._structArray.float32[this._pos4 + 16]; }; Object.defineProperties(SymbolInstanceStruct.prototype, prototypeAccessors$2); return SymbolInstanceStruct; }(Struct); SymbolInstanceStruct.prototype.size = 68; var SymbolInstanceArray = function (StructArrayLayout8i15ui1ul4f68) { function SymbolInstanceArray() { StructArrayLayout8i15ui1ul4f68.apply(this, arguments); } if (StructArrayLayout8i15ui1ul4f68) SymbolInstanceArray.__proto__ = StructArrayLayout8i15ui1ul4f68; SymbolInstanceArray.prototype = Object.create(StructArrayLayout8i15ui1ul4f68 && StructArrayLayout8i15ui1ul4f68.prototype); SymbolInstanceArray.prototype.constructor = SymbolInstanceArray; SymbolInstanceArray.prototype.get = function get(index) { return new SymbolInstanceStruct(this, index); }; return SymbolInstanceArray; }(StructArrayLayout8i15ui1ul4f68); register('SymbolInstanceArray', SymbolInstanceArray); var GlyphOffsetArray = function (StructArrayLayout1f4) { function GlyphOffsetArray() { StructArrayLayout1f4.apply(this, arguments); } if (StructArrayLayout1f4) GlyphOffsetArray.__proto__ = StructArrayLayout1f4; GlyphOffsetArray.prototype = Object.create(StructArrayLayout1f4 && StructArrayLayout1f4.prototype); GlyphOffsetArray.prototype.constructor = GlyphOffsetArray; GlyphOffsetArray.prototype.getoffsetX = function getoffsetX(index) { return this.float32[index * 1 + 0]; }; return GlyphOffsetArray; }(StructArrayLayout1f4); register('GlyphOffsetArray', GlyphOffsetArray); var SymbolLineVertexArray = function (StructArrayLayout3i6) { function SymbolLineVertexArray() { StructArrayLayout3i6.apply(this, arguments); } if (StructArrayLayout3i6) SymbolLineVertexArray.__proto__ = StructArrayLayout3i6; SymbolLineVertexArray.prototype = Object.create(StructArrayLayout3i6 && StructArrayLayout3i6.prototype); SymbolLineVertexArray.prototype.constructor = SymbolLineVertexArray; SymbolLineVertexArray.prototype.getx = function getx(index) { return this.int16[index * 3 + 0]; }; SymbolLineVertexArray.prototype.gety = function gety(index) { return this.int16[index * 3 + 1]; }; SymbolLineVertexArray.prototype.gettileUnitDistanceFromAnchor = function gettileUnitDistanceFromAnchor(index) { return this.int16[index * 3 + 2]; }; return SymbolLineVertexArray; }(StructArrayLayout3i6); register('SymbolLineVertexArray', SymbolLineVertexArray); var FeatureIndexStruct = function (Struct) { function FeatureIndexStruct() { Struct.apply(this, arguments); } if (Struct) FeatureIndexStruct.__proto__ = Struct; FeatureIndexStruct.prototype = Object.create(Struct && Struct.prototype); FeatureIndexStruct.prototype.constructor = FeatureIndexStruct; var prototypeAccessors$3 = { featureIndex: { configurable: true }, sourceLayerIndex: { configurable: true }, bucketIndex: { configurable: true } }; prototypeAccessors$3.featureIndex.get = function () { return this._structArray.uint32[this._pos4 + 0]; }; prototypeAccessors$3.sourceLayerIndex.get = function () { return this._structArray.uint16[this._pos2 + 2]; }; prototypeAccessors$3.bucketIndex.get = function () { return this._structArray.uint16[this._pos2 + 3]; }; Object.defineProperties(FeatureIndexStruct.prototype, prototypeAccessors$3); return FeatureIndexStruct; }(Struct); FeatureIndexStruct.prototype.size = 8; var FeatureIndexArray = function (StructArrayLayout1ul2ui8) { function FeatureIndexArray() { StructArrayLayout1ul2ui8.apply(this, arguments); } if (StructArrayLayout1ul2ui8) FeatureIndexArray.__proto__ = StructArrayLayout1ul2ui8; FeatureIndexArray.prototype = Object.create(StructArrayLayout1ul2ui8 && StructArrayLayout1ul2ui8.prototype); FeatureIndexArray.prototype.constructor = FeatureIndexArray; FeatureIndexArray.prototype.get = function get(index) { return new FeatureIndexStruct(this, index); }; return FeatureIndexArray; }(StructArrayLayout1ul2ui8); register('FeatureIndexArray', FeatureIndexArray); var layout$1 = createLayout([{ name: 'a_pos', components: 2, type: 'Int16' }], 4); var members = layout$1.members; var SegmentVector = function SegmentVector(segments) { if (segments === void 0) segments = []; this.segments = segments; }; SegmentVector.prototype.prepareSegment = function prepareSegment(numVertices, layoutVertexArray, indexArray, sortKey) { var segment = this.segments[this.segments.length - 1]; if (numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) { warnOnce('Max vertices per segment is ' + SegmentVector.MAX_VERTEX_ARRAY_LENGTH + ': bucket requested ' + numVertices); } if (!segment || segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH || segment.sortKey !== sortKey) { segment = { vertexOffset: layoutVertexArray.length, primitiveOffset: indexArray.length, vertexLength: 0, primitiveLength: 0 }; if (sortKey !== undefined) { segment.sortKey = sortKey; } this.segments.push(segment); } return segment; }; SegmentVector.prototype.get = function get() { return this.segments; }; SegmentVector.prototype.destroy = function destroy() { for (var i = 0, list = this.segments; i < list.length; i += 1) { var segment = list[i]; for (var k in segment.vaos) { segment.vaos[k].destroy(); } } }; SegmentVector.simpleSegment = function simpleSegment(vertexOffset, primitiveOffset, vertexLength, primitiveLength) { return new SegmentVector([{ vertexOffset: vertexOffset, primitiveOffset: primitiveOffset, vertexLength: vertexLength, primitiveLength: primitiveLength, vaos: {}, sortKey: 0 }]); }; SegmentVector.MAX_VERTEX_ARRAY_LENGTH = Math.pow(2, 16) - 1; register('SegmentVector', SegmentVector); function packUint8ToFloat(a, b) { a = clamp(Math.floor(a), 0, 255); b = clamp(Math.floor(b), 0, 255); return 256 * a + b; } var patternAttributes = createLayout([ { name: 'a_pattern_from', components: 4, type: 'Uint16' }, { name: 'a_pattern_to', components: 4, type: 'Uint16' }, { name: 'a_pixel_ratio_from', components: 1, type: 'Uint16' }, { name: 'a_pixel_ratio_to', components: 1, type: 'Uint16' } ]); var murmurhash3_gc = createCommonjsModule(function (module) { function murmurhash3_32_gc(key, seed) { var remainder, bytes, h1, h1b, c1, c2, k1, i; remainder = key.length & 3; bytes = key.length - remainder; h1 = seed; c1 = 3432918353; c2 = 461845907; i = 0; while (i < bytes) { k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24; ++i; k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295; k1 = k1 << 15 | k1 >>> 17; k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295; h1 ^= k1; h1 = h1 << 13 | h1 >>> 19; h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295; h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16); } k1 = 0; switch (remainder) { case 3: k1 ^= (key.charCodeAt(i + 2) & 255) << 16; case 2: k1 ^= (key.charCodeAt(i + 1) & 255) << 8; case 1: k1 ^= key.charCodeAt(i) & 255; k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295; k1 = k1 << 15 | k1 >>> 17; k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295; h1 ^= k1; } h1 ^= key.length; h1 ^= h1 >>> 16; h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295; h1 ^= h1 >>> 13; h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295; h1 ^= h1 >>> 16; return h1 >>> 0; } { module.exports = murmurhash3_32_gc; } }); var murmurhash2_gc = createCommonjsModule(function (module) { function murmurhash2_32_gc(str, seed) { var l = str.length, h = seed ^ l, i = 0, k; while (l >= 4) { k = str.charCodeAt(i) & 255 | (str.charCodeAt(++i) & 255) << 8 | (str.charCodeAt(++i) & 255) << 16 | (str.charCodeAt(++i) & 255) << 24; k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16); k ^= k >>> 24; k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16); h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16) ^ k; l -= 4; ++i; } switch (l) { case 3: h ^= (str.charCodeAt(i + 2) & 255) << 16; case 2: h ^= (str.charCodeAt(i + 1) & 255) << 8; case 1: h ^= str.charCodeAt(i) & 255; h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16); } h ^= h >>> 13; h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16); h ^= h >>> 15; return h >>> 0; } { module.exports = murmurhash2_32_gc; } }); var murmurhashJs = murmurhash3_gc; var murmur3_1 = murmurhash3_gc; var murmur2_1 = murmurhash2_gc; murmurhashJs.murmur3 = murmur3_1; murmurhashJs.murmur2 = murmur2_1; var FeaturePositionMap = function FeaturePositionMap() { this.ids = []; this.positions = []; this.indexed = false; }; FeaturePositionMap.prototype.add = function add(id, index, start, end) { this.ids.push(getNumericId(id)); this.positions.push(index, start, end); }; FeaturePositionMap.prototype.getPositions = function getPositions(id) { var intId = getNumericId(id); var i = 0; var j = this.ids.length - 1; while (i < j) { var m = i + j >> 1; if (this.ids[m] >= intId) { j = m; } else { i = m + 1; } } var positions = []; while (this.ids[i] === intId) { var index = this.positions[3 * i]; var start = this.positions[3 * i + 1]; var end = this.positions[3 * i + 2]; positions.push({ index: index, start: start, end: end }); i++; } return positions; }; FeaturePositionMap.serialize = function serialize(map, transferables) { var ids = new Float64Array(map.ids); var positions = new Uint32Array(map.positions); sort(ids, positions, 0, ids.length - 1); if (transferables) { transferables.push(ids.buffer, positions.buffer); } return { ids: ids, positions: positions }; }; FeaturePositionMap.deserialize = function deserialize(obj) { var map = new FeaturePositionMap(); map.ids = obj.ids; map.positions = obj.positions; map.indexed = true; return map; }; var MAX_SAFE_INTEGER$1 = Math.pow(2, 53) - 1; function getNumericId(value) { var numValue = +value; if (!isNaN(numValue) && numValue <= MAX_SAFE_INTEGER$1) { return numValue; } return murmurhashJs(String(value)); } function sort(ids, positions, left, right) { while (left < right) { var pivot = ids[left + right >> 1]; var i = left - 1; var j = right + 1; while (true) { do { i++; } while (ids[i] < pivot); do { j--; } while (ids[j] > pivot); if (i >= j) { break; } swap(ids, i, j); swap(positions, 3 * i, 3 * j); swap(positions, 3 * i + 1, 3 * j + 1); swap(positions, 3 * i + 2, 3 * j + 2); } if (j - left < right - j) { sort(ids, positions, left, j); left = j + 1; } else { sort(ids, positions, j + 1, right); right = j; } } } function swap(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } register('FeaturePositionMap', FeaturePositionMap); var Uniform = function Uniform(context, location) { this.gl = context.gl; this.location = location; }; var Uniform1i = function (Uniform) { function Uniform1i(context, location) { Uniform.call(this, context, location); this.current = 0; } if (Uniform) Uniform1i.__proto__ = Uniform; Uniform1i.prototype = Object.create(Uniform && Uniform.prototype); Uniform1i.prototype.constructor = Uniform1i; Uniform1i.prototype.set = function set(v) { if (this.current !== v) { this.current = v; this.gl.uniform1i(this.location, v); } }; return Uniform1i; }(Uniform); var Uniform1f = function (Uniform) { function Uniform1f(context, location) { Uniform.call(this, context, location); this.current = 0; } if (Uniform) Uniform1f.__proto__ = Uniform; Uniform1f.prototype = Object.create(Uniform && Uniform.prototype); Uniform1f.prototype.constructor = Uniform1f; Uniform1f.prototype.set = function set(v) { if (this.current !== v) { this.current = v; this.gl.uniform1f(this.location, v); } }; return Uniform1f; }(Uniform); var Uniform2f = function (Uniform) { function Uniform2f(context, location) { Uniform.call(this, context, location); this.current = [ 0, 0 ]; } if (Uniform) Uniform2f.__proto__ = Uniform; Uniform2f.prototype = Object.create(Uniform && Uniform.prototype); Uniform2f.prototype.constructor = Uniform2f; Uniform2f.prototype.set = function set(v) { if (v[0] !== this.current[0] || v[1] !== this.current[1]) { this.current = v; this.gl.uniform2f(this.location, v[0], v[1]); } }; return Uniform2f; }(Uniform); var Uniform3f = function (Uniform) { function Uniform3f(context, location) { Uniform.call(this, context, location); this.current = [ 0, 0, 0 ]; } if (Uniform) Uniform3f.__proto__ = Uniform; Uniform3f.prototype = Object.create(Uniform && Uniform.prototype); Uniform3f.prototype.constructor = Uniform3f; Uniform3f.prototype.set = function set(v) { if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2]) { this.current = v; this.gl.uniform3f(this.location, v[0], v[1], v[2]); } }; return Uniform3f; }(Uniform); var Uniform4f = function (Uniform) { function Uniform4f(context, location) { Uniform.call(this, context, location); this.current = [ 0, 0, 0, 0 ]; } if (Uniform) Uniform4f.__proto__ = Uniform; Uniform4f.prototype = Object.create(Uniform && Uniform.prototype); Uniform4f.prototype.constructor = Uniform4f; Uniform4f.prototype.set = function set(v) { if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2] || v[3] !== this.current[3]) { this.current = v; this.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]); } }; return Uniform4f; }(Uniform); var UniformColor = function (Uniform) { function UniformColor(context, location) { Uniform.call(this, context, location); this.current = Color.transparent; } if (Uniform) UniformColor.__proto__ = Uniform; UniformColor.prototype = Object.create(Uniform && Uniform.prototype); UniformColor.prototype.constructor = UniformColor; UniformColor.prototype.set = function set(v) { if (v.r !== this.current.r || v.g !== this.current.g || v.b !== this.current.b || v.a !== this.current.a) { this.current = v; this.gl.uniform4f(this.location, v.r, v.g, v.b, v.a); } }; return UniformColor; }(Uniform); var emptyMat4 = new Float32Array(16); var UniformMatrix4f = function (Uniform) { function UniformMatrix4f(context, location) { Uniform.call(this, context, location); this.current = emptyMat4; } if (Uniform) UniformMatrix4f.__proto__ = Uniform; UniformMatrix4f.prototype = Object.create(Uniform && Uniform.prototype); UniformMatrix4f.prototype.constructor = UniformMatrix4f; UniformMatrix4f.prototype.set = function set(v) { if (v[12] !== this.current[12] || v[0] !== this.current[0]) { this.current = v; this.gl.uniformMatrix4fv(this.location, false, v); return; } for (var i = 1; i < 16; i++) { if (v[i] !== this.current[i]) { this.current = v; this.gl.uniformMatrix4fv(this.location, false, v); break; } } }; return UniformMatrix4f; }(Uniform); function packColor(color) { return [ packUint8ToFloat(255 * color.r, 255 * color.g), packUint8ToFloat(255 * color.b, 255 * color.a) ]; } var ConstantBinder = function ConstantBinder(value, names, type) { this.value = value; this.uniformNames = names.map(function (name) { return 'u_' + name; }); this.type = type; }; ConstantBinder.prototype.setUniform = function setUniform(uniform, globals, currentValue) { uniform.set(currentValue.constantOr(this.value)); }; ConstantBinder.prototype.getBinding = function getBinding(context, location, _) { return this.type === 'color' ? new UniformColor(context, location) : new Uniform1f(context, location); }; var CrossFadedConstantBinder = function CrossFadedConstantBinder(value, names) { this.uniformNames = names.map(function (name) { return 'u_' + name; }); this.patternFrom = null; this.patternTo = null; this.pixelRatioFrom = 1; this.pixelRatioTo = 1; }; CrossFadedConstantBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions(posTo, posFrom) { this.pixelRatioFrom = posFrom.pixelRatio; this.pixelRatioTo = posTo.pixelRatio; this.patternFrom = posFrom.tlbr; this.patternTo = posTo.tlbr; }; CrossFadedConstantBinder.prototype.setUniform = function setUniform(uniform, globals, currentValue, uniformName) { var pos = uniformName === 'u_pattern_to' ? this.patternTo : uniformName === 'u_pattern_from' ? this.patternFrom : uniformName === 'u_pixel_ratio_to' ? this.pixelRatioTo : uniformName === 'u_pixel_ratio_from' ? this.pixelRatioFrom : null; if (pos) { uniform.set(pos); } }; CrossFadedConstantBinder.prototype.getBinding = function getBinding(context, location, name) { return name.substr(0, 9) === 'u_pattern' ? new Uniform4f(context, location) : new Uniform1f(context, location); }; var SourceExpressionBinder = function SourceExpressionBinder(expression, names, type, PaintVertexArray) { this.expression = expression; this.type = type; this.maxValue = 0; this.paintVertexAttributes = names.map(function (name) { return { name: 'a_' + name, type: 'Float32', components: type === 'color' ? 2 : 1, offset: 0 }; }); this.paintVertexArray = new PaintVertexArray(); }; SourceExpressionBinder.prototype.populatePaintArray = function populatePaintArray(newLength, feature, imagePositions, canonical, formattedSection) { var start = this.paintVertexArray.length; var value = this.expression.evaluate(new EvaluationParameters(0), feature, {}, canonical, [], formattedSection); this.paintVertexArray.resize(newLength); this._setPaintValue(start, newLength, value); }; SourceExpressionBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState) { var value = this.expression.evaluate({ zoom: 0 }, feature, featureState); this._setPaintValue(start, end, value); }; SourceExpressionBinder.prototype._setPaintValue = function _setPaintValue(start, end, value) { if (this.type === 'color') { var color = packColor(value); for (var i = start; i < end; i++) { this.paintVertexArray.emplace(i, color[0], color[1]); } } else { for (var i$1 = start; i$1 < end; i$1++) { this.paintVertexArray.emplace(i$1, value); } this.maxValue = Math.max(this.maxValue, Math.abs(value)); } }; SourceExpressionBinder.prototype.upload = function upload(context) { if (this.paintVertexArray && this.paintVertexArray.arrayBuffer) { if (this.paintVertexBuffer && this.paintVertexBuffer.buffer) { this.paintVertexBuffer.updateData(this.paintVertexArray); } else { this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent); } } }; SourceExpressionBinder.prototype.destroy = function destroy() { if (this.paintVertexBuffer) { this.paintVertexBuffer.destroy(); } }; var CompositeExpressionBinder = function CompositeExpressionBinder(expression, names, type, useIntegerZoom, zoom, PaintVertexArray) { this.expression = expression; this.uniformNames = names.map(function (name) { return 'u_' + name + '_t'; }); this.type = type; this.useIntegerZoom = useIntegerZoom; this.zoom = zoom; this.maxValue = 0; this.paintVertexAttributes = names.map(function (name) { return { name: 'a_' + name, type: 'Float32', components: type === 'color' ? 4 : 2, offset: 0 }; }); this.paintVertexArray = new PaintVertexArray(); }; CompositeExpressionBinder.prototype.populatePaintArray = function populatePaintArray(newLength, feature, imagePositions, canonical, formattedSection) { var min = this.expression.evaluate(new EvaluationParameters(this.zoom), feature, {}, canonical, [], formattedSection); var max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1), feature, {}, canonical, [], formattedSection); var start = this.paintVertexArray.length; this.paintVertexArray.resize(newLength); this._setPaintValue(start, newLength, min, max); }; CompositeExpressionBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState) { var min = this.expression.evaluate({ zoom: this.zoom }, feature, featureState); var max = this.expression.evaluate({ zoom: this.zoom + 1 }, feature, featureState); this._setPaintValue(start, end, min, max); }; CompositeExpressionBinder.prototype._setPaintValue = function _setPaintValue(start, end, min, max) { if (this.type === 'color') { var minColor = packColor(min); var maxColor = packColor(max); for (var i = start; i < end; i++) { this.paintVertexArray.emplace(i, minColor[0], minColor[1], maxColor[0], maxColor[1]); } } else { for (var i$1 = start; i$1 < end; i$1++) { this.paintVertexArray.emplace(i$1, min, max); } this.maxValue = Math.max(this.maxValue, Math.abs(min), Math.abs(max)); } }; CompositeExpressionBinder.prototype.upload = function upload(context) { if (this.paintVertexArray && this.paintVertexArray.arrayBuffer) { if (this.paintVertexBuffer && this.paintVertexBuffer.buffer) { this.paintVertexBuffer.updateData(this.paintVertexArray); } else { this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent); } } }; CompositeExpressionBinder.prototype.destroy = function destroy() { if (this.paintVertexBuffer) { this.paintVertexBuffer.destroy(); } }; CompositeExpressionBinder.prototype.setUniform = function setUniform(uniform, globals) { var currentZoom = this.useIntegerZoom ? Math.floor(globals.zoom) : globals.zoom; var factor = clamp(this.expression.interpolationFactor(currentZoom, this.zoom, this.zoom + 1), 0, 1); uniform.set(factor); }; CompositeExpressionBinder.prototype.getBinding = function getBinding(context, location, _) { return new Uniform1f(context, location); }; var CrossFadedCompositeBinder = function CrossFadedCompositeBinder(expression, type, useIntegerZoom, zoom, PaintVertexArray, layerId) { this.expression = expression; this.type = type; this.useIntegerZoom = useIntegerZoom; this.zoom = zoom; this.layerId = layerId; this.zoomInPaintVertexArray = new PaintVertexArray(); this.zoomOutPaintVertexArray = new PaintVertexArray(); }; CrossFadedCompositeBinder.prototype.populatePaintArray = function populatePaintArray(length, feature, imagePositions) { var start = this.zoomInPaintVertexArray.length; this.zoomInPaintVertexArray.resize(length); this.zoomOutPaintVertexArray.resize(length); this._setPaintValues(start, length, feature.patterns && feature.patterns[this.layerId], imagePositions); }; CrossFadedCompositeBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState, imagePositions) { this._setPaintValues(start, end, feature.patterns && feature.patterns[this.layerId], imagePositions); }; CrossFadedCompositeBinder.prototype._setPaintValues = function _setPaintValues(start, end, patterns, positions) { if (!positions || !patterns) { return; } var min = patterns.min; var mid = patterns.mid; var max = patterns.max; var imageMin = positions[min]; var imageMid = positions[mid]; var imageMax = positions[max]; if (!imageMin || !imageMid || !imageMax) { return; } for (var i = start; i < end; i++) { this.zoomInPaintVertexArray.emplace(i, imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], imageMin.tl[0], imageMin.tl[1], imageMin.br[0], imageMin.br[1], imageMid.pixelRatio, imageMin.pixelRatio); this.zoomOutPaintVertexArray.emplace(i, imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], imageMax.tl[0], imageMax.tl[1], imageMax.br[0], imageMax.br[1], imageMid.pixelRatio, imageMax.pixelRatio); } }; CrossFadedCompositeBinder.prototype.upload = function upload(context) { if (this.zoomInPaintVertexArray && this.zoomInPaintVertexArray.arrayBuffer && this.zoomOutPaintVertexArray && this.zoomOutPaintVertexArray.arrayBuffer) { this.zoomInPaintVertexBuffer = context.createVertexBuffer(this.zoomInPaintVertexArray, patternAttributes.members, this.expression.isStateDependent); this.zoomOutPaintVertexBuffer = context.createVertexBuffer(this.zoomOutPaintVertexArray, patternAttributes.members, this.expression.isStateDependent); } }; CrossFadedCompositeBinder.prototype.destroy = function destroy() { if (this.zoomOutPaintVertexBuffer) { this.zoomOutPaintVertexBuffer.destroy(); } if (this.zoomInPaintVertexBuffer) { this.zoomInPaintVertexBuffer.destroy(); } }; var ProgramConfiguration = function ProgramConfiguration(layer, zoom, filterProperties) { this.binders = {}; this._buffers = []; var keys = []; for (var property in layer.paint._values) { if (!filterProperties(property)) { continue; } var value = layer.paint.get(property); if (!(value instanceof PossiblyEvaluatedPropertyValue) || !supportsPropertyExpression(value.property.specification)) { continue; } var names = paintAttributeNames(property, layer.type); var expression = value.value; var type = value.property.specification.type; var useIntegerZoom = value.property.useIntegerZoom; var propType = value.property.specification['property-type']; var isCrossFaded = propType === 'cross-faded' || propType === 'cross-faded-data-driven'; if (expression.kind === 'constant') { this.binders[property] = isCrossFaded ? new CrossFadedConstantBinder(expression.value, names) : new ConstantBinder(expression.value, names, type); keys.push('/u_' + property); } else if (expression.kind === 'source' || isCrossFaded) { var StructArrayLayout = layoutType(property, type, 'source'); this.binders[property] = isCrossFaded ? new CrossFadedCompositeBinder(expression, type, useIntegerZoom, zoom, StructArrayLayout, layer.id) : new SourceExpressionBinder(expression, names, type, StructArrayLayout); keys.push('/a_' + property); } else { var StructArrayLayout$1 = layoutType(property, type, 'composite'); this.binders[property] = new CompositeExpressionBinder(expression, names, type, useIntegerZoom, zoom, StructArrayLayout$1); keys.push('/z_' + property); } } this.cacheKey = keys.sort().join(''); }; ProgramConfiguration.prototype.getMaxValue = function getMaxValue(property) { var binder = this.binders[property]; return binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder ? binder.maxValue : 0; }; ProgramConfiguration.prototype.populatePaintArrays = function populatePaintArrays(newLength, feature, imagePositions, canonical, formattedSection) { for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof CrossFadedCompositeBinder) { binder.populatePaintArray(newLength, feature, imagePositions, canonical, formattedSection); } } }; ProgramConfiguration.prototype.setConstantPatternPositions = function setConstantPatternPositions(posTo, posFrom) { for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof CrossFadedConstantBinder) { binder.setConstantPatternPositions(posTo, posFrom); } } }; ProgramConfiguration.prototype.updatePaintArrays = function updatePaintArrays(featureStates, featureMap, vtLayer, layer, imagePositions) { var dirty = false; for (var id in featureStates) { var positions = featureMap.getPositions(id); for (var i = 0, list = positions; i < list.length; i += 1) { var pos = list[i]; var feature = vtLayer.feature(pos.index); for (var property in this.binders) { var binder = this.binders[property]; if ((binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof CrossFadedCompositeBinder) && binder.expression.isStateDependent === true) { var value = layer.paint.get(property); binder.expression = value.value; binder.updatePaintArray(pos.start, pos.end, feature, featureStates[id], imagePositions); dirty = true; } } } } return dirty; }; ProgramConfiguration.prototype.defines = function defines() { var result = []; for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof ConstantBinder || binder instanceof CrossFadedConstantBinder) { result.push.apply(result, binder.uniformNames.map(function (name) { return '#define HAS_UNIFORM_' + name; })); } } return result; }; ProgramConfiguration.prototype.getBinderAttributes = function getBinderAttributes() { var result = []; for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder) { for (var i = 0; i < binder.paintVertexAttributes.length; i++) { result.push(binder.paintVertexAttributes[i].name); } } else if (binder instanceof CrossFadedCompositeBinder) { for (var i$1 = 0; i$1 < patternAttributes.members.length; i$1++) { result.push(patternAttributes.members[i$1].name); } } } return result; }; ProgramConfiguration.prototype.getBinderUniforms = function getBinderUniforms() { var uniforms = []; for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof ConstantBinder || binder instanceof CrossFadedConstantBinder || binder instanceof CompositeExpressionBinder) { for (var i = 0, list = binder.uniformNames; i < list.length; i += 1) { var uniformName = list[i]; uniforms.push(uniformName); } } } return uniforms; }; ProgramConfiguration.prototype.getPaintVertexBuffers = function getPaintVertexBuffers() { return this._buffers; }; ProgramConfiguration.prototype.getUniforms = function getUniforms(context, locations) { var uniforms = []; for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof ConstantBinder || binder instanceof CrossFadedConstantBinder || binder instanceof CompositeExpressionBinder) { for (var i = 0, list = binder.uniformNames; i < list.length; i += 1) { var name = list[i]; if (locations[name]) { var binding = binder.getBinding(context, locations[name], name); uniforms.push({ name: name, property: property, binding: binding }); } } } } return uniforms; }; ProgramConfiguration.prototype.setUniforms = function setUniforms(context, binderUniforms, properties, globals) { for (var i = 0, list = binderUniforms; i < list.length; i += 1) { var ref = list[i]; var name = ref.name; var property = ref.property; var binding = ref.binding; this.binders[property].setUniform(binding, globals, properties.get(property), name); } }; ProgramConfiguration.prototype.updatePaintBuffers = function updatePaintBuffers(crossfade) { this._buffers = []; for (var property in this.binders) { var binder = this.binders[property]; if (crossfade && binder instanceof CrossFadedCompositeBinder) { var patternVertexBuffer = crossfade.fromScale === 2 ? binder.zoomInPaintVertexBuffer : binder.zoomOutPaintVertexBuffer; if (patternVertexBuffer) { this._buffers.push(patternVertexBuffer); } } else if ((binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder) && binder.paintVertexBuffer) { this._buffers.push(binder.paintVertexBuffer); } } }; ProgramConfiguration.prototype.upload = function upload(context) { for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof CrossFadedCompositeBinder) { binder.upload(context); } } this.updatePaintBuffers(); }; ProgramConfiguration.prototype.destroy = function destroy() { for (var property in this.binders) { var binder = this.binders[property]; if (binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder || binder instanceof CrossFadedCompositeBinder) { binder.destroy(); } } }; var ProgramConfigurationSet = function ProgramConfigurationSet(layers, zoom, filterProperties) { if (filterProperties === void 0) filterProperties = function () { return true; }; this.programConfigurations = {}; for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; this.programConfigurations[layer.id] = new ProgramConfiguration(layer, zoom, filterProperties); } this.needsUpload = false; this._featureMap = new FeaturePositionMap(); this._bufferOffset = 0; }; ProgramConfigurationSet.prototype.populatePaintArrays = function populatePaintArrays(length, feature, index, imagePositions, canonical, formattedSection) { for (var key in this.programConfigurations) { this.programConfigurations[key].populatePaintArrays(length, feature, imagePositions, canonical, formattedSection); } if (feature.id !== undefined) { this._featureMap.add(feature.id, index, this._bufferOffset, length); } this._bufferOffset = length; this.needsUpload = true; }; ProgramConfigurationSet.prototype.updatePaintArrays = function updatePaintArrays(featureStates, vtLayer, layers, imagePositions) { for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; this.needsUpload = this.programConfigurations[layer.id].updatePaintArrays(featureStates, this._featureMap, vtLayer, layer, imagePositions) || this.needsUpload; } }; ProgramConfigurationSet.prototype.get = function get(layerId) { return this.programConfigurations[layerId]; }; ProgramConfigurationSet.prototype.upload = function upload(context) { if (!this.needsUpload) { return; } for (var layerId in this.programConfigurations) { this.programConfigurations[layerId].upload(context); } this.needsUpload = false; }; ProgramConfigurationSet.prototype.destroy = function destroy() { for (var layerId in this.programConfigurations) { this.programConfigurations[layerId].destroy(); } }; function paintAttributeNames(property, type) { var attributeNameExceptions = { 'text-opacity': ['opacity'], 'icon-opacity': ['opacity'], 'text-color': ['fill_color'], 'icon-color': ['fill_color'], 'text-halo-color': ['halo_color'], 'icon-halo-color': ['halo_color'], 'text-halo-blur': ['halo_blur'], 'icon-halo-blur': ['halo_blur'], 'text-halo-width': ['halo_width'], 'icon-halo-width': ['halo_width'], 'line-gap-width': ['gapwidth'], 'line-pattern': [ 'pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from' ], 'fill-pattern': [ 'pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from' ], 'fill-extrusion-pattern': [ 'pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from' ] }; return attributeNameExceptions[property] || [property.replace(type + '-', '').replace(/-/g, '_')]; } function getLayoutException(property) { var propertyExceptions = { 'line-pattern': { 'source': StructArrayLayout10ui20, 'composite': StructArrayLayout10ui20 }, 'fill-pattern': { 'source': StructArrayLayout10ui20, 'composite': StructArrayLayout10ui20 }, 'fill-extrusion-pattern': { 'source': StructArrayLayout10ui20, 'composite': StructArrayLayout10ui20 } }; return propertyExceptions[property]; } function layoutType(property, type, binderType) { var defaultLayouts = { 'color': { 'source': StructArrayLayout2f8, 'composite': StructArrayLayout4f16 }, 'number': { 'source': StructArrayLayout1f4, 'composite': StructArrayLayout2f8 } }; var layoutException = getLayoutException(property); return layoutException && layoutException[binderType] || defaultLayouts[type][binderType]; } register('ConstantBinder', ConstantBinder); register('CrossFadedConstantBinder', CrossFadedConstantBinder); register('SourceExpressionBinder', SourceExpressionBinder); register('CrossFadedCompositeBinder', CrossFadedCompositeBinder); register('CompositeExpressionBinder', CompositeExpressionBinder); register('ProgramConfiguration', ProgramConfiguration, { omit: ['_buffers'] }); register('ProgramConfigurationSet', ProgramConfigurationSet); var EXTENT$1 = 8192; var BITS = 15; var MAX = Math.pow(2, BITS - 1) - 1; var MIN = -MAX - 1; function loadGeometry(feature) { var scale = EXTENT$1 / feature.extent; var geometry = feature.loadGeometry(); for (var r = 0; r < geometry.length; r++) { var ring = geometry[r]; for (var p = 0; p < ring.length; p++) { var point = ring[p]; var x = Math.round(point.x * scale); var y = Math.round(point.y * scale); point.x = clamp(x, MIN, MAX); point.y = clamp(y, MIN, MAX); if (x < point.x || x > point.x + 1 || y < point.y || y > point.y + 1) { warnOnce('Geometry exceeds allowed extent, reduce your vector tile buffer size'); } } } return geometry; } function toEvaluationFeature(feature, needGeometry) { return { type: feature.type, id: feature.id, properties: feature.properties, geometry: needGeometry ? loadGeometry(feature) : [] }; } function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) { layoutVertexArray.emplaceBack(x * 2 + (extrudeX + 1) / 2, y * 2 + (extrudeY + 1) / 2); } var CircleBucket = function CircleBucket(options) { this.zoom = options.zoom; this.overscaling = options.overscaling; this.layers = options.layers; this.layerIds = this.layers.map(function (layer) { return layer.id; }); this.index = options.index; this.hasPattern = false; this.layoutVertexArray = new StructArrayLayout2i4(); this.indexArray = new StructArrayLayout3ui6(); this.segments = new SegmentVector(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.stateDependentLayerIds = this.layers.filter(function (l) { return l.isStateDependent(); }).map(function (l) { return l.id; }); }; CircleBucket.prototype.populate = function populate(features, options, canonical) { var styleLayer = this.layers[0]; var bucketFeatures = []; var circleSortKey = null; if (styleLayer.type === 'circle') { circleSortKey = styleLayer.layout.get('circle-sort-key'); } for (var i = 0, list = features; i < list.length; i += 1) { var ref = list[i]; var feature = ref.feature; var id = ref.id; var index = ref.index; var sourceLayerIndex = ref.sourceLayerIndex; var needGeometry = this.layers[0]._featureFilter.needGeometry; var evaluationFeature = toEvaluationFeature(feature, needGeometry); if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) { continue; } var sortKey = circleSortKey ? circleSortKey.evaluate(evaluationFeature, {}, canonical) : undefined; var bucketFeature = { id: id, properties: feature.properties, type: feature.type, sourceLayerIndex: sourceLayerIndex, index: index, geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature), patterns: {}, sortKey: sortKey }; bucketFeatures.push(bucketFeature); } if (circleSortKey) { bucketFeatures.sort(function (a, b) { return a.sortKey - b.sortKey; }); } for (var i$1 = 0, list$1 = bucketFeatures; i$1 < list$1.length; i$1 += 1) { var bucketFeature$1 = list$1[i$1]; var ref$1 = bucketFeature$1; var geometry = ref$1.geometry; var index$1 = ref$1.index; var sourceLayerIndex$1 = ref$1.sourceLayerIndex; var feature$1 = features[index$1].feature; this.addFeature(bucketFeature$1, geometry, index$1, canonical); options.featureIndex.insert(feature$1, geometry, index$1, sourceLayerIndex$1, this.index); } }; CircleBucket.prototype.update = function update(states, vtLayer, imagePositions) { if (!this.stateDependentLayers.length) { return; } this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions); }; CircleBucket.prototype.isEmpty = function isEmpty() { return this.layoutVertexArray.length === 0; }; CircleBucket.prototype.uploadPending = function uploadPending() { return !this.uploaded || this.programConfigurations.needsUpload; }; CircleBucket.prototype.upload = function upload(context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); this.uploaded = true; }; CircleBucket.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); }; CircleBucket.prototype.addFeature = function addFeature(feature, geometry, index, canonical) { for (var i$1 = 0, list$1 = geometry; i$1 < list$1.length; i$1 += 1) { var ring = list$1[i$1]; for (var i = 0, list = ring; i < list.length; i += 1) { var point = list[i]; var x = point.x; var y = point.y; if (x < 0 || x >= EXTENT$1 || y < 0 || y >= EXTENT$1) { continue; } var segment = this.segments.prepareSegment(4, this.layoutVertexArray, this.indexArray, feature.sortKey); var index$1 = segment.vertexLength; addCircleVertex(this.layoutVertexArray, x, y, -1, -1); addCircleVertex(this.layoutVertexArray, x, y, 1, -1); addCircleVertex(this.layoutVertexArray, x, y, 1, 1); addCircleVertex(this.layoutVertexArray, x, y, -1, 1); this.indexArray.emplaceBack(index$1, index$1 + 1, index$1 + 2); this.indexArray.emplaceBack(index$1, index$1 + 3, index$1 + 2); segment.vertexLength += 4; segment.primitiveLength += 2; } } this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {}, canonical); }; register('CircleBucket', CircleBucket, { omit: ['layers'] }); function polygonIntersectsPolygon(polygonA, polygonB) { for (var i = 0; i < polygonA.length; i++) { if (polygonContainsPoint(polygonB, polygonA[i])) { return true; } } for (var i$1 = 0; i$1 < polygonB.length; i$1++) { if (polygonContainsPoint(polygonA, polygonB[i$1])) { return true; } } if (lineIntersectsLine(polygonA, polygonB)) { return true; } return false; } function polygonIntersectsBufferedPoint(polygon, point, radius) { if (polygonContainsPoint(polygon, point)) { return true; } if (pointIntersectsBufferedLine(point, polygon, radius)) { return true; } return false; } function polygonIntersectsMultiPolygon(polygon, multiPolygon) { if (polygon.length === 1) { return multiPolygonContainsPoint(multiPolygon, polygon[0]); } for (var m = 0; m < multiPolygon.length; m++) { var ring = multiPolygon[m]; for (var n = 0; n < ring.length; n++) { if (polygonContainsPoint(polygon, ring[n])) { return true; } } } for (var i = 0; i < polygon.length; i++) { if (multiPolygonContainsPoint(multiPolygon, polygon[i])) { return true; } } for (var k = 0; k < multiPolygon.length; k++) { if (lineIntersectsLine(polygon, multiPolygon[k])) { return true; } } return false; } function polygonIntersectsBufferedMultiLine(polygon, multiLine, radius) { for (var i = 0; i < multiLine.length; i++) { var line = multiLine[i]; if (polygon.length >= 3) { for (var k = 0; k < line.length; k++) { if (polygonContainsPoint(polygon, line[k])) { return true; } } } if (lineIntersectsBufferedLine(polygon, line, radius)) { return true; } } return false; } function lineIntersectsBufferedLine(lineA, lineB, radius) { if (lineA.length > 1) { if (lineIntersectsLine(lineA, lineB)) { return true; } for (var j = 0; j < lineB.length; j++) { if (pointIntersectsBufferedLine(lineB[j], lineA, radius)) { return true; } } } for (var k = 0; k < lineA.length; k++) { if (pointIntersectsBufferedLine(lineA[k], lineB, radius)) { return true; } } return false; } function lineIntersectsLine(lineA, lineB) { if (lineA.length === 0 || lineB.length === 0) { return false; } for (var i = 0; i < lineA.length - 1; i++) { var a0 = lineA[i]; var a1 = lineA[i + 1]; for (var j = 0; j < lineB.length - 1; j++) { var b0 = lineB[j]; var b1 = lineB[j + 1]; if (lineSegmentIntersectsLineSegment(a0, a1, b0, b1)) { return true; } } } return false; } function lineSegmentIntersectsLineSegment(a0, a1, b0, b1) { return isCounterClockwise(a0, b0, b1) !== isCounterClockwise(a1, b0, b1) && isCounterClockwise(a0, a1, b0) !== isCounterClockwise(a0, a1, b1); } function pointIntersectsBufferedLine(p, line, radius) { var radiusSquared = radius * radius; if (line.length === 1) { return p.distSqr(line[0]) < radiusSquared; } for (var i = 1; i < line.length; i++) { var v = line[i - 1], w = line[i]; if (distToSegmentSquared(p, v, w) < radiusSquared) { return true; } } return false; } function distToSegmentSquared(p, v, w) { var l2 = v.distSqr(w); if (l2 === 0) { return p.distSqr(v); } var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2; if (t < 0) { return p.distSqr(v); } if (t > 1) { return p.distSqr(w); } return p.distSqr(w.sub(v)._mult(t)._add(v)); } function multiPolygonContainsPoint(rings, p) { var c = false, ring, p1, p2; for (var k = 0; k < rings.length; k++) { ring = rings[k]; for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) { p1 = ring[i]; p2 = ring[j]; if (p1.y > p.y !== p2.y > p.y && p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x) { c = !c; } } } return c; } function polygonContainsPoint(ring, p) { var c = false; for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) { var p1 = ring[i]; var p2 = ring[j]; if (p1.y > p.y !== p2.y > p.y && p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x) { c = !c; } } return c; } function polygonIntersectsBox(ring, boxX1, boxY1, boxX2, boxY2) { for (var i$1 = 0, list = ring; i$1 < list.length; i$1 += 1) { var p = list[i$1]; if (boxX1 <= p.x && boxY1 <= p.y && boxX2 >= p.x && boxY2 >= p.y) { return true; } } var corners = [ new pointGeometry(boxX1, boxY1), new pointGeometry(boxX1, boxY2), new pointGeometry(boxX2, boxY2), new pointGeometry(boxX2, boxY1) ]; if (ring.length > 2) { for (var i$2 = 0, list$1 = corners; i$2 < list$1.length; i$2 += 1) { var corner = list$1[i$2]; if (polygonContainsPoint(ring, corner)) { return true; } } } for (var i = 0; i < ring.length - 1; i++) { var p1 = ring[i]; var p2 = ring[i + 1]; if (edgeIntersectsBox(p1, p2, corners)) { return true; } } return false; } function edgeIntersectsBox(e1, e2, corners) { var tl = corners[0]; var br = corners[2]; if (e1.x < tl.x && e2.x < tl.x || e1.x > br.x && e2.x > br.x || e1.y < tl.y && e2.y < tl.y || e1.y > br.y && e2.y > br.y) { return false; } var dir = isCounterClockwise(e1, e2, corners[0]); return dir !== isCounterClockwise(e1, e2, corners[1]) || dir !== isCounterClockwise(e1, e2, corners[2]) || dir !== isCounterClockwise(e1, e2, corners[3]); } function getMaximumPaintValue(property, layer, bucket) { var value = layer.paint.get(property).value; if (value.kind === 'constant') { return value.value; } else { return bucket.programConfigurations.get(layer.id).getMaxValue(property); } } function translateDistance(translate) { return Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]); } function translate(queryGeometry, translate, translateAnchor, bearing, pixelsToTileUnits) { if (!translate[0] && !translate[1]) { return queryGeometry; } var pt = pointGeometry.convert(translate)._mult(pixelsToTileUnits); if (translateAnchor === 'viewport') { pt._rotate(-bearing); } var translated = []; for (var i = 0; i < queryGeometry.length; i++) { var point = queryGeometry[i]; translated.push(point.sub(pt)); } return translated; } var layout$2 = new Properties({ 'circle-sort-key': new DataDrivenProperty(spec['layout_circle']['circle-sort-key']) }); var paint$1 = new Properties({ 'circle-radius': new DataDrivenProperty(spec['paint_circle']['circle-radius']), 'circle-color': new DataDrivenProperty(spec['paint_circle']['circle-color']), 'circle-blur': new DataDrivenProperty(spec['paint_circle']['circle-blur']), 'circle-opacity': new DataDrivenProperty(spec['paint_circle']['circle-opacity']), 'circle-translate': new DataConstantProperty(spec['paint_circle']['circle-translate']), 'circle-translate-anchor': new DataConstantProperty(spec['paint_circle']['circle-translate-anchor']), 'circle-pitch-scale': new DataConstantProperty(spec['paint_circle']['circle-pitch-scale']), 'circle-pitch-alignment': new DataConstantProperty(spec['paint_circle']['circle-pitch-alignment']), 'circle-stroke-width': new DataDrivenProperty(spec['paint_circle']['circle-stroke-width']), 'circle-stroke-color': new DataDrivenProperty(spec['paint_circle']['circle-stroke-color']), 'circle-stroke-opacity': new DataDrivenProperty(spec['paint_circle']['circle-stroke-opacity']) }); var properties = { paint: paint$1, layout: layout$2 }; var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; if (!Math.hypot) { Math.hypot = function () { var arguments$1 = arguments; var y = 0, i = arguments.length; while (i--) { y += arguments$1[i] * arguments$1[i]; } return Math.sqrt(y); }; } function create() { var out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; } out[0] = 1; out[3] = 1; return out; } function rotate(out, a, rad) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var s = Math.sin(rad); var c = Math.cos(rad); out[0] = a0 * c + a2 * s; out[1] = a1 * c + a3 * s; out[2] = a0 * -s + a2 * c; out[3] = a1 * -s + a3 * c; return out; } function create$1() { var out = new ARRAY_TYPE(9); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[5] = 0; out[6] = 0; out[7] = 0; } out[0] = 1; out[4] = 1; out[8] = 1; return out; } function fromRotation(out, rad) { var s = Math.sin(rad), c = Math.cos(rad); out[0] = c; out[1] = s; out[2] = 0; out[3] = -s; out[4] = c; out[5] = 0; out[6] = 0; out[7] = 0; out[8] = 1; return out; } function create$2() { var out = new ARRAY_TYPE(16); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; } out[0] = 1; out[5] = 1; out[10] = 1; out[15] = 1; return out; } function clone$1(a) { var out = new ARRAY_TYPE(16); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function invert(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; } function multiply(out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; return out; } function translate$1(out, a, v) { var x = v[0], y = v[1], z = v[2]; var a00, a01, a02, a03; var a10, a11, a12, a13; var a20, a21, a22, a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; } function scale(out, a, v) { var x = v[0], y = v[1], z = v[2]; out[0] = a[0] * x; out[1] = a[1] * x; out[2] = a[2] * x; out[3] = a[3] * x; out[4] = a[4] * y; out[5] = a[5] * y; out[6] = a[6] * y; out[7] = a[7] * y; out[8] = a[8] * z; out[9] = a[9] * z; out[10] = a[10] * z; out[11] = a[11] * z; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } function rotateX(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; var a20 = a[8]; var a21 = a[9]; var a22 = a[10]; var a23 = a[11]; if (a !== out) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } out[4] = a10 * c + a20 * s; out[5] = a11 * c + a21 * s; out[6] = a12 * c + a22 * s; out[7] = a13 * c + a23 * s; out[8] = a20 * c - a10 * s; out[9] = a21 * c - a11 * s; out[10] = a22 * c - a12 * s; out[11] = a23 * c - a13 * s; return out; } function rotateZ(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a03 = a[3]; var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; if (a !== out) { out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } out[0] = a00 * c + a10 * s; out[1] = a01 * c + a11 * s; out[2] = a02 * c + a12 * s; out[3] = a03 * c + a13 * s; out[4] = a10 * c - a00 * s; out[5] = a11 * c - a01 * s; out[6] = a12 * c - a02 * s; out[7] = a13 * c - a03 * s; return out; } function perspective(out, fovy, aspect, near, far) { var f = 1 / Math.tan(fovy / 2), nf; out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { nf = 1 / (near - far); out[10] = (far + near) * nf; out[14] = 2 * far * near * nf; } else { out[10] = -1; out[14] = -2 * near; } return out; } function ortho(out, left, right, bottom, top, near, far) { var lr = 1 / (left - right); var bt = 1 / (bottom - top); var nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; } var mul = multiply; function create$3() { var out = new ARRAY_TYPE(3); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } return out; } function clone$2(a) { var out = new ARRAY_TYPE(3); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; return out; } function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; return out; } function scale$1(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; return out; } function normalize(out, a) { var x = a[0]; var y = a[1]; var z = a[2]; var len = x * x + y * y + z * z; if (len > 0) { len = 1 / Math.sqrt(len); } out[0] = a[0] * len; out[1] = a[1] * len; out[2] = a[2] * len; return out; } function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function cross(out, a, b) { var ax = a[0], ay = a[1], az = a[2]; var bx = b[0], by = b[1], bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } function transformMat3(out, a, m) { var x = a[0], y = a[1], z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; } var sub = subtract; var forEach = function () { var vec = create$3(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 3; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; } return a; }; }(); function create$4() { var out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; } return out; } function scale$2(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; return out; } function dot$1(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; } function transformMat4(out, a, m) { var x = a[0], y = a[1], z = a[2], w = a[3]; out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; return out; } var forEach$1 = function () { var vec = create$4(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 4; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; vec[3] = a[i + 3]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; a[i + 3] = vec[3]; } return a; }; }(); function create$5() { var out = new ARRAY_TYPE(2); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; } return out; } function squaredLength(a) { var x = a[0], y = a[1]; return x * x + y * y; } var sqrLen = squaredLength; var forEach$2 = function () { var vec = create$5(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 2; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; } return a; }; }(); var CircleStyleLayer = function (StyleLayer) { function CircleStyleLayer(layer) { StyleLayer.call(this, layer, properties); } if (StyleLayer) CircleStyleLayer.__proto__ = StyleLayer; CircleStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); CircleStyleLayer.prototype.constructor = CircleStyleLayer; CircleStyleLayer.prototype.createBucket = function createBucket(parameters) { return new CircleBucket(parameters); }; CircleStyleLayer.prototype.queryRadius = function queryRadius(bucket) { var circleBucket = bucket; return getMaximumPaintValue('circle-radius', this, circleBucket) + getMaximumPaintValue('circle-stroke-width', this, circleBucket) + translateDistance(this.paint.get('circle-translate')); }; CircleStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits, pixelPosMatrix) { var translatedPolygon = translate(queryGeometry, this.paint.get('circle-translate'), this.paint.get('circle-translate-anchor'), transform.angle, pixelsToTileUnits); var radius = this.paint.get('circle-radius').evaluate(feature, featureState); var stroke = this.paint.get('circle-stroke-width').evaluate(feature, featureState); var size = radius + stroke; var alignWithMap = this.paint.get('circle-pitch-alignment') === 'map'; var transformedPolygon = alignWithMap ? translatedPolygon : projectQueryGeometry(translatedPolygon, pixelPosMatrix); var transformedSize = alignWithMap ? size * pixelsToTileUnits : size; for (var i$1 = 0, list$1 = geometry; i$1 < list$1.length; i$1 += 1) { var ring = list$1[i$1]; for (var i = 0, list = ring; i < list.length; i += 1) { var point = list[i]; var transformedPoint = alignWithMap ? point : projectPoint(point, pixelPosMatrix); var adjustedSize = transformedSize; var projectedCenter = transformMat4([], [ point.x, point.y, 0, 1 ], pixelPosMatrix); if (this.paint.get('circle-pitch-scale') === 'viewport' && this.paint.get('circle-pitch-alignment') === 'map') { adjustedSize *= projectedCenter[3] / transform.cameraToCenterDistance; } else if (this.paint.get('circle-pitch-scale') === 'map' && this.paint.get('circle-pitch-alignment') === 'viewport') { adjustedSize *= transform.cameraToCenterDistance / projectedCenter[3]; } if (polygonIntersectsBufferedPoint(transformedPolygon, transformedPoint, adjustedSize)) { return true; } } } return false; }; return CircleStyleLayer; }(StyleLayer); function projectPoint(p, pixelPosMatrix) { var point = transformMat4([], [ p.x, p.y, 0, 1 ], pixelPosMatrix); return new pointGeometry(point[0] / point[3], point[1] / point[3]); } function projectQueryGeometry(queryGeometry, pixelPosMatrix) { return queryGeometry.map(function (p) { return projectPoint(p, pixelPosMatrix); }); } var HeatmapBucket = function (CircleBucket) { function HeatmapBucket() { CircleBucket.apply(this, arguments); } if (CircleBucket) HeatmapBucket.__proto__ = CircleBucket; HeatmapBucket.prototype = Object.create(CircleBucket && CircleBucket.prototype); HeatmapBucket.prototype.constructor = HeatmapBucket; return HeatmapBucket; }(CircleBucket); register('HeatmapBucket', HeatmapBucket, { omit: ['layers'] }); function createImage(image, ref, channels, data) { var width = ref.width; var height = ref.height; if (!data) { data = new Uint8Array(width * height * channels); } else if (data instanceof Uint8ClampedArray) { data = new Uint8Array(data.buffer); } else if (data.length !== width * height * channels) { throw new RangeError('mismatched image size'); } image.width = width; image.height = height; image.data = data; return image; } function resizeImage(image, ref, channels) { var width = ref.width; var height = ref.height; if (width === image.width && height === image.height) { return; } var newImage = createImage({}, { width: width, height: height }, channels); copyImage(image, newImage, { x: 0, y: 0 }, { x: 0, y: 0 }, { width: Math.min(image.width, width), height: Math.min(image.height, height) }, channels); image.width = width; image.height = height; image.data = newImage.data; } function copyImage(srcImg, dstImg, srcPt, dstPt, size, channels) { if (size.width === 0 || size.height === 0) { return dstImg; } if (size.width > srcImg.width || size.height > srcImg.height || srcPt.x > srcImg.width - size.width || srcPt.y > srcImg.height - size.height) { throw new RangeError('out of range source coordinates for image copy'); } if (size.width > dstImg.width || size.height > dstImg.height || dstPt.x > dstImg.width - size.width || dstPt.y > dstImg.height - size.height) { throw new RangeError('out of range destination coordinates for image copy'); } var srcData = srcImg.data; var dstData = dstImg.data; for (var y = 0; y < size.height; y++) { var srcOffset = ((srcPt.y + y) * srcImg.width + srcPt.x) * channels; var dstOffset = ((dstPt.y + y) * dstImg.width + dstPt.x) * channels; for (var i = 0; i < size.width * channels; i++) { dstData[dstOffset + i] = srcData[srcOffset + i]; } } return dstImg; } var AlphaImage = function AlphaImage(size, data) { createImage(this, size, 1, data); }; AlphaImage.prototype.resize = function resize(size) { resizeImage(this, size, 1); }; AlphaImage.prototype.clone = function clone() { return new AlphaImage({ width: this.width, height: this.height }, new Uint8Array(this.data)); }; AlphaImage.copy = function copy(srcImg, dstImg, srcPt, dstPt, size) { copyImage(srcImg, dstImg, srcPt, dstPt, size, 1); }; var RGBAImage = function RGBAImage(size, data) { createImage(this, size, 4, data); }; RGBAImage.prototype.resize = function resize(size) { resizeImage(this, size, 4); }; RGBAImage.prototype.replace = function replace(data, copy) { if (copy) { this.data.set(data); } else if (data instanceof Uint8ClampedArray) { this.data = new Uint8Array(data.buffer); } else { this.data = data; } }; RGBAImage.prototype.clone = function clone() { return new RGBAImage({ width: this.width, height: this.height }, new Uint8Array(this.data)); }; RGBAImage.copy = function copy(srcImg, dstImg, srcPt, dstPt, size) { copyImage(srcImg, dstImg, srcPt, dstPt, size, 4); }; register('AlphaImage', AlphaImage); register('RGBAImage', RGBAImage); var paint$2 = new Properties({ 'heatmap-radius': new DataDrivenProperty(spec['paint_heatmap']['heatmap-radius']), 'heatmap-weight': new DataDrivenProperty(spec['paint_heatmap']['heatmap-weight']), 'heatmap-intensity': new DataConstantProperty(spec['paint_heatmap']['heatmap-intensity']), 'heatmap-color': new ColorRampProperty(spec['paint_heatmap']['heatmap-color']), 'heatmap-opacity': new DataConstantProperty(spec['paint_heatmap']['heatmap-opacity']) }); var properties$1 = { paint: paint$2 }; function renderColorRamp(params) { var evaluationGlobals = {}; var width = params.resolution || 256; var height = params.clips ? params.clips.length : 1; var image = params.image || new RGBAImage({ width: width, height: height }); var renderPixel = function (stride, index, progress) { evaluationGlobals[params.evaluationKey] = progress; var pxColor = params.expression.evaluate(evaluationGlobals); image.data[stride + index + 0] = Math.floor(pxColor.r * 255 / pxColor.a); image.data[stride + index + 1] = Math.floor(pxColor.g * 255 / pxColor.a); image.data[stride + index + 2] = Math.floor(pxColor.b * 255 / pxColor.a); image.data[stride + index + 3] = Math.floor(pxColor.a * 255); }; if (!params.clips) { for (var i = 0, j = 0; i < width; i++, j += 4) { var progress = i / (width - 1); renderPixel(0, j, progress); } } else { for (var clip = 0, stride = 0; clip < height; ++clip, stride += width * 4) { for (var i$1 = 0, j$1 = 0; i$1 < width; i$1++, j$1 += 4) { var progress$1 = i$1 / (width - 1); var ref = params.clips[clip]; var start = ref.start; var end = ref.end; var evaluationProgress = start * (1 - progress$1) + end * progress$1; renderPixel(stride, j$1, evaluationProgress); } } } return image; } var HeatmapStyleLayer = function (StyleLayer) { function HeatmapStyleLayer(layer) { StyleLayer.call(this, layer, properties$1); this._updateColorRamp(); } if (StyleLayer) HeatmapStyleLayer.__proto__ = StyleLayer; HeatmapStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); HeatmapStyleLayer.prototype.constructor = HeatmapStyleLayer; HeatmapStyleLayer.prototype.createBucket = function createBucket(options) { return new HeatmapBucket(options); }; HeatmapStyleLayer.prototype._handleSpecialPaintPropertyUpdate = function _handleSpecialPaintPropertyUpdate(name) { if (name === 'heatmap-color') { this._updateColorRamp(); } }; HeatmapStyleLayer.prototype._updateColorRamp = function _updateColorRamp() { var expression = this._transitionablePaint._values['heatmap-color'].value.expression; this.colorRamp = renderColorRamp({ expression: expression, evaluationKey: 'heatmapDensity', image: this.colorRamp }); this.colorRampTexture = null; }; HeatmapStyleLayer.prototype.resize = function resize() { if (this.heatmapFbo) { this.heatmapFbo.destroy(); this.heatmapFbo = null; } }; HeatmapStyleLayer.prototype.queryRadius = function queryRadius() { return 0; }; HeatmapStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature() { return false; }; HeatmapStyleLayer.prototype.hasOffscreenPass = function hasOffscreenPass() { return this.paint.get('heatmap-opacity') !== 0 && this.visibility !== 'none'; }; return HeatmapStyleLayer; }(StyleLayer); var paint$3 = new Properties({ 'hillshade-illumination-direction': new DataConstantProperty(spec['paint_hillshade']['hillshade-illumination-direction']), 'hillshade-illumination-anchor': new DataConstantProperty(spec['paint_hillshade']['hillshade-illumination-anchor']), 'hillshade-exaggeration': new DataConstantProperty(spec['paint_hillshade']['hillshade-exaggeration']), 'hillshade-shadow-color': new DataConstantProperty(spec['paint_hillshade']['hillshade-shadow-color']), 'hillshade-highlight-color': new DataConstantProperty(spec['paint_hillshade']['hillshade-highlight-color']), 'hillshade-accent-color': new DataConstantProperty(spec['paint_hillshade']['hillshade-accent-color']) }); var properties$2 = { paint: paint$3 }; var HillshadeStyleLayer = function (StyleLayer) { function HillshadeStyleLayer(layer) { StyleLayer.call(this, layer, properties$2); } if (StyleLayer) HillshadeStyleLayer.__proto__ = StyleLayer; HillshadeStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); HillshadeStyleLayer.prototype.constructor = HillshadeStyleLayer; HillshadeStyleLayer.prototype.hasOffscreenPass = function hasOffscreenPass() { return this.paint.get('hillshade-exaggeration') !== 0 && this.visibility !== 'none'; }; return HillshadeStyleLayer; }(StyleLayer); var layout$3 = createLayout([{ name: 'a_pos', components: 2, type: 'Int16' }], 4); var members$1 = layout$3.members; var earcut_1 = earcut; var default_1 = earcut; function earcut(data, holeIndices, dim) { dim = dim || 2; var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = []; if (!outerNode || outerNode.next === outerNode.prev) { return triangles; } var minX, minY, maxX, maxY, x, y, invSize; if (hasHoles) { outerNode = eliminateHoles(data, holeIndices, outerNode, dim); } if (data.length > 80 * dim) { minX = maxX = data[0]; minY = maxY = data[1]; for (var i = dim; i < outerLen; i += dim) { x = data[i]; y = data[i + 1]; if (x < minX) { minX = x; } if (y < minY) { minY = y; } if (x > maxX) { maxX = x; } if (y > maxY) { maxY = y; } } invSize = Math.max(maxX - minX, maxY - minY); invSize = invSize !== 0 ? 1 / invSize : 0; } earcutLinked(outerNode, triangles, dim, minX, minY, invSize); return triangles; } function linkedList(data, start, end, dim, clockwise) { var i, last; if (clockwise === signedArea(data, start, end, dim) > 0) { for (i = start; i < end; i += dim) { last = insertNode(i, data[i], data[i + 1], last); } } else { for (i = end - dim; i >= start; i -= dim) { last = insertNode(i, data[i], data[i + 1], last); } } if (last && equals(last, last.next)) { removeNode(last); last = last.next; } return last; } function filterPoints(start, end) { if (!start) { return start; } if (!end) { end = start; } var p = start, again; do { again = false; if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { removeNode(p); p = end = p.prev; if (p === p.next) { break; } again = true; } else { p = p.next; } } while (again || p !== end); return end; } function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { if (!ear) { return; } if (!pass && invSize) { indexCurve(ear, minX, minY, invSize); } var stop = ear, prev, next; while (ear.prev !== ear.next) { prev = ear.prev; next = ear.next; if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { triangles.push(prev.i / dim); triangles.push(ear.i / dim); triangles.push(next.i / dim); removeNode(ear); ear = next.next; stop = next.next; continue; } ear = next; if (ear === stop) { if (!pass) { earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); } else if (pass === 1) { ear = cureLocalIntersections(filterPoints(ear), triangles, dim); earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); } else if (pass === 2) { splitEarcut(ear, triangles, dim, minX, minY, invSize); } break; } } } function isEar(ear) { var a = ear.prev, b = ear, c = ear.next; if (area(a, b, c) >= 0) { return false; } var p = ear.next.next; while (p !== ear.prev) { if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) { return false; } p = p.next; } return true; } function isEarHashed(ear, minX, minY, invSize) { var a = ear.prev, b = ear, c = ear.next; if (area(a, b, c) >= 0) { return false; } var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x, minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y, maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x, maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; var minZ = zOrder(minTX, minTY, minX, minY, invSize), maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); var p = ear.prevZ, n = ear.nextZ; while (p && p.z >= minZ && n && n.z <= maxZ) { if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) { return false; } p = p.prevZ; if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) { return false; } n = n.nextZ; } while (p && p.z >= minZ) { if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) { return false; } p = p.prevZ; } while (n && n.z <= maxZ) { if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) { return false; } n = n.nextZ; } return true; } function cureLocalIntersections(start, triangles, dim) { var p = start; do { var a = p.prev, b = p.next.next; if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { triangles.push(a.i / dim); triangles.push(p.i / dim); triangles.push(b.i / dim); removeNode(p); removeNode(p.next); p = start = b; } p = p.next; } while (p !== start); return filterPoints(p); } function splitEarcut(start, triangles, dim, minX, minY, invSize) { var a = start; do { var b = a.next.next; while (b !== a.prev) { if (a.i !== b.i && isValidDiagonal(a, b)) { var c = splitPolygon(a, b); a = filterPoints(a, a.next); c = filterPoints(c, c.next); earcutLinked(a, triangles, dim, minX, minY, invSize); earcutLinked(c, triangles, dim, minX, minY, invSize); return; } b = b.next; } a = a.next; } while (a !== start); } function eliminateHoles(data, holeIndices, outerNode, dim) { var queue = [], i, len, start, end, list; for (i = 0, len = holeIndices.length; i < len; i++) { start = holeIndices[i] * dim; end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; list = linkedList(data, start, end, dim, false); if (list === list.next) { list.steiner = true; } queue.push(getLeftmost(list)); } queue.sort(compareX); for (i = 0; i < queue.length; i++) { eliminateHole(queue[i], outerNode); outerNode = filterPoints(outerNode, outerNode.next); } return outerNode; } function compareX(a, b) { return a.x - b.x; } function eliminateHole(hole, outerNode) { outerNode = findHoleBridge(hole, outerNode); if (outerNode) { var b = splitPolygon(outerNode, hole); filterPoints(outerNode, outerNode.next); filterPoints(b, b.next); } } function findHoleBridge(hole, outerNode) { var p = outerNode, hx = hole.x, hy = hole.y, qx = -Infinity, m; do { if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); if (x <= hx && x > qx) { qx = x; if (x === hx) { if (hy === p.y) { return p; } if (hy === p.next.y) { return p.next; } } m = p.x < p.next.x ? p : p.next; } } p = p.next; } while (p !== outerNode); if (!m) { return null; } if (hx === qx) { return m; } var stop = m, mx = m.x, my = m.y, tanMin = Infinity, tan; p = m; do { if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { tan = Math.abs(hy - p.y) / (hx - p.x); if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) { m = p; tanMin = tan; } } p = p.next; } while (p !== stop); return m; } function sectorContainsSector(m, p) { return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; } function indexCurve(start, minX, minY, invSize) { var p = start; do { if (p.z === null) { p.z = zOrder(p.x, p.y, minX, minY, invSize); } p.prevZ = p.prev; p.nextZ = p.next; p = p.next; } while (p !== start); p.prevZ.nextZ = null; p.prevZ = null; sortLinked(p); } function sortLinked(list) { var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; do { p = list; list = null; tail = null; numMerges = 0; while (p) { numMerges++; q = p; pSize = 0; for (i = 0; i < inSize; i++) { pSize++; q = q.nextZ; if (!q) { break; } } qSize = inSize; while (pSize > 0 || qSize > 0 && q) { if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { e = p; p = p.nextZ; pSize--; } else { e = q; q = q.nextZ; qSize--; } if (tail) { tail.nextZ = e; } else { list = e; } e.prevZ = tail; tail = e; } p = q; } tail.nextZ = null; inSize *= 2; } while (numMerges > 1); return list; } function zOrder(x, y, minX, minY, invSize) { x = 32767 * (x - minX) * invSize; y = 32767 * (y - minY) * invSize; x = (x | x << 8) & 16711935; x = (x | x << 4) & 252645135; x = (x | x << 2) & 858993459; x = (x | x << 1) & 1431655765; y = (y | y << 8) & 16711935; y = (y | y << 4) & 252645135; y = (y | y << 2) & 858993459; y = (y | y << 1) & 1431655765; return x | y << 1; } function getLeftmost(start) { var p = start, leftmost = start; do { if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) { leftmost = p; } p = p.next; } while (p !== start); return leftmost; } function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; } function isValidDiagonal(a, b) { return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && (area(a.prev, a, b.prev) || area(a, b.prev, b)) || equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); } function area(p, q, r) { return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); } function equals(p1, p2) { return p1.x === p2.x && p1.y === p2.y; } function intersects(p1, q1, p2, q2) { var o1 = sign(area(p1, q1, p2)); var o2 = sign(area(p1, q1, q2)); var o3 = sign(area(p2, q2, p1)); var o4 = sign(area(p2, q2, q1)); if (o1 !== o2 && o3 !== o4) { return true; } if (o1 === 0 && onSegment(p1, p2, q1)) { return true; } if (o2 === 0 && onSegment(p1, q2, q1)) { return true; } if (o3 === 0 && onSegment(p2, p1, q2)) { return true; } if (o4 === 0 && onSegment(p2, q1, q2)) { return true; } return false; } function onSegment(p, q, r) { return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); } function sign(num) { return num > 0 ? 1 : num < 0 ? -1 : 0; } function intersectsPolygon(a, b) { var p = a; do { if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) { return true; } p = p.next; } while (p !== a); return false; } function locallyInside(a, b) { return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; } function middleInside(a, b) { var p = a, inside = false, px = (a.x + b.x) / 2, py = (a.y + b.y) / 2; do { if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) { inside = !inside; } p = p.next; } while (p !== a); return inside; } function splitPolygon(a, b) { var a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev; a.next = b; b.prev = a; a2.next = an; an.prev = a2; b2.next = a2; a2.prev = b2; bp.next = b2; b2.prev = bp; return b2; } function insertNode(i, x, y, last) { var p = new Node(i, x, y); if (!last) { p.prev = p; p.next = p; } else { p.next = last.next; p.prev = last; last.next.prev = p; last.next = p; } return p; } function removeNode(p) { p.next.prev = p.prev; p.prev.next = p.next; if (p.prevZ) { p.prevZ.nextZ = p.nextZ; } if (p.nextZ) { p.nextZ.prevZ = p.prevZ; } } function Node(i, x, y) { this.i = i; this.x = x; this.y = y; this.prev = null; this.next = null; this.z = null; this.prevZ = null; this.nextZ = null; this.steiner = false; } earcut.deviation = function (data, holeIndices, dim, triangles) { var hasHoles = holeIndices && holeIndices.length; var outerLen = hasHoles ? holeIndices[0] * dim : data.length; var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); if (hasHoles) { for (var i = 0, len = holeIndices.length; i < len; i++) { var start = holeIndices[i] * dim; var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; polygonArea -= Math.abs(signedArea(data, start, end, dim)); } } var trianglesArea = 0; for (i = 0; i < triangles.length; i += 3) { var a = triangles[i] * dim; var b = triangles[i + 1] * dim; var c = triangles[i + 2] * dim; trianglesArea += Math.abs((data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1])); } return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea); }; function signedArea(data, start, end, dim) { var sum = 0; for (var i = start, j = end - dim; i < end; i += dim) { sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); j = i; } return sum; } earcut.flatten = function (data) { var dim = data[0][0].length, result = { vertices: [], holes: [], dimensions: dim }, holeIndex = 0; for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].length; j++) { for (var d = 0; d < dim; d++) { result.vertices.push(data[i][j][d]); } } if (i > 0) { holeIndex += data[i - 1].length; result.holes.push(holeIndex); } } return result; }; earcut_1.default = default_1; function quickselect(arr, k, left, right, compare) { quickselectStep(arr, k, left || 0, right || arr.length - 1, compare || defaultCompare); } function quickselectStep(arr, k, left, right, compare) { while (right > left) { if (right - left > 600) { var n = right - left + 1; var m = k - left + 1; var z = Math.log(n); var s = 0.5 * Math.exp(2 * z / 3); var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); quickselectStep(arr, k, newLeft, newRight, compare); } var t = arr[k]; var i = left; var j = right; swap$1(arr, left, k); if (compare(arr[right], t) > 0) { swap$1(arr, left, right); } while (i < j) { swap$1(arr, i, j); i++; j--; while (compare(arr[i], t) < 0) { i++; } while (compare(arr[j], t) > 0) { j--; } } if (compare(arr[left], t) === 0) { swap$1(arr, left, j); } else { j++; swap$1(arr, j, right); } if (j <= k) { left = j + 1; } if (k <= j) { right = j - 1; } } } function swap$1(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } function defaultCompare(a, b) { return a < b ? -1 : a > b ? 1 : 0; } function classifyRings(rings, maxRings) { var len = rings.length; if (len <= 1) { return [rings]; } var polygons = []; var polygon, ccw; for (var i = 0; i < len; i++) { var area = calculateSignedArea(rings[i]); if (area === 0) { continue; } rings[i].area = Math.abs(area); if (ccw === undefined) { ccw = area < 0; } if (ccw === area < 0) { if (polygon) { polygons.push(polygon); } polygon = [rings[i]]; } else { polygon.push(rings[i]); } } if (polygon) { polygons.push(polygon); } if (maxRings > 1) { for (var j = 0; j < polygons.length; j++) { if (polygons[j].length <= maxRings) { continue; } quickselect(polygons[j], maxRings, 1, polygons[j].length - 1, compareAreas); polygons[j] = polygons[j].slice(0, maxRings); } } return polygons; } function compareAreas(a, b) { return b.area - a.area; } function hasPattern(type, layers, options) { var patterns = options.patternDependencies; var hasPattern = false; for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; var patternProperty = layer.paint.get(type + '-pattern'); if (!patternProperty.isConstant()) { hasPattern = true; } var constantPattern = patternProperty.constantOr(null); if (constantPattern) { hasPattern = true; patterns[constantPattern.to] = true; patterns[constantPattern.from] = true; } } return hasPattern; } function addPatternDependencies(type, layers, patternFeature, zoom, options) { var patterns = options.patternDependencies; for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; var patternProperty = layer.paint.get(type + '-pattern'); var patternPropertyValue = patternProperty.value; if (patternPropertyValue.kind !== 'constant') { var min = patternPropertyValue.evaluate({ zoom: zoom - 1 }, patternFeature, {}, options.availableImages); var mid = patternPropertyValue.evaluate({ zoom: zoom }, patternFeature, {}, options.availableImages); var max = patternPropertyValue.evaluate({ zoom: zoom + 1 }, patternFeature, {}, options.availableImages); min = min && min.name ? min.name : min; mid = mid && mid.name ? mid.name : mid; max = max && max.name ? max.name : max; patterns[min] = true; patterns[mid] = true; patterns[max] = true; patternFeature.patterns[layer.id] = { min: min, mid: mid, max: max }; } } return patternFeature; } var EARCUT_MAX_RINGS = 500; var FillBucket = function FillBucket(options) { this.zoom = options.zoom; this.overscaling = options.overscaling; this.layers = options.layers; this.layerIds = this.layers.map(function (layer) { return layer.id; }); this.index = options.index; this.hasPattern = false; this.patternFeatures = []; this.layoutVertexArray = new StructArrayLayout2i4(); this.indexArray = new StructArrayLayout3ui6(); this.indexArray2 = new StructArrayLayout2ui4(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.segments2 = new SegmentVector(); this.stateDependentLayerIds = this.layers.filter(function (l) { return l.isStateDependent(); }).map(function (l) { return l.id; }); }; FillBucket.prototype.populate = function populate(features, options, canonical) { this.hasPattern = hasPattern('fill', this.layers, options); var fillSortKey = this.layers[0].layout.get('fill-sort-key'); var bucketFeatures = []; for (var i = 0, list = features; i < list.length; i += 1) { var ref = list[i]; var feature = ref.feature; var id = ref.id; var index = ref.index; var sourceLayerIndex = ref.sourceLayerIndex; var needGeometry = this.layers[0]._featureFilter.needGeometry; var evaluationFeature = toEvaluationFeature(feature, needGeometry); if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) { continue; } var sortKey = fillSortKey ? fillSortKey.evaluate(evaluationFeature, {}, canonical, options.availableImages) : undefined; var bucketFeature = { id: id, properties: feature.properties, type: feature.type, sourceLayerIndex: sourceLayerIndex, index: index, geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature), patterns: {}, sortKey: sortKey }; bucketFeatures.push(bucketFeature); } if (fillSortKey) { bucketFeatures.sort(function (a, b) { return a.sortKey - b.sortKey; }); } for (var i$1 = 0, list$1 = bucketFeatures; i$1 < list$1.length; i$1 += 1) { var bucketFeature$1 = list$1[i$1]; var ref$1 = bucketFeature$1; var geometry = ref$1.geometry; var index$1 = ref$1.index; var sourceLayerIndex$1 = ref$1.sourceLayerIndex; if (this.hasPattern) { var patternFeature = addPatternDependencies('fill', this.layers, bucketFeature$1, this.zoom, options); this.patternFeatures.push(patternFeature); } else { this.addFeature(bucketFeature$1, geometry, index$1, canonical, {}); } var feature$1 = features[index$1].feature; options.featureIndex.insert(feature$1, geometry, index$1, sourceLayerIndex$1, this.index); } }; FillBucket.prototype.update = function update(states, vtLayer, imagePositions) { if (!this.stateDependentLayers.length) { return; } this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions); }; FillBucket.prototype.addFeatures = function addFeatures(options, canonical, imagePositions) { for (var i = 0, list = this.patternFeatures; i < list.length; i += 1) { var feature = list[i]; this.addFeature(feature, feature.geometry, feature.index, canonical, imagePositions); } }; FillBucket.prototype.isEmpty = function isEmpty() { return this.layoutVertexArray.length === 0; }; FillBucket.prototype.uploadPending = function uploadPending() { return !this.uploaded || this.programConfigurations.needsUpload; }; FillBucket.prototype.upload = function upload(context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$1); this.indexBuffer = context.createIndexBuffer(this.indexArray); this.indexBuffer2 = context.createIndexBuffer(this.indexArray2); } this.programConfigurations.upload(context); this.uploaded = true; }; FillBucket.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.indexBuffer2.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); this.segments2.destroy(); }; FillBucket.prototype.addFeature = function addFeature(feature, geometry, index, canonical, imagePositions) { for (var i$4 = 0, list$2 = classifyRings(geometry, EARCUT_MAX_RINGS); i$4 < list$2.length; i$4 += 1) { var polygon = list$2[i$4]; var numVertices = 0; for (var i$2 = 0, list = polygon; i$2 < list.length; i$2 += 1) { var ring = list[i$2]; numVertices += ring.length; } var triangleSegment = this.segments.prepareSegment(numVertices, this.layoutVertexArray, this.indexArray); var triangleIndex = triangleSegment.vertexLength; var flattened = []; var holeIndices = []; for (var i$3 = 0, list$1 = polygon; i$3 < list$1.length; i$3 += 1) { var ring$1 = list$1[i$3]; if (ring$1.length === 0) { continue; } if (ring$1 !== polygon[0]) { holeIndices.push(flattened.length / 2); } var lineSegment = this.segments2.prepareSegment(ring$1.length, this.layoutVertexArray, this.indexArray2); var lineIndex = lineSegment.vertexLength; this.layoutVertexArray.emplaceBack(ring$1[0].x, ring$1[0].y); this.indexArray2.emplaceBack(lineIndex + ring$1.length - 1, lineIndex); flattened.push(ring$1[0].x); flattened.push(ring$1[0].y); for (var i = 1; i < ring$1.length; i++) { this.layoutVertexArray.emplaceBack(ring$1[i].x, ring$1[i].y); this.indexArray2.emplaceBack(lineIndex + i - 1, lineIndex + i); flattened.push(ring$1[i].x); flattened.push(ring$1[i].y); } lineSegment.vertexLength += ring$1.length; lineSegment.primitiveLength += ring$1.length; } var indices = earcut_1(flattened, holeIndices); for (var i$1 = 0; i$1 < indices.length; i$1 += 3) { this.indexArray.emplaceBack(triangleIndex + indices[i$1], triangleIndex + indices[i$1 + 1], triangleIndex + indices[i$1 + 2]); } triangleSegment.vertexLength += numVertices; triangleSegment.primitiveLength += indices.length / 3; } this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, canonical); }; register('FillBucket', FillBucket, { omit: [ 'layers', 'patternFeatures' ] }); var layout$4 = new Properties({ 'fill-sort-key': new DataDrivenProperty(spec['layout_fill']['fill-sort-key']) }); var paint$4 = new Properties({ 'fill-antialias': new DataConstantProperty(spec['paint_fill']['fill-antialias']), 'fill-opacity': new DataDrivenProperty(spec['paint_fill']['fill-opacity']), 'fill-color': new DataDrivenProperty(spec['paint_fill']['fill-color']), 'fill-outline-color': new DataDrivenProperty(spec['paint_fill']['fill-outline-color']), 'fill-translate': new DataConstantProperty(spec['paint_fill']['fill-translate']), 'fill-translate-anchor': new DataConstantProperty(spec['paint_fill']['fill-translate-anchor']), 'fill-pattern': new CrossFadedDataDrivenProperty(spec['paint_fill']['fill-pattern']) }); var properties$3 = { paint: paint$4, layout: layout$4 }; var FillStyleLayer = function (StyleLayer) { function FillStyleLayer(layer) { StyleLayer.call(this, layer, properties$3); } if (StyleLayer) FillStyleLayer.__proto__ = StyleLayer; FillStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); FillStyleLayer.prototype.constructor = FillStyleLayer; FillStyleLayer.prototype.recalculate = function recalculate(parameters, availableImages) { StyleLayer.prototype.recalculate.call(this, parameters, availableImages); var outlineColor = this.paint._values['fill-outline-color']; if (outlineColor.value.kind === 'constant' && outlineColor.value.value === undefined) { this.paint._values['fill-outline-color'] = this.paint._values['fill-color']; } }; FillStyleLayer.prototype.createBucket = function createBucket(parameters) { return new FillBucket(parameters); }; FillStyleLayer.prototype.queryRadius = function queryRadius() { return translateDistance(this.paint.get('fill-translate')); }; FillStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits) { var translatedPolygon = translate(queryGeometry, this.paint.get('fill-translate'), this.paint.get('fill-translate-anchor'), transform.angle, pixelsToTileUnits); return polygonIntersectsMultiPolygon(translatedPolygon, geometry); }; FillStyleLayer.prototype.isTileClipped = function isTileClipped() { return true; }; return FillStyleLayer; }(StyleLayer); var layout$5 = createLayout([ { name: 'a_pos', components: 2, type: 'Int16' }, { name: 'a_normal_ed', components: 4, type: 'Int16' } ], 4); var members$2 = layout$5.members; var vectortilefeature = VectorTileFeature; function VectorTileFeature(pbf, end, extent, keys, values) { this.properties = {}; this.extent = extent; this.type = 0; this._pbf = pbf; this._geometry = -1; this._keys = keys; this._values = values; pbf.readFields(readFeature, this, end); } function readFeature(tag, feature, pbf) { if (tag == 1) { feature.id = pbf.readVarint(); } else if (tag == 2) { readTag(pbf, feature); } else if (tag == 3) { feature.type = pbf.readVarint(); } else if (tag == 4) { feature._geometry = pbf.pos; } } function readTag(pbf, feature) { var end = pbf.readVarint() + pbf.pos; while (pbf.pos < end) { var key = feature._keys[pbf.readVarint()], value = feature._values[pbf.readVarint()]; feature.properties[key] = value; } } VectorTileFeature.types = [ 'Unknown', 'Point', 'LineString', 'Polygon' ]; VectorTileFeature.prototype.loadGeometry = function () { var pbf = this._pbf; pbf.pos = this._geometry; var end = pbf.readVarint() + pbf.pos, cmd = 1, length = 0, x = 0, y = 0, lines = [], line; while (pbf.pos < end) { if (length <= 0) { var cmdLen = pbf.readVarint(); cmd = cmdLen & 7; length = cmdLen >> 3; } length--; if (cmd === 1 || cmd === 2) { x += pbf.readSVarint(); y += pbf.readSVarint(); if (cmd === 1) { if (line) { lines.push(line); } line = []; } line.push(new pointGeometry(x, y)); } else if (cmd === 7) { if (line) { line.push(line[0].clone()); } } else { throw new Error('unknown command ' + cmd); } } if (line) { lines.push(line); } return lines; }; VectorTileFeature.prototype.bbox = function () { var pbf = this._pbf; pbf.pos = this._geometry; var end = pbf.readVarint() + pbf.pos, cmd = 1, length = 0, x = 0, y = 0, x1 = Infinity, x2 = -Infinity, y1 = Infinity, y2 = -Infinity; while (pbf.pos < end) { if (length <= 0) { var cmdLen = pbf.readVarint(); cmd = cmdLen & 7; length = cmdLen >> 3; } length--; if (cmd === 1 || cmd === 2) { x += pbf.readSVarint(); y += pbf.readSVarint(); if (x < x1) { x1 = x; } if (x > x2) { x2 = x; } if (y < y1) { y1 = y; } if (y > y2) { y2 = y; } } else if (cmd !== 7) { throw new Error('unknown command ' + cmd); } } return [ x1, y1, x2, y2 ]; }; VectorTileFeature.prototype.toGeoJSON = function (x, y, z) { var size = this.extent * Math.pow(2, z), x0 = this.extent * x, y0 = this.extent * y, coords = this.loadGeometry(), type = VectorTileFeature.types[this.type], i, j; function project(line) { for (var j = 0; j < line.length; j++) { var p = line[j], y2 = 180 - (p.y + y0) * 360 / size; line[j] = [ (p.x + x0) * 360 / size - 180, 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90 ]; } } switch (this.type) { case 1: var points = []; for (i = 0; i < coords.length; i++) { points[i] = coords[i][0]; } coords = points; project(coords); break; case 2: for (i = 0; i < coords.length; i++) { project(coords[i]); } break; case 3: coords = classifyRings$1(coords); for (i = 0; i < coords.length; i++) { for (j = 0; j < coords[i].length; j++) { project(coords[i][j]); } } break; } if (coords.length === 1) { coords = coords[0]; } else { type = 'Multi' + type; } var result = { type: 'Feature', geometry: { type: type, coordinates: coords }, properties: this.properties }; if ('id' in this) { result.id = this.id; } return result; }; function classifyRings$1(rings) { var len = rings.length; if (len <= 1) { return [rings]; } var polygons = [], polygon, ccw; for (var i = 0; i < len; i++) { var area = signedArea$1(rings[i]); if (area === 0) { continue; } if (ccw === undefined) { ccw = area < 0; } if (ccw === area < 0) { if (polygon) { polygons.push(polygon); } polygon = [rings[i]]; } else { polygon.push(rings[i]); } } if (polygon) { polygons.push(polygon); } return polygons; } function signedArea$1(ring) { var sum = 0; for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) { p1 = ring[i]; p2 = ring[j]; sum += (p2.x - p1.x) * (p1.y + p2.y); } return sum; } var vectortilelayer = VectorTileLayer; function VectorTileLayer(pbf, end) { this.version = 1; this.name = null; this.extent = 4096; this.length = 0; this._pbf = pbf; this._keys = []; this._values = []; this._features = []; pbf.readFields(readLayer, this, end); this.length = this._features.length; } function readLayer(tag, layer, pbf) { if (tag === 15) { layer.version = pbf.readVarint(); } else if (tag === 1) { layer.name = pbf.readString(); } else if (tag === 5) { layer.extent = pbf.readVarint(); } else if (tag === 2) { layer._features.push(pbf.pos); } else if (tag === 3) { layer._keys.push(pbf.readString()); } else if (tag === 4) { layer._values.push(readValueMessage(pbf)); } } function readValueMessage(pbf) { var value = null, end = pbf.readVarint() + pbf.pos; while (pbf.pos < end) { var tag = pbf.readVarint() >> 3; value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null; } return value; } VectorTileLayer.prototype.feature = function (i) { if (i < 0 || i >= this._features.length) { throw new Error('feature index out of bounds'); } this._pbf.pos = this._features[i]; var end = this._pbf.readVarint() + this._pbf.pos; return new vectortilefeature(this._pbf, end, this.extent, this._keys, this._values); }; var vectortile = VectorTile; function VectorTile(pbf, end) { this.layers = pbf.readFields(readTile, {}, end); } function readTile(tag, layers, pbf) { if (tag === 3) { var layer = new vectortilelayer(pbf, pbf.readVarint() + pbf.pos); if (layer.length) { layers[layer.name] = layer; } } } var VectorTile$1 = vectortile; var VectorTileFeature$1 = vectortilefeature; var VectorTileLayer$1 = vectortilelayer; var vectorTile = { VectorTile: VectorTile$1, VectorTileFeature: VectorTileFeature$1, VectorTileLayer: VectorTileLayer$1 }; var vectorTileFeatureTypes = vectorTile.VectorTileFeature.types; var EARCUT_MAX_RINGS$1 = 500; var FACTOR = Math.pow(2, 13); function addVertex(vertexArray, x, y, nx, ny, nz, t, e) { vertexArray.emplaceBack(x, y, Math.floor(nx * FACTOR) * 2 + t, ny * FACTOR * 2, nz * FACTOR * 2, Math.round(e)); } var FillExtrusionBucket = function FillExtrusionBucket(options) { this.zoom = options.zoom; this.overscaling = options.overscaling; this.layers = options.layers; this.layerIds = this.layers.map(function (layer) { return layer.id; }); this.index = options.index; this.hasPattern = false; this.layoutVertexArray = new StructArrayLayout2i4i12(); this.indexArray = new StructArrayLayout3ui6(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.stateDependentLayerIds = this.layers.filter(function (l) { return l.isStateDependent(); }).map(function (l) { return l.id; }); }; FillExtrusionBucket.prototype.populate = function populate(features, options, canonical) { this.features = []; this.hasPattern = hasPattern('fill-extrusion', this.layers, options); for (var i = 0, list = features; i < list.length; i += 1) { var ref = list[i]; var feature = ref.feature; var id = ref.id; var index = ref.index; var sourceLayerIndex = ref.sourceLayerIndex; var needGeometry = this.layers[0]._featureFilter.needGeometry; var evaluationFeature = toEvaluationFeature(feature, needGeometry); if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) { continue; } var bucketFeature = { id: id, sourceLayerIndex: sourceLayerIndex, index: index, geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature), properties: feature.properties, type: feature.type, patterns: {} }; if (this.hasPattern) { this.features.push(addPatternDependencies('fill-extrusion', this.layers, bucketFeature, this.zoom, options)); } else { this.addFeature(bucketFeature, bucketFeature.geometry, index, canonical, {}); } options.featureIndex.insert(feature, bucketFeature.geometry, index, sourceLayerIndex, this.index, true); } }; FillExtrusionBucket.prototype.addFeatures = function addFeatures(options, canonical, imagePositions) { for (var i = 0, list = this.features; i < list.length; i += 1) { var feature = list[i]; var geometry = feature.geometry; this.addFeature(feature, geometry, feature.index, canonical, imagePositions); } }; FillExtrusionBucket.prototype.update = function update(states, vtLayer, imagePositions) { if (!this.stateDependentLayers.length) { return; } this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions); }; FillExtrusionBucket.prototype.isEmpty = function isEmpty() { return this.layoutVertexArray.length === 0; }; FillExtrusionBucket.prototype.uploadPending = function uploadPending() { return !this.uploaded || this.programConfigurations.needsUpload; }; FillExtrusionBucket.prototype.upload = function upload(context) { if (!this.uploaded) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$2); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); this.uploaded = true; }; FillExtrusionBucket.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); }; FillExtrusionBucket.prototype.addFeature = function addFeature(feature, geometry, index, canonical, imagePositions) { for (var i$4 = 0, list$3 = classifyRings(geometry, EARCUT_MAX_RINGS$1); i$4 < list$3.length; i$4 += 1) { var polygon = list$3[i$4]; var numVertices = 0; for (var i$1 = 0, list = polygon; i$1 < list.length; i$1 += 1) { var ring = list[i$1]; numVertices += ring.length; } var segment = this.segments.prepareSegment(4, this.layoutVertexArray, this.indexArray); for (var i$2 = 0, list$1 = polygon; i$2 < list$1.length; i$2 += 1) { var ring$1 = list$1[i$2]; if (ring$1.length === 0) { continue; } if (isEntirelyOutside(ring$1)) { continue; } var edgeDistance = 0; for (var p = 0; p < ring$1.length; p++) { var p1 = ring$1[p]; if (p >= 1) { var p2 = ring$1[p - 1]; if (!isBoundaryEdge(p1, p2)) { if (segment.vertexLength + 4 > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) { segment = this.segments.prepareSegment(4, this.layoutVertexArray, this.indexArray); } var perp = p1.sub(p2)._perp()._unit(); var dist = p2.dist(p1); if (edgeDistance + dist > 32768) { edgeDistance = 0; } addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p1.x, p1.y, perp.x, perp.y, 0, 1, edgeDistance); edgeDistance += dist; addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 0, edgeDistance); addVertex(this.layoutVertexArray, p2.x, p2.y, perp.x, perp.y, 0, 1, edgeDistance); var bottomRight = segment.vertexLength; this.indexArray.emplaceBack(bottomRight, bottomRight + 2, bottomRight + 1); this.indexArray.emplaceBack(bottomRight + 1, bottomRight + 2, bottomRight + 3); segment.vertexLength += 4; segment.primitiveLength += 2; } } } } if (segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) { segment = this.segments.prepareSegment(numVertices, this.layoutVertexArray, this.indexArray); } if (vectorTileFeatureTypes[feature.type] !== 'Polygon') { continue; } var flattened = []; var holeIndices = []; var triangleIndex = segment.vertexLength; for (var i$3 = 0, list$2 = polygon; i$3 < list$2.length; i$3 += 1) { var ring$2 = list$2[i$3]; if (ring$2.length === 0) { continue; } if (ring$2 !== polygon[0]) { holeIndices.push(flattened.length / 2); } for (var i = 0; i < ring$2.length; i++) { var p$1 = ring$2[i]; addVertex(this.layoutVertexArray, p$1.x, p$1.y, 0, 0, 1, 1, 0); flattened.push(p$1.x); flattened.push(p$1.y); } } var indices = earcut_1(flattened, holeIndices); for (var j = 0; j < indices.length; j += 3) { this.indexArray.emplaceBack(triangleIndex + indices[j], triangleIndex + indices[j + 2], triangleIndex + indices[j + 1]); } segment.primitiveLength += indices.length / 3; segment.vertexLength += numVertices; } this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, canonical); }; register('FillExtrusionBucket', FillExtrusionBucket, { omit: [ 'layers', 'features' ] }); function isBoundaryEdge(p1, p2) { return p1.x === p2.x && (p1.x < 0 || p1.x > EXTENT$1) || p1.y === p2.y && (p1.y < 0 || p1.y > EXTENT$1); } function isEntirelyOutside(ring) { return ring.every(function (p) { return p.x < 0; }) || ring.every(function (p) { return p.x > EXTENT$1; }) || ring.every(function (p) { return p.y < 0; }) || ring.every(function (p) { return p.y > EXTENT$1; }); } var paint$5 = new Properties({ 'fill-extrusion-opacity': new DataConstantProperty(spec['paint_fill-extrusion']['fill-extrusion-opacity']), 'fill-extrusion-color': new DataDrivenProperty(spec['paint_fill-extrusion']['fill-extrusion-color']), 'fill-extrusion-translate': new DataConstantProperty(spec['paint_fill-extrusion']['fill-extrusion-translate']), 'fill-extrusion-translate-anchor': new DataConstantProperty(spec['paint_fill-extrusion']['fill-extrusion-translate-anchor']), 'fill-extrusion-pattern': new CrossFadedDataDrivenProperty(spec['paint_fill-extrusion']['fill-extrusion-pattern']), 'fill-extrusion-height': new DataDrivenProperty(spec['paint_fill-extrusion']['fill-extrusion-height']), 'fill-extrusion-base': new DataDrivenProperty(spec['paint_fill-extrusion']['fill-extrusion-base']), 'fill-extrusion-vertical-gradient': new DataConstantProperty(spec['paint_fill-extrusion']['fill-extrusion-vertical-gradient']) }); var properties$4 = { paint: paint$5 }; var FillExtrusionStyleLayer = function (StyleLayer) { function FillExtrusionStyleLayer(layer) { StyleLayer.call(this, layer, properties$4); } if (StyleLayer) FillExtrusionStyleLayer.__proto__ = StyleLayer; FillExtrusionStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); FillExtrusionStyleLayer.prototype.constructor = FillExtrusionStyleLayer; FillExtrusionStyleLayer.prototype.createBucket = function createBucket(parameters) { return new FillExtrusionBucket(parameters); }; FillExtrusionStyleLayer.prototype.queryRadius = function queryRadius() { return translateDistance(this.paint.get('fill-extrusion-translate')); }; FillExtrusionStyleLayer.prototype.is3D = function is3D() { return true; }; FillExtrusionStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits, pixelPosMatrix) { var translatedPolygon = translate(queryGeometry, this.paint.get('fill-extrusion-translate'), this.paint.get('fill-extrusion-translate-anchor'), transform.angle, pixelsToTileUnits); var height = this.paint.get('fill-extrusion-height').evaluate(feature, featureState); var base = this.paint.get('fill-extrusion-base').evaluate(feature, featureState); var projectedQueryGeometry = projectQueryGeometry$1(translatedPolygon, pixelPosMatrix, transform, 0); var projected = projectExtrusion(geometry, base, height, pixelPosMatrix); var projectedBase = projected[0]; var projectedTop = projected[1]; return checkIntersection(projectedBase, projectedTop, projectedQueryGeometry); }; return FillExtrusionStyleLayer; }(StyleLayer); function dot$2(a, b) { return a.x * b.x + a.y * b.y; } function getIntersectionDistance(projectedQueryGeometry, projectedFace) { if (projectedQueryGeometry.length === 1) { var i = 0; var a = projectedFace[i++]; var b; while (!b || a.equals(b)) { b = projectedFace[i++]; if (!b) { return Infinity; } } for (; i < projectedFace.length; i++) { var c = projectedFace[i]; var p = projectedQueryGeometry[0]; var ab = b.sub(a); var ac = c.sub(a); var ap = p.sub(a); var dotABAB = dot$2(ab, ab); var dotABAC = dot$2(ab, ac); var dotACAC = dot$2(ac, ac); var dotAPAB = dot$2(ap, ab); var dotAPAC = dot$2(ap, ac); var denom = dotABAB * dotACAC - dotABAC * dotABAC; var v = (dotACAC * dotAPAB - dotABAC * dotAPAC) / denom; var w = (dotABAB * dotAPAC - dotABAC * dotAPAB) / denom; var u = 1 - v - w; var distance = a.z * u + b.z * v + c.z * w; if (isFinite(distance)) { return distance; } } return Infinity; } else { var closestDistance = Infinity; for (var i$1 = 0, list = projectedFace; i$1 < list.length; i$1 += 1) { var p$1 = list[i$1]; closestDistance = Math.min(closestDistance, p$1.z); } return closestDistance; } } function checkIntersection(projectedBase, projectedTop, projectedQueryGeometry) { var closestDistance = Infinity; if (polygonIntersectsMultiPolygon(projectedQueryGeometry, projectedTop)) { closestDistance = getIntersectionDistance(projectedQueryGeometry, projectedTop[0]); } for (var r = 0; r < projectedTop.length; r++) { var ringTop = projectedTop[r]; var ringBase = projectedBase[r]; for (var p = 0; p < ringTop.length - 1; p++) { var topA = ringTop[p]; var topB = ringTop[p + 1]; var baseA = ringBase[p]; var baseB = ringBase[p + 1]; var face = [ topA, topB, baseB, baseA, topA ]; if (polygonIntersectsPolygon(projectedQueryGeometry, face)) { closestDistance = Math.min(closestDistance, getIntersectionDistance(projectedQueryGeometry, face)); } } } return closestDistance === Infinity ? false : closestDistance; } function projectExtrusion(geometry, zBase, zTop, m) { var projectedBase = []; var projectedTop = []; var baseXZ = m[8] * zBase; var baseYZ = m[9] * zBase; var baseZZ = m[10] * zBase; var baseWZ = m[11] * zBase; var topXZ = m[8] * zTop; var topYZ = m[9] * zTop; var topZZ = m[10] * zTop; var topWZ = m[11] * zTop; for (var i$1 = 0, list$1 = geometry; i$1 < list$1.length; i$1 += 1) { var r = list$1[i$1]; var ringBase = []; var ringTop = []; for (var i = 0, list = r; i < list.length; i += 1) { var p = list[i]; var x = p.x; var y = p.y; var sX = m[0] * x + m[4] * y + m[12]; var sY = m[1] * x + m[5] * y + m[13]; var sZ = m[2] * x + m[6] * y + m[14]; var sW = m[3] * x + m[7] * y + m[15]; var baseX = sX + baseXZ; var baseY = sY + baseYZ; var baseZ = sZ + baseZZ; var baseW = sW + baseWZ; var topX = sX + topXZ; var topY = sY + topYZ; var topZ = sZ + topZZ; var topW = sW + topWZ; var b = new pointGeometry(baseX / baseW, baseY / baseW); b.z = baseZ / baseW; ringBase.push(b); var t = new pointGeometry(topX / topW, topY / topW); t.z = topZ / topW; ringTop.push(t); } projectedBase.push(ringBase); projectedTop.push(ringTop); } return [ projectedBase, projectedTop ]; } function projectQueryGeometry$1(queryGeometry, pixelPosMatrix, transform, z) { var projectedQueryGeometry = []; for (var i = 0, list = queryGeometry; i < list.length; i += 1) { var p = list[i]; var v = [ p.x, p.y, z, 1 ]; transformMat4(v, v, pixelPosMatrix); projectedQueryGeometry.push(new pointGeometry(v[0] / v[3], v[1] / v[3])); } return projectedQueryGeometry; } var lineLayoutAttributes = createLayout([ { name: 'a_pos_normal', components: 2, type: 'Int16' }, { name: 'a_data', components: 4, type: 'Uint8' } ], 4); var members$3 = lineLayoutAttributes.members; var lineLayoutAttributesExt = createLayout([ { name: 'a_uv_x', components: 1, type: 'Float32' }, { name: 'a_split_index', components: 1, type: 'Float32' } ]); var members$4 = lineLayoutAttributesExt.members; var vectorTileFeatureTypes$1 = vectorTile.VectorTileFeature.types; var EXTRUDE_SCALE = 63; var COS_HALF_SHARP_CORNER = Math.cos(75 / 2 * (Math.PI / 180)); var SHARP_CORNER_OFFSET = 15; var DEG_PER_TRIANGLE = 20; var LINE_DISTANCE_BUFFER_BITS = 15; var LINE_DISTANCE_SCALE = 1 / 2; var MAX_LINE_DISTANCE = Math.pow(2, LINE_DISTANCE_BUFFER_BITS - 1) / LINE_DISTANCE_SCALE; var LineBucket = function LineBucket(options) { var this$1 = this; this.zoom = options.zoom; this.overscaling = options.overscaling; this.layers = options.layers; this.layerIds = this.layers.map(function (layer) { return layer.id; }); this.index = options.index; this.hasPattern = false; this.patternFeatures = []; this.lineClipsArray = []; this.gradients = {}; this.layers.forEach(function (layer) { this$1.gradients[layer.id] = {}; }); this.layoutVertexArray = new StructArrayLayout2i4ub8(); this.layoutVertexArray2 = new StructArrayLayout2f8(); this.indexArray = new StructArrayLayout3ui6(); this.programConfigurations = new ProgramConfigurationSet(options.layers, options.zoom); this.segments = new SegmentVector(); this.maxLineLength = 0; this.stateDependentLayerIds = this.layers.filter(function (l) { return l.isStateDependent(); }).map(function (l) { return l.id; }); }; LineBucket.prototype.populate = function populate(features, options, canonical) { this.hasPattern = hasPattern('line', this.layers, options); var lineSortKey = this.layers[0].layout.get('line-sort-key'); var bucketFeatures = []; for (var i = 0, list = features; i < list.length; i += 1) { var ref = list[i]; var feature = ref.feature; var id = ref.id; var index = ref.index; var sourceLayerIndex = ref.sourceLayerIndex; var needGeometry = this.layers[0]._featureFilter.needGeometry; var evaluationFeature = toEvaluationFeature(feature, needGeometry); if (!this.layers[0]._featureFilter.filter(new EvaluationParameters(this.zoom), evaluationFeature, canonical)) { continue; } var sortKey = lineSortKey ? lineSortKey.evaluate(evaluationFeature, {}, canonical) : undefined; var bucketFeature = { id: id, properties: feature.properties, type: feature.type, sourceLayerIndex: sourceLayerIndex, index: index, geometry: needGeometry ? evaluationFeature.geometry : loadGeometry(feature), patterns: {}, sortKey: sortKey }; bucketFeatures.push(bucketFeature); } if (lineSortKey) { bucketFeatures.sort(function (a, b) { return a.sortKey - b.sortKey; }); } for (var i$1 = 0, list$1 = bucketFeatures; i$1 < list$1.length; i$1 += 1) { var bucketFeature$1 = list$1[i$1]; var ref$1 = bucketFeature$1; var geometry = ref$1.geometry; var index$1 = ref$1.index; var sourceLayerIndex$1 = ref$1.sourceLayerIndex; if (this.hasPattern) { var patternBucketFeature = addPatternDependencies('line', this.layers, bucketFeature$1, this.zoom, options); this.patternFeatures.push(patternBucketFeature); } else { this.addFeature(bucketFeature$1, geometry, index$1, canonical, {}); } var feature$1 = features[index$1].feature; options.featureIndex.insert(feature$1, geometry, index$1, sourceLayerIndex$1, this.index); } }; LineBucket.prototype.update = function update(states, vtLayer, imagePositions) { if (!this.stateDependentLayers.length) { return; } this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions); }; LineBucket.prototype.addFeatures = function addFeatures(options, canonical, imagePositions) { for (var i = 0, list = this.patternFeatures; i < list.length; i += 1) { var feature = list[i]; this.addFeature(feature, feature.geometry, feature.index, canonical, imagePositions); } }; LineBucket.prototype.isEmpty = function isEmpty() { return this.layoutVertexArray.length === 0; }; LineBucket.prototype.uploadPending = function uploadPending() { return !this.uploaded || this.programConfigurations.needsUpload; }; LineBucket.prototype.upload = function upload(context) { if (!this.uploaded) { if (this.layoutVertexArray2.length !== 0) { this.layoutVertexBuffer2 = context.createVertexBuffer(this.layoutVertexArray2, members$4); } this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, members$3); this.indexBuffer = context.createIndexBuffer(this.indexArray); } this.programConfigurations.upload(context); this.uploaded = true; }; LineBucket.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); }; LineBucket.prototype.lineFeatureClips = function lineFeatureClips(feature) { if (!!feature.properties && feature.properties.hasOwnProperty('mapbox_clip_start') && feature.properties.hasOwnProperty('mapbox_clip_end')) { var start = +feature.properties['mapbox_clip_start']; var end = +feature.properties['mapbox_clip_end']; return { start: start, end: end }; } }; LineBucket.prototype.addFeature = function addFeature(feature, geometry, index, canonical, imagePositions) { var layout = this.layers[0].layout; var join = layout.get('line-join').evaluate(feature, {}); var cap = layout.get('line-cap'); var miterLimit = layout.get('line-miter-limit'); var roundLimit = layout.get('line-round-limit'); this.lineClips = this.lineFeatureClips(feature); for (var i = 0, list = geometry; i < list.length; i += 1) { var line = list[i]; this.addLine(line, feature, join, cap, miterLimit, roundLimit); } this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions, canonical); }; LineBucket.prototype.addLine = function addLine(vertices, feature, join, cap, miterLimit, roundLimit) { this.distance = 0; this.scaledDistance = 0; this.totalDistance = 0; if (this.lineClips) { this.lineClipsArray.push(this.lineClips); for (var i = 0; i < vertices.length - 1; i++) { this.totalDistance += vertices[i].dist(vertices[i + 1]); } this.updateScaledDistance(); this.maxLineLength = Math.max(this.maxLineLength, this.totalDistance); } var isPolygon = vectorTileFeatureTypes$1[feature.type] === 'Polygon'; var len = vertices.length; while (len >= 2 && vertices[len - 1].equals(vertices[len - 2])) { len--; } var first = 0; while (first < len - 1 && vertices[first].equals(vertices[first + 1])) { first++; } if (len < (isPolygon ? 3 : 2)) { return; } if (join === 'bevel') { miterLimit = 1.05; } var sharpCornerOffset = this.overscaling <= 16 ? SHARP_CORNER_OFFSET * EXTENT$1 / (512 * this.overscaling) : 0; var segment = this.segments.prepareSegment(len * 10, this.layoutVertexArray, this.indexArray); var currentVertex; var prevVertex = undefined; var nextVertex = undefined; var prevNormal = undefined; var nextNormal = undefined; this.e1 = this.e2 = -1; if (isPolygon) { currentVertex = vertices[len - 2]; nextNormal = vertices[first].sub(currentVertex)._unit()._perp(); } for (var i$1 = first; i$1 < len; i$1++) { nextVertex = i$1 === len - 1 ? isPolygon ? vertices[first + 1] : undefined : vertices[i$1 + 1]; if (nextVertex && vertices[i$1].equals(nextVertex)) { continue; } if (nextNormal) { prevNormal = nextNormal; } if (currentVertex) { prevVertex = currentVertex; } currentVertex = vertices[i$1]; nextNormal = nextVertex ? nextVertex.sub(currentVertex)._unit()._perp() : prevNormal; prevNormal = prevNormal || nextNormal; var joinNormal = prevNormal.add(nextNormal); if (joinNormal.x !== 0 || joinNormal.y !== 0) { joinNormal._unit(); } var cosAngle = prevNormal.x * nextNormal.x + prevNormal.y * nextNormal.y; var cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y; var miterLength = cosHalfAngle !== 0 ? 1 / cosHalfAngle : Infinity; var approxAngle = 2 * Math.sqrt(2 - 2 * cosHalfAngle); var isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex; var lineTurnsLeft = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0; if (isSharpCorner && i$1 > first) { var prevSegmentLength = currentVertex.dist(prevVertex); if (prevSegmentLength > 2 * sharpCornerOffset) { var newPrevVertex = currentVertex.sub(currentVertex.sub(prevVertex)._mult(sharpCornerOffset / prevSegmentLength)._round()); this.updateDistance(prevVertex, newPrevVertex); this.addCurrentVertex(newPrevVertex, prevNormal, 0, 0, segment); prevVertex = newPrevVertex; } } var middleVertex = prevVertex && nextVertex; var currentJoin = middleVertex ? join : isPolygon ? 'butt' : cap; if (middleVertex && currentJoin === 'round') { if (miterLength < roundLimit) { currentJoin = 'miter'; } else if (miterLength <= 2) { currentJoin = 'fakeround'; } } if (currentJoin === 'miter' && miterLength > miterLimit) { currentJoin = 'bevel'; } if (currentJoin === 'bevel') { if (miterLength > 2) { currentJoin = 'flipbevel'; } if (miterLength < miterLimit) { currentJoin = 'miter'; } } if (prevVertex) { this.updateDistance(prevVertex, currentVertex); } if (currentJoin === 'miter') { joinNormal._mult(miterLength); this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment); } else if (currentJoin === 'flipbevel') { if (miterLength > 100) { joinNormal = nextNormal.mult(-1); } else { var bevelLength = miterLength * prevNormal.add(nextNormal).mag() / prevNormal.sub(nextNormal).mag(); joinNormal._perp()._mult(bevelLength * (lineTurnsLeft ? -1 : 1)); } this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment); this.addCurrentVertex(currentVertex, joinNormal.mult(-1), 0, 0, segment); } else if (currentJoin === 'bevel' || currentJoin === 'fakeround') { var offset = -Math.sqrt(miterLength * miterLength - 1); var offsetA = lineTurnsLeft ? offset : 0; var offsetB = lineTurnsLeft ? 0 : offset; if (prevVertex) { this.addCurrentVertex(currentVertex, prevNormal, offsetA, offsetB, segment); } if (currentJoin === 'fakeround') { var n = Math.round(approxAngle * 180 / Math.PI / DEG_PER_TRIANGLE); for (var m = 1; m < n; m++) { var t = m / n; if (t !== 0.5) { var t2 = t - 0.5; var A = 1.0904 + cosAngle * (-3.2452 + cosAngle * (3.55645 - cosAngle * 1.43519)); var B = 0.848013 + cosAngle * (-1.06021 + cosAngle * 0.215638); t = t + t * t2 * (t - 1) * (A * t2 * t2 + B); } var extrude = nextNormal.sub(prevNormal)._mult(t)._add(prevNormal)._unit()._mult(lineTurnsLeft ? -1 : 1); this.addHalfVertex(currentVertex, extrude.x, extrude.y, false, lineTurnsLeft, 0, segment); } } if (nextVertex) { this.addCurrentVertex(currentVertex, nextNormal, -offsetA, -offsetB, segment); } } else if (currentJoin === 'butt') { this.addCurrentVertex(currentVertex, joinNormal, 0, 0, segment); } else if (currentJoin === 'square') { var offset$1 = prevVertex ? 1 : -1; this.addCurrentVertex(currentVertex, joinNormal, offset$1, offset$1, segment); } else if (currentJoin === 'round') { if (prevVertex) { this.addCurrentVertex(currentVertex, prevNormal, 0, 0, segment); this.addCurrentVertex(currentVertex, prevNormal, 1, 1, segment, true); } if (nextVertex) { this.addCurrentVertex(currentVertex, nextNormal, -1, -1, segment, true); this.addCurrentVertex(currentVertex, nextNormal, 0, 0, segment); } } if (isSharpCorner && i$1 < len - 1) { var nextSegmentLength = currentVertex.dist(nextVertex); if (nextSegmentLength > 2 * sharpCornerOffset) { var newCurrentVertex = currentVertex.add(nextVertex.sub(currentVertex)._mult(sharpCornerOffset / nextSegmentLength)._round()); this.updateDistance(currentVertex, newCurrentVertex); this.addCurrentVertex(newCurrentVertex, nextNormal, 0, 0, segment); currentVertex = newCurrentVertex; } } } }; LineBucket.prototype.addCurrentVertex = function addCurrentVertex(p, normal, endLeft, endRight, segment, round) { if (round === void 0) round = false; var leftX = normal.x + normal.y * endLeft; var leftY = normal.y - normal.x * endLeft; var rightX = -normal.x + normal.y * endRight; var rightY = -normal.y - normal.x * endRight; this.addHalfVertex(p, leftX, leftY, round, false, endLeft, segment); this.addHalfVertex(p, rightX, rightY, round, true, -endRight, segment); if (this.distance > MAX_LINE_DISTANCE / 2 && this.totalDistance === 0) { this.distance = 0; this.addCurrentVertex(p, normal, endLeft, endRight, segment, round); } }; LineBucket.prototype.addHalfVertex = function addHalfVertex(ref, extrudeX, extrudeY, round, up, dir, segment) { var x = ref.x; var y = ref.y; var totalDistance = this.lineClips ? this.scaledDistance * (MAX_LINE_DISTANCE - 1) : this.scaledDistance; var linesofarScaled = totalDistance * LINE_DISTANCE_SCALE; this.layoutVertexArray.emplaceBack((x << 1) + (round ? 1 : 0), (y << 1) + (up ? 1 : 0), Math.round(EXTRUDE_SCALE * extrudeX) + 128, Math.round(EXTRUDE_SCALE * extrudeY) + 128, (dir === 0 ? 0 : dir < 0 ? -1 : 1) + 1 | (linesofarScaled & 63) << 2, linesofarScaled >> 6); if (this.lineClips) { var progressRealigned = this.scaledDistance - this.lineClips.start; var endClipRealigned = this.lineClips.end - this.lineClips.start; var uvX = progressRealigned / endClipRealigned; this.layoutVertexArray2.emplaceBack(uvX, this.lineClipsArray.length); } var e = segment.vertexLength++; if (this.e1 >= 0 && this.e2 >= 0) { this.indexArray.emplaceBack(this.e1, this.e2, e); segment.primitiveLength++; } if (up) { this.e2 = e; } else { this.e1 = e; } }; LineBucket.prototype.updateScaledDistance = function updateScaledDistance() { this.scaledDistance = this.lineClips ? this.lineClips.start + (this.lineClips.end - this.lineClips.start) * this.distance / this.totalDistance : this.distance; }; LineBucket.prototype.updateDistance = function updateDistance(prev, next) { this.distance += prev.dist(next); this.updateScaledDistance(); }; register('LineBucket', LineBucket, { omit: [ 'layers', 'patternFeatures' ] }); var layout$6 = new Properties({ 'line-cap': new DataConstantProperty(spec['layout_line']['line-cap']), 'line-join': new DataDrivenProperty(spec['layout_line']['line-join']), 'line-miter-limit': new DataConstantProperty(spec['layout_line']['line-miter-limit']), 'line-round-limit': new DataConstantProperty(spec['layout_line']['line-round-limit']), 'line-sort-key': new DataDrivenProperty(spec['layout_line']['line-sort-key']) }); var paint$6 = new Properties({ 'line-opacity': new DataDrivenProperty(spec['paint_line']['line-opacity']), 'line-color': new DataDrivenProperty(spec['paint_line']['line-color']), 'line-translate': new DataConstantProperty(spec['paint_line']['line-translate']), 'line-translate-anchor': new DataConstantProperty(spec['paint_line']['line-translate-anchor']), 'line-width': new DataDrivenProperty(spec['paint_line']['line-width']), 'line-gap-width': new DataDrivenProperty(spec['paint_line']['line-gap-width']), 'line-offset': new DataDrivenProperty(spec['paint_line']['line-offset']), 'line-blur': new DataDrivenProperty(spec['paint_line']['line-blur']), 'line-dasharray': new CrossFadedProperty(spec['paint_line']['line-dasharray']), 'line-pattern': new CrossFadedDataDrivenProperty(spec['paint_line']['line-pattern']), 'line-gradient': new ColorRampProperty(spec['paint_line']['line-gradient']) }); var properties$5 = { paint: paint$6, layout: layout$6 }; var LineFloorwidthProperty = function (DataDrivenProperty) { function LineFloorwidthProperty() { DataDrivenProperty.apply(this, arguments); } if (DataDrivenProperty) LineFloorwidthProperty.__proto__ = DataDrivenProperty; LineFloorwidthProperty.prototype = Object.create(DataDrivenProperty && DataDrivenProperty.prototype); LineFloorwidthProperty.prototype.constructor = LineFloorwidthProperty; LineFloorwidthProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters) { parameters = new EvaluationParameters(Math.floor(parameters.zoom), { now: parameters.now, fadeDuration: parameters.fadeDuration, zoomHistory: parameters.zoomHistory, transition: parameters.transition }); return DataDrivenProperty.prototype.possiblyEvaluate.call(this, value, parameters); }; LineFloorwidthProperty.prototype.evaluate = function evaluate(value, globals, feature, featureState) { globals = extend({}, globals, { zoom: Math.floor(globals.zoom) }); return DataDrivenProperty.prototype.evaluate.call(this, value, globals, feature, featureState); }; return LineFloorwidthProperty; }(DataDrivenProperty); var lineFloorwidthProperty = new LineFloorwidthProperty(properties$5.paint.properties['line-width'].specification); lineFloorwidthProperty.useIntegerZoom = true; var LineStyleLayer = function (StyleLayer) { function LineStyleLayer(layer) { StyleLayer.call(this, layer, properties$5); this.gradientVersion = 0; } if (StyleLayer) LineStyleLayer.__proto__ = StyleLayer; LineStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); LineStyleLayer.prototype.constructor = LineStyleLayer; LineStyleLayer.prototype._handleSpecialPaintPropertyUpdate = function _handleSpecialPaintPropertyUpdate(name) { if (name === 'line-gradient') { var expression = this._transitionablePaint._values['line-gradient'].value.expression; this.stepInterpolant = expression._styleExpression.expression instanceof Step; this.gradientVersion = (this.gradientVersion + 1) % MAX_SAFE_INTEGER; } }; LineStyleLayer.prototype.gradientExpression = function gradientExpression() { return this._transitionablePaint._values['line-gradient'].value.expression; }; LineStyleLayer.prototype.recalculate = function recalculate(parameters, availableImages) { StyleLayer.prototype.recalculate.call(this, parameters, availableImages); this.paint._values['line-floorwidth'] = lineFloorwidthProperty.possiblyEvaluate(this._transitioningPaint._values['line-width'].value, parameters); }; LineStyleLayer.prototype.createBucket = function createBucket(parameters) { return new LineBucket(parameters); }; LineStyleLayer.prototype.queryRadius = function queryRadius(bucket) { var lineBucket = bucket; var width = getLineWidth(getMaximumPaintValue('line-width', this, lineBucket), getMaximumPaintValue('line-gap-width', this, lineBucket)); var offset = getMaximumPaintValue('line-offset', this, lineBucket); return width / 2 + Math.abs(offset) + translateDistance(this.paint.get('line-translate')); }; LineStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits) { var translatedPolygon = translate(queryGeometry, this.paint.get('line-translate'), this.paint.get('line-translate-anchor'), transform.angle, pixelsToTileUnits); var halfWidth = pixelsToTileUnits / 2 * getLineWidth(this.paint.get('line-width').evaluate(feature, featureState), this.paint.get('line-gap-width').evaluate(feature, featureState)); var lineOffset = this.paint.get('line-offset').evaluate(feature, featureState); if (lineOffset) { geometry = offsetLine(geometry, lineOffset * pixelsToTileUnits); } return polygonIntersectsBufferedMultiLine(translatedPolygon, geometry, halfWidth); }; LineStyleLayer.prototype.isTileClipped = function isTileClipped() { return true; }; return LineStyleLayer; }(StyleLayer); function getLineWidth(lineWidth, lineGapWidth) { if (lineGapWidth > 0) { return lineGapWidth + 2 * lineWidth; } else { return lineWidth; } } function offsetLine(rings, offset) { var newRings = []; var zero = new pointGeometry(0, 0); for (var k = 0; k < rings.length; k++) { var ring = rings[k]; var newRing = []; for (var i = 0; i < ring.length; i++) { var a = ring[i - 1]; var b = ring[i]; var c = ring[i + 1]; var aToB = i === 0 ? zero : b.sub(a)._unit()._perp(); var bToC = i === ring.length - 1 ? zero : c.sub(b)._unit()._perp(); var extrude = aToB._add(bToC)._unit(); var cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y; extrude._mult(1 / cosHalfAngle); newRing.push(extrude._mult(offset)._add(b)); } newRings.push(newRing); } return newRings; } var symbolLayoutAttributes = createLayout([ { name: 'a_pos_offset', components: 4, type: 'Int16' }, { name: 'a_data', components: 4, type: 'Uint16' }, { name: 'a_pixeloffset', components: 4, type: 'Int16' } ], 4); var dynamicLayoutAttributes = createLayout([{ name: 'a_projected_pos', components: 3, type: 'Float32' }], 4); var placementOpacityAttributes = createLayout([{ name: 'a_fade_opacity', components: 1, type: 'Uint32' }], 4); var collisionVertexAttributes = createLayout([ { name: 'a_placed', components: 2, type: 'Uint8' }, { name: 'a_shift', components: 2, type: 'Float32' } ]); var collisionBox = createLayout([ { type: 'Int16', name: 'anchorPointX' }, { type: 'Int16', name: 'anchorPointY' }, { type: 'Int16', name: 'x1' }, { type: 'Int16', name: 'y1' }, { type: 'Int16', name: 'x2' }, { type: 'Int16', name: 'y2' }, { type: 'Uint32', name: 'featureIndex' }, { type: 'Uint16', name: 'sourceLayerIndex' }, { type: 'Uint16', name: 'bucketIndex' } ]); var collisionBoxLayout = createLayout([ { name: 'a_pos', components: 2, type: 'Int16' }, { name: 'a_anchor_pos', components: 2, type: 'Int16' }, { name: 'a_extrude', components: 2, type: 'Int16' } ], 4); var collisionCircleLayout = createLayout([ { name: 'a_pos', components: 2, type: 'Float32' }, { name: 'a_radius', components: 1, type: 'Float32' }, { name: 'a_flags', components: 2, type: 'Int16' } ], 4); var quadTriangle = createLayout([{ name: 'triangle', components: 3, type: 'Uint16' }]); var placement = createLayout([ { type: 'Int16', name: 'anchorX' }, { type: 'Int16', name: 'anchorY' }, { type: 'Uint16', name: 'glyphStartIndex' }, { type: 'Uint16', name: 'numGlyphs' }, { type: 'Uint32', name: 'vertexStartIndex' }, { type: 'Uint32', name: 'lineStartIndex' }, { type: 'Uint32', name: 'lineLength' }, { type: 'Uint16', name: 'segment' }, { type: 'Uint16', name: 'lowerSize' }, { type: 'Uint16', name: 'upperSize' }, { type: 'Float32', name: 'lineOffsetX' }, { type: 'Float32', name: 'lineOffsetY' }, { type: 'Uint8', name: 'writingMode' }, { type: 'Uint8', name: 'placedOrientation' }, { type: 'Uint8', name: 'hidden' }, { type: 'Uint32', name: 'crossTileID' }, { type: 'Int16', name: 'associatedIconIndex' } ]); var symbolInstance = createLayout([ { type: 'Int16', name: 'anchorX' }, { type: 'Int16', name: 'anchorY' }, { type: 'Int16', name: 'rightJustifiedTextSymbolIndex' }, { type: 'Int16', name: 'centerJustifiedTextSymbolIndex' }, { type: 'Int16', name: 'leftJustifiedTextSymbolIndex' }, { type: 'Int16', name: 'verticalPlacedTextSymbolIndex' }, { type: 'Int16', name: 'placedIconSymbolIndex' }, { type: 'Int16', name: 'verticalPlacedIconSymbolIndex' }, { type: 'Uint16', name: 'key' }, { type: 'Uint16', name: 'textBoxStartIndex' }, { type: 'Uint16', name: 'textBoxEndIndex' }, { type: 'Uint16', name: 'verticalTextBoxStartIndex' }, { type: 'Uint16', name: 'verticalTextBoxEndIndex' }, { type: 'Uint16', name: 'iconBoxStartIndex' }, { type: 'Uint16', name: 'iconBoxEndIndex' }, { type: 'Uint16', name: 'verticalIconBoxStartIndex' }, { type: 'Uint16', name: 'verticalIconBoxEndIndex' }, { type: 'Uint16', name: 'featureIndex' }, { type: 'Uint16', name: 'numHorizontalGlyphVertices' }, { type: 'Uint16', name: 'numVerticalGlyphVertices' }, { type: 'Uint16', name: 'numIconVertices' }, { type: 'Uint16', name: 'numVerticalIconVertices' }, { type: 'Uint16', name: 'useRuntimeCollisionCircles' }, { type: 'Uint32', name: 'crossTileID' }, { type: 'Float32', name: 'textBoxScale' }, { type: 'Float32', components: 2, name: 'textOffset' }, { type: 'Float32', name: 'collisionCircleDiameter' } ]); var glyphOffset = createLayout([{ type: 'Float32', name: 'offsetX' }]); var lineVertex = createLayout([ { type: 'Int16', name: 'x' }, { type: 'Int16', name: 'y' }, { type: 'Int16', name: 'tileUnitDistanceFromAnchor' } ]); function transformText(text, layer, feature) { var transform = layer.layout.get('text-transform').evaluate(feature, {}); if (transform === 'uppercase') { text = text.toLocaleUpperCase(); } else if (transform === 'lowercase') { text = text.toLocaleLowerCase(); } if (plugin.applyArabicShaping) { text = plugin.applyArabicShaping(text); } return text; } function transformText$1 (text, layer, feature) { text.sections.forEach(function (section) { section.text = transformText(section.text, layer, feature); }); return text; } function mergeLines (features) { var leftIndex = {}; var rightIndex = {}; var mergedFeatures = []; var mergedIndex = 0; function add(k) { mergedFeatures.push(features[k]); mergedIndex++; } function mergeFromRight(leftKey, rightKey, geom) { var i = rightIndex[leftKey]; delete rightIndex[leftKey]; rightIndex[rightKey] = i; mergedFeatures[i].geometry[0].pop(); mergedFeatures[i].geometry[0] = mergedFeatures[i].geometry[0].concat(geom[0]); return i; } function mergeFromLeft(leftKey, rightKey, geom) { var i = leftIndex[rightKey]; delete leftIndex[rightKey]; leftIndex[leftKey] = i; mergedFeatures[i].geometry[0].shift(); mergedFeatures[i].geometry[0] = geom[0].concat(mergedFeatures[i].geometry[0]); return i; } function getKey(text, geom, onRight) { var point = onRight ? geom[0][geom[0].length - 1] : geom[0][0]; return text + ':' + point.x + ':' + point.y; } for (var k = 0; k < features.length; k++) { var feature = features[k]; var geom = feature.geometry; var text = feature.text ? feature.text.toString() : null; if (!text) { add(k); continue; } var leftKey = getKey(text, geom), rightKey = getKey(text, geom, true); if (leftKey in rightIndex && rightKey in leftIndex && rightIndex[leftKey] !== leftIndex[rightKey]) { var j = mergeFromLeft(leftKey, rightKey, geom); var i = mergeFromRight(leftKey, rightKey, mergedFeatures[j].geometry); delete leftIndex[leftKey]; delete rightIndex[rightKey]; rightIndex[getKey(text, mergedFeatures[i].geometry, true)] = i; mergedFeatures[j].geometry = null; } else if (leftKey in rightIndex) { mergeFromRight(leftKey, rightKey, geom); } else if (rightKey in leftIndex) { mergeFromLeft(leftKey, rightKey, geom); } else { add(k); leftIndex[leftKey] = mergedIndex - 1; rightIndex[rightKey] = mergedIndex - 1; } } return mergedFeatures.filter(function (f) { return f.geometry; }); } var verticalizedCharacterMap = { '!': '\uFE15', '#': '\uFF03', '$': '\uFF04', '%': '\uFF05', '&': '\uFF06', '(': '\uFE35', ')': '\uFE36', '*': '\uFF0A', '+': '\uFF0B', ',': '\uFE10', '-': '\uFE32', '.': '\u30FB', '/': '\uFF0F', ':': '\uFE13', ';': '\uFE14', '<': '\uFE3F', '=': '\uFF1D', '>': '\uFE40', '?': '\uFE16', '@': '\uFF20', '[': '\uFE47', '\\': '\uFF3C', ']': '\uFE48', '^': '\uFF3E', '_': '︳', '`': '\uFF40', '{': '\uFE37', '|': '\u2015', '}': '\uFE38', '~': '\uFF5E', '\xA2': '\uFFE0', '\xA3': '\uFFE1', '\xA5': '\uFFE5', '\xA6': '\uFFE4', '\xAC': '\uFFE2', '\xAF': '\uFFE3', '\u2013': '\uFE32', '\u2014': '\uFE31', '\u2018': '\uFE43', '\u2019': '\uFE44', '\u201C': '\uFE41', '\u201D': '\uFE42', '\u2026': '\uFE19', '\u2027': '\u30FB', '\u20A9': '\uFFE6', '\u3001': '\uFE11', '\u3002': '\uFE12', '\u3008': '\uFE3F', '\u3009': '\uFE40', '\u300A': '\uFE3D', '\u300B': '\uFE3E', '\u300C': '\uFE41', '\u300D': '\uFE42', '\u300E': '\uFE43', '\u300F': '\uFE44', '\u3010': '\uFE3B', '\u3011': '\uFE3C', '\u3014': '\uFE39', '\u3015': '\uFE3A', '\u3016': '\uFE17', '\u3017': '\uFE18', '\uFF01': '\uFE15', '\uFF08': '\uFE35', '\uFF09': '\uFE36', '\uFF0C': '\uFE10', '\uFF0D': '\uFE32', '\uFF0E': '\u30FB', '\uFF1A': '\uFE13', '\uFF1B': '\uFE14', '\uFF1C': '\uFE3F', '\uFF1E': '\uFE40', '\uFF1F': '\uFE16', '\uFF3B': '\uFE47', '\uFF3D': '\uFE48', '_': '︳', '\uFF5B': '\uFE37', '\uFF5C': '\u2015', '\uFF5D': '\uFE38', '\uFF5F': '\uFE35', '\uFF60': '\uFE36', '\uFF61': '\uFE12', '\uFF62': '\uFE41', '\uFF63': '\uFE42' }; function verticalizePunctuation(input) { var output = ''; for (var i = 0; i < input.length; i++) { var nextCharCode = input.charCodeAt(i + 1) || null; var prevCharCode = input.charCodeAt(i - 1) || null; var canReplacePunctuation = (!nextCharCode || !charHasRotatedVerticalOrientation(nextCharCode) || verticalizedCharacterMap[input[i + 1]]) && (!prevCharCode || !charHasRotatedVerticalOrientation(prevCharCode) || verticalizedCharacterMap[input[i - 1]]); if (canReplacePunctuation && verticalizedCharacterMap[input[i]]) { output += verticalizedCharacterMap[input[i]]; } else { output += input[i]; } } return output; } var ONE_EM = 24; var read = function (buffer, offset, isLE, mLen, nBytes) { var e, m; var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var nBits = -7; var i = isLE ? nBytes - 1 : 0; var d = isLE ? -1 : 1; var s = buffer[offset + i]; i += d; e = s & (1 << -nBits) - 1; s >>= -nBits; nBits += eLen; for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) { } m = e & (1 << -nBits) - 1; e >>= -nBits; nBits += mLen; for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) { } if (e === 0) { e = 1 - eBias; } else if (e === eMax) { return m ? NaN : (s ? -1 : 1) * Infinity; } else { m = m + Math.pow(2, mLen); e = e - eBias; } return (s ? -1 : 1) * m * Math.pow(2, e - mLen); }; var write = function (buffer, value, offset, isLE, mLen, nBytes) { var e, m, c; var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0; var i = isLE ? 0 : nBytes - 1; var d = isLE ? 1 : -1; var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; value = Math.abs(value); if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0; e = eMax; } else { e = Math.floor(Math.log(value) / Math.LN2); if (value * (c = Math.pow(2, -e)) < 1) { e--; c *= 2; } if (e + eBias >= 1) { value += rt / c; } else { value += rt * Math.pow(2, 1 - eBias); } if (value * c >= 2) { e++; c /= 2; } if (e + eBias >= eMax) { m = 0; e = eMax; } else if (e + eBias >= 1) { m = (value * c - 1) * Math.pow(2, mLen); e = e + eBias; } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); e = 0; } } for (; mLen >= 8; buffer[offset + i] = m & 255, i += d, m /= 256, mLen -= 8) { } e = e << mLen | m; eLen += mLen; for (; eLen > 0; buffer[offset + i] = e & 255, i += d, e /= 256, eLen -= 8) { } buffer[offset + i - d] |= s * 128; }; var ieee754 = { read: read, write: write }; var pbf = Pbf; function Pbf(buf) { this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0); this.pos = 0; this.type = 0; this.length = this.buf.length; } Pbf.Varint = 0; Pbf.Fixed64 = 1; Pbf.Bytes = 2; Pbf.Fixed32 = 5; var SHIFT_LEFT_32 = (1 << 16) * (1 << 16), SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32; var TEXT_DECODER_MIN_LENGTH = 12; var utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8'); Pbf.prototype = { destroy: function () { this.buf = null; }, readFields: function (readField, result, end) { end = end || this.length; while (this.pos < end) { var val = this.readVarint(), tag = val >> 3, startPos = this.pos; this.type = val & 7; readField(tag, result, this); if (this.pos === startPos) { this.skip(val); } } return result; }, readMessage: function (readField, result) { return this.readFields(readField, result, this.readVarint() + this.pos); }, readFixed32: function () { var val = readUInt32(this.buf, this.pos); this.pos += 4; return val; }, readSFixed32: function () { var val = readInt32(this.buf, this.pos); this.pos += 4; return val; }, readFixed64: function () { var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32; this.pos += 8; return val; }, readSFixed64: function () { var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32; this.pos += 8; return val; }, readFloat: function () { var val = ieee754.read(this.buf, this.pos, true, 23, 4); this.pos += 4; return val; }, readDouble: function () { var val = ieee754.read(this.buf, this.pos, true, 52, 8); this.pos += 8; return val; }, readVarint: function (isSigned) { var buf = this.buf, val, b; b = buf[this.pos++]; val = b & 127; if (b < 128) { return val; } b = buf[this.pos++]; val |= (b & 127) << 7; if (b < 128) { return val; } b = buf[this.pos++]; val |= (b & 127) << 14; if (b < 128) { return val; } b = buf[this.pos++]; val |= (b & 127) << 21; if (b < 128) { return val; } b = buf[this.pos]; val |= (b & 15) << 28; return readVarintRemainder(val, isSigned, this); }, readVarint64: function () { return this.readVarint(true); }, readSVarint: function () { var num = this.readVarint(); return num % 2 === 1 ? (num + 1) / -2 : num / 2; }, readBoolean: function () { return Boolean(this.readVarint()); }, readString: function () { var end = this.readVarint() + this.pos; var pos = this.pos; this.pos = end; if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) { return readUtf8TextDecoder(this.buf, pos, end); } return readUtf8(this.buf, pos, end); }, readBytes: function () { var end = this.readVarint() + this.pos, buffer = this.buf.subarray(this.pos, end); this.pos = end; return buffer; }, readPackedVarint: function (arr, isSigned) { if (this.type !== Pbf.Bytes) { return arr.push(this.readVarint(isSigned)); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readVarint(isSigned)); } return arr; }, readPackedSVarint: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readSVarint()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readSVarint()); } return arr; }, readPackedBoolean: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readBoolean()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readBoolean()); } return arr; }, readPackedFloat: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readFloat()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readFloat()); } return arr; }, readPackedDouble: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readDouble()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readDouble()); } return arr; }, readPackedFixed32: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readFixed32()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readFixed32()); } return arr; }, readPackedSFixed32: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readSFixed32()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readSFixed32()); } return arr; }, readPackedFixed64: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readFixed64()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readFixed64()); } return arr; }, readPackedSFixed64: function (arr) { if (this.type !== Pbf.Bytes) { return arr.push(this.readSFixed64()); } var end = readPackedEnd(this); arr = arr || []; while (this.pos < end) { arr.push(this.readSFixed64()); } return arr; }, skip: function (val) { var type = val & 7; if (type === Pbf.Varint) { while (this.buf[this.pos++] > 127) { } } else if (type === Pbf.Bytes) { this.pos = this.readVarint() + this.pos; } else if (type === Pbf.Fixed32) { this.pos += 4; } else if (type === Pbf.Fixed64) { this.pos += 8; } else { throw new Error('Unimplemented type: ' + type); } }, writeTag: function (tag, type) { this.writeVarint(tag << 3 | type); }, realloc: function (min) { var length = this.length || 16; while (length < this.pos + min) { length *= 2; } if (length !== this.length) { var buf = new Uint8Array(length); buf.set(this.buf); this.buf = buf; this.length = length; } }, finish: function () { this.length = this.pos; this.pos = 0; return this.buf.subarray(0, this.length); }, writeFixed32: function (val) { this.realloc(4); writeInt32(this.buf, val, this.pos); this.pos += 4; }, writeSFixed32: function (val) { this.realloc(4); writeInt32(this.buf, val, this.pos); this.pos += 4; }, writeFixed64: function (val) { this.realloc(8); writeInt32(this.buf, val & -1, this.pos); writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); this.pos += 8; }, writeSFixed64: function (val) { this.realloc(8); writeInt32(this.buf, val & -1, this.pos); writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); this.pos += 8; }, writeVarint: function (val) { val = +val || 0; if (val > 268435455 || val < 0) { writeBigVarint(val, this); return; } this.realloc(4); this.buf[this.pos++] = val & 127 | (val > 127 ? 128 : 0); if (val <= 127) { return; } this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0); if (val <= 127) { return; } this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0); if (val <= 127) { return; } this.buf[this.pos++] = val >>> 7 & 127; }, writeSVarint: function (val) { this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2); }, writeBoolean: function (val) { this.writeVarint(Boolean(val)); }, writeString: function (str) { str = String(str); this.realloc(str.length * 4); this.pos++; var startPos = this.pos; this.pos = writeUtf8(this.buf, str, this.pos); var len = this.pos - startPos; if (len >= 128) { makeRoomForExtraLength(startPos, len, this); } this.pos = startPos - 1; this.writeVarint(len); this.pos += len; }, writeFloat: function (val) { this.realloc(4); ieee754.write(this.buf, val, this.pos, true, 23, 4); this.pos += 4; }, writeDouble: function (val) { this.realloc(8); ieee754.write(this.buf, val, this.pos, true, 52, 8); this.pos += 8; }, writeBytes: function (buffer) { var len = buffer.length; this.writeVarint(len); this.realloc(len); for (var i = 0; i < len; i++) { this.buf[this.pos++] = buffer[i]; } }, writeRawMessage: function (fn, obj) { this.pos++; var startPos = this.pos; fn(obj, this); var len = this.pos - startPos; if (len >= 128) { makeRoomForExtraLength(startPos, len, this); } this.pos = startPos - 1; this.writeVarint(len); this.pos += len; }, writeMessage: function (tag, fn, obj) { this.writeTag(tag, Pbf.Bytes); this.writeRawMessage(fn, obj); }, writePackedVarint: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedVarint, arr); } }, writePackedSVarint: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedSVarint, arr); } }, writePackedBoolean: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedBoolean, arr); } }, writePackedFloat: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedFloat, arr); } }, writePackedDouble: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedDouble, arr); } }, writePackedFixed32: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedFixed32, arr); } }, writePackedSFixed32: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedSFixed32, arr); } }, writePackedFixed64: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedFixed64, arr); } }, writePackedSFixed64: function (tag, arr) { if (arr.length) { this.writeMessage(tag, writePackedSFixed64, arr); } }, writeBytesField: function (tag, buffer) { this.writeTag(tag, Pbf.Bytes); this.writeBytes(buffer); }, writeFixed32Field: function (tag, val) { this.writeTag(tag, Pbf.Fixed32); this.writeFixed32(val); }, writeSFixed32Field: function (tag, val) { this.writeTag(tag, Pbf.Fixed32); this.writeSFixed32(val); }, writeFixed64Field: function (tag, val) { this.writeTag(tag, Pbf.Fixed64); this.writeFixed64(val); }, writeSFixed64Field: function (tag, val) { this.writeTag(tag, Pbf.Fixed64); this.writeSFixed64(val); }, writeVarintField: function (tag, val) { this.writeTag(tag, Pbf.Varint); this.writeVarint(val); }, writeSVarintField: function (tag, val) { this.writeTag(tag, Pbf.Varint); this.writeSVarint(val); }, writeStringField: function (tag, str) { this.writeTag(tag, Pbf.Bytes); this.writeString(str); }, writeFloatField: function (tag, val) { this.writeTag(tag, Pbf.Fixed32); this.writeFloat(val); }, writeDoubleField: function (tag, val) { this.writeTag(tag, Pbf.Fixed64); this.writeDouble(val); }, writeBooleanField: function (tag, val) { this.writeVarintField(tag, Boolean(val)); } }; function readVarintRemainder(l, s, p) { var buf = p.buf, h, b; b = buf[p.pos++]; h = (b & 112) >> 4; if (b < 128) { return toNum(l, h, s); } b = buf[p.pos++]; h |= (b & 127) << 3; if (b < 128) { return toNum(l, h, s); } b = buf[p.pos++]; h |= (b & 127) << 10; if (b < 128) { return toNum(l, h, s); } b = buf[p.pos++]; h |= (b & 127) << 17; if (b < 128) { return toNum(l, h, s); } b = buf[p.pos++]; h |= (b & 127) << 24; if (b < 128) { return toNum(l, h, s); } b = buf[p.pos++]; h |= (b & 1) << 31; if (b < 128) { return toNum(l, h, s); } throw new Error('Expected varint not more than 10 bytes'); } function readPackedEnd(pbf) { return pbf.type === Pbf.Bytes ? pbf.readVarint() + pbf.pos : pbf.pos + 1; } function toNum(low, high, isSigned) { if (isSigned) { return high * 4294967296 + (low >>> 0); } return (high >>> 0) * 4294967296 + (low >>> 0); } function writeBigVarint(val, pbf) { var low, high; if (val >= 0) { low = val % 4294967296 | 0; high = val / 4294967296 | 0; } else { low = ~(-val % 4294967296); high = ~(-val / 4294967296); if (low ^ 4294967295) { low = low + 1 | 0; } else { low = 0; high = high + 1 | 0; } } if (val >= 18446744073709552000 || val < -18446744073709552000) { throw new Error('Given varint doesn\'t fit into 10 bytes'); } pbf.realloc(10); writeBigVarintLow(low, high, pbf); writeBigVarintHigh(high, pbf); } function writeBigVarintLow(low, high, pbf) { pbf.buf[pbf.pos++] = low & 127 | 128; low >>>= 7; pbf.buf[pbf.pos++] = low & 127 | 128; low >>>= 7; pbf.buf[pbf.pos++] = low & 127 | 128; low >>>= 7; pbf.buf[pbf.pos++] = low & 127 | 128; low >>>= 7; pbf.buf[pbf.pos] = low & 127; } function writeBigVarintHigh(high, pbf) { var lsb = (high & 7) << 4; pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 128 : 0); if (!high) { return; } pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0); if (!high) { return; } pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0); if (!high) { return; } pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0); if (!high) { return; } pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0); if (!high) { return; } pbf.buf[pbf.pos++] = high & 127; } function makeRoomForExtraLength(startPos, len, pbf) { var extraLen = len <= 16383 ? 1 : len <= 2097151 ? 2 : len <= 268435455 ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7)); pbf.realloc(extraLen); for (var i = pbf.pos - 1; i >= startPos; i--) { pbf.buf[i + extraLen] = pbf.buf[i]; } } function writePackedVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeVarint(arr[i]); } } function writePackedSVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeSVarint(arr[i]); } } function writePackedFloat(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeFloat(arr[i]); } } function writePackedDouble(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeDouble(arr[i]); } } function writePackedBoolean(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeBoolean(arr[i]); } } function writePackedFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeFixed32(arr[i]); } } function writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeSFixed32(arr[i]); } } function writePackedFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeFixed64(arr[i]); } } function writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) { pbf.writeSFixed64(arr[i]); } } function readUInt32(buf, pos) { return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + buf[pos + 3] * 16777216; } function writeInt32(buf, val, pos) { buf[pos] = val; buf[pos + 1] = val >>> 8; buf[pos + 2] = val >>> 16; buf[pos + 3] = val >>> 24; } function readInt32(buf, pos) { return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + (buf[pos + 3] << 24); } function readUtf8(buf, pos, end) { var str = ''; var i = pos; while (i < end) { var b0 = buf[i]; var c = null; var bytesPerSequence = b0 > 239 ? 4 : b0 > 223 ? 3 : b0 > 191 ? 2 : 1; if (i + bytesPerSequence > end) { break; } var b1, b2, b3; if (bytesPerSequence === 1) { if (b0 < 128) { c = b0; } } else if (bytesPerSequence === 2) { b1 = buf[i + 1]; if ((b1 & 192) === 128) { c = (b0 & 31) << 6 | b1 & 63; if (c <= 127) { c = null; } } } else if (bytesPerSequence === 3) { b1 = buf[i + 1]; b2 = buf[i + 2]; if ((b1 & 192) === 128 && (b2 & 192) === 128) { c = (b0 & 15) << 12 | (b1 & 63) << 6 | b2 & 63; if (c <= 2047 || c >= 55296 && c <= 57343) { c = null; } } } else if (bytesPerSequence === 4) { b1 = buf[i + 1]; b2 = buf[i + 2]; b3 = buf[i + 3]; if ((b1 & 192) === 128 && (b2 & 192) === 128 && (b3 & 192) === 128) { c = (b0 & 15) << 18 | (b1 & 63) << 12 | (b2 & 63) << 6 | b3 & 63; if (c <= 65535 || c >= 1114112) { c = null; } } } if (c === null) { c = 65533; bytesPerSequence = 1; } else if (c > 65535) { c -= 65536; str += String.fromCharCode(c >>> 10 & 1023 | 55296); c = 56320 | c & 1023; } str += String.fromCharCode(c); i += bytesPerSequence; } return str; } function readUtf8TextDecoder(buf, pos, end) { return utf8TextDecoder.decode(buf.subarray(pos, end)); } function writeUtf8(buf, str, pos) { for (var i = 0, c, lead; i < str.length; i++) { c = str.charCodeAt(i); if (c > 55295 && c < 57344) { if (lead) { if (c < 56320) { buf[pos++] = 239; buf[pos++] = 191; buf[pos++] = 189; lead = c; continue; } else { c = lead - 55296 << 10 | c - 56320 | 65536; lead = null; } } else { if (c > 56319 || i + 1 === str.length) { buf[pos++] = 239; buf[pos++] = 191; buf[pos++] = 189; } else { lead = c; } continue; } } else if (lead) { buf[pos++] = 239; buf[pos++] = 191; buf[pos++] = 189; lead = null; } if (c < 128) { buf[pos++] = c; } else { if (c < 2048) { buf[pos++] = c >> 6 | 192; } else { if (c < 65536) { buf[pos++] = c >> 12 | 224; } else { buf[pos++] = c >> 18 | 240; buf[pos++] = c >> 12 & 63 | 128; } buf[pos++] = c >> 6 & 63 | 128; } buf[pos++] = c & 63 | 128; } } return pos; } var border = 3; function readFontstacks(tag, glyphs, pbf) { if (tag === 1) { pbf.readMessage(readFontstack, glyphs); } } function readFontstack(tag, glyphs, pbf) { if (tag === 3) { var ref = pbf.readMessage(readGlyph, {}); var id = ref.id; var bitmap = ref.bitmap; var width = ref.width; var height = ref.height; var left = ref.left; var top = ref.top; var advance = ref.advance; glyphs.push({ id: id, bitmap: new AlphaImage({ width: width + 2 * border, height: height + 2 * border }, bitmap), metrics: { width: width, height: height, left: left, top: top, advance: advance } }); } } function readGlyph(tag, glyph, pbf) { if (tag === 1) { glyph.id = pbf.readVarint(); } else if (tag === 2) { glyph.bitmap = pbf.readBytes(); } else if (tag === 3) { glyph.width = pbf.readVarint(); } else if (tag === 4) { glyph.height = pbf.readVarint(); } else if (tag === 5) { glyph.left = pbf.readSVarint(); } else if (tag === 6) { glyph.top = pbf.readSVarint(); } else if (tag === 7) { glyph.advance = pbf.readVarint(); } } function parseGlyphPBF (data) { return new pbf(data).readFields(readFontstacks, []); } var GLYPH_PBF_BORDER = border; function potpack(boxes) { // calculate total box area and maximum box width var area = 0; var maxWidth = 0; for (var i$1 = 0, list = boxes; i$1 < list.length; i$1 += 1) { var box = list[i$1]; area += box.w * box.h; maxWidth = Math.max(maxWidth, box.w); } // sort the boxes for insertion by height, descending boxes.sort(function (a, b) { return b.h - a.h; }); // aim for a squarish resulting container, // slightly adjusted for sub-100% space utilization var startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth); // start with a single empty space, unbounded at the bottom var spaces = [{x: 0, y: 0, w: startWidth, h: Infinity}]; var width = 0; var height = 0; for (var i$2 = 0, list$1 = boxes; i$2 < list$1.length; i$2 += 1) { // look through spaces backwards so that we check smaller spaces first var box$1 = list$1[i$2]; for (var i = spaces.length - 1; i >= 0; i--) { var space = spaces[i]; // look for empty spaces that can accommodate the current box if (box$1.w > space.w || box$1.h > space.h) { continue; } // found the space; add the box to its top-left corner // |-------|-------| // | box | | // |_______| | // | space | // |_______________| box$1.x = space.x; box$1.y = space.y; height = Math.max(height, box$1.y + box$1.h); width = Math.max(width, box$1.x + box$1.w); if (box$1.w === space.w && box$1.h === space.h) { // space matches the box exactly; remove it var last = spaces.pop(); if (i < spaces.length) { spaces[i] = last; } } else if (box$1.h === space.h) { // space matches the box height; update it accordingly // |-------|---------------| // | box | updated space | // |_______|_______________| space.x += box$1.w; space.w -= box$1.w; } else if (box$1.w === space.w) { // space matches the box width; update it accordingly // |---------------| // | box | // |_______________| // | updated space | // |_______________| space.y += box$1.h; space.h -= box$1.h; } else { // otherwise the box splits the space into two spaces // |-------|-----------| // | box | new space | // |_______|___________| // | updated space | // |___________________| spaces.push({ x: space.x + box$1.w, y: space.y, w: space.w - box$1.w, h: box$1.h }); space.y += box$1.h; space.h -= box$1.h; } break; } } return { w: width, // container width h: height, // container height fill: (area / (width * height)) || 0 // space utilization }; } var IMAGE_PADDING = 1; var ImagePosition = function ImagePosition(paddedRect, ref) { var pixelRatio = ref.pixelRatio; var version = ref.version; var stretchX = ref.stretchX; var stretchY = ref.stretchY; var content = ref.content; this.paddedRect = paddedRect; this.pixelRatio = pixelRatio; this.stretchX = stretchX; this.stretchY = stretchY; this.content = content; this.version = version; }; var prototypeAccessors = { tl: { configurable: true }, br: { configurable: true }, tlbr: { configurable: true }, displaySize: { configurable: true } }; prototypeAccessors.tl.get = function () { return [ this.paddedRect.x + IMAGE_PADDING, this.paddedRect.y + IMAGE_PADDING ]; }; prototypeAccessors.br.get = function () { return [ this.paddedRect.x + this.paddedRect.w - IMAGE_PADDING, this.paddedRect.y + this.paddedRect.h - IMAGE_PADDING ]; }; prototypeAccessors.tlbr.get = function () { return this.tl.concat(this.br); }; prototypeAccessors.displaySize.get = function () { return [ (this.paddedRect.w - IMAGE_PADDING * 2) / this.pixelRatio, (this.paddedRect.h - IMAGE_PADDING * 2) / this.pixelRatio ]; }; Object.defineProperties(ImagePosition.prototype, prototypeAccessors); var ImageAtlas = function ImageAtlas(icons, patterns) { var iconPositions = {}, patternPositions = {}; this.haveRenderCallbacks = []; var bins = []; this.addImages(icons, iconPositions, bins); this.addImages(patterns, patternPositions, bins); var ref = potpack(bins); var w = ref.w; var h = ref.h; var image = new RGBAImage({ width: w || 1, height: h || 1 }); for (var id in icons) { var src = icons[id]; var bin = iconPositions[id].paddedRect; RGBAImage.copy(src.data, image, { x: 0, y: 0 }, { x: bin.x + IMAGE_PADDING, y: bin.y + IMAGE_PADDING }, src.data); } for (var id$1 in patterns) { var src$1 = patterns[id$1]; var bin$1 = patternPositions[id$1].paddedRect; var x = bin$1.x + IMAGE_PADDING, y = bin$1.y + IMAGE_PADDING, w$1 = src$1.data.width, h$1 = src$1.data.height; RGBAImage.copy(src$1.data, image, { x: 0, y: 0 }, { x: x, y: y }, src$1.data); RGBAImage.copy(src$1.data, image, { x: 0, y: h$1 - 1 }, { x: x, y: y - 1 }, { width: w$1, height: 1 }); RGBAImage.copy(src$1.data, image, { x: 0, y: 0 }, { x: x, y: y + h$1 }, { width: w$1, height: 1 }); RGBAImage.copy(src$1.data, image, { x: w$1 - 1, y: 0 }, { x: x - 1, y: y }, { width: 1, height: h$1 }); RGBAImage.copy(src$1.data, image, { x: 0, y: 0 }, { x: x + w$1, y: y }, { width: 1, height: h$1 }); } this.image = image; this.iconPositions = iconPositions; this.patternPositions = patternPositions; }; ImageAtlas.prototype.addImages = function addImages(images, positions, bins) { for (var id in images) { var src = images[id]; var bin = { x: 0, y: 0, w: src.data.width + 2 * IMAGE_PADDING, h: src.data.height + 2 * IMAGE_PADDING }; bins.push(bin); positions[id] = new ImagePosition(bin, src); if (src.hasRenderCallback) { this.haveRenderCallbacks.push(id); } } }; ImageAtlas.prototype.patchUpdatedImages = function patchUpdatedImages(imageManager, texture) { imageManager.dispatchRenderCallbacks(this.haveRenderCallbacks); for (var name in imageManager.updatedImages) { this.patchUpdatedImage(this.iconPositions[name], imageManager.getImage(name), texture); this.patchUpdatedImage(this.patternPositions[name], imageManager.getImage(name), texture); } }; ImageAtlas.prototype.patchUpdatedImage = function patchUpdatedImage(position, image, texture) { if (!position || !image) { return; } if (position.version === image.version) { return; } position.version = image.version; var ref = position.tl; var x = ref[0]; var y = ref[1]; texture.update(image.data, undefined, { x: x, y: y }); }; register('ImagePosition', ImagePosition); register('ImageAtlas', ImageAtlas); var WritingMode = { horizontal: 1, vertical: 2, horizontalOnly: 3 }; var SHAPING_DEFAULT_OFFSET = -17; function isEmpty(positionedLines) { for (var i = 0, list = positionedLines; i < list.length; i += 1) { var line = list[i]; if (line.positionedGlyphs.length !== 0) { return false; } } return true; } var PUAbegin = 57344; var PUAend = 63743; var SectionOptions = function SectionOptions() { this.scale = 1; this.fontStack = ''; this.imageName = null; }; SectionOptions.forText = function forText(scale, fontStack) { var textOptions = new SectionOptions(); textOptions.scale = scale || 1; textOptions.fontStack = fontStack; return textOptions; }; SectionOptions.forImage = function forImage(imageName) { var imageOptions = new SectionOptions(); imageOptions.imageName = imageName; return imageOptions; }; var TaggedString = function TaggedString() { this.text = ''; this.sectionIndex = []; this.sections = []; this.imageSectionID = null; }; TaggedString.fromFeature = function fromFeature(text, defaultFontStack) { var result = new TaggedString(); for (var i = 0; i < text.sections.length; i++) { var section = text.sections[i]; if (!section.image) { result.addTextSection(section, defaultFontStack); } else { result.addImageSection(section); } } return result; }; TaggedString.prototype.length = function length() { return this.text.length; }; TaggedString.prototype.getSection = function getSection(index) { return this.sections[this.sectionIndex[index]]; }; TaggedString.prototype.getSectionIndex = function getSectionIndex(index) { return this.sectionIndex[index]; }; TaggedString.prototype.getCharCode = function getCharCode(index) { return this.text.charCodeAt(index); }; TaggedString.prototype.verticalizePunctuation = function verticalizePunctuation$1() { this.text = verticalizePunctuation(this.text); }; TaggedString.prototype.trim = function trim() { var beginningWhitespace = 0; for (var i = 0; i < this.text.length && whitespace[this.text.charCodeAt(i)]; i++) { beginningWhitespace++; } var trailingWhitespace = this.text.length; for (var i$1 = this.text.length - 1; i$1 >= 0 && i$1 >= beginningWhitespace && whitespace[this.text.charCodeAt(i$1)]; i$1--) { trailingWhitespace--; } this.text = this.text.substring(beginningWhitespace, trailingWhitespace); this.sectionIndex = this.sectionIndex.slice(beginningWhitespace, trailingWhitespace); }; TaggedString.prototype.substring = function substring(start, end) { var substring = new TaggedString(); substring.text = this.text.substring(start, end); substring.sectionIndex = this.sectionIndex.slice(start, end); substring.sections = this.sections; return substring; }; TaggedString.prototype.toString = function toString() { return this.text; }; TaggedString.prototype.getMaxScale = function getMaxScale() { var this$1 = this; return this.sectionIndex.reduce(function (max, index) { return Math.max(max, this$1.sections[index].scale); }, 0); }; TaggedString.prototype.addTextSection = function addTextSection(section, defaultFontStack) { this.text += section.text; this.sections.push(SectionOptions.forText(section.scale, section.fontStack || defaultFontStack)); var index = this.sections.length - 1; for (var i = 0; i < section.text.length; ++i) { this.sectionIndex.push(index); } }; TaggedString.prototype.addImageSection = function addImageSection(section) { var imageName = section.image ? section.image.name : ''; if (imageName.length === 0) { warnOnce('Can\'t add FormattedSection with an empty image.'); return; } var nextImageSectionCharCode = this.getNextImageSectionCharCode(); if (!nextImageSectionCharCode) { warnOnce('Reached maximum number of images ' + (PUAend - PUAbegin + 2)); return; } this.text += String.fromCharCode(nextImageSectionCharCode); this.sections.push(SectionOptions.forImage(imageName)); this.sectionIndex.push(this.sections.length - 1); }; TaggedString.prototype.getNextImageSectionCharCode = function getNextImageSectionCharCode() { if (!this.imageSectionID) { this.imageSectionID = PUAbegin; return this.imageSectionID; } if (this.imageSectionID >= PUAend) { return null; } return ++this.imageSectionID; }; function breakLines(input, lineBreakPoints) { var lines = []; var text = input.text; var start = 0; for (var i = 0, list = lineBreakPoints; i < list.length; i += 1) { var lineBreak = list[i]; lines.push(input.substring(start, lineBreak)); start = lineBreak; } if (start < text.length) { lines.push(input.substring(start, text.length)); } return lines; } function shapeText(text, glyphMap, glyphPositions, imagePositions, defaultFontStack, maxWidth, lineHeight, textAnchor, textJustify, spacing, translate, writingMode, allowVerticalPlacement, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom) { var logicalInput = TaggedString.fromFeature(text, defaultFontStack); if (writingMode === WritingMode.vertical) { logicalInput.verticalizePunctuation(); } var lines; var processBidirectionalText = plugin.processBidirectionalText; var processStyledBidirectionalText = plugin.processStyledBidirectionalText; if (processBidirectionalText && logicalInput.sections.length === 1) { lines = []; var untaggedLines = processBidirectionalText(logicalInput.toString(), determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize)); for (var i$1 = 0, list = untaggedLines; i$1 < list.length; i$1 += 1) { var line = list[i$1]; var taggedLine = new TaggedString(); taggedLine.text = line; taggedLine.sections = logicalInput.sections; for (var i = 0; i < line.length; i++) { taggedLine.sectionIndex.push(0); } lines.push(taggedLine); } } else if (processStyledBidirectionalText) { lines = []; var processedLines = processStyledBidirectionalText(logicalInput.text, logicalInput.sectionIndex, determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize)); for (var i$2 = 0, list$1 = processedLines; i$2 < list$1.length; i$2 += 1) { var line$1 = list$1[i$2]; var taggedLine$1 = new TaggedString(); taggedLine$1.text = line$1[0]; taggedLine$1.sectionIndex = line$1[1]; taggedLine$1.sections = logicalInput.sections; lines.push(taggedLine$1); } } else { lines = breakLines(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize)); } var positionedLines = []; var shaping = { positionedLines: positionedLines, text: logicalInput.toString(), top: translate[1], bottom: translate[1], left: translate[0], right: translate[0], writingMode: writingMode, iconsInText: false, verticalizable: false }; shapeLines(shaping, glyphMap, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement, layoutTextSizeThisZoom); if (isEmpty(positionedLines)) { return false; } return shaping; } var whitespace = {}; whitespace[9] = true; whitespace[10] = true; whitespace[11] = true; whitespace[12] = true; whitespace[13] = true; whitespace[32] = true; var breakable = {}; breakable[10] = true; breakable[32] = true; breakable[38] = true; breakable[40] = true; breakable[41] = true; breakable[43] = true; breakable[45] = true; breakable[47] = true; breakable[173] = true; breakable[183] = true; breakable[8203] = true; breakable[8208] = true; breakable[8211] = true; breakable[8231] = true; function getGlyphAdvance(codePoint, section, glyphMap, imagePositions, spacing, layoutTextSize) { if (!section.imageName) { var positions = glyphMap[section.fontStack]; var glyph = positions && positions[codePoint]; if (!glyph) { return 0; } return glyph.metrics.advance * section.scale + spacing; } else { var imagePosition = imagePositions[section.imageName]; if (!imagePosition) { return 0; } return imagePosition.displaySize[0] * section.scale * ONE_EM / layoutTextSize + spacing; } } function determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize) { var totalWidth = 0; for (var index = 0; index < logicalInput.length(); index++) { var section = logicalInput.getSection(index); totalWidth += getGlyphAdvance(logicalInput.getCharCode(index), section, glyphMap, imagePositions, spacing, layoutTextSize); } var lineCount = Math.max(1, Math.ceil(totalWidth / maxWidth)); return totalWidth / lineCount; } function calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) { var raggedness = Math.pow(lineWidth - targetWidth, 2); if (isLastBreak) { if (lineWidth < targetWidth) { return raggedness / 2; } else { return raggedness * 2; } } return raggedness + Math.abs(penalty) * penalty; } function calculatePenalty(codePoint, nextCodePoint, penalizableIdeographicBreak) { var penalty = 0; if (codePoint === 10) { penalty -= 10000; } if (penalizableIdeographicBreak) { penalty += 150; } if (codePoint === 40 || codePoint === 65288) { penalty += 50; } if (nextCodePoint === 41 || nextCodePoint === 65289) { penalty += 50; } return penalty; } function evaluateBreak(breakIndex, breakX, targetWidth, potentialBreaks, penalty, isLastBreak) { var bestPriorBreak = null; var bestBreakBadness = calculateBadness(breakX, targetWidth, penalty, isLastBreak); for (var i = 0, list = potentialBreaks; i < list.length; i += 1) { var potentialBreak = list[i]; var lineWidth = breakX - potentialBreak.x; var breakBadness = calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) + potentialBreak.badness; if (breakBadness <= bestBreakBadness) { bestPriorBreak = potentialBreak; bestBreakBadness = breakBadness; } } return { index: breakIndex, x: breakX, priorBreak: bestPriorBreak, badness: bestBreakBadness }; } function leastBadBreaks(lastLineBreak) { if (!lastLineBreak) { return []; } return leastBadBreaks(lastLineBreak.priorBreak).concat(lastLineBreak.index); } function determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize) { if (symbolPlacement !== 'point') { return []; } if (!logicalInput) { return []; } var potentialLineBreaks = []; var targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize); var hasServerSuggestedBreakpoints = logicalInput.text.indexOf('\u200B') >= 0; var currentX = 0; for (var i = 0; i < logicalInput.length(); i++) { var section = logicalInput.getSection(i); var codePoint = logicalInput.getCharCode(i); if (!whitespace[codePoint]) { currentX += getGlyphAdvance(codePoint, section, glyphMap, imagePositions, spacing, layoutTextSize); } if (i < logicalInput.length() - 1) { var ideographicBreak = charAllowsIdeographicBreaking(codePoint); if (breakable[codePoint] || ideographicBreak || section.imageName) { potentialLineBreaks.push(evaluateBreak(i + 1, currentX, targetWidth, potentialLineBreaks, calculatePenalty(codePoint, logicalInput.getCharCode(i + 1), ideographicBreak && hasServerSuggestedBreakpoints), false)); } } } return leastBadBreaks(evaluateBreak(logicalInput.length(), currentX, targetWidth, potentialLineBreaks, 0, true)); } function getAnchorAlignment(anchor) { var horizontalAlign = 0.5, verticalAlign = 0.5; switch (anchor) { case 'right': case 'top-right': case 'bottom-right': horizontalAlign = 1; break; case 'left': case 'top-left': case 'bottom-left': horizontalAlign = 0; break; } switch (anchor) { case 'bottom': case 'bottom-right': case 'bottom-left': verticalAlign = 1; break; case 'top': case 'top-right': case 'top-left': verticalAlign = 0; break; } return { horizontalAlign: horizontalAlign, verticalAlign: verticalAlign }; } function shapeLines(shaping, glyphMap, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement, layoutTextSizeThisZoom) { var x = 0; var y = SHAPING_DEFAULT_OFFSET; var maxLineLength = 0; var maxLineHeight = 0; var justify = textJustify === 'right' ? 1 : textJustify === 'left' ? 0 : 0.5; var lineIndex = 0; for (var i$1 = 0, list = lines; i$1 < list.length; i$1 += 1) { var line = list[i$1]; line.trim(); var lineMaxScale = line.getMaxScale(); var maxLineOffset = (lineMaxScale - 1) * ONE_EM; var positionedLine = { positionedGlyphs: [], lineOffset: 0 }; shaping.positionedLines[lineIndex] = positionedLine; var positionedGlyphs = positionedLine.positionedGlyphs; var lineOffset = 0; if (!line.length()) { y += lineHeight; ++lineIndex; continue; } for (var i = 0; i < line.length(); i++) { var section = line.getSection(i); var sectionIndex = line.getSectionIndex(i); var codePoint = line.getCharCode(i); var baselineOffset = 0; var metrics = null; var rect = null; var imageName = null; var verticalAdvance = ONE_EM; var vertical = !(writingMode === WritingMode.horizontal || !allowVerticalPlacement && !charHasUprightVerticalOrientation(codePoint) || allowVerticalPlacement && (whitespace[codePoint] || charInComplexShapingScript(codePoint))); if (!section.imageName) { var positions = glyphPositions[section.fontStack]; var glyphPosition = positions && positions[codePoint]; if (glyphPosition && glyphPosition.rect) { rect = glyphPosition.rect; metrics = glyphPosition.metrics; } else { var glyphs = glyphMap[section.fontStack]; var glyph = glyphs && glyphs[codePoint]; if (!glyph) { continue; } metrics = glyph.metrics; } baselineOffset = (lineMaxScale - section.scale) * ONE_EM; } else { var imagePosition = imagePositions[section.imageName]; if (!imagePosition) { continue; } imageName = section.imageName; shaping.iconsInText = shaping.iconsInText || true; rect = imagePosition.paddedRect; var size = imagePosition.displaySize; section.scale = section.scale * ONE_EM / layoutTextSizeThisZoom; metrics = { width: size[0], height: size[1], left: IMAGE_PADDING, top: -GLYPH_PBF_BORDER, advance: vertical ? size[1] : size[0] }; var imageOffset = ONE_EM - size[1] * section.scale; baselineOffset = maxLineOffset + imageOffset; verticalAdvance = metrics.advance; var offset = vertical ? size[0] * section.scale - ONE_EM * lineMaxScale : size[1] * section.scale - ONE_EM * lineMaxScale; if (offset > 0 && offset > lineOffset) { lineOffset = offset; } } if (!vertical) { positionedGlyphs.push({ glyph: codePoint, imageName: imageName, x: x, y: y + baselineOffset, vertical: vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex: sectionIndex, metrics: metrics, rect: rect }); x += metrics.advance * section.scale + spacing; } else { shaping.verticalizable = true; positionedGlyphs.push({ glyph: codePoint, imageName: imageName, x: x, y: y + baselineOffset, vertical: vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex: sectionIndex, metrics: metrics, rect: rect }); x += verticalAdvance * section.scale + spacing; } } if (positionedGlyphs.length !== 0) { var lineLength = x - spacing; maxLineLength = Math.max(lineLength, maxLineLength); justifyLine(positionedGlyphs, 0, positionedGlyphs.length - 1, justify, lineOffset); } x = 0; var currentLineHeight = lineHeight * lineMaxScale + lineOffset; positionedLine.lineOffset = Math.max(lineOffset, maxLineOffset); y += currentLineHeight; maxLineHeight = Math.max(currentLineHeight, maxLineHeight); ++lineIndex; } var height = y - SHAPING_DEFAULT_OFFSET; var ref = getAnchorAlignment(textAnchor); var horizontalAlign = ref.horizontalAlign; var verticalAlign = ref.verticalAlign; align$1(shaping.positionedLines, justify, horizontalAlign, verticalAlign, maxLineLength, maxLineHeight, lineHeight, height, lines.length); shaping.top += -verticalAlign * height; shaping.bottom = shaping.top + height; shaping.left += -horizontalAlign * maxLineLength; shaping.right = shaping.left + maxLineLength; } function justifyLine(positionedGlyphs, start, end, justify, lineOffset) { if (!justify && !lineOffset) { return; } var lastPositionedGlyph = positionedGlyphs[end]; var lastAdvance = lastPositionedGlyph.metrics.advance * lastPositionedGlyph.scale; var lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify; for (var j = start; j <= end; j++) { positionedGlyphs[j].x -= lineIndent; positionedGlyphs[j].y += lineOffset; } } function align$1(positionedLines, justify, horizontalAlign, verticalAlign, maxLineLength, maxLineHeight, lineHeight, blockHeight, lineCount) { var shiftX = (justify - horizontalAlign) * maxLineLength; var shiftY = 0; if (maxLineHeight !== lineHeight) { shiftY = -blockHeight * verticalAlign - SHAPING_DEFAULT_OFFSET; } else { shiftY = (-verticalAlign * lineCount + 0.5) * lineHeight; } for (var i$1 = 0, list$1 = positionedLines; i$1 < list$1.length; i$1 += 1) { var line = list$1[i$1]; for (var i = 0, list = line.positionedGlyphs; i < list.length; i += 1) { var positionedGlyph = list[i]; positionedGlyph.x += shiftX; positionedGlyph.y += shiftY; } } } function shapeIcon(image, iconOffset, iconAnchor) { var ref = getAnchorAlignment(iconAnchor); var horizontalAlign = ref.horizontalAlign; var verticalAlign = ref.verticalAlign; var dx = iconOffset[0]; var dy = iconOffset[1]; var x1 = dx - image.displaySize[0] * horizontalAlign; var x2 = x1 + image.displaySize[0]; var y1 = dy - image.displaySize[1] * verticalAlign; var y2 = y1 + image.displaySize[1]; return { image: image, top: y1, bottom: y2, left: x1, right: x2 }; } function fitIconToText(shapedIcon, shapedText, textFit, padding, iconOffset, fontScale) { var image = shapedIcon.image; var collisionPadding; if (image.content) { var content = image.content; var pixelRatio = image.pixelRatio || 1; collisionPadding = [ content[0] / pixelRatio, content[1] / pixelRatio, image.displaySize[0] - content[2] / pixelRatio, image.displaySize[1] - content[3] / pixelRatio ]; } var textLeft = shapedText.left * fontScale; var textRight = shapedText.right * fontScale; var top, right, bottom, left; if (textFit === 'width' || textFit === 'both') { left = iconOffset[0] + textLeft - padding[3]; right = iconOffset[0] + textRight + padding[1]; } else { left = iconOffset[0] + (textLeft + textRight - image.displaySize[0]) / 2; right = left + image.displaySize[0]; } var textTop = shapedText.top * fontScale; var textBottom = shapedText.bottom * fontScale; if (textFit === 'height' || textFit === 'both') { top = iconOffset[1] + textTop - padding[0]; bottom = iconOffset[1] + textBottom + padding[2]; } else { top = iconOffset[1] + (textTop + textBottom - image.displaySize[1]) / 2; bottom = top + image.displaySize[1]; } return { image: image, top: top, right: right, bottom: bottom, left: left, collisionPadding: collisionPadding }; } var Anchor = function (Point) { function Anchor(x, y, angle, segment) { Point.call(this, x, y); this.angle = angle; if (segment !== undefined) { this.segment = segment; } } if (Point) Anchor.__proto__ = Point; Anchor.prototype = Object.create(Point && Point.prototype); Anchor.prototype.constructor = Anchor; Anchor.prototype.clone = function clone() { return new Anchor(this.x, this.y, this.angle, this.segment); }; return Anchor; }(pointGeometry); register('Anchor', Anchor); var SIZE_PACK_FACTOR = 128; function getSizeData(tileZoom, value) { var expression = value.expression; if (expression.kind === 'constant') { var layoutSize = expression.evaluate(new EvaluationParameters(tileZoom + 1)); return { kind: 'constant', layoutSize: layoutSize }; } else if (expression.kind === 'source') { return { kind: 'source' }; } else { var zoomStops = expression.zoomStops; var interpolationType = expression.interpolationType; var lower = 0; while (lower < zoomStops.length && zoomStops[lower] <= tileZoom) { lower++; } lower = Math.max(0, lower - 1); var upper = lower; while (upper < zoomStops.length && zoomStops[upper] < tileZoom + 1) { upper++; } upper = Math.min(zoomStops.length - 1, upper); var minZoom = zoomStops[lower]; var maxZoom = zoomStops[upper]; if (expression.kind === 'composite') { return { kind: 'composite', minZoom: minZoom, maxZoom: maxZoom, interpolationType: interpolationType }; } var minSize = expression.evaluate(new EvaluationParameters(minZoom)); var maxSize = expression.evaluate(new EvaluationParameters(maxZoom)); return { kind: 'camera', minZoom: minZoom, maxZoom: maxZoom, minSize: minSize, maxSize: maxSize, interpolationType: interpolationType }; } } function evaluateSizeForFeature(sizeData, ref, ref$1) { var uSize = ref.uSize; var uSizeT = ref.uSizeT; var lowerSize = ref$1.lowerSize; var upperSize = ref$1.upperSize; if (sizeData.kind === 'source') { return lowerSize / SIZE_PACK_FACTOR; } else if (sizeData.kind === 'composite') { return number(lowerSize / SIZE_PACK_FACTOR, upperSize / SIZE_PACK_FACTOR, uSizeT); } return uSize; } function evaluateSizeForZoom(sizeData, zoom) { var uSizeT = 0; var uSize = 0; if (sizeData.kind === 'constant') { uSize = sizeData.layoutSize; } else if (sizeData.kind !== 'source') { var interpolationType = sizeData.interpolationType; var minZoom = sizeData.minZoom; var maxZoom = sizeData.maxZoom; var t = !interpolationType ? 0 : clamp(Interpolate.interpolationFactor(interpolationType, zoom, minZoom, maxZoom), 0, 1); if (sizeData.kind === 'camera') { uSize = number(sizeData.minSize, sizeData.maxSize, t); } else { uSizeT = t; } } return { uSizeT: uSizeT, uSize: uSize }; } var symbolSize = /*#__PURE__*/Object.freeze({ __proto__: null, getSizeData: getSizeData, evaluateSizeForFeature: evaluateSizeForFeature, evaluateSizeForZoom: evaluateSizeForZoom, SIZE_PACK_FACTOR: SIZE_PACK_FACTOR }); function checkMaxAngle(line, anchor, labelLength, windowSize, maxAngle) { if (anchor.segment === undefined) { return true; } var p = anchor; var index = anchor.segment + 1; var anchorDistance = 0; while (anchorDistance > -labelLength / 2) { index--; if (index < 0) { return false; } anchorDistance -= line[index].dist(p); p = line[index]; } anchorDistance += line[index].dist(line[index + 1]); index++; var recentCorners = []; var recentAngleDelta = 0; while (anchorDistance < labelLength / 2) { var prev = line[index - 1]; var current = line[index]; var next = line[index + 1]; if (!next) { return false; } var angleDelta = prev.angleTo(current) - current.angleTo(next); angleDelta = Math.abs((angleDelta + 3 * Math.PI) % (Math.PI * 2) - Math.PI); recentCorners.push({ distance: anchorDistance, angleDelta: angleDelta }); recentAngleDelta += angleDelta; while (anchorDistance - recentCorners[0].distance > windowSize) { recentAngleDelta -= recentCorners.shift().angleDelta; } if (recentAngleDelta > maxAngle) { return false; } index++; anchorDistance += current.dist(next); } return true; } function getLineLength(line) { var lineLength = 0; for (var k = 0; k < line.length - 1; k++) { lineLength += line[k].dist(line[k + 1]); } return lineLength; } function getAngleWindowSize(shapedText, glyphSize, boxScale) { return shapedText ? 3 / 5 * glyphSize * boxScale : 0; } function getShapedLabelLength(shapedText, shapedIcon) { return Math.max(shapedText ? shapedText.right - shapedText.left : 0, shapedIcon ? shapedIcon.right - shapedIcon.left : 0); } function getCenterAnchor(line, maxAngle, shapedText, shapedIcon, glyphSize, boxScale) { var angleWindowSize = getAngleWindowSize(shapedText, glyphSize, boxScale); var labelLength = getShapedLabelLength(shapedText, shapedIcon) * boxScale; var prevDistance = 0; var centerDistance = getLineLength(line) / 2; for (var i = 0; i < line.length - 1; i++) { var a = line[i], b = line[i + 1]; var segmentDistance = a.dist(b); if (prevDistance + segmentDistance > centerDistance) { var t = (centerDistance - prevDistance) / segmentDistance, x = number(a.x, b.x, t), y = number(a.y, b.y, t); var anchor = new Anchor(x, y, b.angleTo(a), i); anchor._round(); if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) { return anchor; } else { return; } } prevDistance += segmentDistance; } } function getAnchors(line, spacing, maxAngle, shapedText, shapedIcon, glyphSize, boxScale, overscaling, tileExtent) { var angleWindowSize = getAngleWindowSize(shapedText, glyphSize, boxScale); var shapedLabelLength = getShapedLabelLength(shapedText, shapedIcon); var labelLength = shapedLabelLength * boxScale; var isLineContinued = line[0].x === 0 || line[0].x === tileExtent || line[0].y === 0 || line[0].y === tileExtent; if (spacing - labelLength < spacing / 4) { spacing = labelLength + spacing / 4; } var fixedExtraOffset = glyphSize * 2; var offset = !isLineContinued ? (shapedLabelLength / 2 + fixedExtraOffset) * boxScale * overscaling % spacing : spacing / 2 * overscaling % spacing; return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, false, tileExtent); } function resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, placeAtMiddle, tileExtent) { var halfLabelLength = labelLength / 2; var lineLength = getLineLength(line); var distance = 0, markedDistance = offset - spacing; var anchors = []; for (var i = 0; i < line.length - 1; i++) { var a = line[i], b = line[i + 1]; var segmentDist = a.dist(b), angle = b.angleTo(a); while (markedDistance + spacing < distance + segmentDist) { markedDistance += spacing; var t = (markedDistance - distance) / segmentDist, x = number(a.x, b.x, t), y = number(a.y, b.y, t); if (x >= 0 && x < tileExtent && y >= 0 && y < tileExtent && markedDistance - halfLabelLength >= 0 && markedDistance + halfLabelLength <= lineLength) { var anchor = new Anchor(x, y, angle, i); anchor._round(); if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) { anchors.push(anchor); } } } distance += segmentDist; } if (!placeAtMiddle && !anchors.length && !isLineContinued) { anchors = resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, true, tileExtent); } return anchors; } function clipLine(lines, x1, y1, x2, y2) { var clippedLines = []; for (var l = 0; l < lines.length; l++) { var line = lines[l]; var clippedLine = void 0; for (var i = 0; i < line.length - 1; i++) { var p0 = line[i]; var p1 = line[i + 1]; if (p0.x < x1 && p1.x < x1) { continue; } else if (p0.x < x1) { p0 = new pointGeometry(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round(); } else if (p1.x < x1) { p1 = new pointGeometry(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round(); } if (p0.y < y1 && p1.y < y1) { continue; } else if (p0.y < y1) { p0 = new pointGeometry(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round(); } else if (p1.y < y1) { p1 = new pointGeometry(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round(); } if (p0.x >= x2 && p1.x >= x2) { continue; } else if (p0.x >= x2) { p0 = new pointGeometry(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round(); } else if (p1.x >= x2) { p1 = new pointGeometry(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round(); } if (p0.y >= y2 && p1.y >= y2) { continue; } else if (p0.y >= y2) { p0 = new pointGeometry(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round(); } else if (p1.y >= y2) { p1 = new pointGeometry(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round(); } if (!clippedLine || !p0.equals(clippedLine[clippedLine.length - 1])) { clippedLine = [p0]; clippedLines.push(clippedLine); } clippedLine.push(p1); } } return clippedLines; } var border$1 = IMAGE_PADDING; function getIconQuads(shapedIcon, iconRotate, isSDFIcon, hasIconTextFit) { var quads = []; var image = shapedIcon.image; var pixelRatio = image.pixelRatio; var imageWidth = image.paddedRect.w - 2 * border$1; var imageHeight = image.paddedRect.h - 2 * border$1; var iconWidth = shapedIcon.right - shapedIcon.left; var iconHeight = shapedIcon.bottom - shapedIcon.top; var stretchX = image.stretchX || [[ 0, imageWidth ]]; var stretchY = image.stretchY || [[ 0, imageHeight ]]; var reduceRanges = function (sum, range) { return sum + range[1] - range[0]; }; var stretchWidth = stretchX.reduce(reduceRanges, 0); var stretchHeight = stretchY.reduce(reduceRanges, 0); var fixedWidth = imageWidth - stretchWidth; var fixedHeight = imageHeight - stretchHeight; var stretchOffsetX = 0; var stretchContentWidth = stretchWidth; var stretchOffsetY = 0; var stretchContentHeight = stretchHeight; var fixedOffsetX = 0; var fixedContentWidth = fixedWidth; var fixedOffsetY = 0; var fixedContentHeight = fixedHeight; if (image.content && hasIconTextFit) { var content = image.content; stretchOffsetX = sumWithinRange(stretchX, 0, content[0]); stretchOffsetY = sumWithinRange(stretchY, 0, content[1]); stretchContentWidth = sumWithinRange(stretchX, content[0], content[2]); stretchContentHeight = sumWithinRange(stretchY, content[1], content[3]); fixedOffsetX = content[0] - stretchOffsetX; fixedOffsetY = content[1] - stretchOffsetY; fixedContentWidth = content[2] - content[0] - stretchContentWidth; fixedContentHeight = content[3] - content[1] - stretchContentHeight; } var makeBox = function (left, top, right, bottom) { var leftEm = getEmOffset(left.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); var leftPx = getPxOffset(left.fixed - fixedOffsetX, fixedContentWidth, left.stretch, stretchWidth); var topEm = getEmOffset(top.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top); var topPx = getPxOffset(top.fixed - fixedOffsetY, fixedContentHeight, top.stretch, stretchHeight); var rightEm = getEmOffset(right.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); var rightPx = getPxOffset(right.fixed - fixedOffsetX, fixedContentWidth, right.stretch, stretchWidth); var bottomEm = getEmOffset(bottom.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top); var bottomPx = getPxOffset(bottom.fixed - fixedOffsetY, fixedContentHeight, bottom.stretch, stretchHeight); var tl = new pointGeometry(leftEm, topEm); var tr = new pointGeometry(rightEm, topEm); var br = new pointGeometry(rightEm, bottomEm); var bl = new pointGeometry(leftEm, bottomEm); var pixelOffsetTL = new pointGeometry(leftPx / pixelRatio, topPx / pixelRatio); var pixelOffsetBR = new pointGeometry(rightPx / pixelRatio, bottomPx / pixelRatio); var angle = iconRotate * Math.PI / 180; if (angle) { var sin = Math.sin(angle), cos = Math.cos(angle), matrix = [ cos, -sin, sin, cos ]; tl._matMult(matrix); tr._matMult(matrix); bl._matMult(matrix); br._matMult(matrix); } var x1 = left.stretch + left.fixed; var x2 = right.stretch + right.fixed; var y1 = top.stretch + top.fixed; var y2 = bottom.stretch + bottom.fixed; var subRect = { x: image.paddedRect.x + border$1 + x1, y: image.paddedRect.y + border$1 + y1, w: x2 - x1, h: y2 - y1 }; var minFontScaleX = fixedContentWidth / pixelRatio / iconWidth; var minFontScaleY = fixedContentHeight / pixelRatio / iconHeight; return { tl: tl, tr: tr, bl: bl, br: br, tex: subRect, writingMode: undefined, glyphOffset: [ 0, 0 ], sectionIndex: 0, pixelOffsetTL: pixelOffsetTL, pixelOffsetBR: pixelOffsetBR, minFontScaleX: minFontScaleX, minFontScaleY: minFontScaleY, isSDF: isSDFIcon }; }; if (!hasIconTextFit || !image.stretchX && !image.stretchY) { quads.push(makeBox({ fixed: 0, stretch: -1 }, { fixed: 0, stretch: -1 }, { fixed: 0, stretch: imageWidth + 1 }, { fixed: 0, stretch: imageHeight + 1 })); } else { var xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth); var yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight); for (var xi = 0; xi < xCuts.length - 1; xi++) { var x1 = xCuts[xi]; var x2 = xCuts[xi + 1]; for (var yi = 0; yi < yCuts.length - 1; yi++) { var y1 = yCuts[yi]; var y2 = yCuts[yi + 1]; quads.push(makeBox(x1, y1, x2, y2)); } } } return quads; } function sumWithinRange(ranges, min, max) { var sum = 0; for (var i = 0, list = ranges; i < list.length; i += 1) { var range = list[i]; sum += Math.max(min, Math.min(max, range[1])) - Math.max(min, Math.min(max, range[0])); } return sum; } function stretchZonesToCuts(stretchZones, fixedSize, stretchSize) { var cuts = [{ fixed: -border$1, stretch: 0 }]; for (var i = 0, list = stretchZones; i < list.length; i += 1) { var ref = list[i]; var c1 = ref[0]; var c2 = ref[1]; var last = cuts[cuts.length - 1]; cuts.push({ fixed: c1 - last.stretch, stretch: last.stretch }); cuts.push({ fixed: c1 - last.stretch, stretch: last.stretch + (c2 - c1) }); } cuts.push({ fixed: fixedSize + border$1, stretch: stretchSize }); return cuts; } function getEmOffset(stretchOffset, stretchSize, iconSize, iconOffset) { return stretchOffset / stretchSize * iconSize + iconOffset; } function getPxOffset(fixedOffset, fixedSize, stretchOffset, stretchSize) { return fixedOffset - fixedSize * stretchOffset / stretchSize; } function getGlyphQuads(anchor, shaping, textOffset, layer, alongLine, feature, imageMap, allowVerticalPlacement) { var textRotate = layer.layout.get('text-rotate').evaluate(feature, {}) * Math.PI / 180; var quads = []; for (var i$1 = 0, list$1 = shaping.positionedLines; i$1 < list$1.length; i$1 += 1) { var line = list$1[i$1]; for (var i = 0, list = line.positionedGlyphs; i < list.length; i += 1) { var positionedGlyph = list[i]; if (!positionedGlyph.rect) { continue; } var textureRect = positionedGlyph.rect || {}; var glyphPadding = 1; var rectBuffer = GLYPH_PBF_BORDER + glyphPadding; var isSDF = true; var pixelRatio = 1; var lineOffset = 0; var rotateVerticalGlyph = (alongLine || allowVerticalPlacement) && positionedGlyph.vertical; var halfAdvance = positionedGlyph.metrics.advance * positionedGlyph.scale / 2; if (allowVerticalPlacement && shaping.verticalizable) { var scaledGlyphOffset = (positionedGlyph.scale - 1) * ONE_EM; var imageOffset = (ONE_EM - positionedGlyph.metrics.width * positionedGlyph.scale) / 2; lineOffset = line.lineOffset / 2 - (positionedGlyph.imageName ? -imageOffset : scaledGlyphOffset); } if (positionedGlyph.imageName) { var image = imageMap[positionedGlyph.imageName]; isSDF = image.sdf; pixelRatio = image.pixelRatio; rectBuffer = IMAGE_PADDING / pixelRatio; } var glyphOffset = alongLine ? [ positionedGlyph.x + halfAdvance, positionedGlyph.y ] : [ 0, 0 ]; var builtInOffset = alongLine ? [ 0, 0 ] : [ positionedGlyph.x + halfAdvance + textOffset[0], positionedGlyph.y + textOffset[1] - lineOffset ]; var verticalizedLabelOffset = [ 0, 0 ]; if (rotateVerticalGlyph) { verticalizedLabelOffset = builtInOffset; builtInOffset = [ 0, 0 ]; } var x1 = (positionedGlyph.metrics.left - rectBuffer) * positionedGlyph.scale - halfAdvance + builtInOffset[0]; var y1 = (-positionedGlyph.metrics.top - rectBuffer) * positionedGlyph.scale + builtInOffset[1]; var x2 = x1 + textureRect.w * positionedGlyph.scale / pixelRatio; var y2 = y1 + textureRect.h * positionedGlyph.scale / pixelRatio; var tl = new pointGeometry(x1, y1); var tr = new pointGeometry(x2, y1); var bl = new pointGeometry(x1, y2); var br = new pointGeometry(x2, y2); if (rotateVerticalGlyph) { var center = new pointGeometry(-halfAdvance, halfAdvance - SHAPING_DEFAULT_OFFSET); var verticalRotation = -Math.PI / 2; var xHalfWidthOffsetCorrection = ONE_EM / 2 - halfAdvance; var yImageOffsetCorrection = positionedGlyph.imageName ? xHalfWidthOffsetCorrection : 0; var halfWidthOffsetCorrection = new pointGeometry(5 - SHAPING_DEFAULT_OFFSET - xHalfWidthOffsetCorrection, -yImageOffsetCorrection); var verticalOffsetCorrection = new (Function.prototype.bind.apply(pointGeometry, [null].concat(verticalizedLabelOffset)))(); tl._rotateAround(verticalRotation, center)._add(halfWidthOffsetCorrection)._add(verticalOffsetCorrection); tr._rotateAround(verticalRotation, center)._add(halfWidthOffsetCorrection)._add(verticalOffsetCorrection); bl._rotateAround(verticalRotation, center)._add(halfWidthOffsetCorrection)._add(verticalOffsetCorrection); br._rotateAround(verticalRotation, center)._add(halfWidthOffsetCorrection)._add(verticalOffsetCorrection); } if (textRotate) { var sin = Math.sin(textRotate), cos = Math.cos(textRotate), matrix = [ cos, -sin, sin, cos ]; tl._matMult(matrix); tr._matMult(matrix); bl._matMult(matrix); br._matMult(matrix); } var pixelOffsetTL = new pointGeometry(0, 0); var pixelOffsetBR = new pointGeometry(0, 0); var minFontScaleX = 0; var minFontScaleY = 0; quads.push({ tl: tl, tr: tr, bl: bl, br: br, tex: textureRect, writingMode: shaping.writingMode, glyphOffset: glyphOffset, sectionIndex: positionedGlyph.sectionIndex, isSDF: isSDF, pixelOffsetTL: pixelOffsetTL, pixelOffsetBR: pixelOffsetBR, minFontScaleX: minFontScaleX, minFontScaleY: minFontScaleY }); } } return quads; } var CollisionFeature = function CollisionFeature(collisionBoxArray, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaped, boxScale, padding, alignLine, rotate) { this.boxStartIndex = collisionBoxArray.length; if (alignLine) { var top = shaped.top; var bottom = shaped.bottom; var collisionPadding = shaped.collisionPadding; if (collisionPadding) { top -= collisionPadding[1]; bottom += collisionPadding[3]; } var height = bottom - top; if (height > 0) { height = Math.max(10, height); this.circleDiameter = height; } } else { var y1 = shaped.top * boxScale - padding; var y2 = shaped.bottom * boxScale + padding; var x1 = shaped.left * boxScale - padding; var x2 = shaped.right * boxScale + padding; var collisionPadding$1 = shaped.collisionPadding; if (collisionPadding$1) { x1 -= collisionPadding$1[0] * boxScale; y1 -= collisionPadding$1[1] * boxScale; x2 += collisionPadding$1[2] * boxScale; y2 += collisionPadding$1[3] * boxScale; } if (rotate) { var tl = new pointGeometry(x1, y1); var tr = new pointGeometry(x2, y1); var bl = new pointGeometry(x1, y2); var br = new pointGeometry(x2, y2); var rotateRadians = rotate * Math.PI / 180; tl._rotate(rotateRadians); tr._rotate(rotateRadians); bl._rotate(rotateRadians); br._rotate(rotateRadians); x1 = Math.min(tl.x, tr.x, bl.x, br.x); x2 = Math.max(tl.x, tr.x, bl.x, br.x); y1 = Math.min(tl.y, tr.y, bl.y, br.y); y2 = Math.max(tl.y, tr.y, bl.y, br.y); } collisionBoxArray.emplaceBack(anchor.x, anchor.y, x1, y1, x2, y2, featureIndex, sourceLayerIndex, bucketIndex); } this.boxEndIndex = collisionBoxArray.length; }; var TinyQueue = function TinyQueue(data, compare) { if (data === void 0) data = []; if (compare === void 0) compare = defaultCompare$1; this.data = data; this.length = this.data.length; this.compare = compare; if (this.length > 0) { for (var i = (this.length >> 1) - 1; i >= 0; i--) { this._down(i); } } }; TinyQueue.prototype.push = function push(item) { this.data.push(item); this.length++; this._up(this.length - 1); }; TinyQueue.prototype.pop = function pop() { if (this.length === 0) { return undefined; } var top = this.data[0]; var bottom = this.data.pop(); this.length--; if (this.length > 0) { this.data[0] = bottom; this._down(0); } return top; }; TinyQueue.prototype.peek = function peek() { return this.data[0]; }; TinyQueue.prototype._up = function _up(pos) { var ref = this; var data = ref.data; var compare = ref.compare; var item = data[pos]; while (pos > 0) { var parent = pos - 1 >> 1; var current = data[parent]; if (compare(item, current) >= 0) { break; } data[pos] = current; pos = parent; } data[pos] = item; }; TinyQueue.prototype._down = function _down(pos) { var ref = this; var data = ref.data; var compare = ref.compare; var halfLength = this.length >> 1; var item = data[pos]; while (pos < halfLength) { var left = (pos << 1) + 1; var best = data[left]; var right = left + 1; if (right < this.length && compare(data[right], best) < 0) { left = right; best = data[right]; } if (compare(best, item) >= 0) { break; } data[pos] = best; pos = left; } data[pos] = item; }; function defaultCompare$1(a, b) { return a < b ? -1 : a > b ? 1 : 0; } function findPoleOfInaccessibility (polygonRings, precision, debug) { if (precision === void 0) precision = 1; if (debug === void 0) debug = false; var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; var outerRing = polygonRings[0]; for (var i = 0; i < outerRing.length; i++) { var p = outerRing[i]; if (!i || p.x < minX) { minX = p.x; } if (!i || p.y < minY) { minY = p.y; } if (!i || p.x > maxX) { maxX = p.x; } if (!i || p.y > maxY) { maxY = p.y; } } var width = maxX - minX; var height = maxY - minY; var cellSize = Math.min(width, height); var h = cellSize / 2; var cellQueue = new TinyQueue([], compareMax); if (cellSize === 0) { return new pointGeometry(minX, minY); } for (var x = minX; x < maxX; x += cellSize) { for (var y = minY; y < maxY; y += cellSize) { cellQueue.push(new Cell(x + h, y + h, h, polygonRings)); } } var bestCell = getCentroidCell(polygonRings); var numProbes = cellQueue.length; while (cellQueue.length) { var cell = cellQueue.pop(); if (cell.d > bestCell.d || !bestCell.d) { bestCell = cell; if (debug) { console.log('found best %d after %d probes', Math.round(10000 * cell.d) / 10000, numProbes); } } if (cell.max - bestCell.d <= precision) { continue; } h = cell.h / 2; cellQueue.push(new Cell(cell.p.x - h, cell.p.y - h, h, polygonRings)); cellQueue.push(new Cell(cell.p.x + h, cell.p.y - h, h, polygonRings)); cellQueue.push(new Cell(cell.p.x - h, cell.p.y + h, h, polygonRings)); cellQueue.push(new Cell(cell.p.x + h, cell.p.y + h, h, polygonRings)); numProbes += 4; } if (debug) { console.log('num probes: ' + numProbes); console.log('best distance: ' + bestCell.d); } return bestCell.p; } function compareMax(a, b) { return b.max - a.max; } function Cell(x, y, h, polygon) { this.p = new pointGeometry(x, y); this.h = h; this.d = pointToPolygonDist(this.p, polygon); this.max = this.d + this.h * Math.SQRT2; } function pointToPolygonDist(p, polygon) { var inside = false; var minDistSq = Infinity; for (var k = 0; k < polygon.length; k++) { var ring = polygon[k]; for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) { var a = ring[i]; var b = ring[j]; if (a.y > p.y !== b.y > p.y && p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x) { inside = !inside; } minDistSq = Math.min(minDistSq, distToSegmentSquared(p, a, b)); } } return (inside ? 1 : -1) * Math.sqrt(minDistSq); } function getCentroidCell(polygon) { var area = 0; var x = 0; var y = 0; var points = polygon[0]; for (var i = 0, len = points.length, j = len - 1; i < len; j = i++) { var a = points[i]; var b = points[j]; var f = a.x * b.y - b.x * a.y; x += (a.x + b.x) * f; y += (a.y + b.y) * f; area += f * 3; } return new Cell(x / area, y / area, 0, polygon); } var baselineOffset = 7; var INVALID_TEXT_OFFSET = Number.POSITIVE_INFINITY; function evaluateVariableOffset(anchor, offset) { function fromRadialOffset(anchor, radialOffset) { var x = 0, y = 0; if (radialOffset < 0) { radialOffset = 0; } var hypotenuse = radialOffset / Math.sqrt(2); switch (anchor) { case 'top-right': case 'top-left': y = hypotenuse - baselineOffset; break; case 'bottom-right': case 'bottom-left': y = -hypotenuse + baselineOffset; break; case 'bottom': y = -radialOffset + baselineOffset; break; case 'top': y = radialOffset - baselineOffset; break; } switch (anchor) { case 'top-right': case 'bottom-right': x = -hypotenuse; break; case 'top-left': case 'bottom-left': x = hypotenuse; break; case 'left': x = radialOffset; break; case 'right': x = -radialOffset; break; } return [ x, y ]; } function fromTextOffset(anchor, offsetX, offsetY) { var x = 0, y = 0; offsetX = Math.abs(offsetX); offsetY = Math.abs(offsetY); switch (anchor) { case 'top-right': case 'top-left': case 'top': y = offsetY - baselineOffset; break; case 'bottom-right': case 'bottom-left': case 'bottom': y = -offsetY + baselineOffset; break; } switch (anchor) { case 'top-right': case 'bottom-right': case 'right': x = -offsetX; break; case 'top-left': case 'bottom-left': case 'left': x = offsetX; break; } return [ x, y ]; } return offset[1] !== INVALID_TEXT_OFFSET ? fromTextOffset(anchor, offset[0], offset[1]) : fromRadialOffset(anchor, offset[0]); } function performSymbolLayout(bucket, glyphMap, glyphPositions, imageMap, imagePositions, showCollisionBoxes, canonical) { bucket.createArrays(); var tileSize = 512 * bucket.overscaling; bucket.tilePixelRatio = EXTENT$1 / tileSize; bucket.compareText = {}; bucket.iconsNeedLinear = false; var layout = bucket.layers[0].layout; var unevaluatedLayoutValues = bucket.layers[0]._unevaluatedLayout._values; var sizes = {}; if (bucket.textSizeData.kind === 'composite') { var ref = bucket.textSizeData; var minZoom = ref.minZoom; var maxZoom = ref.maxZoom; sizes.compositeTextSizes = [ unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(minZoom), canonical), unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), canonical) ]; } if (bucket.iconSizeData.kind === 'composite') { var ref$1 = bucket.iconSizeData; var minZoom$1 = ref$1.minZoom; var maxZoom$1 = ref$1.maxZoom; sizes.compositeIconSizes = [ unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(minZoom$1), canonical), unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(maxZoom$1), canonical) ]; } sizes.layoutTextSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical); sizes.layoutIconSize = unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical); sizes.textMaxSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(18)); var lineHeight = layout.get('text-line-height') * ONE_EM; var textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point'; var keepUpright = layout.get('text-keep-upright'); var textSize = layout.get('text-size'); var loop = function () { var feature = list[i$1]; var fontstack = layout.get('text-font').evaluate(feature, {}, canonical).join(','); var layoutTextSizeThisZoom = textSize.evaluate(feature, {}, canonical); var layoutTextSize = sizes.layoutTextSize.evaluate(feature, {}, canonical); var layoutIconSize = sizes.layoutIconSize.evaluate(feature, {}, canonical); var shapedTextOrientations = { horizontal: {}, vertical: undefined }; var text = feature.text; var textOffset = [ 0, 0 ]; if (text) { var unformattedText = text.toString(); var spacing = layout.get('text-letter-spacing').evaluate(feature, {}, canonical) * ONE_EM; var spacingIfAllowed = allowsLetterSpacing(unformattedText) ? spacing : 0; var textAnchor = layout.get('text-anchor').evaluate(feature, {}, canonical); var variableTextAnchor = layout.get('text-variable-anchor'); if (!variableTextAnchor) { var radialOffset = layout.get('text-radial-offset').evaluate(feature, {}, canonical); if (radialOffset) { textOffset = evaluateVariableOffset(textAnchor, [ radialOffset * ONE_EM, INVALID_TEXT_OFFSET ]); } else { textOffset = layout.get('text-offset').evaluate(feature, {}, canonical).map(function (t) { return t * ONE_EM; }); } } var textJustify = textAlongLine ? 'center' : layout.get('text-justify').evaluate(feature, {}, canonical); var symbolPlacement = layout.get('symbol-placement'); var maxWidth = symbolPlacement === 'point' ? layout.get('text-max-width').evaluate(feature, {}, canonical) * ONE_EM : 0; var addVerticalShapingForPointLabelIfNeeded = function () { if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) { shapedTextOrientations.vertical = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, 'left', spacingIfAllowed, textOffset, WritingMode.vertical, true, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom); } }; if (!textAlongLine && variableTextAnchor) { var justifications = textJustify === 'auto' ? variableTextAnchor.map(function (a) { return getAnchorJustification(a); }) : [textJustify]; var singleLine = false; for (var i = 0; i < justifications.length; i++) { var justification = justifications[i]; if (shapedTextOrientations.horizontal[justification]) { continue; } if (singleLine) { shapedTextOrientations.horizontal[justification] = shapedTextOrientations.horizontal[0]; } else { var shaping = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, 'center', justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom); if (shaping) { shapedTextOrientations.horizontal[justification] = shaping; singleLine = shaping.positionedLines.length === 1; } } } addVerticalShapingForPointLabelIfNeeded(); } else { if (textJustify === 'auto') { textJustify = getAnchorJustification(textAnchor); } var shaping$1 = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed, textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom); if (shaping$1) { shapedTextOrientations.horizontal[textJustify] = shaping$1; } addVerticalShapingForPointLabelIfNeeded(); if (allowsVerticalWritingMode(unformattedText) && textAlongLine && keepUpright) { shapedTextOrientations.vertical = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed, textOffset, WritingMode.vertical, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom); } } } var shapedIcon = void 0; var isSDFIcon = false; if (feature.icon && feature.icon.name) { var image = imageMap[feature.icon.name]; if (image) { shapedIcon = shapeIcon(imagePositions[feature.icon.name], layout.get('icon-offset').evaluate(feature, {}, canonical), layout.get('icon-anchor').evaluate(feature, {}, canonical)); isSDFIcon = image.sdf; if (bucket.sdfIcons === undefined) { bucket.sdfIcons = image.sdf; } else if (bucket.sdfIcons !== image.sdf) { warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer'); } if (image.pixelRatio !== bucket.pixelRatio) { bucket.iconsNeedLinear = true; } else if (layout.get('icon-rotate').constantOr(1) !== 0) { bucket.iconsNeedLinear = true; } } } var shapedText = getDefaultHorizontalShaping(shapedTextOrientations.horizontal) || shapedTextOrientations.vertical; bucket.iconsInText = shapedText ? shapedText.iconsInText : false; if (shapedText || shapedIcon) { addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, canonical); } }; for (var i$1 = 0, list = bucket.features; i$1 < list.length; i$1 += 1) loop(); if (showCollisionBoxes) { bucket.generateCollisionDebugBuffers(); } } function getAnchorJustification(anchor) { switch (anchor) { case 'right': case 'top-right': case 'bottom-right': return 'right'; case 'left': case 'top-left': case 'bottom-left': return 'left'; } return 'center'; } function addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, canonical) { var textMaxSize = sizes.textMaxSize.evaluate(feature, {}); if (textMaxSize === undefined) { textMaxSize = layoutTextSize; } var layout = bucket.layers[0].layout; var iconOffset = layout.get('icon-offset').evaluate(feature, {}, canonical); var defaultHorizontalShaping = getDefaultHorizontalShaping(shapedTextOrientations.horizontal); var glyphSize = 24, fontScale = layoutTextSize / glyphSize, textBoxScale = bucket.tilePixelRatio * fontScale, textMaxBoxScale = bucket.tilePixelRatio * textMaxSize / glyphSize, iconBoxScale = bucket.tilePixelRatio * layoutIconSize, symbolMinDistance = bucket.tilePixelRatio * layout.get('symbol-spacing'), textPadding = layout.get('text-padding') * bucket.tilePixelRatio, iconPadding = layout.get('icon-padding') * bucket.tilePixelRatio, textMaxAngle = layout.get('text-max-angle') / 180 * Math.PI, textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point', iconAlongLine = layout.get('icon-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point', symbolPlacement = layout.get('symbol-placement'), textRepeatDistance = symbolMinDistance / 2; var iconTextFit = layout.get('icon-text-fit'); var verticallyShapedIcon; if (shapedIcon && iconTextFit !== 'none') { if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) { verticallyShapedIcon = fitIconToText(shapedIcon, shapedTextOrientations.vertical, iconTextFit, layout.get('icon-text-fit-padding'), iconOffset, fontScale); } if (defaultHorizontalShaping) { shapedIcon = fitIconToText(shapedIcon, defaultHorizontalShaping, iconTextFit, layout.get('icon-text-fit-padding'), iconOffset, fontScale); } } var addSymbolAtAnchor = function (line, anchor) { if (anchor.x < 0 || anchor.x >= EXTENT$1 || anchor.y < 0 || anchor.y >= EXTENT$1) { return; } addSymbol(bucket, anchor, line, shapedTextOrientations, shapedIcon, imageMap, verticallyShapedIcon, bucket.layers[0], bucket.collisionBoxArray, feature.index, feature.sourceLayerIndex, bucket.index, textBoxScale, textPadding, textAlongLine, textOffset, iconBoxScale, iconPadding, iconAlongLine, iconOffset, feature, sizes, isSDFIcon, canonical, layoutTextSize); }; if (symbolPlacement === 'line') { for (var i$1 = 0, list$1 = clipLine(feature.geometry, 0, 0, EXTENT$1, EXTENT$1); i$1 < list$1.length; i$1 += 1) { var line = list$1[i$1]; var anchors = getAnchors(line, symbolMinDistance, textMaxAngle, shapedTextOrientations.vertical || defaultHorizontalShaping, shapedIcon, glyphSize, textMaxBoxScale, bucket.overscaling, EXTENT$1); for (var i = 0, list = anchors; i < list.length; i += 1) { var anchor = list[i]; var shapedText = defaultHorizontalShaping; if (!shapedText || !anchorIsTooClose(bucket, shapedText.text, textRepeatDistance, anchor)) { addSymbolAtAnchor(line, anchor); } } } } else if (symbolPlacement === 'line-center') { for (var i$2 = 0, list$2 = feature.geometry; i$2 < list$2.length; i$2 += 1) { var line$1 = list$2[i$2]; if (line$1.length > 1) { var anchor$1 = getCenterAnchor(line$1, textMaxAngle, shapedTextOrientations.vertical || defaultHorizontalShaping, shapedIcon, glyphSize, textMaxBoxScale); if (anchor$1) { addSymbolAtAnchor(line$1, anchor$1); } } } } else if (feature.type === 'Polygon') { for (var i$3 = 0, list$3 = classifyRings(feature.geometry, 0); i$3 < list$3.length; i$3 += 1) { var polygon = list$3[i$3]; var poi = findPoleOfInaccessibility(polygon, 16); addSymbolAtAnchor(polygon[0], new Anchor(poi.x, poi.y, 0)); } } else if (feature.type === 'LineString') { for (var i$4 = 0, list$4 = feature.geometry; i$4 < list$4.length; i$4 += 1) { var line$2 = list$4[i$4]; addSymbolAtAnchor(line$2, new Anchor(line$2[0].x, line$2[0].y, 0)); } } else if (feature.type === 'Point') { for (var i$6 = 0, list$6 = feature.geometry; i$6 < list$6.length; i$6 += 1) { var points = list$6[i$6]; for (var i$5 = 0, list$5 = points; i$5 < list$5.length; i$5 += 1) { var point = list$5[i$5]; addSymbolAtAnchor([point], new Anchor(point.x, point.y, 0)); } } } } var MAX_GLYPH_ICON_SIZE = 255; var MAX_PACKED_SIZE = MAX_GLYPH_ICON_SIZE * SIZE_PACK_FACTOR; function addTextVertices(bucket, anchor, shapedText, imageMap, layer, textAlongLine, feature, textOffset, lineArray, writingMode, placementTypes, placedTextSymbolIndices, placedIconIndex, sizes, canonical) { var glyphQuads = getGlyphQuads(anchor, shapedText, textOffset, layer, textAlongLine, feature, imageMap, bucket.allowVerticalPlacement); var sizeData = bucket.textSizeData; var textSizeData = null; if (sizeData.kind === 'source') { textSizeData = [SIZE_PACK_FACTOR * layer.layout.get('text-size').evaluate(feature, {})]; if (textSizeData[0] > MAX_PACKED_SIZE) { warnOnce(bucket.layerIds[0] + ': Value for "text-size" is >= ' + MAX_GLYPH_ICON_SIZE + '. Reduce your "text-size".'); } } else if (sizeData.kind === 'composite') { textSizeData = [ SIZE_PACK_FACTOR * sizes.compositeTextSizes[0].evaluate(feature, {}, canonical), SIZE_PACK_FACTOR * sizes.compositeTextSizes[1].evaluate(feature, {}, canonical) ]; if (textSizeData[0] > MAX_PACKED_SIZE || textSizeData[1] > MAX_PACKED_SIZE) { warnOnce(bucket.layerIds[0] + ': Value for "text-size" is >= ' + MAX_GLYPH_ICON_SIZE + '. Reduce your "text-size".'); } } bucket.addSymbols(bucket.text, glyphQuads, textSizeData, textOffset, textAlongLine, feature, writingMode, anchor, lineArray.lineStartIndex, lineArray.lineLength, placedIconIndex, canonical); for (var i = 0, list = placementTypes; i < list.length; i += 1) { var placementType = list[i]; placedTextSymbolIndices[placementType] = bucket.text.placedSymbolArray.length - 1; } return glyphQuads.length * 4; } function getDefaultHorizontalShaping(horizontalShaping) { for (var justification in horizontalShaping) { return horizontalShaping[justification]; } return null; } function addSymbol(bucket, anchor, line, shapedTextOrientations, shapedIcon, imageMap, verticallyShapedIcon, layer, collisionBoxArray, featureIndex, sourceLayerIndex, bucketIndex, textBoxScale, textPadding, textAlongLine, textOffset, iconBoxScale, iconPadding, iconAlongLine, iconOffset, feature, sizes, isSDFIcon, canonical, layoutTextSize) { var assign; var lineArray = bucket.addToLineVertexArray(anchor, line); var textCollisionFeature, iconCollisionFeature, verticalTextCollisionFeature, verticalIconCollisionFeature; var numIconVertices = 0; var numVerticalIconVertices = 0; var numHorizontalGlyphVertices = 0; var numVerticalGlyphVertices = 0; var placedIconSymbolIndex = -1; var verticalPlacedIconSymbolIndex = -1; var placedTextSymbolIndices = {}; var key = murmurhashJs(''); var textOffset0 = 0; var textOffset1 = 0; if (layer._unevaluatedLayout.getValue('text-radial-offset') === undefined) { assign = layer.layout.get('text-offset').evaluate(feature, {}, canonical).map(function (t) { return t * ONE_EM; }), textOffset0 = assign[0], textOffset1 = assign[1]; } else { textOffset0 = layer.layout.get('text-radial-offset').evaluate(feature, {}, canonical) * ONE_EM; textOffset1 = INVALID_TEXT_OFFSET; } if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) { var textRotation = layer.layout.get('text-rotate').evaluate(feature, {}, canonical); var verticalTextRotation = textRotation + 90; var verticalShaping = shapedTextOrientations.vertical; verticalTextCollisionFeature = new CollisionFeature(collisionBoxArray, anchor, featureIndex, sourceLayerIndex, bucketIndex, verticalShaping, textBoxScale, textPadding, textAlongLine, verticalTextRotation); if (verticallyShapedIcon) { verticalIconCollisionFeature = new CollisionFeature(collisionBoxArray, anchor, featureIndex, sourceLayerIndex, bucketIndex, verticallyShapedIcon, iconBoxScale, iconPadding, textAlongLine, verticalTextRotation); } } if (shapedIcon) { var iconRotate = layer.layout.get('icon-rotate').evaluate(feature, {}); var hasIconTextFit = layer.layout.get('icon-text-fit') !== 'none'; var iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon, hasIconTextFit); var verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon, hasIconTextFit) : undefined; iconCollisionFeature = new CollisionFeature(collisionBoxArray, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, false, iconRotate); numIconVertices = iconQuads.length * 4; var sizeData = bucket.iconSizeData; var iconSizeData = null; if (sizeData.kind === 'source') { iconSizeData = [SIZE_PACK_FACTOR * layer.layout.get('icon-size').evaluate(feature, {})]; if (iconSizeData[0] > MAX_PACKED_SIZE) { warnOnce(bucket.layerIds[0] + ': Value for "icon-size" is >= ' + MAX_GLYPH_ICON_SIZE + '. Reduce your "icon-size".'); } } else if (sizeData.kind === 'composite') { iconSizeData = [ SIZE_PACK_FACTOR * sizes.compositeIconSizes[0].evaluate(feature, {}, canonical), SIZE_PACK_FACTOR * sizes.compositeIconSizes[1].evaluate(feature, {}, canonical) ]; if (iconSizeData[0] > MAX_PACKED_SIZE || iconSizeData[1] > MAX_PACKED_SIZE) { warnOnce(bucket.layerIds[0] + ': Value for "icon-size" is >= ' + MAX_GLYPH_ICON_SIZE + '. Reduce your "icon-size".'); } } bucket.addSymbols(bucket.icon, iconQuads, iconSizeData, iconOffset, iconAlongLine, feature, false, anchor, lineArray.lineStartIndex, lineArray.lineLength, -1, canonical); placedIconSymbolIndex = bucket.icon.placedSymbolArray.length - 1; if (verticalIconQuads) { numVerticalIconVertices = verticalIconQuads.length * 4; bucket.addSymbols(bucket.icon, verticalIconQuads, iconSizeData, iconOffset, iconAlongLine, feature, WritingMode.vertical, anchor, lineArray.lineStartIndex, lineArray.lineLength, -1, canonical); verticalPlacedIconSymbolIndex = bucket.icon.placedSymbolArray.length - 1; } } for (var justification in shapedTextOrientations.horizontal) { var shaping = shapedTextOrientations.horizontal[justification]; if (!textCollisionFeature) { key = murmurhashJs(shaping.text); var textRotate = layer.layout.get('text-rotate').evaluate(feature, {}, canonical); textCollisionFeature = new CollisionFeature(collisionBoxArray, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaping, textBoxScale, textPadding, textAlongLine, textRotate); } var singleLine = shaping.positionedLines.length === 1; numHorizontalGlyphVertices += addTextVertices(bucket, anchor, shaping, imageMap, layer, textAlongLine, feature, textOffset, lineArray, shapedTextOrientations.vertical ? WritingMode.horizontal : WritingMode.horizontalOnly, singleLine ? Object.keys(shapedTextOrientations.horizontal) : [justification], placedTextSymbolIndices, placedIconSymbolIndex, sizes, canonical); if (singleLine) { break; } } if (shapedTextOrientations.vertical) { numVerticalGlyphVertices += addTextVertices(bucket, anchor, shapedTextOrientations.vertical, imageMap, layer, textAlongLine, feature, textOffset, lineArray, WritingMode.vertical, ['vertical'], placedTextSymbolIndices, verticalPlacedIconSymbolIndex, sizes, canonical); } var textBoxStartIndex = textCollisionFeature ? textCollisionFeature.boxStartIndex : bucket.collisionBoxArray.length; var textBoxEndIndex = textCollisionFeature ? textCollisionFeature.boxEndIndex : bucket.collisionBoxArray.length; var verticalTextBoxStartIndex = verticalTextCollisionFeature ? verticalTextCollisionFeature.boxStartIndex : bucket.collisionBoxArray.length; var verticalTextBoxEndIndex = verticalTextCollisionFeature ? verticalTextCollisionFeature.boxEndIndex : bucket.collisionBoxArray.length; var iconBoxStartIndex = iconCollisionFeature ? iconCollisionFeature.boxStartIndex : bucket.collisionBoxArray.length; var iconBoxEndIndex = iconCollisionFeature ? iconCollisionFeature.boxEndIndex : bucket.collisionBoxArray.length; var verticalIconBoxStartIndex = verticalIconCollisionFeature ? verticalIconCollisionFeature.boxStartIndex : bucket.collisionBoxArray.length; var verticalIconBoxEndIndex = verticalIconCollisionFeature ? verticalIconCollisionFeature.boxEndIndex : bucket.collisionBoxArray.length; var collisionCircleDiameter = -1; var getCollisionCircleHeight = function (feature, prevHeight) { if (feature && feature.circleDiameter) { return Math.max(feature.circleDiameter, prevHeight); } return prevHeight; }; collisionCircleDiameter = getCollisionCircleHeight(textCollisionFeature, collisionCircleDiameter); collisionCircleDiameter = getCollisionCircleHeight(verticalTextCollisionFeature, collisionCircleDiameter); collisionCircleDiameter = getCollisionCircleHeight(iconCollisionFeature, collisionCircleDiameter); collisionCircleDiameter = getCollisionCircleHeight(verticalIconCollisionFeature, collisionCircleDiameter); var useRuntimeCollisionCircles = collisionCircleDiameter > -1 ? 1 : 0; if (useRuntimeCollisionCircles) { collisionCircleDiameter *= layoutTextSize / ONE_EM; } if (bucket.glyphOffsetArray.length >= SymbolBucket.MAX_GLYPHS) { warnOnce('Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907'); } if (feature.sortKey !== undefined) { bucket.addToSortKeyRanges(bucket.symbolInstances.length, feature.sortKey); } bucket.symbolInstances.emplaceBack(anchor.x, anchor.y, placedTextSymbolIndices.right >= 0 ? placedTextSymbolIndices.right : -1, placedTextSymbolIndices.center >= 0 ? placedTextSymbolIndices.center : -1, placedTextSymbolIndices.left >= 0 ? placedTextSymbolIndices.left : -1, placedTextSymbolIndices.vertical || -1, placedIconSymbolIndex, verticalPlacedIconSymbolIndex, key, textBoxStartIndex, textBoxEndIndex, verticalTextBoxStartIndex, verticalTextBoxEndIndex, iconBoxStartIndex, iconBoxEndIndex, verticalIconBoxStartIndex, verticalIconBoxEndIndex, featureIndex, numHorizontalGlyphVertices, numVerticalGlyphVertices, numIconVertices, numVerticalIconVertices, useRuntimeCollisionCircles, 0, textBoxScale, textOffset0, textOffset1, collisionCircleDiameter); } function anchorIsTooClose(bucket, text, repeatDistance, anchor) { var compareText = bucket.compareText; if (!(text in compareText)) { compareText[text] = []; } else { var otherAnchors = compareText[text]; for (var k = otherAnchors.length - 1; k >= 0; k--) { if (anchor.dist(otherAnchors[k]) < repeatDistance) { return true; } } } compareText[text].push(anchor); return false; } var vectorTileFeatureTypes$2 = vectorTile.VectorTileFeature.types; var shaderOpacityAttributes = [{ name: 'a_fade_opacity', components: 1, type: 'Uint8', offset: 0 }]; function addVertex$1(array, anchorX, anchorY, ox, oy, tx, ty, sizeVertex, isSDF, pixelOffsetX, pixelOffsetY, minFontScaleX, minFontScaleY) { var aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0; var aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0; array.emplaceBack(anchorX, anchorY, Math.round(ox * 32), Math.round(oy * 32), tx, ty, (aSizeX << 1) + (isSDF ? 1 : 0), aSizeY, pixelOffsetX * 16, pixelOffsetY * 16, minFontScaleX * 256, minFontScaleY * 256); } function addDynamicAttributes(dynamicLayoutVertexArray, p, angle) { dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle); dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle); dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle); dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle); } function containsRTLText(formattedText) { for (var i = 0, list = formattedText.sections; i < list.length; i += 1) { var section = list[i]; if (stringContainsRTLText(section.text)) { return true; } } return false; } var SymbolBuffers = function SymbolBuffers(programConfigurations) { this.layoutVertexArray = new StructArrayLayout4i4ui4i24(); this.indexArray = new StructArrayLayout3ui6(); this.programConfigurations = programConfigurations; this.segments = new SegmentVector(); this.dynamicLayoutVertexArray = new StructArrayLayout3f12(); this.opacityVertexArray = new StructArrayLayout1ul4(); this.placedSymbolArray = new PlacedSymbolArray(); }; SymbolBuffers.prototype.isEmpty = function isEmpty() { return this.layoutVertexArray.length === 0 && this.indexArray.length === 0 && this.dynamicLayoutVertexArray.length === 0 && this.opacityVertexArray.length === 0; }; SymbolBuffers.prototype.upload = function upload(context, dynamicIndexBuffer, upload$1, update) { if (this.isEmpty()) { return; } if (upload$1) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members); this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer); this.dynamicLayoutVertexBuffer = context.createVertexBuffer(this.dynamicLayoutVertexArray, dynamicLayoutAttributes.members, true); this.opacityVertexBuffer = context.createVertexBuffer(this.opacityVertexArray, shaderOpacityAttributes, true); this.opacityVertexBuffer.itemSize = 1; } if (upload$1 || update) { this.programConfigurations.upload(context); } }; SymbolBuffers.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.programConfigurations.destroy(); this.segments.destroy(); this.dynamicLayoutVertexBuffer.destroy(); this.opacityVertexBuffer.destroy(); }; register('SymbolBuffers', SymbolBuffers); var CollisionBuffers = function CollisionBuffers(LayoutArray, layoutAttributes, IndexArray) { this.layoutVertexArray = new LayoutArray(); this.layoutAttributes = layoutAttributes; this.indexArray = new IndexArray(); this.segments = new SegmentVector(); this.collisionVertexArray = new StructArrayLayout2ub2f12(); }; CollisionBuffers.prototype.upload = function upload(context) { this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, this.layoutAttributes); this.indexBuffer = context.createIndexBuffer(this.indexArray); this.collisionVertexBuffer = context.createVertexBuffer(this.collisionVertexArray, collisionVertexAttributes.members, true); }; CollisionBuffers.prototype.destroy = function destroy() { if (!this.layoutVertexBuffer) { return; } this.layoutVertexBuffer.destroy(); this.indexBuffer.destroy(); this.segments.destroy(); this.collisionVertexBuffer.destroy(); }; register('CollisionBuffers', CollisionBuffers); var SymbolBucket = function SymbolBucket(options) { this.collisionBoxArray = options.collisionBoxArray; this.zoom = options.zoom; this.overscaling = options.overscaling; this.layers = options.layers; this.layerIds = this.layers.map(function (layer) { return layer.id; }); this.index = options.index; this.pixelRatio = options.pixelRatio; this.sourceLayerIndex = options.sourceLayerIndex; this.hasPattern = false; this.hasRTLText = false; this.sortKeyRanges = []; this.collisionCircleArray = []; this.placementInvProjMatrix = identity([]); this.placementViewportMatrix = identity([]); var layer = this.layers[0]; var unevaluatedLayoutValues = layer._unevaluatedLayout._values; this.textSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['text-size']); this.iconSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['icon-size']); var layout = this.layers[0].layout; var sortKey = layout.get('symbol-sort-key'); var zOrder = layout.get('symbol-z-order'); this.canOverlap = layout.get('text-allow-overlap') || layout.get('icon-allow-overlap') || layout.get('text-ignore-placement') || layout.get('icon-ignore-placement'); this.sortFeaturesByKey = zOrder !== 'viewport-y' && sortKey.constantOr(1) !== undefined; var zOrderByViewportY = zOrder === 'viewport-y' || zOrder === 'auto' && !this.sortFeaturesByKey; this.sortFeaturesByY = zOrderByViewportY && this.canOverlap; if (layout.get('symbol-placement') === 'point') { this.writingModes = layout.get('text-writing-mode').map(function (wm) { return WritingMode[wm]; }); } this.stateDependentLayerIds = this.layers.filter(function (l) { return l.isStateDependent(); }).map(function (l) { return l.id; }); this.sourceID = options.sourceID; }; SymbolBucket.prototype.createArrays = function createArrays() { this.text = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, function (property) { return /^text/.test(property); })); this.icon = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, function (property) { return /^icon/.test(property); })); this.glyphOffsetArray = new GlyphOffsetArray(); this.lineVertexArray = new SymbolLineVertexArray(); this.symbolInstances = new SymbolInstanceArray(); }; SymbolBucket.prototype.calculateGlyphDependencies = function calculateGlyphDependencies(text, stack, textAlongLine, allowVerticalPlacement, doesAllowVerticalWritingMode) { for (var i = 0; i < text.length; i++) { stack[text.charCodeAt(i)] = true; if ((textAlongLine || allowVerticalPlacement) && doesAllowVerticalWritingMode) { var verticalChar = verticalizedCharacterMap[text.charAt(i)]; if (verticalChar) { stack[verticalChar.charCodeAt(0)] = true; } } } }; SymbolBucket.prototype.populate = function populate(features, options, canonical) { var layer = this.layers[0]; var layout = layer.layout; var textFont = layout.get('text-font'); var textField = layout.get('text-field'); var iconImage = layout.get('icon-image'); var hasText = (textField.value.kind !== 'constant' || textField.value.value instanceof Formatted && !textField.value.value.isEmpty() || textField.value.value.toString().length > 0) && (textFont.value.kind !== 'constant' || textFont.value.value.length > 0); var hasIcon = iconImage.value.kind !== 'constant' || !!iconImage.value.value || Object.keys(iconImage.parameters).length > 0; var symbolSortKey = layout.get('symbol-sort-key'); this.features = []; if (!hasText && !hasIcon) { return; } var icons = options.iconDependencies; var stacks = options.glyphDependencies; var availableImages = options.availableImages; var globalProperties = new EvaluationParameters(this.zoom); for (var i$1 = 0, list$1 = features; i$1 < list$1.length; i$1 += 1) { var ref = list$1[i$1]; var feature = ref.feature; var id = ref.id; var index = ref.index; var sourceLayerIndex = ref.sourceLayerIndex; var needGeometry = layer._featureFilter.needGeometry; var evaluationFeature = toEvaluationFeature(feature, needGeometry); if (!layer._featureFilter.filter(globalProperties, evaluationFeature, canonical)) { continue; } if (!needGeometry) { evaluationFeature.geometry = loadGeometry(feature); } var text = void 0; if (hasText) { var resolvedTokens = layer.getValueAndResolveTokens('text-field', evaluationFeature, canonical, availableImages); var formattedText = Formatted.factory(resolvedTokens); if (containsRTLText(formattedText)) { this.hasRTLText = true; } if (!this.hasRTLText || getRTLTextPluginStatus() === 'unavailable' || this.hasRTLText && plugin.isParsed()) { text = transformText$1(formattedText, layer, evaluationFeature); } } var icon = void 0; if (hasIcon) { var resolvedTokens$1 = layer.getValueAndResolveTokens('icon-image', evaluationFeature, canonical, availableImages); if (resolvedTokens$1 instanceof ResolvedImage) { icon = resolvedTokens$1; } else { icon = ResolvedImage.fromString(resolvedTokens$1); } } if (!text && !icon) { continue; } var sortKey = this.sortFeaturesByKey ? symbolSortKey.evaluate(evaluationFeature, {}, canonical) : undefined; var symbolFeature = { id: id, text: text, icon: icon, index: index, sourceLayerIndex: sourceLayerIndex, geometry: evaluationFeature.geometry, properties: feature.properties, type: vectorTileFeatureTypes$2[feature.type], sortKey: sortKey }; this.features.push(symbolFeature); if (icon) { icons[icon.name] = true; } if (text) { var fontStack = textFont.evaluate(evaluationFeature, {}, canonical).join(','); var textAlongLine = layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point'; this.allowVerticalPlacement = this.writingModes && this.writingModes.indexOf(WritingMode.vertical) >= 0; for (var i = 0, list = text.sections; i < list.length; i += 1) { var section = list[i]; if (!section.image) { var doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString()); var sectionFont = section.fontStack || fontStack; var sectionStack = stacks[sectionFont] = stacks[sectionFont] || {}; this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, this.allowVerticalPlacement, doesAllowVerticalWritingMode); } else { icons[section.image.name] = true; } } } } if (layout.get('symbol-placement') === 'line') { this.features = mergeLines(this.features); } if (this.sortFeaturesByKey) { this.features.sort(function (a, b) { return a.sortKey - b.sortKey; }); } }; SymbolBucket.prototype.update = function update(states, vtLayer, imagePositions) { if (!this.stateDependentLayers.length) { return; } this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions); this.icon.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions); }; SymbolBucket.prototype.isEmpty = function isEmpty() { return this.symbolInstances.length === 0 && !this.hasRTLText; }; SymbolBucket.prototype.uploadPending = function uploadPending() { return !this.uploaded || this.text.programConfigurations.needsUpload || this.icon.programConfigurations.needsUpload; }; SymbolBucket.prototype.upload = function upload(context) { if (!this.uploaded && this.hasDebugData()) { this.textCollisionBox.upload(context); this.iconCollisionBox.upload(context); } this.text.upload(context, this.sortFeaturesByY, !this.uploaded, this.text.programConfigurations.needsUpload); this.icon.upload(context, this.sortFeaturesByY, !this.uploaded, this.icon.programConfigurations.needsUpload); this.uploaded = true; }; SymbolBucket.prototype.destroyDebugData = function destroyDebugData() { this.textCollisionBox.destroy(); this.iconCollisionBox.destroy(); }; SymbolBucket.prototype.destroy = function destroy() { this.text.destroy(); this.icon.destroy(); if (this.hasDebugData()) { this.destroyDebugData(); } }; SymbolBucket.prototype.addToLineVertexArray = function addToLineVertexArray(anchor, line) { var lineStartIndex = this.lineVertexArray.length; if (anchor.segment !== undefined) { var sumForwardLength = anchor.dist(line[anchor.segment + 1]); var sumBackwardLength = anchor.dist(line[anchor.segment]); var vertices = {}; for (var i = anchor.segment + 1; i < line.length; i++) { vertices[i] = { x: line[i].x, y: line[i].y, tileUnitDistanceFromAnchor: sumForwardLength }; if (i < line.length - 1) { sumForwardLength += line[i + 1].dist(line[i]); } } for (var i$1 = anchor.segment || 0; i$1 >= 0; i$1--) { vertices[i$1] = { x: line[i$1].x, y: line[i$1].y, tileUnitDistanceFromAnchor: sumBackwardLength }; if (i$1 > 0) { sumBackwardLength += line[i$1 - 1].dist(line[i$1]); } } for (var i$2 = 0; i$2 < line.length; i$2++) { var vertex = vertices[i$2]; this.lineVertexArray.emplaceBack(vertex.x, vertex.y, vertex.tileUnitDistanceFromAnchor); } } return { lineStartIndex: lineStartIndex, lineLength: this.lineVertexArray.length - lineStartIndex }; }; SymbolBucket.prototype.addSymbols = function addSymbols(arrays, quads, sizeVertex, lineOffset, alongLine, feature, writingMode, labelAnchor, lineStartIndex, lineLength, associatedIconIndex, canonical) { var indexArray = arrays.indexArray; var layoutVertexArray = arrays.layoutVertexArray; var segment = arrays.segments.prepareSegment(4 * quads.length, layoutVertexArray, indexArray, this.canOverlap ? feature.sortKey : undefined); var glyphOffsetArrayStart = this.glyphOffsetArray.length; var vertexStartIndex = segment.vertexLength; var angle = this.allowVerticalPlacement && writingMode === WritingMode.vertical ? Math.PI / 2 : 0; var sections = feature.text && feature.text.sections; for (var i = 0; i < quads.length; i++) { var ref = quads[i]; var tl = ref.tl; var tr = ref.tr; var bl = ref.bl; var br = ref.br; var tex = ref.tex; var pixelOffsetTL = ref.pixelOffsetTL; var pixelOffsetBR = ref.pixelOffsetBR; var minFontScaleX = ref.minFontScaleX; var minFontScaleY = ref.minFontScaleY; var glyphOffset = ref.glyphOffset; var isSDF = ref.isSDF; var sectionIndex = ref.sectionIndex; var index = segment.vertexLength; var y = glyphOffset[1]; addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY); addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY); addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY); addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY); addDynamicAttributes(arrays.dynamicLayoutVertexArray, labelAnchor, angle); indexArray.emplaceBack(index, index + 1, index + 2); indexArray.emplaceBack(index + 1, index + 2, index + 3); segment.vertexLength += 4; segment.primitiveLength += 2; this.glyphOffsetArray.emplaceBack(glyphOffset[0]); if (i === quads.length - 1 || sectionIndex !== quads[i + 1].sectionIndex) { arrays.programConfigurations.populatePaintArrays(layoutVertexArray.length, feature, feature.index, {}, canonical, sections && sections[sectionIndex]); } } arrays.placedSymbolArray.emplaceBack(labelAnchor.x, labelAnchor.y, glyphOffsetArrayStart, this.glyphOffsetArray.length - glyphOffsetArrayStart, vertexStartIndex, lineStartIndex, lineLength, labelAnchor.segment, sizeVertex ? sizeVertex[0] : 0, sizeVertex ? sizeVertex[1] : 0, lineOffset[0], lineOffset[1], writingMode, 0, false, 0, associatedIconIndex); }; SymbolBucket.prototype._addCollisionDebugVertex = function _addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point, anchorX, anchorY, extrude) { collisionVertexArray.emplaceBack(0, 0); return layoutVertexArray.emplaceBack(point.x, point.y, anchorX, anchorY, Math.round(extrude.x), Math.round(extrude.y)); }; SymbolBucket.prototype.addCollisionDebugVertices = function addCollisionDebugVertices(x1, y1, x2, y2, arrays, boxAnchorPoint, symbolInstance) { var segment = arrays.segments.prepareSegment(4, arrays.layoutVertexArray, arrays.indexArray); var index = segment.vertexLength; var layoutVertexArray = arrays.layoutVertexArray; var collisionVertexArray = arrays.collisionVertexArray; var anchorX = symbolInstance.anchorX; var anchorY = symbolInstance.anchorY; this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new pointGeometry(x1, y1)); this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new pointGeometry(x2, y1)); this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new pointGeometry(x2, y2)); this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new pointGeometry(x1, y2)); segment.vertexLength += 4; var indexArray = arrays.indexArray; indexArray.emplaceBack(index, index + 1); indexArray.emplaceBack(index + 1, index + 2); indexArray.emplaceBack(index + 2, index + 3); indexArray.emplaceBack(index + 3, index); segment.primitiveLength += 4; }; SymbolBucket.prototype.addDebugCollisionBoxes = function addDebugCollisionBoxes(startIndex, endIndex, symbolInstance, isText) { for (var b = startIndex; b < endIndex; b++) { var box = this.collisionBoxArray.get(b); var x1 = box.x1; var y1 = box.y1; var x2 = box.x2; var y2 = box.y2; this.addCollisionDebugVertices(x1, y1, x2, y2, isText ? this.textCollisionBox : this.iconCollisionBox, box.anchorPoint, symbolInstance); } }; SymbolBucket.prototype.generateCollisionDebugBuffers = function generateCollisionDebugBuffers() { if (this.hasDebugData()) { this.destroyDebugData(); } this.textCollisionBox = new CollisionBuffers(StructArrayLayout2i2i2i12, collisionBoxLayout.members, StructArrayLayout2ui4); this.iconCollisionBox = new CollisionBuffers(StructArrayLayout2i2i2i12, collisionBoxLayout.members, StructArrayLayout2ui4); for (var i = 0; i < this.symbolInstances.length; i++) { var symbolInstance = this.symbolInstances.get(i); this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance, true); this.addDebugCollisionBoxes(symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance, true); this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance, false); this.addDebugCollisionBoxes(symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex, symbolInstance, false); } }; SymbolBucket.prototype._deserializeCollisionBoxesForSymbol = function _deserializeCollisionBoxesForSymbol(collisionBoxArray, textStartIndex, textEndIndex, verticalTextStartIndex, verticalTextEndIndex, iconStartIndex, iconEndIndex, verticalIconStartIndex, verticalIconEndIndex) { var collisionArrays = {}; for (var k = textStartIndex; k < textEndIndex; k++) { var box = collisionBoxArray.get(k); collisionArrays.textBox = { x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY }; collisionArrays.textFeatureIndex = box.featureIndex; break; } for (var k$1 = verticalTextStartIndex; k$1 < verticalTextEndIndex; k$1++) { var box$1 = collisionBoxArray.get(k$1); collisionArrays.verticalTextBox = { x1: box$1.x1, y1: box$1.y1, x2: box$1.x2, y2: box$1.y2, anchorPointX: box$1.anchorPointX, anchorPointY: box$1.anchorPointY }; collisionArrays.verticalTextFeatureIndex = box$1.featureIndex; break; } for (var k$2 = iconStartIndex; k$2 < iconEndIndex; k$2++) { var box$2 = collisionBoxArray.get(k$2); collisionArrays.iconBox = { x1: box$2.x1, y1: box$2.y1, x2: box$2.x2, y2: box$2.y2, anchorPointX: box$2.anchorPointX, anchorPointY: box$2.anchorPointY }; collisionArrays.iconFeatureIndex = box$2.featureIndex; break; } for (var k$3 = verticalIconStartIndex; k$3 < verticalIconEndIndex; k$3++) { var box$3 = collisionBoxArray.get(k$3); collisionArrays.verticalIconBox = { x1: box$3.x1, y1: box$3.y1, x2: box$3.x2, y2: box$3.y2, anchorPointX: box$3.anchorPointX, anchorPointY: box$3.anchorPointY }; collisionArrays.verticalIconFeatureIndex = box$3.featureIndex; break; } return collisionArrays; }; SymbolBucket.prototype.deserializeCollisionBoxes = function deserializeCollisionBoxes(collisionBoxArray) { this.collisionArrays = []; for (var i = 0; i < this.symbolInstances.length; i++) { var symbolInstance = this.symbolInstances.get(i); this.collisionArrays.push(this._deserializeCollisionBoxesForSymbol(collisionBoxArray, symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex)); } }; SymbolBucket.prototype.hasTextData = function hasTextData() { return this.text.segments.get().length > 0; }; SymbolBucket.prototype.hasIconData = function hasIconData() { return this.icon.segments.get().length > 0; }; SymbolBucket.prototype.hasDebugData = function hasDebugData() { return this.textCollisionBox && this.iconCollisionBox; }; SymbolBucket.prototype.hasTextCollisionBoxData = function hasTextCollisionBoxData() { return this.hasDebugData() && this.textCollisionBox.segments.get().length > 0; }; SymbolBucket.prototype.hasIconCollisionBoxData = function hasIconCollisionBoxData() { return this.hasDebugData() && this.iconCollisionBox.segments.get().length > 0; }; SymbolBucket.prototype.addIndicesForPlacedSymbol = function addIndicesForPlacedSymbol(iconOrText, placedSymbolIndex) { var placedSymbol = iconOrText.placedSymbolArray.get(placedSymbolIndex); var endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4; for (var vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) { iconOrText.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); iconOrText.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); } }; SymbolBucket.prototype.getSortedSymbolIndexes = function getSortedSymbolIndexes(angle) { if (this.sortedAngle === angle && this.symbolInstanceIndexes !== undefined) { return this.symbolInstanceIndexes; } var sin = Math.sin(angle); var cos = Math.cos(angle); var rotatedYs = []; var featureIndexes = []; var result = []; for (var i = 0; i < this.symbolInstances.length; ++i) { result.push(i); var symbolInstance = this.symbolInstances.get(i); rotatedYs.push(Math.round(sin * symbolInstance.anchorX + cos * symbolInstance.anchorY) | 0); featureIndexes.push(symbolInstance.featureIndex); } result.sort(function (aIndex, bIndex) { return rotatedYs[aIndex] - rotatedYs[bIndex] || featureIndexes[bIndex] - featureIndexes[aIndex]; }); return result; }; SymbolBucket.prototype.addToSortKeyRanges = function addToSortKeyRanges(symbolInstanceIndex, sortKey) { var last = this.sortKeyRanges[this.sortKeyRanges.length - 1]; if (last && last.sortKey === sortKey) { last.symbolInstanceEnd = symbolInstanceIndex + 1; } else { this.sortKeyRanges.push({ sortKey: sortKey, symbolInstanceStart: symbolInstanceIndex, symbolInstanceEnd: symbolInstanceIndex + 1 }); } }; SymbolBucket.prototype.sortFeatures = function sortFeatures(angle) { var this$1 = this; if (!this.sortFeaturesByY) { return; } if (this.sortedAngle === angle) { return; } if (this.text.segments.get().length > 1 || this.icon.segments.get().length > 1) { return; } this.symbolInstanceIndexes = this.getSortedSymbolIndexes(angle); this.sortedAngle = angle; this.text.indexArray.clear(); this.icon.indexArray.clear(); this.featureSortOrder = []; for (var i$1 = 0, list = this.symbolInstanceIndexes; i$1 < list.length; i$1 += 1) { var i = list[i$1]; var symbolInstance = this.symbolInstances.get(i); this.featureSortOrder.push(symbolInstance.featureIndex); [ symbolInstance.rightJustifiedTextSymbolIndex, symbolInstance.centerJustifiedTextSymbolIndex, symbolInstance.leftJustifiedTextSymbolIndex ].forEach(function (index, i, array) { if (index >= 0 && array.indexOf(index) === i) { this$1.addIndicesForPlacedSymbol(this$1.text, index); } }); if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) { this.addIndicesForPlacedSymbol(this.text, symbolInstance.verticalPlacedTextSymbolIndex); } if (symbolInstance.placedIconSymbolIndex >= 0) { this.addIndicesForPlacedSymbol(this.icon, symbolInstance.placedIconSymbolIndex); } if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) { this.addIndicesForPlacedSymbol(this.icon, symbolInstance.verticalPlacedIconSymbolIndex); } } if (this.text.indexBuffer) { this.text.indexBuffer.updateData(this.text.indexArray); } if (this.icon.indexBuffer) { this.icon.indexBuffer.updateData(this.icon.indexArray); } }; register('SymbolBucket', SymbolBucket, { omit: [ 'layers', 'collisionBoxArray', 'features', 'compareText' ] }); SymbolBucket.MAX_GLYPHS = 65535; SymbolBucket.addDynamicAttributes = addDynamicAttributes; function resolveTokens(properties, text) { return text.replace(/{([^{}]+)}/g, function (match, key) { return key in properties ? String(properties[key]) : ''; }); } var layout$7 = new Properties({ 'symbol-placement': new DataConstantProperty(spec['layout_symbol']['symbol-placement']), 'symbol-spacing': new DataConstantProperty(spec['layout_symbol']['symbol-spacing']), 'symbol-avoid-edges': new DataConstantProperty(spec['layout_symbol']['symbol-avoid-edges']), 'symbol-sort-key': new DataDrivenProperty(spec['layout_symbol']['symbol-sort-key']), 'symbol-z-order': new DataConstantProperty(spec['layout_symbol']['symbol-z-order']), 'icon-allow-overlap': new DataConstantProperty(spec['layout_symbol']['icon-allow-overlap']), 'icon-ignore-placement': new DataConstantProperty(spec['layout_symbol']['icon-ignore-placement']), 'icon-optional': new DataConstantProperty(spec['layout_symbol']['icon-optional']), 'icon-rotation-alignment': new DataConstantProperty(spec['layout_symbol']['icon-rotation-alignment']), 'icon-size': new DataDrivenProperty(spec['layout_symbol']['icon-size']), 'icon-text-fit': new DataConstantProperty(spec['layout_symbol']['icon-text-fit']), 'icon-text-fit-padding': new DataConstantProperty(spec['layout_symbol']['icon-text-fit-padding']), 'icon-image': new DataDrivenProperty(spec['layout_symbol']['icon-image']), 'icon-rotate': new DataDrivenProperty(spec['layout_symbol']['icon-rotate']), 'icon-padding': new DataConstantProperty(spec['layout_symbol']['icon-padding']), 'icon-keep-upright': new DataConstantProperty(spec['layout_symbol']['icon-keep-upright']), 'icon-offset': new DataDrivenProperty(spec['layout_symbol']['icon-offset']), 'icon-anchor': new DataDrivenProperty(spec['layout_symbol']['icon-anchor']), 'icon-pitch-alignment': new DataConstantProperty(spec['layout_symbol']['icon-pitch-alignment']), 'text-pitch-alignment': new DataConstantProperty(spec['layout_symbol']['text-pitch-alignment']), 'text-rotation-alignment': new DataConstantProperty(spec['layout_symbol']['text-rotation-alignment']), 'text-field': new DataDrivenProperty(spec['layout_symbol']['text-field']), 'text-font': new DataDrivenProperty(spec['layout_symbol']['text-font']), 'text-size': new DataDrivenProperty(spec['layout_symbol']['text-size']), 'text-max-width': new DataDrivenProperty(spec['layout_symbol']['text-max-width']), 'text-line-height': new DataConstantProperty(spec['layout_symbol']['text-line-height']), 'text-letter-spacing': new DataDrivenProperty(spec['layout_symbol']['text-letter-spacing']), 'text-justify': new DataDrivenProperty(spec['layout_symbol']['text-justify']), 'text-radial-offset': new DataDrivenProperty(spec['layout_symbol']['text-radial-offset']), 'text-variable-anchor': new DataConstantProperty(spec['layout_symbol']['text-variable-anchor']), 'text-anchor': new DataDrivenProperty(spec['layout_symbol']['text-anchor']), 'text-max-angle': new DataConstantProperty(spec['layout_symbol']['text-max-angle']), 'text-writing-mode': new DataConstantProperty(spec['layout_symbol']['text-writing-mode']), 'text-rotate': new DataDrivenProperty(spec['layout_symbol']['text-rotate']), 'text-padding': new DataConstantProperty(spec['layout_symbol']['text-padding']), 'text-keep-upright': new DataConstantProperty(spec['layout_symbol']['text-keep-upright']), 'text-transform': new DataDrivenProperty(spec['layout_symbol']['text-transform']), 'text-offset': new DataDrivenProperty(spec['layout_symbol']['text-offset']), 'text-allow-overlap': new DataConstantProperty(spec['layout_symbol']['text-allow-overlap']), 'text-ignore-placement': new DataConstantProperty(spec['layout_symbol']['text-ignore-placement']), 'text-optional': new DataConstantProperty(spec['layout_symbol']['text-optional']) }); var paint$7 = new Properties({ 'icon-opacity': new DataDrivenProperty(spec['paint_symbol']['icon-opacity']), 'icon-color': new DataDrivenProperty(spec['paint_symbol']['icon-color']), 'icon-halo-color': new DataDrivenProperty(spec['paint_symbol']['icon-halo-color']), 'icon-halo-width': new DataDrivenProperty(spec['paint_symbol']['icon-halo-width']), 'icon-halo-blur': new DataDrivenProperty(spec['paint_symbol']['icon-halo-blur']), 'icon-translate': new DataConstantProperty(spec['paint_symbol']['icon-translate']), 'icon-translate-anchor': new DataConstantProperty(spec['paint_symbol']['icon-translate-anchor']), 'text-opacity': new DataDrivenProperty(spec['paint_symbol']['text-opacity']), 'text-color': new DataDrivenProperty(spec['paint_symbol']['text-color'], { runtimeType: ColorType, getOverride: function (o) { return o.textColor; }, hasOverride: function (o) { return !!o.textColor; } }), 'text-halo-color': new DataDrivenProperty(spec['paint_symbol']['text-halo-color']), 'text-halo-width': new DataDrivenProperty(spec['paint_symbol']['text-halo-width']), 'text-halo-blur': new DataDrivenProperty(spec['paint_symbol']['text-halo-blur']), 'text-translate': new DataConstantProperty(spec['paint_symbol']['text-translate']), 'text-translate-anchor': new DataConstantProperty(spec['paint_symbol']['text-translate-anchor']) }); var properties$6 = { paint: paint$7, layout: layout$7 }; var FormatSectionOverride = function FormatSectionOverride(defaultValue) { this.type = defaultValue.property.overrides ? defaultValue.property.overrides.runtimeType : NullType; this.defaultValue = defaultValue; }; FormatSectionOverride.prototype.evaluate = function evaluate(ctx) { if (ctx.formattedSection) { var overrides = this.defaultValue.property.overrides; if (overrides && overrides.hasOverride(ctx.formattedSection)) { return overrides.getOverride(ctx.formattedSection); } } if (ctx.feature && ctx.featureState) { return this.defaultValue.evaluate(ctx.feature, ctx.featureState); } return this.defaultValue.property.specification.default; }; FormatSectionOverride.prototype.eachChild = function eachChild(fn) { if (!this.defaultValue.isConstant()) { var expr = this.defaultValue.value; fn(expr._styleExpression.expression); } }; FormatSectionOverride.prototype.outputDefined = function outputDefined() { return false; }; FormatSectionOverride.prototype.serialize = function serialize() { return null; }; register('FormatSectionOverride', FormatSectionOverride, { omit: ['defaultValue'] }); var SymbolStyleLayer = function (StyleLayer) { function SymbolStyleLayer(layer) { StyleLayer.call(this, layer, properties$6); } if (StyleLayer) SymbolStyleLayer.__proto__ = StyleLayer; SymbolStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); SymbolStyleLayer.prototype.constructor = SymbolStyleLayer; SymbolStyleLayer.prototype.recalculate = function recalculate(parameters, availableImages) { StyleLayer.prototype.recalculate.call(this, parameters, availableImages); if (this.layout.get('icon-rotation-alignment') === 'auto') { if (this.layout.get('symbol-placement') !== 'point') { this.layout._values['icon-rotation-alignment'] = 'map'; } else { this.layout._values['icon-rotation-alignment'] = 'viewport'; } } if (this.layout.get('text-rotation-alignment') === 'auto') { if (this.layout.get('symbol-placement') !== 'point') { this.layout._values['text-rotation-alignment'] = 'map'; } else { this.layout._values['text-rotation-alignment'] = 'viewport'; } } if (this.layout.get('text-pitch-alignment') === 'auto') { this.layout._values['text-pitch-alignment'] = this.layout.get('text-rotation-alignment'); } if (this.layout.get('icon-pitch-alignment') === 'auto') { this.layout._values['icon-pitch-alignment'] = this.layout.get('icon-rotation-alignment'); } if (this.layout.get('symbol-placement') === 'point') { var writingModes = this.layout.get('text-writing-mode'); if (writingModes) { var deduped = []; for (var i = 0, list = writingModes; i < list.length; i += 1) { var m = list[i]; if (deduped.indexOf(m) < 0) { deduped.push(m); } } this.layout._values['text-writing-mode'] = deduped; } else { this.layout._values['text-writing-mode'] = ['horizontal']; } } this._setPaintOverrides(); }; SymbolStyleLayer.prototype.getValueAndResolveTokens = function getValueAndResolveTokens(name, feature, canonical, availableImages) { var value = this.layout.get(name).evaluate(feature, {}, canonical, availableImages); var unevaluated = this._unevaluatedLayout._values[name]; if (!unevaluated.isDataDriven() && !isExpression(unevaluated.value) && value) { return resolveTokens(feature.properties, value); } return value; }; SymbolStyleLayer.prototype.createBucket = function createBucket(parameters) { return new SymbolBucket(parameters); }; SymbolStyleLayer.prototype.queryRadius = function queryRadius() { return 0; }; SymbolStyleLayer.prototype.queryIntersectsFeature = function queryIntersectsFeature() { return false; }; SymbolStyleLayer.prototype._setPaintOverrides = function _setPaintOverrides() { for (var i = 0, list = properties$6.paint.overridableProperties; i < list.length; i += 1) { var overridable = list[i]; if (!SymbolStyleLayer.hasPaintOverride(this.layout, overridable)) { continue; } var overriden = this.paint.get(overridable); var override = new FormatSectionOverride(overriden); var styleExpression = new StyleExpression(override, overriden.property.specification); var expression = null; if (overriden.value.kind === 'constant' || overriden.value.kind === 'source') { expression = new ZoomConstantExpression('source', styleExpression); } else { expression = new ZoomDependentExpression('composite', styleExpression, overriden.value.zoomStops, overriden.value._interpolationType); } this.paint._values[overridable] = new PossiblyEvaluatedPropertyValue(overriden.property, expression, overriden.parameters); } }; SymbolStyleLayer.prototype._handleOverridablePaintPropertyUpdate = function _handleOverridablePaintPropertyUpdate(name, oldValue, newValue) { if (!this.layout || oldValue.isDataDriven() || newValue.isDataDriven()) { return false; } return SymbolStyleLayer.hasPaintOverride(this.layout, name); }; SymbolStyleLayer.hasPaintOverride = function hasPaintOverride(layout, propertyName) { var textField = layout.get('text-field'); var property = properties$6.paint.properties[propertyName]; var hasOverrides = false; var checkSections = function (sections) { for (var i = 0, list = sections; i < list.length; i += 1) { var section = list[i]; if (property.overrides && property.overrides.hasOverride(section)) { hasOverrides = true; return; } } }; if (textField.value.kind === 'constant' && textField.value.value instanceof Formatted) { checkSections(textField.value.value.sections); } else if (textField.value.kind === 'source') { var checkExpression = function (expression) { if (hasOverrides) { return; } if (expression instanceof Literal && typeOf(expression.value) === FormattedType) { var formatted = expression.value; checkSections(formatted.sections); } else if (expression instanceof FormatExpression) { checkSections(expression.sections); } else { expression.eachChild(checkExpression); } }; var expr = textField.value; if (expr._styleExpression) { checkExpression(expr._styleExpression.expression); } } return hasOverrides; }; return SymbolStyleLayer; }(StyleLayer); var paint$8 = new Properties({ 'background-color': new DataConstantProperty(spec['paint_background']['background-color']), 'background-pattern': new CrossFadedProperty(spec['paint_background']['background-pattern']), 'background-opacity': new DataConstantProperty(spec['paint_background']['background-opacity']) }); var properties$7 = { paint: paint$8 }; var BackgroundStyleLayer = function (StyleLayer) { function BackgroundStyleLayer(layer) { StyleLayer.call(this, layer, properties$7); } if (StyleLayer) BackgroundStyleLayer.__proto__ = StyleLayer; BackgroundStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); BackgroundStyleLayer.prototype.constructor = BackgroundStyleLayer; return BackgroundStyleLayer; }(StyleLayer); var paint$9 = new Properties({ 'raster-opacity': new DataConstantProperty(spec['paint_raster']['raster-opacity']), 'raster-hue-rotate': new DataConstantProperty(spec['paint_raster']['raster-hue-rotate']), 'raster-brightness-min': new DataConstantProperty(spec['paint_raster']['raster-brightness-min']), 'raster-brightness-max': new DataConstantProperty(spec['paint_raster']['raster-brightness-max']), 'raster-saturation': new DataConstantProperty(spec['paint_raster']['raster-saturation']), 'raster-contrast': new DataConstantProperty(spec['paint_raster']['raster-contrast']), 'raster-resampling': new DataConstantProperty(spec['paint_raster']['raster-resampling']), 'raster-fade-duration': new DataConstantProperty(spec['paint_raster']['raster-fade-duration']) }); var properties$8 = { paint: paint$9 }; var RasterStyleLayer = function (StyleLayer) { function RasterStyleLayer(layer) { StyleLayer.call(this, layer, properties$8); } if (StyleLayer) RasterStyleLayer.__proto__ = StyleLayer; RasterStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); RasterStyleLayer.prototype.constructor = RasterStyleLayer; return RasterStyleLayer; }(StyleLayer); function validateCustomStyleLayer(layerObject) { var errors = []; var id = layerObject.id; if (id === undefined) { errors.push({ message: 'layers.' + id + ': missing required property "id"' }); } if (layerObject.render === undefined) { errors.push({ message: 'layers.' + id + ': missing required method "render"' }); } if (layerObject.renderingMode && layerObject.renderingMode !== '2d' && layerObject.renderingMode !== '3d') { errors.push({ message: 'layers.' + id + ': property "renderingMode" must be either "2d" or "3d"' }); } return errors; } var CustomStyleLayer = function (StyleLayer) { function CustomStyleLayer(implementation) { StyleLayer.call(this, implementation, {}); this.implementation = implementation; } if (StyleLayer) CustomStyleLayer.__proto__ = StyleLayer; CustomStyleLayer.prototype = Object.create(StyleLayer && StyleLayer.prototype); CustomStyleLayer.prototype.constructor = CustomStyleLayer; CustomStyleLayer.prototype.is3D = function is3D() { return this.implementation.renderingMode === '3d'; }; CustomStyleLayer.prototype.hasOffscreenPass = function hasOffscreenPass() { return this.implementation.prerender !== undefined; }; CustomStyleLayer.prototype.recalculate = function recalculate() { }; CustomStyleLayer.prototype.updateTransitions = function updateTransitions() { }; CustomStyleLayer.prototype.hasTransition = function hasTransition() { }; CustomStyleLayer.prototype.serialize = function serialize() { }; CustomStyleLayer.prototype.onAdd = function onAdd(map) { if (this.implementation.onAdd) { this.implementation.onAdd(map, map.painter.context.gl); } }; CustomStyleLayer.prototype.onRemove = function onRemove(map) { if (this.implementation.onRemove) { this.implementation.onRemove(map, map.painter.context.gl); } }; return CustomStyleLayer; }(StyleLayer); var subclasses = { circle: CircleStyleLayer, heatmap: HeatmapStyleLayer, hillshade: HillshadeStyleLayer, fill: FillStyleLayer, 'fill-extrusion': FillExtrusionStyleLayer, line: LineStyleLayer, symbol: SymbolStyleLayer, background: BackgroundStyleLayer, raster: RasterStyleLayer }; function createStyleLayer(layer) { if (layer.type === 'custom') { return new CustomStyleLayer(layer); } else { return new subclasses[layer.type](layer); } } var HTMLImageElement = window$1.HTMLImageElement; var HTMLCanvasElement = window$1.HTMLCanvasElement; var HTMLVideoElement = window$1.HTMLVideoElement; var ImageData$1 = window$1.ImageData; var ImageBitmap$1 = window$1.ImageBitmap; var Texture = function Texture(context, image, format, options) { this.context = context; this.format = format; this.texture = context.gl.createTexture(); this.update(image, options); }; Texture.prototype.update = function update(image, options, position) { var width = image.width; var height = image.height; var resize = (!this.size || this.size[0] !== width || this.size[1] !== height) && !position; var ref = this; var context = ref.context; var gl = context.gl; this.useMipmap = Boolean(options && options.useMipmap); gl.bindTexture(gl.TEXTURE_2D, this.texture); context.pixelStoreUnpackFlipY.set(false); context.pixelStoreUnpack.set(1); context.pixelStoreUnpackPremultiplyAlpha.set(this.format === gl.RGBA && (!options || options.premultiply !== false)); if (resize) { this.size = [ width, height ]; if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData$1 || ImageBitmap$1 && image instanceof ImageBitmap$1) { gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, gl.UNSIGNED_BYTE, image); } else { gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, gl.UNSIGNED_BYTE, image.data); } } else { var ref$1 = position || { x: 0, y: 0 }; var x = ref$1.x; var y = ref$1.y; if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData$1 || ImageBitmap$1 && image instanceof ImageBitmap$1) { gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, gl.RGBA, gl.UNSIGNED_BYTE, image); } else { gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, image.data); } } if (this.useMipmap && this.isSizePowerOfTwo()) { gl.generateMipmap(gl.TEXTURE_2D); } }; Texture.prototype.bind = function bind(filter, wrap, minFilter) { var ref = this; var context = ref.context; var gl = context.gl; gl.bindTexture(gl.TEXTURE_2D, this.texture); if (minFilter === gl.LINEAR_MIPMAP_NEAREST && !this.isSizePowerOfTwo()) { minFilter = gl.LINEAR; } if (filter !== this.filter) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter || filter); this.filter = filter; } if (wrap !== this.wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); this.wrap = wrap; } }; Texture.prototype.isSizePowerOfTwo = function isSizePowerOfTwo() { return this.size[0] === this.size[1] && Math.log(this.size[0]) / Math.LN2 % 1 === 0; }; Texture.prototype.destroy = function destroy() { var ref = this.context; var gl = ref.gl; gl.deleteTexture(this.texture); this.texture = null; }; var ThrottledInvoker = function ThrottledInvoker(callback) { var this$1 = this; this._callback = callback; this._triggered = false; if (typeof MessageChannel !== 'undefined') { this._channel = new MessageChannel(); this._channel.port2.onmessage = function () { this$1._triggered = false; this$1._callback(); }; } }; ThrottledInvoker.prototype.trigger = function trigger() { var this$1 = this; if (!this._triggered) { this._triggered = true; if (this._channel) { this._channel.port1.postMessage(true); } else { setTimeout(function () { this$1._triggered = false; this$1._callback(); }, 0); } } }; ThrottledInvoker.prototype.remove = function remove() { delete this._channel; this._callback = function () { }; }; var Actor = function Actor(target, parent, mapId) { this.target = target; this.parent = parent; this.mapId = mapId; this.callbacks = {}; this.tasks = {}; this.taskQueue = []; this.cancelCallbacks = {}; bindAll([ 'receive', 'process' ], this); this.invoker = new ThrottledInvoker(this.process); this.target.addEventListener('message', this.receive, false); this.globalScope = isWorker() ? target : window$1; }; Actor.prototype.send = function send(type, data, callback, targetMapId, mustQueue) { var this$1 = this; if (mustQueue === void 0) mustQueue = false; var id = Math.round(Math.random() * 1000000000000000000).toString(36).substring(0, 10); if (callback) { this.callbacks[id] = callback; } var buffers = isSafari(this.globalScope) ? undefined : []; this.target.postMessage({ id: id, type: type, hasCallback: !!callback, targetMapId: targetMapId, mustQueue: mustQueue, sourceMapId: this.mapId, data: serialize(data, buffers) }, buffers); return { cancel: function () { if (callback) { delete this$1.callbacks[id]; } this$1.target.postMessage({ id: id, type: '', targetMapId: targetMapId, sourceMapId: this$1.mapId }); } }; }; Actor.prototype.receive = function receive(message) { var data = message.data, id = data.id; if (!id) { return; } if (data.targetMapId && this.mapId !== data.targetMapId) { return; } if (data.type === '') { delete this.tasks[id]; var cancel = this.cancelCallbacks[id]; delete this.cancelCallbacks[id]; if (cancel) { cancel(); } } else { if (isWorker() || data.mustQueue) { this.tasks[id] = data; this.taskQueue.push(id); this.invoker.trigger(); } else { this.processTask(id, data); } } }; Actor.prototype.process = function process() { if (!this.taskQueue.length) { return; } var id = this.taskQueue.shift(); var task = this.tasks[id]; delete this.tasks[id]; if (this.taskQueue.length) { this.invoker.trigger(); } if (!task) { return; } this.processTask(id, task); }; Actor.prototype.processTask = function processTask(id, task) { var this$1 = this; if (task.type === '') { var callback = this.callbacks[id]; delete this.callbacks[id]; if (callback) { if (task.error) { callback(deserialize(task.error)); } else { callback(null, deserialize(task.data)); } } } else { var completed = false; var buffers = isSafari(this.globalScope) ? undefined : []; var done = task.hasCallback ? function (err, data) { completed = true; delete this$1.cancelCallbacks[id]; this$1.target.postMessage({ id: id, type: '', sourceMapId: this$1.mapId, error: err ? serialize(err) : null, data: serialize(data, buffers) }, buffers); } : function (_) { completed = true; }; var callback$1 = null; var params = deserialize(task.data); if (this.parent[task.type]) { callback$1 = this.parent[task.type](task.sourceMapId, params, done); } else if (this.parent.getWorkerSource) { var keys = task.type.split('.'); var scope = this.parent.getWorkerSource(task.sourceMapId, keys[0], params.source); callback$1 = scope[keys[1]](params, done); } else { done(new Error('Could not find function ' + task.type)); } if (!completed && callback$1 && callback$1.cancel) { this.cancelCallbacks[id] = callback$1.cancel; } } }; Actor.prototype.remove = function remove() { this.invoker.remove(); this.target.removeEventListener('message', this.receive, false); }; /** * getTileBBox * * @param {Number} x Tile coordinate x * @param {Number} y Tile coordinate y * @param {Number} z Tile zoom * @returns {String} String of the bounding box */ function getTileBBox(x, y, z) { // for Google/OSM tile scheme we need to alter the y y = (Math.pow(2, z) - y - 1); var min = getMercCoords(x * 256, y * 256, z), max = getMercCoords((x + 1) * 256, (y + 1) * 256, z); return min[0] + ',' + min[1] + ',' + max[0] + ',' + max[1]; } /** * getMercCoords * * @param {Number} x Pixel coordinate x * @param {Number} y Pixel coordinate y * @param {Number} z Tile zoom * @returns {Array} [x, y] */ function getMercCoords(x, y, z) { var resolution = (2 * Math.PI * 6378137 / 256) / Math.pow(2, z), merc_x = (x * resolution - 2 * Math.PI * 6378137 / 2.0), merc_y = (y * resolution - 2 * Math.PI * 6378137 / 2.0); return [merc_x, merc_y]; } var LngLatBounds = function LngLatBounds(sw, ne) { if (!sw) ; else if (ne) { this.setSouthWest(sw).setNorthEast(ne); } else if (sw.length === 4) { this.setSouthWest([ sw[0], sw[1] ]).setNorthEast([ sw[2], sw[3] ]); } else { this.setSouthWest(sw[0]).setNorthEast(sw[1]); } }; LngLatBounds.prototype.setNorthEast = function setNorthEast(ne) { this._ne = ne instanceof LngLat ? new LngLat(ne.lng, ne.lat) : LngLat.convert(ne); return this; }; LngLatBounds.prototype.setSouthWest = function setSouthWest(sw) { this._sw = sw instanceof LngLat ? new LngLat(sw.lng, sw.lat) : LngLat.convert(sw); return this; }; LngLatBounds.prototype.extend = function extend(obj) { var sw = this._sw, ne = this._ne; var sw2, ne2; if (obj instanceof LngLat) { sw2 = obj; ne2 = obj; } else if (obj instanceof LngLatBounds) { sw2 = obj._sw; ne2 = obj._ne; if (!sw2 || !ne2) { return this; } } else { if (Array.isArray(obj)) { if (obj.length === 4 || obj.every(Array.isArray)) { var lngLatBoundsObj = obj; return this.extend(LngLatBounds.convert(lngLatBoundsObj)); } else { var lngLatObj = obj; return this.extend(LngLat.convert(lngLatObj)); } } return this; } if (!sw && !ne) { this._sw = new LngLat(sw2.lng, sw2.lat); this._ne = new LngLat(ne2.lng, ne2.lat); } else { sw.lng = Math.min(sw2.lng, sw.lng); sw.lat = Math.min(sw2.lat, sw.lat); ne.lng = Math.max(ne2.lng, ne.lng); ne.lat = Math.max(ne2.lat, ne.lat); } return this; }; LngLatBounds.prototype.getCenter = function getCenter() { return new LngLat((this._sw.lng + this._ne.lng) / 2, (this._sw.lat + this._ne.lat) / 2); }; LngLatBounds.prototype.getSouthWest = function getSouthWest() { return this._sw; }; LngLatBounds.prototype.getNorthEast = function getNorthEast() { return this._ne; }; LngLatBounds.prototype.getNorthWest = function getNorthWest() { return new LngLat(this.getWest(), this.getNorth()); }; LngLatBounds.prototype.getSouthEast = function getSouthEast() { return new LngLat(this.getEast(), this.getSouth()); }; LngLatBounds.prototype.getWest = function getWest() { return this._sw.lng; }; LngLatBounds.prototype.getSouth = function getSouth() { return this._sw.lat; }; LngLatBounds.prototype.getEast = function getEast() { return this._ne.lng; }; LngLatBounds.prototype.getNorth = function getNorth() { return this._ne.lat; }; LngLatBounds.prototype.toArray = function toArray() { return [ this._sw.toArray(), this._ne.toArray() ]; }; LngLatBounds.prototype.toString = function toString() { return 'LngLatBounds(' + this._sw.toString() + ', ' + this._ne.toString() + ')'; }; LngLatBounds.prototype.isEmpty = function isEmpty() { return !(this._sw && this._ne); }; LngLatBounds.prototype.contains = function contains(lnglat) { var ref = LngLat.convert(lnglat); var lng = ref.lng; var lat = ref.lat; var containsLatitude = this._sw.lat <= lat && lat <= this._ne.lat; var containsLongitude = this._sw.lng <= lng && lng <= this._ne.lng; if (this._sw.lng > this._ne.lng) { containsLongitude = this._sw.lng >= lng && lng >= this._ne.lng; } return containsLatitude && containsLongitude; }; LngLatBounds.convert = function convert(input) { if (!input || input instanceof LngLatBounds) { return input; } return new LngLatBounds(input); }; var earthRadius = 6371008.8; var LngLat = function LngLat(lng, lat) { if (isNaN(lng) || isNaN(lat)) { throw new Error('Invalid LngLat object: (' + lng + ', ' + lat + ')'); } this.lng = +lng; this.lat = +lat; if (this.lat > 90 || this.lat < -90) { throw new Error('Invalid LngLat latitude value: must be between -90 and 90'); } }; LngLat.prototype.wrap = function wrap$1() { return new LngLat(wrap(this.lng, -180, 180), this.lat); }; LngLat.prototype.toArray = function toArray() { return [ this.lng, this.lat ]; }; LngLat.prototype.toString = function toString() { return 'LngLat(' + this.lng + ', ' + this.lat + ')'; }; LngLat.prototype.distanceTo = function distanceTo(lngLat) { var rad = Math.PI / 180; var lat1 = this.lat * rad; var lat2 = lngLat.lat * rad; var a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((lngLat.lng - this.lng) * rad); var maxMeters = earthRadius * Math.acos(Math.min(a, 1)); return maxMeters; }; LngLat.prototype.toBounds = function toBounds(radius) { if (radius === void 0) radius = 0; var earthCircumferenceInMetersAtEquator = 40075017; var latAccuracy = 360 * radius / earthCircumferenceInMetersAtEquator, lngAccuracy = latAccuracy / Math.cos(Math.PI / 180 * this.lat); return new LngLatBounds(new LngLat(this.lng - lngAccuracy, this.lat - latAccuracy), new LngLat(this.lng + lngAccuracy, this.lat + latAccuracy)); }; LngLat.convert = function convert(input) { if (input instanceof LngLat) { return input; } if (Array.isArray(input) && (input.length === 2 || input.length === 3)) { return new LngLat(Number(input[0]), Number(input[1])); } if (!Array.isArray(input) && typeof input === 'object' && input !== null) { return new LngLat(Number('lng' in input ? input.lng : input.lon), Number(input.lat)); } throw new Error('`LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, an object {lon: , lat: }, or an array of [, ]'); }; var earthCircumfrence = 2 * Math.PI * earthRadius; function circumferenceAtLatitude(latitude) { return earthCircumfrence * Math.cos(latitude * Math.PI / 180); } function mercatorXfromLng$1(lng) { return (180 + lng) / 360; } function mercatorYfromLat$1(lat) { return (180 - 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360))) / 360; } function mercatorZfromAltitude(altitude, lat) { return altitude / circumferenceAtLatitude(lat); } function lngFromMercatorX(x) { return x * 360 - 180; } function latFromMercatorY(y) { var y2 = 180 - y * 360; return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90; } function altitudeFromMercatorZ(z, y) { return z * circumferenceAtLatitude(latFromMercatorY(y)); } function mercatorScale(lat) { return 1 / Math.cos(lat * Math.PI / 180); } var MercatorCoordinate = function MercatorCoordinate(x, y, z) { if (z === void 0) z = 0; this.x = +x; this.y = +y; this.z = +z; }; MercatorCoordinate.fromLngLat = function fromLngLat(lngLatLike, altitude) { if (altitude === void 0) altitude = 0; var lngLat = LngLat.convert(lngLatLike); return new MercatorCoordinate(mercatorXfromLng$1(lngLat.lng), mercatorYfromLat$1(lngLat.lat), mercatorZfromAltitude(altitude, lngLat.lat)); }; MercatorCoordinate.prototype.toLngLat = function toLngLat() { return new LngLat(lngFromMercatorX(this.x), latFromMercatorY(this.y)); }; MercatorCoordinate.prototype.toAltitude = function toAltitude() { return altitudeFromMercatorZ(this.z, this.y); }; MercatorCoordinate.prototype.meterInMercatorCoordinateUnits = function meterInMercatorCoordinateUnits() { return 1 / earthCircumfrence * mercatorScale(latFromMercatorY(this.y)); }; var CanonicalTileID = function CanonicalTileID(z, x, y) { this.z = z; this.x = x; this.y = y; this.key = calculateKey(0, z, z, x, y); }; CanonicalTileID.prototype.equals = function equals(id) { return this.z === id.z && this.x === id.x && this.y === id.y; }; CanonicalTileID.prototype.url = function url(urls, scheme) { var bbox = getTileBBox(this.x, this.y, this.z); var quadkey = getQuadkey(this.z, this.x, this.y); return urls[(this.x + this.y) % urls.length].replace('{prefix}', (this.x % 16).toString(16) + (this.y % 16).toString(16)).replace('{z}', String(this.z)).replace('{x}', String(this.x)).replace('{y}', String(scheme === 'tms' ? Math.pow(2, this.z) - this.y - 1 : this.y)).replace('{quadkey}', quadkey).replace('{bbox-epsg-3857}', bbox); }; CanonicalTileID.prototype.getTilePoint = function getTilePoint(coord) { var tilesAtZoom = Math.pow(2, this.z); return new pointGeometry((coord.x * tilesAtZoom - this.x) * EXTENT$1, (coord.y * tilesAtZoom - this.y) * EXTENT$1); }; CanonicalTileID.prototype.toString = function toString() { return this.z + '/' + this.x + '/' + this.y; }; var UnwrappedTileID = function UnwrappedTileID(wrap, canonical) { this.wrap = wrap; this.canonical = canonical; this.key = calculateKey(wrap, canonical.z, canonical.z, canonical.x, canonical.y); }; var OverscaledTileID = function OverscaledTileID(overscaledZ, wrap, z, x, y) { this.overscaledZ = overscaledZ; this.wrap = wrap; this.canonical = new CanonicalTileID(z, +x, +y); this.key = calculateKey(wrap, overscaledZ, z, x, y); }; OverscaledTileID.prototype.equals = function equals(id) { return this.overscaledZ === id.overscaledZ && this.wrap === id.wrap && this.canonical.equals(id.canonical); }; OverscaledTileID.prototype.scaledTo = function scaledTo(targetZ) { var zDifference = this.canonical.z - targetZ; if (targetZ > this.canonical.z) { return new OverscaledTileID(targetZ, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y); } else { return new OverscaledTileID(targetZ, this.wrap, targetZ, this.canonical.x >> zDifference, this.canonical.y >> zDifference); } }; OverscaledTileID.prototype.calculateScaledKey = function calculateScaledKey(targetZ, withWrap) { var zDifference = this.canonical.z - targetZ; if (targetZ > this.canonical.z) { return calculateKey(this.wrap * +withWrap, targetZ, this.canonical.z, this.canonical.x, this.canonical.y); } else { return calculateKey(this.wrap * +withWrap, targetZ, targetZ, this.canonical.x >> zDifference, this.canonical.y >> zDifference); } }; OverscaledTileID.prototype.isChildOf = function isChildOf(parent) { if (parent.wrap !== this.wrap) { return false; } var zDifference = this.canonical.z - parent.canonical.z; return parent.overscaledZ === 0 || parent.overscaledZ < this.overscaledZ && parent.canonical.x === this.canonical.x >> zDifference && parent.canonical.y === this.canonical.y >> zDifference; }; OverscaledTileID.prototype.children = function children(sourceMaxZoom) { if (this.overscaledZ >= sourceMaxZoom) { return [new OverscaledTileID(this.overscaledZ + 1, this.wrap, this.canonical.z, this.canonical.x, this.canonical.y)]; } var z = this.canonical.z + 1; var x = this.canonical.x * 2; var y = this.canonical.y * 2; return [ new OverscaledTileID(z, this.wrap, z, x, y), new OverscaledTileID(z, this.wrap, z, x + 1, y), new OverscaledTileID(z, this.wrap, z, x, y + 1), new OverscaledTileID(z, this.wrap, z, x + 1, y + 1) ]; }; OverscaledTileID.prototype.isLessThan = function isLessThan(rhs) { if (this.wrap < rhs.wrap) { return true; } if (this.wrap > rhs.wrap) { return false; } if (this.overscaledZ < rhs.overscaledZ) { return true; } if (this.overscaledZ > rhs.overscaledZ) { return false; } if (this.canonical.x < rhs.canonical.x) { return true; } if (this.canonical.x > rhs.canonical.x) { return false; } if (this.canonical.y < rhs.canonical.y) { return true; } return false; }; OverscaledTileID.prototype.wrapped = function wrapped() { return new OverscaledTileID(this.overscaledZ, 0, this.canonical.z, this.canonical.x, this.canonical.y); }; OverscaledTileID.prototype.unwrapTo = function unwrapTo(wrap) { return new OverscaledTileID(this.overscaledZ, wrap, this.canonical.z, this.canonical.x, this.canonical.y); }; OverscaledTileID.prototype.overscaleFactor = function overscaleFactor() { return Math.pow(2, this.overscaledZ - this.canonical.z); }; OverscaledTileID.prototype.toUnwrapped = function toUnwrapped() { return new UnwrappedTileID(this.wrap, this.canonical); }; OverscaledTileID.prototype.toString = function toString() { return this.overscaledZ + '/' + this.canonical.x + '/' + this.canonical.y; }; OverscaledTileID.prototype.getTilePoint = function getTilePoint(coord) { return this.canonical.getTilePoint(new MercatorCoordinate(coord.x - this.wrap, coord.y)); }; function calculateKey(wrap, overscaledZ, z, x, y) { wrap *= 2; if (wrap < 0) { wrap = wrap * -1 - 1; } var dim = 1 << z; return (dim * dim * wrap + dim * y + x).toString(36) + z.toString(36) + overscaledZ.toString(36); } function getQuadkey(z, x, y) { var quadkey = '', mask; for (var i = z; i > 0; i--) { mask = 1 << i - 1; quadkey += (x & mask ? 1 : 0) + (y & mask ? 2 : 0); } return quadkey; } register('CanonicalTileID', CanonicalTileID); register('OverscaledTileID', OverscaledTileID, { omit: ['posMatrix'] }); var DEMData = function DEMData(uid, data, encoding) { this.uid = uid; if (data.height !== data.width) { throw new RangeError('DEM tiles must be square'); } if (encoding && encoding !== 'mapbox' && encoding !== 'terrarium') { return warnOnce('"' + encoding + '" is not a valid encoding type. Valid types include "mapbox" and "terrarium".'); } this.stride = data.height; var dim = this.dim = data.height - 2; this.data = new Uint32Array(data.data.buffer); this.encoding = encoding || 'mapbox'; for (var x = 0; x < dim; x++) { this.data[this._idx(-1, x)] = this.data[this._idx(0, x)]; this.data[this._idx(dim, x)] = this.data[this._idx(dim - 1, x)]; this.data[this._idx(x, -1)] = this.data[this._idx(x, 0)]; this.data[this._idx(x, dim)] = this.data[this._idx(x, dim - 1)]; } this.data[this._idx(-1, -1)] = this.data[this._idx(0, 0)]; this.data[this._idx(dim, -1)] = this.data[this._idx(dim - 1, 0)]; this.data[this._idx(-1, dim)] = this.data[this._idx(0, dim - 1)]; this.data[this._idx(dim, dim)] = this.data[this._idx(dim - 1, dim - 1)]; }; DEMData.prototype.get = function get(x, y) { var pixels = new Uint8Array(this.data.buffer); var index = this._idx(x, y) * 4; var unpack = this.encoding === 'terrarium' ? this._unpackTerrarium : this._unpackMapbox; return unpack(pixels[index], pixels[index + 1], pixels[index + 2]); }; DEMData.prototype.getUnpackVector = function getUnpackVector() { return this.encoding === 'terrarium' ? [ 256, 1, 1 / 256, 32768 ] : [ 6553.6, 25.6, 0.1, 10000 ]; }; DEMData.prototype._idx = function _idx(x, y) { if (x < -1 || x >= this.dim + 1 || y < -1 || y >= this.dim + 1) { throw new RangeError('out of range source coordinates for DEM data'); } return (y + 1) * this.stride + (x + 1); }; DEMData.prototype._unpackMapbox = function _unpackMapbox(r, g, b) { return (r * 256 * 256 + g * 256 + b) / 10 - 10000; }; DEMData.prototype._unpackTerrarium = function _unpackTerrarium(r, g, b) { return r * 256 + g + b / 256 - 32768; }; DEMData.prototype.getPixels = function getPixels() { return new RGBAImage({ width: this.stride, height: this.stride }, new Uint8Array(this.data.buffer)); }; DEMData.prototype.backfillBorder = function backfillBorder(borderTile, dx, dy) { if (this.dim !== borderTile.dim) { throw new Error('dem dimension mismatch'); } var xMin = dx * this.dim, xMax = dx * this.dim + this.dim, yMin = dy * this.dim, yMax = dy * this.dim + this.dim; switch (dx) { case -1: xMin = xMax - 1; break; case 1: xMax = xMin + 1; break; } switch (dy) { case -1: yMin = yMax - 1; break; case 1: yMax = yMin + 1; break; } var ox = -dx * this.dim; var oy = -dy * this.dim; for (var y = yMin; y < yMax; y++) { for (var x = xMin; x < xMax; x++) { this.data[this._idx(x, y)] = borderTile.data[this._idx(x + ox, y + oy)]; } } }; register('DEMData', DEMData); function deserialize$1(input, style) { var output = {}; if (!style) { return output; } var loop = function () { var bucket = list$1[i$1]; var layers = bucket.layerIds.map(function (id) { return style.getLayer(id); }).filter(Boolean); if (layers.length === 0) { return; } bucket.layers = layers; if (bucket.stateDependentLayerIds) { bucket.stateDependentLayers = bucket.stateDependentLayerIds.map(function (lId) { return layers.filter(function (l) { return l.id === lId; })[0]; }); } for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; output[layer.id] = bucket; } }; for (var i$1 = 0, list$1 = input; i$1 < list$1.length; i$1 += 1) loop(); return output; } var DictionaryCoder = function DictionaryCoder(strings) { this._stringToNumber = {}; this._numberToString = []; for (var i = 0; i < strings.length; i++) { var string = strings[i]; this._stringToNumber[string] = i; this._numberToString[i] = string; } }; DictionaryCoder.prototype.encode = function encode(string) { return this._stringToNumber[string]; }; DictionaryCoder.prototype.decode = function decode(n) { return this._numberToString[n]; }; var Feature = function Feature(vectorTileFeature, z, x, y, id) { this.type = 'Feature'; this._vectorTileFeature = vectorTileFeature; vectorTileFeature._z = z; vectorTileFeature._x = x; vectorTileFeature._y = y; this.properties = vectorTileFeature.properties; this.id = id; }; var prototypeAccessors$1 = { geometry: { configurable: true } }; prototypeAccessors$1.geometry.get = function () { if (this._geometry === undefined) { this._geometry = this._vectorTileFeature.toGeoJSON(this._vectorTileFeature._x, this._vectorTileFeature._y, this._vectorTileFeature._z).geometry; } return this._geometry; }; prototypeAccessors$1.geometry.set = function (g) { this._geometry = g; }; Feature.prototype.toJSON = function toJSON() { var json = { geometry: this.geometry }; for (var i in this) { if (i === '_geometry' || i === '_vectorTileFeature') { continue; } json[i] = this[i]; } return json; }; Object.defineProperties(Feature.prototype, prototypeAccessors$1); var SourceFeatureState = function SourceFeatureState() { this.state = {}; this.stateChanges = {}; this.deletedStates = {}; }; SourceFeatureState.prototype.updateState = function updateState(sourceLayer, featureId, newState) { var feature = String(featureId); this.stateChanges[sourceLayer] = this.stateChanges[sourceLayer] || {}; this.stateChanges[sourceLayer][feature] = this.stateChanges[sourceLayer][feature] || {}; extend(this.stateChanges[sourceLayer][feature], newState); if (this.deletedStates[sourceLayer] === null) { this.deletedStates[sourceLayer] = {}; for (var ft in this.state[sourceLayer]) { if (ft !== feature) { this.deletedStates[sourceLayer][ft] = null; } } } else { var featureDeletionQueued = this.deletedStates[sourceLayer] && this.deletedStates[sourceLayer][feature] === null; if (featureDeletionQueued) { this.deletedStates[sourceLayer][feature] = {}; for (var prop in this.state[sourceLayer][feature]) { if (!newState[prop]) { this.deletedStates[sourceLayer][feature][prop] = null; } } } else { for (var key in newState) { var deletionInQueue = this.deletedStates[sourceLayer] && this.deletedStates[sourceLayer][feature] && this.deletedStates[sourceLayer][feature][key] === null; if (deletionInQueue) { delete this.deletedStates[sourceLayer][feature][key]; } } } } }; SourceFeatureState.prototype.removeFeatureState = function removeFeatureState(sourceLayer, featureId, key) { var sourceLayerDeleted = this.deletedStates[sourceLayer] === null; if (sourceLayerDeleted) { return; } var feature = String(featureId); this.deletedStates[sourceLayer] = this.deletedStates[sourceLayer] || {}; if (key && featureId !== undefined) { if (this.deletedStates[sourceLayer][feature] !== null) { this.deletedStates[sourceLayer][feature] = this.deletedStates[sourceLayer][feature] || {}; this.deletedStates[sourceLayer][feature][key] = null; } } else if (featureId !== undefined) { var updateInQueue = this.stateChanges[sourceLayer] && this.stateChanges[sourceLayer][feature]; if (updateInQueue) { this.deletedStates[sourceLayer][feature] = {}; for (key in this.stateChanges[sourceLayer][feature]) { this.deletedStates[sourceLayer][feature][key] = null; } } else { this.deletedStates[sourceLayer][feature] = null; } } else { this.deletedStates[sourceLayer] = null; } }; SourceFeatureState.prototype.getState = function getState(sourceLayer, featureId) { var feature = String(featureId); var base = this.state[sourceLayer] || {}; var changes = this.stateChanges[sourceLayer] || {}; var reconciledState = extend({}, base[feature], changes[feature]); if (this.deletedStates[sourceLayer] === null) { return {}; } else if (this.deletedStates[sourceLayer]) { var featureDeletions = this.deletedStates[sourceLayer][featureId]; if (featureDeletions === null) { return {}; } for (var prop in featureDeletions) { delete reconciledState[prop]; } } return reconciledState; }; SourceFeatureState.prototype.initializeTileState = function initializeTileState(tile, painter) { tile.setFeatureState(this.state, painter); }; SourceFeatureState.prototype.coalesceChanges = function coalesceChanges(tiles, painter) { var featuresChanged = {}; for (var sourceLayer in this.stateChanges) { this.state[sourceLayer] = this.state[sourceLayer] || {}; var layerStates = {}; for (var feature in this.stateChanges[sourceLayer]) { if (!this.state[sourceLayer][feature]) { this.state[sourceLayer][feature] = {}; } extend(this.state[sourceLayer][feature], this.stateChanges[sourceLayer][feature]); layerStates[feature] = this.state[sourceLayer][feature]; } featuresChanged[sourceLayer] = layerStates; } for (var sourceLayer$1 in this.deletedStates) { this.state[sourceLayer$1] = this.state[sourceLayer$1] || {}; var layerStates$1 = {}; if (this.deletedStates[sourceLayer$1] === null) { for (var ft in this.state[sourceLayer$1]) { layerStates$1[ft] = {}; this.state[sourceLayer$1][ft] = {}; } } else { for (var feature$1 in this.deletedStates[sourceLayer$1]) { var deleteWholeFeatureState = this.deletedStates[sourceLayer$1][feature$1] === null; if (deleteWholeFeatureState) { this.state[sourceLayer$1][feature$1] = {}; } else { for (var i = 0, list = Object.keys(this.deletedStates[sourceLayer$1][feature$1]); i < list.length; i += 1) { var key = list[i]; delete this.state[sourceLayer$1][feature$1][key]; } } layerStates$1[feature$1] = this.state[sourceLayer$1][feature$1]; } } featuresChanged[sourceLayer$1] = featuresChanged[sourceLayer$1] || {}; extend(featuresChanged[sourceLayer$1], layerStates$1); } this.stateChanges = {}; this.deletedStates = {}; if (Object.keys(featuresChanged).length === 0) { return; } for (var id in tiles) { var tile = tiles[id]; tile.setFeatureState(featuresChanged, painter); } }; var FeatureIndex = function FeatureIndex(tileID, promoteId) { this.tileID = tileID; this.x = tileID.canonical.x; this.y = tileID.canonical.y; this.z = tileID.canonical.z; this.grid = new gridIndex(EXTENT$1, 16, 0); this.grid3D = new gridIndex(EXTENT$1, 16, 0); this.featureIndexArray = new FeatureIndexArray(); this.promoteId = promoteId; }; FeatureIndex.prototype.insert = function insert(feature, geometry, featureIndex, sourceLayerIndex, bucketIndex, is3D) { var key = this.featureIndexArray.length; this.featureIndexArray.emplaceBack(featureIndex, sourceLayerIndex, bucketIndex); var grid = is3D ? this.grid3D : this.grid; for (var r = 0; r < geometry.length; r++) { var ring = geometry[r]; var bbox = [ Infinity, Infinity, -Infinity, -Infinity ]; for (var i = 0; i < ring.length; i++) { var p = ring[i]; bbox[0] = Math.min(bbox[0], p.x); bbox[1] = Math.min(bbox[1], p.y); bbox[2] = Math.max(bbox[2], p.x); bbox[3] = Math.max(bbox[3], p.y); } if (bbox[0] < EXTENT$1 && bbox[1] < EXTENT$1 && bbox[2] >= 0 && bbox[3] >= 0) { grid.insert(key, bbox[0], bbox[1], bbox[2], bbox[3]); } } }; FeatureIndex.prototype.loadVTLayers = function loadVTLayers() { if (!this.vtLayers) { this.vtLayers = new vectorTile.VectorTile(new pbf(this.rawTileData)).layers; this.sourceLayerCoder = new DictionaryCoder(this.vtLayers ? Object.keys(this.vtLayers).sort() : ['_geojsonTileLayer']); } return this.vtLayers; }; FeatureIndex.prototype.query = function query(args, styleLayers, serializedLayers, sourceFeatureState) { var this$1 = this; this.loadVTLayers(); var params = args.params || {}, pixelsToTileUnits = EXTENT$1 / args.tileSize / args.scale, filter = createFilter(params.filter); var queryGeometry = args.queryGeometry; var queryPadding = args.queryPadding * pixelsToTileUnits; var bounds = getBounds(queryGeometry); var matching = this.grid.query(bounds.minX - queryPadding, bounds.minY - queryPadding, bounds.maxX + queryPadding, bounds.maxY + queryPadding); var cameraBounds = getBounds(args.cameraQueryGeometry); var matching3D = this.grid3D.query(cameraBounds.minX - queryPadding, cameraBounds.minY - queryPadding, cameraBounds.maxX + queryPadding, cameraBounds.maxY + queryPadding, function (bx1, by1, bx2, by2) { return polygonIntersectsBox(args.cameraQueryGeometry, bx1 - queryPadding, by1 - queryPadding, bx2 + queryPadding, by2 + queryPadding); }); for (var i = 0, list = matching3D; i < list.length; i += 1) { var key = list[i]; matching.push(key); } matching.sort(topDownFeatureComparator); var result = {}; var previousIndex; var loop = function (k) { var index = matching[k]; if (index === previousIndex) { return; } previousIndex = index; var match = this$1.featureIndexArray.get(index); var featureGeometry = null; this$1.loadMatchingFeature(result, match.bucketIndex, match.sourceLayerIndex, match.featureIndex, filter, params.layers, params.availableImages, styleLayers, serializedLayers, sourceFeatureState, function (feature, styleLayer, featureState) { if (!featureGeometry) { featureGeometry = loadGeometry(feature); } return styleLayer.queryIntersectsFeature(queryGeometry, feature, featureState, featureGeometry, this$1.z, args.transform, pixelsToTileUnits, args.pixelPosMatrix); }); }; for (var k = 0; k < matching.length; k++) loop(k); return result; }; FeatureIndex.prototype.loadMatchingFeature = function loadMatchingFeature(result, bucketIndex, sourceLayerIndex, featureIndex, filter, filterLayerIDs, availableImages, styleLayers, serializedLayers, sourceFeatureState, intersectionTest) { var layerIDs = this.bucketLayerIDs[bucketIndex]; if (filterLayerIDs && !arraysIntersect(filterLayerIDs, layerIDs)) { return; } var sourceLayerName = this.sourceLayerCoder.decode(sourceLayerIndex); var sourceLayer = this.vtLayers[sourceLayerName]; var feature = sourceLayer.feature(featureIndex); if (filter.needGeometry) { var evaluationFeature = toEvaluationFeature(feature, true); if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) { return; } } else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) { return; } var id = this.getId(feature, sourceLayerName); for (var l = 0; l < layerIDs.length; l++) { var layerID = layerIDs[l]; if (filterLayerIDs && filterLayerIDs.indexOf(layerID) < 0) { continue; } var styleLayer = styleLayers[layerID]; if (!styleLayer) { continue; } var featureState = {}; if (id !== undefined && sourceFeatureState) { featureState = sourceFeatureState.getState(styleLayer.sourceLayer || '_geojsonTileLayer', id); } var serializedLayer = extend({}, serializedLayers[layerID]); serializedLayer.paint = evaluateProperties(serializedLayer.paint, styleLayer.paint, feature, featureState, availableImages); serializedLayer.layout = evaluateProperties(serializedLayer.layout, styleLayer.layout, feature, featureState, availableImages); var intersectionZ = !intersectionTest || intersectionTest(feature, styleLayer, featureState); if (!intersectionZ) { continue; } var geojsonFeature = new Feature(feature, this.z, this.x, this.y, id); geojsonFeature.layer = serializedLayer; var layerResult = result[layerID]; if (layerResult === undefined) { layerResult = result[layerID] = []; } layerResult.push({ featureIndex: featureIndex, feature: geojsonFeature, intersectionZ: intersectionZ }); } }; FeatureIndex.prototype.lookupSymbolFeatures = function lookupSymbolFeatures(symbolFeatureIndexes, serializedLayers, bucketIndex, sourceLayerIndex, filterSpec, filterLayerIDs, availableImages, styleLayers) { var result = {}; this.loadVTLayers(); var filter = createFilter(filterSpec); for (var i = 0, list = symbolFeatureIndexes; i < list.length; i += 1) { var symbolFeatureIndex = list[i]; this.loadMatchingFeature(result, bucketIndex, sourceLayerIndex, symbolFeatureIndex, filter, filterLayerIDs, availableImages, styleLayers, serializedLayers); } return result; }; FeatureIndex.prototype.hasLayer = function hasLayer(id) { for (var i$1 = 0, list$1 = this.bucketLayerIDs; i$1 < list$1.length; i$1 += 1) { var layerIDs = list$1[i$1]; for (var i = 0, list = layerIDs; i < list.length; i += 1) { var layerID = list[i]; if (id === layerID) { return true; } } } return false; }; FeatureIndex.prototype.getId = function getId(feature, sourceLayerId) { var id = feature.id; if (this.promoteId) { var propName = typeof this.promoteId === 'string' ? this.promoteId : this.promoteId[sourceLayerId]; id = feature.properties[propName]; if (typeof id === 'boolean') { id = Number(id); } } return id; }; register('FeatureIndex', FeatureIndex, { omit: [ 'rawTileData', 'sourceLayerCoder' ] }); function evaluateProperties(serializedProperties, styleLayerProperties, feature, featureState, availableImages) { return mapObject(serializedProperties, function (property, key) { var prop = styleLayerProperties instanceof PossiblyEvaluated ? styleLayerProperties.get(key) : null; return prop && prop.evaluate ? prop.evaluate(feature, featureState, availableImages) : prop; }); } function getBounds(geometry) { var minX = Infinity; var minY = Infinity; var maxX = -Infinity; var maxY = -Infinity; for (var i = 0, list = geometry; i < list.length; i += 1) { var p = list[i]; minX = Math.min(minX, p.x); minY = Math.min(minY, p.y); maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y); } return { minX: minX, minY: minY, maxX: maxX, maxY: maxY }; } function topDownFeatureComparator(a, b) { return b - a; } var CLOCK_SKEW_RETRY_TIMEOUT = 30000; var Tile = function Tile(tileID, size) { this.tileID = tileID; this.uid = uniqueId(); this.uses = 0; this.tileSize = size; this.buckets = {}; this.expirationTime = null; this.queryPadding = 0; this.hasSymbolBuckets = false; this.hasRTLText = false; this.dependencies = {}; this.expiredRequestCount = 0; this.state = 'loading'; }; Tile.prototype.registerFadeDuration = function registerFadeDuration(duration) { var fadeEndTime = duration + this.timeAdded; if (fadeEndTime < exported.now()) { return; } if (this.fadeEndTime && fadeEndTime < this.fadeEndTime) { return; } this.fadeEndTime = fadeEndTime; }; Tile.prototype.wasRequested = function wasRequested() { return this.state === 'errored' || this.state === 'loaded' || this.state === 'reloading'; }; Tile.prototype.loadVectorData = function loadVectorData(data, painter, justReloaded) { if (this.hasData()) { this.unloadVectorData(); } this.state = 'loaded'; if (!data) { this.collisionBoxArray = new CollisionBoxArray(); return; } if (data.featureIndex) { this.latestFeatureIndex = data.featureIndex; if (data.rawTileData) { this.latestRawTileData = data.rawTileData; this.latestFeatureIndex.rawTileData = data.rawTileData; } else if (this.latestRawTileData) { this.latestFeatureIndex.rawTileData = this.latestRawTileData; } } this.collisionBoxArray = data.collisionBoxArray; this.buckets = deserialize$1(data.buckets, painter.style); this.hasSymbolBuckets = false; for (var id in this.buckets) { var bucket = this.buckets[id]; if (bucket instanceof SymbolBucket) { this.hasSymbolBuckets = true; if (justReloaded) { bucket.justReloaded = true; } else { break; } } } this.hasRTLText = false; if (this.hasSymbolBuckets) { for (var id$1 in this.buckets) { var bucket$1 = this.buckets[id$1]; if (bucket$1 instanceof SymbolBucket) { if (bucket$1.hasRTLText) { this.hasRTLText = true; lazyLoadRTLTextPlugin(); break; } } } } this.queryPadding = 0; for (var id$2 in this.buckets) { var bucket$2 = this.buckets[id$2]; this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id$2).queryRadius(bucket$2)); } if (data.imageAtlas) { this.imageAtlas = data.imageAtlas; } if (data.glyphAtlasImage) { this.glyphAtlasImage = data.glyphAtlasImage; } }; Tile.prototype.unloadVectorData = function unloadVectorData() { for (var id in this.buckets) { this.buckets[id].destroy(); } this.buckets = {}; if (this.imageAtlasTexture) { this.imageAtlasTexture.destroy(); } if (this.imageAtlas) { this.imageAtlas = null; } if (this.glyphAtlasTexture) { this.glyphAtlasTexture.destroy(); } this.latestFeatureIndex = null; this.state = 'unloaded'; }; Tile.prototype.getBucket = function getBucket(layer) { return this.buckets[layer.id]; }; Tile.prototype.upload = function upload(context) { for (var id in this.buckets) { var bucket = this.buckets[id]; if (bucket.uploadPending()) { bucket.upload(context); } } var gl = context.gl; if (this.imageAtlas && !this.imageAtlas.uploaded) { this.imageAtlasTexture = new Texture(context, this.imageAtlas.image, gl.RGBA); this.imageAtlas.uploaded = true; } if (this.glyphAtlasImage) { this.glyphAtlasTexture = new Texture(context, this.glyphAtlasImage, gl.ALPHA); this.glyphAtlasImage = null; } }; Tile.prototype.prepare = function prepare(imageManager) { if (this.imageAtlas) { this.imageAtlas.patchUpdatedImages(imageManager, this.imageAtlasTexture); } }; Tile.prototype.queryRenderedFeatures = function queryRenderedFeatures(layers, serializedLayers, sourceFeatureState, queryGeometry, cameraQueryGeometry, scale, params, transform, maxPitchScaleFactor, pixelPosMatrix) { if (!this.latestFeatureIndex || !this.latestFeatureIndex.rawTileData) { return {}; } return this.latestFeatureIndex.query({ queryGeometry: queryGeometry, cameraQueryGeometry: cameraQueryGeometry, scale: scale, tileSize: this.tileSize, pixelPosMatrix: pixelPosMatrix, transform: transform, params: params, queryPadding: this.queryPadding * maxPitchScaleFactor }, layers, serializedLayers, sourceFeatureState); }; Tile.prototype.querySourceFeatures = function querySourceFeatures(result, params) { var featureIndex = this.latestFeatureIndex; if (!featureIndex || !featureIndex.rawTileData) { return; } var vtLayers = featureIndex.loadVTLayers(); var sourceLayer = params ? params.sourceLayer : ''; var layer = vtLayers._geojsonTileLayer || vtLayers[sourceLayer]; if (!layer) { return; } var filter = createFilter(params && params.filter); var ref = this.tileID.canonical; var z = ref.z; var x = ref.x; var y = ref.y; var coord = { z: z, x: x, y: y }; for (var i = 0; i < layer.length; i++) { var feature = layer.feature(i); if (filter.needGeometry) { var evaluationFeature = toEvaluationFeature(feature, true); if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), evaluationFeature, this.tileID.canonical)) { continue; } } else if (!filter.filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) { continue; } var id = featureIndex.getId(feature, sourceLayer); var geojsonFeature = new Feature(feature, z, x, y, id); geojsonFeature.tile = coord; result.push(geojsonFeature); } }; Tile.prototype.hasData = function hasData() { return this.state === 'loaded' || this.state === 'reloading' || this.state === 'expired'; }; Tile.prototype.patternsLoaded = function patternsLoaded() { return this.imageAtlas && !!Object.keys(this.imageAtlas.patternPositions).length; }; Tile.prototype.setExpiryData = function setExpiryData(data) { var prior = this.expirationTime; if (data.cacheControl) { var parsedCC = parseCacheControl(data.cacheControl); if (parsedCC['max-age']) { this.expirationTime = Date.now() + parsedCC['max-age'] * 1000; } } else if (data.expires) { this.expirationTime = new Date(data.expires).getTime(); } if (this.expirationTime) { var now = Date.now(); var isExpired = false; if (this.expirationTime > now) { isExpired = false; } else if (!prior) { isExpired = true; } else if (this.expirationTime < prior) { isExpired = true; } else { var delta = this.expirationTime - prior; if (!delta) { isExpired = true; } else { this.expirationTime = now + Math.max(delta, CLOCK_SKEW_RETRY_TIMEOUT); } } if (isExpired) { this.expiredRequestCount++; this.state = 'expired'; } else { this.expiredRequestCount = 0; } } }; Tile.prototype.getExpiryTimeout = function getExpiryTimeout() { if (this.expirationTime) { if (this.expiredRequestCount) { return 1000 * (1 << Math.min(this.expiredRequestCount - 1, 31)); } else { return Math.min(this.expirationTime - new Date().getTime(), Math.pow(2, 31) - 1); } } }; Tile.prototype.setFeatureState = function setFeatureState(states, painter) { if (!this.latestFeatureIndex || !this.latestFeatureIndex.rawTileData || Object.keys(states).length === 0) { return; } var vtLayers = this.latestFeatureIndex.loadVTLayers(); for (var id in this.buckets) { if (!painter.style.hasLayer(id)) { continue; } var bucket = this.buckets[id]; var sourceLayerId = bucket.layers[0]['sourceLayer'] || '_geojsonTileLayer'; var sourceLayer = vtLayers[sourceLayerId]; var sourceLayerStates = states[sourceLayerId]; if (!sourceLayer || !sourceLayerStates || Object.keys(sourceLayerStates).length === 0) { continue; } bucket.update(sourceLayerStates, sourceLayer, this.imageAtlas && this.imageAtlas.patternPositions || {}); var layer = painter && painter.style && painter.style.getLayer(id); if (layer) { this.queryPadding = Math.max(this.queryPadding, layer.queryRadius(bucket)); } } }; Tile.prototype.holdingForFade = function holdingForFade() { return this.symbolFadeHoldUntil !== undefined; }; Tile.prototype.symbolFadeFinished = function symbolFadeFinished() { return !this.symbolFadeHoldUntil || this.symbolFadeHoldUntil < exported.now(); }; Tile.prototype.clearFadeHold = function clearFadeHold() { this.symbolFadeHoldUntil = undefined; }; Tile.prototype.setHoldDuration = function setHoldDuration(duration) { this.symbolFadeHoldUntil = exported.now() + duration; }; Tile.prototype.setDependencies = function setDependencies(namespace, dependencies) { var index = {}; for (var i = 0, list = dependencies; i < list.length; i += 1) { var dep = list[i]; index[dep] = true; } this.dependencies[namespace] = index; }; Tile.prototype.hasDependency = function hasDependency(namespaces, keys) { for (var i$1 = 0, list$1 = namespaces; i$1 < list$1.length; i$1 += 1) { var namespace = list$1[i$1]; var dependencies = this.dependencies[namespace]; if (dependencies) { for (var i = 0, list = keys; i < list.length; i += 1) { var key = list[i]; if (dependencies[key]) { return true; } } } } return false; }; var refProperties = [ 'type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout' ]; var performance = window$1.performance; var RequestPerformance = function RequestPerformance(request) { this._marks = { start: [ request.url, 'start' ].join('#'), end: [ request.url, 'end' ].join('#'), measure: request.url.toString() }; performance.mark(this._marks.start); }; RequestPerformance.prototype.finish = function finish() { performance.mark(this._marks.end); var resourceTimingData = performance.getEntriesByName(this._marks.measure); if (resourceTimingData.length === 0) { performance.measure(this._marks.measure, this._marks.start, this._marks.end); resourceTimingData = performance.getEntriesByName(this._marks.measure); performance.clearMarks(this._marks.start); performance.clearMarks(this._marks.end); performance.clearMeasures(this._marks.measure); } return resourceTimingData; }; exports.Actor = Actor; exports.AlphaImage = AlphaImage; exports.CanonicalTileID = CanonicalTileID; exports.CollisionBoxArray = CollisionBoxArray; exports.Color = Color; exports.DEMData = DEMData; exports.DataConstantProperty = DataConstantProperty; exports.DictionaryCoder = DictionaryCoder; exports.EXTENT = EXTENT$1; exports.ErrorEvent = ErrorEvent; exports.EvaluationParameters = EvaluationParameters; exports.Event = Event; exports.Evented = Evented; exports.FeatureIndex = FeatureIndex; exports.FillBucket = FillBucket; exports.FillExtrusionBucket = FillExtrusionBucket; exports.ImageAtlas = ImageAtlas; exports.ImagePosition = ImagePosition; exports.LineBucket = LineBucket; exports.LngLat = LngLat; exports.LngLatBounds = LngLatBounds; exports.MercatorCoordinate = MercatorCoordinate; exports.ONE_EM = ONE_EM; exports.OverscaledTileID = OverscaledTileID; exports.Point = pointGeometry; exports.Point$1 = pointGeometry; exports.Properties = Properties; exports.Protobuf = pbf; exports.RGBAImage = RGBAImage; exports.RequestManager = RequestManager; exports.RequestPerformance = RequestPerformance; exports.ResourceType = ResourceType; exports.SegmentVector = SegmentVector; exports.SourceFeatureState = SourceFeatureState; exports.StructArrayLayout1ui2 = StructArrayLayout1ui2; exports.StructArrayLayout2f1f2i16 = StructArrayLayout2f1f2i16; exports.StructArrayLayout2i4 = StructArrayLayout2i4; exports.StructArrayLayout3ui6 = StructArrayLayout3ui6; exports.StructArrayLayout4i8 = StructArrayLayout4i8; exports.SymbolBucket = SymbolBucket; exports.Texture = Texture; exports.Tile = Tile; exports.Transitionable = Transitionable; exports.Uniform1f = Uniform1f; exports.Uniform1i = Uniform1i; exports.Uniform2f = Uniform2f; exports.Uniform3f = Uniform3f; exports.Uniform4f = Uniform4f; exports.UniformColor = UniformColor; exports.UniformMatrix4f = UniformMatrix4f; exports.UnwrappedTileID = UnwrappedTileID; exports.ValidationError = ValidationError; exports.WritingMode = WritingMode; exports.ZoomHistory = ZoomHistory; exports.add = add; exports.addDynamicAttributes = addDynamicAttributes; exports.asyncAll = asyncAll; exports.bezier = bezier; exports.bindAll = bindAll; exports.browser = exported; exports.cacheEntryPossiblyAdded = cacheEntryPossiblyAdded; exports.clamp = clamp; exports.clearTileCache = clearTileCache; exports.clipLine = clipLine; exports.clone = clone$1; exports.clone$1 = clone; exports.clone$2 = clone$2; exports.collisionCircleLayout = collisionCircleLayout; exports.config = config; exports.create = create$2; exports.create$1 = create$1; exports.create$2 = create; exports.createCommonjsModule = createCommonjsModule; exports.createExpression = createExpression; exports.createLayout = createLayout; exports.createStyleLayer = createStyleLayer; exports.cross = cross; exports.deepEqual = deepEqual; exports.dot = dot; exports.dot$1 = dot$1; exports.ease = ease; exports.emitValidationErrors = emitValidationErrors; exports.endsWith = endsWith; exports.enforceCacheSizeLimit = enforceCacheSizeLimit; exports.evaluateSizeForFeature = evaluateSizeForFeature; exports.evaluateSizeForZoom = evaluateSizeForZoom; exports.evaluateVariableOffset = evaluateVariableOffset; exports.evented = evented; exports.extend = extend; exports.featureFilter = createFilter; exports.filterObject = filterObject; exports.fromRotation = fromRotation; exports.getAnchorAlignment = getAnchorAlignment; exports.getAnchorJustification = getAnchorJustification; exports.getArrayBuffer = getArrayBuffer; exports.getImage = getImage; exports.getJSON = getJSON; exports.getRTLTextPluginStatus = getRTLTextPluginStatus; exports.getReferrer = getReferrer; exports.getVideo = getVideo; exports.identity = identity; exports.invert = invert; exports.isChar = unicodeBlockLookup; exports.isMapboxURL = isMapboxURL; exports.keysDifference = keysDifference; exports.makeRequest = makeRequest; exports.mapObject = mapObject; exports.mercatorXfromLng = mercatorXfromLng$1; exports.mercatorYfromLat = mercatorYfromLat$1; exports.mercatorZfromAltitude = mercatorZfromAltitude; exports.mul = mul; exports.multiply = multiply; exports.mvt = vectorTile; exports.nextPowerOfTwo = nextPowerOfTwo; exports.normalize = normalize; exports.number = number; exports.offscreenCanvasSupported = offscreenCanvasSupported; exports.ortho = ortho; exports.parseGlyphPBF = parseGlyphPBF; exports.pbf = pbf; exports.performSymbolLayout = performSymbolLayout; exports.perspective = perspective; exports.pick = pick; exports.plugin = plugin; exports.polygonIntersectsPolygon = polygonIntersectsPolygon; exports.postMapLoadEvent = postMapLoadEvent; exports.postTurnstileEvent = postTurnstileEvent; exports.potpack = potpack; exports.refProperties = refProperties; exports.register = register; exports.registerForPluginStateChange = registerForPluginStateChange; exports.renderColorRamp = renderColorRamp; exports.rotate = rotate; exports.rotateX = rotateX; exports.rotateZ = rotateZ; exports.scale = scale; exports.scale$1 = scale$2; exports.scale$2 = scale$1; exports.setCacheLimits = setCacheLimits; exports.setRTLTextPlugin = setRTLTextPlugin; exports.sphericalToCartesian = sphericalToCartesian; exports.sqrLen = sqrLen; exports.styleSpec = spec; exports.sub = sub; exports.symbolSize = symbolSize; exports.transformMat3 = transformMat3; exports.transformMat4 = transformMat4; exports.translate = translate$1; exports.triggerPluginCompletionEvent = triggerPluginCompletionEvent; exports.uniqueId = uniqueId; exports.validateCustomStyleLayer = validateCustomStyleLayer; exports.validateLight = validateLight$1; exports.validateStyle = validateStyle; exports.values = values; exports.vectorTile = vectorTile; exports.version = version; exports.warnOnce = warnOnce; exports.webpSupported = exported$1; exports.window = window$1; exports.wrap = wrap; }); define(['./shared'], function (performance) { 'use strict'; function stringify(obj) { var type = typeof obj; if (type === 'number' || type === 'boolean' || type === 'string' || obj === undefined || obj === null) { return JSON.stringify(obj); } if (Array.isArray(obj)) { var str$1 = '['; for (var i$1 = 0, list = obj; i$1 < list.length; i$1 += 1) { var val = list[i$1]; str$1 += stringify(val) + ','; } return str$1 + ']'; } var keys = Object.keys(obj).sort(); var str = '{'; for (var i = 0; i < keys.length; i++) { str += JSON.stringify(keys[i]) + ':' + stringify(obj[keys[i]]) + ','; } return str + '}'; } function getKey(layer) { var key = ''; for (var i = 0, list = performance.refProperties; i < list.length; i += 1) { var k = list[i]; key += '/' + stringify(layer[k]); } return key; } function groupByLayout(layers, cachedKeys) { var groups = {}; for (var i = 0; i < layers.length; i++) { var k = cachedKeys && cachedKeys[layers[i].id] || getKey(layers[i]); if (cachedKeys) { cachedKeys[layers[i].id] = k; } var group = groups[k]; if (!group) { group = groups[k] = []; } group.push(layers[i]); } var result = []; for (var k$1 in groups) { result.push(groups[k$1]); } return result; } var StyleLayerIndex = function StyleLayerIndex(layerConfigs) { this.keyCache = {}; if (layerConfigs) { this.replace(layerConfigs); } }; StyleLayerIndex.prototype.replace = function replace(layerConfigs) { this._layerConfigs = {}; this._layers = {}; this.update(layerConfigs, []); }; StyleLayerIndex.prototype.update = function update(layerConfigs, removedIds) { var this$1 = this; for (var i = 0, list = layerConfigs; i < list.length; i += 1) { var layerConfig = list[i]; this._layerConfigs[layerConfig.id] = layerConfig; var layer = this._layers[layerConfig.id] = performance.createStyleLayer(layerConfig); layer._featureFilter = performance.featureFilter(layer.filter); if (this.keyCache[layerConfig.id]) { delete this.keyCache[layerConfig.id]; } } for (var i$1 = 0, list$1 = removedIds; i$1 < list$1.length; i$1 += 1) { var id = list$1[i$1]; delete this.keyCache[id]; delete this._layerConfigs[id]; delete this._layers[id]; } this.familiesBySource = {}; var groups = groupByLayout(performance.values(this._layerConfigs), this.keyCache); for (var i$2 = 0, list$2 = groups; i$2 < list$2.length; i$2 += 1) { var layerConfigs$1 = list$2[i$2]; var layers = layerConfigs$1.map(function (layerConfig) { return this$1._layers[layerConfig.id]; }); var layer$1 = layers[0]; if (layer$1.visibility === 'none') { continue; } var sourceId = layer$1.source || ''; var sourceGroup = this.familiesBySource[sourceId]; if (!sourceGroup) { sourceGroup = this.familiesBySource[sourceId] = {}; } var sourceLayerId = layer$1.sourceLayer || '_geojsonTileLayer'; var sourceLayerFamilies = sourceGroup[sourceLayerId]; if (!sourceLayerFamilies) { sourceLayerFamilies = sourceGroup[sourceLayerId] = []; } sourceLayerFamilies.push(layers); } }; var padding = 1; var GlyphAtlas = function GlyphAtlas(stacks) { var positions = {}; var bins = []; for (var stack in stacks) { var glyphs = stacks[stack]; var stackPositions = positions[stack] = {}; for (var id in glyphs) { var src = glyphs[+id]; if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) { continue; } var bin = { x: 0, y: 0, w: src.bitmap.width + 2 * padding, h: src.bitmap.height + 2 * padding }; bins.push(bin); stackPositions[id] = { rect: bin, metrics: src.metrics }; } } var ref = performance.potpack(bins); var w = ref.w; var h = ref.h; var image = new performance.AlphaImage({ width: w || 1, height: h || 1 }); for (var stack$1 in stacks) { var glyphs$1 = stacks[stack$1]; for (var id$1 in glyphs$1) { var src$1 = glyphs$1[+id$1]; if (!src$1 || src$1.bitmap.width === 0 || src$1.bitmap.height === 0) { continue; } var bin$1 = positions[stack$1][id$1].rect; performance.AlphaImage.copy(src$1.bitmap, image, { x: 0, y: 0 }, { x: bin$1.x + padding, y: bin$1.y + padding }, src$1.bitmap); } } this.image = image; this.positions = positions; }; performance.register('GlyphAtlas', GlyphAtlas); var WorkerTile = function WorkerTile(params) { this.tileID = new performance.OverscaledTileID(params.tileID.overscaledZ, params.tileID.wrap, params.tileID.canonical.z, params.tileID.canonical.x, params.tileID.canonical.y); this.uid = params.uid; this.zoom = params.zoom; this.pixelRatio = params.pixelRatio; this.tileSize = params.tileSize; this.source = params.source; this.overscaling = this.tileID.overscaleFactor(); this.showCollisionBoxes = params.showCollisionBoxes; this.collectResourceTiming = !!params.collectResourceTiming; this.returnDependencies = !!params.returnDependencies; this.promoteId = params.promoteId; }; WorkerTile.prototype.parse = function parse(data, layerIndex, availableImages, actor, callback) { var this$1 = this; this.status = 'parsing'; this.data = data; this.collisionBoxArray = new performance.CollisionBoxArray(); var sourceLayerCoder = new performance.DictionaryCoder(Object.keys(data.layers).sort()); var featureIndex = new performance.FeatureIndex(this.tileID, this.promoteId); featureIndex.bucketLayerIDs = []; var buckets = {}; var options = { featureIndex: featureIndex, iconDependencies: {}, patternDependencies: {}, glyphDependencies: {}, availableImages: availableImages }; var layerFamilies = layerIndex.familiesBySource[this.source]; for (var sourceLayerId in layerFamilies) { var sourceLayer = data.layers[sourceLayerId]; if (!sourceLayer) { continue; } if (sourceLayer.version === 1) { performance.warnOnce('Vector tile source "' + this.source + '" layer "' + sourceLayerId + '" ' + 'does not use vector tile spec v2 and therefore may have some rendering errors.'); } var sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId); var features = []; for (var index = 0; index < sourceLayer.length; index++) { var feature = sourceLayer.feature(index); var id = featureIndex.getId(feature, sourceLayerId); features.push({ feature: feature, id: id, index: index, sourceLayerIndex: sourceLayerIndex }); } for (var i = 0, list = layerFamilies[sourceLayerId]; i < list.length; i += 1) { var family = list[i]; var layer = family[0]; if (layer.minzoom && this.zoom < Math.floor(layer.minzoom)) { continue; } if (layer.maxzoom && this.zoom >= layer.maxzoom) { continue; } if (layer.visibility === 'none') { continue; } recalculateLayers(family, this.zoom, availableImages); var bucket = buckets[layer.id] = layer.createBucket({ index: featureIndex.bucketLayerIDs.length, layers: family, zoom: this.zoom, pixelRatio: this.pixelRatio, overscaling: this.overscaling, collisionBoxArray: this.collisionBoxArray, sourceLayerIndex: sourceLayerIndex, sourceID: this.source }); bucket.populate(features, options, this.tileID.canonical); featureIndex.bucketLayerIDs.push(family.map(function (l) { return l.id; })); } } var error; var glyphMap; var iconMap; var patternMap; var stacks = performance.mapObject(options.glyphDependencies, function (glyphs) { return Object.keys(glyphs).map(Number); }); if (Object.keys(stacks).length) { actor.send('getGlyphs', { uid: this.uid, stacks: stacks }, function (err, result) { if (!error) { error = err; glyphMap = result; maybePrepare.call(this$1); } }); } else { glyphMap = {}; } var icons = Object.keys(options.iconDependencies); if (icons.length) { actor.send('getImages', { icons: icons, source: this.source, tileID: this.tileID, type: 'icons' }, function (err, result) { if (!error) { error = err; iconMap = result; maybePrepare.call(this$1); } }); } else { iconMap = {}; } var patterns = Object.keys(options.patternDependencies); if (patterns.length) { actor.send('getImages', { icons: patterns, source: this.source, tileID: this.tileID, type: 'patterns' }, function (err, result) { if (!error) { error = err; patternMap = result; maybePrepare.call(this$1); } }); } else { patternMap = {}; } maybePrepare.call(this); function maybePrepare() { if (error) { return callback(error); } else if (glyphMap && iconMap && patternMap) { var glyphAtlas = new GlyphAtlas(glyphMap); var imageAtlas = new performance.ImageAtlas(iconMap, patternMap); for (var key in buckets) { var bucket = buckets[key]; if (bucket instanceof performance.SymbolBucket) { recalculateLayers(bucket.layers, this.zoom, availableImages); performance.performSymbolLayout(bucket, glyphMap, glyphAtlas.positions, iconMap, imageAtlas.iconPositions, this.showCollisionBoxes, this.tileID.canonical); } else if (bucket.hasPattern && (bucket instanceof performance.LineBucket || bucket instanceof performance.FillBucket || bucket instanceof performance.FillExtrusionBucket)) { recalculateLayers(bucket.layers, this.zoom, availableImages); bucket.addFeatures(options, this.tileID.canonical, imageAtlas.patternPositions); } } this.status = 'done'; callback(null, { buckets: performance.values(buckets).filter(function (b) { return !b.isEmpty(); }), featureIndex: featureIndex, collisionBoxArray: this.collisionBoxArray, glyphAtlasImage: glyphAtlas.image, imageAtlas: imageAtlas, glyphMap: this.returnDependencies ? glyphMap : null, iconMap: this.returnDependencies ? iconMap : null, glyphPositions: this.returnDependencies ? glyphAtlas.positions : null }); } } }; function recalculateLayers(layers, zoom, availableImages) { var parameters = new performance.EvaluationParameters(zoom); for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; layer.recalculate(parameters, availableImages); } } function loadVectorTile(params, callback) { var request = performance.getArrayBuffer(params.request, function (err, data, cacheControl, expires) { if (err) { callback(err); } else if (data) { callback(null, { vectorTile: new performance.vectorTile.VectorTile(new performance.pbf(data)), rawData: data, cacheControl: cacheControl, expires: expires }); } }); return function () { request.cancel(); callback(); }; } var VectorTileWorkerSource = function VectorTileWorkerSource(actor, layerIndex, availableImages, loadVectorData) { this.actor = actor; this.layerIndex = layerIndex; this.availableImages = availableImages; this.loadVectorData = loadVectorData || loadVectorTile; this.loading = {}; this.loaded = {}; }; VectorTileWorkerSource.prototype.loadTile = function loadTile(params, callback) { var this$1 = this; var uid = params.uid; if (!this.loading) { this.loading = {}; } var perf = params && params.request && params.request.collectResourceTiming ? new performance.RequestPerformance(params.request) : false; var workerTile = this.loading[uid] = new WorkerTile(params); workerTile.abort = this.loadVectorData(params, function (err, response) { delete this$1.loading[uid]; if (err || !response) { workerTile.status = 'done'; this$1.loaded[uid] = workerTile; return callback(err); } var rawTileData = response.rawData; var cacheControl = {}; if (response.expires) { cacheControl.expires = response.expires; } if (response.cacheControl) { cacheControl.cacheControl = response.cacheControl; } var resourceTiming = {}; if (perf) { var resourceTimingData = perf.finish(); if (resourceTimingData) { resourceTiming.resourceTiming = JSON.parse(JSON.stringify(resourceTimingData)); } } workerTile.vectorTile = response.vectorTile; workerTile.parse(response.vectorTile, this$1.layerIndex, this$1.availableImages, this$1.actor, function (err, result) { if (err || !result) { return callback(err); } callback(null, performance.extend({ rawTileData: rawTileData.slice(0) }, result, cacheControl, resourceTiming)); }); this$1.loaded = this$1.loaded || {}; this$1.loaded[uid] = workerTile; }); }; VectorTileWorkerSource.prototype.reloadTile = function reloadTile(params, callback) { var this$1 = this; var loaded = this.loaded, uid = params.uid, vtSource = this; if (loaded && loaded[uid]) { var workerTile = loaded[uid]; workerTile.showCollisionBoxes = params.showCollisionBoxes; var done = function (err, data) { var reloadCallback = workerTile.reloadCallback; if (reloadCallback) { delete workerTile.reloadCallback; workerTile.parse(workerTile.vectorTile, vtSource.layerIndex, this$1.availableImages, vtSource.actor, reloadCallback); } callback(err, data); }; if (workerTile.status === 'parsing') { workerTile.reloadCallback = done; } else if (workerTile.status === 'done') { if (workerTile.vectorTile) { workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, done); } else { done(); } } } }; VectorTileWorkerSource.prototype.abortTile = function abortTile(params, callback) { var loading = this.loading, uid = params.uid; if (loading && loading[uid] && loading[uid].abort) { loading[uid].abort(); delete loading[uid]; } callback(); }; VectorTileWorkerSource.prototype.removeTile = function removeTile(params, callback) { var loaded = this.loaded, uid = params.uid; if (loaded && loaded[uid]) { delete loaded[uid]; } callback(); }; var ImageBitmap = performance.window.ImageBitmap; var RasterDEMTileWorkerSource = function RasterDEMTileWorkerSource() { this.loaded = {}; }; RasterDEMTileWorkerSource.prototype.loadTile = function loadTile(params, callback) { var uid = params.uid; var encoding = params.encoding; var rawImageData = params.rawImageData; var imagePixels = ImageBitmap && rawImageData instanceof ImageBitmap ? this.getImageData(rawImageData) : rawImageData; var dem = new performance.DEMData(uid, imagePixels, encoding); this.loaded = this.loaded || {}; this.loaded[uid] = dem; callback(null, dem); }; RasterDEMTileWorkerSource.prototype.getImageData = function getImageData(imgBitmap) { if (!this.offscreenCanvas || !this.offscreenCanvasContext) { this.offscreenCanvas = new OffscreenCanvas(imgBitmap.width, imgBitmap.height); this.offscreenCanvasContext = this.offscreenCanvas.getContext('2d'); } this.offscreenCanvas.width = imgBitmap.width; this.offscreenCanvas.height = imgBitmap.height; this.offscreenCanvasContext.drawImage(imgBitmap, 0, 0, imgBitmap.width, imgBitmap.height); var imgData = this.offscreenCanvasContext.getImageData(-1, -1, imgBitmap.width + 2, imgBitmap.height + 2); this.offscreenCanvasContext.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height); return new performance.RGBAImage({ width: imgData.width, height: imgData.height }, imgData.data); }; RasterDEMTileWorkerSource.prototype.removeTile = function removeTile(params) { var loaded = this.loaded, uid = params.uid; if (loaded && loaded[uid]) { delete loaded[uid]; } }; var geojsonRewind = rewind; function rewind(gj, outer) { var type = gj && gj.type, i; if (type === 'FeatureCollection') { for (i = 0; i < gj.features.length; i++) { rewind(gj.features[i], outer); } } else if (type === 'GeometryCollection') { for (i = 0; i < gj.geometries.length; i++) { rewind(gj.geometries[i], outer); } } else if (type === 'Feature') { rewind(gj.geometry, outer); } else if (type === 'Polygon') { rewindRings(gj.coordinates, outer); } else if (type === 'MultiPolygon') { for (i = 0; i < gj.coordinates.length; i++) { rewindRings(gj.coordinates[i], outer); } } return gj; } function rewindRings(rings, outer) { if (rings.length === 0) { return; } rewindRing(rings[0], outer); for (var i = 1; i < rings.length; i++) { rewindRing(rings[i], !outer); } } function rewindRing(ring, dir) { var area = 0, err = 0; for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) { var k = (ring[i][0] - ring[j][0]) * (ring[j][1] + ring[i][1]); var m = area + k; err += Math.abs(area) >= Math.abs(k) ? area - m + k : k - m + area; area = m; } if (area + err >= 0 !== !!dir) { ring.reverse(); } } var toGeoJSON = performance.vectorTile.VectorTileFeature.prototype.toGeoJSON; var FeatureWrapper = function FeatureWrapper(feature) { this._feature = feature; this.extent = performance.EXTENT; this.type = feature.type; this.properties = feature.tags; if ('id' in feature && !isNaN(feature.id)) { this.id = parseInt(feature.id, 10); } }; FeatureWrapper.prototype.loadGeometry = function loadGeometry() { if (this._feature.type === 1) { var geometry = []; for (var i = 0, list = this._feature.geometry; i < list.length; i += 1) { var point = list[i]; geometry.push([new performance.Point$1(point[0], point[1])]); } return geometry; } else { var geometry$1 = []; for (var i$2 = 0, list$2 = this._feature.geometry; i$2 < list$2.length; i$2 += 1) { var ring = list$2[i$2]; var newRing = []; for (var i$1 = 0, list$1 = ring; i$1 < list$1.length; i$1 += 1) { var point$1 = list$1[i$1]; newRing.push(new performance.Point$1(point$1[0], point$1[1])); } geometry$1.push(newRing); } return geometry$1; } }; FeatureWrapper.prototype.toGeoJSON = function toGeoJSON$1(x, y, z) { return toGeoJSON.call(this, x, y, z); }; var GeoJSONWrapper = function GeoJSONWrapper(features) { this.layers = { '_geojsonTileLayer': this }; this.name = '_geojsonTileLayer'; this.extent = performance.EXTENT; this.length = features.length; this._features = features; }; GeoJSONWrapper.prototype.feature = function feature(i) { return new FeatureWrapper(this._features[i]); }; var VectorTileFeature = performance.vectorTile.VectorTileFeature; var geojson_wrapper = GeoJSONWrapper$1; function GeoJSONWrapper$1(features, options) { this.options = options || {}; this.features = features; this.length = features.length; } GeoJSONWrapper$1.prototype.feature = function (i) { return new FeatureWrapper$1(this.features[i], this.options.extent); }; function FeatureWrapper$1(feature, extent) { this.id = typeof feature.id === 'number' ? feature.id : undefined; this.type = feature.type; this.rawGeometry = feature.type === 1 ? [feature.geometry] : feature.geometry; this.properties = feature.tags; this.extent = extent || 4096; } FeatureWrapper$1.prototype.loadGeometry = function () { var rings = this.rawGeometry; this.geometry = []; for (var i = 0; i < rings.length; i++) { var ring = rings[i]; var newRing = []; for (var j = 0; j < ring.length; j++) { newRing.push(new performance.Point$1(ring[j][0], ring[j][1])); } this.geometry.push(newRing); } return this.geometry; }; FeatureWrapper$1.prototype.bbox = function () { if (!this.geometry) { this.loadGeometry(); } var rings = this.geometry; var x1 = Infinity; var x2 = -Infinity; var y1 = Infinity; var y2 = -Infinity; for (var i = 0; i < rings.length; i++) { var ring = rings[i]; for (var j = 0; j < ring.length; j++) { var coord = ring[j]; x1 = Math.min(x1, coord.x); x2 = Math.max(x2, coord.x); y1 = Math.min(y1, coord.y); y2 = Math.max(y2, coord.y); } } return [ x1, y1, x2, y2 ]; }; FeatureWrapper$1.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON; var vtPbf = fromVectorTileJs; var fromVectorTileJs_1 = fromVectorTileJs; var fromGeojsonVt_1 = fromGeojsonVt; var GeoJSONWrapper_1 = geojson_wrapper; function fromVectorTileJs(tile) { var out = new performance.pbf(); writeTile(tile, out); return out.finish(); } function fromGeojsonVt(layers, options) { options = options || {}; var l = {}; for (var k in layers) { l[k] = new geojson_wrapper(layers[k].features, options); l[k].name = k; l[k].version = options.version; l[k].extent = options.extent; } return fromVectorTileJs({ layers: l }); } function writeTile(tile, pbf) { for (var key in tile.layers) { pbf.writeMessage(3, writeLayer, tile.layers[key]); } } function writeLayer(layer, pbf) { pbf.writeVarintField(15, layer.version || 1); pbf.writeStringField(1, layer.name || ''); pbf.writeVarintField(5, layer.extent || 4096); var i; var context = { keys: [], values: [], keycache: {}, valuecache: {} }; for (i = 0; i < layer.length; i++) { context.feature = layer.feature(i); pbf.writeMessage(2, writeFeature, context); } var keys = context.keys; for (i = 0; i < keys.length; i++) { pbf.writeStringField(3, keys[i]); } var values = context.values; for (i = 0; i < values.length; i++) { pbf.writeMessage(4, writeValue, values[i]); } } function writeFeature(context, pbf) { var feature = context.feature; if (feature.id !== undefined) { pbf.writeVarintField(1, feature.id); } pbf.writeMessage(2, writeProperties, context); pbf.writeVarintField(3, feature.type); pbf.writeMessage(4, writeGeometry, feature); } function writeProperties(context, pbf) { var feature = context.feature; var keys = context.keys; var values = context.values; var keycache = context.keycache; var valuecache = context.valuecache; for (var key in feature.properties) { var keyIndex = keycache[key]; if (typeof keyIndex === 'undefined') { keys.push(key); keyIndex = keys.length - 1; keycache[key] = keyIndex; } pbf.writeVarint(keyIndex); var value = feature.properties[key]; var type = typeof value; if (type !== 'string' && type !== 'boolean' && type !== 'number') { value = JSON.stringify(value); } var valueKey = type + ':' + value; var valueIndex = valuecache[valueKey]; if (typeof valueIndex === 'undefined') { values.push(value); valueIndex = values.length - 1; valuecache[valueKey] = valueIndex; } pbf.writeVarint(valueIndex); } } function command(cmd, length) { return (length << 3) + (cmd & 7); } function zigzag(num) { return num << 1 ^ num >> 31; } function writeGeometry(feature, pbf) { var geometry = feature.loadGeometry(); var type = feature.type; var x = 0; var y = 0; var rings = geometry.length; for (var r = 0; r < rings; r++) { var ring = geometry[r]; var count = 1; if (type === 1) { count = ring.length; } pbf.writeVarint(command(1, count)); var lineCount = type === 3 ? ring.length - 1 : ring.length; for (var i = 0; i < lineCount; i++) { if (i === 1 && type !== 1) { pbf.writeVarint(command(2, lineCount - 1)); } var dx = ring[i].x - x; var dy = ring[i].y - y; pbf.writeVarint(zigzag(dx)); pbf.writeVarint(zigzag(dy)); x += dx; y += dy; } if (type === 3) { pbf.writeVarint(command(7, 1)); } } } function writeValue(value, pbf) { var type = typeof value; if (type === 'string') { pbf.writeStringField(1, value); } else if (type === 'boolean') { pbf.writeBooleanField(7, value); } else if (type === 'number') { if (value % 1 !== 0) { pbf.writeDoubleField(3, value); } else if (value < 0) { pbf.writeSVarintField(6, value); } else { pbf.writeVarintField(5, value); } } } vtPbf.fromVectorTileJs = fromVectorTileJs_1; vtPbf.fromGeojsonVt = fromGeojsonVt_1; vtPbf.GeoJSONWrapper = GeoJSONWrapper_1; function sortKD(ids, coords, nodeSize, left, right, depth) { if (right - left <= nodeSize) { return; } var m = left + right >> 1; select(ids, coords, m, left, right, depth % 2); sortKD(ids, coords, nodeSize, left, m - 1, depth + 1); sortKD(ids, coords, nodeSize, m + 1, right, depth + 1); } function select(ids, coords, k, left, right, inc) { while (right > left) { if (right - left > 600) { var n = right - left + 1; var m = k - left + 1; var z = Math.log(n); var s = 0.5 * Math.exp(2 * z / 3); var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); select(ids, coords, k, newLeft, newRight, inc); } var t = coords[2 * k + inc]; var i = left; var j = right; swapItem(ids, coords, left, k); if (coords[2 * right + inc] > t) { swapItem(ids, coords, left, right); } while (i < j) { swapItem(ids, coords, i, j); i++; j--; while (coords[2 * i + inc] < t) { i++; } while (coords[2 * j + inc] > t) { j--; } } if (coords[2 * left + inc] === t) { swapItem(ids, coords, left, j); } else { j++; swapItem(ids, coords, j, right); } if (j <= k) { left = j + 1; } if (k <= j) { right = j - 1; } } } function swapItem(ids, coords, i, j) { swap(ids, i, j); swap(coords, 2 * i, 2 * j); swap(coords, 2 * i + 1, 2 * j + 1); } function swap(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } function range(ids, coords, minX, minY, maxX, maxY, nodeSize) { var stack = [ 0, ids.length - 1, 0 ]; var result = []; var x, y; while (stack.length) { var axis = stack.pop(); var right = stack.pop(); var left = stack.pop(); if (right - left <= nodeSize) { for (var i = left; i <= right; i++) { x = coords[2 * i]; y = coords[2 * i + 1]; if (x >= minX && x <= maxX && y >= minY && y <= maxY) { result.push(ids[i]); } } continue; } var m = Math.floor((left + right) / 2); x = coords[2 * m]; y = coords[2 * m + 1]; if (x >= minX && x <= maxX && y >= minY && y <= maxY) { result.push(ids[m]); } var nextAxis = (axis + 1) % 2; if (axis === 0 ? minX <= x : minY <= y) { stack.push(left); stack.push(m - 1); stack.push(nextAxis); } if (axis === 0 ? maxX >= x : maxY >= y) { stack.push(m + 1); stack.push(right); stack.push(nextAxis); } } return result; } function within(ids, coords, qx, qy, r, nodeSize) { var stack = [ 0, ids.length - 1, 0 ]; var result = []; var r2 = r * r; while (stack.length) { var axis = stack.pop(); var right = stack.pop(); var left = stack.pop(); if (right - left <= nodeSize) { for (var i = left; i <= right; i++) { if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) { result.push(ids[i]); } } continue; } var m = Math.floor((left + right) / 2); var x = coords[2 * m]; var y = coords[2 * m + 1]; if (sqDist(x, y, qx, qy) <= r2) { result.push(ids[m]); } var nextAxis = (axis + 1) % 2; if (axis === 0 ? qx - r <= x : qy - r <= y) { stack.push(left); stack.push(m - 1); stack.push(nextAxis); } if (axis === 0 ? qx + r >= x : qy + r >= y) { stack.push(m + 1); stack.push(right); stack.push(nextAxis); } } return result; } function sqDist(ax, ay, bx, by) { var dx = ax - bx; var dy = ay - by; return dx * dx + dy * dy; } var defaultGetX = function (p) { return p[0]; }; var defaultGetY = function (p) { return p[1]; }; var KDBush = function KDBush(points, getX, getY, nodeSize, ArrayType) { if (getX === void 0) getX = defaultGetX; if (getY === void 0) getY = defaultGetY; if (nodeSize === void 0) nodeSize = 64; if (ArrayType === void 0) ArrayType = Float64Array; this.nodeSize = nodeSize; this.points = points; var IndexArrayType = points.length < 65536 ? Uint16Array : Uint32Array; var ids = this.ids = new IndexArrayType(points.length); var coords = this.coords = new ArrayType(points.length * 2); for (var i = 0; i < points.length; i++) { ids[i] = i; coords[2 * i] = getX(points[i]); coords[2 * i + 1] = getY(points[i]); } sortKD(ids, coords, nodeSize, 0, ids.length - 1, 0); }; KDBush.prototype.range = function range$1(minX, minY, maxX, maxY) { return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize); }; KDBush.prototype.within = function within$1(x, y, r) { return within(this.ids, this.coords, x, y, r, this.nodeSize); }; var defaultOptions = { minZoom: 0, maxZoom: 16, minPoints: 2, radius: 40, extent: 512, nodeSize: 64, log: false, generateId: false, reduce: null, map: function (props) { return props; } }; var Supercluster = function Supercluster(options) { this.options = extend(Object.create(defaultOptions), options); this.trees = new Array(this.options.maxZoom + 1); }; Supercluster.prototype.load = function load(points) { var ref = this.options; var log = ref.log; var minZoom = ref.minZoom; var maxZoom = ref.maxZoom; var nodeSize = ref.nodeSize; if (log) { console.time('total time'); } var timerId = 'prepare ' + points.length + ' points'; if (log) { console.time(timerId); } this.points = points; var clusters = []; for (var i = 0; i < points.length; i++) { if (!points[i].geometry) { continue; } clusters.push(createPointCluster(points[i], i)); } this.trees[maxZoom + 1] = new KDBush(clusters, getX, getY, nodeSize, Float32Array); if (log) { console.timeEnd(timerId); } for (var z = maxZoom; z >= minZoom; z--) { var now = +Date.now(); clusters = this._cluster(clusters, z); this.trees[z] = new KDBush(clusters, getX, getY, nodeSize, Float32Array); if (log) { console.log('z%d: %d clusters in %dms', z, clusters.length, +Date.now() - now); } } if (log) { console.timeEnd('total time'); } return this; }; Supercluster.prototype.getClusters = function getClusters(bbox, zoom) { var minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180; var minLat = Math.max(-90, Math.min(90, bbox[1])); var maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180; var maxLat = Math.max(-90, Math.min(90, bbox[3])); if (bbox[2] - bbox[0] >= 360) { minLng = -180; maxLng = 180; } else if (minLng > maxLng) { var easternHem = this.getClusters([ minLng, minLat, 180, maxLat ], zoom); var westernHem = this.getClusters([ -180, minLat, maxLng, maxLat ], zoom); return easternHem.concat(westernHem); } var tree = this.trees[this._limitZoom(zoom)]; var ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat)); var clusters = []; for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; var c = tree.points[id]; clusters.push(c.numPoints ? getClusterJSON(c) : this.points[c.index]); } return clusters; }; Supercluster.prototype.getChildren = function getChildren(clusterId) { var originId = this._getOriginId(clusterId); var originZoom = this._getOriginZoom(clusterId); var errorMsg = 'No cluster with the specified id.'; var index = this.trees[originZoom]; if (!index) { throw new Error(errorMsg); } var origin = index.points[originId]; if (!origin) { throw new Error(errorMsg); } var r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1)); var ids = index.within(origin.x, origin.y, r); var children = []; for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; var c = index.points[id]; if (c.parentId === clusterId) { children.push(c.numPoints ? getClusterJSON(c) : this.points[c.index]); } } if (children.length === 0) { throw new Error(errorMsg); } return children; }; Supercluster.prototype.getLeaves = function getLeaves(clusterId, limit, offset) { limit = limit || 10; offset = offset || 0; var leaves = []; this._appendLeaves(leaves, clusterId, limit, offset, 0); return leaves; }; Supercluster.prototype.getTile = function getTile(z, x, y) { var tree = this.trees[this._limitZoom(z)]; var z2 = Math.pow(2, z); var ref = this.options; var extent = ref.extent; var radius = ref.radius; var p = radius / extent; var top = (y - p) / z2; var bottom = (y + 1 + p) / z2; var tile = { features: [] }; this._addTileFeatures(tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom), tree.points, x, y, z2, tile); if (x === 0) { this._addTileFeatures(tree.range(1 - p / z2, top, 1, bottom), tree.points, z2, y, z2, tile); } if (x === z2 - 1) { this._addTileFeatures(tree.range(0, top, p / z2, bottom), tree.points, -1, y, z2, tile); } return tile.features.length ? tile : null; }; Supercluster.prototype.getClusterExpansionZoom = function getClusterExpansionZoom(clusterId) { var expansionZoom = this._getOriginZoom(clusterId) - 1; while (expansionZoom <= this.options.maxZoom) { var children = this.getChildren(clusterId); expansionZoom++; if (children.length !== 1) { break; } clusterId = children[0].properties.cluster_id; } return expansionZoom; }; Supercluster.prototype._appendLeaves = function _appendLeaves(result, clusterId, limit, offset, skipped) { var children = this.getChildren(clusterId); for (var i = 0, list = children; i < list.length; i += 1) { var child = list[i]; var props = child.properties; if (props && props.cluster) { if (skipped + props.point_count <= offset) { skipped += props.point_count; } else { skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped); } } else if (skipped < offset) { skipped++; } else { result.push(child); } if (result.length === limit) { break; } } return skipped; }; Supercluster.prototype._addTileFeatures = function _addTileFeatures(ids, points, x, y, z2, tile) { for (var i$1 = 0, list = ids; i$1 < list.length; i$1 += 1) { var i = list[i$1]; var c = points[i]; var isCluster = c.numPoints; var f = { type: 1, geometry: [[ Math.round(this.options.extent * (c.x * z2 - x)), Math.round(this.options.extent * (c.y * z2 - y)) ]], tags: isCluster ? getClusterProperties(c) : this.points[c.index].properties }; var id = void 0; if (isCluster) { id = c.id; } else if (this.options.generateId) { id = c.index; } else if (this.points[c.index].id) { id = this.points[c.index].id; } if (id !== undefined) { f.id = id; } tile.features.push(f); } }; Supercluster.prototype._limitZoom = function _limitZoom(z) { return Math.max(this.options.minZoom, Math.min(+z, this.options.maxZoom + 1)); }; Supercluster.prototype._cluster = function _cluster(points, zoom) { var clusters = []; var ref = this.options; var radius = ref.radius; var extent = ref.extent; var reduce = ref.reduce; var minPoints = ref.minPoints; var r = radius / (extent * Math.pow(2, zoom)); for (var i = 0; i < points.length; i++) { var p = points[i]; if (p.zoom <= zoom) { continue; } p.zoom = zoom; var tree = this.trees[zoom + 1]; var neighborIds = tree.within(p.x, p.y, r); var numPointsOrigin = p.numPoints || 1; var numPoints = numPointsOrigin; for (var i$1 = 0, list = neighborIds; i$1 < list.length; i$1 += 1) { var neighborId = list[i$1]; var b = tree.points[neighborId]; if (b.zoom > zoom) { numPoints += b.numPoints || 1; } } if (numPoints >= minPoints) { var wx = p.x * numPointsOrigin; var wy = p.y * numPointsOrigin; var clusterProperties = reduce && numPointsOrigin > 1 ? this._map(p, true) : null; var id = (i << 5) + (zoom + 1) + this.points.length; for (var i$2 = 0, list$1 = neighborIds; i$2 < list$1.length; i$2 += 1) { var neighborId$1 = list$1[i$2]; var b$1 = tree.points[neighborId$1]; if (b$1.zoom <= zoom) { continue; } b$1.zoom = zoom; var numPoints2 = b$1.numPoints || 1; wx += b$1.x * numPoints2; wy += b$1.y * numPoints2; b$1.parentId = id; if (reduce) { if (!clusterProperties) { clusterProperties = this._map(p, true); } reduce(clusterProperties, this._map(b$1)); } } p.parentId = id; clusters.push(createCluster(wx / numPoints, wy / numPoints, id, numPoints, clusterProperties)); } else { clusters.push(p); if (numPoints > 1) { for (var i$3 = 0, list$2 = neighborIds; i$3 < list$2.length; i$3 += 1) { var neighborId$2 = list$2[i$3]; var b$2 = tree.points[neighborId$2]; if (b$2.zoom <= zoom) { continue; } b$2.zoom = zoom; clusters.push(b$2); } } } } return clusters; }; Supercluster.prototype._getOriginId = function _getOriginId(clusterId) { return clusterId - this.points.length >> 5; }; Supercluster.prototype._getOriginZoom = function _getOriginZoom(clusterId) { return (clusterId - this.points.length) % 32; }; Supercluster.prototype._map = function _map(point, clone) { if (point.numPoints) { return clone ? extend({}, point.properties) : point.properties; } var original = this.points[point.index].properties; var result = this.options.map(original); return clone && result === original ? extend({}, result) : result; }; function createCluster(x, y, id, numPoints, properties) { return { x: x, y: y, zoom: Infinity, id: id, parentId: -1, numPoints: numPoints, properties: properties }; } function createPointCluster(p, id) { var ref = p.geometry.coordinates; var x = ref[0]; var y = ref[1]; return { x: lngX(x), y: latY(y), zoom: Infinity, index: id, parentId: -1 }; } function getClusterJSON(cluster) { return { type: 'Feature', id: cluster.id, properties: getClusterProperties(cluster), geometry: { type: 'Point', coordinates: [ xLng(cluster.x), yLat(cluster.y) ] } }; } function getClusterProperties(cluster) { var count = cluster.numPoints; var abbrev = count >= 10000 ? Math.round(count / 1000) + 'k' : count >= 1000 ? Math.round(count / 100) / 10 + 'k' : count; return extend(extend({}, cluster.properties), { cluster: true, cluster_id: cluster.id, point_count: count, point_count_abbreviated: abbrev }); } function lngX(lng) { return lng / 360 + 0.5; } function latY(lat) { var sin = Math.sin(lat * Math.PI / 180); var y = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI; return y < 0 ? 0 : y > 1 ? 1 : y; } function xLng(x) { return (x - 0.5) * 360; } function yLat(y) { var y2 = (180 - y * 360) * Math.PI / 180; return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90; } function extend(dest, src) { for (var id in src) { dest[id] = src[id]; } return dest; } function getX(p) { return p.x; } function getY(p) { return p.y; } function simplify(coords, first, last, sqTolerance) { var maxSqDist = sqTolerance; var mid = last - first >> 1; var minPosToMid = last - first; var index; var ax = coords[first]; var ay = coords[first + 1]; var bx = coords[last]; var by = coords[last + 1]; for (var i = first + 3; i < last; i += 3) { var d = getSqSegDist(coords[i], coords[i + 1], ax, ay, bx, by); if (d > maxSqDist) { index = i; maxSqDist = d; } else if (d === maxSqDist) { var posToMid = Math.abs(i - mid); if (posToMid < minPosToMid) { index = i; minPosToMid = posToMid; } } } if (maxSqDist > sqTolerance) { if (index - first > 3) { simplify(coords, first, index, sqTolerance); } coords[index + 2] = maxSqDist; if (last - index > 3) { simplify(coords, index, last, sqTolerance); } } } function getSqSegDist(px, py, x, y, bx, by) { var dx = bx - x; var dy = by - y; if (dx !== 0 || dy !== 0) { var t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy); if (t > 1) { x = bx; y = by; } else if (t > 0) { x += dx * t; y += dy * t; } } dx = px - x; dy = py - y; return dx * dx + dy * dy; } function createFeature(id, type, geom, tags) { var feature = { id: typeof id === 'undefined' ? null : id, type: type, geometry: geom, tags: tags, minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }; calcBBox(feature); return feature; } function calcBBox(feature) { var geom = feature.geometry; var type = feature.type; if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') { calcLineBBox(feature, geom); } else if (type === 'Polygon' || type === 'MultiLineString') { for (var i = 0; i < geom.length; i++) { calcLineBBox(feature, geom[i]); } } else if (type === 'MultiPolygon') { for (i = 0; i < geom.length; i++) { for (var j = 0; j < geom[i].length; j++) { calcLineBBox(feature, geom[i][j]); } } } } function calcLineBBox(feature, geom) { for (var i = 0; i < geom.length; i += 3) { feature.minX = Math.min(feature.minX, geom[i]); feature.minY = Math.min(feature.minY, geom[i + 1]); feature.maxX = Math.max(feature.maxX, geom[i]); feature.maxY = Math.max(feature.maxY, geom[i + 1]); } } function convert(data, options) { var features = []; if (data.type === 'FeatureCollection') { for (var i = 0; i < data.features.length; i++) { convertFeature(features, data.features[i], options, i); } } else if (data.type === 'Feature') { convertFeature(features, data, options); } else { convertFeature(features, { geometry: data }, options); } return features; } function convertFeature(features, geojson, options, index) { if (!geojson.geometry) { return; } var coords = geojson.geometry.coordinates; var type = geojson.geometry.type; var tolerance = Math.pow(options.tolerance / ((1 << options.maxZoom) * options.extent), 2); var geometry = []; var id = geojson.id; if (options.promoteId) { id = geojson.properties[options.promoteId]; } else if (options.generateId) { id = index || 0; } if (type === 'Point') { convertPoint(coords, geometry); } else if (type === 'MultiPoint') { for (var i = 0; i < coords.length; i++) { convertPoint(coords[i], geometry); } } else if (type === 'LineString') { convertLine(coords, geometry, tolerance, false); } else if (type === 'MultiLineString') { if (options.lineMetrics) { for (i = 0; i < coords.length; i++) { geometry = []; convertLine(coords[i], geometry, tolerance, false); features.push(createFeature(id, 'LineString', geometry, geojson.properties)); } return; } else { convertLines(coords, geometry, tolerance, false); } } else if (type === 'Polygon') { convertLines(coords, geometry, tolerance, true); } else if (type === 'MultiPolygon') { for (i = 0; i < coords.length; i++) { var polygon = []; convertLines(coords[i], polygon, tolerance, true); geometry.push(polygon); } } else if (type === 'GeometryCollection') { for (i = 0; i < geojson.geometry.geometries.length; i++) { convertFeature(features, { id: id, geometry: geojson.geometry.geometries[i], properties: geojson.properties }, options, index); } return; } else { throw new Error('Input data is not a valid GeoJSON object.'); } features.push(createFeature(id, type, geometry, geojson.properties)); } function convertPoint(coords, out) { out.push(projectX(coords[0])); out.push(projectY(coords[1])); out.push(0); } function convertLine(ring, out, tolerance, isPolygon) { var x0, y0; var size = 0; for (var j = 0; j < ring.length; j++) { var x = projectX(ring[j][0]); var y = projectY(ring[j][1]); out.push(x); out.push(y); out.push(0); if (j > 0) { if (isPolygon) { size += (x0 * y - x * y0) / 2; } else { size += Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)); } } x0 = x; y0 = y; } var last = out.length - 3; out[2] = 1; simplify(out, 0, last, tolerance); out[last + 2] = 1; out.size = Math.abs(size); out.start = 0; out.end = out.size; } function convertLines(rings, out, tolerance, isPolygon) { for (var i = 0; i < rings.length; i++) { var geom = []; convertLine(rings[i], geom, tolerance, isPolygon); out.push(geom); } } function projectX(x) { return x / 360 + 0.5; } function projectY(y) { var sin = Math.sin(y * Math.PI / 180); var y2 = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI; return y2 < 0 ? 0 : y2 > 1 ? 1 : y2; } function clip(features, scale, k1, k2, axis, minAll, maxAll, options) { k1 /= scale; k2 /= scale; if (minAll >= k1 && maxAll < k2) { return features; } else if (maxAll < k1 || minAll >= k2) { return null; } var clipped = []; for (var i = 0; i < features.length; i++) { var feature = features[i]; var geometry = feature.geometry; var type = feature.type; var min = axis === 0 ? feature.minX : feature.minY; var max = axis === 0 ? feature.maxX : feature.maxY; if (min >= k1 && max < k2) { clipped.push(feature); continue; } else if (max < k1 || min >= k2) { continue; } var newGeometry = []; if (type === 'Point' || type === 'MultiPoint') { clipPoints(geometry, newGeometry, k1, k2, axis); } else if (type === 'LineString') { clipLine(geometry, newGeometry, k1, k2, axis, false, options.lineMetrics); } else if (type === 'MultiLineString') { clipLines(geometry, newGeometry, k1, k2, axis, false); } else if (type === 'Polygon') { clipLines(geometry, newGeometry, k1, k2, axis, true); } else if (type === 'MultiPolygon') { for (var j = 0; j < geometry.length; j++) { var polygon = []; clipLines(geometry[j], polygon, k1, k2, axis, true); if (polygon.length) { newGeometry.push(polygon); } } } if (newGeometry.length) { if (options.lineMetrics && type === 'LineString') { for (j = 0; j < newGeometry.length; j++) { clipped.push(createFeature(feature.id, type, newGeometry[j], feature.tags)); } continue; } if (type === 'LineString' || type === 'MultiLineString') { if (newGeometry.length === 1) { type = 'LineString'; newGeometry = newGeometry[0]; } else { type = 'MultiLineString'; } } if (type === 'Point' || type === 'MultiPoint') { type = newGeometry.length === 3 ? 'Point' : 'MultiPoint'; } clipped.push(createFeature(feature.id, type, newGeometry, feature.tags)); } } return clipped.length ? clipped : null; } function clipPoints(geom, newGeom, k1, k2, axis) { for (var i = 0; i < geom.length; i += 3) { var a = geom[i + axis]; if (a >= k1 && a <= k2) { newGeom.push(geom[i]); newGeom.push(geom[i + 1]); newGeom.push(geom[i + 2]); } } } function clipLine(geom, newGeom, k1, k2, axis, isPolygon, trackMetrics) { var slice = newSlice(geom); var intersect = axis === 0 ? intersectX : intersectY; var len = geom.start; var segLen, t; for (var i = 0; i < geom.length - 3; i += 3) { var ax = geom[i]; var ay = geom[i + 1]; var az = geom[i + 2]; var bx = geom[i + 3]; var by = geom[i + 4]; var a = axis === 0 ? ax : ay; var b = axis === 0 ? bx : by; var exited = false; if (trackMetrics) { segLen = Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2)); } if (a < k1) { if (b > k1) { t = intersect(slice, ax, ay, bx, by, k1); if (trackMetrics) { slice.start = len + segLen * t; } } } else if (a > k2) { if (b < k2) { t = intersect(slice, ax, ay, bx, by, k2); if (trackMetrics) { slice.start = len + segLen * t; } } } else { addPoint(slice, ax, ay, az); } if (b < k1 && a >= k1) { t = intersect(slice, ax, ay, bx, by, k1); exited = true; } if (b > k2 && a <= k2) { t = intersect(slice, ax, ay, bx, by, k2); exited = true; } if (!isPolygon && exited) { if (trackMetrics) { slice.end = len + segLen * t; } newGeom.push(slice); slice = newSlice(geom); } if (trackMetrics) { len += segLen; } } var last = geom.length - 3; ax = geom[last]; ay = geom[last + 1]; az = geom[last + 2]; a = axis === 0 ? ax : ay; if (a >= k1 && a <= k2) { addPoint(slice, ax, ay, az); } last = slice.length - 3; if (isPolygon && last >= 3 && (slice[last] !== slice[0] || slice[last + 1] !== slice[1])) { addPoint(slice, slice[0], slice[1], slice[2]); } if (slice.length) { newGeom.push(slice); } } function newSlice(line) { var slice = []; slice.size = line.size; slice.start = line.start; slice.end = line.end; return slice; } function clipLines(geom, newGeom, k1, k2, axis, isPolygon) { for (var i = 0; i < geom.length; i++) { clipLine(geom[i], newGeom, k1, k2, axis, isPolygon, false); } } function addPoint(out, x, y, z) { out.push(x); out.push(y); out.push(z); } function intersectX(out, ax, ay, bx, by, x) { var t = (x - ax) / (bx - ax); out.push(x); out.push(ay + (by - ay) * t); out.push(1); return t; } function intersectY(out, ax, ay, bx, by, y) { var t = (y - ay) / (by - ay); out.push(ax + (bx - ax) * t); out.push(y); out.push(1); return t; } function wrap(features, options) { var buffer = options.buffer / options.extent; var merged = features; var left = clip(features, 1, -1 - buffer, buffer, 0, -1, 2, options); var right = clip(features, 1, 1 - buffer, 2 + buffer, 0, -1, 2, options); if (left || right) { merged = clip(features, 1, -buffer, 1 + buffer, 0, -1, 2, options) || []; if (left) { merged = shiftFeatureCoords(left, 1).concat(merged); } if (right) { merged = merged.concat(shiftFeatureCoords(right, -1)); } } return merged; } function shiftFeatureCoords(features, offset) { var newFeatures = []; for (var i = 0; i < features.length; i++) { var feature = features[i], type = feature.type; var newGeometry; if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') { newGeometry = shiftCoords(feature.geometry, offset); } else if (type === 'MultiLineString' || type === 'Polygon') { newGeometry = []; for (var j = 0; j < feature.geometry.length; j++) { newGeometry.push(shiftCoords(feature.geometry[j], offset)); } } else if (type === 'MultiPolygon') { newGeometry = []; for (j = 0; j < feature.geometry.length; j++) { var newPolygon = []; for (var k = 0; k < feature.geometry[j].length; k++) { newPolygon.push(shiftCoords(feature.geometry[j][k], offset)); } newGeometry.push(newPolygon); } } newFeatures.push(createFeature(feature.id, type, newGeometry, feature.tags)); } return newFeatures; } function shiftCoords(points, offset) { var newPoints = []; newPoints.size = points.size; if (points.start !== undefined) { newPoints.start = points.start; newPoints.end = points.end; } for (var i = 0; i < points.length; i += 3) { newPoints.push(points[i] + offset, points[i + 1], points[i + 2]); } return newPoints; } function transformTile(tile, extent) { if (tile.transformed) { return tile; } var z2 = 1 << tile.z, tx = tile.x, ty = tile.y, i, j, k; for (i = 0; i < tile.features.length; i++) { var feature = tile.features[i], geom = feature.geometry, type = feature.type; feature.geometry = []; if (type === 1) { for (j = 0; j < geom.length; j += 2) { feature.geometry.push(transformPoint(geom[j], geom[j + 1], extent, z2, tx, ty)); } } else { for (j = 0; j < geom.length; j++) { var ring = []; for (k = 0; k < geom[j].length; k += 2) { ring.push(transformPoint(geom[j][k], geom[j][k + 1], extent, z2, tx, ty)); } feature.geometry.push(ring); } } } tile.transformed = true; return tile; } function transformPoint(x, y, extent, z2, tx, ty) { return [ Math.round(extent * (x * z2 - tx)), Math.round(extent * (y * z2 - ty)) ]; } function createTile(features, z, tx, ty, options) { var tolerance = z === options.maxZoom ? 0 : options.tolerance / ((1 << z) * options.extent); var tile = { features: [], numPoints: 0, numSimplified: 0, numFeatures: 0, source: null, x: tx, y: ty, z: z, transformed: false, minX: 2, minY: 1, maxX: -1, maxY: 0 }; for (var i = 0; i < features.length; i++) { tile.numFeatures++; addFeature(tile, features[i], tolerance, options); var minX = features[i].minX; var minY = features[i].minY; var maxX = features[i].maxX; var maxY = features[i].maxY; if (minX < tile.minX) { tile.minX = minX; } if (minY < tile.minY) { tile.minY = minY; } if (maxX > tile.maxX) { tile.maxX = maxX; } if (maxY > tile.maxY) { tile.maxY = maxY; } } return tile; } function addFeature(tile, feature, tolerance, options) { var geom = feature.geometry, type = feature.type, simplified = []; if (type === 'Point' || type === 'MultiPoint') { for (var i = 0; i < geom.length; i += 3) { simplified.push(geom[i]); simplified.push(geom[i + 1]); tile.numPoints++; tile.numSimplified++; } } else if (type === 'LineString') { addLine(simplified, geom, tile, tolerance, false, false); } else if (type === 'MultiLineString' || type === 'Polygon') { for (i = 0; i < geom.length; i++) { addLine(simplified, geom[i], tile, tolerance, type === 'Polygon', i === 0); } } else if (type === 'MultiPolygon') { for (var k = 0; k < geom.length; k++) { var polygon = geom[k]; for (i = 0; i < polygon.length; i++) { addLine(simplified, polygon[i], tile, tolerance, true, i === 0); } } } if (simplified.length) { var tags = feature.tags || null; if (type === 'LineString' && options.lineMetrics) { tags = {}; for (var key in feature.tags) { tags[key] = feature.tags[key]; } tags['mapbox_clip_start'] = geom.start / geom.size; tags['mapbox_clip_end'] = geom.end / geom.size; } var tileFeature = { geometry: simplified, type: type === 'Polygon' || type === 'MultiPolygon' ? 3 : type === 'LineString' || type === 'MultiLineString' ? 2 : 1, tags: tags }; if (feature.id !== null) { tileFeature.id = feature.id; } tile.features.push(tileFeature); } } function addLine(result, geom, tile, tolerance, isPolygon, isOuter) { var sqTolerance = tolerance * tolerance; if (tolerance > 0 && geom.size < (isPolygon ? sqTolerance : tolerance)) { tile.numPoints += geom.length / 3; return; } var ring = []; for (var i = 0; i < geom.length; i += 3) { if (tolerance === 0 || geom[i + 2] > sqTolerance) { tile.numSimplified++; ring.push(geom[i]); ring.push(geom[i + 1]); } tile.numPoints++; } if (isPolygon) { rewind$1(ring, isOuter); } result.push(ring); } function rewind$1(ring, clockwise) { var area = 0; for (var i = 0, len = ring.length, j = len - 2; i < len; j = i, i += 2) { area += (ring[i] - ring[j]) * (ring[i + 1] + ring[j + 1]); } if (area > 0 === clockwise) { for (i = 0, len = ring.length; i < len / 2; i += 2) { var x = ring[i]; var y = ring[i + 1]; ring[i] = ring[len - 2 - i]; ring[i + 1] = ring[len - 1 - i]; ring[len - 2 - i] = x; ring[len - 1 - i] = y; } } } function geojsonvt(data, options) { return new GeoJSONVT(data, options); } function GeoJSONVT(data, options) { options = this.options = extend$1(Object.create(this.options), options); var debug = options.debug; if (debug) { console.time('preprocess data'); } if (options.maxZoom < 0 || options.maxZoom > 24) { throw new Error('maxZoom should be in the 0-24 range'); } if (options.promoteId && options.generateId) { throw new Error('promoteId and generateId cannot be used together.'); } var features = convert(data, options); this.tiles = {}; this.tileCoords = []; if (debug) { console.timeEnd('preprocess data'); console.log('index: maxZoom: %d, maxPoints: %d', options.indexMaxZoom, options.indexMaxPoints); console.time('generate tiles'); this.stats = {}; this.total = 0; } features = wrap(features, options); if (features.length) { this.splitTile(features, 0, 0, 0); } if (debug) { if (features.length) { console.log('features: %d, points: %d', this.tiles[0].numFeatures, this.tiles[0].numPoints); } console.timeEnd('generate tiles'); console.log('tiles generated:', this.total, JSON.stringify(this.stats)); } } GeoJSONVT.prototype.options = { maxZoom: 14, indexMaxZoom: 5, indexMaxPoints: 100000, tolerance: 3, extent: 4096, buffer: 64, lineMetrics: false, promoteId: null, generateId: false, debug: 0 }; GeoJSONVT.prototype.splitTile = function (features, z, x, y, cz, cx, cy) { var stack = [ features, z, x, y ], options = this.options, debug = options.debug; while (stack.length) { y = stack.pop(); x = stack.pop(); z = stack.pop(); features = stack.pop(); var z2 = 1 << z, id = toID(z, x, y), tile = this.tiles[id]; if (!tile) { if (debug > 1) { console.time('creation'); } tile = this.tiles[id] = createTile(features, z, x, y, options); this.tileCoords.push({ z: z, x: x, y: y }); if (debug) { if (debug > 1) { console.log('tile z%d-%d-%d (features: %d, points: %d, simplified: %d)', z, x, y, tile.numFeatures, tile.numPoints, tile.numSimplified); console.timeEnd('creation'); } var key = 'z' + z; this.stats[key] = (this.stats[key] || 0) + 1; this.total++; } } tile.source = features; if (!cz) { if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints) { continue; } } else { if (z === options.maxZoom || z === cz) { continue; } var m = 1 << cz - z; if (x !== Math.floor(cx / m) || y !== Math.floor(cy / m)) { continue; } } tile.source = null; if (features.length === 0) { continue; } if (debug > 1) { console.time('clipping'); } var k1 = 0.5 * options.buffer / options.extent, k2 = 0.5 - k1, k3 = 0.5 + k1, k4 = 1 + k1, tl, bl, tr, br, left, right; tl = bl = tr = br = null; left = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX, options); right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX, options); features = null; if (left) { tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options); bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options); left = null; } if (right) { tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY, options); br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY, options); right = null; } if (debug > 1) { console.timeEnd('clipping'); } stack.push(tl || [], z + 1, x * 2, y * 2); stack.push(bl || [], z + 1, x * 2, y * 2 + 1); stack.push(tr || [], z + 1, x * 2 + 1, y * 2); stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1); } }; GeoJSONVT.prototype.getTile = function (z, x, y) { var options = this.options, extent = options.extent, debug = options.debug; if (z < 0 || z > 24) { return null; } var z2 = 1 << z; x = (x % z2 + z2) % z2; var id = toID(z, x, y); if (this.tiles[id]) { return transformTile(this.tiles[id], extent); } if (debug > 1) { console.log('drilling down to z%d-%d-%d', z, x, y); } var z0 = z, x0 = x, y0 = y, parent; while (!parent && z0 > 0) { z0--; x0 = Math.floor(x0 / 2); y0 = Math.floor(y0 / 2); parent = this.tiles[toID(z0, x0, y0)]; } if (!parent || !parent.source) { return null; } if (debug > 1) { console.log('found parent tile z%d-%d-%d', z0, x0, y0); } if (debug > 1) { console.time('drilling down'); } this.splitTile(parent.source, z0, x0, y0, z, x, y); if (debug > 1) { console.timeEnd('drilling down'); } return this.tiles[id] ? transformTile(this.tiles[id], extent) : null; }; function toID(z, x, y) { return ((1 << z) * y + x) * 32 + z; } function extend$1(dest, src) { for (var i in src) { dest[i] = src[i]; } return dest; } function loadGeoJSONTile(params, callback) { var canonical = params.tileID.canonical; if (!this._geoJSONIndex) { return callback(null, null); } var geoJSONTile = this._geoJSONIndex.getTile(canonical.z, canonical.x, canonical.y); if (!geoJSONTile) { return callback(null, null); } var geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features); var pbf = vtPbf(geojsonWrapper); if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) { pbf = new Uint8Array(pbf); } callback(null, { vectorTile: geojsonWrapper, rawData: pbf.buffer }); } var GeoJSONWorkerSource = function (VectorTileWorkerSource) { function GeoJSONWorkerSource(actor, layerIndex, availableImages, loadGeoJSON) { VectorTileWorkerSource.call(this, actor, layerIndex, availableImages, loadGeoJSONTile); if (loadGeoJSON) { this.loadGeoJSON = loadGeoJSON; } } if (VectorTileWorkerSource) GeoJSONWorkerSource.__proto__ = VectorTileWorkerSource; GeoJSONWorkerSource.prototype = Object.create(VectorTileWorkerSource && VectorTileWorkerSource.prototype); GeoJSONWorkerSource.prototype.constructor = GeoJSONWorkerSource; GeoJSONWorkerSource.prototype.loadData = function loadData(params, callback) { if (this._pendingCallback) { this._pendingCallback(null, { abandoned: true }); } this._pendingCallback = callback; this._pendingLoadDataParams = params; if (this._state && this._state !== 'Idle') { this._state = 'NeedsLoadData'; } else { this._state = 'Coalescing'; this._loadData(); } }; GeoJSONWorkerSource.prototype._loadData = function _loadData() { var this$1 = this; if (!this._pendingCallback || !this._pendingLoadDataParams) { return; } var callback = this._pendingCallback; var params = this._pendingLoadDataParams; delete this._pendingCallback; delete this._pendingLoadDataParams; var perf = params && params.request && params.request.collectResourceTiming ? new performance.RequestPerformance(params.request) : false; this.loadGeoJSON(params, function (err, data) { if (err || !data) { return callback(err); } else if (typeof data !== 'object') { return callback(new Error('Input data given to \'' + params.source + '\' is not a valid GeoJSON object.')); } else { geojsonRewind(data, true); try { if (params.filter) { var compiled = performance.createExpression(params.filter, { type: 'boolean', 'property-type': 'data-driven', overridable: false, transition: false }); if (compiled.result === 'error') { throw new Error(compiled.value.map(function (err) { return err.key + ': ' + err.message; }).join(', ')); } var features = data.features.filter(function (feature) { return compiled.value.evaluate({ zoom: 0 }, feature); }); data = { type: 'FeatureCollection', features: features }; } this$1._geoJSONIndex = params.cluster ? new Supercluster(getSuperclusterOptions(params)).load(data.features) : geojsonvt(data, params.geojsonVtOptions); } catch (err) { return callback(err); } this$1.loaded = {}; var result = {}; if (perf) { var resourceTimingData = perf.finish(); if (resourceTimingData) { result.resourceTiming = {}; result.resourceTiming[params.source] = JSON.parse(JSON.stringify(resourceTimingData)); } } callback(null, result); } }); }; GeoJSONWorkerSource.prototype.coalesce = function coalesce() { if (this._state === 'Coalescing') { this._state = 'Idle'; } else if (this._state === 'NeedsLoadData') { this._state = 'Coalescing'; this._loadData(); } }; GeoJSONWorkerSource.prototype.reloadTile = function reloadTile(params, callback) { var loaded = this.loaded, uid = params.uid; if (loaded && loaded[uid]) { return VectorTileWorkerSource.prototype.reloadTile.call(this, params, callback); } else { return this.loadTile(params, callback); } }; GeoJSONWorkerSource.prototype.loadGeoJSON = function loadGeoJSON(params, callback) { if (params.request) { performance.getJSON(params.request, callback); } else if (typeof params.data === 'string') { try { return callback(null, JSON.parse(params.data)); } catch (e) { return callback(new Error('Input data given to \'' + params.source + '\' is not a valid GeoJSON object.')); } } else { return callback(new Error('Input data given to \'' + params.source + '\' is not a valid GeoJSON object.')); } }; GeoJSONWorkerSource.prototype.removeSource = function removeSource(params, callback) { if (this._pendingCallback) { this._pendingCallback(null, { abandoned: true }); } callback(); }; GeoJSONWorkerSource.prototype.getClusterExpansionZoom = function getClusterExpansionZoom(params, callback) { try { callback(null, this._geoJSONIndex.getClusterExpansionZoom(params.clusterId)); } catch (e) { callback(e); } }; GeoJSONWorkerSource.prototype.getClusterChildren = function getClusterChildren(params, callback) { try { callback(null, this._geoJSONIndex.getChildren(params.clusterId)); } catch (e) { callback(e); } }; GeoJSONWorkerSource.prototype.getClusterLeaves = function getClusterLeaves(params, callback) { try { callback(null, this._geoJSONIndex.getLeaves(params.clusterId, params.limit, params.offset)); } catch (e) { callback(e); } }; return GeoJSONWorkerSource; }(VectorTileWorkerSource); function getSuperclusterOptions(ref) { var superclusterOptions = ref.superclusterOptions; var clusterProperties = ref.clusterProperties; if (!clusterProperties || !superclusterOptions) { return superclusterOptions; } var mapExpressions = {}; var reduceExpressions = {}; var globals = { accumulated: null, zoom: 0 }; var feature = { properties: null }; var propertyNames = Object.keys(clusterProperties); for (var i = 0, list = propertyNames; i < list.length; i += 1) { var key = list[i]; var ref$1 = clusterProperties[key]; var operator = ref$1[0]; var mapExpression = ref$1[1]; var mapExpressionParsed = performance.createExpression(mapExpression); var reduceExpressionParsed = performance.createExpression(typeof operator === 'string' ? [ operator, ['accumulated'], [ 'get', key ] ] : operator); mapExpressions[key] = mapExpressionParsed.value; reduceExpressions[key] = reduceExpressionParsed.value; } superclusterOptions.map = function (pointProperties) { feature.properties = pointProperties; var properties = {}; for (var i = 0, list = propertyNames; i < list.length; i += 1) { var key = list[i]; properties[key] = mapExpressions[key].evaluate(globals, feature); } return properties; }; superclusterOptions.reduce = function (accumulated, clusterProperties) { feature.properties = clusterProperties; for (var i = 0, list = propertyNames; i < list.length; i += 1) { var key = list[i]; globals.accumulated = accumulated[key]; accumulated[key] = reduceExpressions[key].evaluate(globals, feature); } }; return superclusterOptions; } var Worker = function Worker(self) { var this$1 = this; this.self = self; this.actor = new performance.Actor(self, this); this.layerIndexes = {}; this.availableImages = {}; this.workerSourceTypes = { vector: VectorTileWorkerSource, geojson: GeoJSONWorkerSource }; this.workerSources = {}; this.demWorkerSources = {}; this.self.registerWorkerSource = function (name, WorkerSource) { if (this$1.workerSourceTypes[name]) { throw new Error('Worker source with name "' + name + '" already registered.'); } this$1.workerSourceTypes[name] = WorkerSource; }; this.self.registerRTLTextPlugin = function (rtlTextPlugin) { if (performance.plugin.isParsed()) { throw new Error('RTL text plugin already registered.'); } performance.plugin['applyArabicShaping'] = rtlTextPlugin.applyArabicShaping; performance.plugin['processBidirectionalText'] = rtlTextPlugin.processBidirectionalText; performance.plugin['processStyledBidirectionalText'] = rtlTextPlugin.processStyledBidirectionalText; }; }; Worker.prototype.setReferrer = function setReferrer(mapID, referrer) { this.referrer = referrer; }; Worker.prototype.setImages = function setImages(mapId, images, callback) { this.availableImages[mapId] = images; for (var workerSource in this.workerSources[mapId]) { var ws = this.workerSources[mapId][workerSource]; for (var source in ws) { ws[source].availableImages = images; } } callback(); }; Worker.prototype.setLayers = function setLayers(mapId, layers, callback) { this.getLayerIndex(mapId).replace(layers); callback(); }; Worker.prototype.updateLayers = function updateLayers(mapId, params, callback) { this.getLayerIndex(mapId).update(params.layers, params.removedIds); callback(); }; Worker.prototype.loadTile = function loadTile(mapId, params, callback) { this.getWorkerSource(mapId, params.type, params.source).loadTile(params, callback); }; Worker.prototype.loadDEMTile = function loadDEMTile(mapId, params, callback) { this.getDEMWorkerSource(mapId, params.source).loadTile(params, callback); }; Worker.prototype.reloadTile = function reloadTile(mapId, params, callback) { this.getWorkerSource(mapId, params.type, params.source).reloadTile(params, callback); }; Worker.prototype.abortTile = function abortTile(mapId, params, callback) { this.getWorkerSource(mapId, params.type, params.source).abortTile(params, callback); }; Worker.prototype.removeTile = function removeTile(mapId, params, callback) { this.getWorkerSource(mapId, params.type, params.source).removeTile(params, callback); }; Worker.prototype.removeDEMTile = function removeDEMTile(mapId, params) { this.getDEMWorkerSource(mapId, params.source).removeTile(params); }; Worker.prototype.removeSource = function removeSource(mapId, params, callback) { if (!this.workerSources[mapId] || !this.workerSources[mapId][params.type] || !this.workerSources[mapId][params.type][params.source]) { return; } var worker = this.workerSources[mapId][params.type][params.source]; delete this.workerSources[mapId][params.type][params.source]; if (worker.removeSource !== undefined) { worker.removeSource(params, callback); } else { callback(); } }; Worker.prototype.loadWorkerSource = function loadWorkerSource(map, params, callback) { try { this.self.importScripts(params.url); callback(); } catch (e) { callback(e.toString()); } }; Worker.prototype.syncRTLPluginState = function syncRTLPluginState(map, state, callback) { try { performance.plugin.setState(state); var pluginURL = performance.plugin.getPluginURL(); if (performance.plugin.isLoaded() && !performance.plugin.isParsed() && pluginURL != null) { this.self.importScripts(pluginURL); var complete = performance.plugin.isParsed(); var error = complete ? undefined : new Error('RTL Text Plugin failed to import scripts from ' + pluginURL); callback(error, complete); } } catch (e) { callback(e.toString()); } }; Worker.prototype.getAvailableImages = function getAvailableImages(mapId) { var availableImages = this.availableImages[mapId]; if (!availableImages) { availableImages = []; } return availableImages; }; Worker.prototype.getLayerIndex = function getLayerIndex(mapId) { var layerIndexes = this.layerIndexes[mapId]; if (!layerIndexes) { layerIndexes = this.layerIndexes[mapId] = new StyleLayerIndex(); } return layerIndexes; }; Worker.prototype.getWorkerSource = function getWorkerSource(mapId, type, source) { var this$1 = this; if (!this.workerSources[mapId]) { this.workerSources[mapId] = {}; } if (!this.workerSources[mapId][type]) { this.workerSources[mapId][type] = {}; } if (!this.workerSources[mapId][type][source]) { var actor = { send: function (type, data, callback) { this$1.actor.send(type, data, callback, mapId); } }; this.workerSources[mapId][type][source] = new this.workerSourceTypes[type](actor, this.getLayerIndex(mapId), this.getAvailableImages(mapId)); } return this.workerSources[mapId][type][source]; }; Worker.prototype.getDEMWorkerSource = function getDEMWorkerSource(mapId, source) { if (!this.demWorkerSources[mapId]) { this.demWorkerSources[mapId] = {}; } if (!this.demWorkerSources[mapId][source]) { this.demWorkerSources[mapId][source] = new RasterDEMTileWorkerSource(); } return this.demWorkerSources[mapId][source]; }; Worker.prototype.enforceCacheSizeLimit = function enforceCacheSizeLimit$1(mapId, limit) { performance.enforceCacheSizeLimit(limit); }; if (typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope) { self.worker = new Worker(self); } return Worker; }); define(['./shared'], function (performance) { 'use strict'; var mapboxGlSupported = performance.createCommonjsModule(function (module) { if ( module.exports) { module.exports = isSupported; } else if (window) { window.mapboxgl = window.mapboxgl || {}; window.mapboxgl.supported = isSupported; window.mapboxgl.notSupportedReason = notSupportedReason; } function isSupported(options) { return !notSupportedReason(options); } function notSupportedReason(options) { if (!isBrowser()) { return 'not a browser'; } if (!isArraySupported()) { return 'insufficent Array support'; } if (!isFunctionSupported()) { return 'insufficient Function support'; } if (!isObjectSupported()) { return 'insufficient Object support'; } if (!isJSONSupported()) { return 'insufficient JSON support'; } if (!isWorkerSupported()) { return 'insufficient worker support'; } if (!isUint8ClampedArraySupported()) { return 'insufficient Uint8ClampedArray support'; } if (!isArrayBufferSupported()) { return 'insufficient ArrayBuffer support'; } if (!isCanvasGetImageDataSupported()) { return 'insufficient Canvas/getImageData support'; } if (!isWebGLSupportedCached(options && options.failIfMajorPerformanceCaveat)) { return 'insufficient WebGL support'; } } function isBrowser() { return typeof window !== 'undefined' && typeof document !== 'undefined'; } function isArraySupported() { return Array.prototype && Array.prototype.every && Array.prototype.filter && Array.prototype.forEach && Array.prototype.indexOf && Array.prototype.lastIndexOf && Array.prototype.map && Array.prototype.some && Array.prototype.reduce && Array.prototype.reduceRight && Array.isArray; } function isFunctionSupported() { return Function.prototype && Function.prototype.bind; } function isObjectSupported() { return Object.keys && Object.create && Object.getPrototypeOf && Object.getOwnPropertyNames && Object.isSealed && Object.isFrozen && Object.isExtensible && Object.getOwnPropertyDescriptor && Object.defineProperty && Object.defineProperties && Object.seal && Object.freeze && Object.preventExtensions; } function isJSONSupported() { return 'JSON' in window && 'parse' in JSON && 'stringify' in JSON; } function isWorkerSupported() { if (!('Worker' in window && 'Blob' in window && 'URL' in window)) { return false; } var blob = new Blob([''], { type: 'text/javascript' }); var workerURL = URL.createObjectURL(blob); var supported; var worker; try { worker = new Worker(workerURL); supported = true; } catch (e) { supported = false; } if (worker) { worker.terminate(); } URL.revokeObjectURL(workerURL); return supported; } function isUint8ClampedArraySupported() { return 'Uint8ClampedArray' in window; } function isArrayBufferSupported() { return ArrayBuffer.isView; } function isCanvasGetImageDataSupported() { var canvas = document.createElement('canvas'); canvas.width = canvas.height = 1; var context = canvas.getContext('2d'); if (!context) { return false; } var imageData = context.getImageData(0, 0, 1, 1); return imageData && imageData.width === canvas.width; } var isWebGLSupportedCache = {}; function isWebGLSupportedCached(failIfMajorPerformanceCaveat) { if (isWebGLSupportedCache[failIfMajorPerformanceCaveat] === undefined) { isWebGLSupportedCache[failIfMajorPerformanceCaveat] = isWebGLSupported(failIfMajorPerformanceCaveat); } return isWebGLSupportedCache[failIfMajorPerformanceCaveat]; } isSupported.webGLContextAttributes = { antialias: false, alpha: true, stencil: true, depth: true }; function getWebGLContext(failIfMajorPerformanceCaveat) { var canvas = document.createElement('canvas'); var attributes = Object.create(isSupported.webGLContextAttributes); attributes.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat; if (canvas.probablySupportsContext) { return canvas.probablySupportsContext('webgl', attributes) || canvas.probablySupportsContext('experimental-webgl', attributes); } else if (canvas.supportsContext) { return canvas.supportsContext('webgl', attributes) || canvas.supportsContext('experimental-webgl', attributes); } else { return canvas.getContext('webgl', attributes) || canvas.getContext('experimental-webgl', attributes); } } function isWebGLSupported(failIfMajorPerformanceCaveat) { var gl = getWebGLContext(failIfMajorPerformanceCaveat); if (!gl) { return false; } var shader = gl.createShader(gl.VERTEX_SHADER); if (!shader || gl.isContextLost()) { return false; } gl.shaderSource(shader, 'void main() {}'); gl.compileShader(shader); return gl.getShaderParameter(shader, gl.COMPILE_STATUS) === true; } }); var DOM = {}; DOM.create = function (tagName, className, container) { var el = performance.window.document.createElement(tagName); if (className !== undefined) { el.className = className; } if (container) { container.appendChild(el); } return el; }; DOM.createNS = function (namespaceURI, tagName) { var el = performance.window.document.createElementNS(namespaceURI, tagName); return el; }; var docStyle = performance.window.document && performance.window.document.documentElement.style; function testProp(props) { if (!docStyle) { return props[0]; } for (var i = 0; i < props.length; i++) { if (props[i] in docStyle) { return props[i]; } } return props[0]; } var selectProp = testProp([ 'userSelect', 'MozUserSelect', 'WebkitUserSelect', 'msUserSelect' ]); var userSelect; DOM.disableDrag = function () { if (docStyle && selectProp) { userSelect = docStyle[selectProp]; docStyle[selectProp] = 'none'; } }; DOM.enableDrag = function () { if (docStyle && selectProp) { docStyle[selectProp] = userSelect; } }; var transformProp = testProp([ 'transform', 'WebkitTransform' ]); DOM.setTransform = function (el, value) { el.style[transformProp] = value; }; var passiveSupported = false; try { var options$1 = Object.defineProperty({}, 'passive', { get: function get() { passiveSupported = true; } }); performance.window.addEventListener('test', options$1, options$1); performance.window.removeEventListener('test', options$1, options$1); } catch (err) { passiveSupported = false; } DOM.addEventListener = function (target, type, callback, options) { if (options === void 0) options = {}; if ('passive' in options && passiveSupported) { target.addEventListener(type, callback, options); } else { target.addEventListener(type, callback, options.capture); } }; DOM.removeEventListener = function (target, type, callback, options) { if (options === void 0) options = {}; if ('passive' in options && passiveSupported) { target.removeEventListener(type, callback, options); } else { target.removeEventListener(type, callback, options.capture); } }; var suppressClick = function (e) { e.preventDefault(); e.stopPropagation(); performance.window.removeEventListener('click', suppressClick, true); }; DOM.suppressClick = function () { performance.window.addEventListener('click', suppressClick, true); performance.window.setTimeout(function () { performance.window.removeEventListener('click', suppressClick, true); }, 0); }; DOM.mousePos = function (el, e) { var rect = el.getBoundingClientRect(); return new performance.Point(e.clientX - rect.left - el.clientLeft, e.clientY - rect.top - el.clientTop); }; DOM.touchPos = function (el, touches) { var rect = el.getBoundingClientRect(), points = []; for (var i = 0; i < touches.length; i++) { points.push(new performance.Point(touches[i].clientX - rect.left - el.clientLeft, touches[i].clientY - rect.top - el.clientTop)); } return points; }; DOM.mouseButton = function (e) { if (typeof performance.window.InstallTrigger !== 'undefined' && e.button === 2 && e.ctrlKey && performance.window.navigator.platform.toUpperCase().indexOf('MAC') >= 0) { return 0; } return e.button; }; DOM.remove = function (node) { if (node.parentNode) { node.parentNode.removeChild(node); } }; function loadSprite (baseURL, requestManager, callback) { var json, image, error; var format = performance.browser.devicePixelRatio > 1 ? '@2x' : ''; var jsonRequest = performance.getJSON(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.json'), performance.ResourceType.SpriteJSON), function (err, data) { jsonRequest = null; if (!error) { error = err; json = data; maybeComplete(); } }); var imageRequest = performance.getImage(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.png'), performance.ResourceType.SpriteImage), function (err, img) { imageRequest = null; if (!error) { error = err; image = img; maybeComplete(); } }); function maybeComplete() { if (error) { callback(error); } else if (json && image) { var imageData = performance.browser.getImageData(image); var result = {}; for (var id in json) { var ref = json[id]; var width = ref.width; var height = ref.height; var x = ref.x; var y = ref.y; var sdf = ref.sdf; var pixelRatio = ref.pixelRatio; var stretchX = ref.stretchX; var stretchY = ref.stretchY; var content = ref.content; var data = new performance.RGBAImage({ width: width, height: height }); performance.RGBAImage.copy(imageData, data, { x: x, y: y }, { x: 0, y: 0 }, { width: width, height: height }); result[id] = { data: data, pixelRatio: pixelRatio, sdf: sdf, stretchX: stretchX, stretchY: stretchY, content: content }; } callback(null, result); } } return { cancel: function cancel() { if (jsonRequest) { jsonRequest.cancel(); jsonRequest = null; } if (imageRequest) { imageRequest.cancel(); imageRequest = null; } } }; } function renderStyleImage(image) { var userImage = image.userImage; if (userImage && userImage.render) { var updated = userImage.render(); if (updated) { image.data.replace(new Uint8Array(userImage.data.buffer)); return true; } } return false; } var padding = 1; var ImageManager = function (Evented) { function ImageManager() { Evented.call(this); this.images = {}; this.updatedImages = {}; this.callbackDispatchedThisFrame = {}; this.loaded = false; this.requestors = []; this.patterns = {}; this.atlasImage = new performance.RGBAImage({ width: 1, height: 1 }); this.dirty = true; } if (Evented) ImageManager.__proto__ = Evented; ImageManager.prototype = Object.create(Evented && Evented.prototype); ImageManager.prototype.constructor = ImageManager; ImageManager.prototype.isLoaded = function isLoaded() { return this.loaded; }; ImageManager.prototype.setLoaded = function setLoaded(loaded) { if (this.loaded === loaded) { return; } this.loaded = loaded; if (loaded) { for (var i = 0, list = this.requestors; i < list.length; i += 1) { var ref = list[i]; var ids = ref.ids; var callback = ref.callback; this._notify(ids, callback); } this.requestors = []; } }; ImageManager.prototype.getImage = function getImage(id) { return this.images[id]; }; ImageManager.prototype.addImage = function addImage(id, image) { if (this._validate(id, image)) { this.images[id] = image; } }; ImageManager.prototype._validate = function _validate(id, image) { var valid = true; if (!this._validateStretch(image.stretchX, image.data && image.data.width)) { this.fire(new performance.ErrorEvent(new Error('Image "' + id + '" has invalid "stretchX" value'))); valid = false; } if (!this._validateStretch(image.stretchY, image.data && image.data.height)) { this.fire(new performance.ErrorEvent(new Error('Image "' + id + '" has invalid "stretchY" value'))); valid = false; } if (!this._validateContent(image.content, image)) { this.fire(new performance.ErrorEvent(new Error('Image "' + id + '" has invalid "content" value'))); valid = false; } return valid; }; ImageManager.prototype._validateStretch = function _validateStretch(stretch, size) { if (!stretch) { return true; } var last = 0; for (var i = 0, list = stretch; i < list.length; i += 1) { var part = list[i]; if (part[0] < last || part[1] < part[0] || size < part[1]) { return false; } last = part[1]; } return true; }; ImageManager.prototype._validateContent = function _validateContent(content, image) { if (!content) { return true; } if (content.length !== 4) { return false; } if (content[0] < 0 || image.data.width < content[0]) { return false; } if (content[1] < 0 || image.data.height < content[1]) { return false; } if (content[2] < 0 || image.data.width < content[2]) { return false; } if (content[3] < 0 || image.data.height < content[3]) { return false; } if (content[2] < content[0]) { return false; } if (content[3] < content[1]) { return false; } return true; }; ImageManager.prototype.updateImage = function updateImage(id, image) { var oldImage = this.images[id]; image.version = oldImage.version + 1; this.images[id] = image; this.updatedImages[id] = true; }; ImageManager.prototype.removeImage = function removeImage(id) { var image = this.images[id]; delete this.images[id]; delete this.patterns[id]; if (image.userImage && image.userImage.onRemove) { image.userImage.onRemove(); } }; ImageManager.prototype.listImages = function listImages() { return Object.keys(this.images); }; ImageManager.prototype.getImages = function getImages(ids, callback) { var hasAllDependencies = true; if (!this.isLoaded()) { for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; if (!this.images[id]) { hasAllDependencies = false; } } } if (this.isLoaded() || hasAllDependencies) { this._notify(ids, callback); } else { this.requestors.push({ ids: ids, callback: callback }); } }; ImageManager.prototype._notify = function _notify(ids, callback) { var response = {}; for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; if (!this.images[id]) { this.fire(new performance.Event('styleimagemissing', { id: id })); } var image = this.images[id]; if (image) { response[id] = { data: image.data.clone(), pixelRatio: image.pixelRatio, sdf: image.sdf, version: image.version, stretchX: image.stretchX, stretchY: image.stretchY, content: image.content, hasRenderCallback: Boolean(image.userImage && image.userImage.render) }; } else { performance.warnOnce('Image "' + id + '" could not be loaded. Please make sure you have added the image with map.addImage() or a "sprite" property in your style. You can provide missing images by listening for the "styleimagemissing" map event.'); } } callback(null, response); }; ImageManager.prototype.getPixelSize = function getPixelSize() { var ref = this.atlasImage; var width = ref.width; var height = ref.height; return { width: width, height: height }; }; ImageManager.prototype.getPattern = function getPattern(id) { var pattern = this.patterns[id]; var image = this.getImage(id); if (!image) { return null; } if (pattern && pattern.position.version === image.version) { return pattern.position; } if (!pattern) { var w = image.data.width + padding * 2; var h = image.data.height + padding * 2; var bin = { w: w, h: h, x: 0, y: 0 }; var position = new performance.ImagePosition(bin, image); this.patterns[id] = { bin: bin, position: position }; } else { pattern.position.version = image.version; } this._updatePatternAtlas(); return this.patterns[id].position; }; ImageManager.prototype.bind = function bind(context) { var gl = context.gl; if (!this.atlasTexture) { this.atlasTexture = new performance.Texture(context, this.atlasImage, gl.RGBA); } else if (this.dirty) { this.atlasTexture.update(this.atlasImage); this.dirty = false; } this.atlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); }; ImageManager.prototype._updatePatternAtlas = function _updatePatternAtlas() { var bins = []; for (var id in this.patterns) { bins.push(this.patterns[id].bin); } var ref = performance.potpack(bins); var w = ref.w; var h = ref.h; var dst = this.atlasImage; dst.resize({ width: w || 1, height: h || 1 }); for (var id$1 in this.patterns) { var ref$1 = this.patterns[id$1]; var bin = ref$1.bin; var x = bin.x + padding; var y = bin.y + padding; var src = this.images[id$1].data; var w$1 = src.width; var h$1 = src.height; performance.RGBAImage.copy(src, dst, { x: 0, y: 0 }, { x: x, y: y }, { width: w$1, height: h$1 }); performance.RGBAImage.copy(src, dst, { x: 0, y: h$1 - 1 }, { x: x, y: y - 1 }, { width: w$1, height: 1 }); performance.RGBAImage.copy(src, dst, { x: 0, y: 0 }, { x: x, y: y + h$1 }, { width: w$1, height: 1 }); performance.RGBAImage.copy(src, dst, { x: w$1 - 1, y: 0 }, { x: x - 1, y: y }, { width: 1, height: h$1 }); performance.RGBAImage.copy(src, dst, { x: 0, y: 0 }, { x: x + w$1, y: y }, { width: 1, height: h$1 }); } this.dirty = true; }; ImageManager.prototype.beginFrame = function beginFrame() { this.callbackDispatchedThisFrame = {}; }; ImageManager.prototype.dispatchRenderCallbacks = function dispatchRenderCallbacks(ids) { for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; if (this.callbackDispatchedThisFrame[id]) { continue; } this.callbackDispatchedThisFrame[id] = true; var image = this.images[id]; var updated = renderStyleImage(image); if (updated) { this.updateImage(id, image); } } }; return ImageManager; }(performance.Evented); function loadGlyphRange (fontstack, range, urlTemplate, requestManager, callback) { var begin = range * 256; var end = begin + 255; var request = requestManager.transformRequest(requestManager.normalizeGlyphsURL(urlTemplate).replace('{fontstack}', fontstack).replace('{range}', begin + '-' + end), performance.ResourceType.Glyphs); performance.getArrayBuffer(request, function (err, data) { if (err) { callback(err); } else if (data) { var glyphs = {}; for (var i = 0, list = performance.parseGlyphPBF(data); i < list.length; i += 1) { var glyph = list[i]; glyphs[glyph.id] = glyph; } callback(null, glyphs); } }); } var tinySdf = TinySDF; var default_1 = TinySDF; var INF = 100000000000000000000; function TinySDF(fontSize, buffer, radius, cutoff, fontFamily, fontWeight) { this.fontSize = fontSize || 24; this.buffer = buffer === undefined ? 3 : buffer; this.cutoff = cutoff || 0.25; this.fontFamily = fontFamily || 'sans-serif'; this.fontWeight = fontWeight || 'normal'; this.radius = radius || 8; var size = this.size = this.fontSize + this.buffer * 2; this.canvas = document.createElement('canvas'); this.canvas.width = this.canvas.height = size; this.ctx = this.canvas.getContext('2d'); this.ctx.font = this.fontWeight + ' ' + this.fontSize + 'px ' + this.fontFamily; this.ctx.textBaseline = 'middle'; this.ctx.fillStyle = 'black'; this.gridOuter = new Float64Array(size * size); this.gridInner = new Float64Array(size * size); this.f = new Float64Array(size); this.d = new Float64Array(size); this.z = new Float64Array(size + 1); this.v = new Int16Array(size); this.middle = Math.round(size / 2 * (navigator.userAgent.indexOf('Gecko/') >= 0 ? 1.2 : 1)); } TinySDF.prototype.draw = function (char) { this.ctx.clearRect(0, 0, this.size, this.size); this.ctx.fillText(char, this.buffer, this.middle); var imgData = this.ctx.getImageData(0, 0, this.size, this.size); var alphaChannel = new Uint8ClampedArray(this.size * this.size); for (var i = 0; i < this.size * this.size; i++) { var a = imgData.data[i * 4 + 3] / 255; this.gridOuter[i] = a === 1 ? 0 : a === 0 ? INF : Math.pow(Math.max(0, 0.5 - a), 2); this.gridInner[i] = a === 1 ? INF : a === 0 ? 0 : Math.pow(Math.max(0, a - 0.5), 2); } edt(this.gridOuter, this.size, this.size, this.f, this.d, this.v, this.z); edt(this.gridInner, this.size, this.size, this.f, this.d, this.v, this.z); for (i = 0; i < this.size * this.size; i++) { var d = this.gridOuter[i] - this.gridInner[i]; alphaChannel[i] = Math.max(0, Math.min(255, Math.round(255 - 255 * (d / this.radius + this.cutoff)))); } return alphaChannel; }; function edt(data, width, height, f, d, v, z) { for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { f[y] = data[y * width + x]; } edt1d(f, d, v, z, height); for (y = 0; y < height; y++) { data[y * width + x] = d[y]; } } for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { f[x] = data[y * width + x]; } edt1d(f, d, v, z, width); for (x = 0; x < width; x++) { data[y * width + x] = Math.sqrt(d[x]); } } } function edt1d(f, d, v, z, n) { v[0] = 0; z[0] = -INF; z[1] = +INF; for (var q = 1, k = 0; q < n; q++) { var s = (f[q] + q * q - (f[v[k]] + v[k] * v[k])) / (2 * q - 2 * v[k]); while (s <= z[k]) { k--; s = (f[q] + q * q - (f[v[k]] + v[k] * v[k])) / (2 * q - 2 * v[k]); } k++; v[k] = q; z[k] = s; z[k + 1] = +INF; } for (q = 0, k = 0; q < n; q++) { while (z[k + 1] < q) { k++; } d[q] = (q - v[k]) * (q - v[k]) + f[v[k]]; } } tinySdf.default = default_1; var GlyphManager = function GlyphManager(requestManager, localIdeographFontFamily) { this.requestManager = requestManager; this.localIdeographFontFamily = localIdeographFontFamily; this.entries = {}; }; GlyphManager.prototype.setURL = function setURL(url) { this.url = url; }; GlyphManager.prototype.getGlyphs = function getGlyphs(glyphs, callback) { var this$1 = this; var all = []; for (var stack in glyphs) { for (var i = 0, list = glyphs[stack]; i < list.length; i += 1) { var id = list[i]; all.push({ stack: stack, id: id }); } } performance.asyncAll(all, function (ref, callback) { var stack = ref.stack; var id = ref.id; var entry = this$1.entries[stack]; if (!entry) { entry = this$1.entries[stack] = { glyphs: {}, requests: {}, ranges: {} }; } var glyph = entry.glyphs[id]; if (glyph !== undefined) { callback(null, { stack: stack, id: id, glyph: glyph }); return; } glyph = this$1._tinySDF(entry, stack, id); if (glyph) { entry.glyphs[id] = glyph; callback(null, { stack: stack, id: id, glyph: glyph }); return; } var range = Math.floor(id / 256); if (range * 256 > 65535) { callback(new Error('glyphs > 65535 not supported')); return; } if (entry.ranges[range]) { callback(null, { stack: stack, id: id, glyph: glyph }); return; } var requests = entry.requests[range]; if (!requests) { requests = entry.requests[range] = []; GlyphManager.loadGlyphRange(stack, range, this$1.url, this$1.requestManager, function (err, response) { if (response) { for (var id in response) { if (!this$1._doesCharSupportLocalGlyph(+id)) { entry.glyphs[+id] = response[+id]; } } entry.ranges[range] = true; } for (var i = 0, list = requests; i < list.length; i += 1) { var cb = list[i]; cb(err, response); } delete entry.requests[range]; }); } requests.push(function (err, result) { if (err) { callback(err); } else if (result) { callback(null, { stack: stack, id: id, glyph: result[id] || null }); } }); }, function (err, glyphs) { if (err) { callback(err); } else if (glyphs) { var result = {}; for (var i = 0, list = glyphs; i < list.length; i += 1) { var ref = list[i]; var stack = ref.stack; var id = ref.id; var glyph = ref.glyph; (result[stack] || (result[stack] = {}))[id] = glyph && { id: glyph.id, bitmap: glyph.bitmap.clone(), metrics: glyph.metrics }; } callback(null, result); } }); }; GlyphManager.prototype._doesCharSupportLocalGlyph = function _doesCharSupportLocalGlyph(id) { return !!this.localIdeographFontFamily && (performance.isChar['CJK Unified Ideographs'](id) || performance.isChar['Hangul Syllables'](id) || performance.isChar['Hiragana'](id) || performance.isChar['Katakana'](id)); }; GlyphManager.prototype._tinySDF = function _tinySDF(entry, stack, id) { var family = this.localIdeographFontFamily; if (!family) { return; } if (!this._doesCharSupportLocalGlyph(id)) { return; } var tinySDF = entry.tinySDF; if (!tinySDF) { var fontWeight = '400'; if (/bold/i.test(stack)) { fontWeight = '900'; } else if (/medium/i.test(stack)) { fontWeight = '500'; } else if (/light/i.test(stack)) { fontWeight = '200'; } tinySDF = entry.tinySDF = new GlyphManager.TinySDF(24, 3, 8, 0.25, family, fontWeight); } return { id: id, bitmap: new performance.AlphaImage({ width: 30, height: 30 }, tinySDF.draw(String.fromCharCode(id))), metrics: { width: 24, height: 24, left: 0, top: -8, advance: 24 } }; }; GlyphManager.loadGlyphRange = loadGlyphRange; GlyphManager.TinySDF = tinySdf; var LightPositionProperty = function LightPositionProperty() { this.specification = performance.styleSpec.light.position; }; LightPositionProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters) { return performance.sphericalToCartesian(value.expression.evaluate(parameters)); }; LightPositionProperty.prototype.interpolate = function interpolate$1(a, b, t) { return { x: performance.number(a.x, b.x, t), y: performance.number(a.y, b.y, t), z: performance.number(a.z, b.z, t) }; }; var properties = new performance.Properties({ 'anchor': new performance.DataConstantProperty(performance.styleSpec.light.anchor), 'position': new LightPositionProperty(), 'color': new performance.DataConstantProperty(performance.styleSpec.light.color), 'intensity': new performance.DataConstantProperty(performance.styleSpec.light.intensity) }); var TRANSITION_SUFFIX = '-transition'; var Light = function (Evented) { function Light(lightOptions) { Evented.call(this); this._transitionable = new performance.Transitionable(properties); this.setLight(lightOptions); this._transitioning = this._transitionable.untransitioned(); } if (Evented) Light.__proto__ = Evented; Light.prototype = Object.create(Evented && Evented.prototype); Light.prototype.constructor = Light; Light.prototype.getLight = function getLight() { return this._transitionable.serialize(); }; Light.prototype.setLight = function setLight(light, options) { if (options === void 0) options = {}; if (this._validate(performance.validateLight, light, options)) { return; } for (var name in light) { var value = light[name]; if (performance.endsWith(name, TRANSITION_SUFFIX)) { this._transitionable.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), value); } else { this._transitionable.setValue(name, value); } } }; Light.prototype.updateTransitions = function updateTransitions(parameters) { this._transitioning = this._transitionable.transitioned(parameters, this._transitioning); }; Light.prototype.hasTransition = function hasTransition() { return this._transitioning.hasTransition(); }; Light.prototype.recalculate = function recalculate(parameters) { this.properties = this._transitioning.possiblyEvaluate(parameters); }; Light.prototype._validate = function _validate(validate, value, options) { if (options && options.validate === false) { return false; } return performance.emitValidationErrors(this, validate.call(performance.validateStyle, performance.extend({ value: value, style: { glyphs: true, sprite: true }, styleSpec: performance.styleSpec }))); }; return Light; }(performance.Evented); var LineAtlas = function LineAtlas(width, height) { this.width = width; this.height = height; this.nextRow = 0; this.data = new Uint8Array(this.width * this.height); this.dashEntry = {}; }; LineAtlas.prototype.getDash = function getDash(dasharray, round) { var key = dasharray.join(',') + String(round); if (!this.dashEntry[key]) { this.dashEntry[key] = this.addDash(dasharray, round); } return this.dashEntry[key]; }; LineAtlas.prototype.getDashRanges = function getDashRanges(dasharray, lineAtlasWidth, stretch) { var oddDashArray = dasharray.length % 2 === 1; var ranges = []; var left = oddDashArray ? -dasharray[dasharray.length - 1] * stretch : 0; var right = dasharray[0] * stretch; var isDash = true; ranges.push({ left: left, right: right, isDash: isDash, zeroLength: dasharray[0] === 0 }); var currentDashLength = dasharray[0]; for (var i = 1; i < dasharray.length; i++) { isDash = !isDash; var dashLength = dasharray[i]; left = currentDashLength * stretch; currentDashLength += dashLength; right = currentDashLength * stretch; ranges.push({ left: left, right: right, isDash: isDash, zeroLength: dashLength === 0 }); } return ranges; }; LineAtlas.prototype.addRoundDash = function addRoundDash(ranges, stretch, n) { var halfStretch = stretch / 2; for (var y = -n; y <= n; y++) { var row = this.nextRow + n + y; var index = this.width * row; var currIndex = 0; var range = ranges[currIndex]; for (var x = 0; x < this.width; x++) { if (x / range.right > 1) { range = ranges[++currIndex]; } var distLeft = Math.abs(x - range.left); var distRight = Math.abs(x - range.right); var minDist = Math.min(distLeft, distRight); var signedDistance = void 0; var distMiddle = y / n * (halfStretch + 1); if (range.isDash) { var distEdge = halfStretch - Math.abs(distMiddle); signedDistance = Math.sqrt(minDist * minDist + distEdge * distEdge); } else { signedDistance = halfStretch - Math.sqrt(minDist * minDist + distMiddle * distMiddle); } this.data[index + x] = Math.max(0, Math.min(255, signedDistance + 128)); } } }; LineAtlas.prototype.addRegularDash = function addRegularDash(ranges) { for (var i = ranges.length - 1; i >= 0; --i) { var part = ranges[i]; var next = ranges[i + 1]; if (part.zeroLength) { ranges.splice(i, 1); } else if (next && next.isDash === part.isDash) { next.left = part.left; ranges.splice(i, 1); } } var first = ranges[0]; var last = ranges[ranges.length - 1]; if (first.isDash === last.isDash) { first.left = last.left - this.width; last.right = first.right + this.width; } var index = this.width * this.nextRow; var currIndex = 0; var range = ranges[currIndex]; for (var x = 0; x < this.width; x++) { if (x / range.right > 1) { range = ranges[++currIndex]; } var distLeft = Math.abs(x - range.left); var distRight = Math.abs(x - range.right); var minDist = Math.min(distLeft, distRight); var signedDistance = range.isDash ? minDist : -minDist; this.data[index + x] = Math.max(0, Math.min(255, signedDistance + 128)); } }; LineAtlas.prototype.addDash = function addDash(dasharray, round) { var n = round ? 7 : 0; var height = 2 * n + 1; if (this.nextRow + height > this.height) { performance.warnOnce('LineAtlas out of space'); return null; } var length = 0; for (var i = 0; i < dasharray.length; i++) { length += dasharray[i]; } if (length !== 0) { var stretch = this.width / length; var ranges = this.getDashRanges(dasharray, this.width, stretch); if (round) { this.addRoundDash(ranges, stretch, n); } else { this.addRegularDash(ranges); } } var dashEntry = { y: (this.nextRow + n + 0.5) / this.height, height: 2 * n / this.height, width: length }; this.nextRow += height; this.dirty = true; return dashEntry; }; LineAtlas.prototype.bind = function bind(context) { var gl = context.gl; if (!this.texture) { this.texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, this.width, this.height, 0, gl.ALPHA, gl.UNSIGNED_BYTE, this.data); } else { gl.bindTexture(gl.TEXTURE_2D, this.texture); if (this.dirty) { this.dirty = false; gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.width, this.height, gl.ALPHA, gl.UNSIGNED_BYTE, this.data); } } }; var Dispatcher = function Dispatcher(workerPool, parent) { this.workerPool = workerPool; this.actors = []; this.currentActor = 0; this.id = performance.uniqueId(); var workers = this.workerPool.acquire(this.id); for (var i = 0; i < workers.length; i++) { var worker = workers[i]; var actor = new Dispatcher.Actor(worker, parent, this.id); actor.name = 'Worker ' + i; this.actors.push(actor); } }; Dispatcher.prototype.broadcast = function broadcast(type, data, cb) { cb = cb || function () { }; performance.asyncAll(this.actors, function (actor, done) { actor.send(type, data, done); }, cb); }; Dispatcher.prototype.getActor = function getActor() { this.currentActor = (this.currentActor + 1) % this.actors.length; return this.actors[this.currentActor]; }; Dispatcher.prototype.remove = function remove() { this.actors.forEach(function (actor) { actor.remove(); }); this.actors = []; this.workerPool.release(this.id); }; Dispatcher.Actor = performance.Actor; function loadTileJSON (options, requestManager, callback) { var loaded = function (err, tileJSON) { if (err) { return callback(err); } else if (tileJSON) { var result = performance.pick(performance.extend(tileJSON, options), [ 'tiles', 'minzoom', 'maxzoom', 'attribution', 'mapbox_logo', 'bounds', 'scheme', 'tileSize', 'encoding' ]); if (tileJSON.vector_layers) { result.vectorLayers = tileJSON.vector_layers; result.vectorLayerIds = result.vectorLayers.map(function (layer) { return layer.id; }); } result.tiles = requestManager.canonicalizeTileset(result, options.url); callback(null, result); } }; if (options.url) { return performance.getJSON(requestManager.transformRequest(requestManager.normalizeSourceURL(options.url), performance.ResourceType.Source), loaded); } else { return performance.browser.frame(function () { return loaded(null, options); }); } } var TileBounds = function TileBounds(bounds, minzoom, maxzoom) { this.bounds = performance.LngLatBounds.convert(this.validateBounds(bounds)); this.minzoom = minzoom || 0; this.maxzoom = maxzoom || 24; }; TileBounds.prototype.validateBounds = function validateBounds(bounds) { if (!Array.isArray(bounds) || bounds.length !== 4) { return [ -180, -90, 180, 90 ]; } return [ Math.max(-180, bounds[0]), Math.max(-90, bounds[1]), Math.min(180, bounds[2]), Math.min(90, bounds[3]) ]; }; TileBounds.prototype.contains = function contains(tileID) { var worldSize = Math.pow(2, tileID.z); var level = { minX: Math.floor(performance.mercatorXfromLng(this.bounds.getWest()) * worldSize), minY: Math.floor(performance.mercatorYfromLat(this.bounds.getNorth()) * worldSize), maxX: Math.ceil(performance.mercatorXfromLng(this.bounds.getEast()) * worldSize), maxY: Math.ceil(performance.mercatorYfromLat(this.bounds.getSouth()) * worldSize) }; var hit = tileID.x >= level.minX && tileID.x < level.maxX && tileID.y >= level.minY && tileID.y < level.maxY; return hit; }; var VectorTileSource = function (Evented) { function VectorTileSource(id, options, dispatcher, eventedParent) { Evented.call(this); this.id = id; this.dispatcher = dispatcher; this.type = 'vector'; this.minzoom = 0; this.maxzoom = 22; this.scheme = 'xyz'; this.tileSize = 512; this.reparseOverscaled = true; this.isTileClipped = true; this._loaded = false; performance.extend(this, performance.pick(options, [ 'url', 'scheme', 'tileSize', 'promoteId' ])); this._options = performance.extend({ type: 'vector' }, options); this._collectResourceTiming = options.collectResourceTiming; if (this.tileSize !== 512) { throw new Error('vector tile sources must have a tileSize of 512'); } this.setEventedParent(eventedParent); } if (Evented) VectorTileSource.__proto__ = Evented; VectorTileSource.prototype = Object.create(Evented && Evented.prototype); VectorTileSource.prototype.constructor = VectorTileSource; VectorTileSource.prototype.load = function load() { var this$1 = this; this._loaded = false; this.fire(new performance.Event('dataloading', { dataType: 'source' })); this._tileJSONRequest = loadTileJSON(this._options, this.map._requestManager, function (err, tileJSON) { this$1._tileJSONRequest = null; this$1._loaded = true; if (err) { this$1.fire(new performance.ErrorEvent(err)); } else if (tileJSON) { performance.extend(this$1, tileJSON); if (tileJSON.bounds) { this$1.tileBounds = new TileBounds(tileJSON.bounds, this$1.minzoom, this$1.maxzoom); } performance.postTurnstileEvent(tileJSON.tiles, this$1.map._requestManager._customAccessToken); performance.postMapLoadEvent(tileJSON.tiles, this$1.map._getMapId(), this$1.map._requestManager._skuToken, this$1.map._requestManager._customAccessToken); this$1.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'metadata' })); this$1.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'content' })); } }); }; VectorTileSource.prototype.loaded = function loaded() { return this._loaded; }; VectorTileSource.prototype.hasTile = function hasTile(tileID) { return !this.tileBounds || this.tileBounds.contains(tileID.canonical); }; VectorTileSource.prototype.onAdd = function onAdd(map) { this.map = map; this.load(); }; VectorTileSource.prototype.setSourceProperty = function setSourceProperty(callback) { if (this._tileJSONRequest) { this._tileJSONRequest.cancel(); } callback(); var sourceCache = this.map.style.sourceCaches[this.id]; sourceCache.clearTiles(); this.load(); }; VectorTileSource.prototype.setTiles = function setTiles(tiles) { var this$1 = this; this.setSourceProperty(function () { this$1._options.tiles = tiles; }); return this; }; VectorTileSource.prototype.setUrl = function setUrl(url) { var this$1 = this; this.setSourceProperty(function () { this$1.url = url; this$1._options.url = url; }); return this; }; VectorTileSource.prototype.onRemove = function onRemove() { if (this._tileJSONRequest) { this._tileJSONRequest.cancel(); this._tileJSONRequest = null; } }; VectorTileSource.prototype.serialize = function serialize() { return performance.extend({}, this._options); }; VectorTileSource.prototype.loadTile = function loadTile(tile, callback) { var url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme)); var params = { request: this.map._requestManager.transformRequest(url, performance.ResourceType.Tile), uid: tile.uid, tileID: tile.tileID, zoom: tile.tileID.overscaledZ, tileSize: this.tileSize * tile.tileID.overscaleFactor(), type: this.type, source: this.id, pixelRatio: performance.browser.devicePixelRatio, showCollisionBoxes: this.map.showCollisionBoxes, promoteId: this.promoteId }; params.request.collectResourceTiming = this._collectResourceTiming; if (!tile.actor || tile.state === 'expired') { tile.actor = this.dispatcher.getActor(); tile.request = tile.actor.send('loadTile', params, done.bind(this)); } else if (tile.state === 'loading') { tile.reloadCallback = callback; } else { tile.request = tile.actor.send('reloadTile', params, done.bind(this)); } function done(err, data) { delete tile.request; if (tile.aborted) { return callback(null); } if (err && err.status !== 404) { return callback(err); } if (data && data.resourceTiming) { tile.resourceTiming = data.resourceTiming; } if (this.map._refreshExpiredTiles && data) { tile.setExpiryData(data); } tile.loadVectorData(data, this.map.painter); performance.cacheEntryPossiblyAdded(this.dispatcher); callback(null); if (tile.reloadCallback) { this.loadTile(tile, tile.reloadCallback); tile.reloadCallback = null; } } }; VectorTileSource.prototype.abortTile = function abortTile(tile) { if (tile.request) { tile.request.cancel(); delete tile.request; } if (tile.actor) { tile.actor.send('abortTile', { uid: tile.uid, type: this.type, source: this.id }, undefined); } }; VectorTileSource.prototype.unloadTile = function unloadTile(tile) { tile.unloadVectorData(); if (tile.actor) { tile.actor.send('removeTile', { uid: tile.uid, type: this.type, source: this.id }, undefined); } }; VectorTileSource.prototype.hasTransition = function hasTransition() { return false; }; return VectorTileSource; }(performance.Evented); var RasterTileSource = function (Evented) { function RasterTileSource(id, options, dispatcher, eventedParent) { Evented.call(this); this.id = id; this.dispatcher = dispatcher; this.setEventedParent(eventedParent); this.type = 'raster'; this.minzoom = 0; this.maxzoom = 22; this.roundZoom = true; this.scheme = 'xyz'; this.tileSize = 512; this._loaded = false; this._options = performance.extend({ type: 'raster' }, options); performance.extend(this, performance.pick(options, [ 'url', 'scheme', 'tileSize' ])); } if (Evented) RasterTileSource.__proto__ = Evented; RasterTileSource.prototype = Object.create(Evented && Evented.prototype); RasterTileSource.prototype.constructor = RasterTileSource; RasterTileSource.prototype.load = function load() { var this$1 = this; this._loaded = false; this.fire(new performance.Event('dataloading', { dataType: 'source' })); this._tileJSONRequest = loadTileJSON(this._options, this.map._requestManager, function (err, tileJSON) { this$1._tileJSONRequest = null; this$1._loaded = true; if (err) { this$1.fire(new performance.ErrorEvent(err)); } else if (tileJSON) { performance.extend(this$1, tileJSON); if (tileJSON.bounds) { this$1.tileBounds = new TileBounds(tileJSON.bounds, this$1.minzoom, this$1.maxzoom); } performance.postTurnstileEvent(tileJSON.tiles); performance.postMapLoadEvent(tileJSON.tiles, this$1.map._getMapId(), this$1.map._requestManager._skuToken); this$1.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'metadata' })); this$1.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'content' })); } }); }; RasterTileSource.prototype.loaded = function loaded() { return this._loaded; }; RasterTileSource.prototype.onAdd = function onAdd(map) { this.map = map; this.load(); }; RasterTileSource.prototype.onRemove = function onRemove() { if (this._tileJSONRequest) { this._tileJSONRequest.cancel(); this._tileJSONRequest = null; } }; RasterTileSource.prototype.serialize = function serialize() { return performance.extend({}, this._options); }; RasterTileSource.prototype.hasTile = function hasTile(tileID) { return !this.tileBounds || this.tileBounds.contains(tileID.canonical); }; RasterTileSource.prototype.loadTile = function loadTile(tile, callback) { var this$1 = this; var url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), this.tileSize); tile.request = performance.getImage(this.map._requestManager.transformRequest(url, performance.ResourceType.Tile), function (err, img) { delete tile.request; if (tile.aborted) { tile.state = 'unloaded'; callback(null); } else if (err) { tile.state = 'errored'; callback(err); } else if (img) { if (this$1.map._refreshExpiredTiles) { tile.setExpiryData(img); } delete img.cacheControl; delete img.expires; var context = this$1.map.painter.context; var gl = context.gl; tile.texture = this$1.map.painter.getTileTexture(img.width); if (tile.texture) { tile.texture.update(img, { useMipmap: true }); } else { tile.texture = new performance.Texture(context, img, gl.RGBA, { useMipmap: true }); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); if (context.extTextureFilterAnisotropic) { gl.texParameterf(gl.TEXTURE_2D, context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, context.extTextureFilterAnisotropicMax); } } tile.state = 'loaded'; performance.cacheEntryPossiblyAdded(this$1.dispatcher); callback(null); } }); }; RasterTileSource.prototype.abortTile = function abortTile(tile, callback) { if (tile.request) { tile.request.cancel(); delete tile.request; } callback(); }; RasterTileSource.prototype.unloadTile = function unloadTile(tile, callback) { if (tile.texture) { this.map.painter.saveTileTexture(tile.texture); } callback(); }; RasterTileSource.prototype.hasTransition = function hasTransition() { return false; }; return RasterTileSource; }(performance.Evented); var RasterDEMTileSource = function (RasterTileSource) { function RasterDEMTileSource(id, options, dispatcher, eventedParent) { RasterTileSource.call(this, id, options, dispatcher, eventedParent); this.type = 'raster-dem'; this.maxzoom = 22; this._options = performance.extend({ type: 'raster-dem' }, options); this.encoding = options.encoding || 'mapbox'; } if (RasterTileSource) RasterDEMTileSource.__proto__ = RasterTileSource; RasterDEMTileSource.prototype = Object.create(RasterTileSource && RasterTileSource.prototype); RasterDEMTileSource.prototype.constructor = RasterDEMTileSource; RasterDEMTileSource.prototype.serialize = function serialize() { return { type: 'raster-dem', url: this.url, tileSize: this.tileSize, tiles: this.tiles, bounds: this.bounds, encoding: this.encoding }; }; RasterDEMTileSource.prototype.loadTile = function loadTile(tile, callback) { var url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), this.tileSize); tile.request = performance.getImage(this.map._requestManager.transformRequest(url, performance.ResourceType.Tile), imageLoaded.bind(this)); tile.neighboringTiles = this._getNeighboringTiles(tile.tileID); function imageLoaded(err, img) { delete tile.request; if (tile.aborted) { tile.state = 'unloaded'; callback(null); } else if (err) { tile.state = 'errored'; callback(err); } else if (img) { if (this.map._refreshExpiredTiles) { tile.setExpiryData(img); } delete img.cacheControl; delete img.expires; var transfer = performance.window.ImageBitmap && img instanceof performance.window.ImageBitmap && performance.offscreenCanvasSupported(); var rawImageData = transfer ? img : performance.browser.getImageData(img, 1); var params = { uid: tile.uid, coord: tile.tileID, source: this.id, rawImageData: rawImageData, encoding: this.encoding }; if (!tile.actor || tile.state === 'expired') { tile.actor = this.dispatcher.getActor(); tile.actor.send('loadDEMTile', params, done.bind(this)); } } } function done(err, dem) { if (err) { tile.state = 'errored'; callback(err); } if (dem) { tile.dem = dem; tile.needsHillshadePrepare = true; tile.state = 'loaded'; callback(null); } } }; RasterDEMTileSource.prototype._getNeighboringTiles = function _getNeighboringTiles(tileID) { var canonical = tileID.canonical; var dim = Math.pow(2, canonical.z); var px = (canonical.x - 1 + dim) % dim; var pxw = canonical.x === 0 ? tileID.wrap - 1 : tileID.wrap; var nx = (canonical.x + 1 + dim) % dim; var nxw = canonical.x + 1 === dim ? tileID.wrap + 1 : tileID.wrap; var neighboringTiles = {}; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y).key] = { backfilled: false }; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y).key] = { backfilled: false }; if (canonical.y > 0) { neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y - 1).key] = { backfilled: false }; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y - 1).key] = { backfilled: false }; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y - 1).key] = { backfilled: false }; } if (canonical.y + 1 < dim) { neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y + 1).key] = { backfilled: false }; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y + 1).key] = { backfilled: false }; neighboringTiles[new performance.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y + 1).key] = { backfilled: false }; } return neighboringTiles; }; RasterDEMTileSource.prototype.unloadTile = function unloadTile(tile) { if (tile.demTexture) { this.map.painter.saveTileTexture(tile.demTexture); } if (tile.fbo) { tile.fbo.destroy(); delete tile.fbo; } if (tile.dem) { delete tile.dem; } delete tile.neighboringTiles; tile.state = 'unloaded'; if (tile.actor) { tile.actor.send('removeDEMTile', { uid: tile.uid, source: this.id }); } }; return RasterDEMTileSource; }(RasterTileSource); var GeoJSONSource = function (Evented) { function GeoJSONSource(id, options, dispatcher, eventedParent) { Evented.call(this); this.id = id; this.type = 'geojson'; this.minzoom = 0; this.maxzoom = 18; this.tileSize = 512; this.isTileClipped = true; this.reparseOverscaled = true; this._removed = false; this._loaded = false; this.actor = dispatcher.getActor(); this.setEventedParent(eventedParent); this._data = options.data; this._options = performance.extend({}, options); this._collectResourceTiming = options.collectResourceTiming; this._resourceTiming = []; if (options.maxzoom !== undefined) { this.maxzoom = options.maxzoom; } if (options.type) { this.type = options.type; } if (options.attribution) { this.attribution = options.attribution; } this.promoteId = options.promoteId; var scale = performance.EXTENT / this.tileSize; this.workerOptions = performance.extend({ source: this.id, cluster: options.cluster || false, geojsonVtOptions: { buffer: (options.buffer !== undefined ? options.buffer : 128) * scale, tolerance: (options.tolerance !== undefined ? options.tolerance : 0.375) * scale, extent: performance.EXTENT, maxZoom: this.maxzoom, lineMetrics: options.lineMetrics || false, generateId: options.generateId || false }, superclusterOptions: { maxZoom: options.clusterMaxZoom !== undefined ? Math.min(options.clusterMaxZoom, this.maxzoom - 1) : this.maxzoom - 1, minPoints: Math.max(2, options.clusterMinPoints || 2), extent: performance.EXTENT, radius: (options.clusterRadius || 50) * scale, log: false, generateId: options.generateId || false }, clusterProperties: options.clusterProperties, filter: options.filter }, options.workerOptions); } if (Evented) GeoJSONSource.__proto__ = Evented; GeoJSONSource.prototype = Object.create(Evented && Evented.prototype); GeoJSONSource.prototype.constructor = GeoJSONSource; GeoJSONSource.prototype.load = function load() { var this$1 = this; this.fire(new performance.Event('dataloading', { dataType: 'source' })); this._updateWorkerData(function (err) { if (err) { this$1.fire(new performance.ErrorEvent(err)); return; } var data = { dataType: 'source', sourceDataType: 'metadata' }; if (this$1._collectResourceTiming && this$1._resourceTiming && this$1._resourceTiming.length > 0) { data.resourceTiming = this$1._resourceTiming; this$1._resourceTiming = []; } this$1.fire(new performance.Event('data', data)); }); }; GeoJSONSource.prototype.onAdd = function onAdd(map) { this.map = map; this.load(); }; GeoJSONSource.prototype.setData = function setData(data) { var this$1 = this; this._data = data; this.fire(new performance.Event('dataloading', { dataType: 'source' })); this._updateWorkerData(function (err) { if (err) { this$1.fire(new performance.ErrorEvent(err)); return; } var data = { dataType: 'source', sourceDataType: 'content' }; if (this$1._collectResourceTiming && this$1._resourceTiming && this$1._resourceTiming.length > 0) { data.resourceTiming = this$1._resourceTiming; this$1._resourceTiming = []; } this$1.fire(new performance.Event('data', data)); }); return this; }; GeoJSONSource.prototype.getClusterExpansionZoom = function getClusterExpansionZoom(clusterId, callback) { this.actor.send('geojson.getClusterExpansionZoom', { clusterId: clusterId, source: this.id }, callback); return this; }; GeoJSONSource.prototype.getClusterChildren = function getClusterChildren(clusterId, callback) { this.actor.send('geojson.getClusterChildren', { clusterId: clusterId, source: this.id }, callback); return this; }; GeoJSONSource.prototype.getClusterLeaves = function getClusterLeaves(clusterId, limit, offset, callback) { this.actor.send('geojson.getClusterLeaves', { source: this.id, clusterId: clusterId, limit: limit, offset: offset }, callback); return this; }; GeoJSONSource.prototype._updateWorkerData = function _updateWorkerData(callback) { var this$1 = this; this._loaded = false; var options = performance.extend({}, this.workerOptions); var data = this._data; if (typeof data === 'string') { options.request = this.map._requestManager.transformRequest(performance.browser.resolveURL(data), performance.ResourceType.Source); options.request.collectResourceTiming = this._collectResourceTiming; } else { options.data = JSON.stringify(data); } this.actor.send(this.type + '.loadData', options, function (err, result) { if (this$1._removed || result && result.abandoned) { return; } this$1._loaded = true; if (result && result.resourceTiming && result.resourceTiming[this$1.id]) { this$1._resourceTiming = result.resourceTiming[this$1.id].slice(0); } this$1.actor.send(this$1.type + '.coalesce', { source: options.source }, null); callback(err); }); }; GeoJSONSource.prototype.loaded = function loaded() { return this._loaded; }; GeoJSONSource.prototype.loadTile = function loadTile(tile, callback) { var this$1 = this; var message = !tile.actor ? 'loadTile' : 'reloadTile'; tile.actor = this.actor; var params = { type: this.type, uid: tile.uid, tileID: tile.tileID, zoom: tile.tileID.overscaledZ, maxZoom: this.maxzoom, tileSize: this.tileSize, source: this.id, pixelRatio: performance.browser.devicePixelRatio, showCollisionBoxes: this.map.showCollisionBoxes, promoteId: this.promoteId }; tile.request = this.actor.send(message, params, function (err, data) { delete tile.request; tile.unloadVectorData(); if (tile.aborted) { return callback(null); } if (err) { return callback(err); } tile.loadVectorData(data, this$1.map.painter, message === 'reloadTile'); return callback(null); }); }; GeoJSONSource.prototype.abortTile = function abortTile(tile) { if (tile.request) { tile.request.cancel(); delete tile.request; } tile.aborted = true; }; GeoJSONSource.prototype.unloadTile = function unloadTile(tile) { tile.unloadVectorData(); this.actor.send('removeTile', { uid: tile.uid, type: this.type, source: this.id }); }; GeoJSONSource.prototype.onRemove = function onRemove() { this._removed = true; this.actor.send('removeSource', { type: this.type, source: this.id }); }; GeoJSONSource.prototype.serialize = function serialize() { return performance.extend({}, this._options, { type: this.type, data: this._data }); }; GeoJSONSource.prototype.hasTransition = function hasTransition() { return false; }; return GeoJSONSource; }(performance.Evented); var rasterBoundsAttributes = performance.createLayout([ { name: 'a_pos', type: 'Int16', components: 2 }, { name: 'a_texture_pos', type: 'Int16', components: 2 } ]); var ImageSource = function (Evented) { function ImageSource(id, options, dispatcher, eventedParent) { Evented.call(this); this.id = id; this.dispatcher = dispatcher; this.coordinates = options.coordinates; this.type = 'image'; this.minzoom = 0; this.maxzoom = 22; this.tileSize = 512; this.tiles = {}; this._loaded = false; this.setEventedParent(eventedParent); this.options = options; } if (Evented) ImageSource.__proto__ = Evented; ImageSource.prototype = Object.create(Evented && Evented.prototype); ImageSource.prototype.constructor = ImageSource; ImageSource.prototype.load = function load(newCoordinates, successCallback) { var this$1 = this; this._loaded = false; this.fire(new performance.Event('dataloading', { dataType: 'source' })); this.url = this.options.url; performance.getImage(this.map._requestManager.transformRequest(this.url, performance.ResourceType.Image), function (err, image) { this$1._loaded = true; if (err) { this$1.fire(new performance.ErrorEvent(err)); } else if (image) { this$1.image = image; if (newCoordinates) { this$1.coordinates = newCoordinates; } if (successCallback) { successCallback(); } this$1._finishLoading(); } }); }; ImageSource.prototype.loaded = function loaded() { return this._loaded; }; ImageSource.prototype.updateImage = function updateImage(options) { var this$1 = this; if (!this.image || !options.url) { return this; } this.options.url = options.url; this.load(options.coordinates, function () { this$1.texture = null; }); return this; }; ImageSource.prototype._finishLoading = function _finishLoading() { if (this.map) { this.setCoordinates(this.coordinates); this.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'metadata' })); } }; ImageSource.prototype.onAdd = function onAdd(map) { this.map = map; this.load(); }; ImageSource.prototype.setCoordinates = function setCoordinates(coordinates) { var this$1 = this; this.coordinates = coordinates; var cornerCoords = coordinates.map(performance.MercatorCoordinate.fromLngLat); this.tileID = getCoordinatesCenterTileID(cornerCoords); this.minzoom = this.maxzoom = this.tileID.z; var tileCoords = cornerCoords.map(function (coord) { return this$1.tileID.getTilePoint(coord)._round(); }); this._boundsArray = new performance.StructArrayLayout4i8(); this._boundsArray.emplaceBack(tileCoords[0].x, tileCoords[0].y, 0, 0); this._boundsArray.emplaceBack(tileCoords[1].x, tileCoords[1].y, performance.EXTENT, 0); this._boundsArray.emplaceBack(tileCoords[3].x, tileCoords[3].y, 0, performance.EXTENT); this._boundsArray.emplaceBack(tileCoords[2].x, tileCoords[2].y, performance.EXTENT, performance.EXTENT); if (this.boundsBuffer) { this.boundsBuffer.destroy(); delete this.boundsBuffer; } this.fire(new performance.Event('data', { dataType: 'source', sourceDataType: 'content' })); return this; }; ImageSource.prototype.prepare = function prepare() { if (Object.keys(this.tiles).length === 0 || !this.image) { return; } var context = this.map.painter.context; var gl = context.gl; if (!this.boundsBuffer) { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } if (!this.boundsSegments) { this.boundsSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { this.texture = new performance.Texture(context, this.image, gl.RGBA); this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); } for (var w in this.tiles) { var tile = this.tiles[w]; if (tile.state !== 'loaded') { tile.state = 'loaded'; tile.texture = this.texture; } } }; ImageSource.prototype.loadTile = function loadTile(tile, callback) { if (this.tileID && this.tileID.equals(tile.tileID.canonical)) { this.tiles[String(tile.tileID.wrap)] = tile; tile.buckets = {}; callback(null); } else { tile.state = 'errored'; callback(null); } }; ImageSource.prototype.serialize = function serialize() { return { type: 'image', url: this.options.url, coordinates: this.coordinates }; }; ImageSource.prototype.hasTransition = function hasTransition() { return false; }; return ImageSource; }(performance.Evented); function getCoordinatesCenterTileID(coords) { var minX = Infinity; var minY = Infinity; var maxX = -Infinity; var maxY = -Infinity; for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; minX = Math.min(minX, coord.x); minY = Math.min(minY, coord.y); maxX = Math.max(maxX, coord.x); maxY = Math.max(maxY, coord.y); } var dx = maxX - minX; var dy = maxY - minY; var dMax = Math.max(dx, dy); var zoom = Math.max(0, Math.floor(-Math.log(dMax) / Math.LN2)); var tilesAtZoom = Math.pow(2, zoom); return new performance.CanonicalTileID(zoom, Math.floor((minX + maxX) / 2 * tilesAtZoom), Math.floor((minY + maxY) / 2 * tilesAtZoom)); } var VideoSource = function (ImageSource) { function VideoSource(id, options, dispatcher, eventedParent) { ImageSource.call(this, id, options, dispatcher, eventedParent); this.roundZoom = true; this.type = 'video'; this.options = options; } if (ImageSource) VideoSource.__proto__ = ImageSource; VideoSource.prototype = Object.create(ImageSource && ImageSource.prototype); VideoSource.prototype.constructor = VideoSource; VideoSource.prototype.load = function load() { var this$1 = this; this._loaded = false; var options = this.options; this.urls = []; for (var i = 0, list = options.urls; i < list.length; i += 1) { var url = list[i]; this.urls.push(this.map._requestManager.transformRequest(url, performance.ResourceType.Source).url); } performance.getVideo(this.urls, function (err, video) { this$1._loaded = true; if (err) { this$1.fire(new performance.ErrorEvent(err)); } else if (video) { this$1.video = video; this$1.video.loop = true; this$1.video.setAttribute('playsinline', ''); this$1.video.addEventListener('playing', function () { this$1.map.triggerRepaint(); }); if (this$1.map) { this$1.video.play(); } this$1._finishLoading(); } }); }; VideoSource.prototype.pause = function pause() { if (this.video) { this.video.pause(); } }; VideoSource.prototype.play = function play() { if (this.video) { this.video.play(); } }; VideoSource.prototype.seek = function seek(seconds) { if (this.video) { var seekableRange = this.video.seekable; if (seconds < seekableRange.start(0) || seconds > seekableRange.end(0)) { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + this.id, null, 'Playback for this video can be set only between the ' + seekableRange.start(0) + ' and ' + seekableRange.end(0) + '-second mark.'))); } else { this.video.currentTime = seconds; } } }; VideoSource.prototype.getVideo = function getVideo() { return this.video; }; VideoSource.prototype.onAdd = function onAdd(map) { if (this.map) { return; } this.map = map; this.load(); if (this.video) { this.video.play(); this.setCoordinates(this.coordinates); } }; VideoSource.prototype.prepare = function prepare() { if (Object.keys(this.tiles).length === 0 || this.video.readyState < 2) { return; } var context = this.map.painter.context; var gl = context.gl; if (!this.boundsBuffer) { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } if (!this.boundsSegments) { this.boundsSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { this.texture = new performance.Texture(context, this.video, gl.RGBA); this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); } else if (!this.video.paused) { this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.video); } for (var w in this.tiles) { var tile = this.tiles[w]; if (tile.state !== 'loaded') { tile.state = 'loaded'; tile.texture = this.texture; } } }; VideoSource.prototype.serialize = function serialize() { return { type: 'video', urls: this.urls, coordinates: this.coordinates }; }; VideoSource.prototype.hasTransition = function hasTransition() { return this.video && !this.video.paused; }; return VideoSource; }(ImageSource); var CanvasSource = function (ImageSource) { function CanvasSource(id, options, dispatcher, eventedParent) { ImageSource.call(this, id, options, dispatcher, eventedParent); if (!options.coordinates) { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + id, null, 'missing required property "coordinates"'))); } else if (!Array.isArray(options.coordinates) || options.coordinates.length !== 4 || options.coordinates.some(function (c) { return !Array.isArray(c) || c.length !== 2 || c.some(function (l) { return typeof l !== 'number'; }); })) { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + id, null, '"coordinates" property must be an array of 4 longitude/latitude array pairs'))); } if (options.animate && typeof options.animate !== 'boolean') { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + id, null, 'optional "animate" property must be a boolean value'))); } if (!options.canvas) { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + id, null, 'missing required property "canvas"'))); } else if (typeof options.canvas !== 'string' && !(options.canvas instanceof performance.window.HTMLCanvasElement)) { this.fire(new performance.ErrorEvent(new performance.ValidationError('sources.' + id, null, '"canvas" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance'))); } this.options = options; this.animate = options.animate !== undefined ? options.animate : true; } if (ImageSource) CanvasSource.__proto__ = ImageSource; CanvasSource.prototype = Object.create(ImageSource && ImageSource.prototype); CanvasSource.prototype.constructor = CanvasSource; CanvasSource.prototype.load = function load() { this._loaded = true; if (!this.canvas) { this.canvas = this.options.canvas instanceof performance.window.HTMLCanvasElement ? this.options.canvas : performance.window.document.getElementById(this.options.canvas); } this.width = this.canvas.width; this.height = this.canvas.height; if (this._hasInvalidDimensions()) { this.fire(new performance.ErrorEvent(new Error('Canvas dimensions cannot be less than or equal to zero.'))); return; } this.play = function () { this._playing = true; this.map.triggerRepaint(); }; this.pause = function () { if (this._playing) { this.prepare(); this._playing = false; } }; this._finishLoading(); }; CanvasSource.prototype.getCanvas = function getCanvas() { return this.canvas; }; CanvasSource.prototype.onAdd = function onAdd(map) { this.map = map; this.load(); if (this.canvas) { if (this.animate) { this.play(); } } }; CanvasSource.prototype.onRemove = function onRemove() { this.pause(); }; CanvasSource.prototype.prepare = function prepare() { var resize = false; if (this.canvas.width !== this.width) { this.width = this.canvas.width; resize = true; } if (this.canvas.height !== this.height) { this.height = this.canvas.height; resize = true; } if (this._hasInvalidDimensions()) { return; } if (Object.keys(this.tiles).length === 0) { return; } var context = this.map.painter.context; var gl = context.gl; if (!this.boundsBuffer) { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } if (!this.boundsSegments) { this.boundsSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { this.texture = new performance.Texture(context, this.canvas, gl.RGBA, { premultiply: true }); } else if (resize || this._playing) { this.texture.update(this.canvas, { premultiply: true }); } for (var w in this.tiles) { var tile = this.tiles[w]; if (tile.state !== 'loaded') { tile.state = 'loaded'; tile.texture = this.texture; } } }; CanvasSource.prototype.serialize = function serialize() { return { type: 'canvas', coordinates: this.coordinates }; }; CanvasSource.prototype.hasTransition = function hasTransition() { return this._playing; }; CanvasSource.prototype._hasInvalidDimensions = function _hasInvalidDimensions() { for (var i = 0, list = [ this.canvas.width, this.canvas.height ]; i < list.length; i += 1) { var x = list[i]; if (isNaN(x) || x <= 0) { return true; } } return false; }; return CanvasSource; }(ImageSource); var sourceTypes = { vector: VectorTileSource, raster: RasterTileSource, 'raster-dem': RasterDEMTileSource, geojson: GeoJSONSource, video: VideoSource, image: ImageSource, canvas: CanvasSource }; var create = function (id, specification, dispatcher, eventedParent) { var source = new sourceTypes[specification.type](id, specification, dispatcher, eventedParent); if (source.id !== id) { throw new Error('Expected Source id to be ' + id + ' instead of ' + source.id); } performance.bindAll([ 'load', 'abort', 'unload', 'serialize', 'prepare' ], source); return source; }; var getType = function (name) { return sourceTypes[name]; }; var setType = function (name, type) { sourceTypes[name] = type; }; function getPixelPosMatrix(transform, tileID) { var t = performance.identity([]); performance.translate(t, t, [ 1, 1, 0 ]); performance.scale(t, t, [ transform.width * 0.5, transform.height * 0.5, 1 ]); return performance.multiply(t, t, transform.calculatePosMatrix(tileID.toUnwrapped())); } function queryIncludes3DLayer(layers, styleLayers, sourceID) { if (layers) { for (var i = 0, list = layers; i < list.length; i += 1) { var layerID = list[i]; var layer = styleLayers[layerID]; if (layer && layer.source === sourceID && layer.type === 'fill-extrusion') { return true; } } } else { for (var key in styleLayers) { var layer$1 = styleLayers[key]; if (layer$1.source === sourceID && layer$1.type === 'fill-extrusion') { return true; } } } return false; } function queryRenderedFeatures(sourceCache, styleLayers, serializedLayers, queryGeometry, params, transform) { var has3DLayer = queryIncludes3DLayer(params && params.layers, styleLayers, sourceCache.id); var maxPitchScaleFactor = transform.maxPitchScaleFactor(); var tilesIn = sourceCache.tilesIn(queryGeometry, maxPitchScaleFactor, has3DLayer); tilesIn.sort(sortTilesIn); var renderedFeatureLayers = []; for (var i = 0, list = tilesIn; i < list.length; i += 1) { var tileIn = list[i]; renderedFeatureLayers.push({ wrappedTileID: tileIn.tileID.wrapped().key, queryResults: tileIn.tile.queryRenderedFeatures(styleLayers, serializedLayers, sourceCache._state, tileIn.queryGeometry, tileIn.cameraQueryGeometry, tileIn.scale, params, transform, maxPitchScaleFactor, getPixelPosMatrix(sourceCache.transform, tileIn.tileID)) }); } var result = mergeRenderedFeatureLayers(renderedFeatureLayers); for (var layerID in result) { result[layerID].forEach(function (featureWrapper) { var feature = featureWrapper.feature; var state = sourceCache.getFeatureState(feature.layer['source-layer'], feature.id); feature.source = feature.layer.source; if (feature.layer['source-layer']) { feature.sourceLayer = feature.layer['source-layer']; } feature.state = state; }); } return result; } function queryRenderedSymbols(styleLayers, serializedLayers, sourceCaches, queryGeometry, params, collisionIndex, retainedQueryData) { var result = {}; var renderedSymbols = collisionIndex.queryRenderedSymbols(queryGeometry); var bucketQueryData = []; for (var i = 0, list = Object.keys(renderedSymbols).map(Number); i < list.length; i += 1) { var bucketInstanceId = list[i]; bucketQueryData.push(retainedQueryData[bucketInstanceId]); } bucketQueryData.sort(sortTilesIn); var loop = function () { var queryData = list$2[i$2]; var bucketSymbols = queryData.featureIndex.lookupSymbolFeatures(renderedSymbols[queryData.bucketInstanceId], serializedLayers, queryData.bucketIndex, queryData.sourceLayerIndex, params.filter, params.layers, params.availableImages, styleLayers); for (var layerID in bucketSymbols) { var resultFeatures = result[layerID] = result[layerID] || []; var layerSymbols = bucketSymbols[layerID]; layerSymbols.sort(function (a, b) { var featureSortOrder = queryData.featureSortOrder; if (featureSortOrder) { var sortedA = featureSortOrder.indexOf(a.featureIndex); var sortedB = featureSortOrder.indexOf(b.featureIndex); return sortedB - sortedA; } else { return b.featureIndex - a.featureIndex; } }); for (var i$1 = 0, list$1 = layerSymbols; i$1 < list$1.length; i$1 += 1) { var symbolFeature = list$1[i$1]; resultFeatures.push(symbolFeature); } } }; for (var i$2 = 0, list$2 = bucketQueryData; i$2 < list$2.length; i$2 += 1) loop(); var loop$1 = function (layerName) { result[layerName].forEach(function (featureWrapper) { var feature = featureWrapper.feature; var layer = styleLayers[layerName]; var sourceCache = sourceCaches[layer.source]; var state = sourceCache.getFeatureState(feature.layer['source-layer'], feature.id); feature.source = feature.layer.source; if (feature.layer['source-layer']) { feature.sourceLayer = feature.layer['source-layer']; } feature.state = state; }); }; for (var layerName in result) loop$1(layerName); return result; } function querySourceFeatures(sourceCache, params) { var tiles = sourceCache.getRenderableIds().map(function (id) { return sourceCache.getTileByID(id); }); var result = []; var dataTiles = {}; for (var i = 0; i < tiles.length; i++) { var tile = tiles[i]; var dataID = tile.tileID.canonical.key; if (!dataTiles[dataID]) { dataTiles[dataID] = true; tile.querySourceFeatures(result, params); } } return result; } function sortTilesIn(a, b) { var idA = a.tileID; var idB = b.tileID; return idA.overscaledZ - idB.overscaledZ || idA.canonical.y - idB.canonical.y || idA.wrap - idB.wrap || idA.canonical.x - idB.canonical.x; } function mergeRenderedFeatureLayers(tiles) { var result = {}; var wrappedIDLayerMap = {}; for (var i$1 = 0, list$1 = tiles; i$1 < list$1.length; i$1 += 1) { var tile = list$1[i$1]; var queryResults = tile.queryResults; var wrappedID = tile.wrappedTileID; var wrappedIDLayers = wrappedIDLayerMap[wrappedID] = wrappedIDLayerMap[wrappedID] || {}; for (var layerID in queryResults) { var tileFeatures = queryResults[layerID]; var wrappedIDFeatures = wrappedIDLayers[layerID] = wrappedIDLayers[layerID] || {}; var resultFeatures = result[layerID] = result[layerID] || []; for (var i = 0, list = tileFeatures; i < list.length; i += 1) { var tileFeature = list[i]; if (!wrappedIDFeatures[tileFeature.featureIndex]) { wrappedIDFeatures[tileFeature.featureIndex] = true; resultFeatures.push(tileFeature); } } } } return result; } var TileCache = function TileCache(max, onRemove) { this.max = max; this.onRemove = onRemove; this.reset(); }; TileCache.prototype.reset = function reset() { for (var key in this.data) { for (var i = 0, list = this.data[key]; i < list.length; i += 1) { var removedData = list[i]; if (removedData.timeout) { clearTimeout(removedData.timeout); } this.onRemove(removedData.value); } } this.data = {}; this.order = []; return this; }; TileCache.prototype.add = function add(tileID, data, expiryTimeout) { var this$1 = this; var key = tileID.wrapped().key; if (this.data[key] === undefined) { this.data[key] = []; } var dataWrapper = { value: data, timeout: undefined }; if (expiryTimeout !== undefined) { dataWrapper.timeout = setTimeout(function () { this$1.remove(tileID, dataWrapper); }, expiryTimeout); } this.data[key].push(dataWrapper); this.order.push(key); if (this.order.length > this.max) { var removedData = this._getAndRemoveByKey(this.order[0]); if (removedData) { this.onRemove(removedData); } } return this; }; TileCache.prototype.has = function has(tileID) { return tileID.wrapped().key in this.data; }; TileCache.prototype.getAndRemove = function getAndRemove(tileID) { if (!this.has(tileID)) { return null; } return this._getAndRemoveByKey(tileID.wrapped().key); }; TileCache.prototype._getAndRemoveByKey = function _getAndRemoveByKey(key) { var data = this.data[key].shift(); if (data.timeout) { clearTimeout(data.timeout); } if (this.data[key].length === 0) { delete this.data[key]; } this.order.splice(this.order.indexOf(key), 1); return data.value; }; TileCache.prototype.getByKey = function getByKey(key) { var data = this.data[key]; return data ? data[0].value : null; }; TileCache.prototype.get = function get(tileID) { if (!this.has(tileID)) { return null; } var data = this.data[tileID.wrapped().key][0]; return data.value; }; TileCache.prototype.remove = function remove(tileID, value) { if (!this.has(tileID)) { return this; } var key = tileID.wrapped().key; var dataIndex = value === undefined ? 0 : this.data[key].indexOf(value); var data = this.data[key][dataIndex]; this.data[key].splice(dataIndex, 1); if (data.timeout) { clearTimeout(data.timeout); } if (this.data[key].length === 0) { delete this.data[key]; } this.onRemove(data.value); this.order.splice(this.order.indexOf(key), 1); return this; }; TileCache.prototype.setMaxSize = function setMaxSize(max) { this.max = max; while (this.order.length > this.max) { var removedData = this._getAndRemoveByKey(this.order[0]); if (removedData) { this.onRemove(removedData); } } return this; }; TileCache.prototype.filter = function filter(filterFn) { var removed = []; for (var key in this.data) { for (var i = 0, list = this.data[key]; i < list.length; i += 1) { var entry = list[i]; if (!filterFn(entry.value)) { removed.push(entry); } } } for (var i$1 = 0, list$1 = removed; i$1 < list$1.length; i$1 += 1) { var r = list$1[i$1]; this.remove(r.value.tileID, r); } }; var IndexBuffer = function IndexBuffer(context, array, dynamicDraw) { this.context = context; var gl = context.gl; this.buffer = gl.createBuffer(); this.dynamicDraw = Boolean(dynamicDraw); this.context.unbindVAO(); context.bindElementBuffer.set(this.buffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW); if (!this.dynamicDraw) { delete array.arrayBuffer; } }; IndexBuffer.prototype.bind = function bind() { this.context.bindElementBuffer.set(this.buffer); }; IndexBuffer.prototype.updateData = function updateData(array) { var gl = this.context.gl; this.context.unbindVAO(); this.bind(); gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, array.arrayBuffer); }; IndexBuffer.prototype.destroy = function destroy() { var gl = this.context.gl; if (this.buffer) { gl.deleteBuffer(this.buffer); delete this.buffer; } }; var AttributeType = { Int8: 'BYTE', Uint8: 'UNSIGNED_BYTE', Int16: 'SHORT', Uint16: 'UNSIGNED_SHORT', Int32: 'INT', Uint32: 'UNSIGNED_INT', Float32: 'FLOAT' }; var VertexBuffer = function VertexBuffer(context, array, attributes, dynamicDraw) { this.length = array.length; this.attributes = attributes; this.itemSize = array.bytesPerElement; this.dynamicDraw = dynamicDraw; this.context = context; var gl = context.gl; this.buffer = gl.createBuffer(); context.bindVertexBuffer.set(this.buffer); gl.bufferData(gl.ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW); if (!this.dynamicDraw) { delete array.arrayBuffer; } }; VertexBuffer.prototype.bind = function bind() { this.context.bindVertexBuffer.set(this.buffer); }; VertexBuffer.prototype.updateData = function updateData(array) { var gl = this.context.gl; this.bind(); gl.bufferSubData(gl.ARRAY_BUFFER, 0, array.arrayBuffer); }; VertexBuffer.prototype.enableAttributes = function enableAttributes(gl, program) { for (var j = 0; j < this.attributes.length; j++) { var member = this.attributes[j]; var attribIndex = program.attributes[member.name]; if (attribIndex !== undefined) { gl.enableVertexAttribArray(attribIndex); } } }; VertexBuffer.prototype.setVertexAttribPointers = function setVertexAttribPointers(gl, program, vertexOffset) { for (var j = 0; j < this.attributes.length; j++) { var member = this.attributes[j]; var attribIndex = program.attributes[member.name]; if (attribIndex !== undefined) { gl.vertexAttribPointer(attribIndex, member.components, gl[AttributeType[member.type]], false, this.itemSize, member.offset + this.itemSize * (vertexOffset || 0)); } } }; VertexBuffer.prototype.destroy = function destroy() { var gl = this.context.gl; if (this.buffer) { gl.deleteBuffer(this.buffer); delete this.buffer; } }; var BaseValue = function BaseValue(context) { this.gl = context.gl; this.default = this.getDefault(); this.current = this.default; this.dirty = false; }; BaseValue.prototype.get = function get() { return this.current; }; BaseValue.prototype.set = function set(value) { }; BaseValue.prototype.getDefault = function getDefault() { return this.default; }; BaseValue.prototype.setDefault = function setDefault() { this.set(this.default); }; var ClearColor = function (BaseValue) { function ClearColor() { BaseValue.apply(this, arguments); } if (BaseValue) ClearColor.__proto__ = BaseValue; ClearColor.prototype = Object.create(BaseValue && BaseValue.prototype); ClearColor.prototype.constructor = ClearColor; ClearColor.prototype.getDefault = function getDefault() { return performance.Color.transparent; }; ClearColor.prototype.set = function set(v) { var c = this.current; if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) { return; } this.gl.clearColor(v.r, v.g, v.b, v.a); this.current = v; this.dirty = false; }; return ClearColor; }(BaseValue); var ClearDepth = function (BaseValue) { function ClearDepth() { BaseValue.apply(this, arguments); } if (BaseValue) ClearDepth.__proto__ = BaseValue; ClearDepth.prototype = Object.create(BaseValue && BaseValue.prototype); ClearDepth.prototype.constructor = ClearDepth; ClearDepth.prototype.getDefault = function getDefault() { return 1; }; ClearDepth.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.clearDepth(v); this.current = v; this.dirty = false; }; return ClearDepth; }(BaseValue); var ClearStencil = function (BaseValue) { function ClearStencil() { BaseValue.apply(this, arguments); } if (BaseValue) ClearStencil.__proto__ = BaseValue; ClearStencil.prototype = Object.create(BaseValue && BaseValue.prototype); ClearStencil.prototype.constructor = ClearStencil; ClearStencil.prototype.getDefault = function getDefault() { return 0; }; ClearStencil.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.clearStencil(v); this.current = v; this.dirty = false; }; return ClearStencil; }(BaseValue); var ColorMask = function (BaseValue) { function ColorMask() { BaseValue.apply(this, arguments); } if (BaseValue) ColorMask.__proto__ = BaseValue; ColorMask.prototype = Object.create(BaseValue && BaseValue.prototype); ColorMask.prototype.constructor = ColorMask; ColorMask.prototype.getDefault = function getDefault() { return [ true, true, true, true ]; }; ColorMask.prototype.set = function set(v) { var c = this.current; if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) { return; } this.gl.colorMask(v[0], v[1], v[2], v[3]); this.current = v; this.dirty = false; }; return ColorMask; }(BaseValue); var DepthMask = function (BaseValue) { function DepthMask() { BaseValue.apply(this, arguments); } if (BaseValue) DepthMask.__proto__ = BaseValue; DepthMask.prototype = Object.create(BaseValue && BaseValue.prototype); DepthMask.prototype.constructor = DepthMask; DepthMask.prototype.getDefault = function getDefault() { return true; }; DepthMask.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.depthMask(v); this.current = v; this.dirty = false; }; return DepthMask; }(BaseValue); var StencilMask = function (BaseValue) { function StencilMask() { BaseValue.apply(this, arguments); } if (BaseValue) StencilMask.__proto__ = BaseValue; StencilMask.prototype = Object.create(BaseValue && BaseValue.prototype); StencilMask.prototype.constructor = StencilMask; StencilMask.prototype.getDefault = function getDefault() { return 255; }; StencilMask.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.stencilMask(v); this.current = v; this.dirty = false; }; return StencilMask; }(BaseValue); var StencilFunc = function (BaseValue) { function StencilFunc() { BaseValue.apply(this, arguments); } if (BaseValue) StencilFunc.__proto__ = BaseValue; StencilFunc.prototype = Object.create(BaseValue && BaseValue.prototype); StencilFunc.prototype.constructor = StencilFunc; StencilFunc.prototype.getDefault = function getDefault() { return { func: this.gl.ALWAYS, ref: 0, mask: 255 }; }; StencilFunc.prototype.set = function set(v) { var c = this.current; if (v.func === c.func && v.ref === c.ref && v.mask === c.mask && !this.dirty) { return; } this.gl.stencilFunc(v.func, v.ref, v.mask); this.current = v; this.dirty = false; }; return StencilFunc; }(BaseValue); var StencilOp = function (BaseValue) { function StencilOp() { BaseValue.apply(this, arguments); } if (BaseValue) StencilOp.__proto__ = BaseValue; StencilOp.prototype = Object.create(BaseValue && BaseValue.prototype); StencilOp.prototype.constructor = StencilOp; StencilOp.prototype.getDefault = function getDefault() { var gl = this.gl; return [ gl.KEEP, gl.KEEP, gl.KEEP ]; }; StencilOp.prototype.set = function set(v) { var c = this.current; if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && !this.dirty) { return; } this.gl.stencilOp(v[0], v[1], v[2]); this.current = v; this.dirty = false; }; return StencilOp; }(BaseValue); var StencilTest = function (BaseValue) { function StencilTest() { BaseValue.apply(this, arguments); } if (BaseValue) StencilTest.__proto__ = BaseValue; StencilTest.prototype = Object.create(BaseValue && BaseValue.prototype); StencilTest.prototype.constructor = StencilTest; StencilTest.prototype.getDefault = function getDefault() { return false; }; StencilTest.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; if (v) { gl.enable(gl.STENCIL_TEST); } else { gl.disable(gl.STENCIL_TEST); } this.current = v; this.dirty = false; }; return StencilTest; }(BaseValue); var DepthRange = function (BaseValue) { function DepthRange() { BaseValue.apply(this, arguments); } if (BaseValue) DepthRange.__proto__ = BaseValue; DepthRange.prototype = Object.create(BaseValue && BaseValue.prototype); DepthRange.prototype.constructor = DepthRange; DepthRange.prototype.getDefault = function getDefault() { return [ 0, 1 ]; }; DepthRange.prototype.set = function set(v) { var c = this.current; if (v[0] === c[0] && v[1] === c[1] && !this.dirty) { return; } this.gl.depthRange(v[0], v[1]); this.current = v; this.dirty = false; }; return DepthRange; }(BaseValue); var DepthTest = function (BaseValue) { function DepthTest() { BaseValue.apply(this, arguments); } if (BaseValue) DepthTest.__proto__ = BaseValue; DepthTest.prototype = Object.create(BaseValue && BaseValue.prototype); DepthTest.prototype.constructor = DepthTest; DepthTest.prototype.getDefault = function getDefault() { return false; }; DepthTest.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; if (v) { gl.enable(gl.DEPTH_TEST); } else { gl.disable(gl.DEPTH_TEST); } this.current = v; this.dirty = false; }; return DepthTest; }(BaseValue); var DepthFunc = function (BaseValue) { function DepthFunc() { BaseValue.apply(this, arguments); } if (BaseValue) DepthFunc.__proto__ = BaseValue; DepthFunc.prototype = Object.create(BaseValue && BaseValue.prototype); DepthFunc.prototype.constructor = DepthFunc; DepthFunc.prototype.getDefault = function getDefault() { return this.gl.LESS; }; DepthFunc.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.depthFunc(v); this.current = v; this.dirty = false; }; return DepthFunc; }(BaseValue); var Blend = function (BaseValue) { function Blend() { BaseValue.apply(this, arguments); } if (BaseValue) Blend.__proto__ = BaseValue; Blend.prototype = Object.create(BaseValue && BaseValue.prototype); Blend.prototype.constructor = Blend; Blend.prototype.getDefault = function getDefault() { return false; }; Blend.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; if (v) { gl.enable(gl.BLEND); } else { gl.disable(gl.BLEND); } this.current = v; this.dirty = false; }; return Blend; }(BaseValue); var BlendFunc = function (BaseValue) { function BlendFunc() { BaseValue.apply(this, arguments); } if (BaseValue) BlendFunc.__proto__ = BaseValue; BlendFunc.prototype = Object.create(BaseValue && BaseValue.prototype); BlendFunc.prototype.constructor = BlendFunc; BlendFunc.prototype.getDefault = function getDefault() { var gl = this.gl; return [ gl.ONE, gl.ZERO ]; }; BlendFunc.prototype.set = function set(v) { var c = this.current; if (v[0] === c[0] && v[1] === c[1] && !this.dirty) { return; } this.gl.blendFunc(v[0], v[1]); this.current = v; this.dirty = false; }; return BlendFunc; }(BaseValue); var BlendColor = function (BaseValue) { function BlendColor() { BaseValue.apply(this, arguments); } if (BaseValue) BlendColor.__proto__ = BaseValue; BlendColor.prototype = Object.create(BaseValue && BaseValue.prototype); BlendColor.prototype.constructor = BlendColor; BlendColor.prototype.getDefault = function getDefault() { return performance.Color.transparent; }; BlendColor.prototype.set = function set(v) { var c = this.current; if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) { return; } this.gl.blendColor(v.r, v.g, v.b, v.a); this.current = v; this.dirty = false; }; return BlendColor; }(BaseValue); var BlendEquation = function (BaseValue) { function BlendEquation() { BaseValue.apply(this, arguments); } if (BaseValue) BlendEquation.__proto__ = BaseValue; BlendEquation.prototype = Object.create(BaseValue && BaseValue.prototype); BlendEquation.prototype.constructor = BlendEquation; BlendEquation.prototype.getDefault = function getDefault() { return this.gl.FUNC_ADD; }; BlendEquation.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.blendEquation(v); this.current = v; this.dirty = false; }; return BlendEquation; }(BaseValue); var CullFace = function (BaseValue) { function CullFace() { BaseValue.apply(this, arguments); } if (BaseValue) CullFace.__proto__ = BaseValue; CullFace.prototype = Object.create(BaseValue && BaseValue.prototype); CullFace.prototype.constructor = CullFace; CullFace.prototype.getDefault = function getDefault() { return false; }; CullFace.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; if (v) { gl.enable(gl.CULL_FACE); } else { gl.disable(gl.CULL_FACE); } this.current = v; this.dirty = false; }; return CullFace; }(BaseValue); var CullFaceSide = function (BaseValue) { function CullFaceSide() { BaseValue.apply(this, arguments); } if (BaseValue) CullFaceSide.__proto__ = BaseValue; CullFaceSide.prototype = Object.create(BaseValue && BaseValue.prototype); CullFaceSide.prototype.constructor = CullFaceSide; CullFaceSide.prototype.getDefault = function getDefault() { return this.gl.BACK; }; CullFaceSide.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.cullFace(v); this.current = v; this.dirty = false; }; return CullFaceSide; }(BaseValue); var FrontFace = function (BaseValue) { function FrontFace() { BaseValue.apply(this, arguments); } if (BaseValue) FrontFace.__proto__ = BaseValue; FrontFace.prototype = Object.create(BaseValue && BaseValue.prototype); FrontFace.prototype.constructor = FrontFace; FrontFace.prototype.getDefault = function getDefault() { return this.gl.CCW; }; FrontFace.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.frontFace(v); this.current = v; this.dirty = false; }; return FrontFace; }(BaseValue); var Program = function (BaseValue) { function Program() { BaseValue.apply(this, arguments); } if (BaseValue) Program.__proto__ = BaseValue; Program.prototype = Object.create(BaseValue && BaseValue.prototype); Program.prototype.constructor = Program; Program.prototype.getDefault = function getDefault() { return null; }; Program.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.useProgram(v); this.current = v; this.dirty = false; }; return Program; }(BaseValue); var ActiveTextureUnit = function (BaseValue) { function ActiveTextureUnit() { BaseValue.apply(this, arguments); } if (BaseValue) ActiveTextureUnit.__proto__ = BaseValue; ActiveTextureUnit.prototype = Object.create(BaseValue && BaseValue.prototype); ActiveTextureUnit.prototype.constructor = ActiveTextureUnit; ActiveTextureUnit.prototype.getDefault = function getDefault() { return this.gl.TEXTURE0; }; ActiveTextureUnit.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.gl.activeTexture(v); this.current = v; this.dirty = false; }; return ActiveTextureUnit; }(BaseValue); var Viewport = function (BaseValue) { function Viewport() { BaseValue.apply(this, arguments); } if (BaseValue) Viewport.__proto__ = BaseValue; Viewport.prototype = Object.create(BaseValue && BaseValue.prototype); Viewport.prototype.constructor = Viewport; Viewport.prototype.getDefault = function getDefault() { var gl = this.gl; return [ 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight ]; }; Viewport.prototype.set = function set(v) { var c = this.current; if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) { return; } this.gl.viewport(v[0], v[1], v[2], v[3]); this.current = v; this.dirty = false; }; return Viewport; }(BaseValue); var BindFramebuffer = function (BaseValue) { function BindFramebuffer() { BaseValue.apply(this, arguments); } if (BaseValue) BindFramebuffer.__proto__ = BaseValue; BindFramebuffer.prototype = Object.create(BaseValue && BaseValue.prototype); BindFramebuffer.prototype.constructor = BindFramebuffer; BindFramebuffer.prototype.getDefault = function getDefault() { return null; }; BindFramebuffer.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.bindFramebuffer(gl.FRAMEBUFFER, v); this.current = v; this.dirty = false; }; return BindFramebuffer; }(BaseValue); var BindRenderbuffer = function (BaseValue) { function BindRenderbuffer() { BaseValue.apply(this, arguments); } if (BaseValue) BindRenderbuffer.__proto__ = BaseValue; BindRenderbuffer.prototype = Object.create(BaseValue && BaseValue.prototype); BindRenderbuffer.prototype.constructor = BindRenderbuffer; BindRenderbuffer.prototype.getDefault = function getDefault() { return null; }; BindRenderbuffer.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.bindRenderbuffer(gl.RENDERBUFFER, v); this.current = v; this.dirty = false; }; return BindRenderbuffer; }(BaseValue); var BindTexture = function (BaseValue) { function BindTexture() { BaseValue.apply(this, arguments); } if (BaseValue) BindTexture.__proto__ = BaseValue; BindTexture.prototype = Object.create(BaseValue && BaseValue.prototype); BindTexture.prototype.constructor = BindTexture; BindTexture.prototype.getDefault = function getDefault() { return null; }; BindTexture.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.bindTexture(gl.TEXTURE_2D, v); this.current = v; this.dirty = false; }; return BindTexture; }(BaseValue); var BindVertexBuffer = function (BaseValue) { function BindVertexBuffer() { BaseValue.apply(this, arguments); } if (BaseValue) BindVertexBuffer.__proto__ = BaseValue; BindVertexBuffer.prototype = Object.create(BaseValue && BaseValue.prototype); BindVertexBuffer.prototype.constructor = BindVertexBuffer; BindVertexBuffer.prototype.getDefault = function getDefault() { return null; }; BindVertexBuffer.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.bindBuffer(gl.ARRAY_BUFFER, v); this.current = v; this.dirty = false; }; return BindVertexBuffer; }(BaseValue); var BindElementBuffer = function (BaseValue) { function BindElementBuffer() { BaseValue.apply(this, arguments); } if (BaseValue) BindElementBuffer.__proto__ = BaseValue; BindElementBuffer.prototype = Object.create(BaseValue && BaseValue.prototype); BindElementBuffer.prototype.constructor = BindElementBuffer; BindElementBuffer.prototype.getDefault = function getDefault() { return null; }; BindElementBuffer.prototype.set = function set(v) { var gl = this.gl; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, v); this.current = v; this.dirty = false; }; return BindElementBuffer; }(BaseValue); var BindVertexArrayOES = function (BaseValue) { function BindVertexArrayOES(context) { BaseValue.call(this, context); this.vao = context.extVertexArrayObject; } if (BaseValue) BindVertexArrayOES.__proto__ = BaseValue; BindVertexArrayOES.prototype = Object.create(BaseValue && BaseValue.prototype); BindVertexArrayOES.prototype.constructor = BindVertexArrayOES; BindVertexArrayOES.prototype.getDefault = function getDefault() { return null; }; BindVertexArrayOES.prototype.set = function set(v) { if (!this.vao || v === this.current && !this.dirty) { return; } this.vao.bindVertexArrayOES(v); this.current = v; this.dirty = false; }; return BindVertexArrayOES; }(BaseValue); var PixelStoreUnpack = function (BaseValue) { function PixelStoreUnpack() { BaseValue.apply(this, arguments); } if (BaseValue) PixelStoreUnpack.__proto__ = BaseValue; PixelStoreUnpack.prototype = Object.create(BaseValue && BaseValue.prototype); PixelStoreUnpack.prototype.constructor = PixelStoreUnpack; PixelStoreUnpack.prototype.getDefault = function getDefault() { return 4; }; PixelStoreUnpack.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.pixelStorei(gl.UNPACK_ALIGNMENT, v); this.current = v; this.dirty = false; }; return PixelStoreUnpack; }(BaseValue); var PixelStoreUnpackPremultiplyAlpha = function (BaseValue) { function PixelStoreUnpackPremultiplyAlpha() { BaseValue.apply(this, arguments); } if (BaseValue) PixelStoreUnpackPremultiplyAlpha.__proto__ = BaseValue; PixelStoreUnpackPremultiplyAlpha.prototype = Object.create(BaseValue && BaseValue.prototype); PixelStoreUnpackPremultiplyAlpha.prototype.constructor = PixelStoreUnpackPremultiplyAlpha; PixelStoreUnpackPremultiplyAlpha.prototype.getDefault = function getDefault() { return false; }; PixelStoreUnpackPremultiplyAlpha.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, v); this.current = v; this.dirty = false; }; return PixelStoreUnpackPremultiplyAlpha; }(BaseValue); var PixelStoreUnpackFlipY = function (BaseValue) { function PixelStoreUnpackFlipY() { BaseValue.apply(this, arguments); } if (BaseValue) PixelStoreUnpackFlipY.__proto__ = BaseValue; PixelStoreUnpackFlipY.prototype = Object.create(BaseValue && BaseValue.prototype); PixelStoreUnpackFlipY.prototype.constructor = PixelStoreUnpackFlipY; PixelStoreUnpackFlipY.prototype.getDefault = function getDefault() { return false; }; PixelStoreUnpackFlipY.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } var gl = this.gl; gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, v); this.current = v; this.dirty = false; }; return PixelStoreUnpackFlipY; }(BaseValue); var FramebufferAttachment = function (BaseValue) { function FramebufferAttachment(context, parent) { BaseValue.call(this, context); this.context = context; this.parent = parent; } if (BaseValue) FramebufferAttachment.__proto__ = BaseValue; FramebufferAttachment.prototype = Object.create(BaseValue && BaseValue.prototype); FramebufferAttachment.prototype.constructor = FramebufferAttachment; FramebufferAttachment.prototype.getDefault = function getDefault() { return null; }; return FramebufferAttachment; }(BaseValue); var ColorAttachment = function (FramebufferAttachment) { function ColorAttachment() { FramebufferAttachment.apply(this, arguments); } if (FramebufferAttachment) ColorAttachment.__proto__ = FramebufferAttachment; ColorAttachment.prototype = Object.create(FramebufferAttachment && FramebufferAttachment.prototype); ColorAttachment.prototype.constructor = ColorAttachment; ColorAttachment.prototype.setDirty = function setDirty() { this.dirty = true; }; ColorAttachment.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.context.bindFramebuffer.set(this.parent); var gl = this.gl; gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, v, 0); this.current = v; this.dirty = false; }; return ColorAttachment; }(FramebufferAttachment); var DepthAttachment = function (FramebufferAttachment) { function DepthAttachment() { FramebufferAttachment.apply(this, arguments); } if (FramebufferAttachment) DepthAttachment.__proto__ = FramebufferAttachment; DepthAttachment.prototype = Object.create(FramebufferAttachment && FramebufferAttachment.prototype); DepthAttachment.prototype.constructor = DepthAttachment; DepthAttachment.prototype.set = function set(v) { if (v === this.current && !this.dirty) { return; } this.context.bindFramebuffer.set(this.parent); var gl = this.gl; gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, v); this.current = v; this.dirty = false; }; return DepthAttachment; }(FramebufferAttachment); var Framebuffer = function Framebuffer(context, width, height, hasDepth) { this.context = context; this.width = width; this.height = height; var gl = context.gl; var fbo = this.framebuffer = gl.createFramebuffer(); this.colorAttachment = new ColorAttachment(context, fbo); if (hasDepth) { this.depthAttachment = new DepthAttachment(context, fbo); } }; Framebuffer.prototype.destroy = function destroy() { var gl = this.context.gl; var texture = this.colorAttachment.get(); if (texture) { gl.deleteTexture(texture); } if (this.depthAttachment) { var renderbuffer = this.depthAttachment.get(); if (renderbuffer) { gl.deleteRenderbuffer(renderbuffer); } } gl.deleteFramebuffer(this.framebuffer); }; var ALWAYS = 519; var DepthMode = function DepthMode(depthFunc, depthMask, depthRange) { this.func = depthFunc; this.mask = depthMask; this.range = depthRange; }; DepthMode.ReadOnly = false; DepthMode.ReadWrite = true; DepthMode.disabled = new DepthMode(ALWAYS, DepthMode.ReadOnly, [ 0, 1 ]); var ALWAYS$1 = 519; var KEEP = 7680; var StencilMode = function StencilMode(test, ref, mask, fail, depthFail, pass) { this.test = test; this.ref = ref; this.mask = mask; this.fail = fail; this.depthFail = depthFail; this.pass = pass; }; StencilMode.disabled = new StencilMode({ func: ALWAYS$1, mask: 0 }, 0, 0, KEEP, KEEP, KEEP); var ZERO = 0; var ONE = 1; var ONE_MINUS_SRC_ALPHA = 771; var ColorMode = function ColorMode(blendFunction, blendColor, mask) { this.blendFunction = blendFunction; this.blendColor = blendColor; this.mask = mask; }; ColorMode.Replace = [ ONE, ZERO ]; ColorMode.disabled = new ColorMode(ColorMode.Replace, performance.Color.transparent, [ false, false, false, false ]); ColorMode.unblended = new ColorMode(ColorMode.Replace, performance.Color.transparent, [ true, true, true, true ]); ColorMode.alphaBlended = new ColorMode([ ONE, ONE_MINUS_SRC_ALPHA ], performance.Color.transparent, [ true, true, true, true ]); var BACK = 1029; var CCW = 2305; var CullFaceMode = function CullFaceMode(enable, mode, frontFace) { this.enable = enable; this.mode = mode; this.frontFace = frontFace; }; CullFaceMode.disabled = new CullFaceMode(false, BACK, CCW); CullFaceMode.backCCW = new CullFaceMode(true, BACK, CCW); var Context = function Context(gl) { this.gl = gl; this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object'); this.clearColor = new ClearColor(this); this.clearDepth = new ClearDepth(this); this.clearStencil = new ClearStencil(this); this.colorMask = new ColorMask(this); this.depthMask = new DepthMask(this); this.stencilMask = new StencilMask(this); this.stencilFunc = new StencilFunc(this); this.stencilOp = new StencilOp(this); this.stencilTest = new StencilTest(this); this.depthRange = new DepthRange(this); this.depthTest = new DepthTest(this); this.depthFunc = new DepthFunc(this); this.blend = new Blend(this); this.blendFunc = new BlendFunc(this); this.blendColor = new BlendColor(this); this.blendEquation = new BlendEquation(this); this.cullFace = new CullFace(this); this.cullFaceSide = new CullFaceSide(this); this.frontFace = new FrontFace(this); this.program = new Program(this); this.activeTexture = new ActiveTextureUnit(this); this.viewport = new Viewport(this); this.bindFramebuffer = new BindFramebuffer(this); this.bindRenderbuffer = new BindRenderbuffer(this); this.bindTexture = new BindTexture(this); this.bindVertexBuffer = new BindVertexBuffer(this); this.bindElementBuffer = new BindElementBuffer(this); this.bindVertexArrayOES = this.extVertexArrayObject && new BindVertexArrayOES(this); this.pixelStoreUnpack = new PixelStoreUnpack(this); this.pixelStoreUnpackPremultiplyAlpha = new PixelStoreUnpackPremultiplyAlpha(this); this.pixelStoreUnpackFlipY = new PixelStoreUnpackFlipY(this); this.extTextureFilterAnisotropic = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); if (this.extTextureFilterAnisotropic) { this.extTextureFilterAnisotropicMax = gl.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float'); if (this.extTextureHalfFloat) { gl.getExtension('OES_texture_half_float_linear'); this.extRenderToTextureHalfFloat = gl.getExtension('EXT_color_buffer_half_float'); } this.extTimerQuery = gl.getExtension('EXT_disjoint_timer_query'); this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); }; Context.prototype.setDefault = function setDefault() { this.unbindVAO(); this.clearColor.setDefault(); this.clearDepth.setDefault(); this.clearStencil.setDefault(); this.colorMask.setDefault(); this.depthMask.setDefault(); this.stencilMask.setDefault(); this.stencilFunc.setDefault(); this.stencilOp.setDefault(); this.stencilTest.setDefault(); this.depthRange.setDefault(); this.depthTest.setDefault(); this.depthFunc.setDefault(); this.blend.setDefault(); this.blendFunc.setDefault(); this.blendColor.setDefault(); this.blendEquation.setDefault(); this.cullFace.setDefault(); this.cullFaceSide.setDefault(); this.frontFace.setDefault(); this.program.setDefault(); this.activeTexture.setDefault(); this.bindFramebuffer.setDefault(); this.pixelStoreUnpack.setDefault(); this.pixelStoreUnpackPremultiplyAlpha.setDefault(); this.pixelStoreUnpackFlipY.setDefault(); }; Context.prototype.setDirty = function setDirty() { this.clearColor.dirty = true; this.clearDepth.dirty = true; this.clearStencil.dirty = true; this.colorMask.dirty = true; this.depthMask.dirty = true; this.stencilMask.dirty = true; this.stencilFunc.dirty = true; this.stencilOp.dirty = true; this.stencilTest.dirty = true; this.depthRange.dirty = true; this.depthTest.dirty = true; this.depthFunc.dirty = true; this.blend.dirty = true; this.blendFunc.dirty = true; this.blendColor.dirty = true; this.blendEquation.dirty = true; this.cullFace.dirty = true; this.cullFaceSide.dirty = true; this.frontFace.dirty = true; this.program.dirty = true; this.activeTexture.dirty = true; this.viewport.dirty = true; this.bindFramebuffer.dirty = true; this.bindRenderbuffer.dirty = true; this.bindTexture.dirty = true; this.bindVertexBuffer.dirty = true; this.bindElementBuffer.dirty = true; if (this.extVertexArrayObject) { this.bindVertexArrayOES.dirty = true; } this.pixelStoreUnpack.dirty = true; this.pixelStoreUnpackPremultiplyAlpha.dirty = true; this.pixelStoreUnpackFlipY.dirty = true; }; Context.prototype.createIndexBuffer = function createIndexBuffer(array, dynamicDraw) { return new IndexBuffer(this, array, dynamicDraw); }; Context.prototype.createVertexBuffer = function createVertexBuffer(array, attributes, dynamicDraw) { return new VertexBuffer(this, array, attributes, dynamicDraw); }; Context.prototype.createRenderbuffer = function createRenderbuffer(storageFormat, width, height) { var gl = this.gl; var rbo = gl.createRenderbuffer(); this.bindRenderbuffer.set(rbo); gl.renderbufferStorage(gl.RENDERBUFFER, storageFormat, width, height); this.bindRenderbuffer.set(null); return rbo; }; Context.prototype.createFramebuffer = function createFramebuffer(width, height, hasDepth) { return new Framebuffer(this, width, height, hasDepth); }; Context.prototype.clear = function clear(ref) { var color = ref.color; var depth = ref.depth; var gl = this.gl; var mask = 0; if (color) { mask |= gl.COLOR_BUFFER_BIT; this.clearColor.set(color); this.colorMask.set([ true, true, true, true ]); } if (typeof depth !== 'undefined') { mask |= gl.DEPTH_BUFFER_BIT; this.depthRange.set([ 0, 1 ]); this.clearDepth.set(depth); this.depthMask.set(true); } gl.clear(mask); }; Context.prototype.setCullFace = function setCullFace(cullFaceMode) { if (cullFaceMode.enable === false) { this.cullFace.set(false); } else { this.cullFace.set(true); this.cullFaceSide.set(cullFaceMode.mode); this.frontFace.set(cullFaceMode.frontFace); } }; Context.prototype.setDepthMode = function setDepthMode(depthMode) { if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) { this.depthTest.set(false); } else { this.depthTest.set(true); this.depthFunc.set(depthMode.func); this.depthMask.set(depthMode.mask); this.depthRange.set(depthMode.range); } }; Context.prototype.setStencilMode = function setStencilMode(stencilMode) { if (stencilMode.test.func === this.gl.ALWAYS && !stencilMode.mask) { this.stencilTest.set(false); } else { this.stencilTest.set(true); this.stencilMask.set(stencilMode.mask); this.stencilOp.set([ stencilMode.fail, stencilMode.depthFail, stencilMode.pass ]); this.stencilFunc.set({ func: stencilMode.test.func, ref: stencilMode.ref, mask: stencilMode.test.mask }); } }; Context.prototype.setColorMode = function setColorMode(colorMode) { if (performance.deepEqual(colorMode.blendFunction, ColorMode.Replace)) { this.blend.set(false); } else { this.blend.set(true); this.blendFunc.set(colorMode.blendFunction); this.blendColor.set(colorMode.blendColor); } this.colorMask.set(colorMode.mask); }; Context.prototype.unbindVAO = function unbindVAO() { if (this.extVertexArrayObject) { this.bindVertexArrayOES.set(null); } }; var SourceCache = function (Evented) { function SourceCache(id, options, dispatcher) { var this$1 = this; Evented.call(this); this.id = id; this.dispatcher = dispatcher; this.on('data', function (e) { if (e.dataType === 'source' && e.sourceDataType === 'metadata') { this$1._sourceLoaded = true; } if (this$1._sourceLoaded && !this$1._paused && e.dataType === 'source' && e.sourceDataType === 'content') { this$1.reload(); if (this$1.transform) { this$1.update(this$1.transform); } } }); this.on('error', function () { this$1._sourceErrored = true; }); this._source = create(id, options, dispatcher, this); this._tiles = {}; this._cache = new TileCache(0, this._unloadTile.bind(this)); this._timers = {}; this._cacheTimers = {}; this._maxTileCacheSize = null; this._loadedParentTiles = {}; this._coveredTiles = {}; this._state = new performance.SourceFeatureState(); } if (Evented) SourceCache.__proto__ = Evented; SourceCache.prototype = Object.create(Evented && Evented.prototype); SourceCache.prototype.constructor = SourceCache; SourceCache.prototype.onAdd = function onAdd(map) { this.map = map; this._maxTileCacheSize = map ? map._maxTileCacheSize : null; if (this._source && this._source.onAdd) { this._source.onAdd(map); } }; SourceCache.prototype.onRemove = function onRemove(map) { if (this._source && this._source.onRemove) { this._source.onRemove(map); } }; SourceCache.prototype.loaded = function loaded() { if (this._sourceErrored) { return true; } if (!this._sourceLoaded) { return false; } if (!this._source.loaded()) { return false; } for (var t in this._tiles) { var tile = this._tiles[t]; if (tile.state !== 'loaded' && tile.state !== 'errored') { return false; } } return true; }; SourceCache.prototype.getSource = function getSource() { return this._source; }; SourceCache.prototype.pause = function pause() { this._paused = true; }; SourceCache.prototype.resume = function resume() { if (!this._paused) { return; } var shouldReload = this._shouldReloadOnResume; this._paused = false; this._shouldReloadOnResume = false; if (shouldReload) { this.reload(); } if (this.transform) { this.update(this.transform); } }; SourceCache.prototype._loadTile = function _loadTile(tile, callback) { return this._source.loadTile(tile, callback); }; SourceCache.prototype._unloadTile = function _unloadTile(tile) { if (this._source.unloadTile) { return this._source.unloadTile(tile, function () { }); } }; SourceCache.prototype._abortTile = function _abortTile(tile) { if (this._source.abortTile) { return this._source.abortTile(tile, function () { }); } }; SourceCache.prototype.serialize = function serialize() { return this._source.serialize(); }; SourceCache.prototype.prepare = function prepare(context) { if (this._source.prepare) { this._source.prepare(); } this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null); for (var i in this._tiles) { var tile = this._tiles[i]; tile.upload(context); tile.prepare(this.map.style.imageManager); } }; SourceCache.prototype.getIds = function getIds() { return performance.values(this._tiles).map(function (tile) { return tile.tileID; }).sort(compareTileId).map(function (id) { return id.key; }); }; SourceCache.prototype.getRenderableIds = function getRenderableIds(symbolLayer) { var this$1 = this; var renderables = []; for (var id in this._tiles) { if (this._isIdRenderable(id, symbolLayer)) { renderables.push(this._tiles[id]); } } if (symbolLayer) { return renderables.sort(function (a_, b_) { var a = a_.tileID; var b = b_.tileID; var rotatedA = new performance.Point(a.canonical.x, a.canonical.y)._rotate(this$1.transform.angle); var rotatedB = new performance.Point(b.canonical.x, b.canonical.y)._rotate(this$1.transform.angle); return a.overscaledZ - b.overscaledZ || rotatedB.y - rotatedA.y || rotatedB.x - rotatedA.x; }).map(function (tile) { return tile.tileID.key; }); } return renderables.map(function (tile) { return tile.tileID; }).sort(compareTileId).map(function (id) { return id.key; }); }; SourceCache.prototype.hasRenderableParent = function hasRenderableParent(tileID) { var parentTile = this.findLoadedParent(tileID, 0); if (parentTile) { return this._isIdRenderable(parentTile.tileID.key); } return false; }; SourceCache.prototype._isIdRenderable = function _isIdRenderable(id, symbolLayer) { return this._tiles[id] && this._tiles[id].hasData() && !this._coveredTiles[id] && (symbolLayer || !this._tiles[id].holdingForFade()); }; SourceCache.prototype.reload = function reload() { if (this._paused) { this._shouldReloadOnResume = true; return; } this._cache.reset(); for (var i in this._tiles) { if (this._tiles[i].state !== 'errored') { this._reloadTile(i, 'reloading'); } } }; SourceCache.prototype._reloadTile = function _reloadTile(id, state) { var tile = this._tiles[id]; if (!tile) { return; } if (tile.state !== 'loading') { tile.state = state; } this._loadTile(tile, this._tileLoaded.bind(this, tile, id, state)); }; SourceCache.prototype._tileLoaded = function _tileLoaded(tile, id, previousState, err) { if (err) { tile.state = 'errored'; if (err.status !== 404) { this._source.fire(new performance.ErrorEvent(err, { tile: tile })); } else { this.update(this.transform); } return; } tile.timeAdded = performance.browser.now(); if (previousState === 'expired') { tile.refreshedUponExpiration = true; } this._setTileReloadTimer(id, tile); if (this.getSource().type === 'raster-dem' && tile.dem) { this._backfillDEM(tile); } this._state.initializeTileState(tile, this.map ? this.map.painter : null); this._source.fire(new performance.Event('data', { dataType: 'source', tile: tile, coord: tile.tileID })); }; SourceCache.prototype._backfillDEM = function _backfillDEM(tile) { var renderables = this.getRenderableIds(); for (var i = 0; i < renderables.length; i++) { var borderId = renderables[i]; if (tile.neighboringTiles && tile.neighboringTiles[borderId]) { var borderTile = this.getTileByID(borderId); fillBorder(tile, borderTile); fillBorder(borderTile, tile); } } function fillBorder(tile, borderTile) { tile.needsHillshadePrepare = true; var dx = borderTile.tileID.canonical.x - tile.tileID.canonical.x; var dy = borderTile.tileID.canonical.y - tile.tileID.canonical.y; var dim = Math.pow(2, tile.tileID.canonical.z); var borderId = borderTile.tileID.key; if (dx === 0 && dy === 0) { return; } if (Math.abs(dy) > 1) { return; } if (Math.abs(dx) > 1) { if (Math.abs(dx + dim) === 1) { dx += dim; } else if (Math.abs(dx - dim) === 1) { dx -= dim; } } if (!borderTile.dem || !tile.dem) { return; } tile.dem.backfillBorder(borderTile.dem, dx, dy); if (tile.neighboringTiles && tile.neighboringTiles[borderId]) { tile.neighboringTiles[borderId].backfilled = true; } } }; SourceCache.prototype.getTile = function getTile(tileID) { return this.getTileByID(tileID.key); }; SourceCache.prototype.getTileByID = function getTileByID(id) { return this._tiles[id]; }; SourceCache.prototype._retainLoadedChildren = function _retainLoadedChildren(idealTiles, zoom, maxCoveringZoom, retain) { for (var id in this._tiles) { var tile = this._tiles[id]; if (retain[id] || !tile.hasData() || tile.tileID.overscaledZ <= zoom || tile.tileID.overscaledZ > maxCoveringZoom) { continue; } var topmostLoadedID = tile.tileID; while (tile && tile.tileID.overscaledZ > zoom + 1) { var parentID = tile.tileID.scaledTo(tile.tileID.overscaledZ - 1); tile = this._tiles[parentID.key]; if (tile && tile.hasData()) { topmostLoadedID = parentID; } } var tileID = topmostLoadedID; while (tileID.overscaledZ > zoom) { tileID = tileID.scaledTo(tileID.overscaledZ - 1); if (idealTiles[tileID.key]) { retain[topmostLoadedID.key] = topmostLoadedID; break; } } } }; SourceCache.prototype.findLoadedParent = function findLoadedParent(tileID, minCoveringZoom) { if (tileID.key in this._loadedParentTiles) { var parent = this._loadedParentTiles[tileID.key]; if (parent && parent.tileID.overscaledZ >= minCoveringZoom) { return parent; } else { return null; } } for (var z = tileID.overscaledZ - 1; z >= minCoveringZoom; z--) { var parentTileID = tileID.scaledTo(z); var tile = this._getLoadedTile(parentTileID); if (tile) { return tile; } } }; SourceCache.prototype._getLoadedTile = function _getLoadedTile(tileID) { var tile = this._tiles[tileID.key]; if (tile && tile.hasData()) { return tile; } var cachedTile = this._cache.getByKey(tileID.wrapped().key); return cachedTile; }; SourceCache.prototype.updateCacheSize = function updateCacheSize(transform) { var widthInTiles = Math.ceil(transform.width / this._source.tileSize) + 1; var heightInTiles = Math.ceil(transform.height / this._source.tileSize) + 1; var approxTilesInView = widthInTiles * heightInTiles; var commonZoomRange = 5; var viewDependentMaxSize = Math.floor(approxTilesInView * commonZoomRange); var maxSize = typeof this._maxTileCacheSize === 'number' ? Math.min(this._maxTileCacheSize, viewDependentMaxSize) : viewDependentMaxSize; this._cache.setMaxSize(maxSize); }; SourceCache.prototype.handleWrapJump = function handleWrapJump(lng) { var prevLng = this._prevLng === undefined ? lng : this._prevLng; var lngDifference = lng - prevLng; var worldDifference = lngDifference / 360; var wrapDelta = Math.round(worldDifference); this._prevLng = lng; if (wrapDelta) { var tiles = {}; for (var key in this._tiles) { var tile = this._tiles[key]; tile.tileID = tile.tileID.unwrapTo(tile.tileID.wrap + wrapDelta); tiles[tile.tileID.key] = tile; } this._tiles = tiles; for (var id in this._timers) { clearTimeout(this._timers[id]); delete this._timers[id]; } for (var id$1 in this._tiles) { var tile$1 = this._tiles[id$1]; this._setTileReloadTimer(id$1, tile$1); } } }; SourceCache.prototype.update = function update(transform) { var this$1 = this; this.transform = transform; if (!this._sourceLoaded || this._paused) { return; } this.updateCacheSize(transform); this.handleWrapJump(this.transform.center.lng); this._coveredTiles = {}; var idealTileIDs; if (!this.used) { idealTileIDs = []; } else if (this._source.tileID) { idealTileIDs = transform.getVisibleUnwrappedCoordinates(this._source.tileID).map(function (unwrapped) { return new performance.OverscaledTileID(unwrapped.canonical.z, unwrapped.wrap, unwrapped.canonical.z, unwrapped.canonical.x, unwrapped.canonical.y); }); } else { idealTileIDs = transform.coveringTiles({ tileSize: this._source.tileSize, minzoom: this._source.minzoom, maxzoom: this._source.maxzoom, roundZoom: this._source.roundZoom, reparseOverscaled: this._source.reparseOverscaled }); if (this._source.hasTile) { idealTileIDs = idealTileIDs.filter(function (coord) { return this$1._source.hasTile(coord); }); } } var zoom = transform.coveringZoomLevel(this._source); var minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this._source.minzoom); var maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this._source.minzoom); var retain = this._updateRetainedTiles(idealTileIDs, zoom); if (isRasterType(this._source.type)) { var parentsForFading = {}; var fadingTiles = {}; var ids = Object.keys(retain); for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; var tileID = retain[id]; var tile = this._tiles[id]; if (!tile || tile.fadeEndTime && tile.fadeEndTime <= performance.browser.now()) { continue; } var parentTile = this.findLoadedParent(tileID, minCoveringZoom); if (parentTile) { this._addTile(parentTile.tileID); parentsForFading[parentTile.tileID.key] = parentTile.tileID; } fadingTiles[id] = tileID; } this._retainLoadedChildren(fadingTiles, zoom, maxCoveringZoom, retain); for (var id$1 in parentsForFading) { if (!retain[id$1]) { this._coveredTiles[id$1] = true; retain[id$1] = parentsForFading[id$1]; } } } for (var retainedId in retain) { this._tiles[retainedId].clearFadeHold(); } var remove = performance.keysDifference(this._tiles, retain); for (var i$1 = 0, list$1 = remove; i$1 < list$1.length; i$1 += 1) { var tileID$1 = list$1[i$1]; var tile$1 = this._tiles[tileID$1]; if (tile$1.hasSymbolBuckets && !tile$1.holdingForFade()) { tile$1.setHoldDuration(this.map._fadeDuration); } else if (!tile$1.hasSymbolBuckets || tile$1.symbolFadeFinished()) { this._removeTile(tileID$1); } } this._updateLoadedParentTileCache(); }; SourceCache.prototype.releaseSymbolFadeTiles = function releaseSymbolFadeTiles() { for (var id in this._tiles) { if (this._tiles[id].holdingForFade()) { this._removeTile(id); } } }; SourceCache.prototype._updateRetainedTiles = function _updateRetainedTiles(idealTileIDs, zoom) { var retain = {}; var checked = {}; var minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this._source.minzoom); var maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this._source.minzoom); var missingTiles = {}; for (var i = 0, list = idealTileIDs; i < list.length; i += 1) { var tileID = list[i]; var tile = this._addTile(tileID); retain[tileID.key] = tileID; if (tile.hasData()) { continue; } if (zoom < this._source.maxzoom) { missingTiles[tileID.key] = tileID; } } this._retainLoadedChildren(missingTiles, zoom, maxCoveringZoom, retain); for (var i$1 = 0, list$1 = idealTileIDs; i$1 < list$1.length; i$1 += 1) { var tileID$1 = list$1[i$1]; var tile$1 = this._tiles[tileID$1.key]; if (tile$1.hasData()) { continue; } if (zoom + 1 > this._source.maxzoom) { var childCoord = tileID$1.children(this._source.maxzoom)[0]; var childTile = this.getTile(childCoord); if (!!childTile && childTile.hasData()) { retain[childCoord.key] = childCoord; continue; } } else { var children = tileID$1.children(this._source.maxzoom); if (retain[children[0].key] && retain[children[1].key] && retain[children[2].key] && retain[children[3].key]) { continue; } } var parentWasRequested = tile$1.wasRequested(); for (var overscaledZ = tileID$1.overscaledZ - 1; overscaledZ >= minCoveringZoom; --overscaledZ) { var parentId = tileID$1.scaledTo(overscaledZ); if (checked[parentId.key]) { break; } checked[parentId.key] = true; tile$1 = this.getTile(parentId); if (!tile$1 && parentWasRequested) { tile$1 = this._addTile(parentId); } if (tile$1) { retain[parentId.key] = parentId; parentWasRequested = tile$1.wasRequested(); if (tile$1.hasData()) { break; } } } } return retain; }; SourceCache.prototype._updateLoadedParentTileCache = function _updateLoadedParentTileCache() { this._loadedParentTiles = {}; for (var tileKey in this._tiles) { var path = []; var parentTile = void 0; var currentId = this._tiles[tileKey].tileID; while (currentId.overscaledZ > 0) { if (currentId.key in this._loadedParentTiles) { parentTile = this._loadedParentTiles[currentId.key]; break; } path.push(currentId.key); var parentId = currentId.scaledTo(currentId.overscaledZ - 1); parentTile = this._getLoadedTile(parentId); if (parentTile) { break; } currentId = parentId; } for (var i = 0, list = path; i < list.length; i += 1) { var key = list[i]; this._loadedParentTiles[key] = parentTile; } } }; SourceCache.prototype._addTile = function _addTile(tileID) { var tile = this._tiles[tileID.key]; if (tile) { return tile; } tile = this._cache.getAndRemove(tileID); if (tile) { this._setTileReloadTimer(tileID.key, tile); tile.tileID = tileID; this._state.initializeTileState(tile, this.map ? this.map.painter : null); if (this._cacheTimers[tileID.key]) { clearTimeout(this._cacheTimers[tileID.key]); delete this._cacheTimers[tileID.key]; this._setTileReloadTimer(tileID.key, tile); } } var cached = Boolean(tile); if (!cached) { tile = new performance.Tile(tileID, this._source.tileSize * tileID.overscaleFactor()); this._loadTile(tile, this._tileLoaded.bind(this, tile, tileID.key, tile.state)); } if (!tile) { return null; } tile.uses++; this._tiles[tileID.key] = tile; if (!cached) { this._source.fire(new performance.Event('dataloading', { tile: tile, coord: tile.tileID, dataType: 'source' })); } return tile; }; SourceCache.prototype._setTileReloadTimer = function _setTileReloadTimer(id, tile) { var this$1 = this; if (id in this._timers) { clearTimeout(this._timers[id]); delete this._timers[id]; } var expiryTimeout = tile.getExpiryTimeout(); if (expiryTimeout) { this._timers[id] = setTimeout(function () { this$1._reloadTile(id, 'expired'); delete this$1._timers[id]; }, expiryTimeout); } }; SourceCache.prototype._removeTile = function _removeTile(id) { var tile = this._tiles[id]; if (!tile) { return; } tile.uses--; delete this._tiles[id]; if (this._timers[id]) { clearTimeout(this._timers[id]); delete this._timers[id]; } if (tile.uses > 0) { return; } if (tile.hasData() && tile.state !== 'reloading') { this._cache.add(tile.tileID, tile, tile.getExpiryTimeout()); } else { tile.aborted = true; this._abortTile(tile); this._unloadTile(tile); } }; SourceCache.prototype.clearTiles = function clearTiles() { this._shouldReloadOnResume = false; this._paused = false; for (var id in this._tiles) { this._removeTile(id); } this._cache.reset(); }; SourceCache.prototype.tilesIn = function tilesIn(pointQueryGeometry, maxPitchScaleFactor, has3DLayer) { var this$1 = this; var tileResults = []; var transform = this.transform; if (!transform) { return tileResults; } var cameraPointQueryGeometry = has3DLayer ? transform.getCameraQueryGeometry(pointQueryGeometry) : pointQueryGeometry; var queryGeometry = pointQueryGeometry.map(function (p) { return transform.pointCoordinate(p); }); var cameraQueryGeometry = cameraPointQueryGeometry.map(function (p) { return transform.pointCoordinate(p); }); var ids = this.getIds(); var minX = Infinity; var minY = Infinity; var maxX = -Infinity; var maxY = -Infinity; for (var i$1 = 0, list = cameraQueryGeometry; i$1 < list.length; i$1 += 1) { var p = list[i$1]; minX = Math.min(minX, p.x); minY = Math.min(minY, p.y); maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y); } var loop = function (i) { var tile = this$1._tiles[ids[i]]; if (tile.holdingForFade()) { return; } var tileID = tile.tileID; var scale = Math.pow(2, transform.zoom - tile.tileID.overscaledZ); var queryPadding = maxPitchScaleFactor * tile.queryPadding * performance.EXTENT / tile.tileSize / scale; var tileSpaceBounds = [ tileID.getTilePoint(new performance.MercatorCoordinate(minX, minY)), tileID.getTilePoint(new performance.MercatorCoordinate(maxX, maxY)) ]; if (tileSpaceBounds[0].x - queryPadding < performance.EXTENT && tileSpaceBounds[0].y - queryPadding < performance.EXTENT && tileSpaceBounds[1].x + queryPadding >= 0 && tileSpaceBounds[1].y + queryPadding >= 0) { var tileSpaceQueryGeometry = queryGeometry.map(function (c) { return tileID.getTilePoint(c); }); var tileSpaceCameraQueryGeometry = cameraQueryGeometry.map(function (c) { return tileID.getTilePoint(c); }); tileResults.push({ tile: tile, tileID: tileID, queryGeometry: tileSpaceQueryGeometry, cameraQueryGeometry: tileSpaceCameraQueryGeometry, scale: scale }); } }; for (var i = 0; i < ids.length; i++) loop(i); return tileResults; }; SourceCache.prototype.getVisibleCoordinates = function getVisibleCoordinates(symbolLayer) { var this$1 = this; var coords = this.getRenderableIds(symbolLayer).map(function (id) { return this$1._tiles[id].tileID; }); for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; coord.posMatrix = this.transform.calculatePosMatrix(coord.toUnwrapped()); } return coords; }; SourceCache.prototype.hasTransition = function hasTransition() { if (this._source.hasTransition()) { return true; } if (isRasterType(this._source.type)) { for (var id in this._tiles) { var tile = this._tiles[id]; if (tile.fadeEndTime !== undefined && tile.fadeEndTime >= performance.browser.now()) { return true; } } } return false; }; SourceCache.prototype.setFeatureState = function setFeatureState(sourceLayer, featureId, state) { sourceLayer = sourceLayer || '_geojsonTileLayer'; this._state.updateState(sourceLayer, featureId, state); }; SourceCache.prototype.removeFeatureState = function removeFeatureState(sourceLayer, featureId, key) { sourceLayer = sourceLayer || '_geojsonTileLayer'; this._state.removeFeatureState(sourceLayer, featureId, key); }; SourceCache.prototype.getFeatureState = function getFeatureState(sourceLayer, featureId) { sourceLayer = sourceLayer || '_geojsonTileLayer'; return this._state.getState(sourceLayer, featureId); }; SourceCache.prototype.setDependencies = function setDependencies(tileKey, namespace, dependencies) { var tile = this._tiles[tileKey]; if (tile) { tile.setDependencies(namespace, dependencies); } }; SourceCache.prototype.reloadTilesForDependencies = function reloadTilesForDependencies(namespaces, keys) { for (var id in this._tiles) { var tile = this._tiles[id]; if (tile.hasDependency(namespaces, keys)) { this._reloadTile(id, 'reloading'); } } this._cache.filter(function (tile) { return !tile.hasDependency(namespaces, keys); }); }; return SourceCache; }(performance.Evented); SourceCache.maxOverzooming = 10; SourceCache.maxUnderzooming = 3; function compareTileId(a, b) { var aWrap = Math.abs(a.wrap * 2) - +(a.wrap < 0); var bWrap = Math.abs(b.wrap * 2) - +(b.wrap < 0); return a.overscaledZ - b.overscaledZ || bWrap - aWrap || b.canonical.y - a.canonical.y || b.canonical.x - a.canonical.x; } function isRasterType(type) { return type === 'raster' || type === 'image' || type === 'video'; } function WebWorker () { return new performance.window.Worker(exported.workerUrl); } var PRELOAD_POOL_ID = 'mapboxgl_preloaded_worker_pool'; var WorkerPool = function WorkerPool() { this.active = {}; }; WorkerPool.prototype.acquire = function acquire(mapId) { if (!this.workers) { this.workers = []; while (this.workers.length < WorkerPool.workerCount) { this.workers.push(new WebWorker()); } } this.active[mapId] = true; return this.workers.slice(); }; WorkerPool.prototype.release = function release(mapId) { delete this.active[mapId]; if (this.numActive() === 0) { this.workers.forEach(function (w) { w.terminate(); }); this.workers = null; } }; WorkerPool.prototype.isPreloaded = function isPreloaded() { return !!this.active[PRELOAD_POOL_ID]; }; WorkerPool.prototype.numActive = function numActive() { return Object.keys(this.active).length; }; var availableLogicalProcessors = Math.floor(performance.browser.hardwareConcurrency / 2); WorkerPool.workerCount = Math.max(Math.min(availableLogicalProcessors, 6), 1); var globalWorkerPool; function getGlobalWorkerPool() { if (!globalWorkerPool) { globalWorkerPool = new WorkerPool(); } return globalWorkerPool; } function prewarm() { var workerPool = getGlobalWorkerPool(); workerPool.acquire(PRELOAD_POOL_ID); } function clearPrewarmedResources() { var pool = globalWorkerPool; if (pool) { if (pool.isPreloaded() && pool.numActive() === 1) { pool.release(PRELOAD_POOL_ID); globalWorkerPool = null; } else { console.warn('Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()'); } } } function deref(layer, parent) { var result = {}; for (var k in layer) { if (k !== 'ref') { result[k] = layer[k]; } } performance.refProperties.forEach(function (k) { if (k in parent) { result[k] = parent[k]; } }); return result; } function derefLayers(layers) { layers = layers.slice(); var map = Object.create(null); for (var i = 0; i < layers.length; i++) { map[layers[i].id] = layers[i]; } for (var i$1 = 0; i$1 < layers.length; i$1++) { if ('ref' in layers[i$1]) { layers[i$1] = deref(layers[i$1], map[layers[i$1].ref]); } } return layers; } function emptyStyle() { var style = {}; var version = performance.styleSpec['$version']; for (var styleKey in performance.styleSpec['$root']) { var spec = performance.styleSpec['$root'][styleKey]; if (spec.required) { var value = null; if (styleKey === 'version') { value = version; } else { if (spec.type === 'array') { value = []; } else { value = {}; } } if (value != null) { style[styleKey] = value; } } } return style; } var operations = { setStyle: 'setStyle', addLayer: 'addLayer', removeLayer: 'removeLayer', setPaintProperty: 'setPaintProperty', setLayoutProperty: 'setLayoutProperty', setFilter: 'setFilter', addSource: 'addSource', removeSource: 'removeSource', setGeoJSONSourceData: 'setGeoJSONSourceData', setLayerZoomRange: 'setLayerZoomRange', setLayerProperty: 'setLayerProperty', setCenter: 'setCenter', setZoom: 'setZoom', setBearing: 'setBearing', setPitch: 'setPitch', setSprite: 'setSprite', setGlyphs: 'setGlyphs', setTransition: 'setTransition', setLight: 'setLight' }; function addSource(sourceId, after, commands) { commands.push({ command: operations.addSource, args: [ sourceId, after[sourceId] ] }); } function removeSource(sourceId, commands, sourcesRemoved) { commands.push({ command: operations.removeSource, args: [sourceId] }); sourcesRemoved[sourceId] = true; } function updateSource(sourceId, after, commands, sourcesRemoved) { removeSource(sourceId, commands, sourcesRemoved); addSource(sourceId, after, commands); } function canUpdateGeoJSON(before, after, sourceId) { var prop; for (prop in before[sourceId]) { if (!before[sourceId].hasOwnProperty(prop)) { continue; } if (prop !== 'data' && !performance.deepEqual(before[sourceId][prop], after[sourceId][prop])) { return false; } } for (prop in after[sourceId]) { if (!after[sourceId].hasOwnProperty(prop)) { continue; } if (prop !== 'data' && !performance.deepEqual(before[sourceId][prop], after[sourceId][prop])) { return false; } } return true; } function diffSources(before, after, commands, sourcesRemoved) { before = before || {}; after = after || {}; var sourceId; for (sourceId in before) { if (!before.hasOwnProperty(sourceId)) { continue; } if (!after.hasOwnProperty(sourceId)) { removeSource(sourceId, commands, sourcesRemoved); } } for (sourceId in after) { if (!after.hasOwnProperty(sourceId)) { continue; } if (!before.hasOwnProperty(sourceId)) { addSource(sourceId, after, commands); } else if (!performance.deepEqual(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 { updateSource(sourceId, after, commands, sourcesRemoved); } } } } function diffLayerPropertyChanges(before, after, commands, layerId, klass, command) { before = before || {}; after = after || {}; var prop; for (prop in before) { if (!before.hasOwnProperty(prop)) { continue; } if (!performance.deepEqual(before[prop], after[prop])) { commands.push({ command: command, args: [ layerId, prop, after[prop], klass ] }); } } for (prop in after) { if (!after.hasOwnProperty(prop) || before.hasOwnProperty(prop)) { continue; } if (!performance.deepEqual(before[prop], after[prop])) { commands.push({ command: command, args: [ layerId, prop, after[prop], klass ] }); } } } function pluckId(layer) { return layer.id; } function indexById(group, layer) { group[layer.id] = layer; return group; } function diffLayers(before, after, commands) { before = before || []; after = after || []; var beforeOrder = before.map(pluckId); var afterOrder = after.map(pluckId); var beforeIndex = before.reduce(indexById, {}); var afterIndex = after.reduce(indexById, {}); var tracker = beforeOrder.slice(); var clean = Object.create(null); var i, d, layerId, beforeLayer, afterLayer, insertBeforeLayerId, prop; for (i = 0, d = 0; i < beforeOrder.length; i++) { layerId = beforeOrder[i]; if (!afterIndex.hasOwnProperty(layerId)) { commands.push({ command: operations.removeLayer, args: [layerId] }); tracker.splice(tracker.indexOf(layerId, d), 1); } else { d++; } } for (i = 0, d = 0; i < afterOrder.length; i++) { layerId = afterOrder[afterOrder.length - 1 - i]; if (tracker[tracker.length - 1 - i] === layerId) { continue; } if (beforeIndex.hasOwnProperty(layerId)) { commands.push({ command: operations.removeLayer, args: [layerId] }); tracker.splice(tracker.lastIndexOf(layerId, tracker.length - d), 1); } else { d++; } insertBeforeLayerId = tracker[tracker.length - i]; commands.push({ command: operations.addLayer, args: [ afterIndex[layerId], insertBeforeLayerId ] }); tracker.splice(tracker.length - i, 0, layerId); clean[layerId] = true; } for (i = 0; i < afterOrder.length; i++) { layerId = afterOrder[i]; beforeLayer = beforeIndex[layerId]; afterLayer = afterIndex[layerId]; if (clean[layerId] || performance.deepEqual(beforeLayer, afterLayer)) { continue; } if (!performance.deepEqual(beforeLayer.source, afterLayer.source) || !performance.deepEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !performance.deepEqual(beforeLayer.type, afterLayer.type)) { commands.push({ command: operations.removeLayer, args: [layerId] }); insertBeforeLayerId = tracker[tracker.lastIndexOf(layerId) + 1]; commands.push({ command: operations.addLayer, args: [ afterLayer, insertBeforeLayerId ] }); continue; } diffLayerPropertyChanges(beforeLayer.layout, afterLayer.layout, commands, layerId, null, operations.setLayoutProperty); diffLayerPropertyChanges(beforeLayer.paint, afterLayer.paint, commands, layerId, null, operations.setPaintProperty); if (!performance.deepEqual(beforeLayer.filter, afterLayer.filter)) { commands.push({ command: operations.setFilter, args: [ layerId, afterLayer.filter ] }); } if (!performance.deepEqual(beforeLayer.minzoom, afterLayer.minzoom) || !performance.deepEqual(beforeLayer.maxzoom, afterLayer.maxzoom)) { commands.push({ command: operations.setLayerZoomRange, args: [ layerId, afterLayer.minzoom, afterLayer.maxzoom ] }); } for (prop in beforeLayer) { if (!beforeLayer.hasOwnProperty(prop)) { continue; } if (prop === 'layout' || prop === 'paint' || prop === 'filter' || prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom') { continue; } if (prop.indexOf('paint.') === 0) { diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), operations.setPaintProperty); } else if (!performance.deepEqual(beforeLayer[prop], afterLayer[prop])) { commands.push({ command: operations.setLayerProperty, args: [ layerId, prop, afterLayer[prop] ] }); } } for (prop in afterLayer) { if (!afterLayer.hasOwnProperty(prop) || beforeLayer.hasOwnProperty(prop)) { continue; } if (prop === 'layout' || prop === 'paint' || prop === 'filter' || prop === 'metadata' || prop === 'minzoom' || prop === 'maxzoom') { continue; } if (prop.indexOf('paint.') === 0) { diffLayerPropertyChanges(beforeLayer[prop], afterLayer[prop], commands, layerId, prop.slice(6), operations.setPaintProperty); } else if (!performance.deepEqual(beforeLayer[prop], afterLayer[prop])) { commands.push({ command: operations.setLayerProperty, args: [ layerId, prop, afterLayer[prop] ] }); } } } } function diffStyles(before, after) { if (!before) { return [{ command: operations.setStyle, args: [after] }]; } var commands = []; try { if (!performance.deepEqual(before.version, after.version)) { return [{ command: operations.setStyle, args: [after] }]; } if (!performance.deepEqual(before.center, after.center)) { commands.push({ command: operations.setCenter, args: [after.center] }); } if (!performance.deepEqual(before.zoom, after.zoom)) { commands.push({ command: operations.setZoom, args: [after.zoom] }); } if (!performance.deepEqual(before.bearing, after.bearing)) { commands.push({ command: operations.setBearing, args: [after.bearing] }); } if (!performance.deepEqual(before.pitch, after.pitch)) { commands.push({ command: operations.setPitch, args: [after.pitch] }); } if (!performance.deepEqual(before.sprite, after.sprite)) { commands.push({ command: operations.setSprite, args: [after.sprite] }); } if (!performance.deepEqual(before.glyphs, after.glyphs)) { commands.push({ command: operations.setGlyphs, args: [after.glyphs] }); } if (!performance.deepEqual(before.transition, after.transition)) { commands.push({ command: operations.setTransition, args: [after.transition] }); } if (!performance.deepEqual(before.light, after.light)) { commands.push({ command: operations.setLight, args: [after.light] }); } var sourcesRemoved = {}; var removeOrAddSourceCommands = []; diffSources(before.sources, after.sources, removeOrAddSourceCommands, sourcesRemoved); var beforeLayers = []; if (before.layers) { before.layers.forEach(function (layer) { if (sourcesRemoved[layer.source]) { commands.push({ command: operations.removeLayer, args: [layer.id] }); } else { beforeLayers.push(layer); } }); } commands = commands.concat(removeOrAddSourceCommands); diffLayers(beforeLayers, after.layers, commands); } catch (e) { console.warn('Unable to compute style diff:', e); commands = [{ command: operations.setStyle, args: [after] }]; } return commands; } var PathInterpolator = function PathInterpolator(points_, padding_) { this.reset(points_, padding_); }; PathInterpolator.prototype.reset = function reset(points_, padding_) { this.points = points_ || []; this._distances = [0]; for (var i = 1; i < this.points.length; i++) { this._distances[i] = this._distances[i - 1] + this.points[i].dist(this.points[i - 1]); } this.length = this._distances[this._distances.length - 1]; this.padding = Math.min(padding_ || 0, this.length * 0.5); this.paddedLength = this.length - this.padding * 2; }; PathInterpolator.prototype.lerp = function lerp(t) { if (this.points.length === 1) { return this.points[0]; } t = performance.clamp(t, 0, 1); var currentIndex = 1; var distOfCurrentIdx = this._distances[currentIndex]; var distToTarget = t * this.paddedLength + this.padding; while (distOfCurrentIdx < distToTarget && currentIndex < this._distances.length) { distOfCurrentIdx = this._distances[++currentIndex]; } var idxOfPrevPoint = currentIndex - 1; var distOfPrevIdx = this._distances[idxOfPrevPoint]; var segmentLength = distOfCurrentIdx - distOfPrevIdx; var segmentT = segmentLength > 0 ? (distToTarget - distOfPrevIdx) / segmentLength : 0; return this.points[idxOfPrevPoint].mult(1 - segmentT).add(this.points[currentIndex].mult(segmentT)); }; var GridIndex = function GridIndex(width, height, cellSize) { var boxCells = this.boxCells = []; var circleCells = this.circleCells = []; this.xCellCount = Math.ceil(width / cellSize); this.yCellCount = Math.ceil(height / cellSize); for (var i = 0; i < this.xCellCount * this.yCellCount; i++) { boxCells.push([]); circleCells.push([]); } this.circleKeys = []; this.boxKeys = []; this.bboxes = []; this.circles = []; this.width = width; this.height = height; this.xScale = this.xCellCount / width; this.yScale = this.yCellCount / height; this.boxUid = 0; this.circleUid = 0; }; GridIndex.prototype.keysLength = function keysLength() { return this.boxKeys.length + this.circleKeys.length; }; GridIndex.prototype.insert = function insert(key, x1, y1, x2, y2) { this._forEachCell(x1, y1, x2, y2, this._insertBoxCell, this.boxUid++); this.boxKeys.push(key); this.bboxes.push(x1); this.bboxes.push(y1); this.bboxes.push(x2); this.bboxes.push(y2); }; GridIndex.prototype.insertCircle = function insertCircle(key, x, y, radius) { this._forEachCell(x - radius, y - radius, x + radius, y + radius, this._insertCircleCell, this.circleUid++); this.circleKeys.push(key); this.circles.push(x); this.circles.push(y); this.circles.push(radius); }; GridIndex.prototype._insertBoxCell = function _insertBoxCell(x1, y1, x2, y2, cellIndex, uid) { this.boxCells[cellIndex].push(uid); }; GridIndex.prototype._insertCircleCell = function _insertCircleCell(x1, y1, x2, y2, cellIndex, uid) { this.circleCells[cellIndex].push(uid); }; GridIndex.prototype._query = function _query(x1, y1, x2, y2, hitTest, predicate) { if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) { return hitTest ? false : []; } var result = []; if (x1 <= 0 && y1 <= 0 && this.width <= x2 && this.height <= y2) { if (hitTest) { return true; } for (var boxUid = 0; boxUid < this.boxKeys.length; boxUid++) { result.push({ key: this.boxKeys[boxUid], x1: this.bboxes[boxUid * 4], y1: this.bboxes[boxUid * 4 + 1], x2: this.bboxes[boxUid * 4 + 2], y2: this.bboxes[boxUid * 4 + 3] }); } for (var circleUid = 0; circleUid < this.circleKeys.length; circleUid++) { var x = this.circles[circleUid * 3]; var y = this.circles[circleUid * 3 + 1]; var radius = this.circles[circleUid * 3 + 2]; result.push({ key: this.circleKeys[circleUid], x1: x - radius, y1: y - radius, x2: x + radius, y2: y + radius }); } return predicate ? result.filter(predicate) : result; } else { var queryArgs = { hitTest: hitTest, seenUids: { box: {}, circle: {} } }; this._forEachCell(x1, y1, x2, y2, this._queryCell, result, queryArgs, predicate); return hitTest ? result.length > 0 : result; } }; GridIndex.prototype._queryCircle = function _queryCircle(x, y, radius, hitTest, predicate) { var x1 = x - radius; var x2 = x + radius; var y1 = y - radius; var y2 = y + radius; if (x2 < 0 || x1 > this.width || y2 < 0 || y1 > this.height) { return hitTest ? false : []; } var result = []; var queryArgs = { hitTest: hitTest, circle: { x: x, y: y, radius: radius }, seenUids: { box: {}, circle: {} } }; this._forEachCell(x1, y1, x2, y2, this._queryCellCircle, result, queryArgs, predicate); return hitTest ? result.length > 0 : result; }; GridIndex.prototype.query = function query(x1, y1, x2, y2, predicate) { return this._query(x1, y1, x2, y2, false, predicate); }; GridIndex.prototype.hitTest = function hitTest(x1, y1, x2, y2, predicate) { return this._query(x1, y1, x2, y2, true, predicate); }; GridIndex.prototype.hitTestCircle = function hitTestCircle(x, y, radius, predicate) { return this._queryCircle(x, y, radius, true, predicate); }; GridIndex.prototype._queryCell = function _queryCell(x1, y1, x2, y2, cellIndex, result, queryArgs, predicate) { var seenUids = queryArgs.seenUids; var boxCell = this.boxCells[cellIndex]; if (boxCell !== null) { var bboxes = this.bboxes; for (var i = 0, list = boxCell; i < list.length; i += 1) { var boxUid = list[i]; if (!seenUids.box[boxUid]) { seenUids.box[boxUid] = true; var offset = boxUid * 4; if (x1 <= bboxes[offset + 2] && y1 <= bboxes[offset + 3] && x2 >= bboxes[offset + 0] && y2 >= bboxes[offset + 1] && (!predicate || predicate(this.boxKeys[boxUid]))) { if (queryArgs.hitTest) { result.push(true); return true; } else { result.push({ key: this.boxKeys[boxUid], x1: bboxes[offset], y1: bboxes[offset + 1], x2: bboxes[offset + 2], y2: bboxes[offset + 3] }); } } } } } var circleCell = this.circleCells[cellIndex]; if (circleCell !== null) { var circles = this.circles; for (var i$1 = 0, list$1 = circleCell; i$1 < list$1.length; i$1 += 1) { var circleUid = list$1[i$1]; if (!seenUids.circle[circleUid]) { seenUids.circle[circleUid] = true; var offset$1 = circleUid * 3; if (this._circleAndRectCollide(circles[offset$1], circles[offset$1 + 1], circles[offset$1 + 2], x1, y1, x2, y2) && (!predicate || predicate(this.circleKeys[circleUid]))) { if (queryArgs.hitTest) { result.push(true); return true; } else { var x = circles[offset$1]; var y = circles[offset$1 + 1]; var radius = circles[offset$1 + 2]; result.push({ key: this.circleKeys[circleUid], x1: x - radius, y1: y - radius, x2: x + radius, y2: y + radius }); } } } } } }; GridIndex.prototype._queryCellCircle = function _queryCellCircle(x1, y1, x2, y2, cellIndex, result, queryArgs, predicate) { var circle = queryArgs.circle; var seenUids = queryArgs.seenUids; var boxCell = this.boxCells[cellIndex]; if (boxCell !== null) { var bboxes = this.bboxes; for (var i = 0, list = boxCell; i < list.length; i += 1) { var boxUid = list[i]; if (!seenUids.box[boxUid]) { seenUids.box[boxUid] = true; var offset = boxUid * 4; if (this._circleAndRectCollide(circle.x, circle.y, circle.radius, bboxes[offset + 0], bboxes[offset + 1], bboxes[offset + 2], bboxes[offset + 3]) && (!predicate || predicate(this.boxKeys[boxUid]))) { result.push(true); return true; } } } } var circleCell = this.circleCells[cellIndex]; if (circleCell !== null) { var circles = this.circles; for (var i$1 = 0, list$1 = circleCell; i$1 < list$1.length; i$1 += 1) { var circleUid = list$1[i$1]; if (!seenUids.circle[circleUid]) { seenUids.circle[circleUid] = true; var offset$1 = circleUid * 3; if (this._circlesCollide(circles[offset$1], circles[offset$1 + 1], circles[offset$1 + 2], circle.x, circle.y, circle.radius) && (!predicate || predicate(this.circleKeys[circleUid]))) { result.push(true); return true; } } } } }; GridIndex.prototype._forEachCell = function _forEachCell(x1, y1, x2, y2, fn, arg1, arg2, predicate) { var cx1 = this._convertToXCellCoord(x1); var cy1 = this._convertToYCellCoord(y1); var cx2 = this._convertToXCellCoord(x2); var cy2 = this._convertToYCellCoord(y2); for (var x = cx1; x <= cx2; x++) { for (var y = cy1; y <= cy2; y++) { var cellIndex = this.xCellCount * y + x; if (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2, predicate)) { return; } } } }; GridIndex.prototype._convertToXCellCoord = function _convertToXCellCoord(x) { return Math.max(0, Math.min(this.xCellCount - 1, Math.floor(x * this.xScale))); }; GridIndex.prototype._convertToYCellCoord = function _convertToYCellCoord(y) { return Math.max(0, Math.min(this.yCellCount - 1, Math.floor(y * this.yScale))); }; GridIndex.prototype._circlesCollide = function _circlesCollide(x1, y1, r1, x2, y2, r2) { var dx = x2 - x1; var dy = y2 - y1; var bothRadii = r1 + r2; return bothRadii * bothRadii > dx * dx + dy * dy; }; GridIndex.prototype._circleAndRectCollide = function _circleAndRectCollide(circleX, circleY, radius, x1, y1, x2, y2) { var halfRectWidth = (x2 - x1) / 2; var distX = Math.abs(circleX - (x1 + halfRectWidth)); if (distX > halfRectWidth + radius) { return false; } var halfRectHeight = (y2 - y1) / 2; var distY = Math.abs(circleY - (y1 + halfRectHeight)); if (distY > halfRectHeight + radius) { return false; } if (distX <= halfRectWidth || distY <= halfRectHeight) { return true; } var dx = distX - halfRectWidth; var dy = distY - halfRectHeight; return dx * dx + dy * dy <= radius * radius; }; function getLabelPlaneMatrix(posMatrix, pitchWithMap, rotateWithMap, transform, pixelsToTileUnits) { var m = performance.create(); if (pitchWithMap) { performance.scale(m, m, [ 1 / pixelsToTileUnits, 1 / pixelsToTileUnits, 1 ]); if (!rotateWithMap) { performance.rotateZ(m, m, transform.angle); } } else { performance.multiply(m, transform.labelPlaneMatrix, posMatrix); } return m; } function getGlCoordMatrix(posMatrix, pitchWithMap, rotateWithMap, transform, pixelsToTileUnits) { if (pitchWithMap) { var m = performance.clone(posMatrix); performance.scale(m, m, [ pixelsToTileUnits, pixelsToTileUnits, 1 ]); if (!rotateWithMap) { performance.rotateZ(m, m, -transform.angle); } return m; } else { return transform.glCoordMatrix; } } function project(point, matrix) { var pos = [ point.x, point.y, 0, 1 ]; xyTransformMat4(pos, pos, matrix); var w = pos[3]; return { point: new performance.Point(pos[0] / w, pos[1] / w), signedDistanceFromCamera: w }; } function getPerspectiveRatio(cameraToCenterDistance, signedDistanceFromCamera) { return 0.5 + 0.5 * (cameraToCenterDistance / signedDistanceFromCamera); } function isVisible(anchorPos, clippingBuffer) { var x = anchorPos[0] / anchorPos[3]; var y = anchorPos[1] / anchorPos[3]; var inPaddedViewport = x >= -clippingBuffer[0] && x <= clippingBuffer[0] && y >= -clippingBuffer[1] && y <= clippingBuffer[1]; return inPaddedViewport; } function updateLineLabels(bucket, posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright) { var sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; var partiallyEvaluatedSize = performance.evaluateSizeForZoom(sizeData, painter.transform.zoom); var clippingBuffer = [ 256 / painter.width * 2 + 1, 256 / painter.height * 2 + 1 ]; var dynamicLayoutVertexArray = isText ? bucket.text.dynamicLayoutVertexArray : bucket.icon.dynamicLayoutVertexArray; dynamicLayoutVertexArray.clear(); var lineVertexArray = bucket.lineVertexArray; var placedSymbols = isText ? bucket.text.placedSymbolArray : bucket.icon.placedSymbolArray; var aspectRatio = painter.transform.width / painter.transform.height; var useVertical = false; for (var s = 0; s < placedSymbols.length; s++) { var symbol = placedSymbols.get(s); if (symbol.hidden || symbol.writingMode === performance.WritingMode.vertical && !useVertical) { hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); continue; } useVertical = false; var anchorPos = [ symbol.anchorX, symbol.anchorY, 0, 1 ]; performance.transformMat4(anchorPos, anchorPos, posMatrix); if (!isVisible(anchorPos, clippingBuffer)) { hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); continue; } var cameraToAnchorDistance = anchorPos[3]; var perspectiveRatio = getPerspectiveRatio(painter.transform.cameraToCenterDistance, cameraToAnchorDistance); var fontSize = performance.evaluateSizeForFeature(sizeData, partiallyEvaluatedSize, symbol); var pitchScaledFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio; var tileAnchorPoint = new performance.Point(symbol.anchorX, symbol.anchorY); var anchorPoint = project(tileAnchorPoint, labelPlaneMatrix).point; var projectionCache = {}; var placeUnflipped = placeGlyphsAlongLine(symbol, pitchScaledFontSize, false, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio); useVertical = placeUnflipped.useVertical; if (placeUnflipped.notEnoughRoom || useVertical || placeUnflipped.needsFlipping && placeGlyphsAlongLine(symbol, pitchScaledFontSize, true, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, bucket.glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio).notEnoughRoom) { hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); } } if (isText) { bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray); } else { bucket.icon.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray); } } function placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache) { var glyphEndIndex = symbol.glyphStartIndex + symbol.numGlyphs; var lineStartIndex = symbol.lineStartIndex; var lineEndIndex = symbol.lineStartIndex + symbol.lineLength; var firstGlyphOffset = glyphOffsetArray.getoffsetX(symbol.glyphStartIndex); var lastGlyphOffset = glyphOffsetArray.getoffsetX(glyphEndIndex - 1); var firstPlacedGlyph = placeGlyphAlongLine(fontScale * firstGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache); if (!firstPlacedGlyph) { return null; } var lastPlacedGlyph = placeGlyphAlongLine(fontScale * lastGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache); if (!lastPlacedGlyph) { return null; } return { first: firstPlacedGlyph, last: lastPlacedGlyph }; } function requiresOrientationChange(writingMode, firstPoint, lastPoint, aspectRatio) { if (writingMode === performance.WritingMode.horizontal) { var rise = Math.abs(lastPoint.y - firstPoint.y); var run = Math.abs(lastPoint.x - firstPoint.x) * aspectRatio; if (rise > run) { return { useVertical: true }; } } if (writingMode === performance.WritingMode.vertical ? firstPoint.y < lastPoint.y : firstPoint.x > lastPoint.x) { return { needsFlipping: true }; } return null; } function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio) { var fontScale = fontSize / 24; var lineOffsetX = symbol.lineOffsetX * fontScale; var lineOffsetY = symbol.lineOffsetY * fontScale; var placedGlyphs; if (symbol.numGlyphs > 1) { var glyphEndIndex = symbol.glyphStartIndex + symbol.numGlyphs; var lineStartIndex = symbol.lineStartIndex; var lineEndIndex = symbol.lineStartIndex + symbol.lineLength; var firstAndLastGlyph = placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache); if (!firstAndLastGlyph) { return { notEnoughRoom: true }; } var firstPoint = project(firstAndLastGlyph.first.point, glCoordMatrix).point; var lastPoint = project(firstAndLastGlyph.last.point, glCoordMatrix).point; if (keepUpright && !flip) { var orientationChange = requiresOrientationChange(symbol.writingMode, firstPoint, lastPoint, aspectRatio); if (orientationChange) { return orientationChange; } } placedGlyphs = [firstAndLastGlyph.first]; for (var glyphIndex = symbol.glyphStartIndex + 1; glyphIndex < glyphEndIndex - 1; glyphIndex++) { placedGlyphs.push(placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(glyphIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache)); } placedGlyphs.push(firstAndLastGlyph.last); } else { if (keepUpright && !flip) { var a = project(tileAnchorPoint, posMatrix).point; var tileVertexIndex = symbol.lineStartIndex + symbol.segment + 1; var tileSegmentEnd = new performance.Point(lineVertexArray.getx(tileVertexIndex), lineVertexArray.gety(tileVertexIndex)); var projectedVertex = project(tileSegmentEnd, posMatrix); var b = projectedVertex.signedDistanceFromCamera > 0 ? projectedVertex.point : projectTruncatedLineSegment(tileAnchorPoint, tileSegmentEnd, a, 1, posMatrix); var orientationChange$1 = requiresOrientationChange(symbol.writingMode, a, b, aspectRatio); if (orientationChange$1) { return orientationChange$1; } } var singleGlyph = placeGlyphAlongLine(fontScale * glyphOffsetArray.getoffsetX(symbol.glyphStartIndex), lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, symbol.lineStartIndex, symbol.lineStartIndex + symbol.lineLength, lineVertexArray, labelPlaneMatrix, projectionCache); if (!singleGlyph) { return { notEnoughRoom: true }; } placedGlyphs = [singleGlyph]; } for (var i = 0, list = placedGlyphs; i < list.length; i += 1) { var glyph = list[i]; performance.addDynamicAttributes(dynamicLayoutVertexArray, glyph.point, glyph.angle); } return {}; } function projectTruncatedLineSegment(previousTilePoint, currentTilePoint, previousProjectedPoint, minimumLength, projectionMatrix) { var projectedUnitVertex = project(previousTilePoint.add(previousTilePoint.sub(currentTilePoint)._unit()), projectionMatrix).point; var projectedUnitSegment = previousProjectedPoint.sub(projectedUnitVertex); return previousProjectedPoint.add(projectedUnitSegment._mult(minimumLength / projectedUnitSegment.mag())); } function placeGlyphAlongLine(offsetX, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, anchorSegment, lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache) { var combinedOffsetX = flip ? offsetX - lineOffsetX : offsetX + lineOffsetX; var dir = combinedOffsetX > 0 ? 1 : -1; var angle = 0; if (flip) { dir *= -1; angle = Math.PI; } if (dir < 0) { angle += Math.PI; } var currentIndex = dir > 0 ? lineStartIndex + anchorSegment : lineStartIndex + anchorSegment + 1; var current = anchorPoint; var prev = anchorPoint; var distanceToPrev = 0; var currentSegmentDistance = 0; var absOffsetX = Math.abs(combinedOffsetX); var pathVertices = []; while (distanceToPrev + currentSegmentDistance <= absOffsetX) { currentIndex += dir; if (currentIndex < lineStartIndex || currentIndex >= lineEndIndex) { return null; } prev = current; pathVertices.push(current); current = projectionCache[currentIndex]; if (current === undefined) { var currentVertex = new performance.Point(lineVertexArray.getx(currentIndex), lineVertexArray.gety(currentIndex)); var projection = project(currentVertex, labelPlaneMatrix); if (projection.signedDistanceFromCamera > 0) { current = projectionCache[currentIndex] = projection.point; } else { var previousLineVertexIndex = currentIndex - dir; var previousTilePoint = distanceToPrev === 0 ? tileAnchorPoint : new performance.Point(lineVertexArray.getx(previousLineVertexIndex), lineVertexArray.gety(previousLineVertexIndex)); current = projectTruncatedLineSegment(previousTilePoint, currentVertex, prev, absOffsetX - distanceToPrev + 1, labelPlaneMatrix); } } distanceToPrev += currentSegmentDistance; currentSegmentDistance = prev.dist(current); } var segmentInterpolationT = (absOffsetX - distanceToPrev) / currentSegmentDistance; var prevToCurrent = current.sub(prev); var p = prevToCurrent.mult(segmentInterpolationT)._add(prev); p._add(prevToCurrent._unit()._perp()._mult(lineOffsetY * dir)); var segmentAngle = angle + Math.atan2(current.y - prev.y, current.x - prev.x); pathVertices.push(p); return { point: p, angle: segmentAngle, path: pathVertices }; } var hiddenGlyphAttributes = new Float32Array([ -Infinity, -Infinity, 0, -Infinity, -Infinity, 0, -Infinity, -Infinity, 0, -Infinity, -Infinity, 0 ]); function hideGlyphs(num, dynamicLayoutVertexArray) { for (var i = 0; i < num; i++) { var offset = dynamicLayoutVertexArray.length; dynamicLayoutVertexArray.resize(offset + 4); dynamicLayoutVertexArray.float32.set(hiddenGlyphAttributes, offset * 3); } } function xyTransformMat4(out, a, m) { var x = a[0], y = a[1]; out[0] = m[0] * x + m[4] * y + m[12]; out[1] = m[1] * x + m[5] * y + m[13]; out[3] = m[3] * x + m[7] * y + m[15]; return out; } var viewportPadding = 100; var CollisionIndex = function CollisionIndex(transform, grid, ignoredGrid) { if (grid === void 0) grid = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25); if (ignoredGrid === void 0) ignoredGrid = new GridIndex(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25); this.transform = transform; this.grid = grid; this.ignoredGrid = ignoredGrid; this.pitchfactor = Math.cos(transform._pitch) * transform.cameraToCenterDistance; this.screenRightBoundary = transform.width + viewportPadding; this.screenBottomBoundary = transform.height + viewportPadding; this.gridRightBoundary = transform.width + 2 * viewportPadding; this.gridBottomBoundary = transform.height + 2 * viewportPadding; }; CollisionIndex.prototype.placeCollisionBox = function placeCollisionBox(collisionBox, allowOverlap, textPixelRatio, posMatrix, collisionGroupPredicate) { var projectedPoint = this.projectAndGetPerspectiveRatio(posMatrix, collisionBox.anchorPointX, collisionBox.anchorPointY); var tileToViewport = textPixelRatio * projectedPoint.perspectiveRatio; var tlX = collisionBox.x1 * tileToViewport + projectedPoint.point.x; var tlY = collisionBox.y1 * tileToViewport + projectedPoint.point.y; var brX = collisionBox.x2 * tileToViewport + projectedPoint.point.x; var brY = collisionBox.y2 * tileToViewport + projectedPoint.point.y; if (!this.isInsideGrid(tlX, tlY, brX, brY) || !allowOverlap && this.grid.hitTest(tlX, tlY, brX, brY, collisionGroupPredicate)) { return { box: [], offscreen: false }; } return { box: [ tlX, tlY, brX, brY ], offscreen: this.isOffscreen(tlX, tlY, brX, brY) }; }; CollisionIndex.prototype.placeCollisionCircles = function placeCollisionCircles(allowOverlap, symbol, lineVertexArray, glyphOffsetArray, fontSize, posMatrix, labelPlaneMatrix, labelToScreenMatrix, showCollisionCircles, pitchWithMap, collisionGroupPredicate, circlePixelDiameter, textPixelPadding) { var placedCollisionCircles = []; var tileUnitAnchorPoint = new performance.Point(symbol.anchorX, symbol.anchorY); var screenAnchorPoint = project(tileUnitAnchorPoint, posMatrix); var perspectiveRatio = getPerspectiveRatio(this.transform.cameraToCenterDistance, screenAnchorPoint.signedDistanceFromCamera); var labelPlaneFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio; var labelPlaneFontScale = labelPlaneFontSize / performance.ONE_EM; var labelPlaneAnchorPoint = project(tileUnitAnchorPoint, labelPlaneMatrix).point; var projectionCache = {}; var lineOffsetX = symbol.lineOffsetX * labelPlaneFontScale; var lineOffsetY = symbol.lineOffsetY * labelPlaneFontScale; var firstAndLastGlyph = placeFirstAndLastGlyph(labelPlaneFontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, false, labelPlaneAnchorPoint, tileUnitAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache); var collisionDetected = false; var inGrid = false; var entirelyOffscreen = true; if (firstAndLastGlyph) { var radius = circlePixelDiameter * 0.5 * perspectiveRatio + textPixelPadding; var screenPlaneMin = new performance.Point(-viewportPadding, -viewportPadding); var screenPlaneMax = new performance.Point(this.screenRightBoundary, this.screenBottomBoundary); var interpolator = new PathInterpolator(); var first = firstAndLastGlyph.first; var last = firstAndLastGlyph.last; var projectedPath = []; for (var i = first.path.length - 1; i >= 1; i--) { projectedPath.push(first.path[i]); } for (var i$1 = 1; i$1 < last.path.length; i$1++) { projectedPath.push(last.path[i$1]); } var circleDist = radius * 2.5; if (labelToScreenMatrix) { var screenSpacePath = projectedPath.map(function (p) { return project(p, labelToScreenMatrix); }); if (screenSpacePath.some(function (point) { return point.signedDistanceFromCamera <= 0; })) { projectedPath = []; } else { projectedPath = screenSpacePath.map(function (p) { return p.point; }); } } var segments = []; if (projectedPath.length > 0) { var minPoint = projectedPath[0].clone(); var maxPoint = projectedPath[0].clone(); for (var i$2 = 1; i$2 < projectedPath.length; i$2++) { minPoint.x = Math.min(minPoint.x, projectedPath[i$2].x); minPoint.y = Math.min(minPoint.y, projectedPath[i$2].y); maxPoint.x = Math.max(maxPoint.x, projectedPath[i$2].x); maxPoint.y = Math.max(maxPoint.y, projectedPath[i$2].y); } if (minPoint.x >= screenPlaneMin.x && maxPoint.x <= screenPlaneMax.x && minPoint.y >= screenPlaneMin.y && maxPoint.y <= screenPlaneMax.y) { segments = [projectedPath]; } else if (maxPoint.x < screenPlaneMin.x || minPoint.x > screenPlaneMax.x || maxPoint.y < screenPlaneMin.y || minPoint.y > screenPlaneMax.y) { segments = []; } else { segments = performance.clipLine([projectedPath], screenPlaneMin.x, screenPlaneMin.y, screenPlaneMax.x, screenPlaneMax.y); } } for (var i$4 = 0, list = segments; i$4 < list.length; i$4 += 1) { var seg = list[i$4]; interpolator.reset(seg, radius * 0.25); var numCircles = 0; if (interpolator.length <= 0.5 * radius) { numCircles = 1; } else { numCircles = Math.ceil(interpolator.paddedLength / circleDist) + 1; } for (var i$3 = 0; i$3 < numCircles; i$3++) { var t = i$3 / Math.max(numCircles - 1, 1); var circlePosition = interpolator.lerp(t); var centerX = circlePosition.x + viewportPadding; var centerY = circlePosition.y + viewportPadding; placedCollisionCircles.push(centerX, centerY, radius, 0); var x1 = centerX - radius; var y1 = centerY - radius; var x2 = centerX + radius; var y2 = centerY + radius; entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2); inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2); if (!allowOverlap) { if (this.grid.hitTestCircle(centerX, centerY, radius, collisionGroupPredicate)) { collisionDetected = true; if (!showCollisionCircles) { return { circles: [], offscreen: false, collisionDetected: collisionDetected }; } } } } } } return { circles: !showCollisionCircles && collisionDetected || !inGrid ? [] : placedCollisionCircles, offscreen: entirelyOffscreen, collisionDetected: collisionDetected }; }; CollisionIndex.prototype.queryRenderedSymbols = function queryRenderedSymbols(viewportQueryGeometry) { if (viewportQueryGeometry.length === 0 || this.grid.keysLength() === 0 && this.ignoredGrid.keysLength() === 0) { return {}; } var query = []; var minX = Infinity; var minY = Infinity; var maxX = -Infinity; var maxY = -Infinity; for (var i = 0, list = viewportQueryGeometry; i < list.length; i += 1) { var point = list[i]; var gridPoint = new performance.Point(point.x + viewportPadding, point.y + viewportPadding); minX = Math.min(minX, gridPoint.x); minY = Math.min(minY, gridPoint.y); maxX = Math.max(maxX, gridPoint.x); maxY = Math.max(maxY, gridPoint.y); query.push(gridPoint); } var features = this.grid.query(minX, minY, maxX, maxY).concat(this.ignoredGrid.query(minX, minY, maxX, maxY)); var seenFeatures = {}; var result = {}; for (var i$1 = 0, list$1 = features; i$1 < list$1.length; i$1 += 1) { var feature = list$1[i$1]; var featureKey = feature.key; if (seenFeatures[featureKey.bucketInstanceId] === undefined) { seenFeatures[featureKey.bucketInstanceId] = {}; } if (seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex]) { continue; } var bbox = [ new performance.Point(feature.x1, feature.y1), new performance.Point(feature.x2, feature.y1), new performance.Point(feature.x2, feature.y2), new performance.Point(feature.x1, feature.y2) ]; if (!performance.polygonIntersectsPolygon(query, bbox)) { continue; } seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex] = true; if (result[featureKey.bucketInstanceId] === undefined) { result[featureKey.bucketInstanceId] = []; } result[featureKey.bucketInstanceId].push(featureKey.featureIndex); } return result; }; CollisionIndex.prototype.insertCollisionBox = function insertCollisionBox(collisionBox, ignorePlacement, bucketInstanceId, featureIndex, collisionGroupID) { var grid = ignorePlacement ? this.ignoredGrid : this.grid; var key = { bucketInstanceId: bucketInstanceId, featureIndex: featureIndex, collisionGroupID: collisionGroupID }; grid.insert(key, collisionBox[0], collisionBox[1], collisionBox[2], collisionBox[3]); }; CollisionIndex.prototype.insertCollisionCircles = function insertCollisionCircles(collisionCircles, ignorePlacement, bucketInstanceId, featureIndex, collisionGroupID) { var grid = ignorePlacement ? this.ignoredGrid : this.grid; var key = { bucketInstanceId: bucketInstanceId, featureIndex: featureIndex, collisionGroupID: collisionGroupID }; for (var k = 0; k < collisionCircles.length; k += 4) { grid.insertCircle(key, collisionCircles[k], collisionCircles[k + 1], collisionCircles[k + 2]); } }; CollisionIndex.prototype.projectAndGetPerspectiveRatio = function projectAndGetPerspectiveRatio(posMatrix, x, y) { var p = [ x, y, 0, 1 ]; xyTransformMat4(p, p, posMatrix); var a = new performance.Point((p[0] / p[3] + 1) / 2 * this.transform.width + viewportPadding, (-p[1] / p[3] + 1) / 2 * this.transform.height + viewportPadding); return { point: a, perspectiveRatio: 0.5 + 0.5 * (this.transform.cameraToCenterDistance / p[3]) }; }; CollisionIndex.prototype.isOffscreen = function isOffscreen(x1, y1, x2, y2) { return x2 < viewportPadding || x1 >= this.screenRightBoundary || y2 < viewportPadding || y1 > this.screenBottomBoundary; }; CollisionIndex.prototype.isInsideGrid = function isInsideGrid(x1, y1, x2, y2) { return x2 >= 0 && x1 < this.gridRightBoundary && y2 >= 0 && y1 < this.gridBottomBoundary; }; CollisionIndex.prototype.getViewportMatrix = function getViewportMatrix() { var m = performance.identity([]); performance.translate(m, m, [ -viewportPadding, -viewportPadding, 0 ]); return m; }; function pixelsToTileUnits (tile, pixelValue, z) { return pixelValue * (performance.EXTENT / (tile.tileSize * Math.pow(2, z - tile.tileID.overscaledZ))); } var OpacityState = function OpacityState(prevState, increment, placed, skipFade) { if (prevState) { this.opacity = Math.max(0, Math.min(1, prevState.opacity + (prevState.placed ? increment : -increment))); } else { this.opacity = skipFade && placed ? 1 : 0; } this.placed = placed; }; OpacityState.prototype.isHidden = function isHidden() { return this.opacity === 0 && !this.placed; }; var JointOpacityState = function JointOpacityState(prevState, increment, placedText, placedIcon, skipFade) { this.text = new OpacityState(prevState ? prevState.text : null, increment, placedText, skipFade); this.icon = new OpacityState(prevState ? prevState.icon : null, increment, placedIcon, skipFade); }; JointOpacityState.prototype.isHidden = function isHidden() { return this.text.isHidden() && this.icon.isHidden(); }; var JointPlacement = function JointPlacement(text, icon, skipFade) { this.text = text; this.icon = icon; this.skipFade = skipFade; }; var CollisionCircleArray = function CollisionCircleArray() { this.invProjMatrix = performance.create(); this.viewportMatrix = performance.create(); this.circles = []; }; var RetainedQueryData = function RetainedQueryData(bucketInstanceId, featureIndex, sourceLayerIndex, bucketIndex, tileID) { this.bucketInstanceId = bucketInstanceId; this.featureIndex = featureIndex; this.sourceLayerIndex = sourceLayerIndex; this.bucketIndex = bucketIndex; this.tileID = tileID; }; var CollisionGroups = function CollisionGroups(crossSourceCollisions) { this.crossSourceCollisions = crossSourceCollisions; this.maxGroupID = 0; this.collisionGroups = {}; }; CollisionGroups.prototype.get = function get(sourceID) { if (!this.crossSourceCollisions) { if (!this.collisionGroups[sourceID]) { var nextGroupID = ++this.maxGroupID; this.collisionGroups[sourceID] = { ID: nextGroupID, predicate: function (key) { return key.collisionGroupID === nextGroupID; } }; } return this.collisionGroups[sourceID]; } else { return { ID: 0, predicate: null }; } }; function calculateVariableLayoutShift(anchor, width, height, textOffset, textBoxScale) { var ref = performance.getAnchorAlignment(anchor); var horizontalAlign = ref.horizontalAlign; var verticalAlign = ref.verticalAlign; var shiftX = -(horizontalAlign - 0.5) * width; var shiftY = -(verticalAlign - 0.5) * height; var offset = performance.evaluateVariableOffset(anchor, textOffset); return new performance.Point(shiftX + offset[0] * textBoxScale, shiftY + offset[1] * textBoxScale); } function shiftVariableCollisionBox(collisionBox, shiftX, shiftY, rotateWithMap, pitchWithMap, angle) { var x1 = collisionBox.x1; var x2 = collisionBox.x2; var y1 = collisionBox.y1; var y2 = collisionBox.y2; var anchorPointX = collisionBox.anchorPointX; var anchorPointY = collisionBox.anchorPointY; var rotatedOffset = new performance.Point(shiftX, shiftY); if (rotateWithMap) { rotatedOffset._rotate(pitchWithMap ? angle : -angle); } return { x1: x1 + rotatedOffset.x, y1: y1 + rotatedOffset.y, x2: x2 + rotatedOffset.x, y2: y2 + rotatedOffset.y, anchorPointX: anchorPointX, anchorPointY: anchorPointY }; } var Placement = function Placement(transform, fadeDuration, crossSourceCollisions, prevPlacement) { this.transform = transform.clone(); this.collisionIndex = new CollisionIndex(this.transform); this.placements = {}; this.opacities = {}; this.variableOffsets = {}; this.stale = false; this.commitTime = 0; this.fadeDuration = fadeDuration; this.retainedQueryData = {}; this.collisionGroups = new CollisionGroups(crossSourceCollisions); this.collisionCircleArrays = {}; this.prevPlacement = prevPlacement; if (prevPlacement) { prevPlacement.prevPlacement = undefined; } this.placedOrientations = {}; }; Placement.prototype.getBucketParts = function getBucketParts(results, styleLayer, tile, sortAcrossTiles) { var symbolBucket = tile.getBucket(styleLayer); var bucketFeatureIndex = tile.latestFeatureIndex; if (!symbolBucket || !bucketFeatureIndex || styleLayer.id !== symbolBucket.layerIds[0]) { return; } var collisionBoxArray = tile.collisionBoxArray; var layout = symbolBucket.layers[0].layout; var scale = Math.pow(2, this.transform.zoom - tile.tileID.overscaledZ); var textPixelRatio = tile.tileSize / performance.EXTENT; var posMatrix = this.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); var pitchWithMap = layout.get('text-pitch-alignment') === 'map'; var rotateWithMap = layout.get('text-rotation-alignment') === 'map'; var pixelsToTiles = pixelsToTileUnits(tile, 1, this.transform.zoom); var textLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, pitchWithMap, rotateWithMap, this.transform, pixelsToTiles); var labelToScreenMatrix = null; if (pitchWithMap) { var glMatrix = getGlCoordMatrix(posMatrix, pitchWithMap, rotateWithMap, this.transform, pixelsToTiles); labelToScreenMatrix = performance.multiply([], this.transform.labelPlaneMatrix, glMatrix); } this.retainedQueryData[symbolBucket.bucketInstanceId] = new RetainedQueryData(symbolBucket.bucketInstanceId, bucketFeatureIndex, symbolBucket.sourceLayerIndex, symbolBucket.index, tile.tileID); var parameters = { bucket: symbolBucket, layout: layout, posMatrix: posMatrix, textLabelPlaneMatrix: textLabelPlaneMatrix, labelToScreenMatrix: labelToScreenMatrix, scale: scale, textPixelRatio: textPixelRatio, holdingForFade: tile.holdingForFade(), collisionBoxArray: collisionBoxArray, partiallyEvaluatedTextSize: performance.evaluateSizeForZoom(symbolBucket.textSizeData, this.transform.zoom), collisionGroup: this.collisionGroups.get(symbolBucket.sourceID) }; if (sortAcrossTiles) { for (var i = 0, list = symbolBucket.sortKeyRanges; i < list.length; i += 1) { var range = list[i]; var sortKey = range.sortKey; var symbolInstanceStart = range.symbolInstanceStart; var symbolInstanceEnd = range.symbolInstanceEnd; results.push({ sortKey: sortKey, symbolInstanceStart: symbolInstanceStart, symbolInstanceEnd: symbolInstanceEnd, parameters: parameters }); } } else { results.push({ symbolInstanceStart: 0, symbolInstanceEnd: symbolBucket.symbolInstances.length, parameters: parameters }); } }; Placement.prototype.attemptAnchorPlacement = function attemptAnchorPlacement(anchor, textBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, textAllowOverlap, symbolInstance, bucket, orientation, iconBox) { var textOffset = [ symbolInstance.textOffset0, symbolInstance.textOffset1 ]; var shift = calculateVariableLayoutShift(anchor, width, height, textOffset, textBoxScale); var placedGlyphBoxes = this.collisionIndex.placeCollisionBox(shiftVariableCollisionBox(textBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); if (iconBox) { var placedIconBoxes = this.collisionIndex.placeCollisionBox(shiftVariableCollisionBox(iconBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); if (placedIconBoxes.box.length === 0) { return; } } if (placedGlyphBoxes.box.length > 0) { var prevAnchor; if (this.prevPlacement && this.prevPlacement.variableOffsets[symbolInstance.crossTileID] && this.prevPlacement.placements[symbolInstance.crossTileID] && this.prevPlacement.placements[symbolInstance.crossTileID].text) { prevAnchor = this.prevPlacement.variableOffsets[symbolInstance.crossTileID].anchor; } this.variableOffsets[symbolInstance.crossTileID] = { textOffset: textOffset, width: width, height: height, anchor: anchor, textBoxScale: textBoxScale, prevAnchor: prevAnchor }; this.markUsedJustification(bucket, anchor, symbolInstance, orientation); if (bucket.allowVerticalPlacement) { this.markUsedOrientation(bucket, orientation, symbolInstance); this.placedOrientations[symbolInstance.crossTileID] = orientation; } return { shift: shift, placedGlyphBoxes: placedGlyphBoxes }; } }; Placement.prototype.placeLayerBucketPart = function placeLayerBucketPart(bucketPart, seenCrossTileIDs, showCollisionBoxes) { var this$1 = this; var ref = bucketPart.parameters; var bucket = ref.bucket; var layout = ref.layout; var posMatrix = ref.posMatrix; var textLabelPlaneMatrix = ref.textLabelPlaneMatrix; var labelToScreenMatrix = ref.labelToScreenMatrix; var textPixelRatio = ref.textPixelRatio; var holdingForFade = ref.holdingForFade; var collisionBoxArray = ref.collisionBoxArray; var partiallyEvaluatedTextSize = ref.partiallyEvaluatedTextSize; var collisionGroup = ref.collisionGroup; var textOptional = layout.get('text-optional'); var iconOptional = layout.get('icon-optional'); var textAllowOverlap = layout.get('text-allow-overlap'); var iconAllowOverlap = layout.get('icon-allow-overlap'); var rotateWithMap = layout.get('text-rotation-alignment') === 'map'; var pitchWithMap = layout.get('text-pitch-alignment') === 'map'; var hasIconTextFit = layout.get('icon-text-fit') !== 'none'; var zOrderByViewportY = layout.get('symbol-z-order') === 'viewport-y'; var alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || iconOptional); var alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || textOptional); if (!bucket.collisionArrays && collisionBoxArray) { bucket.deserializeCollisionBoxes(collisionBoxArray); } var placeSymbol = function (symbolInstance, collisionArrays) { if (seenCrossTileIDs[symbolInstance.crossTileID]) { return; } if (holdingForFade) { this$1.placements[symbolInstance.crossTileID] = new JointPlacement(false, false, false); return; } var placeText = false; var placeIcon = false; var offscreen = true; var shift = null; var placed = { box: null, offscreen: null }; var placedVerticalText = { box: null, offscreen: null }; var placedGlyphBoxes = null; var placedGlyphCircles = null; var placedIconBoxes = null; var textFeatureIndex = 0; var verticalTextFeatureIndex = 0; var iconFeatureIndex = 0; if (collisionArrays.textFeatureIndex) { textFeatureIndex = collisionArrays.textFeatureIndex; } else if (symbolInstance.useRuntimeCollisionCircles) { textFeatureIndex = symbolInstance.featureIndex; } if (collisionArrays.verticalTextFeatureIndex) { verticalTextFeatureIndex = collisionArrays.verticalTextFeatureIndex; } var textBox = collisionArrays.textBox; if (textBox) { var updatePreviousOrientationIfNotPlaced = function (isPlaced) { var previousOrientation = performance.WritingMode.horizontal; if (bucket.allowVerticalPlacement && !isPlaced && this$1.prevPlacement) { var prevPlacedOrientation = this$1.prevPlacement.placedOrientations[symbolInstance.crossTileID]; if (prevPlacedOrientation) { this$1.placedOrientations[symbolInstance.crossTileID] = prevPlacedOrientation; previousOrientation = prevPlacedOrientation; this$1.markUsedOrientation(bucket, previousOrientation, symbolInstance); } } return previousOrientation; }; var placeTextForPlacementModes = function (placeHorizontalFn, placeVerticalFn) { if (bucket.allowVerticalPlacement && symbolInstance.numVerticalGlyphVertices > 0 && collisionArrays.verticalTextBox) { for (var i = 0, list = bucket.writingModes; i < list.length; i += 1) { var placementMode = list[i]; if (placementMode === performance.WritingMode.vertical) { placed = placeVerticalFn(); placedVerticalText = placed; } else { placed = placeHorizontalFn(); } if (placed && placed.box && placed.box.length) { break; } } } else { placed = placeHorizontalFn(); } }; if (!layout.get('text-variable-anchor')) { var placeBox = function (collisionTextBox, orientation) { var placedFeature = this$1.collisionIndex.placeCollisionBox(collisionTextBox, textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); if (placedFeature && placedFeature.box && placedFeature.box.length) { this$1.markUsedOrientation(bucket, orientation, symbolInstance); this$1.placedOrientations[symbolInstance.crossTileID] = orientation; } return placedFeature; }; var placeHorizontal = function () { return placeBox(textBox, performance.WritingMode.horizontal); }; var placeVertical = function () { var verticalTextBox = collisionArrays.verticalTextBox; if (bucket.allowVerticalPlacement && symbolInstance.numVerticalGlyphVertices > 0 && verticalTextBox) { return placeBox(verticalTextBox, performance.WritingMode.vertical); } return { box: null, offscreen: null }; }; placeTextForPlacementModes(placeHorizontal, placeVertical); updatePreviousOrientationIfNotPlaced(placed && placed.box && placed.box.length); } else { var anchors = layout.get('text-variable-anchor'); if (this$1.prevPlacement && this$1.prevPlacement.variableOffsets[symbolInstance.crossTileID]) { var prevOffsets = this$1.prevPlacement.variableOffsets[symbolInstance.crossTileID]; if (anchors.indexOf(prevOffsets.anchor) > 0) { anchors = anchors.filter(function (anchor) { return anchor !== prevOffsets.anchor; }); anchors.unshift(prevOffsets.anchor); } } var placeBoxForVariableAnchors = function (collisionTextBox, collisionIconBox, orientation) { var width = collisionTextBox.x2 - collisionTextBox.x1; var height = collisionTextBox.y2 - collisionTextBox.y1; var textBoxScale = symbolInstance.textBoxScale; var variableIconBox = hasIconTextFit && !iconAllowOverlap ? collisionIconBox : null; var placedBox = { box: [], offscreen: false }; var placementAttempts = textAllowOverlap ? anchors.length * 2 : anchors.length; for (var i = 0; i < placementAttempts; ++i) { var anchor = anchors[i % anchors.length]; var allowOverlap = i >= anchors.length; var result = this$1.attemptAnchorPlacement(anchor, collisionTextBox, width, height, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, allowOverlap, symbolInstance, bucket, orientation, variableIconBox); if (result) { placedBox = result.placedGlyphBoxes; if (placedBox && placedBox.box && placedBox.box.length) { placeText = true; shift = result.shift; break; } } } return placedBox; }; var placeHorizontal$1 = function () { return placeBoxForVariableAnchors(textBox, collisionArrays.iconBox, performance.WritingMode.horizontal); }; var placeVertical$1 = function () { var verticalTextBox = collisionArrays.verticalTextBox; var wasPlaced = placed && placed.box && placed.box.length; if (bucket.allowVerticalPlacement && !wasPlaced && symbolInstance.numVerticalGlyphVertices > 0 && verticalTextBox) { return placeBoxForVariableAnchors(verticalTextBox, collisionArrays.verticalIconBox, performance.WritingMode.vertical); } return { box: null, offscreen: null }; }; placeTextForPlacementModes(placeHorizontal$1, placeVertical$1); if (placed) { placeText = placed.box; offscreen = placed.offscreen; } var prevOrientation = updatePreviousOrientationIfNotPlaced(placed && placed.box); if (!placeText && this$1.prevPlacement) { var prevOffset = this$1.prevPlacement.variableOffsets[symbolInstance.crossTileID]; if (prevOffset) { this$1.variableOffsets[symbolInstance.crossTileID] = prevOffset; this$1.markUsedJustification(bucket, prevOffset.anchor, symbolInstance, prevOrientation); } } } } placedGlyphBoxes = placed; placeText = placedGlyphBoxes && placedGlyphBoxes.box && placedGlyphBoxes.box.length > 0; offscreen = placedGlyphBoxes && placedGlyphBoxes.offscreen; if (symbolInstance.useRuntimeCollisionCircles) { var placedSymbol = bucket.text.placedSymbolArray.get(symbolInstance.centerJustifiedTextSymbolIndex); var fontSize = performance.evaluateSizeForFeature(bucket.textSizeData, partiallyEvaluatedTextSize, placedSymbol); var textPixelPadding = layout.get('text-padding'); var circlePixelDiameter = symbolInstance.collisionCircleDiameter; placedGlyphCircles = this$1.collisionIndex.placeCollisionCircles(textAllowOverlap, placedSymbol, bucket.lineVertexArray, bucket.glyphOffsetArray, fontSize, posMatrix, textLabelPlaneMatrix, labelToScreenMatrix, showCollisionBoxes, pitchWithMap, collisionGroup.predicate, circlePixelDiameter, textPixelPadding); placeText = textAllowOverlap || placedGlyphCircles.circles.length > 0 && !placedGlyphCircles.collisionDetected; offscreen = offscreen && placedGlyphCircles.offscreen; } if (collisionArrays.iconFeatureIndex) { iconFeatureIndex = collisionArrays.iconFeatureIndex; } if (collisionArrays.iconBox) { var placeIconFeature = function (iconBox) { var shiftedIconBox = hasIconTextFit && shift ? shiftVariableCollisionBox(iconBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this$1.transform.angle) : iconBox; return this$1.collisionIndex.placeCollisionBox(shiftedIconBox, iconAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); }; if (placedVerticalText && placedVerticalText.box && placedVerticalText.box.length && collisionArrays.verticalIconBox) { placedIconBoxes = placeIconFeature(collisionArrays.verticalIconBox); placeIcon = placedIconBoxes.box.length > 0; } else { placedIconBoxes = placeIconFeature(collisionArrays.iconBox); placeIcon = placedIconBoxes.box.length > 0; } offscreen = offscreen && placedIconBoxes.offscreen; } var iconWithoutText = textOptional || symbolInstance.numHorizontalGlyphVertices === 0 && symbolInstance.numVerticalGlyphVertices === 0; var textWithoutIcon = iconOptional || symbolInstance.numIconVertices === 0; if (!iconWithoutText && !textWithoutIcon) { placeIcon = placeText = placeIcon && placeText; } else if (!textWithoutIcon) { placeText = placeIcon && placeText; } else if (!iconWithoutText) { placeIcon = placeIcon && placeText; } if (placeText && placedGlyphBoxes && placedGlyphBoxes.box) { if (placedVerticalText && placedVerticalText.box && verticalTextFeatureIndex) { this$1.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, layout.get('text-ignore-placement'), bucket.bucketInstanceId, verticalTextFeatureIndex, collisionGroup.ID); } else { this$1.collisionIndex.insertCollisionBox(placedGlyphBoxes.box, layout.get('text-ignore-placement'), bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID); } } if (placeIcon && placedIconBoxes) { this$1.collisionIndex.insertCollisionBox(placedIconBoxes.box, layout.get('icon-ignore-placement'), bucket.bucketInstanceId, iconFeatureIndex, collisionGroup.ID); } if (placedGlyphCircles) { if (placeText) { this$1.collisionIndex.insertCollisionCircles(placedGlyphCircles.circles, layout.get('text-ignore-placement'), bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID); } if (showCollisionBoxes) { var id = bucket.bucketInstanceId; var circleArray = this$1.collisionCircleArrays[id]; if (circleArray === undefined) { circleArray = this$1.collisionCircleArrays[id] = new CollisionCircleArray(); } for (var i = 0; i < placedGlyphCircles.circles.length; i += 4) { circleArray.circles.push(placedGlyphCircles.circles[i + 0]); circleArray.circles.push(placedGlyphCircles.circles[i + 1]); circleArray.circles.push(placedGlyphCircles.circles[i + 2]); circleArray.circles.push(placedGlyphCircles.collisionDetected ? 1 : 0); } } } this$1.placements[symbolInstance.crossTileID] = new JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded); seenCrossTileIDs[symbolInstance.crossTileID] = true; }; if (zOrderByViewportY) { var symbolIndexes = bucket.getSortedSymbolIndexes(this.transform.angle); for (var i = symbolIndexes.length - 1; i >= 0; --i) { var symbolIndex = symbolIndexes[i]; placeSymbol(bucket.symbolInstances.get(symbolIndex), bucket.collisionArrays[symbolIndex]); } } else { for (var i$1 = bucketPart.symbolInstanceStart; i$1 < bucketPart.symbolInstanceEnd; i$1++) { placeSymbol(bucket.symbolInstances.get(i$1), bucket.collisionArrays[i$1]); } } if (showCollisionBoxes && bucket.bucketInstanceId in this.collisionCircleArrays) { var circleArray = this.collisionCircleArrays[bucket.bucketInstanceId]; performance.invert(circleArray.invProjMatrix, posMatrix); circleArray.viewportMatrix = this.collisionIndex.getViewportMatrix(); } bucket.justReloaded = false; }; Placement.prototype.markUsedJustification = function markUsedJustification(bucket, placedAnchor, symbolInstance, orientation) { var justifications = { 'left': symbolInstance.leftJustifiedTextSymbolIndex, 'center': symbolInstance.centerJustifiedTextSymbolIndex, 'right': symbolInstance.rightJustifiedTextSymbolIndex }; var autoIndex; if (orientation === performance.WritingMode.vertical) { autoIndex = symbolInstance.verticalPlacedTextSymbolIndex; } else { autoIndex = justifications[performance.getAnchorJustification(placedAnchor)]; } var indexes = [ symbolInstance.leftJustifiedTextSymbolIndex, symbolInstance.centerJustifiedTextSymbolIndex, symbolInstance.rightJustifiedTextSymbolIndex, symbolInstance.verticalPlacedTextSymbolIndex ]; for (var i = 0, list = indexes; i < list.length; i += 1) { var index = list[i]; if (index >= 0) { if (autoIndex >= 0 && index !== autoIndex) { bucket.text.placedSymbolArray.get(index).crossTileID = 0; } else { bucket.text.placedSymbolArray.get(index).crossTileID = symbolInstance.crossTileID; } } } }; Placement.prototype.markUsedOrientation = function markUsedOrientation(bucket, orientation, symbolInstance) { var horizontal = orientation === performance.WritingMode.horizontal || orientation === performance.WritingMode.horizontalOnly ? orientation : 0; var vertical = orientation === performance.WritingMode.vertical ? orientation : 0; var horizontalIndexes = [ symbolInstance.leftJustifiedTextSymbolIndex, symbolInstance.centerJustifiedTextSymbolIndex, symbolInstance.rightJustifiedTextSymbolIndex ]; for (var i = 0, list = horizontalIndexes; i < list.length; i += 1) { var index = list[i]; bucket.text.placedSymbolArray.get(index).placedOrientation = horizontal; } if (symbolInstance.verticalPlacedTextSymbolIndex) { bucket.text.placedSymbolArray.get(symbolInstance.verticalPlacedTextSymbolIndex).placedOrientation = vertical; } }; Placement.prototype.commit = function commit(now) { this.commitTime = now; this.zoomAtLastRecencyCheck = this.transform.zoom; var prevPlacement = this.prevPlacement; var placementChanged = false; this.prevZoomAdjustment = prevPlacement ? prevPlacement.zoomAdjustment(this.transform.zoom) : 0; var increment = prevPlacement ? prevPlacement.symbolFadeChange(now) : 1; var prevOpacities = prevPlacement ? prevPlacement.opacities : {}; var prevOffsets = prevPlacement ? prevPlacement.variableOffsets : {}; var prevOrientations = prevPlacement ? prevPlacement.placedOrientations : {}; for (var crossTileID in this.placements) { var jointPlacement = this.placements[crossTileID]; var prevOpacity = prevOpacities[crossTileID]; if (prevOpacity) { this.opacities[crossTileID] = new JointOpacityState(prevOpacity, increment, jointPlacement.text, jointPlacement.icon); placementChanged = placementChanged || jointPlacement.text !== prevOpacity.text.placed || jointPlacement.icon !== prevOpacity.icon.placed; } else { this.opacities[crossTileID] = new JointOpacityState(null, increment, jointPlacement.text, jointPlacement.icon, jointPlacement.skipFade); placementChanged = placementChanged || jointPlacement.text || jointPlacement.icon; } } for (var crossTileID$1 in prevOpacities) { var prevOpacity$1 = prevOpacities[crossTileID$1]; if (!this.opacities[crossTileID$1]) { var jointOpacity = new JointOpacityState(prevOpacity$1, increment, false, false); if (!jointOpacity.isHidden()) { this.opacities[crossTileID$1] = jointOpacity; placementChanged = placementChanged || prevOpacity$1.text.placed || prevOpacity$1.icon.placed; } } } for (var crossTileID$2 in prevOffsets) { if (!this.variableOffsets[crossTileID$2] && this.opacities[crossTileID$2] && !this.opacities[crossTileID$2].isHidden()) { this.variableOffsets[crossTileID$2] = prevOffsets[crossTileID$2]; } } for (var crossTileID$3 in prevOrientations) { if (!this.placedOrientations[crossTileID$3] && this.opacities[crossTileID$3] && !this.opacities[crossTileID$3].isHidden()) { this.placedOrientations[crossTileID$3] = prevOrientations[crossTileID$3]; } } if (placementChanged) { this.lastPlacementChangeTime = now; } else if (typeof this.lastPlacementChangeTime !== 'number') { this.lastPlacementChangeTime = prevPlacement ? prevPlacement.lastPlacementChangeTime : now; } }; Placement.prototype.updateLayerOpacities = function updateLayerOpacities(styleLayer, tiles) { var seenCrossTileIDs = {}; for (var i = 0, list = tiles; i < list.length; i += 1) { var tile = list[i]; var symbolBucket = tile.getBucket(styleLayer); if (symbolBucket && tile.latestFeatureIndex && styleLayer.id === symbolBucket.layerIds[0]) { this.updateBucketOpacities(symbolBucket, seenCrossTileIDs, tile.collisionBoxArray); } } }; Placement.prototype.updateBucketOpacities = function updateBucketOpacities(bucket, seenCrossTileIDs, collisionBoxArray) { var this$1 = this; if (bucket.hasTextData()) { bucket.text.opacityVertexArray.clear(); } if (bucket.hasIconData()) { bucket.icon.opacityVertexArray.clear(); } if (bucket.hasIconCollisionBoxData()) { bucket.iconCollisionBox.collisionVertexArray.clear(); } if (bucket.hasTextCollisionBoxData()) { bucket.textCollisionBox.collisionVertexArray.clear(); } var layout = bucket.layers[0].layout; var duplicateOpacityState = new JointOpacityState(null, 0, false, false, true); var textAllowOverlap = layout.get('text-allow-overlap'); var iconAllowOverlap = layout.get('icon-allow-overlap'); var variablePlacement = layout.get('text-variable-anchor'); var rotateWithMap = layout.get('text-rotation-alignment') === 'map'; var pitchWithMap = layout.get('text-pitch-alignment') === 'map'; var hasIconTextFit = layout.get('icon-text-fit') !== 'none'; var defaultOpacityState = new JointOpacityState(null, 0, textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || layout.get('icon-optional')), iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get('text-optional')), true); if (!bucket.collisionArrays && collisionBoxArray && (bucket.hasIconCollisionBoxData() || bucket.hasTextCollisionBoxData())) { bucket.deserializeCollisionBoxes(collisionBoxArray); } var addOpacities = function (iconOrText, numVertices, opacity) { for (var i = 0; i < numVertices / 4; i++) { iconOrText.opacityVertexArray.emplaceBack(opacity); } }; var loop = function (s) { var symbolInstance = bucket.symbolInstances.get(s); var numHorizontalGlyphVertices = symbolInstance.numHorizontalGlyphVertices; var numVerticalGlyphVertices = symbolInstance.numVerticalGlyphVertices; var crossTileID = symbolInstance.crossTileID; var isDuplicate = seenCrossTileIDs[crossTileID]; var opacityState = this$1.opacities[crossTileID]; if (isDuplicate) { opacityState = duplicateOpacityState; } else if (!opacityState) { opacityState = defaultOpacityState; this$1.opacities[crossTileID] = opacityState; } seenCrossTileIDs[crossTileID] = true; var hasText = numHorizontalGlyphVertices > 0 || numVerticalGlyphVertices > 0; var hasIcon = symbolInstance.numIconVertices > 0; var placedOrientation = this$1.placedOrientations[symbolInstance.crossTileID]; var horizontalHidden = placedOrientation === performance.WritingMode.vertical; var verticalHidden = placedOrientation === performance.WritingMode.horizontal || placedOrientation === performance.WritingMode.horizontalOnly; if (hasText) { var packedOpacity = packOpacity(opacityState.text); var horizontalOpacity = horizontalHidden ? PACKED_HIDDEN_OPACITY : packedOpacity; addOpacities(bucket.text, numHorizontalGlyphVertices, horizontalOpacity); var verticalOpacity = verticalHidden ? PACKED_HIDDEN_OPACITY : packedOpacity; addOpacities(bucket.text, numVerticalGlyphVertices, verticalOpacity); var symbolHidden = opacityState.text.isHidden(); [ symbolInstance.rightJustifiedTextSymbolIndex, symbolInstance.centerJustifiedTextSymbolIndex, symbolInstance.leftJustifiedTextSymbolIndex ].forEach(function (index) { if (index >= 0) { bucket.text.placedSymbolArray.get(index).hidden = symbolHidden || horizontalHidden ? 1 : 0; } }); if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) { bucket.text.placedSymbolArray.get(symbolInstance.verticalPlacedTextSymbolIndex).hidden = symbolHidden || verticalHidden ? 1 : 0; } var prevOffset = this$1.variableOffsets[symbolInstance.crossTileID]; if (prevOffset) { this$1.markUsedJustification(bucket, prevOffset.anchor, symbolInstance, placedOrientation); } var prevOrientation = this$1.placedOrientations[symbolInstance.crossTileID]; if (prevOrientation) { this$1.markUsedJustification(bucket, 'left', symbolInstance, prevOrientation); this$1.markUsedOrientation(bucket, prevOrientation, symbolInstance); } } if (hasIcon) { var packedOpacity$1 = packOpacity(opacityState.icon); var useHorizontal = !(hasIconTextFit && symbolInstance.verticalPlacedIconSymbolIndex && horizontalHidden); if (symbolInstance.placedIconSymbolIndex >= 0) { var horizontalOpacity$1 = useHorizontal ? packedOpacity$1 : PACKED_HIDDEN_OPACITY; addOpacities(bucket.icon, symbolInstance.numIconVertices, horizontalOpacity$1); bucket.icon.placedSymbolArray.get(symbolInstance.placedIconSymbolIndex).hidden = opacityState.icon.isHidden(); } if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) { var verticalOpacity$1 = !useHorizontal ? packedOpacity$1 : PACKED_HIDDEN_OPACITY; addOpacities(bucket.icon, symbolInstance.numVerticalIconVertices, verticalOpacity$1); bucket.icon.placedSymbolArray.get(symbolInstance.verticalPlacedIconSymbolIndex).hidden = opacityState.icon.isHidden(); } } if (bucket.hasIconCollisionBoxData() || bucket.hasTextCollisionBoxData()) { var collisionArrays = bucket.collisionArrays[s]; if (collisionArrays) { var shift = new performance.Point(0, 0); if (collisionArrays.textBox || collisionArrays.verticalTextBox) { var used = true; if (variablePlacement) { var variableOffset = this$1.variableOffsets[crossTileID]; if (variableOffset) { shift = calculateVariableLayoutShift(variableOffset.anchor, variableOffset.width, variableOffset.height, variableOffset.textOffset, variableOffset.textBoxScale); if (rotateWithMap) { shift._rotate(pitchWithMap ? this$1.transform.angle : -this$1.transform.angle); } } else { used = false; } } if (collisionArrays.textBox) { updateCollisionVertices(bucket.textCollisionBox.collisionVertexArray, opacityState.text.placed, !used || horizontalHidden, shift.x, shift.y); } if (collisionArrays.verticalTextBox) { updateCollisionVertices(bucket.textCollisionBox.collisionVertexArray, opacityState.text.placed, !used || verticalHidden, shift.x, shift.y); } } var verticalIconUsed = Boolean(!verticalHidden && collisionArrays.verticalIconBox); if (collisionArrays.iconBox) { updateCollisionVertices(bucket.iconCollisionBox.collisionVertexArray, opacityState.icon.placed, verticalIconUsed, hasIconTextFit ? shift.x : 0, hasIconTextFit ? shift.y : 0); } if (collisionArrays.verticalIconBox) { updateCollisionVertices(bucket.iconCollisionBox.collisionVertexArray, opacityState.icon.placed, !verticalIconUsed, hasIconTextFit ? shift.x : 0, hasIconTextFit ? shift.y : 0); } } } }; for (var s = 0; s < bucket.symbolInstances.length; s++) loop(s); bucket.sortFeatures(this.transform.angle); if (this.retainedQueryData[bucket.bucketInstanceId]) { this.retainedQueryData[bucket.bucketInstanceId].featureSortOrder = bucket.featureSortOrder; } if (bucket.hasTextData() && bucket.text.opacityVertexBuffer) { bucket.text.opacityVertexBuffer.updateData(bucket.text.opacityVertexArray); } if (bucket.hasIconData() && bucket.icon.opacityVertexBuffer) { bucket.icon.opacityVertexBuffer.updateData(bucket.icon.opacityVertexArray); } if (bucket.hasIconCollisionBoxData() && bucket.iconCollisionBox.collisionVertexBuffer) { bucket.iconCollisionBox.collisionVertexBuffer.updateData(bucket.iconCollisionBox.collisionVertexArray); } if (bucket.hasTextCollisionBoxData() && bucket.textCollisionBox.collisionVertexBuffer) { bucket.textCollisionBox.collisionVertexBuffer.updateData(bucket.textCollisionBox.collisionVertexArray); } if (bucket.bucketInstanceId in this.collisionCircleArrays) { var instance = this.collisionCircleArrays[bucket.bucketInstanceId]; bucket.placementInvProjMatrix = instance.invProjMatrix; bucket.placementViewportMatrix = instance.viewportMatrix; bucket.collisionCircleArray = instance.circles; delete this.collisionCircleArrays[bucket.bucketInstanceId]; } }; Placement.prototype.symbolFadeChange = function symbolFadeChange(now) { return this.fadeDuration === 0 ? 1 : (now - this.commitTime) / this.fadeDuration + this.prevZoomAdjustment; }; Placement.prototype.zoomAdjustment = function zoomAdjustment(zoom) { return Math.max(0, (this.transform.zoom - zoom) / 1.5); }; Placement.prototype.hasTransitions = function hasTransitions(now) { return this.stale || now - this.lastPlacementChangeTime < this.fadeDuration; }; Placement.prototype.stillRecent = function stillRecent(now, zoom) { var durationAdjustment = this.zoomAtLastRecencyCheck === zoom ? 1 - this.zoomAdjustment(zoom) : 1; this.zoomAtLastRecencyCheck = zoom; return this.commitTime + this.fadeDuration * durationAdjustment > now; }; Placement.prototype.setStale = function setStale() { this.stale = true; }; function updateCollisionVertices(collisionVertexArray, placed, notUsed, shiftX, shiftY) { collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0); collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0); collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0); collisionVertexArray.emplaceBack(placed ? 1 : 0, notUsed ? 1 : 0, shiftX || 0, shiftY || 0); } var shift25 = Math.pow(2, 25); var shift24 = Math.pow(2, 24); var shift17 = Math.pow(2, 17); var shift16 = Math.pow(2, 16); var shift9 = Math.pow(2, 9); var shift8 = Math.pow(2, 8); var shift1 = Math.pow(2, 1); function packOpacity(opacityState) { if (opacityState.opacity === 0 && !opacityState.placed) { return 0; } else if (opacityState.opacity === 1 && opacityState.placed) { return 4294967295; } var targetBit = opacityState.placed ? 1 : 0; var opacityBits = Math.floor(opacityState.opacity * 127); return opacityBits * shift25 + targetBit * shift24 + opacityBits * shift17 + targetBit * shift16 + opacityBits * shift9 + targetBit * shift8 + opacityBits * shift1 + targetBit; } var PACKED_HIDDEN_OPACITY = 0; var LayerPlacement = function LayerPlacement(styleLayer) { this._sortAcrossTiles = styleLayer.layout.get('symbol-z-order') !== 'viewport-y' && styleLayer.layout.get('symbol-sort-key').constantOr(1) !== undefined; this._currentTileIndex = 0; this._currentPartIndex = 0; this._seenCrossTileIDs = {}; this._bucketParts = []; }; LayerPlacement.prototype.continuePlacement = function continuePlacement(tiles, placement, showCollisionBoxes, styleLayer, shouldPausePlacement) { var bucketParts = this._bucketParts; while (this._currentTileIndex < tiles.length) { var tile = tiles[this._currentTileIndex]; placement.getBucketParts(bucketParts, styleLayer, tile, this._sortAcrossTiles); this._currentTileIndex++; if (shouldPausePlacement()) { return true; } } if (this._sortAcrossTiles) { this._sortAcrossTiles = false; bucketParts.sort(function (a, b) { return a.sortKey - b.sortKey; }); } while (this._currentPartIndex < bucketParts.length) { var bucketPart = bucketParts[this._currentPartIndex]; placement.placeLayerBucketPart(bucketPart, this._seenCrossTileIDs, showCollisionBoxes); this._currentPartIndex++; if (shouldPausePlacement()) { return true; } } return false; }; var PauseablePlacement = function PauseablePlacement(transform, order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, prevPlacement) { this.placement = new Placement(transform, fadeDuration, crossSourceCollisions, prevPlacement); this._currentPlacementIndex = order.length - 1; this._forceFullPlacement = forceFullPlacement; this._showCollisionBoxes = showCollisionBoxes; this._done = false; }; PauseablePlacement.prototype.isDone = function isDone() { return this._done; }; PauseablePlacement.prototype.continuePlacement = function continuePlacement(order, layers, layerTiles) { var this$1 = this; var startTime = performance.browser.now(); var shouldPausePlacement = function () { var elapsedTime = performance.browser.now() - startTime; return this$1._forceFullPlacement ? false : elapsedTime > 2; }; while (this._currentPlacementIndex >= 0) { var layerId = order[this._currentPlacementIndex]; var layer = layers[layerId]; var placementZoom = this.placement.collisionIndex.transform.zoom; if (layer.type === 'symbol' && (!layer.minzoom || layer.minzoom <= placementZoom) && (!layer.maxzoom || layer.maxzoom > placementZoom)) { if (!this._inProgressLayer) { this._inProgressLayer = new LayerPlacement(layer); } var pausePlacement = this._inProgressLayer.continuePlacement(layerTiles[layer.source], this.placement, this._showCollisionBoxes, layer, shouldPausePlacement); if (pausePlacement) { return; } delete this._inProgressLayer; } this._currentPlacementIndex--; } this._done = true; }; PauseablePlacement.prototype.commit = function commit(now) { this.placement.commit(now); return this.placement; }; var roundingFactor = 512 / performance.EXTENT / 2; var TileLayerIndex = function TileLayerIndex(tileID, symbolInstances, bucketInstanceId) { this.tileID = tileID; this.indexedSymbolInstances = {}; this.bucketInstanceId = bucketInstanceId; for (var i = 0; i < symbolInstances.length; i++) { var symbolInstance = symbolInstances.get(i); var key = symbolInstance.key; if (!this.indexedSymbolInstances[key]) { this.indexedSymbolInstances[key] = []; } this.indexedSymbolInstances[key].push({ crossTileID: symbolInstance.crossTileID, coord: this.getScaledCoordinates(symbolInstance, tileID) }); } }; TileLayerIndex.prototype.getScaledCoordinates = function getScaledCoordinates(symbolInstance, childTileID) { var zDifference = childTileID.canonical.z - this.tileID.canonical.z; var scale = roundingFactor / Math.pow(2, zDifference); return { x: Math.floor((childTileID.canonical.x * performance.EXTENT + symbolInstance.anchorX) * scale), y: Math.floor((childTileID.canonical.y * performance.EXTENT + symbolInstance.anchorY) * scale) }; }; TileLayerIndex.prototype.findMatches = function findMatches(symbolInstances, newTileID, zoomCrossTileIDs) { var tolerance = this.tileID.canonical.z < newTileID.canonical.z ? 1 : Math.pow(2, this.tileID.canonical.z - newTileID.canonical.z); for (var i = 0; i < symbolInstances.length; i++) { var symbolInstance = symbolInstances.get(i); if (symbolInstance.crossTileID) { continue; } var indexedInstances = this.indexedSymbolInstances[symbolInstance.key]; if (!indexedInstances) { continue; } var scaledSymbolCoord = this.getScaledCoordinates(symbolInstance, newTileID); for (var i$1 = 0, list = indexedInstances; i$1 < list.length; i$1 += 1) { var thisTileSymbol = list[i$1]; if (Math.abs(thisTileSymbol.coord.x - scaledSymbolCoord.x) <= tolerance && Math.abs(thisTileSymbol.coord.y - scaledSymbolCoord.y) <= tolerance && !zoomCrossTileIDs[thisTileSymbol.crossTileID]) { zoomCrossTileIDs[thisTileSymbol.crossTileID] = true; symbolInstance.crossTileID = thisTileSymbol.crossTileID; break; } } } }; var CrossTileIDs = function CrossTileIDs() { this.maxCrossTileID = 0; }; CrossTileIDs.prototype.generate = function generate() { return ++this.maxCrossTileID; }; var CrossTileSymbolLayerIndex = function CrossTileSymbolLayerIndex() { this.indexes = {}; this.usedCrossTileIDs = {}; this.lng = 0; }; CrossTileSymbolLayerIndex.prototype.handleWrapJump = function handleWrapJump(lng) { var wrapDelta = Math.round((lng - this.lng) / 360); if (wrapDelta !== 0) { for (var zoom in this.indexes) { var zoomIndexes = this.indexes[zoom]; var newZoomIndex = {}; for (var key in zoomIndexes) { var index = zoomIndexes[key]; index.tileID = index.tileID.unwrapTo(index.tileID.wrap + wrapDelta); newZoomIndex[index.tileID.key] = index; } this.indexes[zoom] = newZoomIndex; } } this.lng = lng; }; CrossTileSymbolLayerIndex.prototype.addBucket = function addBucket(tileID, bucket, crossTileIDs) { if (this.indexes[tileID.overscaledZ] && this.indexes[tileID.overscaledZ][tileID.key]) { if (this.indexes[tileID.overscaledZ][tileID.key].bucketInstanceId === bucket.bucketInstanceId) { return false; } else { this.removeBucketCrossTileIDs(tileID.overscaledZ, this.indexes[tileID.overscaledZ][tileID.key]); } } for (var i = 0; i < bucket.symbolInstances.length; i++) { var symbolInstance = bucket.symbolInstances.get(i); symbolInstance.crossTileID = 0; } if (!this.usedCrossTileIDs[tileID.overscaledZ]) { this.usedCrossTileIDs[tileID.overscaledZ] = {}; } var zoomCrossTileIDs = this.usedCrossTileIDs[tileID.overscaledZ]; for (var zoom in this.indexes) { var zoomIndexes = this.indexes[zoom]; if (Number(zoom) > tileID.overscaledZ) { for (var id in zoomIndexes) { var childIndex = zoomIndexes[id]; if (childIndex.tileID.isChildOf(tileID)) { childIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs); } } } else { var parentCoord = tileID.scaledTo(Number(zoom)); var parentIndex = zoomIndexes[parentCoord.key]; if (parentIndex) { parentIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs); } } } for (var i$1 = 0; i$1 < bucket.symbolInstances.length; i$1++) { var symbolInstance$1 = bucket.symbolInstances.get(i$1); if (!symbolInstance$1.crossTileID) { symbolInstance$1.crossTileID = crossTileIDs.generate(); zoomCrossTileIDs[symbolInstance$1.crossTileID] = true; } } if (this.indexes[tileID.overscaledZ] === undefined) { this.indexes[tileID.overscaledZ] = {}; } this.indexes[tileID.overscaledZ][tileID.key] = new TileLayerIndex(tileID, bucket.symbolInstances, bucket.bucketInstanceId); return true; }; CrossTileSymbolLayerIndex.prototype.removeBucketCrossTileIDs = function removeBucketCrossTileIDs(zoom, removedBucket) { for (var key in removedBucket.indexedSymbolInstances) { for (var i = 0, list = removedBucket.indexedSymbolInstances[key]; i < list.length; i += 1) { var symbolInstance = list[i]; delete this.usedCrossTileIDs[zoom][symbolInstance.crossTileID]; } } }; CrossTileSymbolLayerIndex.prototype.removeStaleBuckets = function removeStaleBuckets(currentIDs) { var tilesChanged = false; for (var z in this.indexes) { var zoomIndexes = this.indexes[z]; for (var tileKey in zoomIndexes) { if (!currentIDs[zoomIndexes[tileKey].bucketInstanceId]) { this.removeBucketCrossTileIDs(z, zoomIndexes[tileKey]); delete zoomIndexes[tileKey]; tilesChanged = true; } } } return tilesChanged; }; var CrossTileSymbolIndex = function CrossTileSymbolIndex() { this.layerIndexes = {}; this.crossTileIDs = new CrossTileIDs(); this.maxBucketInstanceId = 0; this.bucketsInCurrentPlacement = {}; }; CrossTileSymbolIndex.prototype.addLayer = function addLayer(styleLayer, tiles, lng) { var layerIndex = this.layerIndexes[styleLayer.id]; if (layerIndex === undefined) { layerIndex = this.layerIndexes[styleLayer.id] = new CrossTileSymbolLayerIndex(); } var symbolBucketsChanged = false; var currentBucketIDs = {}; layerIndex.handleWrapJump(lng); for (var i = 0, list = tiles; i < list.length; i += 1) { var tile = list[i]; var symbolBucket = tile.getBucket(styleLayer); if (!symbolBucket || styleLayer.id !== symbolBucket.layerIds[0]) { continue; } if (!symbolBucket.bucketInstanceId) { symbolBucket.bucketInstanceId = ++this.maxBucketInstanceId; } if (layerIndex.addBucket(tile.tileID, symbolBucket, this.crossTileIDs)) { symbolBucketsChanged = true; } currentBucketIDs[symbolBucket.bucketInstanceId] = true; } if (layerIndex.removeStaleBuckets(currentBucketIDs)) { symbolBucketsChanged = true; } return symbolBucketsChanged; }; CrossTileSymbolIndex.prototype.pruneUnusedLayers = function pruneUnusedLayers(usedLayers) { var usedLayerMap = {}; usedLayers.forEach(function (usedLayer) { usedLayerMap[usedLayer] = true; }); for (var layerId in this.layerIndexes) { if (!usedLayerMap[layerId]) { delete this.layerIndexes[layerId]; } } }; var emitValidationErrors = function (evented, errors) { return performance.emitValidationErrors(evented, errors && errors.filter(function (error) { return error.identifier !== 'source.canvas'; })); }; var supportedDiffOperations = performance.pick(operations, [ 'addLayer', 'removeLayer', 'setPaintProperty', 'setLayoutProperty', 'setFilter', 'addSource', 'removeSource', 'setLayerZoomRange', 'setLight', 'setTransition', 'setGeoJSONSourceData' ]); var ignoredDiffOperations = performance.pick(operations, [ 'setCenter', 'setZoom', 'setBearing', 'setPitch' ]); var empty = emptyStyle(); var Style = function (Evented) { function Style(map, options) { var this$1 = this; if (options === void 0) options = {}; Evented.call(this); this.map = map; this.dispatcher = new Dispatcher(getGlobalWorkerPool(), this); this.imageManager = new ImageManager(); this.imageManager.setEventedParent(this); this.glyphManager = new GlyphManager(map._requestManager, options.localIdeographFontFamily); this.lineAtlas = new LineAtlas(256, 512); this.crossTileSymbolIndex = new CrossTileSymbolIndex(); this._layers = {}; this._serializedLayers = {}; this._order = []; this.sourceCaches = {}; this.zoomHistory = new performance.ZoomHistory(); this._loaded = false; this._availableImages = []; this._resetUpdates(); this.dispatcher.broadcast('setReferrer', performance.getReferrer()); var self = this; this._rtlTextPluginCallback = Style.registerForPluginStateChange(function (event) { var state = { pluginStatus: event.pluginStatus, pluginURL: event.pluginURL }; self.dispatcher.broadcast('syncRTLPluginState', state, function (err, results) { performance.triggerPluginCompletionEvent(err); if (results) { var allComplete = results.every(function (elem) { return elem; }); if (allComplete) { for (var id in self.sourceCaches) { self.sourceCaches[id].reload(); } } } }); }); this.on('data', function (event) { if (event.dataType !== 'source' || event.sourceDataType !== 'metadata') { return; } var sourceCache = this$1.sourceCaches[event.sourceId]; if (!sourceCache) { return; } var source = sourceCache.getSource(); if (!source || !source.vectorLayerIds) { return; } for (var layerId in this$1._layers) { var layer = this$1._layers[layerId]; if (layer.source === source.id) { this$1._validateLayer(layer); } } }); } if (Evented) Style.__proto__ = Evented; Style.prototype = Object.create(Evented && Evented.prototype); Style.prototype.constructor = Style; Style.prototype.loadURL = function loadURL(url, options) { var this$1 = this; if (options === void 0) options = {}; this.fire(new performance.Event('dataloading', { dataType: 'style' })); var validate = typeof options.validate === 'boolean' ? options.validate : !performance.isMapboxURL(url); url = this.map._requestManager.normalizeStyleURL(url, options.accessToken); var request = this.map._requestManager.transformRequest(url, performance.ResourceType.Style); this._request = performance.getJSON(request, function (error, json) { this$1._request = null; if (error) { this$1.fire(new performance.ErrorEvent(error)); } else if (json) { this$1._load(json, validate); } }); }; Style.prototype.loadJSON = function loadJSON(json, options) { var this$1 = this; if (options === void 0) options = {}; this.fire(new performance.Event('dataloading', { dataType: 'style' })); this._request = performance.browser.frame(function () { this$1._request = null; this$1._load(json, options.validate !== false); }); }; Style.prototype.loadEmpty = function loadEmpty() { this.fire(new performance.Event('dataloading', { dataType: 'style' })); this._load(empty, false); }; Style.prototype._load = function _load(json, validate) { if (validate && emitValidationErrors(this, performance.validateStyle(json))) { return; } this._loaded = true; this.stylesheet = json; for (var id in json.sources) { this.addSource(id, json.sources[id], { validate: false }); } if (json.sprite) { this._loadSprite(json.sprite); } else { this.imageManager.setLoaded(true); } this.glyphManager.setURL(json.glyphs); var layers = derefLayers(this.stylesheet.layers); this._order = layers.map(function (layer) { return layer.id; }); this._layers = {}; this._serializedLayers = {}; for (var i = 0, list = layers; i < list.length; i += 1) { var layer = list[i]; layer = performance.createStyleLayer(layer); layer.setEventedParent(this, { layer: { id: layer.id } }); this._layers[layer.id] = layer; this._serializedLayers[layer.id] = layer.serialize(); } this.dispatcher.broadcast('setLayers', this._serializeLayers(this._order)); this.light = new Light(this.stylesheet.light); this.fire(new performance.Event('data', { dataType: 'style' })); this.fire(new performance.Event('style.load')); }; Style.prototype._loadSprite = function _loadSprite(url) { var this$1 = this; this._spriteRequest = loadSprite(url, this.map._requestManager, function (err, images) { this$1._spriteRequest = null; if (err) { this$1.fire(new performance.ErrorEvent(err)); } else if (images) { for (var id in images) { this$1.imageManager.addImage(id, images[id]); } } this$1.imageManager.setLoaded(true); this$1._availableImages = this$1.imageManager.listImages(); this$1.dispatcher.broadcast('setImages', this$1._availableImages); this$1.fire(new performance.Event('data', { dataType: 'style' })); }); }; Style.prototype._validateLayer = function _validateLayer(layer) { var sourceCache = this.sourceCaches[layer.source]; if (!sourceCache) { return; } var sourceLayer = layer.sourceLayer; if (!sourceLayer) { return; } var source = sourceCache.getSource(); if (source.type === 'geojson' || source.vectorLayerIds && source.vectorLayerIds.indexOf(sourceLayer) === -1) { this.fire(new performance.ErrorEvent(new Error('Source layer "' + sourceLayer + '" ' + 'does not exist on source "' + source.id + '" ' + 'as specified by style layer "' + layer.id + '"'))); } }; Style.prototype.loaded = function loaded() { if (!this._loaded) { return false; } if (Object.keys(this._updatedSources).length) { return false; } for (var id in this.sourceCaches) { if (!this.sourceCaches[id].loaded()) { return false; } } if (!this.imageManager.isLoaded()) { return false; } return true; }; Style.prototype._serializeLayers = function _serializeLayers(ids) { var serializedLayers = []; for (var i = 0, list = ids; i < list.length; i += 1) { var id = list[i]; var layer = this._layers[id]; if (layer.type !== 'custom') { serializedLayers.push(layer.serialize()); } } return serializedLayers; }; Style.prototype.hasTransitions = function hasTransitions() { if (this.light && this.light.hasTransition()) { return true; } for (var id in this.sourceCaches) { if (this.sourceCaches[id].hasTransition()) { return true; } } for (var id$1 in this._layers) { if (this._layers[id$1].hasTransition()) { return true; } } return false; }; Style.prototype._checkLoaded = function _checkLoaded() { if (!this._loaded) { throw new Error('Style is not done loading'); } }; Style.prototype.update = function update(parameters) { if (!this._loaded) { return; } var changed = this._changed; if (this._changed) { var updatedIds = Object.keys(this._updatedLayers); var removedIds = Object.keys(this._removedLayers); if (updatedIds.length || removedIds.length) { this._updateWorkerLayers(updatedIds, removedIds); } for (var id in this._updatedSources) { var action = this._updatedSources[id]; if (action === 'reload') { this._reloadSource(id); } else if (action === 'clear') { this._clearSource(id); } } this._updateTilesForChangedImages(); for (var id$1 in this._updatedPaintProps) { this._layers[id$1].updateTransitions(parameters); } this.light.updateTransitions(parameters); this._resetUpdates(); } var sourcesUsedBefore = {}; for (var sourceId in this.sourceCaches) { var sourceCache = this.sourceCaches[sourceId]; sourcesUsedBefore[sourceId] = sourceCache.used; sourceCache.used = false; } for (var i = 0, list = this._order; i < list.length; i += 1) { var layerId = list[i]; var layer = this._layers[layerId]; layer.recalculate(parameters, this._availableImages); if (!layer.isHidden(parameters.zoom) && layer.source) { this.sourceCaches[layer.source].used = true; } } for (var sourceId$1 in sourcesUsedBefore) { var sourceCache$1 = this.sourceCaches[sourceId$1]; if (sourcesUsedBefore[sourceId$1] !== sourceCache$1.used) { sourceCache$1.fire(new performance.Event('data', { sourceDataType: 'visibility', dataType: 'source', sourceId: sourceId$1 })); } } this.light.recalculate(parameters); this.z = parameters.zoom; if (changed) { this.fire(new performance.Event('data', { dataType: 'style' })); } }; Style.prototype._updateTilesForChangedImages = function _updateTilesForChangedImages() { var changedImages = Object.keys(this._changedImages); if (changedImages.length) { for (var name in this.sourceCaches) { this.sourceCaches[name].reloadTilesForDependencies([ 'icons', 'patterns' ], changedImages); } this._changedImages = {}; } }; Style.prototype._updateWorkerLayers = function _updateWorkerLayers(updatedIds, removedIds) { this.dispatcher.broadcast('updateLayers', { layers: this._serializeLayers(updatedIds), removedIds: removedIds }); }; Style.prototype._resetUpdates = function _resetUpdates() { this._changed = false; this._updatedLayers = {}; this._removedLayers = {}; this._updatedSources = {}; this._updatedPaintProps = {}; this._changedImages = {}; }; Style.prototype.setState = function setState(nextState) { var this$1 = this; this._checkLoaded(); if (emitValidationErrors(this, performance.validateStyle(nextState))) { return false; } nextState = performance.clone$1(nextState); nextState.layers = derefLayers(nextState.layers); var changes = diffStyles(this.serialize(), nextState).filter(function (op) { return !(op.command in ignoredDiffOperations); }); if (changes.length === 0) { return false; } var unimplementedOps = changes.filter(function (op) { return !(op.command in supportedDiffOperations); }); if (unimplementedOps.length > 0) { throw new Error('Unimplemented: ' + unimplementedOps.map(function (op) { return op.command; }).join(', ') + '.'); } changes.forEach(function (op) { if (op.command === 'setTransition') { return; } this$1[op.command].apply(this$1, op.args); }); this.stylesheet = nextState; return true; }; Style.prototype.addImage = function addImage(id, image) { if (this.getImage(id)) { return this.fire(new performance.ErrorEvent(new Error('An image with this name already exists.'))); } this.imageManager.addImage(id, image); this._afterImageUpdated(id); }; Style.prototype.updateImage = function updateImage(id, image) { this.imageManager.updateImage(id, image); }; Style.prototype.getImage = function getImage(id) { return this.imageManager.getImage(id); }; Style.prototype.removeImage = function removeImage(id) { if (!this.getImage(id)) { return this.fire(new performance.ErrorEvent(new Error('No image with this name exists.'))); } this.imageManager.removeImage(id); this._afterImageUpdated(id); }; Style.prototype._afterImageUpdated = function _afterImageUpdated(id) { this._availableImages = this.imageManager.listImages(); this._changedImages[id] = true; this._changed = true; this.dispatcher.broadcast('setImages', this._availableImages); this.fire(new performance.Event('data', { dataType: 'style' })); }; Style.prototype.listImages = function listImages() { this._checkLoaded(); return this.imageManager.listImages(); }; Style.prototype.addSource = function addSource(id, source, options) { var this$1 = this; if (options === void 0) options = {}; this._checkLoaded(); if (this.sourceCaches[id] !== undefined) { throw new Error('There is already a source with this ID'); } if (!source.type) { throw new Error('The type property must be defined, but only the following properties were given: ' + Object.keys(source).join(', ') + '.'); } var builtIns = [ 'vector', 'raster', 'geojson', 'video', 'image' ]; var shouldValidate = builtIns.indexOf(source.type) >= 0; if (shouldValidate && this._validate(performance.validateStyle.source, 'sources.' + id, source, null, options)) { return; } if (this.map && this.map._collectResourceTiming) { source.collectResourceTiming = true; } var sourceCache = this.sourceCaches[id] = new SourceCache(id, source, this.dispatcher); sourceCache.style = this; sourceCache.setEventedParent(this, function () { return { isSourceLoaded: this$1.loaded(), source: sourceCache.serialize(), sourceId: id }; }); sourceCache.onAdd(this.map); this._changed = true; }; Style.prototype.removeSource = function removeSource(id) { this._checkLoaded(); if (this.sourceCaches[id] === undefined) { throw new Error('There is no source with this ID'); } for (var layerId in this._layers) { if (this._layers[layerId].source === id) { return this.fire(new performance.ErrorEvent(new Error('Source "' + id + '" cannot be removed while layer "' + layerId + '" is using it.'))); } } var sourceCache = this.sourceCaches[id]; delete this.sourceCaches[id]; delete this._updatedSources[id]; sourceCache.fire(new performance.Event('data', { sourceDataType: 'metadata', dataType: 'source', sourceId: id })); sourceCache.setEventedParent(null); sourceCache.clearTiles(); if (sourceCache.onRemove) { sourceCache.onRemove(this.map); } this._changed = true; }; Style.prototype.setGeoJSONSourceData = function setGeoJSONSourceData(id, data) { this._checkLoaded(); var geojsonSource = this.sourceCaches[id].getSource(); geojsonSource.setData(data); this._changed = true; }; Style.prototype.getSource = function getSource(id) { return this.sourceCaches[id] && this.sourceCaches[id].getSource(); }; Style.prototype.addLayer = function addLayer(layerObject, before, options) { if (options === void 0) options = {}; this._checkLoaded(); var id = layerObject.id; if (this.getLayer(id)) { this.fire(new performance.ErrorEvent(new Error('Layer with id "' + id + '" already exists on this map'))); return; } var layer; if (layerObject.type === 'custom') { if (emitValidationErrors(this, performance.validateCustomStyleLayer(layerObject))) { return; } layer = performance.createStyleLayer(layerObject); } else { if (typeof layerObject.source === 'object') { this.addSource(id, layerObject.source); layerObject = performance.clone$1(layerObject); layerObject = performance.extend(layerObject, { source: id }); } if (this._validate(performance.validateStyle.layer, 'layers.' + id, layerObject, { arrayIndex: -1 }, options)) { return; } layer = performance.createStyleLayer(layerObject); this._validateLayer(layer); layer.setEventedParent(this, { layer: { id: id } }); this._serializedLayers[layer.id] = layer.serialize(); } var index = before ? this._order.indexOf(before) : this._order.length; if (before && index === -1) { this.fire(new performance.ErrorEvent(new Error('Layer with id "' + before + '" does not exist on this map.'))); return; } this._order.splice(index, 0, id); this._layerOrderChanged = true; this._layers[id] = layer; if (this._removedLayers[id] && layer.source && layer.type !== 'custom') { var removed = this._removedLayers[id]; delete this._removedLayers[id]; if (removed.type !== layer.type) { this._updatedSources[layer.source] = 'clear'; } else { this._updatedSources[layer.source] = 'reload'; this.sourceCaches[layer.source].pause(); } } this._updateLayer(layer); if (layer.onAdd) { layer.onAdd(this.map); } }; Style.prototype.moveLayer = function moveLayer(id, before) { this._checkLoaded(); this._changed = true; var layer = this._layers[id]; if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + id + '\' does not exist in the map\'s style and cannot be moved.'))); return; } if (id === before) { return; } var index = this._order.indexOf(id); this._order.splice(index, 1); var newIndex = before ? this._order.indexOf(before) : this._order.length; if (before && newIndex === -1) { this.fire(new performance.ErrorEvent(new Error('Layer with id "' + before + '" does not exist on this map.'))); return; } this._order.splice(newIndex, 0, id); this._layerOrderChanged = true; }; Style.prototype.removeLayer = function removeLayer(id) { this._checkLoaded(); var layer = this._layers[id]; if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + id + '\' does not exist in the map\'s style and cannot be removed.'))); return; } layer.setEventedParent(null); var index = this._order.indexOf(id); this._order.splice(index, 1); this._layerOrderChanged = true; this._changed = true; this._removedLayers[id] = layer; delete this._layers[id]; delete this._serializedLayers[id]; delete this._updatedLayers[id]; delete this._updatedPaintProps[id]; if (layer.onRemove) { layer.onRemove(this.map); } }; Style.prototype.getLayer = function getLayer(id) { return this._layers[id]; }; Style.prototype.hasLayer = function hasLayer(id) { return id in this._layers; }; Style.prototype.setLayerZoomRange = function setLayerZoomRange(layerId, minzoom, maxzoom) { this._checkLoaded(); var layer = this.getLayer(layerId); if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot have zoom extent.'))); return; } if (layer.minzoom === minzoom && layer.maxzoom === maxzoom) { return; } if (minzoom != null) { layer.minzoom = minzoom; } if (maxzoom != null) { layer.maxzoom = maxzoom; } this._updateLayer(layer); }; Style.prototype.setFilter = function setFilter(layerId, filter, options) { if (options === void 0) options = {}; this._checkLoaded(); var layer = this.getLayer(layerId); if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be filtered.'))); return; } if (performance.deepEqual(layer.filter, filter)) { return; } if (filter === null || filter === undefined) { layer.filter = undefined; this._updateLayer(layer); return; } if (this._validate(performance.validateStyle.filter, 'layers.' + layer.id + '.filter', filter, null, options)) { return; } layer.filter = performance.clone$1(filter); this._updateLayer(layer); }; Style.prototype.getFilter = function getFilter(layer) { return performance.clone$1(this.getLayer(layer).filter); }; Style.prototype.setLayoutProperty = function setLayoutProperty(layerId, name, value, options) { if (options === void 0) options = {}; this._checkLoaded(); var layer = this.getLayer(layerId); if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be styled.'))); return; } if (performance.deepEqual(layer.getLayoutProperty(name), value)) { return; } layer.setLayoutProperty(name, value, options); this._updateLayer(layer); }; Style.prototype.getLayoutProperty = function getLayoutProperty(layerId, name) { var layer = this.getLayer(layerId); if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style.'))); return; } return layer.getLayoutProperty(name); }; Style.prototype.setPaintProperty = function setPaintProperty(layerId, name, value, options) { if (options === void 0) options = {}; this._checkLoaded(); var layer = this.getLayer(layerId); if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be styled.'))); return; } if (performance.deepEqual(layer.getPaintProperty(name), value)) { return; } var requiresRelayout = layer.setPaintProperty(name, value, options); if (requiresRelayout) { this._updateLayer(layer); } this._changed = true; this._updatedPaintProps[layerId] = true; }; Style.prototype.getPaintProperty = function getPaintProperty(layer, name) { return this.getLayer(layer).getPaintProperty(name); }; Style.prototype.setFeatureState = function setFeatureState(target, state) { this._checkLoaded(); var sourceId = target.source; var sourceLayer = target.sourceLayer; var sourceCache = this.sourceCaches[sourceId]; if (sourceCache === undefined) { this.fire(new performance.ErrorEvent(new Error('The source \'' + sourceId + '\' does not exist in the map\'s style.'))); return; } var sourceType = sourceCache.getSource().type; if (sourceType === 'geojson' && sourceLayer) { this.fire(new performance.ErrorEvent(new Error('GeoJSON sources cannot have a sourceLayer parameter.'))); return; } if (sourceType === 'vector' && !sourceLayer) { this.fire(new performance.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); return; } if (target.id === undefined) { this.fire(new performance.ErrorEvent(new Error('The feature id parameter must be provided.'))); } sourceCache.setFeatureState(sourceLayer, target.id, state); }; Style.prototype.removeFeatureState = function removeFeatureState(target, key) { this._checkLoaded(); var sourceId = target.source; var sourceCache = this.sourceCaches[sourceId]; if (sourceCache === undefined) { this.fire(new performance.ErrorEvent(new Error('The source \'' + sourceId + '\' does not exist in the map\'s style.'))); return; } var sourceType = sourceCache.getSource().type; var sourceLayer = sourceType === 'vector' ? target.sourceLayer : undefined; if (sourceType === 'vector' && !sourceLayer) { this.fire(new performance.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); return; } if (key && (typeof target.id !== 'string' && typeof target.id !== 'number')) { this.fire(new performance.ErrorEvent(new Error('A feature id is required to remove its specific state property.'))); return; } sourceCache.removeFeatureState(sourceLayer, target.id, key); }; Style.prototype.getFeatureState = function getFeatureState(target) { this._checkLoaded(); var sourceId = target.source; var sourceLayer = target.sourceLayer; var sourceCache = this.sourceCaches[sourceId]; if (sourceCache === undefined) { this.fire(new performance.ErrorEvent(new Error('The source \'' + sourceId + '\' does not exist in the map\'s style.'))); return; } var sourceType = sourceCache.getSource().type; if (sourceType === 'vector' && !sourceLayer) { this.fire(new performance.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); return; } if (target.id === undefined) { this.fire(new performance.ErrorEvent(new Error('The feature id parameter must be provided.'))); } return sourceCache.getFeatureState(sourceLayer, target.id); }; Style.prototype.getTransition = function getTransition() { return performance.extend({ duration: 300, delay: 0 }, this.stylesheet && this.stylesheet.transition); }; Style.prototype.serialize = function serialize() { return performance.filterObject({ version: this.stylesheet.version, name: this.stylesheet.name, metadata: this.stylesheet.metadata, light: this.stylesheet.light, center: this.stylesheet.center, zoom: this.stylesheet.zoom, bearing: this.stylesheet.bearing, pitch: this.stylesheet.pitch, sprite: this.stylesheet.sprite, glyphs: this.stylesheet.glyphs, transition: this.stylesheet.transition, sources: performance.mapObject(this.sourceCaches, function (source) { return source.serialize(); }), layers: this._serializeLayers(this._order) }, function (value) { return value !== undefined; }); }; Style.prototype._updateLayer = function _updateLayer(layer) { this._updatedLayers[layer.id] = true; if (layer.source && !this._updatedSources[layer.source] && this.sourceCaches[layer.source].getSource().type !== 'raster') { this._updatedSources[layer.source] = 'reload'; this.sourceCaches[layer.source].pause(); } this._changed = true; }; Style.prototype._flattenAndSortRenderedFeatures = function _flattenAndSortRenderedFeatures(sourceResults) { var this$1 = this; var isLayer3D = function (layerId) { return this$1._layers[layerId].type === 'fill-extrusion'; }; var layerIndex = {}; var features3D = []; for (var l = this._order.length - 1; l >= 0; l--) { var layerId = this._order[l]; if (isLayer3D(layerId)) { layerIndex[layerId] = l; for (var i$2 = 0, list$1 = sourceResults; i$2 < list$1.length; i$2 += 1) { var sourceResult = list$1[i$2]; var layerFeatures = sourceResult[layerId]; if (layerFeatures) { for (var i$1 = 0, list = layerFeatures; i$1 < list.length; i$1 += 1) { var featureWrapper = list[i$1]; features3D.push(featureWrapper); } } } } } features3D.sort(function (a, b) { return b.intersectionZ - a.intersectionZ; }); var features = []; for (var l$1 = this._order.length - 1; l$1 >= 0; l$1--) { var layerId$1 = this._order[l$1]; if (isLayer3D(layerId$1)) { for (var i = features3D.length - 1; i >= 0; i--) { var topmost3D = features3D[i].feature; if (layerIndex[topmost3D.layer.id] < l$1) { break; } features.push(topmost3D); features3D.pop(); } } else { for (var i$4 = 0, list$3 = sourceResults; i$4 < list$3.length; i$4 += 1) { var sourceResult$1 = list$3[i$4]; var layerFeatures$1 = sourceResult$1[layerId$1]; if (layerFeatures$1) { for (var i$3 = 0, list$2 = layerFeatures$1; i$3 < list$2.length; i$3 += 1) { var featureWrapper$1 = list$2[i$3]; features.push(featureWrapper$1.feature); } } } } } return features; }; Style.prototype.queryRenderedFeatures = function queryRenderedFeatures$1(queryGeometry, params, transform) { if (params && params.filter) { this._validate(performance.validateStyle.filter, 'queryRenderedFeatures.filter', params.filter, null, params); } var includedSources = {}; if (params && params.layers) { if (!Array.isArray(params.layers)) { this.fire(new performance.ErrorEvent(new Error('parameters.layers must be an Array.'))); return []; } for (var i = 0, list = params.layers; i < list.length; i += 1) { var layerId = list[i]; var layer = this._layers[layerId]; if (!layer) { this.fire(new performance.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be queried for features.'))); return []; } includedSources[layer.source] = true; } } var sourceResults = []; params.availableImages = this._availableImages; for (var id in this.sourceCaches) { if (params.layers && !includedSources[id]) { continue; } sourceResults.push(queryRenderedFeatures(this.sourceCaches[id], this._layers, this._serializedLayers, queryGeometry, params, transform)); } if (this.placement) { sourceResults.push(queryRenderedSymbols(this._layers, this._serializedLayers, this.sourceCaches, queryGeometry, params, this.placement.collisionIndex, this.placement.retainedQueryData)); } return this._flattenAndSortRenderedFeatures(sourceResults); }; Style.prototype.querySourceFeatures = function querySourceFeatures$1(sourceID, params) { if (params && params.filter) { this._validate(performance.validateStyle.filter, 'querySourceFeatures.filter', params.filter, null, params); } var sourceCache = this.sourceCaches[sourceID]; return sourceCache ? querySourceFeatures(sourceCache, params) : []; }; Style.prototype.addSourceType = function addSourceType(name, SourceType, callback) { if (Style.getSourceType(name)) { return callback(new Error('A source type called "' + name + '" already exists.')); } Style.setSourceType(name, SourceType); if (!SourceType.workerSourceURL) { return callback(null, null); } this.dispatcher.broadcast('loadWorkerSource', { name: name, url: SourceType.workerSourceURL }, callback); }; Style.prototype.getLight = function getLight() { return this.light.getLight(); }; Style.prototype.setLight = function setLight(lightOptions, options) { if (options === void 0) options = {}; this._checkLoaded(); var light = this.light.getLight(); var _update = false; for (var key in lightOptions) { if (!performance.deepEqual(lightOptions[key], light[key])) { _update = true; break; } } if (!_update) { return; } var parameters = { now: performance.browser.now(), transition: performance.extend({ duration: 300, delay: 0 }, this.stylesheet.transition) }; this.light.setLight(lightOptions, options); this.light.updateTransitions(parameters); }; Style.prototype._validate = function _validate(validate, key, value, props, options) { if (options === void 0) options = {}; if (options && options.validate === false) { return false; } return emitValidationErrors(this, validate.call(performance.validateStyle, performance.extend({ key: key, style: this.serialize(), value: value, styleSpec: performance.styleSpec }, props))); }; Style.prototype._remove = function _remove() { if (this._request) { this._request.cancel(); this._request = null; } if (this._spriteRequest) { this._spriteRequest.cancel(); this._spriteRequest = null; } performance.evented.off('pluginStateChange', this._rtlTextPluginCallback); for (var layerId in this._layers) { var layer = this._layers[layerId]; layer.setEventedParent(null); } for (var id in this.sourceCaches) { this.sourceCaches[id].clearTiles(); this.sourceCaches[id].setEventedParent(null); } this.imageManager.setEventedParent(null); this.setEventedParent(null); this.dispatcher.remove(); }; Style.prototype._clearSource = function _clearSource(id) { this.sourceCaches[id].clearTiles(); }; Style.prototype._reloadSource = function _reloadSource(id) { this.sourceCaches[id].resume(); this.sourceCaches[id].reload(); }; Style.prototype._updateSources = function _updateSources(transform) { for (var id in this.sourceCaches) { this.sourceCaches[id].update(transform); } }; Style.prototype._generateCollisionBoxes = function _generateCollisionBoxes() { for (var id in this.sourceCaches) { this._reloadSource(id); } }; Style.prototype._updatePlacement = function _updatePlacement(transform, showCollisionBoxes, fadeDuration, crossSourceCollisions, forceFullPlacement) { if (forceFullPlacement === void 0) forceFullPlacement = false; var symbolBucketsChanged = false; var placementCommitted = false; var layerTiles = {}; for (var i = 0, list = this._order; i < list.length; i += 1) { var layerID = list[i]; var styleLayer = this._layers[layerID]; if (styleLayer.type !== 'symbol') { continue; } if (!layerTiles[styleLayer.source]) { var sourceCache = this.sourceCaches[styleLayer.source]; layerTiles[styleLayer.source] = sourceCache.getRenderableIds(true).map(function (id) { return sourceCache.getTileByID(id); }).sort(function (a, b) { return b.tileID.overscaledZ - a.tileID.overscaledZ || (a.tileID.isLessThan(b.tileID) ? -1 : 1); }); } var layerBucketsChanged = this.crossTileSymbolIndex.addLayer(styleLayer, layerTiles[styleLayer.source], transform.center.lng); symbolBucketsChanged = symbolBucketsChanged || layerBucketsChanged; } this.crossTileSymbolIndex.pruneUnusedLayers(this._order); forceFullPlacement = forceFullPlacement || this._layerOrderChanged || fadeDuration === 0; if (forceFullPlacement || !this.pauseablePlacement || this.pauseablePlacement.isDone() && !this.placement.stillRecent(performance.browser.now(), transform.zoom)) { this.pauseablePlacement = new PauseablePlacement(transform, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement); this._layerOrderChanged = false; } if (this.pauseablePlacement.isDone()) { this.placement.setStale(); } else { this.pauseablePlacement.continuePlacement(this._order, this._layers, layerTiles); if (this.pauseablePlacement.isDone()) { this.placement = this.pauseablePlacement.commit(performance.browser.now()); placementCommitted = true; } if (symbolBucketsChanged) { this.pauseablePlacement.placement.setStale(); } } if (placementCommitted || symbolBucketsChanged) { for (var i$1 = 0, list$1 = this._order; i$1 < list$1.length; i$1 += 1) { var layerID$1 = list$1[i$1]; var styleLayer$1 = this._layers[layerID$1]; if (styleLayer$1.type !== 'symbol') { continue; } this.placement.updateLayerOpacities(styleLayer$1, layerTiles[styleLayer$1.source]); } } var needsRerender = !this.pauseablePlacement.isDone() || this.placement.hasTransitions(performance.browser.now()); return needsRerender; }; Style.prototype._releaseSymbolFadeTiles = function _releaseSymbolFadeTiles() { for (var id in this.sourceCaches) { this.sourceCaches[id].releaseSymbolFadeTiles(); } }; Style.prototype.getImages = function getImages(mapId, params, callback) { this.imageManager.getImages(params.icons, callback); this._updateTilesForChangedImages(); var sourceCache = this.sourceCaches[params.source]; if (sourceCache) { sourceCache.setDependencies(params.tileID.key, params.type, params.icons); } }; Style.prototype.getGlyphs = function getGlyphs(mapId, params, callback) { this.glyphManager.getGlyphs(params.stacks, callback); }; Style.prototype.getResource = function getResource(mapId, params, callback) { return performance.makeRequest(params, callback); }; return Style; }(performance.Evented); Style.getSourceType = getType; Style.setSourceType = setType; Style.registerForPluginStateChange = performance.registerForPluginStateChange; var posAttributes = performance.createLayout([{ name: 'a_pos', type: 'Int16', components: 2 }]); var preludeFrag = "#ifdef GL_ES\nprecision mediump float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif"; var preludeVert = "#ifdef GL_ES\nprecision highp float;\n#else\n#if !defined(lowp)\n#define lowp\n#endif\n#if !defined(mediump)\n#define mediump\n#endif\n#if !defined(highp)\n#define highp\n#endif\n#endif\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const float packedOpacity) {int intOpacity=int(packedOpacity)/2;return vec2(float(intOpacity)/127.0,mod(packedOpacity,2.0));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0\n);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}"; var backgroundFrag = "uniform vec4 u_color;uniform float u_opacity;void main() {gl_FragColor=u_color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var backgroundVert = "attribute vec2 a_pos;uniform mat4 u_matrix;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);}"; var backgroundPatternFrag = "uniform vec2 u_pattern_tl_a;uniform vec2 u_pattern_br_a;uniform vec2 u_pattern_tl_b;uniform vec2 u_pattern_br_b;uniform vec2 u_texsize;uniform float u_mix;uniform float u_opacity;uniform sampler2D u_image;varying vec2 v_pos_a;varying vec2 v_pos_b;void main() {vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(u_pattern_tl_a/u_texsize,u_pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(u_pattern_tl_b/u_texsize,u_pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);gl_FragColor=mix(color1,color2,u_mix)*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var backgroundPatternVert = "uniform mat4 u_matrix;uniform vec2 u_pattern_size_a;uniform vec2 u_pattern_size_b;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_scale_a;uniform float u_scale_b;uniform float u_tile_units_to_pixels;attribute vec2 a_pos;varying vec2 v_pos_a;varying vec2 v_pos_b;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_a*u_pattern_size_a,u_tile_units_to_pixels,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_b*u_pattern_size_b,u_tile_units_to_pixels,a_pos);}"; var circleFrag = "varying vec3 v_data;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize mediump float radius\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize highp vec4 stroke_color\n#pragma mapbox: initialize mediump float stroke_width\n#pragma mapbox: initialize lowp float stroke_opacity\nvec2 extrude=v_data.xy;float extrude_length=length(extrude);lowp float antialiasblur=v_data.z;float antialiased_blur=-max(blur,antialiasblur);float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));gl_FragColor=opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var circleVert = "uniform mat4 u_matrix;uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;attribute vec2 a_pos;varying vec3 v_data;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define highp vec4 stroke_color\n#pragma mapbox: define mediump float stroke_width\n#pragma mapbox: define lowp float stroke_opacity\nvoid main(void) {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize mediump float radius\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize highp vec4 stroke_color\n#pragma mapbox: initialize mediump float stroke_width\n#pragma mapbox: initialize lowp float stroke_opacity\nvec2 extrude=vec2(mod(a_pos,2.0)*2.0-1.0);vec2 circle_center=floor(a_pos*0.5);if (u_pitch_with_map) {vec2 corner_position=circle_center;if (u_scale_with_map) {corner_position+=extrude*(radius+stroke_width)*u_extrude_scale;} else {vec4 projected_center=u_matrix*vec4(circle_center,0,1);corner_position+=extrude*(radius+stroke_width)*u_extrude_scale*(projected_center.w/u_camera_to_center_distance);}gl_Position=u_matrix*vec4(corner_position,0,1);} else {gl_Position=u_matrix*vec4(circle_center,0,1);if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}lowp float antialiasblur=1.0/u_device_pixel_ratio/(radius+stroke_width);v_data=vec3(extrude.x,extrude.y,antialiasblur);}"; var clippingMaskFrag = "void main() {gl_FragColor=vec4(1.0);}"; var clippingMaskVert = "attribute vec2 a_pos;uniform mat4 u_matrix;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);}"; var heatmapFrag = "uniform highp float u_intensity;varying vec2 v_extrude;\n#pragma mapbox: define highp float weight\n#define GAUSS_COEF 0.3989422804014327\nvoid main() {\n#pragma mapbox: initialize highp float weight\nfloat d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);gl_FragColor=vec4(val,1.0,1.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var heatmapVert = "uniform mat4 u_matrix;uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;attribute vec2 a_pos;varying vec2 v_extrude;\n#pragma mapbox: define highp float weight\n#pragma mapbox: define mediump float radius\nconst highp float ZERO=1.0/255.0/16.0;\n#define GAUSS_COEF 0.3989422804014327\nvoid main(void) {\n#pragma mapbox: initialize highp float weight\n#pragma mapbox: initialize mediump float radius\nvec2 unscaled_extrude=vec2(mod(a_pos,2.0)*2.0-1.0);float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec4 pos=vec4(floor(a_pos*0.5)+extrude,0,1);gl_Position=u_matrix*pos;}"; var heatmapTextureFrag = "uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;varying vec2 v_pos;void main() {float t=texture2D(u_image,v_pos).r;vec4 color=texture2D(u_color_ramp,vec2(t,0.5));gl_FragColor=color*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(0.0);\n#endif\n}"; var heatmapTextureVert = "uniform mat4 u_matrix;uniform vec2 u_world;attribute vec2 a_pos;varying vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"; var collisionBoxFrag = "varying float v_placed;varying float v_notUsed;void main() {float alpha=0.5;gl_FragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {gl_FragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {gl_FragColor*=.1;}}"; var collisionBoxVert = "attribute vec2 a_pos;attribute vec2 a_anchor_pos;attribute vec2 a_extrude;attribute vec2 a_placed;attribute vec2 a_shift;uniform mat4 u_matrix;uniform vec2 u_extrude_scale;uniform float u_camera_to_center_distance;varying float v_placed;varying float v_notUsed;void main() {vec4 projectedPoint=u_matrix*vec4(a_anchor_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float collision_perspective_ratio=clamp(0.5+0.5*(u_camera_to_center_distance/camera_to_anchor_distance),0.0,4.0);gl_Position=u_matrix*vec4(a_pos,0.0,1.0);gl_Position.xy+=(a_extrude+a_shift)*u_extrude_scale*gl_Position.w*collision_perspective_ratio;v_placed=a_placed.x;v_notUsed=a_placed.y;}"; var collisionCircleFrag = "varying float v_radius;varying vec2 v_extrude;varying float v_perspective_ratio;varying float v_collision;void main() {float alpha=0.5*min(v_perspective_ratio,1.0);float stroke_radius=0.9*max(v_perspective_ratio,1.0);float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);gl_FragColor=color*alpha*opacity_t;}"; var collisionCircleVert = "attribute vec2 a_pos;attribute float a_radius;attribute vec2 a_flags;uniform mat4 u_matrix;uniform mat4 u_inv_matrix;uniform vec2 u_viewport_size;uniform float u_camera_to_center_distance;varying float v_radius;varying vec2 v_extrude;varying float v_perspective_ratio;varying float v_collision;vec3 toTilePosition(vec2 screenPos) {vec4 rayStart=u_inv_matrix*vec4(screenPos,-1.0,1.0);vec4 rayEnd =u_inv_matrix*vec4(screenPos, 1.0,1.0);rayStart.xyz/=rayStart.w;rayEnd.xyz /=rayEnd.w;highp float t=(0.0-rayStart.z)/(rayEnd.z-rayStart.z);return mix(rayStart.xyz,rayEnd.xyz,t);}void main() {vec2 quadCenterPos=a_pos;float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;vec3 tilePos=toTilePosition(quadCenterPos);vec4 clipPos=u_matrix*vec4(tilePos,1.0);highp float camera_to_anchor_distance=clipPos.w;highp float collision_perspective_ratio=clamp(0.5+0.5*(u_camera_to_center_distance/camera_to_anchor_distance),0.0,4.0);float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_perspective_ratio=collision_perspective_ratio;v_collision=collision;gl_Position=vec4(clipPos.xyz/clipPos.w,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"; var debugFrag = "uniform highp vec4 u_color;uniform sampler2D u_overlay;varying vec2 v_uv;void main() {vec4 overlay_color=texture2D(u_overlay,v_uv);gl_FragColor=mix(u_color,overlay_color,overlay_color.a);}"; var debugVert = "attribute vec2 a_pos;varying vec2 v_uv;uniform mat4 u_matrix;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=u_matrix*vec4(a_pos*u_overlay_scale,0,1);}"; var fillFrag = "#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float opacity\ngl_FragColor=color*opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillVert = "attribute vec2 a_pos;uniform mat4 u_matrix;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float opacity\ngl_Position=u_matrix*vec4(a_pos,0,1);}"; var fillOutlineFrag = "varying vec2 v_pos;\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 outline_color\n#pragma mapbox: initialize lowp float opacity\nfloat dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);gl_FragColor=outline_color*(alpha*opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillOutlineVert = "attribute vec2 a_pos;uniform mat4 u_matrix;uniform vec2 u_world;varying vec2 v_pos;\n#pragma mapbox: define highp vec4 outline_color\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 outline_color\n#pragma mapbox: initialize lowp float opacity\ngl_Position=u_matrix*vec4(a_pos,0,1);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;}"; var fillOutlinePatternFrag = "uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec2 v_pos;\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);gl_FragColor=mix(color1,color2,u_fade)*alpha*opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillOutlinePatternVert = "uniform mat4 u_matrix;uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;attribute vec2 a_pos;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec2 v_pos;\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=u_matrix*vec4(a_pos,0,1);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;}"; var fillPatternFrag = "uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;varying vec2 v_pos_a;varying vec2 v_pos_b;\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);gl_FragColor=mix(color1,color2,u_fade)*opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillPatternVert = "uniform mat4 u_matrix;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;attribute vec2 a_pos;varying vec2 v_pos_a;varying vec2 v_pos_b;\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=u_matrix*vec4(a_pos,0,1);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}"; var fillExtrusionFrag = "varying vec4 v_color;void main() {gl_FragColor=v_color;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillExtrusionVert = "uniform mat4 u_matrix;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;attribute vec2 a_pos;attribute vec4 a_normal_ed;varying vec4 v_color;\n#pragma mapbox: define highp float base\n#pragma mapbox: define highp float height\n#pragma mapbox: define highp vec4 color\nvoid main() {\n#pragma mapbox: initialize highp float base\n#pragma mapbox: initialize highp float height\n#pragma mapbox: initialize highp vec4 color\nvec3 normal=a_normal_ed.xyz;base=max(0.0,base);height=max(0.0,height);float t=mod(normal.x,2.0);gl_Position=u_matrix*vec4(a_pos,t > 0.0 ? height : base,1);float colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;float directional=clamp(dot(normal/16384.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}"; var fillExtrusionPatternFrag = "uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec4 v_lighting;\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\nvoid main() {\n#pragma mapbox: initialize lowp float base\n#pragma mapbox: initialize lowp float height\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);gl_FragColor=mixedColor*v_lighting;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var fillExtrusionPatternVert = "uniform mat4 u_matrix;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp float u_lightintensity;attribute vec2 a_pos;attribute vec4 a_normal_ed;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec4 v_lighting;\n#pragma mapbox: define lowp float base\n#pragma mapbox: define lowp float height\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\nvoid main() {\n#pragma mapbox: initialize lowp float base\n#pragma mapbox: initialize lowp float height\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=a_normal_ed.xyz;float edgedistance=a_normal_ed.w;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;base=max(0.0,base);height=max(0.0,height);float t=mod(normal.x,2.0);float z=t > 0.0 ? height : base;gl_Position=u_matrix*vec4(a_pos,z,1);vec2 pos=normal.x==1.0 && normal.y==0.0 && normal.z==16384.0\n? a_pos\n: vec2(edgedistance,z*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}"; var hillshadePrepareFrag = "#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D u_image;varying vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(vec2 coord,float bias) {vec4 data=texture2D(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack)/4.0;}void main() {vec2 epsilon=1.0/u_dimension;float a=getElevation(v_pos+vec2(-epsilon.x,-epsilon.y),0.0);float b=getElevation(v_pos+vec2(0,-epsilon.y),0.0);float c=getElevation(v_pos+vec2(epsilon.x,-epsilon.y),0.0);float d=getElevation(v_pos+vec2(-epsilon.x,0),0.0);float e=getElevation(v_pos,0.0);float f=getElevation(v_pos+vec2(epsilon.x,0),0.0);float g=getElevation(v_pos+vec2(-epsilon.x,epsilon.y),0.0);float h=getElevation(v_pos+vec2(0,epsilon.y),0.0);float i=getElevation(v_pos+vec2(epsilon.x,epsilon.y),0.0);float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))/pow(2.0,exaggeration+(19.2562-u_zoom));gl_FragColor=clamp(vec4(deriv.x/2.0+0.5,deriv.y/2.0+0.5,1.0,1.0),0.0,1.0);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var hillshadePrepareVert = "uniform mat4 u_matrix;uniform vec2 u_dimension;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"; var hillshadeFrag = "uniform sampler2D u_image;varying vec2 v_pos;uniform vec2 u_latrange;uniform vec2 u_light;uniform vec4 u_shadow;uniform vec4 u_highlight;uniform vec4 u_accent;\n#define PI 3.141592653589793\nvoid main() {vec4 pixel=texture2D(u_image,v_pos);vec2 deriv=((pixel.rg*2.0)-1.0);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));float slope=atan(1.25*length(deriv)/scaleFactor);float aspect=deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);float intensity=u_light.x;float azimuth=u_light.y+PI;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadow,u_highlight,shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);gl_FragColor=accent_color*(1.0-shade_color.a)+shade_color;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var hillshadeVert = "uniform mat4 u_matrix;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);v_pos=a_texture_pos/8192.0;}"; var lineFrag = "uniform lowp float u_device_pixel_ratio;varying vec2 v_width2;varying vec2 v_normal;varying float v_gamma_scale;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);gl_FragColor=color*(alpha*opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var lineVert = "\n#define scale 0.015873016\nattribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;varying vec2 v_normal;varying vec2 v_width2;varying float v_gamma_scale;varying highp float v_linesofar;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump float gapwidth\n#pragma mapbox: initialize lowp float offset\n#pragma mapbox: initialize mediump float width\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;v_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*2.0;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_width2=vec2(outset,inset);}"; var lineGradientFrag = "uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;varying vec2 v_width2;varying vec2 v_normal;varying float v_gamma_scale;varying highp vec2 v_uv;\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture2D(u_image,v_uv);gl_FragColor=color*(alpha*opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var lineGradientVert = "\n#define scale 0.015873016\nattribute vec2 a_pos_normal;attribute vec4 a_data;attribute float a_uv_x;attribute float a_split_index;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;varying vec2 v_normal;varying vec2 v_width2;varying float v_gamma_scale;varying highp vec2 v_uv;\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\nvoid main() {\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump float gapwidth\n#pragma mapbox: initialize lowp float offset\n#pragma mapbox: initialize mediump float width\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_width2=vec2(outset,inset);}"; var linePatternFrag = "uniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;varying vec2 v_normal;varying vec2 v_width2;varying float v_linesofar;varying float v_gamma_scale;varying float v_width;\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture2D(u_image,pos_a),texture2D(u_image,pos_b),u_fade);gl_FragColor=color*alpha*opacity;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var linePatternVert = "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nattribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;varying vec2 v_normal;varying vec2 v_width2;varying float v_linesofar;varying float v_gamma_scale;varying float v_width;\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_to\n#pragma mapbox: define lowp float pixel_ratio_from\n#pragma mapbox: define lowp float pixel_ratio_to\nvoid main() {\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize lowp float offset\n#pragma mapbox: initialize mediump float gapwidth\n#pragma mapbox: initialize mediump float width\n#pragma mapbox: initialize lowp float floorwidth\n#pragma mapbox: initialize mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_to\n#pragma mapbox: initialize lowp float pixel_ratio_from\n#pragma mapbox: initialize lowp float pixel_ratio_to\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}"; var lineSDFFrag = "uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform float u_sdfgamma;uniform float u_mix;varying vec2 v_normal;varying vec2 v_width2;varying vec2 v_tex_a;varying vec2 v_tex_b;varying float v_gamma_scale;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump float width\n#pragma mapbox: initialize lowp float floorwidth\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture2D(u_image,v_tex_a).a;float sdfdist_b=texture2D(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);alpha*=smoothstep(0.5-u_sdfgamma/floorwidth,0.5+u_sdfgamma/floorwidth,sdfdist);gl_FragColor=color*(alpha*opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var lineSDFVert = "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nattribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_patternscale_a;uniform float u_tex_y_a;uniform vec2 u_patternscale_b;uniform float u_tex_y_b;uniform vec2 u_units_to_pixels;varying vec2 v_normal;varying vec2 v_width2;varying vec2 v_tex_a;varying vec2 v_tex_b;varying float v_gamma_scale;\n#pragma mapbox: define highp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define mediump float gapwidth\n#pragma mapbox: define lowp float offset\n#pragma mapbox: define mediump float width\n#pragma mapbox: define lowp float floorwidth\nvoid main() {\n#pragma mapbox: initialize highp vec4 color\n#pragma mapbox: initialize lowp float blur\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize mediump float gapwidth\n#pragma mapbox: initialize lowp float offset\n#pragma mapbox: initialize mediump float width\n#pragma mapbox: initialize lowp float floorwidth\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_tex_a=vec2(a_linesofar*u_patternscale_a.x/floorwidth,normal.y*u_patternscale_a.y+u_tex_y_a);v_tex_b=vec2(a_linesofar*u_patternscale_b.x/floorwidth,normal.y*u_patternscale_b.y+u_tex_y_b);v_width2=vec2(outset,inset);}"; var rasterFrag = "uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;varying vec2 v_pos0;varying vec2 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture2D(u_image0,v_pos0);vec4 color1=texture2D(u_image1,v_pos1);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);gl_FragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var rasterVert = "uniform mat4 u_matrix;uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos0;varying vec2 v_pos1;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);v_pos0=(((a_texture_pos/8192.0)-0.5)/u_buffer_scale )+0.5;v_pos1=(v_pos0*u_scale_parent)+u_tl_parent;}"; var symbolIconFrag = "uniform sampler2D u_texture;varying vec2 v_tex;varying float v_fade_opacity;\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\nlowp float alpha=opacity*v_fade_opacity;gl_FragColor=texture2D(u_texture,v_tex)*alpha;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var symbolIconVert = "const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec4 a_pixeloffset;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;varying vec2 v_tex;varying float v_fade_opacity;\n#pragma mapbox: define lowp float opacity\nvoid main() {\n#pragma mapbox: initialize lowp float opacity\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0),0.0,1.0);v_tex=a_tex/u_texsize;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;v_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));}"; var symbolSDFFrag = "#define SDF_PX 8.0\nuniform bool u_is_halo;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;varying vec2 v_data0;varying vec3 v_data1;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\nvoid main() {\n#pragma mapbox: initialize highp vec4 fill_color\n#pragma mapbox: initialize highp vec4 halo_color\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize lowp float halo_width\n#pragma mapbox: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float fade_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture2D(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);gl_FragColor=color*(alpha*opacity*fade_opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var symbolSDFVert = "const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec4 a_pixeloffset;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;varying vec2 v_data0;varying vec3 v_data1;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\nvoid main() {\n#pragma mapbox: initialize highp vec4 fill_color\n#pragma mapbox: initialize highp vec4 halo_color\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize lowp float halo_width\n#pragma mapbox: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale+a_pxoffset),0.0,1.0);float gamma_scale=gl_Position.w;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,interpolated_fade_opacity);}"; var symbolTextAndIconFrag = "#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;varying vec4 v_data0;varying vec4 v_data1;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\nvoid main() {\n#pragma mapbox: initialize highp vec4 fill_color\n#pragma mapbox: initialize highp vec4 halo_color\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize lowp float halo_width\n#pragma mapbox: initialize lowp float halo_blur\nfloat fade_opacity=v_data1[2];if (v_data1.w==ICON) {vec2 tex_icon=v_data0.zw;lowp float alpha=opacity*fade_opacity;gl_FragColor=texture2D(u_texture_icon,tex_icon)*alpha;\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture2D(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);gl_FragColor=color*(alpha*opacity*fade_opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; var symbolTextAndIconVert = "const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;varying vec4 v_data0;varying vec4 v_data1;\n#pragma mapbox: define highp vec4 fill_color\n#pragma mapbox: define highp vec4 halo_color\n#pragma mapbox: define lowp float opacity\n#pragma mapbox: define lowp float halo_width\n#pragma mapbox: define lowp float halo_blur\nvoid main() {\n#pragma mapbox: initialize highp vec4 fill_color\n#pragma mapbox: initialize highp vec4 halo_color\n#pragma mapbox: initialize lowp float opacity\n#pragma mapbox: initialize lowp float halo_width\n#pragma mapbox: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);float is_sdf=a_size[0]-2.0*a_size_min;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale),0.0,1.0);float gamma_scale=gl_Position.w;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec4(gamma_scale,size,interpolated_fade_opacity,is_sdf);}"; var prelude = compile(preludeFrag, preludeVert); var background = compile(backgroundFrag, backgroundVert); var backgroundPattern = compile(backgroundPatternFrag, backgroundPatternVert); var circle = compile(circleFrag, circleVert); var clippingMask = compile(clippingMaskFrag, clippingMaskVert); var heatmap = compile(heatmapFrag, heatmapVert); var heatmapTexture = compile(heatmapTextureFrag, heatmapTextureVert); var collisionBox = compile(collisionBoxFrag, collisionBoxVert); var collisionCircle = compile(collisionCircleFrag, collisionCircleVert); var debug = compile(debugFrag, debugVert); var fill = compile(fillFrag, fillVert); var fillOutline = compile(fillOutlineFrag, fillOutlineVert); var fillOutlinePattern = compile(fillOutlinePatternFrag, fillOutlinePatternVert); var fillPattern = compile(fillPatternFrag, fillPatternVert); var fillExtrusion = compile(fillExtrusionFrag, fillExtrusionVert); var fillExtrusionPattern = compile(fillExtrusionPatternFrag, fillExtrusionPatternVert); var hillshadePrepare = compile(hillshadePrepareFrag, hillshadePrepareVert); var hillshade = compile(hillshadeFrag, hillshadeVert); var line = compile(lineFrag, lineVert); var lineGradient = compile(lineGradientFrag, lineGradientVert); var linePattern = compile(linePatternFrag, linePatternVert); var lineSDF = compile(lineSDFFrag, lineSDFVert); var raster = compile(rasterFrag, rasterVert); var symbolIcon = compile(symbolIconFrag, symbolIconVert); var symbolSDF = compile(symbolSDFFrag, symbolSDFVert); var symbolTextAndIcon = compile(symbolTextAndIconFrag, symbolTextAndIconVert); function compile(fragmentSource, vertexSource) { var re = /#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g; var staticAttributes = vertexSource.match(/attribute ([\w]+) ([\w]+)/g); var fragmentUniforms = fragmentSource.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g); var vertexUniforms = vertexSource.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g); var staticUniforms = vertexUniforms ? vertexUniforms.concat(fragmentUniforms) : fragmentUniforms; var fragmentPragmas = {}; fragmentSource = fragmentSource.replace(re, function (match, operation, precision, type, name) { fragmentPragmas[name] = true; if (operation === 'define') { return '\n#ifndef HAS_UNIFORM_u_' + name + '\nvarying ' + precision + ' ' + type + ' ' + name + ';\n#else\nuniform ' + precision + ' ' + type + ' u_' + name + ';\n#endif\n'; } else { return '\n#ifdef HAS_UNIFORM_u_' + name + '\n ' + precision + ' ' + type + ' ' + name + ' = u_' + name + ';\n#endif\n'; } }); vertexSource = vertexSource.replace(re, function (match, operation, precision, type, name) { var attrType = type === 'float' ? 'vec2' : 'vec4'; var unpackType = name.match(/color/) ? 'color' : attrType; if (fragmentPragmas[name]) { if (operation === 'define') { return '\n#ifndef HAS_UNIFORM_u_' + name + '\nuniform lowp float u_' + name + '_t;\nattribute ' + precision + ' ' + attrType + ' a_' + name + ';\nvarying ' + precision + ' ' + type + ' ' + name + ';\n#else\nuniform ' + precision + ' ' + type + ' u_' + name + ';\n#endif\n'; } else { if (unpackType === 'vec4') { return '\n#ifndef HAS_UNIFORM_u_' + name + '\n ' + name + ' = a_' + name + ';\n#else\n ' + precision + ' ' + type + ' ' + name + ' = u_' + name + ';\n#endif\n'; } else { return '\n#ifndef HAS_UNIFORM_u_' + name + '\n ' + name + ' = unpack_mix_' + unpackType + '(a_' + name + ', u_' + name + '_t);\n#else\n ' + precision + ' ' + type + ' ' + name + ' = u_' + name + ';\n#endif\n'; } } } else { if (operation === 'define') { return '\n#ifndef HAS_UNIFORM_u_' + name + '\nuniform lowp float u_' + name + '_t;\nattribute ' + precision + ' ' + attrType + ' a_' + name + ';\n#else\nuniform ' + precision + ' ' + type + ' u_' + name + ';\n#endif\n'; } else { if (unpackType === 'vec4') { return '\n#ifndef HAS_UNIFORM_u_' + name + '\n ' + precision + ' ' + type + ' ' + name + ' = a_' + name + ';\n#else\n ' + precision + ' ' + type + ' ' + name + ' = u_' + name + ';\n#endif\n'; } else { return '\n#ifndef HAS_UNIFORM_u_' + name + '\n ' + precision + ' ' + type + ' ' + name + ' = unpack_mix_' + unpackType + '(a_' + name + ', u_' + name + '_t);\n#else\n ' + precision + ' ' + type + ' ' + name + ' = u_' + name + ';\n#endif\n'; } } } }); return { fragmentSource: fragmentSource, vertexSource: vertexSource, staticAttributes: staticAttributes, staticUniforms: staticUniforms }; } var shaders = /*#__PURE__*/Object.freeze({ __proto__: null, prelude: prelude, background: background, backgroundPattern: backgroundPattern, circle: circle, clippingMask: clippingMask, heatmap: heatmap, heatmapTexture: heatmapTexture, collisionBox: collisionBox, collisionCircle: collisionCircle, debug: debug, fill: fill, fillOutline: fillOutline, fillOutlinePattern: fillOutlinePattern, fillPattern: fillPattern, fillExtrusion: fillExtrusion, fillExtrusionPattern: fillExtrusionPattern, hillshadePrepare: hillshadePrepare, hillshade: hillshade, line: line, lineGradient: lineGradient, linePattern: linePattern, lineSDF: lineSDF, raster: raster, symbolIcon: symbolIcon, symbolSDF: symbolSDF, symbolTextAndIcon: symbolTextAndIcon }); var VertexArrayObject = function VertexArrayObject() { this.boundProgram = null; this.boundLayoutVertexBuffer = null; this.boundPaintVertexBuffers = []; this.boundIndexBuffer = null; this.boundVertexOffset = null; this.boundDynamicVertexBuffer = null; this.vao = null; }; VertexArrayObject.prototype.bind = function bind(context, program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2) { this.context = context; var paintBuffersDiffer = this.boundPaintVertexBuffers.length !== paintVertexBuffers.length; for (var i = 0; !paintBuffersDiffer && i < paintVertexBuffers.length; i++) { if (this.boundPaintVertexBuffers[i] !== paintVertexBuffers[i]) { paintBuffersDiffer = true; } } var isFreshBindRequired = !this.vao || this.boundProgram !== program || this.boundLayoutVertexBuffer !== layoutVertexBuffer || paintBuffersDiffer || this.boundIndexBuffer !== indexBuffer || this.boundVertexOffset !== vertexOffset || this.boundDynamicVertexBuffer !== dynamicVertexBuffer || this.boundDynamicVertexBuffer2 !== dynamicVertexBuffer2; if (!context.extVertexArrayObject || isFreshBindRequired) { this.freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2); } else { context.bindVertexArrayOES.set(this.vao); if (dynamicVertexBuffer) { dynamicVertexBuffer.bind(); } if (indexBuffer && indexBuffer.dynamicDraw) { indexBuffer.bind(); } if (dynamicVertexBuffer2) { dynamicVertexBuffer2.bind(); } } }; VertexArrayObject.prototype.freshBind = function freshBind(program, layoutVertexBuffer, paintVertexBuffers, indexBuffer, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2) { var numPrevAttributes; var numNextAttributes = program.numAttributes; var context = this.context; var gl = context.gl; if (context.extVertexArrayObject) { if (this.vao) { this.destroy(); } this.vao = context.extVertexArrayObject.createVertexArrayOES(); context.bindVertexArrayOES.set(this.vao); numPrevAttributes = 0; this.boundProgram = program; this.boundLayoutVertexBuffer = layoutVertexBuffer; this.boundPaintVertexBuffers = paintVertexBuffers; this.boundIndexBuffer = indexBuffer; this.boundVertexOffset = vertexOffset; this.boundDynamicVertexBuffer = dynamicVertexBuffer; this.boundDynamicVertexBuffer2 = dynamicVertexBuffer2; } else { numPrevAttributes = context.currentNumAttributes || 0; for (var i = numNextAttributes; i < numPrevAttributes; i++) { gl.disableVertexAttribArray(i); } } layoutVertexBuffer.enableAttributes(gl, program); for (var i$1 = 0, list = paintVertexBuffers; i$1 < list.length; i$1 += 1) { var vertexBuffer = list[i$1]; vertexBuffer.enableAttributes(gl, program); } if (dynamicVertexBuffer) { dynamicVertexBuffer.enableAttributes(gl, program); } if (dynamicVertexBuffer2) { dynamicVertexBuffer2.enableAttributes(gl, program); } layoutVertexBuffer.bind(); layoutVertexBuffer.setVertexAttribPointers(gl, program, vertexOffset); for (var i$2 = 0, list$1 = paintVertexBuffers; i$2 < list$1.length; i$2 += 1) { var vertexBuffer$1 = list$1[i$2]; vertexBuffer$1.bind(); vertexBuffer$1.setVertexAttribPointers(gl, program, vertexOffset); } if (dynamicVertexBuffer) { dynamicVertexBuffer.bind(); dynamicVertexBuffer.setVertexAttribPointers(gl, program, vertexOffset); } if (indexBuffer) { indexBuffer.bind(); } if (dynamicVertexBuffer2) { dynamicVertexBuffer2.bind(); dynamicVertexBuffer2.setVertexAttribPointers(gl, program, vertexOffset); } context.currentNumAttributes = numNextAttributes; }; VertexArrayObject.prototype.destroy = function destroy() { if (this.vao) { this.context.extVertexArrayObject.deleteVertexArrayOES(this.vao); this.vao = null; } }; function getTokenizedAttributesAndUniforms(array) { var result = []; for (var i = 0; i < array.length; i++) { if (array[i] === null) { continue; } var token = array[i].split(' '); result.push(token.pop()); } return result; } var Program$1 = function Program(context, name, source, configuration, fixedUniforms, showOverdrawInspector) { var gl = context.gl; this.program = gl.createProgram(); var staticAttrInfo = getTokenizedAttributesAndUniforms(source.staticAttributes); var dynamicAttrInfo = configuration ? configuration.getBinderAttributes() : []; var allAttrInfo = staticAttrInfo.concat(dynamicAttrInfo); var staticUniformsInfo = source.staticUniforms ? getTokenizedAttributesAndUniforms(source.staticUniforms) : []; var dynamicUniformsInfo = configuration ? configuration.getBinderUniforms() : []; var uniformList = staticUniformsInfo.concat(dynamicUniformsInfo); var allUniformsInfo = []; for (var i$1 = 0, list = uniformList; i$1 < list.length; i$1 += 1) { var uniform = list[i$1]; if (allUniformsInfo.indexOf(uniform) < 0) { allUniformsInfo.push(uniform); } } var defines = configuration ? configuration.defines() : []; if (showOverdrawInspector) { defines.push('#define OVERDRAW_INSPECTOR;'); } var fragmentSource = defines.concat(prelude.fragmentSource, source.fragmentSource).join('\n'); var vertexSource = defines.concat(prelude.vertexSource, source.vertexSource).join('\n'); var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); if (gl.isContextLost()) { this.failedToCreate = true; return; } gl.shaderSource(fragmentShader, fragmentSource); gl.compileShader(fragmentShader); gl.attachShader(this.program, fragmentShader); var vertexShader = gl.createShader(gl.VERTEX_SHADER); if (gl.isContextLost()) { this.failedToCreate = true; return; } gl.shaderSource(vertexShader, vertexSource); gl.compileShader(vertexShader); gl.attachShader(this.program, vertexShader); this.attributes = {}; var uniformLocations = {}; this.numAttributes = allAttrInfo.length; for (var i = 0; i < this.numAttributes; i++) { if (allAttrInfo[i]) { gl.bindAttribLocation(this.program, i, allAttrInfo[i]); this.attributes[allAttrInfo[i]] = i; } } gl.linkProgram(this.program); gl.deleteShader(vertexShader); gl.deleteShader(fragmentShader); for (var it = 0; it < allUniformsInfo.length; it++) { var uniform$1 = allUniformsInfo[it]; if (uniform$1 && !uniformLocations[uniform$1]) { var uniformLocation = gl.getUniformLocation(this.program, uniform$1); if (uniformLocation) { uniformLocations[uniform$1] = uniformLocation; } } } this.fixedUniforms = fixedUniforms(context, uniformLocations); this.binderUniforms = configuration ? configuration.getUniforms(context, uniformLocations) : []; }; Program$1.prototype.draw = function draw(context, drawMode, depthMode, stencilMode, colorMode, cullFaceMode, uniformValues, layerID, layoutVertexBuffer, indexBuffer, segments, currentProperties, zoom, configuration, dynamicLayoutBuffer, dynamicLayoutBuffer2) { var obj; var gl = context.gl; if (this.failedToCreate) { return; } context.program.set(this.program); context.setDepthMode(depthMode); context.setStencilMode(stencilMode); context.setColorMode(colorMode); context.setCullFace(cullFaceMode); for (var name in this.fixedUniforms) { this.fixedUniforms[name].set(uniformValues[name]); } if (configuration) { configuration.setUniforms(context, this.binderUniforms, currentProperties, { zoom: zoom }); } var primitiveSize = (obj = {}, obj[gl.LINES] = 2, obj[gl.TRIANGLES] = 3, obj[gl.LINE_STRIP] = 1, obj)[drawMode]; for (var i = 0, list = segments.get(); i < list.length; i += 1) { var segment = list[i]; var vaos = segment.vaos || (segment.vaos = {}); var vao = vaos[layerID] || (vaos[layerID] = new VertexArrayObject()); vao.bind(context, this, layoutVertexBuffer, configuration ? configuration.getPaintVertexBuffers() : [], indexBuffer, segment.vertexOffset, dynamicLayoutBuffer, dynamicLayoutBuffer2); gl.drawElements(drawMode, segment.primitiveLength * primitiveSize, gl.UNSIGNED_SHORT, segment.primitiveOffset * primitiveSize * 2); } }; function patternUniformValues(crossfade, painter, tile) { var tileRatio = 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom); var numTiles = Math.pow(2, tile.tileID.overscaledZ); var tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles; var pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles); var pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y; return { 'u_image': 0, 'u_texsize': tile.imageAtlasTexture.size, 'u_scale': [ tileRatio, crossfade.fromScale, crossfade.toScale ], 'u_fade': crossfade.t, 'u_pixel_coord_upper': [ pixelX >> 16, pixelY >> 16 ], 'u_pixel_coord_lower': [ pixelX & 65535, pixelY & 65535 ] }; } function bgPatternUniformValues(image, crossfade, painter, tile) { var imagePosA = painter.imageManager.getPattern(image.from.toString()); var imagePosB = painter.imageManager.getPattern(image.to.toString()); var ref = painter.imageManager.getPixelSize(); var width = ref.width; var height = ref.height; var numTiles = Math.pow(2, tile.tileID.overscaledZ); var tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles; var pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles); var pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y; return { 'u_image': 0, 'u_pattern_tl_a': imagePosA.tl, 'u_pattern_br_a': imagePosA.br, 'u_pattern_tl_b': imagePosB.tl, 'u_pattern_br_b': imagePosB.br, 'u_texsize': [ width, height ], 'u_mix': crossfade.t, 'u_pattern_size_a': imagePosA.displaySize, 'u_pattern_size_b': imagePosB.displaySize, 'u_scale_a': crossfade.fromScale, 'u_scale_b': crossfade.toScale, 'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom), 'u_pixel_coord_upper': [ pixelX >> 16, pixelY >> 16 ], 'u_pixel_coord_lower': [ pixelX & 65535, pixelY & 65535 ] }; } var fillExtrusionUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_lightpos': new performance.Uniform3f(context, locations.u_lightpos), 'u_lightintensity': new performance.Uniform1f(context, locations.u_lightintensity), 'u_lightcolor': new performance.Uniform3f(context, locations.u_lightcolor), 'u_vertical_gradient': new performance.Uniform1f(context, locations.u_vertical_gradient), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity) }; }; var fillExtrusionPatternUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_lightpos': new performance.Uniform3f(context, locations.u_lightpos), 'u_lightintensity': new performance.Uniform1f(context, locations.u_lightintensity), 'u_lightcolor': new performance.Uniform3f(context, locations.u_lightcolor), 'u_vertical_gradient': new performance.Uniform1f(context, locations.u_vertical_gradient), 'u_height_factor': new performance.Uniform1f(context, locations.u_height_factor), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_pixel_coord_upper': new performance.Uniform2f(context, locations.u_pixel_coord_upper), 'u_pixel_coord_lower': new performance.Uniform2f(context, locations.u_pixel_coord_lower), 'u_scale': new performance.Uniform3f(context, locations.u_scale), 'u_fade': new performance.Uniform1f(context, locations.u_fade), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity) }; }; var fillExtrusionUniformValues = function (matrix, painter, shouldUseVerticalGradient, opacity) { var light = painter.style.light; var _lp = light.properties.get('position'); var lightPos = [ _lp.x, _lp.y, _lp.z ]; var lightMat = performance.create$1(); if (light.properties.get('anchor') === 'viewport') { performance.fromRotation(lightMat, -painter.transform.angle); } performance.transformMat3(lightPos, lightPos, lightMat); var lightColor = light.properties.get('color'); return { 'u_matrix': matrix, 'u_lightpos': lightPos, 'u_lightintensity': light.properties.get('intensity'), 'u_lightcolor': [ lightColor.r, lightColor.g, lightColor.b ], 'u_vertical_gradient': +shouldUseVerticalGradient, 'u_opacity': opacity }; }; var fillExtrusionPatternUniformValues = function (matrix, painter, shouldUseVerticalGradient, opacity, coord, crossfade, tile) { return performance.extend(fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity), patternUniformValues(crossfade, painter, tile), { 'u_height_factor': -Math.pow(2, coord.overscaledZ) / tile.tileSize / 8 }); }; var fillUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix) }; }; var fillPatternUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_pixel_coord_upper': new performance.Uniform2f(context, locations.u_pixel_coord_upper), 'u_pixel_coord_lower': new performance.Uniform2f(context, locations.u_pixel_coord_lower), 'u_scale': new performance.Uniform3f(context, locations.u_scale), 'u_fade': new performance.Uniform1f(context, locations.u_fade) }; }; var fillOutlineUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_world': new performance.Uniform2f(context, locations.u_world) }; }; var fillOutlinePatternUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_world': new performance.Uniform2f(context, locations.u_world), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_pixel_coord_upper': new performance.Uniform2f(context, locations.u_pixel_coord_upper), 'u_pixel_coord_lower': new performance.Uniform2f(context, locations.u_pixel_coord_lower), 'u_scale': new performance.Uniform3f(context, locations.u_scale), 'u_fade': new performance.Uniform1f(context, locations.u_fade) }; }; var fillUniformValues = function (matrix) { return { 'u_matrix': matrix }; }; var fillPatternUniformValues = function (matrix, painter, crossfade, tile) { return performance.extend(fillUniformValues(matrix), patternUniformValues(crossfade, painter, tile)); }; var fillOutlineUniformValues = function (matrix, drawingBufferSize) { return { 'u_matrix': matrix, 'u_world': drawingBufferSize }; }; var fillOutlinePatternUniformValues = function (matrix, painter, crossfade, tile, drawingBufferSize) { return performance.extend(fillPatternUniformValues(matrix, painter, crossfade, tile), { 'u_world': drawingBufferSize }); }; var circleUniforms = function (context, locations) { return { 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_scale_with_map': new performance.Uniform1i(context, locations.u_scale_with_map), 'u_pitch_with_map': new performance.Uniform1i(context, locations.u_pitch_with_map), 'u_extrude_scale': new performance.Uniform2f(context, locations.u_extrude_scale), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix) }; }; var circleUniformValues = function (painter, coord, tile, layer) { var transform = painter.transform; var pitchWithMap, extrudeScale; if (layer.paint.get('circle-pitch-alignment') === 'map') { var pixelRatio = pixelsToTileUnits(tile, 1, transform.zoom); pitchWithMap = true; extrudeScale = [ pixelRatio, pixelRatio ]; } else { pitchWithMap = false; extrudeScale = transform.pixelsToGLUnits; } return { 'u_camera_to_center_distance': transform.cameraToCenterDistance, 'u_scale_with_map': +(layer.paint.get('circle-pitch-scale') === 'map'), 'u_matrix': painter.translatePosMatrix(coord.posMatrix, tile, layer.paint.get('circle-translate'), layer.paint.get('circle-translate-anchor')), 'u_pitch_with_map': +pitchWithMap, 'u_device_pixel_ratio': performance.browser.devicePixelRatio, 'u_extrude_scale': extrudeScale }; }; var collisionUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_pixels_to_tile_units': new performance.Uniform1f(context, locations.u_pixels_to_tile_units), 'u_extrude_scale': new performance.Uniform2f(context, locations.u_extrude_scale), 'u_overscale_factor': new performance.Uniform1f(context, locations.u_overscale_factor) }; }; var collisionCircleUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_inv_matrix': new performance.UniformMatrix4f(context, locations.u_inv_matrix), 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_viewport_size': new performance.Uniform2f(context, locations.u_viewport_size) }; }; var collisionUniformValues = function (matrix, transform, tile) { var pixelRatio = pixelsToTileUnits(tile, 1, transform.zoom); var scale = Math.pow(2, transform.zoom - tile.tileID.overscaledZ); var overscaleFactor = tile.tileID.overscaleFactor(); return { 'u_matrix': matrix, 'u_camera_to_center_distance': transform.cameraToCenterDistance, 'u_pixels_to_tile_units': pixelRatio, 'u_extrude_scale': [ transform.pixelsToGLUnits[0] / (pixelRatio * scale), transform.pixelsToGLUnits[1] / (pixelRatio * scale) ], 'u_overscale_factor': overscaleFactor }; }; var collisionCircleUniformValues = function (matrix, invMatrix, transform) { return { 'u_matrix': matrix, 'u_inv_matrix': invMatrix, 'u_camera_to_center_distance': transform.cameraToCenterDistance, 'u_viewport_size': [ transform.width, transform.height ] }; }; var debugUniforms = function (context, locations) { return { 'u_color': new performance.UniformColor(context, locations.u_color), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_overlay': new performance.Uniform1i(context, locations.u_overlay), 'u_overlay_scale': new performance.Uniform1f(context, locations.u_overlay_scale) }; }; var debugUniformValues = function (matrix, color, scaleRatio) { if (scaleRatio === void 0) scaleRatio = 1; return { 'u_matrix': matrix, 'u_color': color, 'u_overlay': 0, 'u_overlay_scale': scaleRatio }; }; var clippingMaskUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix) }; }; var clippingMaskUniformValues = function (matrix) { return { 'u_matrix': matrix }; }; var heatmapUniforms = function (context, locations) { return { 'u_extrude_scale': new performance.Uniform1f(context, locations.u_extrude_scale), 'u_intensity': new performance.Uniform1f(context, locations.u_intensity), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix) }; }; var heatmapTextureUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_world': new performance.Uniform2f(context, locations.u_world), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_color_ramp': new performance.Uniform1i(context, locations.u_color_ramp), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity) }; }; var heatmapUniformValues = function (matrix, tile, zoom, intensity) { return { 'u_matrix': matrix, 'u_extrude_scale': pixelsToTileUnits(tile, 1, zoom), 'u_intensity': intensity }; }; var heatmapTextureUniformValues = function (painter, layer, textureUnit, colorRampUnit) { var matrix = performance.create(); performance.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); var gl = painter.context.gl; return { 'u_matrix': matrix, 'u_world': [ gl.drawingBufferWidth, gl.drawingBufferHeight ], 'u_image': textureUnit, 'u_color_ramp': colorRampUnit, 'u_opacity': layer.paint.get('heatmap-opacity') }; }; var hillshadeUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_latrange': new performance.Uniform2f(context, locations.u_latrange), 'u_light': new performance.Uniform2f(context, locations.u_light), 'u_shadow': new performance.UniformColor(context, locations.u_shadow), 'u_highlight': new performance.UniformColor(context, locations.u_highlight), 'u_accent': new performance.UniformColor(context, locations.u_accent) }; }; var hillshadePrepareUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_dimension': new performance.Uniform2f(context, locations.u_dimension), 'u_zoom': new performance.Uniform1f(context, locations.u_zoom), 'u_unpack': new performance.Uniform4f(context, locations.u_unpack) }; }; var hillshadeUniformValues = function (painter, tile, layer) { var shadow = layer.paint.get('hillshade-shadow-color'); var highlight = layer.paint.get('hillshade-highlight-color'); var accent = layer.paint.get('hillshade-accent-color'); var azimuthal = layer.paint.get('hillshade-illumination-direction') * (Math.PI / 180); if (layer.paint.get('hillshade-illumination-anchor') === 'viewport') { azimuthal -= painter.transform.angle; } var align = !painter.options.moving; return { 'u_matrix': painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), align), 'u_image': 0, 'u_latrange': getTileLatRange(painter, tile.tileID), 'u_light': [ layer.paint.get('hillshade-exaggeration'), azimuthal ], 'u_shadow': shadow, 'u_highlight': highlight, 'u_accent': accent }; }; var hillshadeUniformPrepareValues = function (tileID, dem) { var stride = dem.stride; var matrix = performance.create(); performance.ortho(matrix, 0, performance.EXTENT, -performance.EXTENT, 0, 0, 1); performance.translate(matrix, matrix, [ 0, -performance.EXTENT, 0 ]); return { 'u_matrix': matrix, 'u_image': 1, 'u_dimension': [ stride, stride ], 'u_zoom': tileID.overscaledZ, 'u_unpack': dem.getUnpackVector() }; }; function getTileLatRange(painter, tileID) { var tilesAtZoom = Math.pow(2, tileID.canonical.z); var y = tileID.canonical.y; return [ new performance.MercatorCoordinate(0, y / tilesAtZoom).toLngLat().lat, new performance.MercatorCoordinate(0, (y + 1) / tilesAtZoom).toLngLat().lat ]; } var lineUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new performance.Uniform1f(context, locations.u_ratio), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_units_to_pixels': new performance.Uniform2f(context, locations.u_units_to_pixels) }; }; var lineGradientUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new performance.Uniform1f(context, locations.u_ratio), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_units_to_pixels': new performance.Uniform2f(context, locations.u_units_to_pixels), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_image_height': new performance.Uniform1f(context, locations.u_image_height) }; }; var linePatternUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_ratio': new performance.Uniform1f(context, locations.u_ratio), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_units_to_pixels': new performance.Uniform2f(context, locations.u_units_to_pixels), 'u_scale': new performance.Uniform3f(context, locations.u_scale), 'u_fade': new performance.Uniform1f(context, locations.u_fade) }; }; var lineSDFUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new performance.Uniform1f(context, locations.u_ratio), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_units_to_pixels': new performance.Uniform2f(context, locations.u_units_to_pixels), 'u_patternscale_a': new performance.Uniform2f(context, locations.u_patternscale_a), 'u_patternscale_b': new performance.Uniform2f(context, locations.u_patternscale_b), 'u_sdfgamma': new performance.Uniform1f(context, locations.u_sdfgamma), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_tex_y_a': new performance.Uniform1f(context, locations.u_tex_y_a), 'u_tex_y_b': new performance.Uniform1f(context, locations.u_tex_y_b), 'u_mix': new performance.Uniform1f(context, locations.u_mix) }; }; var lineUniformValues = function (painter, tile, layer) { var transform = painter.transform; return { 'u_matrix': calculateMatrix(painter, tile, layer), 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), 'u_device_pixel_ratio': performance.browser.devicePixelRatio, 'u_units_to_pixels': [ 1 / transform.pixelsToGLUnits[0], 1 / transform.pixelsToGLUnits[1] ] }; }; var lineGradientUniformValues = function (painter, tile, layer, imageHeight) { return performance.extend(lineUniformValues(painter, tile, layer), { 'u_image': 0, 'u_image_height': imageHeight }); }; var linePatternUniformValues = function (painter, tile, layer, crossfade) { var transform = painter.transform; var tileZoomRatio = calculateTileRatio(tile, transform); return { 'u_matrix': calculateMatrix(painter, tile, layer), 'u_texsize': tile.imageAtlasTexture.size, 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), 'u_device_pixel_ratio': performance.browser.devicePixelRatio, 'u_image': 0, 'u_scale': [ tileZoomRatio, crossfade.fromScale, crossfade.toScale ], 'u_fade': crossfade.t, 'u_units_to_pixels': [ 1 / transform.pixelsToGLUnits[0], 1 / transform.pixelsToGLUnits[1] ] }; }; var lineSDFUniformValues = function (painter, tile, layer, dasharray, crossfade) { var transform = painter.transform; var lineAtlas = painter.lineAtlas; var tileRatio = calculateTileRatio(tile, transform); var round = layer.layout.get('line-cap') === 'round'; var posA = lineAtlas.getDash(dasharray.from, round); var posB = lineAtlas.getDash(dasharray.to, round); var widthA = posA.width * crossfade.fromScale; var widthB = posB.width * crossfade.toScale; return performance.extend(lineUniformValues(painter, tile, layer), { 'u_patternscale_a': [ tileRatio / widthA, -posA.height / 2 ], 'u_patternscale_b': [ tileRatio / widthB, -posB.height / 2 ], 'u_sdfgamma': lineAtlas.width / (Math.min(widthA, widthB) * 256 * performance.browser.devicePixelRatio) / 2, 'u_image': 0, 'u_tex_y_a': posA.y, 'u_tex_y_b': posB.y, 'u_mix': crossfade.t }); }; function calculateTileRatio(tile, transform) { return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); } function calculateMatrix(painter, tile, layer) { return painter.translatePosMatrix(tile.tileID.posMatrix, tile, layer.paint.get('line-translate'), layer.paint.get('line-translate-anchor')); } var rasterUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_tl_parent': new performance.Uniform2f(context, locations.u_tl_parent), 'u_scale_parent': new performance.Uniform1f(context, locations.u_scale_parent), 'u_buffer_scale': new performance.Uniform1f(context, locations.u_buffer_scale), 'u_fade_t': new performance.Uniform1f(context, locations.u_fade_t), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity), 'u_image0': new performance.Uniform1i(context, locations.u_image0), 'u_image1': new performance.Uniform1i(context, locations.u_image1), 'u_brightness_low': new performance.Uniform1f(context, locations.u_brightness_low), 'u_brightness_high': new performance.Uniform1f(context, locations.u_brightness_high), 'u_saturation_factor': new performance.Uniform1f(context, locations.u_saturation_factor), 'u_contrast_factor': new performance.Uniform1f(context, locations.u_contrast_factor), 'u_spin_weights': new performance.Uniform3f(context, locations.u_spin_weights) }; }; var rasterUniformValues = function (matrix, parentTL, parentScaleBy, fade, layer) { return { 'u_matrix': matrix, 'u_tl_parent': parentTL, 'u_scale_parent': parentScaleBy, 'u_buffer_scale': 1, 'u_fade_t': fade.mix, 'u_opacity': fade.opacity * layer.paint.get('raster-opacity'), 'u_image0': 0, 'u_image1': 1, 'u_brightness_low': layer.paint.get('raster-brightness-min'), 'u_brightness_high': layer.paint.get('raster-brightness-max'), 'u_saturation_factor': saturationFactor(layer.paint.get('raster-saturation')), 'u_contrast_factor': contrastFactor(layer.paint.get('raster-contrast')), 'u_spin_weights': spinWeights(layer.paint.get('raster-hue-rotate')) }; }; function spinWeights(angle) { angle *= Math.PI / 180; var s = Math.sin(angle); var c = Math.cos(angle); return [ (2 * c + 1) / 3, (-Math.sqrt(3) * s - c + 1) / 3, (Math.sqrt(3) * s - c + 1) / 3 ]; } function contrastFactor(contrast) { return contrast > 0 ? 1 / (1 - contrast) : 1 + contrast; } function saturationFactor(saturation) { return saturation > 0 ? 1 - 1 / (1.001 - saturation) : -saturation; } var symbolIconUniforms = function (context, locations) { return { 'u_is_size_zoom_constant': new performance.Uniform1i(context, locations.u_is_size_zoom_constant), 'u_is_size_feature_constant': new performance.Uniform1i(context, locations.u_is_size_feature_constant), 'u_size_t': new performance.Uniform1f(context, locations.u_size_t), 'u_size': new performance.Uniform1f(context, locations.u_size), 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_pitch': new performance.Uniform1f(context, locations.u_pitch), 'u_rotate_symbol': new performance.Uniform1i(context, locations.u_rotate_symbol), 'u_aspect_ratio': new performance.Uniform1f(context, locations.u_aspect_ratio), 'u_fade_change': new performance.Uniform1f(context, locations.u_fade_change), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_label_plane_matrix': new performance.UniformMatrix4f(context, locations.u_label_plane_matrix), 'u_coord_matrix': new performance.UniformMatrix4f(context, locations.u_coord_matrix), 'u_is_text': new performance.Uniform1i(context, locations.u_is_text), 'u_pitch_with_map': new performance.Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_texture': new performance.Uniform1i(context, locations.u_texture) }; }; var symbolSDFUniforms = function (context, locations) { return { 'u_is_size_zoom_constant': new performance.Uniform1i(context, locations.u_is_size_zoom_constant), 'u_is_size_feature_constant': new performance.Uniform1i(context, locations.u_is_size_feature_constant), 'u_size_t': new performance.Uniform1f(context, locations.u_size_t), 'u_size': new performance.Uniform1f(context, locations.u_size), 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_pitch': new performance.Uniform1f(context, locations.u_pitch), 'u_rotate_symbol': new performance.Uniform1i(context, locations.u_rotate_symbol), 'u_aspect_ratio': new performance.Uniform1f(context, locations.u_aspect_ratio), 'u_fade_change': new performance.Uniform1f(context, locations.u_fade_change), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_label_plane_matrix': new performance.UniformMatrix4f(context, locations.u_label_plane_matrix), 'u_coord_matrix': new performance.UniformMatrix4f(context, locations.u_coord_matrix), 'u_is_text': new performance.Uniform1i(context, locations.u_is_text), 'u_pitch_with_map': new performance.Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_texture': new performance.Uniform1i(context, locations.u_texture), 'u_gamma_scale': new performance.Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new performance.Uniform1i(context, locations.u_is_halo) }; }; var symbolTextAndIconUniforms = function (context, locations) { return { 'u_is_size_zoom_constant': new performance.Uniform1i(context, locations.u_is_size_zoom_constant), 'u_is_size_feature_constant': new performance.Uniform1i(context, locations.u_is_size_feature_constant), 'u_size_t': new performance.Uniform1f(context, locations.u_size_t), 'u_size': new performance.Uniform1f(context, locations.u_size), 'u_camera_to_center_distance': new performance.Uniform1f(context, locations.u_camera_to_center_distance), 'u_pitch': new performance.Uniform1f(context, locations.u_pitch), 'u_rotate_symbol': new performance.Uniform1i(context, locations.u_rotate_symbol), 'u_aspect_ratio': new performance.Uniform1f(context, locations.u_aspect_ratio), 'u_fade_change': new performance.Uniform1f(context, locations.u_fade_change), 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_label_plane_matrix': new performance.UniformMatrix4f(context, locations.u_label_plane_matrix), 'u_coord_matrix': new performance.UniformMatrix4f(context, locations.u_coord_matrix), 'u_is_text': new performance.Uniform1i(context, locations.u_is_text), 'u_pitch_with_map': new performance.Uniform1i(context, locations.u_pitch_with_map), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_texsize_icon': new performance.Uniform2f(context, locations.u_texsize_icon), 'u_texture': new performance.Uniform1i(context, locations.u_texture), 'u_texture_icon': new performance.Uniform1i(context, locations.u_texture_icon), 'u_gamma_scale': new performance.Uniform1f(context, locations.u_gamma_scale), 'u_device_pixel_ratio': new performance.Uniform1f(context, locations.u_device_pixel_ratio), 'u_is_halo': new performance.Uniform1i(context, locations.u_is_halo) }; }; var symbolIconUniformValues = function (functionType, size, rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, isText, texSize) { var transform = painter.transform; return { 'u_is_size_zoom_constant': +(functionType === 'constant' || functionType === 'source'), 'u_is_size_feature_constant': +(functionType === 'constant' || functionType === 'camera'), 'u_size_t': size ? size.uSizeT : 0, 'u_size': size ? size.uSize : 0, 'u_camera_to_center_distance': transform.cameraToCenterDistance, 'u_pitch': transform.pitch / 360 * 2 * Math.PI, 'u_rotate_symbol': +rotateInShader, 'u_aspect_ratio': transform.width / transform.height, 'u_fade_change': painter.options.fadeDuration ? painter.symbolFadeChange : 1, 'u_matrix': matrix, 'u_label_plane_matrix': labelPlaneMatrix, 'u_coord_matrix': glCoordMatrix, 'u_is_text': +isText, 'u_pitch_with_map': +pitchWithMap, 'u_texsize': texSize, 'u_texture': 0 }; }; var symbolSDFUniformValues = function (functionType, size, rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, isText, texSize, isHalo) { var transform = painter.transform; return performance.extend(symbolIconUniformValues(functionType, size, rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, isText, texSize), { 'u_gamma_scale': pitchWithMap ? Math.cos(transform._pitch) * transform.cameraToCenterDistance : 1, 'u_device_pixel_ratio': performance.browser.devicePixelRatio, 'u_is_halo': +isHalo }); }; var symbolTextAndIconUniformValues = function (functionType, size, rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, texSizeSDF, texSizeIcon) { return performance.extend(symbolSDFUniformValues(functionType, size, rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, glCoordMatrix, true, texSizeSDF, true), { 'u_texsize_icon': texSizeIcon, 'u_texture_icon': 1 }); }; var backgroundUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity), 'u_color': new performance.UniformColor(context, locations.u_color) }; }; var backgroundPatternUniforms = function (context, locations) { return { 'u_matrix': new performance.UniformMatrix4f(context, locations.u_matrix), 'u_opacity': new performance.Uniform1f(context, locations.u_opacity), 'u_image': new performance.Uniform1i(context, locations.u_image), 'u_pattern_tl_a': new performance.Uniform2f(context, locations.u_pattern_tl_a), 'u_pattern_br_a': new performance.Uniform2f(context, locations.u_pattern_br_a), 'u_pattern_tl_b': new performance.Uniform2f(context, locations.u_pattern_tl_b), 'u_pattern_br_b': new performance.Uniform2f(context, locations.u_pattern_br_b), 'u_texsize': new performance.Uniform2f(context, locations.u_texsize), 'u_mix': new performance.Uniform1f(context, locations.u_mix), 'u_pattern_size_a': new performance.Uniform2f(context, locations.u_pattern_size_a), 'u_pattern_size_b': new performance.Uniform2f(context, locations.u_pattern_size_b), 'u_scale_a': new performance.Uniform1f(context, locations.u_scale_a), 'u_scale_b': new performance.Uniform1f(context, locations.u_scale_b), 'u_pixel_coord_upper': new performance.Uniform2f(context, locations.u_pixel_coord_upper), 'u_pixel_coord_lower': new performance.Uniform2f(context, locations.u_pixel_coord_lower), 'u_tile_units_to_pixels': new performance.Uniform1f(context, locations.u_tile_units_to_pixels) }; }; var backgroundUniformValues = function (matrix, opacity, color) { return { 'u_matrix': matrix, 'u_opacity': opacity, 'u_color': color }; }; var backgroundPatternUniformValues = function (matrix, opacity, painter, image, tile, crossfade) { return performance.extend(bgPatternUniformValues(image, crossfade, painter, tile), { 'u_matrix': matrix, 'u_opacity': opacity }); }; var programUniforms = { fillExtrusion: fillExtrusionUniforms, fillExtrusionPattern: fillExtrusionPatternUniforms, fill: fillUniforms, fillPattern: fillPatternUniforms, fillOutline: fillOutlineUniforms, fillOutlinePattern: fillOutlinePatternUniforms, circle: circleUniforms, collisionBox: collisionUniforms, collisionCircle: collisionCircleUniforms, debug: debugUniforms, clippingMask: clippingMaskUniforms, heatmap: heatmapUniforms, heatmapTexture: heatmapTextureUniforms, hillshade: hillshadeUniforms, hillshadePrepare: hillshadePrepareUniforms, line: lineUniforms, lineGradient: lineGradientUniforms, linePattern: linePatternUniforms, lineSDF: lineSDFUniforms, raster: rasterUniforms, symbolIcon: symbolIconUniforms, symbolSDF: symbolSDFUniforms, symbolTextAndIcon: symbolTextAndIconUniforms, background: backgroundUniforms, backgroundPattern: backgroundPatternUniforms }; var quadTriangles; function drawCollisionDebug(painter, sourceCache, layer, coords, translate, translateAnchor, isText) { var context = painter.context; var gl = context.gl; var program = painter.useProgram('collisionBox'); var tileBatches = []; var circleCount = 0; var circleOffset = 0; for (var i = 0; i < coords.length; i++) { var coord = coords[i]; var tile = sourceCache.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket) { continue; } var posMatrix = coord.posMatrix; if (translate[0] !== 0 || translate[1] !== 0) { posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor); } var buffers = isText ? bucket.textCollisionBox : bucket.iconCollisionBox; var circleArray = bucket.collisionCircleArray; if (circleArray.length > 0) { var invTransform = performance.create(); var transform = posMatrix; performance.mul(invTransform, bucket.placementInvProjMatrix, painter.transform.glCoordMatrix); performance.mul(invTransform, invTransform, bucket.placementViewportMatrix); tileBatches.push({ circleArray: circleArray, circleOffset: circleOffset, transform: transform, invTransform: invTransform }); circleCount += circleArray.length / 4; circleOffset = circleCount; } if (!buffers) { continue; } program.draw(context, gl.LINES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, collisionUniformValues(posMatrix, painter.transform, tile), layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, buffers.segments, null, painter.transform.zoom, null, null, buffers.collisionVertexBuffer); } if (!isText || !tileBatches.length) { return; } var circleProgram = painter.useProgram('collisionCircle'); var vertexData = new performance.StructArrayLayout2f1f2i16(); vertexData.resize(circleCount * 4); vertexData._trim(); var vertexOffset = 0; for (var i$2 = 0, list = tileBatches; i$2 < list.length; i$2 += 1) { var batch = list[i$2]; for (var i$1 = 0; i$1 < batch.circleArray.length / 4; i$1++) { var circleIdx = i$1 * 4; var x = batch.circleArray[circleIdx + 0]; var y = batch.circleArray[circleIdx + 1]; var radius = batch.circleArray[circleIdx + 2]; var collision = batch.circleArray[circleIdx + 3]; vertexData.emplace(vertexOffset++, x, y, radius, collision, 0); vertexData.emplace(vertexOffset++, x, y, radius, collision, 1); vertexData.emplace(vertexOffset++, x, y, radius, collision, 2); vertexData.emplace(vertexOffset++, x, y, radius, collision, 3); } } if (!quadTriangles || quadTriangles.length < circleCount * 2) { quadTriangles = createQuadTriangles(circleCount); } var indexBuffer = context.createIndexBuffer(quadTriangles, true); var vertexBuffer = context.createVertexBuffer(vertexData, performance.collisionCircleLayout.members, true); for (var i$3 = 0, list$1 = tileBatches; i$3 < list$1.length; i$3 += 1) { var batch$1 = list$1[i$3]; var uniforms = collisionCircleUniformValues(batch$1.transform, batch$1.invTransform, painter.transform); circleProgram.draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, uniforms, layer.id, vertexBuffer, indexBuffer, performance.SegmentVector.simpleSegment(0, batch$1.circleOffset * 2, batch$1.circleArray.length, batch$1.circleArray.length / 2), null, painter.transform.zoom, null, null, null); } vertexBuffer.destroy(); indexBuffer.destroy(); } function createQuadTriangles(quadCount) { var triCount = quadCount * 2; var array = new performance.StructArrayLayout3ui6(); array.resize(triCount); array._trim(); for (var i = 0; i < triCount; i++) { var idx = i * 6; array.uint16[idx + 0] = i * 4 + 0; array.uint16[idx + 1] = i * 4 + 1; array.uint16[idx + 2] = i * 4 + 2; array.uint16[idx + 3] = i * 4 + 2; array.uint16[idx + 4] = i * 4 + 3; array.uint16[idx + 5] = i * 4 + 0; } return array; } var identityMat4 = performance.identity(new Float32Array(16)); function drawSymbols(painter, sourceCache, layer, coords, variableOffsets) { if (painter.renderPass !== 'translucent') { return; } var stencilMode = StencilMode.disabled; var colorMode = painter.colorModeForRenderPass(); var variablePlacement = layer.layout.get('text-variable-anchor'); if (variablePlacement) { updateVariableAnchors(coords, painter, layer, sourceCache, layer.layout.get('text-rotation-alignment'), layer.layout.get('text-pitch-alignment'), variableOffsets); } if (layer.paint.get('icon-opacity').constantOr(1) !== 0) { drawLayerSymbols(painter, sourceCache, layer, coords, false, layer.paint.get('icon-translate'), layer.paint.get('icon-translate-anchor'), layer.layout.get('icon-rotation-alignment'), layer.layout.get('icon-pitch-alignment'), layer.layout.get('icon-keep-upright'), stencilMode, colorMode); } if (layer.paint.get('text-opacity').constantOr(1) !== 0) { drawLayerSymbols(painter, sourceCache, layer, coords, true, layer.paint.get('text-translate'), layer.paint.get('text-translate-anchor'), layer.layout.get('text-rotation-alignment'), layer.layout.get('text-pitch-alignment'), layer.layout.get('text-keep-upright'), stencilMode, colorMode); } if (sourceCache.map.showCollisionBoxes) { drawCollisionDebug(painter, sourceCache, layer, coords, layer.paint.get('text-translate'), layer.paint.get('text-translate-anchor'), true); drawCollisionDebug(painter, sourceCache, layer, coords, layer.paint.get('icon-translate'), layer.paint.get('icon-translate-anchor'), false); } } function calculateVariableRenderShift(anchor, width, height, textOffset, textBoxScale, renderTextSize) { var ref = performance.getAnchorAlignment(anchor); var horizontalAlign = ref.horizontalAlign; var verticalAlign = ref.verticalAlign; var shiftX = -(horizontalAlign - 0.5) * width; var shiftY = -(verticalAlign - 0.5) * height; var variableOffset = performance.evaluateVariableOffset(anchor, textOffset); return new performance.Point((shiftX / textBoxScale + variableOffset[0]) * renderTextSize, (shiftY / textBoxScale + variableOffset[1]) * renderTextSize); } function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlignment, pitchAlignment, variableOffsets) { var tr = painter.transform; var rotateWithMap = rotationAlignment === 'map'; var pitchWithMap = pitchAlignment === 'map'; for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var tile = sourceCache.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket || !bucket.text || !bucket.text.segments.get().length) { continue; } var sizeData = bucket.textSizeData; var size = performance.evaluateSizeForZoom(sizeData, tr.zoom); var pixelToTileScale = pixelsToTileUnits(tile, 1, painter.transform.zoom); var labelPlaneMatrix = getLabelPlaneMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, pixelToTileScale); var updateTextFitIcon = layer.layout.get('icon-text-fit') !== 'none' && bucket.hasIconData(); if (size) { var tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, performance.symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size, updateTextFitIcon); } } } function updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, transform, labelPlaneMatrix, posMatrix, tileScale, size, updateTextFitIcon) { var placedSymbols = bucket.text.placedSymbolArray; var dynamicTextLayoutVertexArray = bucket.text.dynamicLayoutVertexArray; var dynamicIconLayoutVertexArray = bucket.icon.dynamicLayoutVertexArray; var placedTextShifts = {}; dynamicTextLayoutVertexArray.clear(); for (var s = 0; s < placedSymbols.length; s++) { var symbol = placedSymbols.get(s); var skipOrientation = bucket.allowVerticalPlacement && !symbol.placedOrientation; var variableOffset = !symbol.hidden && symbol.crossTileID && !skipOrientation ? variableOffsets[symbol.crossTileID] : null; if (!variableOffset) { hideGlyphs(symbol.numGlyphs, dynamicTextLayoutVertexArray); } else { var tileAnchor = new performance.Point(symbol.anchorX, symbol.anchorY); var projectedAnchor = project(tileAnchor, pitchWithMap ? posMatrix : labelPlaneMatrix); var perspectiveRatio = getPerspectiveRatio(transform.cameraToCenterDistance, projectedAnchor.signedDistanceFromCamera); var renderTextSize = symbolSize.evaluateSizeForFeature(bucket.textSizeData, size, symbol) * perspectiveRatio / performance.ONE_EM; if (pitchWithMap) { renderTextSize *= bucket.tilePixelRatio / tileScale; } var width = variableOffset.width; var height = variableOffset.height; var anchor = variableOffset.anchor; var textOffset = variableOffset.textOffset; var textBoxScale = variableOffset.textBoxScale; var shift = calculateVariableRenderShift(anchor, width, height, textOffset, textBoxScale, renderTextSize); var shiftedAnchor = pitchWithMap ? project(tileAnchor.add(shift), labelPlaneMatrix).point : projectedAnchor.point.add(rotateWithMap ? shift.rotate(-transform.angle) : shift); var angle = bucket.allowVerticalPlacement && symbol.placedOrientation === performance.WritingMode.vertical ? Math.PI / 2 : 0; for (var g = 0; g < symbol.numGlyphs; g++) { performance.addDynamicAttributes(dynamicTextLayoutVertexArray, shiftedAnchor, angle); } if (updateTextFitIcon && symbol.associatedIconIndex >= 0) { placedTextShifts[symbol.associatedIconIndex] = { shiftedAnchor: shiftedAnchor, angle: angle }; } } } if (updateTextFitIcon) { dynamicIconLayoutVertexArray.clear(); var placedIcons = bucket.icon.placedSymbolArray; for (var i = 0; i < placedIcons.length; i++) { var placedIcon = placedIcons.get(i); if (placedIcon.hidden) { hideGlyphs(placedIcon.numGlyphs, dynamicIconLayoutVertexArray); } else { var shift$1 = placedTextShifts[i]; if (!shift$1) { hideGlyphs(placedIcon.numGlyphs, dynamicIconLayoutVertexArray); } else { for (var g$1 = 0; g$1 < placedIcon.numGlyphs; g$1++) { performance.addDynamicAttributes(dynamicIconLayoutVertexArray, shift$1.shiftedAnchor, shift$1.angle); } } } } bucket.icon.dynamicLayoutVertexBuffer.updateData(dynamicIconLayoutVertexArray); } bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicTextLayoutVertexArray); } function getSymbolProgramName(isSDF, isText, bucket) { if (bucket.iconsInText && isText) { return 'symbolTextAndIcon'; } else if (isSDF) { return 'symbolSDF'; } else { return 'symbolIcon'; } } function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode) { var context = painter.context; var gl = context.gl; var tr = painter.transform; var rotateWithMap = rotationAlignment === 'map'; var pitchWithMap = pitchAlignment === 'map'; var alongLine = rotateWithMap && layer.layout.get('symbol-placement') !== 'point'; var rotateInShader = rotateWithMap && !pitchWithMap && !alongLine; var hasSortKey = layer.layout.get('symbol-sort-key').constantOr(1) !== undefined; var sortFeaturesByKey = false; var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); var variablePlacement = layer.layout.get('text-variable-anchor'); var tileRenderState = []; for (var i$1 = 0, list$1 = coords; i$1 < list$1.length; i$1 += 1) { var coord = list$1[i$1]; var tile = sourceCache.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket) { continue; } var buffers = isText ? bucket.text : bucket.icon; if (!buffers || !buffers.segments.get().length) { continue; } var programConfiguration = buffers.programConfigurations.get(layer.id); var isSDF = isText || bucket.sdfIcons; var sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; var transformed = pitchWithMap || tr.pitch !== 0; var program = painter.useProgram(getSymbolProgramName(isSDF, isText, bucket), programConfiguration); var size = performance.evaluateSizeForZoom(sizeData, tr.zoom); var texSize = void 0; var texSizeIcon = [ 0, 0 ]; var atlasTexture = void 0; var atlasInterpolation = void 0; var atlasTextureIcon = null; var atlasInterpolationIcon = void 0; if (isText) { atlasTexture = tile.glyphAtlasTexture; atlasInterpolation = gl.LINEAR; texSize = tile.glyphAtlasTexture.size; if (bucket.iconsInText) { texSizeIcon = tile.imageAtlasTexture.size; atlasTextureIcon = tile.imageAtlasTexture; var zoomDependentSize = sizeData.kind === 'composite' || sizeData.kind === 'camera'; atlasInterpolationIcon = transformed || painter.options.rotating || painter.options.zooming || zoomDependentSize ? gl.LINEAR : gl.NEAREST; } } else { var iconScaled = layer.layout.get('icon-size').constantOr(0) !== 1 || bucket.iconsNeedLinear; atlasTexture = tile.imageAtlasTexture; atlasInterpolation = isSDF || painter.options.rotating || painter.options.zooming || iconScaled || transformed ? gl.LINEAR : gl.NEAREST; texSize = tile.imageAtlasTexture.size; } var s = pixelsToTileUnits(tile, 1, painter.transform.zoom); var labelPlaneMatrix = getLabelPlaneMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s); var glCoordMatrix = getGlCoordMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s); var hasVariableAnchors = variablePlacement && bucket.hasTextData(); var updateTextFitIcon = layer.layout.get('icon-text-fit') !== 'none' && hasVariableAnchors && bucket.hasIconData(); if (alongLine) { updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright); } var matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), uLabelPlaneMatrix = alongLine || isText && variablePlacement || updateTextFitIcon ? identityMat4 : labelPlaneMatrix, uglCoordMatrix = painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true); var hasHalo = isSDF && layer.paint.get(isText ? 'text-halo-width' : 'icon-halo-width').constantOr(1) !== 0; var uniformValues = void 0; if (isSDF) { if (!bucket.iconsInText) { uniformValues = symbolSDFUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix, uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true); } else { uniformValues = symbolTextAndIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix, uLabelPlaneMatrix, uglCoordMatrix, texSize, texSizeIcon); } } else { uniformValues = symbolIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix, uLabelPlaneMatrix, uglCoordMatrix, isText, texSize); } var state = { program: program, buffers: buffers, uniformValues: uniformValues, atlasTexture: atlasTexture, atlasTextureIcon: atlasTextureIcon, atlasInterpolation: atlasInterpolation, atlasInterpolationIcon: atlasInterpolationIcon, isSDF: isSDF, hasHalo: hasHalo }; if (hasSortKey && bucket.canOverlap) { sortFeaturesByKey = true; var oldSegments = buffers.segments.get(); for (var i = 0, list = oldSegments; i < list.length; i += 1) { var segment = list[i]; tileRenderState.push({ segments: new performance.SegmentVector([segment]), sortKey: segment.sortKey, state: state }); } } else { tileRenderState.push({ segments: buffers.segments, sortKey: 0, state: state }); } } if (sortFeaturesByKey) { tileRenderState.sort(function (a, b) { return a.sortKey - b.sortKey; }); } for (var i$2 = 0, list$2 = tileRenderState; i$2 < list$2.length; i$2 += 1) { var segmentState = list$2[i$2]; var state$1 = segmentState.state; context.activeTexture.set(gl.TEXTURE0); state$1.atlasTexture.bind(state$1.atlasInterpolation, gl.CLAMP_TO_EDGE); if (state$1.atlasTextureIcon) { context.activeTexture.set(gl.TEXTURE1); if (state$1.atlasTextureIcon) { state$1.atlasTextureIcon.bind(state$1.atlasInterpolationIcon, gl.CLAMP_TO_EDGE); } } if (state$1.isSDF) { var uniformValues$1 = state$1.uniformValues; if (state$1.hasHalo) { uniformValues$1['u_is_halo'] = 1; drawSymbolElements(state$1.buffers, segmentState.segments, layer, painter, state$1.program, depthMode, stencilMode, colorMode, uniformValues$1); } uniformValues$1['u_is_halo'] = 0; } drawSymbolElements(state$1.buffers, segmentState.segments, layer, painter, state$1.program, depthMode, stencilMode, colorMode, state$1.uniformValues); } } function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { var context = painter.context; var gl = context.gl; program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, segments, layer.paint, painter.transform.zoom, buffers.programConfigurations.get(layer.id), buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer); } function drawCircles(painter, sourceCache, layer, coords) { if (painter.renderPass !== 'translucent') { return; } var opacity = layer.paint.get('circle-opacity'); var strokeWidth = layer.paint.get('circle-stroke-width'); var strokeOpacity = layer.paint.get('circle-stroke-opacity'); var sortFeaturesByKey = layer.layout.get('circle-sort-key').constantOr(1) !== undefined; if (opacity.constantOr(1) === 0 && (strokeWidth.constantOr(1) === 0 || strokeOpacity.constantOr(1) === 0)) { return; } var context = painter.context; var gl = context.gl; var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); var stencilMode = StencilMode.disabled; var colorMode = painter.colorModeForRenderPass(); var segmentsRenderStates = []; for (var i = 0; i < coords.length; i++) { var coord = coords[i]; var tile = sourceCache.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket) { continue; } var programConfiguration = bucket.programConfigurations.get(layer.id); var program = painter.useProgram('circle', programConfiguration); var layoutVertexBuffer = bucket.layoutVertexBuffer; var indexBuffer = bucket.indexBuffer; var uniformValues = circleUniformValues(painter, coord, tile, layer); var state = { programConfiguration: programConfiguration, program: program, layoutVertexBuffer: layoutVertexBuffer, indexBuffer: indexBuffer, uniformValues: uniformValues }; if (sortFeaturesByKey) { var oldSegments = bucket.segments.get(); for (var i$1 = 0, list = oldSegments; i$1 < list.length; i$1 += 1) { var segment = list[i$1]; segmentsRenderStates.push({ segments: new performance.SegmentVector([segment]), sortKey: segment.sortKey, state: state }); } } else { segmentsRenderStates.push({ segments: bucket.segments, sortKey: 0, state: state }); } } if (sortFeaturesByKey) { segmentsRenderStates.sort(function (a, b) { return a.sortKey - b.sortKey; }); } for (var i$2 = 0, list$1 = segmentsRenderStates; i$2 < list$1.length; i$2 += 1) { var segmentsState = list$1[i$2]; var ref = segmentsState.state; var programConfiguration$1 = ref.programConfiguration; var program$1 = ref.program; var layoutVertexBuffer$1 = ref.layoutVertexBuffer; var indexBuffer$1 = ref.indexBuffer; var uniformValues$1 = ref.uniformValues; var segments = segmentsState.segments; program$1.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues$1, layer.id, layoutVertexBuffer$1, indexBuffer$1, segments, layer.paint, painter.transform.zoom, programConfiguration$1); } } function drawHeatmap(painter, sourceCache, layer, coords) { if (layer.paint.get('heatmap-opacity') === 0) { return; } if (painter.renderPass === 'offscreen') { var context = painter.context; var gl = context.gl; var stencilMode = StencilMode.disabled; var colorMode = new ColorMode([ gl.ONE, gl.ONE ], performance.Color.transparent, [ true, true, true, true ]); bindFramebuffer(context, painter, layer); context.clear({ color: performance.Color.transparent }); for (var i = 0; i < coords.length; i++) { var coord = coords[i]; if (sourceCache.hasRenderableParent(coord)) { continue; } var tile = sourceCache.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket) { continue; } var programConfiguration = bucket.programConfigurations.get(layer.id); var program = painter.useProgram('heatmap', programConfiguration); var ref = painter.transform; var zoom = ref.zoom; program.draw(context, gl.TRIANGLES, DepthMode.disabled, stencilMode, colorMode, CullFaceMode.disabled, heatmapUniformValues(coord.posMatrix, tile, zoom, layer.paint.get('heatmap-intensity')), layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); } context.viewport.set([ 0, 0, painter.width, painter.height ]); } else if (painter.renderPass === 'translucent') { painter.context.setColorMode(painter.colorModeForRenderPass()); renderTextureToMap(painter, layer); } } function bindFramebuffer(context, painter, layer) { var gl = context.gl; context.activeTexture.set(gl.TEXTURE1); context.viewport.set([ 0, 0, painter.width / 4, painter.height / 4 ]); var fbo = layer.heatmapFbo; if (!fbo) { var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); fbo = layer.heatmapFbo = context.createFramebuffer(painter.width / 4, painter.height / 4, false); bindTextureToFramebuffer(context, painter, texture, fbo); } else { gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); context.bindFramebuffer.set(fbo.framebuffer); } } function bindTextureToFramebuffer(context, painter, texture, fbo) { var gl = context.gl; var internalFormat = context.extRenderToTextureHalfFloat ? context.extTextureHalfFloat.HALF_FLOAT_OES : gl.UNSIGNED_BYTE; gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, painter.width / 4, painter.height / 4, 0, gl.RGBA, internalFormat, null); fbo.colorAttachment.set(texture); } function renderTextureToMap(painter, layer) { var context = painter.context; var gl = context.gl; var fbo = layer.heatmapFbo; if (!fbo) { return; } context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); context.activeTexture.set(gl.TEXTURE1); var colorRampTexture = layer.colorRampTexture; if (!colorRampTexture) { colorRampTexture = layer.colorRampTexture = new performance.Texture(context, layer.colorRamp, gl.RGBA); } colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, heatmapTextureUniformValues(painter, layer, 0, 1), layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom); } function drawLine(painter, sourceCache, layer, coords) { if (painter.renderPass !== 'translucent') { return; } var opacity = layer.paint.get('line-opacity'); var width = layer.paint.get('line-width'); if (opacity.constantOr(1) === 0 || width.constantOr(1) === 0) { return; } var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); var colorMode = painter.colorModeForRenderPass(); var dasharray = layer.paint.get('line-dasharray'); var patternProperty = layer.paint.get('line-pattern'); var image = patternProperty.constantOr(1); var gradient = layer.paint.get('line-gradient'); var crossfade = layer.getCrossfadeParameters(); var programId = image ? 'linePattern' : dasharray ? 'lineSDF' : gradient ? 'lineGradient' : 'line'; var context = painter.context; var gl = context.gl; var firstTile = true; for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var tile = sourceCache.getTile(coord); if (image && !tile.patternsLoaded()) { continue; } var bucket = tile.getBucket(layer); if (!bucket) { continue; } var programConfiguration = bucket.programConfigurations.get(layer.id); var prevProgram = painter.context.program.get(); var program = painter.useProgram(programId, programConfiguration); var programChanged = firstTile || program.program !== prevProgram; var constantPattern = patternProperty.constantOr(null); if (constantPattern && tile.imageAtlas) { var atlas = tile.imageAtlas; var posTo = atlas.patternPositions[constantPattern.to.toString()]; var posFrom = atlas.patternPositions[constantPattern.from.toString()]; if (posTo && posFrom) { programConfiguration.setConstantPatternPositions(posTo, posFrom); } } var uniformValues = image ? linePatternUniformValues(painter, tile, layer, crossfade) : dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade) : gradient ? lineGradientUniformValues(painter, tile, layer, bucket.lineClipsArray.length) : lineUniformValues(painter, tile, layer); if (image) { context.activeTexture.set(gl.TEXTURE0); tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); programConfiguration.updatePaintBuffers(crossfade); } else if (dasharray && (programChanged || painter.lineAtlas.dirty)) { context.activeTexture.set(gl.TEXTURE0); painter.lineAtlas.bind(context); } else if (gradient) { var layerGradient = bucket.gradients[layer.id]; var gradientTexture = layerGradient.texture; if (layer.gradientVersion !== layerGradient.version) { var textureResolution = 256; if (layer.stepInterpolant) { var sourceMaxZoom = sourceCache.getSource().maxzoom; var potentialOverzoom = coord.canonical.z === sourceMaxZoom ? Math.ceil(1 << painter.transform.maxZoom - coord.canonical.z) : 1; var lineLength = bucket.maxLineLength / performance.EXTENT; var maxTilePixelSize = 1024; var maxTextureCoverage = lineLength * maxTilePixelSize * potentialOverzoom; textureResolution = performance.clamp(performance.nextPowerOfTwo(maxTextureCoverage), 256, context.maxTextureSize); } layerGradient.gradient = performance.renderColorRamp({ expression: layer.gradientExpression(), evaluationKey: 'lineProgress', resolution: textureResolution, image: layerGradient.gradient || undefined, clips: bucket.lineClipsArray }); if (layerGradient.texture) { layerGradient.texture.update(layerGradient.gradient); } else { layerGradient.texture = new performance.Texture(context, layerGradient.gradient, gl.RGBA); } layerGradient.version = layer.gradientVersion; gradientTexture = layerGradient.texture; } context.activeTexture.set(gl.TEXTURE0); gradientTexture.bind(layer.stepInterpolant ? gl.NEAREST : gl.LINEAR, gl.CLAMP_TO_EDGE); } program.draw(context, gl.TRIANGLES, depthMode, painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration, bucket.layoutVertexBuffer2); firstTile = false; } } function drawFill(painter, sourceCache, layer, coords) { var color = layer.paint.get('fill-color'); var opacity = layer.paint.get('fill-opacity'); if (opacity.constantOr(1) === 0) { return; } var colorMode = painter.colorModeForRenderPass(); var pattern = layer.paint.get('fill-pattern'); var pass = painter.opaquePassEnabledForLayer() && (!pattern.constantOr(1) && color.constantOr(performance.Color.transparent).a === 1 && opacity.constantOr(0) === 1) ? 'opaque' : 'translucent'; if (painter.renderPass === pass) { var depthMode = painter.depthModeForSublayer(1, painter.renderPass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, false); } if (painter.renderPass === 'translucent' && layer.paint.get('fill-antialias')) { var depthMode$1 = painter.depthModeForSublayer(layer.getPaintProperty('fill-outline-color') ? 2 : 0, DepthMode.ReadOnly); drawFillTiles(painter, sourceCache, layer, coords, depthMode$1, colorMode, true); } } function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, isOutline) { var gl = painter.context.gl; var patternProperty = layer.paint.get('fill-pattern'); var image = patternProperty && patternProperty.constantOr(1); var crossfade = layer.getCrossfadeParameters(); var drawMode, programName, uniformValues, indexBuffer, segments; if (!isOutline) { programName = image ? 'fillPattern' : 'fill'; drawMode = gl.TRIANGLES; } else { programName = image && !layer.getPaintProperty('fill-outline-color') ? 'fillOutlinePattern' : 'fillOutline'; drawMode = gl.LINES; } for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var tile = sourceCache.getTile(coord); if (image && !tile.patternsLoaded()) { continue; } var bucket = tile.getBucket(layer); if (!bucket) { continue; } var programConfiguration = bucket.programConfigurations.get(layer.id); var program = painter.useProgram(programName, programConfiguration); if (image) { painter.context.activeTexture.set(gl.TEXTURE0); tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); programConfiguration.updatePaintBuffers(crossfade); } var constantPattern = patternProperty.constantOr(null); if (constantPattern && tile.imageAtlas) { var atlas = tile.imageAtlas; var posTo = atlas.patternPositions[constantPattern.to.toString()]; var posFrom = atlas.patternPositions[constantPattern.from.toString()]; if (posTo && posFrom) { programConfiguration.setConstantPatternPositions(posTo, posFrom); } } var tileMatrix = painter.translatePosMatrix(coord.posMatrix, tile, layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); if (!isOutline) { indexBuffer = bucket.indexBuffer; segments = bucket.segments; uniformValues = image ? fillPatternUniformValues(tileMatrix, painter, crossfade, tile) : fillUniformValues(tileMatrix); } else { indexBuffer = bucket.indexBuffer2; segments = bucket.segments2; var drawingBufferSize = [ gl.drawingBufferWidth, gl.drawingBufferHeight ]; uniformValues = programName === 'fillOutlinePattern' && image ? fillOutlinePatternUniformValues(tileMatrix, painter, crossfade, tile, drawingBufferSize) : fillOutlineUniformValues(tileMatrix, drawingBufferSize); } program.draw(painter.context, drawMode, depthMode, painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, layer.paint, painter.transform.zoom, programConfiguration); } } function draw(painter, source, layer, coords) { var opacity = layer.paint.get('fill-extrusion-opacity'); if (opacity === 0) { return; } if (painter.renderPass === 'translucent') { var depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D); if (opacity === 1 && !layer.paint.get('fill-extrusion-pattern').constantOr(1)) { var colorMode = painter.colorModeForRenderPass(); drawExtrusionTiles(painter, source, layer, coords, depthMode, StencilMode.disabled, colorMode); } else { drawExtrusionTiles(painter, source, layer, coords, depthMode, StencilMode.disabled, ColorMode.disabled); drawExtrusionTiles(painter, source, layer, coords, depthMode, painter.stencilModeFor3D(), painter.colorModeForRenderPass()); } } } function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode) { var context = painter.context; var gl = context.gl; var patternProperty = layer.paint.get('fill-extrusion-pattern'); var image = patternProperty.constantOr(1); var crossfade = layer.getCrossfadeParameters(); var opacity = layer.paint.get('fill-extrusion-opacity'); for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var tile = source.getTile(coord); var bucket = tile.getBucket(layer); if (!bucket) { continue; } var programConfiguration = bucket.programConfigurations.get(layer.id); var program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration); if (image) { painter.context.activeTexture.set(gl.TEXTURE0); tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); programConfiguration.updatePaintBuffers(crossfade); } var constantPattern = patternProperty.constantOr(null); if (constantPattern && tile.imageAtlas) { var atlas = tile.imageAtlas; var posTo = atlas.patternPositions[constantPattern.to.toString()]; var posFrom = atlas.patternPositions[constantPattern.from.toString()]; if (posTo && posFrom) { programConfiguration.setConstantPatternPositions(posTo, posFrom); } } var matrix = painter.translatePosMatrix(coord.posMatrix, tile, layer.paint.get('fill-extrusion-translate'), layer.paint.get('fill-extrusion-translate-anchor')); var shouldUseVerticalGradient = layer.paint.get('fill-extrusion-vertical-gradient'); var uniformValues = image ? fillExtrusionPatternUniformValues(matrix, painter, shouldUseVerticalGradient, opacity, coord, crossfade, tile) : fillExtrusionUniformValues(matrix, painter, shouldUseVerticalGradient, opacity); program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.backCCW, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); } } function drawHillshade(painter, sourceCache, layer, tileIDs) { if (painter.renderPass !== 'offscreen' && painter.renderPass !== 'translucent') { return; } var context = painter.context; var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); var colorMode = painter.colorModeForRenderPass(); var ref = painter.renderPass === 'translucent' ? painter.stencilConfigForOverlap(tileIDs) : [ {}, tileIDs ]; var stencilModes = ref[0]; var coords = ref[1]; for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var tile = sourceCache.getTile(coord); if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { prepareHillshade(painter, tile, layer, depthMode, StencilMode.disabled, colorMode); } else if (painter.renderPass === 'translucent') { renderHillshade(painter, tile, layer, depthMode, stencilModes[coord.overscaledZ], colorMode); } } context.viewport.set([ 0, 0, painter.width, painter.height ]); } function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { var context = painter.context; var gl = context.gl; var fbo = tile.fbo; if (!fbo) { return; } var program = painter.useProgram('hillshade'); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); var uniformValues = hillshadeUniformValues(painter, tile, layer); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } function prepareHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { var context = painter.context; var gl = context.gl; var dem = tile.dem; if (dem && dem.data) { var tileSize = dem.dim; var textureStride = dem.stride; var pixelData = dem.getPixels(); context.activeTexture.set(gl.TEXTURE1); context.pixelStoreUnpackPremultiplyAlpha.set(false); tile.demTexture = tile.demTexture || painter.getTileTexture(textureStride); if (tile.demTexture) { var demTexture = tile.demTexture; demTexture.update(pixelData, { premultiply: false }); demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE); } else { tile.demTexture = new performance.Texture(context, pixelData, gl.RGBA, { premultiply: false }); tile.demTexture.bind(gl.NEAREST, gl.CLAMP_TO_EDGE); } context.activeTexture.set(gl.TEXTURE0); var fbo = tile.fbo; if (!fbo) { var renderTexture = new performance.Texture(context, { width: tileSize, height: tileSize, data: null }, gl.RGBA); renderTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize, true); fbo.colorAttachment.set(renderTexture.texture); } context.bindFramebuffer.set(fbo.framebuffer); context.viewport.set([ 0, 0, tileSize, tileSize ]); painter.useProgram('hillshadePrepare').draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformPrepareValues(tile.tileID, dem), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); tile.needsHillshadePrepare = false; } } function drawRaster(painter, sourceCache, layer, tileIDs) { if (painter.renderPass !== 'translucent') { return; } if (layer.paint.get('raster-opacity') === 0) { return; } if (!tileIDs.length) { return; } var context = painter.context; var gl = context.gl; var source = sourceCache.getSource(); var program = painter.useProgram('raster'); var colorMode = painter.colorModeForRenderPass(); var ref = source instanceof ImageSource ? [ {}, tileIDs ] : painter.stencilConfigForOverlap(tileIDs); var stencilModes = ref[0]; var coords = ref[1]; var minTileZ = coords[coords.length - 1].overscaledZ; var align = !painter.options.moving; for (var i = 0, list = coords; i < list.length; i += 1) { var coord = list[i]; var depthMode = painter.depthModeForSublayer(coord.overscaledZ - minTileZ, layer.paint.get('raster-opacity') === 1 ? DepthMode.ReadWrite : DepthMode.ReadOnly, gl.LESS); var tile = sourceCache.getTile(coord); var posMatrix = painter.transform.calculatePosMatrix(coord.toUnwrapped(), align); tile.registerFadeDuration(layer.paint.get('raster-fade-duration')); var parentTile = sourceCache.findLoadedParent(coord, 0), fade = getFadeValues(tile, parentTile, sourceCache, layer, painter.transform); var parentScaleBy = void 0, parentTL = void 0; var textureFilter = layer.paint.get('raster-resampling') === 'nearest' ? gl.NEAREST : gl.LINEAR; context.activeTexture.set(gl.TEXTURE0); tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); context.activeTexture.set(gl.TEXTURE1); if (parentTile) { parentTile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); parentScaleBy = Math.pow(2, parentTile.tileID.overscaledZ - tile.tileID.overscaledZ); parentTL = [ tile.tileID.canonical.x * parentScaleBy % 1, tile.tileID.canonical.y * parentScaleBy % 1 ]; } else { tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } var uniformValues = rasterUniformValues(posMatrix, parentTL || [ 0, 0 ], parentScaleBy || 1, fade, layer); if (source instanceof ImageSource) { program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.disabled, uniformValues, layer.id, source.boundsBuffer, painter.quadTriangleIndexBuffer, source.boundsSegments); } else { program.draw(context, gl.TRIANGLES, depthMode, stencilModes[coord.overscaledZ], colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } } } function getFadeValues(tile, parentTile, sourceCache, layer, transform) { var fadeDuration = layer.paint.get('raster-fade-duration'); if (fadeDuration > 0) { var now = performance.browser.now(); var sinceTile = (now - tile.timeAdded) / fadeDuration; var sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1; var source = sourceCache.getSource(); var idealZ = transform.coveringZoomLevel({ tileSize: source.tileSize, roundZoom: source.roundZoom }); var fadeIn = !parentTile || Math.abs(parentTile.tileID.overscaledZ - idealZ) > Math.abs(tile.tileID.overscaledZ - idealZ); var childOpacity = fadeIn && tile.refreshedUponExpiration ? 1 : performance.clamp(fadeIn ? sinceTile : 1 - sinceParent, 0, 1); if (tile.refreshedUponExpiration && sinceTile >= 1) { tile.refreshedUponExpiration = false; } if (parentTile) { return { opacity: 1, mix: 1 - childOpacity }; } else { return { opacity: childOpacity, mix: 0 }; } } else { return { opacity: 1, mix: 0 }; } } function drawBackground(painter, sourceCache, layer) { var color = layer.paint.get('background-color'); var opacity = layer.paint.get('background-opacity'); if (opacity === 0) { return; } var context = painter.context; var gl = context.gl; var transform = painter.transform; var tileSize = transform.tileSize; var image = layer.paint.get('background-pattern'); if (painter.isPatternMissing(image)) { return; } var pass = !image && color.a === 1 && opacity === 1 && painter.opaquePassEnabledForLayer() ? 'opaque' : 'translucent'; if (painter.renderPass !== pass) { return; } var stencilMode = StencilMode.disabled; var depthMode = painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); var colorMode = painter.colorModeForRenderPass(); var program = painter.useProgram(image ? 'backgroundPattern' : 'background'); var tileIDs = transform.coveringTiles({ tileSize: tileSize }); if (image) { context.activeTexture.set(gl.TEXTURE0); painter.imageManager.bind(painter.context); } var crossfade = layer.getCrossfadeParameters(); for (var i = 0, list = tileIDs; i < list.length; i += 1) { var tileID = list[i]; var matrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); var uniformValues = image ? backgroundPatternUniformValues(matrix, opacity, painter, image, { tileID: tileID, tileSize: tileSize }, crossfade) : backgroundUniformValues(matrix, opacity, color); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.tileExtentBuffer, painter.quadTriangleIndexBuffer, painter.tileExtentSegments); } } var topColor = new performance.Color(1, 0, 0, 1); var btmColor = new performance.Color(0, 1, 0, 1); var leftColor = new performance.Color(0, 0, 1, 1); var rightColor = new performance.Color(1, 0, 1, 1); var centerColor = new performance.Color(0, 1, 1, 1); function drawDebugPadding(painter) { var padding = painter.transform.padding; var lineWidth = 3; drawHorizontalLine(painter, painter.transform.height - (padding.top || 0), lineWidth, topColor); drawHorizontalLine(painter, padding.bottom || 0, lineWidth, btmColor); drawVerticalLine(painter, padding.left || 0, lineWidth, leftColor); drawVerticalLine(painter, painter.transform.width - (padding.right || 0), lineWidth, rightColor); var center = painter.transform.centerPoint; drawCrosshair(painter, center.x, painter.transform.height - center.y, centerColor); } function drawCrosshair(painter, x, y, color) { var size = 20; var lineWidth = 2; drawDebugSSRect(painter, x - lineWidth / 2, y - size / 2, lineWidth, size, color); drawDebugSSRect(painter, x - size / 2, y - lineWidth / 2, size, lineWidth, color); } function drawHorizontalLine(painter, y, lineWidth, color) { drawDebugSSRect(painter, 0, y + lineWidth / 2, painter.transform.width, lineWidth, color); } function drawVerticalLine(painter, x, lineWidth, color) { drawDebugSSRect(painter, x - lineWidth / 2, 0, lineWidth, painter.transform.height, color); } function drawDebugSSRect(painter, x, y, width, height, color) { var context = painter.context; var gl = context.gl; gl.enable(gl.SCISSOR_TEST); gl.scissor(x * performance.browser.devicePixelRatio, y * performance.browser.devicePixelRatio, width * performance.browser.devicePixelRatio, height * performance.browser.devicePixelRatio); context.clear({ color: color }); gl.disable(gl.SCISSOR_TEST); } function drawDebug(painter, sourceCache, coords) { for (var i = 0; i < coords.length; i++) { drawDebugTile(painter, sourceCache, coords[i]); } } function drawDebugTile(painter, sourceCache, coord) { var context = painter.context; var gl = context.gl; var posMatrix = coord.posMatrix; var program = painter.useProgram('debug'); var depthMode = DepthMode.disabled; var stencilMode = StencilMode.disabled; var colorMode = painter.colorModeForRenderPass(); var id = '$debug'; context.activeTexture.set(gl.TEXTURE0); painter.emptyTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled, debugUniformValues(posMatrix, performance.Color.red), id, painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments); var tileRawData = sourceCache.getTileByID(coord.key).latestRawTileData; var tileByteLength = tileRawData && tileRawData.byteLength || 0; var tileSizeKb = Math.floor(tileByteLength / 1024); var tileSize = sourceCache.getTile(coord).tileSize; var scaleRatio = 512 / Math.min(tileSize, 512) * (coord.overscaledZ / painter.transform.zoom) * 0.5; var tileIdText = coord.canonical.toString(); if (coord.overscaledZ !== coord.canonical.z) { tileIdText += ' => ' + coord.overscaledZ; } var tileLabel = tileIdText + ' ' + tileSizeKb + 'kb'; drawTextToOverlay(painter, tileLabel); program.draw(context, gl.TRIANGLES, depthMode, stencilMode, ColorMode.alphaBlended, CullFaceMode.disabled, debugUniformValues(posMatrix, performance.Color.transparent, scaleRatio), id, painter.debugBuffer, painter.quadTriangleIndexBuffer, painter.debugSegments); } function drawTextToOverlay(painter, text) { painter.initDebugOverlayCanvas(); var canvas = painter.debugOverlayCanvas; var gl = painter.context.gl; var ctx2d = painter.debugOverlayCanvas.getContext('2d'); ctx2d.clearRect(0, 0, canvas.width, canvas.height); ctx2d.shadowColor = 'white'; ctx2d.shadowBlur = 2; ctx2d.lineWidth = 1.5; ctx2d.strokeStyle = 'white'; ctx2d.textBaseline = 'top'; ctx2d.font = 'bold ' + 36 + 'px Open Sans, sans-serif'; ctx2d.fillText(text, 5, 5); ctx2d.strokeText(text, 5, 5); painter.debugOverlayTexture.update(canvas); painter.debugOverlayTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); } function drawCustom(painter, sourceCache, layer) { var context = painter.context; var implementation = layer.implementation; if (painter.renderPass === 'offscreen') { var prerender = implementation.prerender; if (prerender) { painter.setCustomLayerDefaults(); context.setColorMode(painter.colorModeForRenderPass()); prerender.call(implementation, context.gl, painter.transform.customLayerMatrix()); context.setDirty(); painter.setBaseState(); } } else if (painter.renderPass === 'translucent') { painter.setCustomLayerDefaults(); context.setColorMode(painter.colorModeForRenderPass()); context.setStencilMode(StencilMode.disabled); var depthMode = implementation.renderingMode === '3d' ? new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, painter.depthRangeFor3D) : painter.depthModeForSublayer(0, DepthMode.ReadOnly); context.setDepthMode(depthMode); implementation.render(context.gl, painter.transform.customLayerMatrix()); context.setDirty(); painter.setBaseState(); context.bindFramebuffer.set(null); } } var draw$1 = { symbol: drawSymbols, circle: drawCircles, heatmap: drawHeatmap, line: drawLine, fill: drawFill, 'fill-extrusion': draw, hillshade: drawHillshade, raster: drawRaster, background: drawBackground, debug: drawDebug, custom: drawCustom }; var Painter = function Painter(gl, transform) { this.context = new Context(gl); this.transform = transform; this._tileTextures = {}; this.setup(); this.numSublayers = SourceCache.maxUnderzooming + SourceCache.maxOverzooming + 1; this.depthEpsilon = 1 / Math.pow(2, 16); this.crossTileSymbolIndex = new CrossTileSymbolIndex(); this.gpuTimers = {}; }; Painter.prototype.resize = function resize(width, height) { this.width = width * performance.browser.devicePixelRatio; this.height = height * performance.browser.devicePixelRatio; this.context.viewport.set([ 0, 0, this.width, this.height ]); if (this.style) { for (var i = 0, list = this.style._order; i < list.length; i += 1) { var layerId = list[i]; this.style._layers[layerId].resize(); } } }; Painter.prototype.setup = function setup() { var context = this.context; var tileExtentArray = new performance.StructArrayLayout2i4(); tileExtentArray.emplaceBack(0, 0); tileExtentArray.emplaceBack(performance.EXTENT, 0); tileExtentArray.emplaceBack(0, performance.EXTENT); tileExtentArray.emplaceBack(performance.EXTENT, performance.EXTENT); this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray, posAttributes.members); this.tileExtentSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); var debugArray = new performance.StructArrayLayout2i4(); debugArray.emplaceBack(0, 0); debugArray.emplaceBack(performance.EXTENT, 0); debugArray.emplaceBack(0, performance.EXTENT); debugArray.emplaceBack(performance.EXTENT, performance.EXTENT); this.debugBuffer = context.createVertexBuffer(debugArray, posAttributes.members); this.debugSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 5); var rasterBoundsArray = new performance.StructArrayLayout4i8(); rasterBoundsArray.emplaceBack(0, 0, 0, 0); rasterBoundsArray.emplaceBack(performance.EXTENT, 0, performance.EXTENT, 0); rasterBoundsArray.emplaceBack(0, performance.EXTENT, 0, performance.EXTENT); rasterBoundsArray.emplaceBack(performance.EXTENT, performance.EXTENT, performance.EXTENT, performance.EXTENT); this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray, rasterBoundsAttributes.members); this.rasterBoundsSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); var viewportArray = new performance.StructArrayLayout2i4(); viewportArray.emplaceBack(0, 0); viewportArray.emplaceBack(1, 0); viewportArray.emplaceBack(0, 1); viewportArray.emplaceBack(1, 1); this.viewportBuffer = context.createVertexBuffer(viewportArray, posAttributes.members); this.viewportSegments = performance.SegmentVector.simpleSegment(0, 0, 4, 2); var tileLineStripIndices = new performance.StructArrayLayout1ui2(); tileLineStripIndices.emplaceBack(0); tileLineStripIndices.emplaceBack(1); tileLineStripIndices.emplaceBack(3); tileLineStripIndices.emplaceBack(2); tileLineStripIndices.emplaceBack(0); this.tileBorderIndexBuffer = context.createIndexBuffer(tileLineStripIndices); var quadTriangleIndices = new performance.StructArrayLayout3ui6(); quadTriangleIndices.emplaceBack(0, 1, 2); quadTriangleIndices.emplaceBack(2, 1, 3); this.quadTriangleIndexBuffer = context.createIndexBuffer(quadTriangleIndices); this.emptyTexture = new performance.Texture(context, { width: 1, height: 1, data: new Uint8Array([ 0, 0, 0, 0 ]) }, context.gl.RGBA); var gl = this.context.gl; this.stencilClearMode = new StencilMode({ func: gl.ALWAYS, mask: 0 }, 0, 255, gl.ZERO, gl.ZERO, gl.ZERO); }; Painter.prototype.clearStencil = function clearStencil() { var context = this.context; var gl = context.gl; this.nextStencilID = 1; this.currentStencilSource = undefined; var matrix = performance.create(); performance.ortho(matrix, 0, this.width, this.height, 0, 0, 1); performance.scale(matrix, matrix, [ gl.drawingBufferWidth, gl.drawingBufferHeight, 0 ]); this.useProgram('clippingMask').draw(context, gl.TRIANGLES, DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(matrix), '$clipping', this.viewportBuffer, this.quadTriangleIndexBuffer, this.viewportSegments); }; Painter.prototype._renderTileClippingMasks = function _renderTileClippingMasks(layer, tileIDs) { if (this.currentStencilSource === layer.source || !layer.isTileClipped() || !tileIDs || !tileIDs.length) { return; } this.currentStencilSource = layer.source; var context = this.context; var gl = context.gl; if (this.nextStencilID + tileIDs.length > 256) { this.clearStencil(); } context.setColorMode(ColorMode.disabled); context.setDepthMode(DepthMode.disabled); var program = this.useProgram('clippingMask'); this._tileClippingMaskIDs = {}; for (var i = 0, list = tileIDs; i < list.length; i += 1) { var tileID = list[i]; var id = this._tileClippingMaskIDs[tileID.key] = this.nextStencilID++; program.draw(context, gl.TRIANGLES, DepthMode.disabled, new StencilMode({ func: gl.ALWAYS, mask: 0 }, id, 255, gl.KEEP, gl.KEEP, gl.REPLACE), ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(tileID.posMatrix), '$clipping', this.tileExtentBuffer, this.quadTriangleIndexBuffer, this.tileExtentSegments); } }; Painter.prototype.stencilModeFor3D = function stencilModeFor3D() { this.currentStencilSource = undefined; if (this.nextStencilID + 1 > 256) { this.clearStencil(); } var id = this.nextStencilID++; var gl = this.context.gl; return new StencilMode({ func: gl.NOTEQUAL, mask: 255 }, id, 255, gl.KEEP, gl.KEEP, gl.REPLACE); }; Painter.prototype.stencilModeForClipping = function stencilModeForClipping(tileID) { var gl = this.context.gl; return new StencilMode({ func: gl.EQUAL, mask: 255 }, this._tileClippingMaskIDs[tileID.key], 0, gl.KEEP, gl.KEEP, gl.REPLACE); }; Painter.prototype.stencilConfigForOverlap = function stencilConfigForOverlap(tileIDs) { var obj; var gl = this.context.gl; var coords = tileIDs.sort(function (a, b) { return b.overscaledZ - a.overscaledZ; }); var minTileZ = coords[coords.length - 1].overscaledZ; var stencilValues = coords[0].overscaledZ - minTileZ + 1; if (stencilValues > 1) { this.currentStencilSource = undefined; if (this.nextStencilID + stencilValues > 256) { this.clearStencil(); } var zToStencilMode = {}; for (var i = 0; i < stencilValues; i++) { zToStencilMode[i + minTileZ] = new StencilMode({ func: gl.GEQUAL, mask: 255 }, i + this.nextStencilID, 255, gl.KEEP, gl.KEEP, gl.REPLACE); } this.nextStencilID += stencilValues; return [ zToStencilMode, coords ]; } return [ (obj = {}, obj[minTileZ] = StencilMode.disabled, obj), coords ]; }; Painter.prototype.colorModeForRenderPass = function colorModeForRenderPass() { var gl = this.context.gl; if (this._showOverdrawInspector) { var numOverdrawSteps = 8; var a = 1 / numOverdrawSteps; return new ColorMode([ gl.CONSTANT_COLOR, gl.ONE ], new performance.Color(a, a, a, 0), [ true, true, true, true ]); } else if (this.renderPass === 'opaque') { return ColorMode.unblended; } else { return ColorMode.alphaBlended; } }; Painter.prototype.depthModeForSublayer = function depthModeForSublayer(n, mask, func) { if (!this.opaquePassEnabledForLayer()) { return DepthMode.disabled; } var depth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon; return new DepthMode(func || this.context.gl.LEQUAL, mask, [ depth, depth ]); }; Painter.prototype.opaquePassEnabledForLayer = function opaquePassEnabledForLayer() { return this.currentLayer < this.opaquePassCutoff; }; Painter.prototype.render = function render(style, options) { var this$1 = this; this.style = style; this.options = options; this.lineAtlas = style.lineAtlas; this.imageManager = style.imageManager; this.glyphManager = style.glyphManager; this.symbolFadeChange = style.placement.symbolFadeChange(performance.browser.now()); this.imageManager.beginFrame(); var layerIds = this.style._order; var sourceCaches = this.style.sourceCaches; for (var id in sourceCaches) { var sourceCache = sourceCaches[id]; if (sourceCache.used) { sourceCache.prepare(this.context); } } var coordsAscending = {}; var coordsDescending = {}; var coordsDescendingSymbol = {}; for (var id$1 in sourceCaches) { var sourceCache$1 = sourceCaches[id$1]; coordsAscending[id$1] = sourceCache$1.getVisibleCoordinates(); coordsDescending[id$1] = coordsAscending[id$1].slice().reverse(); coordsDescendingSymbol[id$1] = sourceCache$1.getVisibleCoordinates(true).reverse(); } this.opaquePassCutoff = Infinity; for (var i = 0; i < layerIds.length; i++) { var layerId = layerIds[i]; if (this.style._layers[layerId].is3D()) { this.opaquePassCutoff = i; break; } } this.renderPass = 'offscreen'; for (var i$1 = 0, list = layerIds; i$1 < list.length; i$1 += 1) { var layerId$1 = list[i$1]; var layer = this.style._layers[layerId$1]; if (!layer.hasOffscreenPass() || layer.isHidden(this.transform.zoom)) { continue; } var coords = coordsDescending[layer.source]; if (layer.type !== 'custom' && !coords.length) { continue; } this.renderLayer(this, sourceCaches[layer.source], layer, coords); } this.context.bindFramebuffer.set(null); this.context.clear({ color: options.showOverdrawInspector ? performance.Color.black : performance.Color.transparent, depth: 1 }); this.clearStencil(); this._showOverdrawInspector = options.showOverdrawInspector; this.depthRangeFor3D = [ 0, 1 - (style._order.length + 2) * this.numSublayers * this.depthEpsilon ]; this.renderPass = 'opaque'; for (this.currentLayer = layerIds.length - 1; this.currentLayer >= 0; this.currentLayer--) { var layer$1 = this.style._layers[layerIds[this.currentLayer]]; var sourceCache$2 = sourceCaches[layer$1.source]; var coords$1 = coordsAscending[layer$1.source]; this._renderTileClippingMasks(layer$1, coords$1); this.renderLayer(this, sourceCache$2, layer$1, coords$1); } this.renderPass = 'translucent'; for (this.currentLayer = 0; this.currentLayer < layerIds.length; this.currentLayer++) { var layer$2 = this.style._layers[layerIds[this.currentLayer]]; var sourceCache$3 = sourceCaches[layer$2.source]; var coords$2 = (layer$2.type === 'symbol' ? coordsDescendingSymbol : coordsDescending)[layer$2.source]; this._renderTileClippingMasks(layer$2, coordsAscending[layer$2.source]); this.renderLayer(this, sourceCache$3, layer$2, coords$2); } if (this.options.showTileBoundaries) { var selectedSource; var sourceCache$4; var layers = performance.values(this.style._layers); layers.forEach(function (layer) { if (layer.source && !layer.isHidden(this$1.transform.zoom)) { if (layer.source !== (sourceCache$4 && sourceCache$4.id)) { sourceCache$4 = this$1.style.sourceCaches[layer.source]; } if (!selectedSource || selectedSource.getSource().maxzoom < sourceCache$4.getSource().maxzoom) { selectedSource = sourceCache$4; } } }); if (selectedSource) { draw$1.debug(this, selectedSource, selectedSource.getVisibleCoordinates()); } } if (this.options.showPadding) { drawDebugPadding(this); } this.context.setDefault(); }; Painter.prototype.renderLayer = function renderLayer(painter, sourceCache, layer, coords) { if (layer.isHidden(this.transform.zoom)) { return; } if (layer.type !== 'background' && layer.type !== 'custom' && !coords.length) { return; } this.id = layer.id; this.gpuTimingStart(layer); draw$1[layer.type](painter, sourceCache, layer, coords, this.style.placement.variableOffsets); this.gpuTimingEnd(); }; Painter.prototype.gpuTimingStart = function gpuTimingStart(layer) { if (!this.options.gpuTiming) { return; } var ext = this.context.extTimerQuery; var layerTimer = this.gpuTimers[layer.id]; if (!layerTimer) { layerTimer = this.gpuTimers[layer.id] = { calls: 0, cpuTime: 0, query: ext.createQueryEXT() }; } layerTimer.calls++; ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, layerTimer.query); }; Painter.prototype.gpuTimingEnd = function gpuTimingEnd() { if (!this.options.gpuTiming) { return; } var ext = this.context.extTimerQuery; ext.endQueryEXT(ext.TIME_ELAPSED_EXT); }; Painter.prototype.collectGpuTimers = function collectGpuTimers() { var currentLayerTimers = this.gpuTimers; this.gpuTimers = {}; return currentLayerTimers; }; Painter.prototype.queryGpuTimers = function queryGpuTimers(gpuTimers) { var layers = {}; for (var layerId in gpuTimers) { var gpuTimer = gpuTimers[layerId]; var ext = this.context.extTimerQuery; var gpuTime = ext.getQueryObjectEXT(gpuTimer.query, ext.QUERY_RESULT_EXT) / (1000 * 1000); ext.deleteQueryEXT(gpuTimer.query); layers[layerId] = gpuTime; } return layers; }; Painter.prototype.translatePosMatrix = function translatePosMatrix(matrix, tile, translate, translateAnchor, inViewportPixelUnitsUnits) { if (!translate[0] && !translate[1]) { return matrix; } var angle = inViewportPixelUnitsUnits ? translateAnchor === 'map' ? this.transform.angle : 0 : translateAnchor === 'viewport' ? -this.transform.angle : 0; if (angle) { var sinA = Math.sin(angle); var cosA = Math.cos(angle); translate = [ translate[0] * cosA - translate[1] * sinA, translate[0] * sinA + translate[1] * cosA ]; } var translation = [ inViewportPixelUnitsUnits ? translate[0] : pixelsToTileUnits(tile, translate[0], this.transform.zoom), inViewportPixelUnitsUnits ? translate[1] : pixelsToTileUnits(tile, translate[1], this.transform.zoom), 0 ]; var translatedMatrix = new Float32Array(16); performance.translate(translatedMatrix, matrix, translation); return translatedMatrix; }; Painter.prototype.saveTileTexture = function saveTileTexture(texture) { var textures = this._tileTextures[texture.size[0]]; if (!textures) { this._tileTextures[texture.size[0]] = [texture]; } else { textures.push(texture); } }; Painter.prototype.getTileTexture = function getTileTexture(size) { var textures = this._tileTextures[size]; return textures && textures.length > 0 ? textures.pop() : null; }; Painter.prototype.isPatternMissing = function isPatternMissing(image) { if (!image) { return false; } if (!image.from || !image.to) { return true; } var imagePosA = this.imageManager.getPattern(image.from.toString()); var imagePosB = this.imageManager.getPattern(image.to.toString()); return !imagePosA || !imagePosB; }; Painter.prototype.useProgram = function useProgram(name, programConfiguration) { this.cache = this.cache || {}; var key = '' + name + (programConfiguration ? programConfiguration.cacheKey : '') + (this._showOverdrawInspector ? '/overdraw' : ''); if (!this.cache[key]) { this.cache[key] = new Program$1(this.context, name, shaders[name], programConfiguration, programUniforms[name], this._showOverdrawInspector); } return this.cache[key]; }; Painter.prototype.setCustomLayerDefaults = function setCustomLayerDefaults() { this.context.unbindVAO(); this.context.cullFace.setDefault(); this.context.activeTexture.setDefault(); this.context.pixelStoreUnpack.setDefault(); this.context.pixelStoreUnpackPremultiplyAlpha.setDefault(); this.context.pixelStoreUnpackFlipY.setDefault(); }; Painter.prototype.setBaseState = function setBaseState() { var gl = this.context.gl; this.context.cullFace.set(false); this.context.viewport.set([ 0, 0, this.width, this.height ]); this.context.blendEquation.set(gl.FUNC_ADD); }; Painter.prototype.initDebugOverlayCanvas = function initDebugOverlayCanvas() { if (this.debugOverlayCanvas == null) { this.debugOverlayCanvas = performance.window.document.createElement('canvas'); this.debugOverlayCanvas.width = 512; this.debugOverlayCanvas.height = 512; var gl = this.context.gl; this.debugOverlayTexture = new performance.Texture(this.context, this.debugOverlayCanvas, gl.RGBA); } }; Painter.prototype.destroy = function destroy() { this.emptyTexture.destroy(); if (this.debugOverlayTexture) { this.debugOverlayTexture.destroy(); } }; var Frustum = function Frustum(points_, planes_) { this.points = points_; this.planes = planes_; }; Frustum.fromInvProjectionMatrix = function fromInvProjectionMatrix(invProj, worldSize, zoom) { var clipSpaceCorners = [ [ -1, 1, -1, 1 ], [ 1, 1, -1, 1 ], [ 1, -1, -1, 1 ], [ -1, -1, -1, 1 ], [ -1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, -1, 1, 1 ], [ -1, -1, 1, 1 ] ]; var scale = Math.pow(2, zoom); var frustumCoords = clipSpaceCorners.map(function (v) { return performance.transformMat4([], v, invProj); }).map(function (v) { return performance.scale$1([], v, 1 / v[3] / worldSize * scale); }); var frustumPlanePointIndices = [ [ 0, 1, 2 ], [ 6, 5, 4 ], [ 0, 3, 7 ], [ 2, 1, 5 ], [ 3, 2, 6 ], [ 0, 4, 5 ] ]; var frustumPlanes = frustumPlanePointIndices.map(function (p) { var a = performance.sub([], frustumCoords[p[0]], frustumCoords[p[1]]); var b = performance.sub([], frustumCoords[p[2]], frustumCoords[p[1]]); var n = performance.normalize([], performance.cross([], a, b)); var d = -performance.dot(n, frustumCoords[p[1]]); return n.concat(d); }); return new Frustum(frustumCoords, frustumPlanes); }; var Aabb = function Aabb(min_, max_) { this.min = min_; this.max = max_; this.center = performance.scale$2([], performance.add([], this.min, this.max), 0.5); }; Aabb.prototype.quadrant = function quadrant(index) { var split = [ index % 2 === 0, index < 2 ]; var qMin = performance.clone$2(this.min); var qMax = performance.clone$2(this.max); for (var axis = 0; axis < split.length; axis++) { qMin[axis] = split[axis] ? this.min[axis] : this.center[axis]; qMax[axis] = split[axis] ? this.center[axis] : this.max[axis]; } qMax[2] = this.max[2]; return new Aabb(qMin, qMax); }; Aabb.prototype.distanceX = function distanceX(point) { var pointOnAabb = Math.max(Math.min(this.max[0], point[0]), this.min[0]); return pointOnAabb - point[0]; }; Aabb.prototype.distanceY = function distanceY(point) { var pointOnAabb = Math.max(Math.min(this.max[1], point[1]), this.min[1]); return pointOnAabb - point[1]; }; Aabb.prototype.intersects = function intersects(frustum) { var aabbPoints = [ [ this.min[0], this.min[1], 0, 1 ], [ this.max[0], this.min[1], 0, 1 ], [ this.max[0], this.max[1], 0, 1 ], [ this.min[0], this.max[1], 0, 1 ] ]; var fullyInside = true; for (var p = 0; p < frustum.planes.length; p++) { var plane = frustum.planes[p]; var pointsInside = 0; for (var i = 0; i < aabbPoints.length; i++) { pointsInside += performance.dot$1(plane, aabbPoints[i]) >= 0; } if (pointsInside === 0) { return 0; } if (pointsInside !== aabbPoints.length) { fullyInside = false; } } if (fullyInside) { return 2; } for (var axis = 0; axis < 3; axis++) { var projMin = Number.MAX_VALUE; var projMax = -Number.MAX_VALUE; for (var p$1 = 0; p$1 < frustum.points.length; p$1++) { var projectedPoint = frustum.points[p$1][axis] - this.min[axis]; projMin = Math.min(projMin, projectedPoint); projMax = Math.max(projMax, projectedPoint); } if (projMax < 0 || projMin > this.max[axis] - this.min[axis]) { return 0; } } return 1; }; var EdgeInsets = function EdgeInsets(top, bottom, left, right) { if (top === void 0) top = 0; if (bottom === void 0) bottom = 0; if (left === void 0) left = 0; if (right === void 0) right = 0; if (isNaN(top) || top < 0 || isNaN(bottom) || bottom < 0 || isNaN(left) || left < 0 || isNaN(right) || right < 0) { throw new Error('Invalid value for edge-insets, top, bottom, left and right must all be numbers'); } this.top = top; this.bottom = bottom; this.left = left; this.right = right; }; EdgeInsets.prototype.interpolate = function interpolate(start, target, t) { if (target.top != null && start.top != null) { this.top = performance.number(start.top, target.top, t); } if (target.bottom != null && start.bottom != null) { this.bottom = performance.number(start.bottom, target.bottom, t); } if (target.left != null && start.left != null) { this.left = performance.number(start.left, target.left, t); } if (target.right != null && start.right != null) { this.right = performance.number(start.right, target.right, t); } return this; }; EdgeInsets.prototype.getCenter = function getCenter(width, height) { var x = performance.clamp((this.left + width - this.right) / 2, 0, width); var y = performance.clamp((this.top + height - this.bottom) / 2, 0, height); return new performance.Point(x, y); }; EdgeInsets.prototype.equals = function equals(other) { return this.top === other.top && this.bottom === other.bottom && this.left === other.left && this.right === other.right; }; EdgeInsets.prototype.clone = function clone() { return new EdgeInsets(this.top, this.bottom, this.left, this.right); }; EdgeInsets.prototype.toJSON = function toJSON() { return { top: this.top, bottom: this.bottom, left: this.left, right: this.right }; }; var Transform = function Transform(minZoom, maxZoom, minPitch, maxPitch, renderWorldCopies) { this.tileSize = 512; this.maxValidLatitude = 85.051129; this._renderWorldCopies = renderWorldCopies === undefined ? true : renderWorldCopies; this._minZoom = minZoom || 0; this._maxZoom = maxZoom || 22; this._minPitch = minPitch === undefined || minPitch === null ? 0 : minPitch; this._maxPitch = maxPitch === undefined || maxPitch === null ? 60 : maxPitch; this.setMaxBounds(); this.width = 0; this.height = 0; this._center = new performance.LngLat(0, 0); this.zoom = 0; this.angle = 0; this._fov = 0.6435011087932844; this._pitch = 0; this._unmodified = true; this._edgeInsets = new EdgeInsets(); this._posMatrixCache = {}; this._alignedPosMatrixCache = {}; }; var prototypeAccessors = { minZoom: { configurable: true }, maxZoom: { configurable: true }, minPitch: { configurable: true }, maxPitch: { configurable: true }, renderWorldCopies: { configurable: true }, worldSize: { configurable: true }, centerOffset: { configurable: true }, size: { configurable: true }, bearing: { configurable: true }, pitch: { configurable: true }, fov: { configurable: true }, zoom: { configurable: true }, center: { configurable: true }, padding: { configurable: true }, centerPoint: { configurable: true }, unmodified: { configurable: true }, point: { configurable: true } }; Transform.prototype.clone = function clone() { var clone = new Transform(this._minZoom, this._maxZoom, this._minPitch, this.maxPitch, this._renderWorldCopies); clone.tileSize = this.tileSize; clone.latRange = this.latRange; clone.width = this.width; clone.height = this.height; clone._center = this._center; clone.zoom = this.zoom; clone.angle = this.angle; clone._fov = this._fov; clone._pitch = this._pitch; clone._unmodified = this._unmodified; clone._edgeInsets = this._edgeInsets.clone(); clone._calcMatrices(); return clone; }; prototypeAccessors.minZoom.get = function () { return this._minZoom; }; prototypeAccessors.minZoom.set = function (zoom) { if (this._minZoom === zoom) { return; } this._minZoom = zoom; this.zoom = Math.max(this.zoom, zoom); }; prototypeAccessors.maxZoom.get = function () { return this._maxZoom; }; prototypeAccessors.maxZoom.set = function (zoom) { if (this._maxZoom === zoom) { return; } this._maxZoom = zoom; this.zoom = Math.min(this.zoom, zoom); }; prototypeAccessors.minPitch.get = function () { return this._minPitch; }; prototypeAccessors.minPitch.set = function (pitch) { if (this._minPitch === pitch) { return; } this._minPitch = pitch; this.pitch = Math.max(this.pitch, pitch); }; prototypeAccessors.maxPitch.get = function () { return this._maxPitch; }; prototypeAccessors.maxPitch.set = function (pitch) { if (this._maxPitch === pitch) { return; } this._maxPitch = pitch; this.pitch = Math.min(this.pitch, pitch); }; prototypeAccessors.renderWorldCopies.get = function () { return this._renderWorldCopies; }; prototypeAccessors.renderWorldCopies.set = function (renderWorldCopies) { if (renderWorldCopies === undefined) { renderWorldCopies = true; } else if (renderWorldCopies === null) { renderWorldCopies = false; } this._renderWorldCopies = renderWorldCopies; }; prototypeAccessors.worldSize.get = function () { return this.tileSize * this.scale; }; prototypeAccessors.centerOffset.get = function () { return this.centerPoint._sub(this.size._div(2)); }; prototypeAccessors.size.get = function () { return new performance.Point(this.width, this.height); }; prototypeAccessors.bearing.get = function () { return -this.angle / Math.PI * 180; }; prototypeAccessors.bearing.set = function (bearing) { var b = -performance.wrap(bearing, -180, 180) * Math.PI / 180; if (this.angle === b) { return; } this._unmodified = false; this.angle = b; this._calcMatrices(); this.rotationMatrix = performance.create$2(); performance.rotate(this.rotationMatrix, this.rotationMatrix, this.angle); }; prototypeAccessors.pitch.get = function () { return this._pitch / Math.PI * 180; }; prototypeAccessors.pitch.set = function (pitch) { var p = performance.clamp(pitch, this.minPitch, this.maxPitch) / 180 * Math.PI; if (this._pitch === p) { return; } this._unmodified = false; this._pitch = p; this._calcMatrices(); }; prototypeAccessors.fov.get = function () { return this._fov / Math.PI * 180; }; prototypeAccessors.fov.set = function (fov) { fov = Math.max(0.01, Math.min(60, fov)); if (this._fov === fov) { return; } this._unmodified = false; this._fov = fov / 180 * Math.PI; this._calcMatrices(); }; prototypeAccessors.zoom.get = function () { return this._zoom; }; prototypeAccessors.zoom.set = function (zoom) { var z = Math.min(Math.max(zoom, this.minZoom), this.maxZoom); if (this._zoom === z) { return; } this._unmodified = false; this._zoom = z; this.scale = this.zoomScale(z); this.tileZoom = Math.floor(z); this.zoomFraction = z - this.tileZoom; this._constrain(); this._calcMatrices(); }; prototypeAccessors.center.get = function () { return this._center; }; prototypeAccessors.center.set = function (center) { if (center.lat === this._center.lat && center.lng === this._center.lng) { return; } this._unmodified = false; this._center = center; this._constrain(); this._calcMatrices(); }; prototypeAccessors.padding.get = function () { return this._edgeInsets.toJSON(); }; prototypeAccessors.padding.set = function (padding) { if (this._edgeInsets.equals(padding)) { return; } this._unmodified = false; this._edgeInsets.interpolate(this._edgeInsets, padding, 1); this._calcMatrices(); }; prototypeAccessors.centerPoint.get = function () { return this._edgeInsets.getCenter(this.width, this.height); }; Transform.prototype.isPaddingEqual = function isPaddingEqual(padding) { return this._edgeInsets.equals(padding); }; Transform.prototype.interpolatePadding = function interpolatePadding(start, target, t) { this._unmodified = false; this._edgeInsets.interpolate(start, target, t); this._constrain(); this._calcMatrices(); }; Transform.prototype.coveringZoomLevel = function coveringZoomLevel(options) { var z = (options.roundZoom ? Math.round : Math.floor)(this.zoom + this.scaleZoom(this.tileSize / options.tileSize)); return Math.max(0, z); }; Transform.prototype.getVisibleUnwrappedCoordinates = function getVisibleUnwrappedCoordinates(tileID) { var result = [new performance.UnwrappedTileID(0, tileID)]; if (this._renderWorldCopies) { var utl = this.pointCoordinate(new performance.Point(0, 0)); var utr = this.pointCoordinate(new performance.Point(this.width, 0)); var ubl = this.pointCoordinate(new performance.Point(this.width, this.height)); var ubr = this.pointCoordinate(new performance.Point(0, this.height)); var w0 = Math.floor(Math.min(utl.x, utr.x, ubl.x, ubr.x)); var w1 = Math.floor(Math.max(utl.x, utr.x, ubl.x, ubr.x)); var extraWorldCopy = 1; for (var w = w0 - extraWorldCopy; w <= w1 + extraWorldCopy; w++) { if (w === 0) { continue; } result.push(new performance.UnwrappedTileID(w, tileID)); } } return result; }; Transform.prototype.coveringTiles = function coveringTiles(options) { var z = this.coveringZoomLevel(options); var actualZ = z; if (options.minzoom !== undefined && z < options.minzoom) { return []; } if (options.maxzoom !== undefined && z > options.maxzoom) { z = options.maxzoom; } var centerCoord = performance.MercatorCoordinate.fromLngLat(this.center); var numTiles = Math.pow(2, z); var centerPoint = [ numTiles * centerCoord.x, numTiles * centerCoord.y, 0 ]; var cameraFrustum = Frustum.fromInvProjectionMatrix(this.invProjMatrix, this.worldSize, z); var minZoom = options.minzoom || 0; if (this.pitch <= 60 && this._edgeInsets.top < 0.1) { minZoom = z; } var radiusOfMaxLvlLodInTiles = 3; var newRootTile = function (wrap) { return { aabb: new Aabb([ wrap * numTiles, 0, 0 ], [ (wrap + 1) * numTiles, numTiles, 0 ]), zoom: 0, x: 0, y: 0, wrap: wrap, fullyVisible: false }; }; var stack = []; var result = []; var maxZoom = z; var overscaledZ = options.reparseOverscaled ? actualZ : z; if (this._renderWorldCopies) { for (var i = 1; i <= 3; i++) { stack.push(newRootTile(-i)); stack.push(newRootTile(i)); } } stack.push(newRootTile(0)); while (stack.length > 0) { var it = stack.pop(); var x = it.x; var y = it.y; var fullyVisible = it.fullyVisible; if (!fullyVisible) { var intersectResult = it.aabb.intersects(cameraFrustum); if (intersectResult === 0) { continue; } fullyVisible = intersectResult === 2; } var distanceX = it.aabb.distanceX(centerPoint); var distanceY = it.aabb.distanceY(centerPoint); var longestDim = Math.max(Math.abs(distanceX), Math.abs(distanceY)); var distToSplit = radiusOfMaxLvlLodInTiles + (1 << maxZoom - it.zoom) - 2; if (it.zoom === maxZoom || longestDim > distToSplit && it.zoom >= minZoom) { result.push({ tileID: new performance.OverscaledTileID(it.zoom === maxZoom ? overscaledZ : it.zoom, it.wrap, it.zoom, x, y), distanceSq: performance.sqrLen([ centerPoint[0] - 0.5 - x, centerPoint[1] - 0.5 - y ]) }); continue; } for (var i$1 = 0; i$1 < 4; i$1++) { var childX = (x << 1) + i$1 % 2; var childY = (y << 1) + (i$1 >> 1); stack.push({ aabb: it.aabb.quadrant(i$1), zoom: it.zoom + 1, x: childX, y: childY, wrap: it.wrap, fullyVisible: fullyVisible }); } } return result.sort(function (a, b) { return a.distanceSq - b.distanceSq; }).map(function (a) { return a.tileID; }); }; Transform.prototype.resize = function resize(width, height) { this.width = width; this.height = height; this.pixelsToGLUnits = [ 2 / width, -2 / height ]; this._constrain(); this._calcMatrices(); }; prototypeAccessors.unmodified.get = function () { return this._unmodified; }; Transform.prototype.zoomScale = function zoomScale(zoom) { return Math.pow(2, zoom); }; Transform.prototype.scaleZoom = function scaleZoom(scale) { return Math.log(scale) / Math.LN2; }; Transform.prototype.project = function project(lnglat) { var lat = performance.clamp(lnglat.lat, -this.maxValidLatitude, this.maxValidLatitude); return new performance.Point(performance.mercatorXfromLng(lnglat.lng) * this.worldSize, performance.mercatorYfromLat(lat) * this.worldSize); }; Transform.prototype.unproject = function unproject(point) { return new performance.MercatorCoordinate(point.x / this.worldSize, point.y / this.worldSize).toLngLat(); }; prototypeAccessors.point.get = function () { return this.project(this.center); }; Transform.prototype.setLocationAtPoint = function setLocationAtPoint(lnglat, point) { var a = this.pointCoordinate(point); var b = this.pointCoordinate(this.centerPoint); var loc = this.locationCoordinate(lnglat); var newCenter = new performance.MercatorCoordinate(loc.x - (a.x - b.x), loc.y - (a.y - b.y)); this.center = this.coordinateLocation(newCenter); if (this._renderWorldCopies) { this.center = this.center.wrap(); } }; Transform.prototype.locationPoint = function locationPoint(lnglat) { return this.coordinatePoint(this.locationCoordinate(lnglat)); }; Transform.prototype.pointLocation = function pointLocation(p) { return this.coordinateLocation(this.pointCoordinate(p)); }; Transform.prototype.locationCoordinate = function locationCoordinate(lnglat) { return performance.MercatorCoordinate.fromLngLat(lnglat); }; Transform.prototype.coordinateLocation = function coordinateLocation(coord) { return coord.toLngLat(); }; Transform.prototype.pointCoordinate = function pointCoordinate(p) { var targetZ = 0; var coord0 = [ p.x, p.y, 0, 1 ]; var coord1 = [ p.x, p.y, 1, 1 ]; performance.transformMat4(coord0, coord0, this.pixelMatrixInverse); performance.transformMat4(coord1, coord1, this.pixelMatrixInverse); var w0 = coord0[3]; var w1 = coord1[3]; var x0 = coord0[0] / w0; var x1 = coord1[0] / w1; var y0 = coord0[1] / w0; var y1 = coord1[1] / w1; var z0 = coord0[2] / w0; var z1 = coord1[2] / w1; var t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0); return new performance.MercatorCoordinate(performance.number(x0, x1, t) / this.worldSize, performance.number(y0, y1, t) / this.worldSize); }; Transform.prototype.coordinatePoint = function coordinatePoint(coord) { var p = [ coord.x * this.worldSize, coord.y * this.worldSize, 0, 1 ]; performance.transformMat4(p, p, this.pixelMatrix); return new performance.Point(p[0] / p[3], p[1] / p[3]); }; Transform.prototype.getBounds = function getBounds() { return new performance.LngLatBounds().extend(this.pointLocation(new performance.Point(0, 0))).extend(this.pointLocation(new performance.Point(this.width, 0))).extend(this.pointLocation(new performance.Point(this.width, this.height))).extend(this.pointLocation(new performance.Point(0, this.height))); }; Transform.prototype.getMaxBounds = function getMaxBounds() { if (!this.latRange || this.latRange.length !== 2 || !this.lngRange || this.lngRange.length !== 2) { return null; } return new performance.LngLatBounds([ this.lngRange[0], this.latRange[0] ], [ this.lngRange[1], this.latRange[1] ]); }; Transform.prototype.setMaxBounds = function setMaxBounds(bounds) { if (bounds) { this.lngRange = [ bounds.getWest(), bounds.getEast() ]; this.latRange = [ bounds.getSouth(), bounds.getNorth() ]; this._constrain(); } else { this.lngRange = null; this.latRange = [ -this.maxValidLatitude, this.maxValidLatitude ]; } }; Transform.prototype.calculatePosMatrix = function calculatePosMatrix(unwrappedTileID, aligned) { if (aligned === void 0) aligned = false; var posMatrixKey = unwrappedTileID.key; var cache = aligned ? this._alignedPosMatrixCache : this._posMatrixCache; if (cache[posMatrixKey]) { return cache[posMatrixKey]; } var canonical = unwrappedTileID.canonical; var scale = this.worldSize / this.zoomScale(canonical.z); var unwrappedX = canonical.x + Math.pow(2, canonical.z) * unwrappedTileID.wrap; var posMatrix = performance.identity(new Float64Array(16)); performance.translate(posMatrix, posMatrix, [ unwrappedX * scale, canonical.y * scale, 0 ]); performance.scale(posMatrix, posMatrix, [ scale / performance.EXTENT, scale / performance.EXTENT, 1 ]); performance.multiply(posMatrix, aligned ? this.alignedProjMatrix : this.projMatrix, posMatrix); cache[posMatrixKey] = new Float32Array(posMatrix); return cache[posMatrixKey]; }; Transform.prototype.customLayerMatrix = function customLayerMatrix() { return this.mercatorMatrix.slice(); }; Transform.prototype._constrain = function _constrain() { if (!this.center || !this.width || !this.height || this._constraining) { return; } this._constraining = true; var minY = -90; var maxY = 90; var minX = -180; var maxX = 180; var sy, sx, x2, y2; var size = this.size, unmodified = this._unmodified; if (this.latRange) { var latRange = this.latRange; minY = performance.mercatorYfromLat(latRange[1]) * this.worldSize; maxY = performance.mercatorYfromLat(latRange[0]) * this.worldSize; sy = maxY - minY < size.y ? size.y / (maxY - minY) : 0; } if (this.lngRange) { var lngRange = this.lngRange; minX = performance.mercatorXfromLng(lngRange[0]) * this.worldSize; maxX = performance.mercatorXfromLng(lngRange[1]) * this.worldSize; sx = maxX - minX < size.x ? size.x / (maxX - minX) : 0; } var point = this.point; var s = Math.max(sx || 0, sy || 0); if (s) { this.center = this.unproject(new performance.Point(sx ? (maxX + minX) / 2 : point.x, sy ? (maxY + minY) / 2 : point.y)); this.zoom += this.scaleZoom(s); this._unmodified = unmodified; this._constraining = false; return; } if (this.latRange) { var y = point.y, h2 = size.y / 2; if (y - h2 < minY) { y2 = minY + h2; } if (y + h2 > maxY) { y2 = maxY - h2; } } if (this.lngRange) { var x = point.x, w2 = size.x / 2; if (x - w2 < minX) { x2 = minX + w2; } if (x + w2 > maxX) { x2 = maxX - w2; } } if (x2 !== undefined || y2 !== undefined) { this.center = this.unproject(new performance.Point(x2 !== undefined ? x2 : point.x, y2 !== undefined ? y2 : point.y)); } this._unmodified = unmodified; this._constraining = false; }; Transform.prototype._calcMatrices = function _calcMatrices() { if (!this.height) { return; } var halfFov = this._fov / 2; var offset = this.centerOffset; this.cameraToCenterDistance = 0.5 / Math.tan(halfFov) * this.height; var groundAngle = Math.PI / 2 + this._pitch; var fovAboveCenter = this._fov * (0.5 + offset.y / this.height); var topHalfSurfaceDistance = Math.sin(fovAboveCenter) * this.cameraToCenterDistance / Math.sin(performance.clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); var point = this.point; var x = point.x, y = point.y; var furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToCenterDistance; var farZ = furthestDistance * 1.01; var nearZ = this.height / 50; var m = new Float64Array(16); performance.perspective(m, this._fov, this.width / this.height, nearZ, farZ); m[8] = -offset.x * 2 / this.width; m[9] = offset.y * 2 / this.height; performance.scale(m, m, [ 1, -1, 1 ]); performance.translate(m, m, [ 0, 0, -this.cameraToCenterDistance ]); performance.rotateX(m, m, this._pitch); performance.rotateZ(m, m, this.angle); performance.translate(m, m, [ -x, -y, 0 ]); this.mercatorMatrix = performance.scale([], m, [ this.worldSize, this.worldSize, this.worldSize ]); performance.scale(m, m, [ 1, 1, performance.mercatorZfromAltitude(1, this.center.lat) * this.worldSize, 1 ]); this.projMatrix = m; this.invProjMatrix = performance.invert([], this.projMatrix); var xShift = this.width % 2 / 2, yShift = this.height % 2 / 2, angleCos = Math.cos(this.angle), angleSin = Math.sin(this.angle), dx = x - Math.round(x) + angleCos * xShift + angleSin * yShift, dy = y - Math.round(y) + angleCos * yShift + angleSin * xShift; var alignedM = new Float64Array(m); performance.translate(alignedM, alignedM, [ dx > 0.5 ? dx - 1 : dx, dy > 0.5 ? dy - 1 : dy, 0 ]); this.alignedProjMatrix = alignedM; m = performance.create(); performance.scale(m, m, [ this.width / 2, -this.height / 2, 1 ]); performance.translate(m, m, [ 1, -1, 0 ]); this.labelPlaneMatrix = m; m = performance.create(); performance.scale(m, m, [ 1, -1, 1 ]); performance.translate(m, m, [ -1, -1, 0 ]); performance.scale(m, m, [ 2 / this.width, 2 / this.height, 1 ]); this.glCoordMatrix = m; this.pixelMatrix = performance.multiply(new Float64Array(16), this.labelPlaneMatrix, this.projMatrix); m = performance.invert(new Float64Array(16), this.pixelMatrix); if (!m) { throw new Error('failed to invert matrix'); } this.pixelMatrixInverse = m; this._posMatrixCache = {}; this._alignedPosMatrixCache = {}; }; Transform.prototype.maxPitchScaleFactor = function maxPitchScaleFactor() { if (!this.pixelMatrixInverse) { return 1; } var coord = this.pointCoordinate(new performance.Point(0, 0)); var p = [ coord.x * this.worldSize, coord.y * this.worldSize, 0, 1 ]; var topPoint = performance.transformMat4(p, p, this.pixelMatrix); return topPoint[3] / this.cameraToCenterDistance; }; Transform.prototype.getCameraPoint = function getCameraPoint() { var pitch = this._pitch; var yOffset = Math.tan(pitch) * (this.cameraToCenterDistance || 1); return this.centerPoint.add(new performance.Point(0, yOffset)); }; Transform.prototype.getCameraQueryGeometry = function getCameraQueryGeometry(queryGeometry) { var c = this.getCameraPoint(); if (queryGeometry.length === 1) { return [ queryGeometry[0], c ]; } else { var minX = c.x; var minY = c.y; var maxX = c.x; var maxY = c.y; for (var i = 0, list = queryGeometry; i < list.length; i += 1) { var p = list[i]; minX = Math.min(minX, p.x); minY = Math.min(minY, p.y); maxX = Math.max(maxX, p.x); maxY = Math.max(maxY, p.y); } return [ new performance.Point(minX, minY), new performance.Point(maxX, minY), new performance.Point(maxX, maxY), new performance.Point(minX, maxY), new performance.Point(minX, minY) ]; } }; Object.defineProperties(Transform.prototype, prototypeAccessors); function throttle(fn, time) { var pending = false; var timerId = null; var later = function () { timerId = null; if (pending) { fn(); timerId = setTimeout(later, time); pending = false; } }; return function () { pending = true; if (!timerId) { later(); } return timerId; }; } var Hash = function Hash(hashName) { this._hashName = hashName && encodeURIComponent(hashName); performance.bindAll([ '_getCurrentHash', '_onHashChange', '_updateHash' ], this); this._updateHash = throttle(this._updateHashUnthrottled.bind(this), 30 * 1000 / 100); }; Hash.prototype.addTo = function addTo(map) { this._map = map; performance.window.addEventListener('hashchange', this._onHashChange, false); this._map.on('moveend', this._updateHash); return this; }; Hash.prototype.remove = function remove() { performance.window.removeEventListener('hashchange', this._onHashChange, false); this._map.off('moveend', this._updateHash); clearTimeout(this._updateHash()); delete this._map; return this; }; Hash.prototype.getHashString = function getHashString(mapFeedback) { var center = this._map.getCenter(), zoom = Math.round(this._map.getZoom() * 100) / 100, precision = Math.ceil((zoom * Math.LN2 + Math.log(512 / 360 / 0.5)) / Math.LN10), m = Math.pow(10, precision), lng = Math.round(center.lng * m) / m, lat = Math.round(center.lat * m) / m, bearing = this._map.getBearing(), pitch = this._map.getPitch(); var hash = ''; if (mapFeedback) { hash += '/' + lng + '/' + lat + '/' + zoom; } else { hash += zoom + '/' + lat + '/' + lng; } if (bearing || pitch) { hash += '/' + Math.round(bearing * 10) / 10; } if (pitch) { hash += '/' + Math.round(pitch); } if (this._hashName) { var hashName = this._hashName; var found = false; var parts = performance.window.location.hash.slice(1).split('&').map(function (part) { var key = part.split('=')[0]; if (key === hashName) { found = true; return key + '=' + hash; } return part; }).filter(function (a) { return a; }); if (!found) { parts.push(hashName + '=' + hash); } return '#' + parts.join('&'); } return '#' + hash; }; Hash.prototype._getCurrentHash = function _getCurrentHash() { var this$1 = this; var hash = performance.window.location.hash.replace('#', ''); if (this._hashName) { var keyval; hash.split('&').map(function (part) { return part.split('='); }).forEach(function (part) { if (part[0] === this$1._hashName) { keyval = part; } }); return (keyval ? keyval[1] || '' : '').split('/'); } return hash.split('/'); }; Hash.prototype._onHashChange = function _onHashChange() { var loc = this._getCurrentHash(); if (loc.length >= 3 && !loc.some(function (v) { return isNaN(v); })) { var bearing = this._map.dragRotate.isEnabled() && this._map.touchZoomRotate.isEnabled() ? +(loc[3] || 0) : this._map.getBearing(); this._map.jumpTo({ center: [ +loc[2], +loc[1] ], zoom: +loc[0], bearing: bearing, pitch: +(loc[4] || 0) }); return true; } return false; }; Hash.prototype._updateHashUnthrottled = function _updateHashUnthrottled() { var location = performance.window.location.href.replace(/(#.+)?$/, this.getHashString()); try { performance.window.history.replaceState(performance.window.history.state, null, location); } catch (SecurityError) { } }; var defaultInertiaOptions = { linearity: 0.3, easing: performance.bezier(0, 0, 0.3, 1) }; var defaultPanInertiaOptions = performance.extend({ deceleration: 2500, maxSpeed: 1400 }, defaultInertiaOptions); var defaultZoomInertiaOptions = performance.extend({ deceleration: 20, maxSpeed: 1400 }, defaultInertiaOptions); var defaultBearingInertiaOptions = performance.extend({ deceleration: 1000, maxSpeed: 360 }, defaultInertiaOptions); var defaultPitchInertiaOptions = performance.extend({ deceleration: 1000, maxSpeed: 90 }, defaultInertiaOptions); var HandlerInertia = function HandlerInertia(map) { this._map = map; this.clear(); }; HandlerInertia.prototype.clear = function clear() { this._inertiaBuffer = []; }; HandlerInertia.prototype.record = function record(settings) { this._drainInertiaBuffer(); this._inertiaBuffer.push({ time: performance.browser.now(), settings: settings }); }; HandlerInertia.prototype._drainInertiaBuffer = function _drainInertiaBuffer() { var inertia = this._inertiaBuffer, now = performance.browser.now(), cutoff = 160; while (inertia.length > 0 && now - inertia[0].time > cutoff) { inertia.shift(); } }; HandlerInertia.prototype._onMoveEnd = function _onMoveEnd(panInertiaOptions) { this._drainInertiaBuffer(); if (this._inertiaBuffer.length < 2) { return; } var deltas = { zoom: 0, bearing: 0, pitch: 0, pan: new performance.Point(0, 0), pinchAround: undefined, around: undefined }; for (var i = 0, list = this._inertiaBuffer; i < list.length; i += 1) { var ref = list[i]; var settings = ref.settings; deltas.zoom += settings.zoomDelta || 0; deltas.bearing += settings.bearingDelta || 0; deltas.pitch += settings.pitchDelta || 0; if (settings.panDelta) { deltas.pan._add(settings.panDelta); } if (settings.around) { deltas.around = settings.around; } if (settings.pinchAround) { deltas.pinchAround = settings.pinchAround; } } var lastEntry = this._inertiaBuffer[this._inertiaBuffer.length - 1]; var duration = lastEntry.time - this._inertiaBuffer[0].time; var easeOptions = {}; if (deltas.pan.mag()) { var result = calculateEasing(deltas.pan.mag(), duration, performance.extend({}, defaultPanInertiaOptions, panInertiaOptions || {})); easeOptions.offset = deltas.pan.mult(result.amount / deltas.pan.mag()); easeOptions.center = this._map.transform.center; extendDuration(easeOptions, result); } if (deltas.zoom) { var result$1 = calculateEasing(deltas.zoom, duration, defaultZoomInertiaOptions); easeOptions.zoom = this._map.transform.zoom + result$1.amount; extendDuration(easeOptions, result$1); } if (deltas.bearing) { var result$2 = calculateEasing(deltas.bearing, duration, defaultBearingInertiaOptions); easeOptions.bearing = this._map.transform.bearing + performance.clamp(result$2.amount, -179, 179); extendDuration(easeOptions, result$2); } if (deltas.pitch) { var result$3 = calculateEasing(deltas.pitch, duration, defaultPitchInertiaOptions); easeOptions.pitch = this._map.transform.pitch + result$3.amount; extendDuration(easeOptions, result$3); } if (easeOptions.zoom || easeOptions.bearing) { var last = deltas.pinchAround === undefined ? deltas.around : deltas.pinchAround; easeOptions.around = last ? this._map.unproject(last) : this._map.getCenter(); } this.clear(); return performance.extend(easeOptions, { noMoveStart: true }); }; function extendDuration(easeOptions, result) { if (!easeOptions.duration || easeOptions.duration < result.duration) { easeOptions.duration = result.duration; easeOptions.easing = result.easing; } } function calculateEasing(amount, inertiaDuration, inertiaOptions) { var maxSpeed = inertiaOptions.maxSpeed; var linearity = inertiaOptions.linearity; var deceleration = inertiaOptions.deceleration; var speed = performance.clamp(amount * linearity / (inertiaDuration / 1000), -maxSpeed, maxSpeed); var duration = Math.abs(speed) / (deceleration * linearity); return { easing: inertiaOptions.easing, duration: duration * 1000, amount: speed * (duration / 2) }; } var MapMouseEvent = function (Event) { function MapMouseEvent(type, map, originalEvent, data) { if (data === void 0) data = {}; var point = DOM.mousePos(map.getCanvasContainer(), originalEvent); var lngLat = map.unproject(point); Event.call(this, type, performance.extend({ point: point, lngLat: lngLat, originalEvent: originalEvent }, data)); this._defaultPrevented = false; this.target = map; } if (Event) MapMouseEvent.__proto__ = Event; MapMouseEvent.prototype = Object.create(Event && Event.prototype); MapMouseEvent.prototype.constructor = MapMouseEvent; var prototypeAccessors = { defaultPrevented: { configurable: true } }; MapMouseEvent.prototype.preventDefault = function preventDefault() { this._defaultPrevented = true; }; prototypeAccessors.defaultPrevented.get = function () { return this._defaultPrevented; }; Object.defineProperties(MapMouseEvent.prototype, prototypeAccessors); return MapMouseEvent; }(performance.Event); var MapTouchEvent = function (Event) { function MapTouchEvent(type, map, originalEvent) { var touches = type === 'touchend' ? originalEvent.changedTouches : originalEvent.touches; var points = DOM.touchPos(map.getCanvasContainer(), touches); var lngLats = points.map(function (t) { return map.unproject(t); }); var point = points.reduce(function (prev, curr, i, arr) { return prev.add(curr.div(arr.length)); }, new performance.Point(0, 0)); var lngLat = map.unproject(point); Event.call(this, type, { points: points, point: point, lngLats: lngLats, lngLat: lngLat, originalEvent: originalEvent }); this._defaultPrevented = false; } if (Event) MapTouchEvent.__proto__ = Event; MapTouchEvent.prototype = Object.create(Event && Event.prototype); MapTouchEvent.prototype.constructor = MapTouchEvent; var prototypeAccessors$1 = { defaultPrevented: { configurable: true } }; MapTouchEvent.prototype.preventDefault = function preventDefault() { this._defaultPrevented = true; }; prototypeAccessors$1.defaultPrevented.get = function () { return this._defaultPrevented; }; Object.defineProperties(MapTouchEvent.prototype, prototypeAccessors$1); return MapTouchEvent; }(performance.Event); var MapWheelEvent = function (Event) { function MapWheelEvent(type, map, originalEvent) { Event.call(this, type, { originalEvent: originalEvent }); this._defaultPrevented = false; } if (Event) MapWheelEvent.__proto__ = Event; MapWheelEvent.prototype = Object.create(Event && Event.prototype); MapWheelEvent.prototype.constructor = MapWheelEvent; var prototypeAccessors$2 = { defaultPrevented: { configurable: true } }; MapWheelEvent.prototype.preventDefault = function preventDefault() { this._defaultPrevented = true; }; prototypeAccessors$2.defaultPrevented.get = function () { return this._defaultPrevented; }; Object.defineProperties(MapWheelEvent.prototype, prototypeAccessors$2); return MapWheelEvent; }(performance.Event); var MapEventHandler = function MapEventHandler(map, options) { this._map = map; this._clickTolerance = options.clickTolerance; }; MapEventHandler.prototype.reset = function reset() { delete this._mousedownPos; }; MapEventHandler.prototype.wheel = function wheel(e) { return this._firePreventable(new MapWheelEvent(e.type, this._map, e)); }; MapEventHandler.prototype.mousedown = function mousedown(e, point) { this._mousedownPos = point; return this._firePreventable(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.mouseup = function mouseup(e) { this._map.fire(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.click = function click(e, point) { if (this._mousedownPos && this._mousedownPos.dist(point) >= this._clickTolerance) { return; } this._map.fire(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.dblclick = function dblclick(e) { return this._firePreventable(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.mouseover = function mouseover(e) { this._map.fire(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.mouseout = function mouseout(e) { this._map.fire(new MapMouseEvent(e.type, this._map, e)); }; MapEventHandler.prototype.touchstart = function touchstart(e) { return this._firePreventable(new MapTouchEvent(e.type, this._map, e)); }; MapEventHandler.prototype.touchmove = function touchmove(e) { this._map.fire(new MapTouchEvent(e.type, this._map, e)); }; MapEventHandler.prototype.touchend = function touchend(e) { this._map.fire(new MapTouchEvent(e.type, this._map, e)); }; MapEventHandler.prototype.touchcancel = function touchcancel(e) { this._map.fire(new MapTouchEvent(e.type, this._map, e)); }; MapEventHandler.prototype._firePreventable = function _firePreventable(mapEvent) { this._map.fire(mapEvent); if (mapEvent.defaultPrevented) { return {}; } }; MapEventHandler.prototype.isEnabled = function isEnabled() { return true; }; MapEventHandler.prototype.isActive = function isActive() { return false; }; MapEventHandler.prototype.enable = function enable() { }; MapEventHandler.prototype.disable = function disable() { }; var BlockableMapEventHandler = function BlockableMapEventHandler(map) { this._map = map; }; BlockableMapEventHandler.prototype.reset = function reset() { this._delayContextMenu = false; delete this._contextMenuEvent; }; BlockableMapEventHandler.prototype.mousemove = function mousemove(e) { this._map.fire(new MapMouseEvent(e.type, this._map, e)); }; BlockableMapEventHandler.prototype.mousedown = function mousedown() { this._delayContextMenu = true; }; BlockableMapEventHandler.prototype.mouseup = function mouseup() { this._delayContextMenu = false; if (this._contextMenuEvent) { this._map.fire(new MapMouseEvent('contextmenu', this._map, this._contextMenuEvent)); delete this._contextMenuEvent; } }; BlockableMapEventHandler.prototype.contextmenu = function contextmenu(e) { if (this._delayContextMenu) { this._contextMenuEvent = e; } else { this._map.fire(new MapMouseEvent(e.type, this._map, e)); } if (this._map.listens('contextmenu')) { e.preventDefault(); } }; BlockableMapEventHandler.prototype.isEnabled = function isEnabled() { return true; }; BlockableMapEventHandler.prototype.isActive = function isActive() { return false; }; BlockableMapEventHandler.prototype.enable = function enable() { }; BlockableMapEventHandler.prototype.disable = function disable() { }; var BoxZoomHandler = function BoxZoomHandler(map, options) { this._map = map; this._el = map.getCanvasContainer(); this._container = map.getContainer(); this._clickTolerance = options.clickTolerance || 1; }; BoxZoomHandler.prototype.isEnabled = function isEnabled() { return !!this._enabled; }; BoxZoomHandler.prototype.isActive = function isActive() { return !!this._active; }; BoxZoomHandler.prototype.enable = function enable() { if (this.isEnabled()) { return; } this._enabled = true; }; BoxZoomHandler.prototype.disable = function disable() { if (!this.isEnabled()) { return; } this._enabled = false; }; BoxZoomHandler.prototype.mousedown = function mousedown(e, point) { if (!this.isEnabled()) { return; } if (!(e.shiftKey && e.button === 0)) { return; } DOM.disableDrag(); this._startPos = this._lastPos = point; this._active = true; }; BoxZoomHandler.prototype.mousemoveWindow = function mousemoveWindow(e, point) { if (!this._active) { return; } var pos = point; if (this._lastPos.equals(pos) || !this._box && pos.dist(this._startPos) < this._clickTolerance) { return; } var p0 = this._startPos; this._lastPos = pos; if (!this._box) { this._box = DOM.create('div', 'mapboxgl-boxzoom', this._container); this._container.classList.add('mapboxgl-crosshair'); this._fireEvent('boxzoomstart', e); } var minX = Math.min(p0.x, pos.x), maxX = Math.max(p0.x, pos.x), minY = Math.min(p0.y, pos.y), maxY = Math.max(p0.y, pos.y); DOM.setTransform(this._box, 'translate(' + minX + 'px,' + minY + 'px)'); this._box.style.width = maxX - minX + 'px'; this._box.style.height = maxY - minY + 'px'; }; BoxZoomHandler.prototype.mouseupWindow = function mouseupWindow(e, point) { var this$1 = this; if (!this._active) { return; } if (e.button !== 0) { return; } var p0 = this._startPos, p1 = point; this.reset(); DOM.suppressClick(); if (p0.x === p1.x && p0.y === p1.y) { this._fireEvent('boxzoomcancel', e); } else { this._map.fire(new performance.Event('boxzoomend', { originalEvent: e })); return { cameraAnimation: function (map) { return map.fitScreenCoordinates(p0, p1, this$1._map.getBearing(), { linear: true }); } }; } }; BoxZoomHandler.prototype.keydown = function keydown(e) { if (!this._active) { return; } if (e.keyCode === 27) { this.reset(); this._fireEvent('boxzoomcancel', e); } }; BoxZoomHandler.prototype.blur = function blur() { this.reset(); }; BoxZoomHandler.prototype.reset = function reset() { this._active = false; this._container.classList.remove('mapboxgl-crosshair'); if (this._box) { DOM.remove(this._box); this._box = null; } DOM.enableDrag(); delete this._startPos; delete this._lastPos; }; BoxZoomHandler.prototype._fireEvent = function _fireEvent(type, e) { return this._map.fire(new performance.Event(type, { originalEvent: e })); }; function indexTouches(touches, points) { var obj = {}; for (var i = 0; i < touches.length; i++) { obj[touches[i].identifier] = points[i]; } return obj; } function getCentroid(points) { var sum = new performance.Point(0, 0); for (var i = 0, list = points; i < list.length; i += 1) { var point = list[i]; sum._add(point); } return sum.div(points.length); } var MAX_TAP_INTERVAL = 500; var MAX_TOUCH_TIME = 500; var MAX_DIST = 30; var SingleTapRecognizer = function SingleTapRecognizer(options) { this.reset(); this.numTouches = options.numTouches; }; SingleTapRecognizer.prototype.reset = function reset() { delete this.centroid; delete this.startTime; delete this.touches; this.aborted = false; }; SingleTapRecognizer.prototype.touchstart = function touchstart(e, points, mapTouches) { if (this.centroid || mapTouches.length > this.numTouches) { this.aborted = true; } if (this.aborted) { return; } if (this.startTime === undefined) { this.startTime = e.timeStamp; } if (mapTouches.length === this.numTouches) { this.centroid = getCentroid(points); this.touches = indexTouches(mapTouches, points); } }; SingleTapRecognizer.prototype.touchmove = function touchmove(e, points, mapTouches) { if (this.aborted || !this.centroid) { return; } var newTouches = indexTouches(mapTouches, points); for (var id in this.touches) { var prevPos = this.touches[id]; var pos = newTouches[id]; if (!pos || pos.dist(prevPos) > MAX_DIST) { this.aborted = true; } } }; SingleTapRecognizer.prototype.touchend = function touchend(e, points, mapTouches) { if (!this.centroid || e.timeStamp - this.startTime > MAX_TOUCH_TIME) { this.aborted = true; } if (mapTouches.length === 0) { var centroid = !this.aborted && this.centroid; this.reset(); if (centroid) { return centroid; } } }; var TapRecognizer = function TapRecognizer(options) { this.singleTap = new SingleTapRecognizer(options); this.numTaps = options.numTaps; this.reset(); }; TapRecognizer.prototype.reset = function reset() { this.lastTime = Infinity; delete this.lastTap; this.count = 0; this.singleTap.reset(); }; TapRecognizer.prototype.touchstart = function touchstart(e, points, mapTouches) { this.singleTap.touchstart(e, points, mapTouches); }; TapRecognizer.prototype.touchmove = function touchmove(e, points, mapTouches) { this.singleTap.touchmove(e, points, mapTouches); }; TapRecognizer.prototype.touchend = function touchend(e, points, mapTouches) { var tap = this.singleTap.touchend(e, points, mapTouches); if (tap) { var soonEnough = e.timeStamp - this.lastTime < MAX_TAP_INTERVAL; var closeEnough = !this.lastTap || this.lastTap.dist(tap) < MAX_DIST; if (!soonEnough || !closeEnough) { this.reset(); } this.count++; this.lastTime = e.timeStamp; this.lastTap = tap; if (this.count === this.numTaps) { this.reset(); return tap; } } }; var TapZoomHandler = function TapZoomHandler() { this._zoomIn = new TapRecognizer({ numTouches: 1, numTaps: 2 }); this._zoomOut = new TapRecognizer({ numTouches: 2, numTaps: 1 }); this.reset(); }; TapZoomHandler.prototype.reset = function reset() { this._active = false; this._zoomIn.reset(); this._zoomOut.reset(); }; TapZoomHandler.prototype.touchstart = function touchstart(e, points, mapTouches) { this._zoomIn.touchstart(e, points, mapTouches); this._zoomOut.touchstart(e, points, mapTouches); }; TapZoomHandler.prototype.touchmove = function touchmove(e, points, mapTouches) { this._zoomIn.touchmove(e, points, mapTouches); this._zoomOut.touchmove(e, points, mapTouches); }; TapZoomHandler.prototype.touchend = function touchend(e, points, mapTouches) { var this$1 = this; var zoomInPoint = this._zoomIn.touchend(e, points, mapTouches); var zoomOutPoint = this._zoomOut.touchend(e, points, mapTouches); if (zoomInPoint) { this._active = true; e.preventDefault(); setTimeout(function () { return this$1.reset(); }, 0); return { cameraAnimation: function (map) { return map.easeTo({ duration: 300, zoom: map.getZoom() + 1, around: map.unproject(zoomInPoint) }, { originalEvent: e }); } }; } else if (zoomOutPoint) { this._active = true; e.preventDefault(); setTimeout(function () { return this$1.reset(); }, 0); return { cameraAnimation: function (map) { return map.easeTo({ duration: 300, zoom: map.getZoom() - 1, around: map.unproject(zoomOutPoint) }, { originalEvent: e }); } }; } }; TapZoomHandler.prototype.touchcancel = function touchcancel() { this.reset(); }; TapZoomHandler.prototype.enable = function enable() { this._enabled = true; }; TapZoomHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; TapZoomHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; TapZoomHandler.prototype.isActive = function isActive() { return this._active; }; var LEFT_BUTTON = 0; var RIGHT_BUTTON = 2; var BUTTONS_FLAGS = {}; BUTTONS_FLAGS[LEFT_BUTTON] = 1; BUTTONS_FLAGS[RIGHT_BUTTON] = 2; function buttonStillPressed(e, button) { var flag = BUTTONS_FLAGS[button]; return e.buttons === undefined || (e.buttons & flag) !== flag; } var MouseHandler = function MouseHandler(options) { this.reset(); this._clickTolerance = options.clickTolerance || 1; }; MouseHandler.prototype.blur = function blur() { this.reset(); }; MouseHandler.prototype.reset = function reset() { this._active = false; this._moved = false; delete this._lastPoint; delete this._eventButton; }; MouseHandler.prototype._correctButton = function _correctButton(e, button) { return false; }; MouseHandler.prototype._move = function _move(lastPoint, point) { return {}; }; MouseHandler.prototype.mousedown = function mousedown(e, point) { if (this._lastPoint) { return; } var eventButton = DOM.mouseButton(e); if (!this._correctButton(e, eventButton)) { return; } this._lastPoint = point; this._eventButton = eventButton; }; MouseHandler.prototype.mousemoveWindow = function mousemoveWindow(e, point) { var lastPoint = this._lastPoint; if (!lastPoint) { return; } e.preventDefault(); if (buttonStillPressed(e, this._eventButton)) { this.reset(); return; } if (!this._moved && point.dist(lastPoint) < this._clickTolerance) { return; } this._moved = true; this._lastPoint = point; return this._move(lastPoint, point); }; MouseHandler.prototype.mouseupWindow = function mouseupWindow(e) { if (!this._lastPoint) { return; } var eventButton = DOM.mouseButton(e); if (eventButton !== this._eventButton) { return; } if (this._moved) { DOM.suppressClick(); } this.reset(); }; MouseHandler.prototype.enable = function enable() { this._enabled = true; }; MouseHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; MouseHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; MouseHandler.prototype.isActive = function isActive() { return this._active; }; var MousePanHandler = function (MouseHandler) { function MousePanHandler() { MouseHandler.apply(this, arguments); } if (MouseHandler) MousePanHandler.__proto__ = MouseHandler; MousePanHandler.prototype = Object.create(MouseHandler && MouseHandler.prototype); MousePanHandler.prototype.constructor = MousePanHandler; MousePanHandler.prototype.mousedown = function mousedown(e, point) { MouseHandler.prototype.mousedown.call(this, e, point); if (this._lastPoint) { this._active = true; } }; MousePanHandler.prototype._correctButton = function _correctButton(e, button) { return button === LEFT_BUTTON && !e.ctrlKey; }; MousePanHandler.prototype._move = function _move(lastPoint, point) { return { around: point, panDelta: point.sub(lastPoint) }; }; return MousePanHandler; }(MouseHandler); var MouseRotateHandler = function (MouseHandler) { function MouseRotateHandler() { MouseHandler.apply(this, arguments); } if (MouseHandler) MouseRotateHandler.__proto__ = MouseHandler; MouseRotateHandler.prototype = Object.create(MouseHandler && MouseHandler.prototype); MouseRotateHandler.prototype.constructor = MouseRotateHandler; MouseRotateHandler.prototype._correctButton = function _correctButton(e, button) { return button === LEFT_BUTTON && e.ctrlKey || button === RIGHT_BUTTON; }; MouseRotateHandler.prototype._move = function _move(lastPoint, point) { var degreesPerPixelMoved = 0.8; var bearingDelta = (point.x - lastPoint.x) * degreesPerPixelMoved; if (bearingDelta) { this._active = true; return { bearingDelta: bearingDelta }; } }; MouseRotateHandler.prototype.contextmenu = function contextmenu(e) { e.preventDefault(); }; return MouseRotateHandler; }(MouseHandler); var MousePitchHandler = function (MouseHandler) { function MousePitchHandler() { MouseHandler.apply(this, arguments); } if (MouseHandler) MousePitchHandler.__proto__ = MouseHandler; MousePitchHandler.prototype = Object.create(MouseHandler && MouseHandler.prototype); MousePitchHandler.prototype.constructor = MousePitchHandler; MousePitchHandler.prototype._correctButton = function _correctButton(e, button) { return button === LEFT_BUTTON && e.ctrlKey || button === RIGHT_BUTTON; }; MousePitchHandler.prototype._move = function _move(lastPoint, point) { var degreesPerPixelMoved = -0.5; var pitchDelta = (point.y - lastPoint.y) * degreesPerPixelMoved; if (pitchDelta) { this._active = true; return { pitchDelta: pitchDelta }; } }; MousePitchHandler.prototype.contextmenu = function contextmenu(e) { e.preventDefault(); }; return MousePitchHandler; }(MouseHandler); var TouchPanHandler = function TouchPanHandler(options) { this._minTouches = 1; this._clickTolerance = options.clickTolerance || 1; this.reset(); }; TouchPanHandler.prototype.reset = function reset() { this._active = false; this._touches = {}; this._sum = new performance.Point(0, 0); }; TouchPanHandler.prototype.touchstart = function touchstart(e, points, mapTouches) { return this._calculateTransform(e, points, mapTouches); }; TouchPanHandler.prototype.touchmove = function touchmove(e, points, mapTouches) { if (!this._active || mapTouches.length < this._minTouches) { return; } e.preventDefault(); return this._calculateTransform(e, points, mapTouches); }; TouchPanHandler.prototype.touchend = function touchend(e, points, mapTouches) { this._calculateTransform(e, points, mapTouches); if (this._active && mapTouches.length < this._minTouches) { this.reset(); } }; TouchPanHandler.prototype.touchcancel = function touchcancel() { this.reset(); }; TouchPanHandler.prototype._calculateTransform = function _calculateTransform(e, points, mapTouches) { if (mapTouches.length > 0) { this._active = true; } var touches = indexTouches(mapTouches, points); var touchPointSum = new performance.Point(0, 0); var touchDeltaSum = new performance.Point(0, 0); var touchDeltaCount = 0; for (var identifier in touches) { var point = touches[identifier]; var prevPoint = this._touches[identifier]; if (prevPoint) { touchPointSum._add(point); touchDeltaSum._add(point.sub(prevPoint)); touchDeltaCount++; touches[identifier] = point; } } this._touches = touches; if (touchDeltaCount < this._minTouches || !touchDeltaSum.mag()) { return; } var panDelta = touchDeltaSum.div(touchDeltaCount); this._sum._add(panDelta); if (this._sum.mag() < this._clickTolerance) { return; } var around = touchPointSum.div(touchDeltaCount); return { around: around, panDelta: panDelta }; }; TouchPanHandler.prototype.enable = function enable() { this._enabled = true; }; TouchPanHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; TouchPanHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; TouchPanHandler.prototype.isActive = function isActive() { return this._active; }; var TwoTouchHandler = function TwoTouchHandler() { this.reset(); }; TwoTouchHandler.prototype.reset = function reset() { this._active = false; delete this._firstTwoTouches; }; TwoTouchHandler.prototype._start = function _start(points) { }; TwoTouchHandler.prototype._move = function _move(points, pinchAround, e) { return {}; }; TwoTouchHandler.prototype.touchstart = function touchstart(e, points, mapTouches) { if (this._firstTwoTouches || mapTouches.length < 2) { return; } this._firstTwoTouches = [ mapTouches[0].identifier, mapTouches[1].identifier ]; this._start([ points[0], points[1] ]); }; TwoTouchHandler.prototype.touchmove = function touchmove(e, points, mapTouches) { if (!this._firstTwoTouches) { return; } e.preventDefault(); var ref = this._firstTwoTouches; var idA = ref[0]; var idB = ref[1]; var a = getTouchById(mapTouches, points, idA); var b = getTouchById(mapTouches, points, idB); if (!a || !b) { return; } var pinchAround = this._aroundCenter ? null : a.add(b).div(2); return this._move([ a, b ], pinchAround, e); }; TwoTouchHandler.prototype.touchend = function touchend(e, points, mapTouches) { if (!this._firstTwoTouches) { return; } var ref = this._firstTwoTouches; var idA = ref[0]; var idB = ref[1]; var a = getTouchById(mapTouches, points, idA); var b = getTouchById(mapTouches, points, idB); if (a && b) { return; } if (this._active) { DOM.suppressClick(); } this.reset(); }; TwoTouchHandler.prototype.touchcancel = function touchcancel() { this.reset(); }; TwoTouchHandler.prototype.enable = function enable(options) { this._enabled = true; this._aroundCenter = !!options && options.around === 'center'; }; TwoTouchHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; TwoTouchHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; TwoTouchHandler.prototype.isActive = function isActive() { return this._active; }; function getTouchById(mapTouches, points, identifier) { for (var i = 0; i < mapTouches.length; i++) { if (mapTouches[i].identifier === identifier) { return points[i]; } } } var ZOOM_THRESHOLD = 0.1; function getZoomDelta(distance, lastDistance) { return Math.log(distance / lastDistance) / Math.LN2; } var TouchZoomHandler = function (TwoTouchHandler) { function TouchZoomHandler() { TwoTouchHandler.apply(this, arguments); } if (TwoTouchHandler) TouchZoomHandler.__proto__ = TwoTouchHandler; TouchZoomHandler.prototype = Object.create(TwoTouchHandler && TwoTouchHandler.prototype); TouchZoomHandler.prototype.constructor = TouchZoomHandler; TouchZoomHandler.prototype.reset = function reset() { TwoTouchHandler.prototype.reset.call(this); delete this._distance; delete this._startDistance; }; TouchZoomHandler.prototype._start = function _start(points) { this._startDistance = this._distance = points[0].dist(points[1]); }; TouchZoomHandler.prototype._move = function _move(points, pinchAround) { var lastDistance = this._distance; this._distance = points[0].dist(points[1]); if (!this._active && Math.abs(getZoomDelta(this._distance, this._startDistance)) < ZOOM_THRESHOLD) { return; } this._active = true; return { zoomDelta: getZoomDelta(this._distance, lastDistance), pinchAround: pinchAround }; }; return TouchZoomHandler; }(TwoTouchHandler); var ROTATION_THRESHOLD = 25; function getBearingDelta(a, b) { return a.angleWith(b) * 180 / Math.PI; } var TouchRotateHandler = function (TwoTouchHandler) { function TouchRotateHandler() { TwoTouchHandler.apply(this, arguments); } if (TwoTouchHandler) TouchRotateHandler.__proto__ = TwoTouchHandler; TouchRotateHandler.prototype = Object.create(TwoTouchHandler && TwoTouchHandler.prototype); TouchRotateHandler.prototype.constructor = TouchRotateHandler; TouchRotateHandler.prototype.reset = function reset() { TwoTouchHandler.prototype.reset.call(this); delete this._minDiameter; delete this._startVector; delete this._vector; }; TouchRotateHandler.prototype._start = function _start(points) { this._startVector = this._vector = points[0].sub(points[1]); this._minDiameter = points[0].dist(points[1]); }; TouchRotateHandler.prototype._move = function _move(points, pinchAround) { var lastVector = this._vector; this._vector = points[0].sub(points[1]); if (!this._active && this._isBelowThreshold(this._vector)) { return; } this._active = true; return { bearingDelta: getBearingDelta(this._vector, lastVector), pinchAround: pinchAround }; }; TouchRotateHandler.prototype._isBelowThreshold = function _isBelowThreshold(vector) { this._minDiameter = Math.min(this._minDiameter, vector.mag()); var circumference = Math.PI * this._minDiameter; var threshold = ROTATION_THRESHOLD / circumference * 360; var bearingDeltaSinceStart = getBearingDelta(vector, this._startVector); return Math.abs(bearingDeltaSinceStart) < threshold; }; return TouchRotateHandler; }(TwoTouchHandler); function isVertical(vector) { return Math.abs(vector.y) > Math.abs(vector.x); } var ALLOWED_SINGLE_TOUCH_TIME = 100; var TouchPitchHandler = function (TwoTouchHandler) { function TouchPitchHandler() { TwoTouchHandler.apply(this, arguments); } if (TwoTouchHandler) TouchPitchHandler.__proto__ = TwoTouchHandler; TouchPitchHandler.prototype = Object.create(TwoTouchHandler && TwoTouchHandler.prototype); TouchPitchHandler.prototype.constructor = TouchPitchHandler; TouchPitchHandler.prototype.reset = function reset() { TwoTouchHandler.prototype.reset.call(this); this._valid = undefined; delete this._firstMove; delete this._lastPoints; }; TouchPitchHandler.prototype._start = function _start(points) { this._lastPoints = points; if (isVertical(points[0].sub(points[1]))) { this._valid = false; } }; TouchPitchHandler.prototype._move = function _move(points, center, e) { var vectorA = points[0].sub(this._lastPoints[0]); var vectorB = points[1].sub(this._lastPoints[1]); this._valid = this.gestureBeginsVertically(vectorA, vectorB, e.timeStamp); if (!this._valid) { return; } this._lastPoints = points; this._active = true; var yDeltaAverage = (vectorA.y + vectorB.y) / 2; var degreesPerPixelMoved = -0.5; return { pitchDelta: yDeltaAverage * degreesPerPixelMoved }; }; TouchPitchHandler.prototype.gestureBeginsVertically = function gestureBeginsVertically(vectorA, vectorB, timeStamp) { if (this._valid !== undefined) { return this._valid; } var threshold = 2; var movedA = vectorA.mag() >= threshold; var movedB = vectorB.mag() >= threshold; if (!movedA && !movedB) { return; } if (!movedA || !movedB) { if (this._firstMove === undefined) { this._firstMove = timeStamp; } if (timeStamp - this._firstMove < ALLOWED_SINGLE_TOUCH_TIME) { return undefined; } else { return false; } } var isSameDirection = vectorA.y > 0 === vectorB.y > 0; return isVertical(vectorA) && isVertical(vectorB) && isSameDirection; }; return TouchPitchHandler; }(TwoTouchHandler); var defaultOptions = { panStep: 100, bearingStep: 15, pitchStep: 10 }; var KeyboardHandler = function KeyboardHandler() { var stepOptions = defaultOptions; this._panStep = stepOptions.panStep; this._bearingStep = stepOptions.bearingStep; this._pitchStep = stepOptions.pitchStep; this._rotationDisabled = false; }; KeyboardHandler.prototype.blur = function blur() { this.reset(); }; KeyboardHandler.prototype.reset = function reset() { this._active = false; }; KeyboardHandler.prototype.keydown = function keydown(e) { var this$1 = this; if (e.altKey || e.ctrlKey || e.metaKey) { return; } var zoomDir = 0; var bearingDir = 0; var pitchDir = 0; var xDir = 0; var yDir = 0; switch (e.keyCode) { case 61: case 107: case 171: case 187: zoomDir = 1; break; case 189: case 109: case 173: zoomDir = -1; break; case 37: if (e.shiftKey) { bearingDir = -1; } else { e.preventDefault(); xDir = -1; } break; case 39: if (e.shiftKey) { bearingDir = 1; } else { e.preventDefault(); xDir = 1; } break; case 38: if (e.shiftKey) { pitchDir = 1; } else { e.preventDefault(); yDir = -1; } break; case 40: if (e.shiftKey) { pitchDir = -1; } else { e.preventDefault(); yDir = 1; } break; default: return; } if (this._rotationDisabled) { bearingDir = 0; pitchDir = 0; } return { cameraAnimation: function (map) { var zoom = map.getZoom(); map.easeTo({ duration: 300, easeId: 'keyboardHandler', easing: easeOut, zoom: zoomDir ? Math.round(zoom) + zoomDir * (e.shiftKey ? 2 : 1) : zoom, bearing: map.getBearing() + bearingDir * this$1._bearingStep, pitch: map.getPitch() + pitchDir * this$1._pitchStep, offset: [ -xDir * this$1._panStep, -yDir * this$1._panStep ], center: map.getCenter() }, { originalEvent: e }); } }; }; KeyboardHandler.prototype.enable = function enable() { this._enabled = true; }; KeyboardHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; KeyboardHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; KeyboardHandler.prototype.isActive = function isActive() { return this._active; }; KeyboardHandler.prototype.disableRotation = function disableRotation() { this._rotationDisabled = true; }; KeyboardHandler.prototype.enableRotation = function enableRotation() { this._rotationDisabled = false; }; function easeOut(t) { return t * (2 - t); } var wheelZoomDelta = 4.000244140625; var defaultZoomRate = 1 / 100; var wheelZoomRate = 1 / 450; var maxScalePerFrame = 2; var ScrollZoomHandler = function ScrollZoomHandler(map, handler) { this._map = map; this._el = map.getCanvasContainer(); this._handler = handler; this._delta = 0; this._defaultZoomRate = defaultZoomRate; this._wheelZoomRate = wheelZoomRate; performance.bindAll(['_onTimeout'], this); }; ScrollZoomHandler.prototype.setZoomRate = function setZoomRate(zoomRate) { this._defaultZoomRate = zoomRate; }; ScrollZoomHandler.prototype.setWheelZoomRate = function setWheelZoomRate(wheelZoomRate) { this._wheelZoomRate = wheelZoomRate; }; ScrollZoomHandler.prototype.isEnabled = function isEnabled() { return !!this._enabled; }; ScrollZoomHandler.prototype.isActive = function isActive() { return !!this._active || this._finishTimeout !== undefined; }; ScrollZoomHandler.prototype.isZooming = function isZooming() { return !!this._zooming; }; ScrollZoomHandler.prototype.enable = function enable(options) { if (this.isEnabled()) { return; } this._enabled = true; this._aroundCenter = options && options.around === 'center'; }; ScrollZoomHandler.prototype.disable = function disable() { if (!this.isEnabled()) { return; } this._enabled = false; }; ScrollZoomHandler.prototype.wheel = function wheel(e) { if (!this.isEnabled()) { return; } var value = e.deltaMode === performance.window.WheelEvent.DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY; var now = performance.browser.now(), timeDelta = now - (this._lastWheelEventTime || 0); this._lastWheelEventTime = now; if (value !== 0 && value % wheelZoomDelta === 0) { this._type = 'wheel'; } else if (value !== 0 && Math.abs(value) < 4) { this._type = 'trackpad'; } else if (timeDelta > 400) { this._type = null; this._lastValue = value; this._timeout = setTimeout(this._onTimeout, 40, e); } else if (!this._type) { this._type = Math.abs(timeDelta * value) < 200 ? 'trackpad' : 'wheel'; if (this._timeout) { clearTimeout(this._timeout); this._timeout = null; value += this._lastValue; } } if (e.shiftKey && value) { value = value / 4; } if (this._type) { this._lastWheelEvent = e; this._delta -= value; if (!this._active) { this._start(e); } } e.preventDefault(); }; ScrollZoomHandler.prototype._onTimeout = function _onTimeout(initialEvent) { this._type = 'wheel'; this._delta -= this._lastValue; if (!this._active) { this._start(initialEvent); } }; ScrollZoomHandler.prototype._start = function _start(e) { if (!this._delta) { return; } if (this._frameId) { this._frameId = null; } this._active = true; if (!this.isZooming()) { this._zooming = true; } if (this._finishTimeout) { clearTimeout(this._finishTimeout); delete this._finishTimeout; } var pos = DOM.mousePos(this._el, e); this._around = performance.LngLat.convert(this._aroundCenter ? this._map.getCenter() : this._map.unproject(pos)); this._aroundPoint = this._map.transform.locationPoint(this._around); if (!this._frameId) { this._frameId = true; this._handler._triggerRenderFrame(); } }; ScrollZoomHandler.prototype.renderFrame = function renderFrame() { var this$1 = this; if (!this._frameId) { return; } this._frameId = null; if (!this.isActive()) { return; } var tr = this._map.transform; if (this._delta !== 0) { var zoomRate = this._type === 'wheel' && Math.abs(this._delta) > wheelZoomDelta ? this._wheelZoomRate : this._defaultZoomRate; var scale = maxScalePerFrame / (1 + Math.exp(-Math.abs(this._delta * zoomRate))); if (this._delta < 0 && scale !== 0) { scale = 1 / scale; } var fromScale = typeof this._targetZoom === 'number' ? tr.zoomScale(this._targetZoom) : tr.scale; this._targetZoom = Math.min(tr.maxZoom, Math.max(tr.minZoom, tr.scaleZoom(fromScale * scale))); if (this._type === 'wheel') { this._startZoom = tr.zoom; this._easing = this._smoothOutEasing(200); } this._delta = 0; } var targetZoom = typeof this._targetZoom === 'number' ? this._targetZoom : tr.zoom; var startZoom = this._startZoom; var easing = this._easing; var finished = false; var zoom; if (this._type === 'wheel' && startZoom && easing) { var t = Math.min((performance.browser.now() - this._lastWheelEventTime) / 200, 1); var k = easing(t); zoom = performance.number(startZoom, targetZoom, k); if (t < 1) { if (!this._frameId) { this._frameId = true; } } else { finished = true; } } else { zoom = targetZoom; finished = true; } this._active = true; if (finished) { this._active = false; this._finishTimeout = setTimeout(function () { this$1._zooming = false; this$1._handler._triggerRenderFrame(); delete this$1._targetZoom; delete this$1._finishTimeout; }, 200); } return { noInertia: true, needsRenderFrame: !finished, zoomDelta: zoom - tr.zoom, around: this._aroundPoint, originalEvent: this._lastWheelEvent }; }; ScrollZoomHandler.prototype._smoothOutEasing = function _smoothOutEasing(duration) { var easing = performance.ease; if (this._prevEase) { var ease = this._prevEase, t = (performance.browser.now() - ease.start) / ease.duration, speed = ease.easing(t + 0.01) - ease.easing(t), x = 0.27 / Math.sqrt(speed * speed + 0.0001) * 0.01, y = Math.sqrt(0.27 * 0.27 - x * x); easing = performance.bezier(x, y, 0.25, 1); } this._prevEase = { start: performance.browser.now(), duration: duration, easing: easing }; return easing; }; ScrollZoomHandler.prototype.blur = function blur() { this.reset(); }; ScrollZoomHandler.prototype.reset = function reset() { this._active = false; }; var DoubleClickZoomHandler = function DoubleClickZoomHandler(clickZoom, TapZoom) { this._clickZoom = clickZoom; this._tapZoom = TapZoom; }; DoubleClickZoomHandler.prototype.enable = function enable() { this._clickZoom.enable(); this._tapZoom.enable(); }; DoubleClickZoomHandler.prototype.disable = function disable() { this._clickZoom.disable(); this._tapZoom.disable(); }; DoubleClickZoomHandler.prototype.isEnabled = function isEnabled() { return this._clickZoom.isEnabled() && this._tapZoom.isEnabled(); }; DoubleClickZoomHandler.prototype.isActive = function isActive() { return this._clickZoom.isActive() || this._tapZoom.isActive(); }; var ClickZoomHandler = function ClickZoomHandler() { this.reset(); }; ClickZoomHandler.prototype.reset = function reset() { this._active = false; }; ClickZoomHandler.prototype.blur = function blur() { this.reset(); }; ClickZoomHandler.prototype.dblclick = function dblclick(e, point) { e.preventDefault(); return { cameraAnimation: function (map) { map.easeTo({ duration: 300, zoom: map.getZoom() + (e.shiftKey ? -1 : 1), around: map.unproject(point) }, { originalEvent: e }); } }; }; ClickZoomHandler.prototype.enable = function enable() { this._enabled = true; }; ClickZoomHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; ClickZoomHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; ClickZoomHandler.prototype.isActive = function isActive() { return this._active; }; var TapDragZoomHandler = function TapDragZoomHandler() { this._tap = new TapRecognizer({ numTouches: 1, numTaps: 1 }); this.reset(); }; TapDragZoomHandler.prototype.reset = function reset() { this._active = false; delete this._swipePoint; delete this._swipeTouch; delete this._tapTime; this._tap.reset(); }; TapDragZoomHandler.prototype.touchstart = function touchstart(e, points, mapTouches) { if (this._swipePoint) { return; } if (this._tapTime && e.timeStamp - this._tapTime > MAX_TAP_INTERVAL) { this.reset(); } if (!this._tapTime) { this._tap.touchstart(e, points, mapTouches); } else if (mapTouches.length > 0) { this._swipePoint = points[0]; this._swipeTouch = mapTouches[0].identifier; } }; TapDragZoomHandler.prototype.touchmove = function touchmove(e, points, mapTouches) { if (!this._tapTime) { this._tap.touchmove(e, points, mapTouches); } else if (this._swipePoint) { if (mapTouches[0].identifier !== this._swipeTouch) { return; } var newSwipePoint = points[0]; var dist = newSwipePoint.y - this._swipePoint.y; this._swipePoint = newSwipePoint; e.preventDefault(); this._active = true; return { zoomDelta: dist / 128 }; } }; TapDragZoomHandler.prototype.touchend = function touchend(e, points, mapTouches) { if (!this._tapTime) { var point = this._tap.touchend(e, points, mapTouches); if (point) { this._tapTime = e.timeStamp; } } else if (this._swipePoint) { if (mapTouches.length === 0) { this.reset(); } } }; TapDragZoomHandler.prototype.touchcancel = function touchcancel() { this.reset(); }; TapDragZoomHandler.prototype.enable = function enable() { this._enabled = true; }; TapDragZoomHandler.prototype.disable = function disable() { this._enabled = false; this.reset(); }; TapDragZoomHandler.prototype.isEnabled = function isEnabled() { return this._enabled; }; TapDragZoomHandler.prototype.isActive = function isActive() { return this._active; }; var DragPanHandler = function DragPanHandler(el, mousePan, touchPan) { this._el = el; this._mousePan = mousePan; this._touchPan = touchPan; }; DragPanHandler.prototype.enable = function enable(options) { this._inertiaOptions = options || {}; this._mousePan.enable(); this._touchPan.enable(); this._el.classList.add('mapboxgl-touch-drag-pan'); }; DragPanHandler.prototype.disable = function disable() { this._mousePan.disable(); this._touchPan.disable(); this._el.classList.remove('mapboxgl-touch-drag-pan'); }; DragPanHandler.prototype.isEnabled = function isEnabled() { return this._mousePan.isEnabled() && this._touchPan.isEnabled(); }; DragPanHandler.prototype.isActive = function isActive() { return this._mousePan.isActive() || this._touchPan.isActive(); }; var DragRotateHandler = function DragRotateHandler(options, mouseRotate, mousePitch) { this._pitchWithRotate = options.pitchWithRotate; this._mouseRotate = mouseRotate; this._mousePitch = mousePitch; }; DragRotateHandler.prototype.enable = function enable() { this._mouseRotate.enable(); if (this._pitchWithRotate) { this._mousePitch.enable(); } }; DragRotateHandler.prototype.disable = function disable() { this._mouseRotate.disable(); this._mousePitch.disable(); }; DragRotateHandler.prototype.isEnabled = function isEnabled() { return this._mouseRotate.isEnabled() && (!this._pitchWithRotate || this._mousePitch.isEnabled()); }; DragRotateHandler.prototype.isActive = function isActive() { return this._mouseRotate.isActive() || this._mousePitch.isActive(); }; var TouchZoomRotateHandler = function TouchZoomRotateHandler(el, touchZoom, touchRotate, tapDragZoom) { this._el = el; this._touchZoom = touchZoom; this._touchRotate = touchRotate; this._tapDragZoom = tapDragZoom; this._rotationDisabled = false; this._enabled = true; }; TouchZoomRotateHandler.prototype.enable = function enable(options) { this._touchZoom.enable(options); if (!this._rotationDisabled) { this._touchRotate.enable(options); } this._tapDragZoom.enable(); this._el.classList.add('mapboxgl-touch-zoom-rotate'); }; TouchZoomRotateHandler.prototype.disable = function disable() { this._touchZoom.disable(); this._touchRotate.disable(); this._tapDragZoom.disable(); this._el.classList.remove('mapboxgl-touch-zoom-rotate'); }; TouchZoomRotateHandler.prototype.isEnabled = function isEnabled() { return this._touchZoom.isEnabled() && (this._rotationDisabled || this._touchRotate.isEnabled()) && this._tapDragZoom.isEnabled(); }; TouchZoomRotateHandler.prototype.isActive = function isActive() { return this._touchZoom.isActive() || this._touchRotate.isActive() || this._tapDragZoom.isActive(); }; TouchZoomRotateHandler.prototype.disableRotation = function disableRotation() { this._rotationDisabled = true; this._touchRotate.disable(); }; TouchZoomRotateHandler.prototype.enableRotation = function enableRotation() { this._rotationDisabled = false; if (this._touchZoom.isEnabled()) { this._touchRotate.enable(); } }; var isMoving = function (p) { return p.zoom || p.drag || p.pitch || p.rotate; }; var RenderFrameEvent = function (Event) { function RenderFrameEvent() { Event.apply(this, arguments); } if (Event) RenderFrameEvent.__proto__ = Event; RenderFrameEvent.prototype = Object.create(Event && Event.prototype); RenderFrameEvent.prototype.constructor = RenderFrameEvent; return RenderFrameEvent; }(performance.Event); function hasChange(result) { return result.panDelta && result.panDelta.mag() || result.zoomDelta || result.bearingDelta || result.pitchDelta; } var HandlerManager = function HandlerManager(map, options) { this._map = map; this._el = this._map.getCanvasContainer(); this._handlers = []; this._handlersById = {}; this._changes = []; this._inertia = new HandlerInertia(map); this._bearingSnap = options.bearingSnap; this._previousActiveHandlers = {}; this._eventsInProgress = {}; this._addDefaultHandlers(options); performance.bindAll([ 'handleEvent', 'handleWindowEvent' ], this); var el = this._el; this._listeners = [ [ el, 'touchstart', { passive: true } ], [ el, 'touchmove', { passive: false } ], [ el, 'touchend', undefined ], [ el, 'touchcancel', undefined ], [ el, 'mousedown', undefined ], [ el, 'mousemove', undefined ], [ el, 'mouseup', undefined ], [ performance.window.document, 'mousemove', { capture: true } ], [ performance.window.document, 'mouseup', undefined ], [ el, 'mouseover', undefined ], [ el, 'mouseout', undefined ], [ el, 'dblclick', undefined ], [ el, 'click', undefined ], [ el, 'keydown', { capture: false } ], [ el, 'keyup', undefined ], [ el, 'wheel', { passive: false } ], [ el, 'contextmenu', undefined ], [ performance.window, 'blur', undefined ] ]; for (var i = 0, list = this._listeners; i < list.length; i += 1) { var ref = list[i]; var target = ref[0]; var type = ref[1]; var listenerOptions = ref[2]; DOM.addEventListener(target, type, target === performance.window.document ? this.handleWindowEvent : this.handleEvent, listenerOptions); } }; HandlerManager.prototype.destroy = function destroy() { for (var i = 0, list = this._listeners; i < list.length; i += 1) { var ref = list[i]; var target = ref[0]; var type = ref[1]; var listenerOptions = ref[2]; DOM.removeEventListener(target, type, target === performance.window.document ? this.handleWindowEvent : this.handleEvent, listenerOptions); } }; HandlerManager.prototype._addDefaultHandlers = function _addDefaultHandlers(options) { var map = this._map; var el = map.getCanvasContainer(); this._add('mapEvent', new MapEventHandler(map, options)); var boxZoom = map.boxZoom = new BoxZoomHandler(map, options); this._add('boxZoom', boxZoom); var tapZoom = new TapZoomHandler(); var clickZoom = new ClickZoomHandler(); map.doubleClickZoom = new DoubleClickZoomHandler(clickZoom, tapZoom); this._add('tapZoom', tapZoom); this._add('clickZoom', clickZoom); var tapDragZoom = new TapDragZoomHandler(); this._add('tapDragZoom', tapDragZoom); var touchPitch = map.touchPitch = new TouchPitchHandler(); this._add('touchPitch', touchPitch); var mouseRotate = new MouseRotateHandler(options); var mousePitch = new MousePitchHandler(options); map.dragRotate = new DragRotateHandler(options, mouseRotate, mousePitch); this._add('mouseRotate', mouseRotate, ['mousePitch']); this._add('mousePitch', mousePitch, ['mouseRotate']); var mousePan = new MousePanHandler(options); var touchPan = new TouchPanHandler(options); map.dragPan = new DragPanHandler(el, mousePan, touchPan); this._add('mousePan', mousePan); this._add('touchPan', touchPan, [ 'touchZoom', 'touchRotate' ]); var touchRotate = new TouchRotateHandler(); var touchZoom = new TouchZoomHandler(); map.touchZoomRotate = new TouchZoomRotateHandler(el, touchZoom, touchRotate, tapDragZoom); this._add('touchRotate', touchRotate, [ 'touchPan', 'touchZoom' ]); this._add('touchZoom', touchZoom, [ 'touchPan', 'touchRotate' ]); var scrollZoom = map.scrollZoom = new ScrollZoomHandler(map, this); this._add('scrollZoom', scrollZoom, ['mousePan']); var keyboard = map.keyboard = new KeyboardHandler(); this._add('keyboard', keyboard); this._add('blockableMapEvent', new BlockableMapEventHandler(map)); for (var i = 0, list = [ 'boxZoom', 'doubleClickZoom', 'tapDragZoom', 'touchPitch', 'dragRotate', 'dragPan', 'touchZoomRotate', 'scrollZoom', 'keyboard' ]; i < list.length; i += 1) { var name = list[i]; if (options.interactive && options[name]) { map[name].enable(options[name]); } } }; HandlerManager.prototype._add = function _add(handlerName, handler, allowed) { this._handlers.push({ handlerName: handlerName, handler: handler, allowed: allowed }); this._handlersById[handlerName] = handler; }; HandlerManager.prototype.stop = function stop(allowEndAnimation) { if (this._updatingCamera) { return; } for (var i = 0, list = this._handlers; i < list.length; i += 1) { var ref = list[i]; var handler = ref.handler; handler.reset(); } this._inertia.clear(); this._fireEvents({}, {}, allowEndAnimation); this._changes = []; }; HandlerManager.prototype.isActive = function isActive() { for (var i = 0, list = this._handlers; i < list.length; i += 1) { var ref = list[i]; var handler = ref.handler; if (handler.isActive()) { return true; } } return false; }; HandlerManager.prototype.isZooming = function isZooming() { return !!this._eventsInProgress.zoom || this._map.scrollZoom.isZooming(); }; HandlerManager.prototype.isRotating = function isRotating() { return !!this._eventsInProgress.rotate; }; HandlerManager.prototype.isMoving = function isMoving$1() { return Boolean(isMoving(this._eventsInProgress)) || this.isZooming(); }; HandlerManager.prototype._blockedByActive = function _blockedByActive(activeHandlers, allowed, myName) { for (var name in activeHandlers) { if (name === myName) { continue; } if (!allowed || allowed.indexOf(name) < 0) { return true; } } return false; }; HandlerManager.prototype.handleWindowEvent = function handleWindowEvent(e) { this.handleEvent(e, e.type + 'Window'); }; HandlerManager.prototype._getMapTouches = function _getMapTouches(touches) { var mapTouches = []; for (var i = 0, list = touches; i < list.length; i += 1) { var t = list[i]; var target = t.target; if (this._el.contains(target)) { mapTouches.push(t); } } return mapTouches; }; HandlerManager.prototype.handleEvent = function handleEvent(e, eventName) { this._updatingCamera = true; var inputEvent = e.type === 'renderFrame' ? undefined : e; var mergedHandlerResult = { needsRenderFrame: false }; var eventsInProgress = {}; var activeHandlers = {}; var mapTouches = e.touches ? this._getMapTouches(e.touches) : undefined; var points = mapTouches ? DOM.touchPos(this._el, mapTouches) : DOM.mousePos(this._el, e); for (var i = 0, list = this._handlers; i < list.length; i += 1) { var ref = list[i]; var handlerName = ref.handlerName; var handler = ref.handler; var allowed = ref.allowed; if (!handler.isEnabled()) { continue; } var data = void 0; if (this._blockedByActive(activeHandlers, allowed, handlerName)) { handler.reset(); } else { if (handler[eventName || e.type]) { data = handler[eventName || e.type](e, points, mapTouches); this.mergeHandlerResult(mergedHandlerResult, eventsInProgress, data, handlerName, inputEvent); if (data && data.needsRenderFrame) { this._triggerRenderFrame(); } } } if (data || handler.isActive()) { activeHandlers[handlerName] = handler; } } var deactivatedHandlers = {}; for (var name in this._previousActiveHandlers) { if (!activeHandlers[name]) { deactivatedHandlers[name] = inputEvent; } } this._previousActiveHandlers = activeHandlers; if (Object.keys(deactivatedHandlers).length || hasChange(mergedHandlerResult)) { this._changes.push([ mergedHandlerResult, eventsInProgress, deactivatedHandlers ]); this._triggerRenderFrame(); } if (Object.keys(activeHandlers).length || hasChange(mergedHandlerResult)) { this._map._stop(true); } this._updatingCamera = false; var cameraAnimation = mergedHandlerResult.cameraAnimation; if (cameraAnimation) { this._inertia.clear(); this._fireEvents({}, {}, true); this._changes = []; cameraAnimation(this._map); } }; HandlerManager.prototype.mergeHandlerResult = function mergeHandlerResult(mergedHandlerResult, eventsInProgress, handlerResult, name, e) { if (!handlerResult) { return; } performance.extend(mergedHandlerResult, handlerResult); var eventData = { handlerName: name, originalEvent: handlerResult.originalEvent || e }; if (handlerResult.zoomDelta !== undefined) { eventsInProgress.zoom = eventData; } if (handlerResult.panDelta !== undefined) { eventsInProgress.drag = eventData; } if (handlerResult.pitchDelta !== undefined) { eventsInProgress.pitch = eventData; } if (handlerResult.bearingDelta !== undefined) { eventsInProgress.rotate = eventData; } }; HandlerManager.prototype._applyChanges = function _applyChanges() { var combined = {}; var combinedEventsInProgress = {}; var combinedDeactivatedHandlers = {}; for (var i = 0, list = this._changes; i < list.length; i += 1) { var ref = list[i]; var change = ref[0]; var eventsInProgress = ref[1]; var deactivatedHandlers = ref[2]; if (change.panDelta) { combined.panDelta = (combined.panDelta || new performance.Point(0, 0))._add(change.panDelta); } if (change.zoomDelta) { combined.zoomDelta = (combined.zoomDelta || 0) + change.zoomDelta; } if (change.bearingDelta) { combined.bearingDelta = (combined.bearingDelta || 0) + change.bearingDelta; } if (change.pitchDelta) { combined.pitchDelta = (combined.pitchDelta || 0) + change.pitchDelta; } if (change.around !== undefined) { combined.around = change.around; } if (change.pinchAround !== undefined) { combined.pinchAround = change.pinchAround; } if (change.noInertia) { combined.noInertia = change.noInertia; } performance.extend(combinedEventsInProgress, eventsInProgress); performance.extend(combinedDeactivatedHandlers, deactivatedHandlers); } this._updateMapTransform(combined, combinedEventsInProgress, combinedDeactivatedHandlers); this._changes = []; }; HandlerManager.prototype._updateMapTransform = function _updateMapTransform(combinedResult, combinedEventsInProgress, deactivatedHandlers) { var map = this._map; var tr = map.transform; if (!hasChange(combinedResult)) { return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); } var panDelta = combinedResult.panDelta; var zoomDelta = combinedResult.zoomDelta; var bearingDelta = combinedResult.bearingDelta; var pitchDelta = combinedResult.pitchDelta; var around = combinedResult.around; var pinchAround = combinedResult.pinchAround; if (pinchAround !== undefined) { around = pinchAround; } map._stop(true); around = around || map.transform.centerPoint; var loc = tr.pointLocation(panDelta ? around.sub(panDelta) : around); if (bearingDelta) { tr.bearing += bearingDelta; } if (pitchDelta) { tr.pitch += pitchDelta; } if (zoomDelta) { tr.zoom += zoomDelta; } tr.setLocationAtPoint(loc, around); this._map._update(); if (!combinedResult.noInertia) { this._inertia.record(combinedResult); } this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); }; HandlerManager.prototype._fireEvents = function _fireEvents(newEventsInProgress, deactivatedHandlers, allowEndAnimation) { var this$1 = this; var wasMoving = isMoving(this._eventsInProgress); var nowMoving = isMoving(newEventsInProgress); var startEvents = {}; for (var eventName in newEventsInProgress) { var ref = newEventsInProgress[eventName]; var originalEvent = ref.originalEvent; if (!this._eventsInProgress[eventName]) { startEvents[eventName + 'start'] = originalEvent; } this._eventsInProgress[eventName] = newEventsInProgress[eventName]; } if (!wasMoving && nowMoving) { this._fireEvent('movestart', nowMoving.originalEvent); } for (var name in startEvents) { this._fireEvent(name, startEvents[name]); } if (nowMoving) { this._fireEvent('move', nowMoving.originalEvent); } for (var eventName$1 in newEventsInProgress) { var ref$1 = newEventsInProgress[eventName$1]; var originalEvent$1 = ref$1.originalEvent; this._fireEvent(eventName$1, originalEvent$1); } var endEvents = {}; var originalEndEvent; for (var eventName$2 in this._eventsInProgress) { var ref$2 = this._eventsInProgress[eventName$2]; var handlerName = ref$2.handlerName; var originalEvent$2 = ref$2.originalEvent; if (!this._handlersById[handlerName].isActive()) { delete this._eventsInProgress[eventName$2]; originalEndEvent = deactivatedHandlers[handlerName] || originalEvent$2; endEvents[eventName$2 + 'end'] = originalEndEvent; } } for (var name$1 in endEvents) { this._fireEvent(name$1, endEvents[name$1]); } var stillMoving = isMoving(this._eventsInProgress); if (allowEndAnimation && (wasMoving || nowMoving) && !stillMoving) { this._updatingCamera = true; var inertialEase = this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions); var shouldSnapToNorth = function (bearing) { return bearing !== 0 && -this$1._bearingSnap < bearing && bearing < this$1._bearingSnap; }; if (inertialEase) { if (shouldSnapToNorth(inertialEase.bearing || this._map.getBearing())) { inertialEase.bearing = 0; } this._map.easeTo(inertialEase, { originalEvent: originalEndEvent }); } else { this._map.fire(new performance.Event('moveend', { originalEvent: originalEndEvent })); if (shouldSnapToNorth(this._map.getBearing())) { this._map.resetNorth(); } } this._updatingCamera = false; } }; HandlerManager.prototype._fireEvent = function _fireEvent(type, e) { this._map.fire(new performance.Event(type, e ? { originalEvent: e } : {})); }; HandlerManager.prototype._requestFrame = function _requestFrame() { var this$1 = this; this._map.triggerRepaint(); return this._map._renderTaskQueue.add(function (timeStamp) { delete this$1._frameId; this$1.handleEvent(new RenderFrameEvent('renderFrame', { timeStamp: timeStamp })); this$1._applyChanges(); }); }; HandlerManager.prototype._triggerRenderFrame = function _triggerRenderFrame() { if (this._frameId === undefined) { this._frameId = this._requestFrame(); } }; var Camera = function (Evented) { function Camera(transform, options) { Evented.call(this); this._moving = false; this._zooming = false; this.transform = transform; this._bearingSnap = options.bearingSnap; performance.bindAll(['_renderFrameCallback'], this); } if (Evented) Camera.__proto__ = Evented; Camera.prototype = Object.create(Evented && Evented.prototype); Camera.prototype.constructor = Camera; Camera.prototype.getCenter = function getCenter() { return new performance.LngLat(this.transform.center.lng, this.transform.center.lat); }; Camera.prototype.setCenter = function setCenter(center, eventData) { return this.jumpTo({ center: center }, eventData); }; Camera.prototype.panBy = function panBy(offset, options, eventData) { offset = performance.Point.convert(offset).mult(-1); return this.panTo(this.transform.center, performance.extend({ offset: offset }, options), eventData); }; Camera.prototype.panTo = function panTo(lnglat, options, eventData) { return this.easeTo(performance.extend({ center: lnglat }, options), eventData); }; Camera.prototype.getZoom = function getZoom() { return this.transform.zoom; }; Camera.prototype.setZoom = function setZoom(zoom, eventData) { this.jumpTo({ zoom: zoom }, eventData); return this; }; Camera.prototype.zoomTo = function zoomTo(zoom, options, eventData) { return this.easeTo(performance.extend({ zoom: zoom }, options), eventData); }; Camera.prototype.zoomIn = function zoomIn(options, eventData) { this.zoomTo(this.getZoom() + 1, options, eventData); return this; }; Camera.prototype.zoomOut = function zoomOut(options, eventData) { this.zoomTo(this.getZoom() - 1, options, eventData); return this; }; Camera.prototype.getBearing = function getBearing() { return this.transform.bearing; }; Camera.prototype.setBearing = function setBearing(bearing, eventData) { this.jumpTo({ bearing: bearing }, eventData); return this; }; Camera.prototype.getPadding = function getPadding() { return this.transform.padding; }; Camera.prototype.setPadding = function setPadding(padding, eventData) { this.jumpTo({ padding: padding }, eventData); return this; }; Camera.prototype.rotateTo = function rotateTo(bearing, options, eventData) { return this.easeTo(performance.extend({ bearing: bearing }, options), eventData); }; Camera.prototype.resetNorth = function resetNorth(options, eventData) { this.rotateTo(0, performance.extend({ duration: 1000 }, options), eventData); return this; }; Camera.prototype.resetNorthPitch = function resetNorthPitch(options, eventData) { this.easeTo(performance.extend({ bearing: 0, pitch: 0, duration: 1000 }, options), eventData); return this; }; Camera.prototype.snapToNorth = function snapToNorth(options, eventData) { if (Math.abs(this.getBearing()) < this._bearingSnap) { return this.resetNorth(options, eventData); } return this; }; Camera.prototype.getPitch = function getPitch() { return this.transform.pitch; }; Camera.prototype.setPitch = function setPitch(pitch, eventData) { this.jumpTo({ pitch: pitch }, eventData); return this; }; Camera.prototype.cameraForBounds = function cameraForBounds(bounds, options) { bounds = performance.LngLatBounds.convert(bounds); var bearing = options && options.bearing || 0; return this._cameraForBoxAndBearing(bounds.getNorthWest(), bounds.getSouthEast(), bearing, options); }; Camera.prototype._cameraForBoxAndBearing = function _cameraForBoxAndBearing(p0, p1, bearing, options) { var defaultPadding = { top: 0, bottom: 0, right: 0, left: 0 }; options = performance.extend({ padding: defaultPadding, offset: [ 0, 0 ], maxZoom: this.transform.maxZoom }, options); if (typeof options.padding === 'number') { var p = options.padding; options.padding = { top: p, bottom: p, right: p, left: p }; } options.padding = performance.extend(defaultPadding, options.padding); var tr = this.transform; var edgePadding = tr.padding; var p0world = tr.project(performance.LngLat.convert(p0)); var p1world = tr.project(performance.LngLat.convert(p1)); var p0rotated = p0world.rotate(-bearing * Math.PI / 180); var p1rotated = p1world.rotate(-bearing * Math.PI / 180); var upperRight = new performance.Point(Math.max(p0rotated.x, p1rotated.x), Math.max(p0rotated.y, p1rotated.y)); var lowerLeft = new performance.Point(Math.min(p0rotated.x, p1rotated.x), Math.min(p0rotated.y, p1rotated.y)); var size = upperRight.sub(lowerLeft); var scaleX = (tr.width - (edgePadding.left + edgePadding.right + options.padding.left + options.padding.right)) / size.x; var scaleY = (tr.height - (edgePadding.top + edgePadding.bottom + options.padding.top + options.padding.bottom)) / size.y; if (scaleY < 0 || scaleX < 0) { performance.warnOnce('Map cannot fit within canvas with the given bounds, padding, and/or offset.'); return; } var zoom = Math.min(tr.scaleZoom(tr.scale * Math.min(scaleX, scaleY)), options.maxZoom); var offset = typeof options.offset.x === 'number' ? new performance.Point(options.offset.x, options.offset.y) : performance.Point.convert(options.offset); var paddingOffsetX = (options.padding.left - options.padding.right) / 2; var paddingOffsetY = (options.padding.top - options.padding.bottom) / 2; var paddingOffset = new performance.Point(paddingOffsetX, paddingOffsetY); var rotatedPaddingOffset = paddingOffset.rotate(bearing * Math.PI / 180); var offsetAtInitialZoom = offset.add(rotatedPaddingOffset); var offsetAtFinalZoom = offsetAtInitialZoom.mult(tr.scale / tr.zoomScale(zoom)); var center = tr.unproject(p0world.add(p1world).div(2).sub(offsetAtFinalZoom)); return { center: center, zoom: zoom, bearing: bearing }; }; Camera.prototype.fitBounds = function fitBounds(bounds, options, eventData) { return this._fitInternal(this.cameraForBounds(bounds, options), options, eventData); }; Camera.prototype.fitScreenCoordinates = function fitScreenCoordinates(p0, p1, bearing, options, eventData) { return this._fitInternal(this._cameraForBoxAndBearing(this.transform.pointLocation(performance.Point.convert(p0)), this.transform.pointLocation(performance.Point.convert(p1)), bearing, options), options, eventData); }; Camera.prototype._fitInternal = function _fitInternal(calculatedOptions, options, eventData) { if (!calculatedOptions) { return this; } options = performance.extend(calculatedOptions, options); delete options.padding; return options.linear ? this.easeTo(options, eventData) : this.flyTo(options, eventData); }; Camera.prototype.jumpTo = function jumpTo(options, eventData) { this.stop(); var tr = this.transform; var zoomChanged = false, bearingChanged = false, pitchChanged = false; if ('zoom' in options && tr.zoom !== +options.zoom) { zoomChanged = true; tr.zoom = +options.zoom; } if (options.center !== undefined) { tr.center = performance.LngLat.convert(options.center); } if ('bearing' in options && tr.bearing !== +options.bearing) { bearingChanged = true; tr.bearing = +options.bearing; } if ('pitch' in options && tr.pitch !== +options.pitch) { pitchChanged = true; tr.pitch = +options.pitch; } if (options.padding != null && !tr.isPaddingEqual(options.padding)) { tr.padding = options.padding; } this.fire(new performance.Event('movestart', eventData)).fire(new performance.Event('move', eventData)); if (zoomChanged) { this.fire(new performance.Event('zoomstart', eventData)).fire(new performance.Event('zoom', eventData)).fire(new performance.Event('zoomend', eventData)); } if (bearingChanged) { this.fire(new performance.Event('rotatestart', eventData)).fire(new performance.Event('rotate', eventData)).fire(new performance.Event('rotateend', eventData)); } if (pitchChanged) { this.fire(new performance.Event('pitchstart', eventData)).fire(new performance.Event('pitch', eventData)).fire(new performance.Event('pitchend', eventData)); } return this.fire(new performance.Event('moveend', eventData)); }; Camera.prototype.easeTo = function easeTo(options, eventData) { var this$1 = this; this._stop(false, options.easeId); options = performance.extend({ offset: [ 0, 0 ], duration: 500, easing: performance.ease }, options); if (options.animate === false || !options.essential && performance.browser.prefersReducedMotion) { options.duration = 0; } var tr = this.transform, startZoom = this.getZoom(), startBearing = this.getBearing(), startPitch = this.getPitch(), startPadding = this.getPadding(), zoom = 'zoom' in options ? +options.zoom : startZoom, bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing, pitch = 'pitch' in options ? +options.pitch : startPitch, padding = 'padding' in options ? options.padding : tr.padding; var offsetAsPoint = performance.Point.convert(options.offset); var pointAtOffset = tr.centerPoint.add(offsetAsPoint); var locationAtOffset = tr.pointLocation(pointAtOffset); var center = performance.LngLat.convert(options.center || locationAtOffset); this._normalizeCenter(center); var from = tr.project(locationAtOffset); var delta = tr.project(center).sub(from); var finalScale = tr.zoomScale(zoom - startZoom); var around, aroundPoint; if (options.around) { around = performance.LngLat.convert(options.around); aroundPoint = tr.locationPoint(around); } var currently = { moving: this._moving, zooming: this._zooming, rotating: this._rotating, pitching: this._pitching }; this._zooming = this._zooming || zoom !== startZoom; this._rotating = this._rotating || startBearing !== bearing; this._pitching = this._pitching || pitch !== startPitch; this._padding = !tr.isPaddingEqual(padding); this._easeId = options.easeId; this._prepareEase(eventData, options.noMoveStart, currently); this._ease(function (k) { if (this$1._zooming) { tr.zoom = performance.number(startZoom, zoom, k); } if (this$1._rotating) { tr.bearing = performance.number(startBearing, bearing, k); } if (this$1._pitching) { tr.pitch = performance.number(startPitch, pitch, k); } if (this$1._padding) { tr.interpolatePadding(startPadding, padding, k); pointAtOffset = tr.centerPoint.add(offsetAsPoint); } if (around) { tr.setLocationAtPoint(around, aroundPoint); } else { var scale = tr.zoomScale(tr.zoom - startZoom); var base = zoom > startZoom ? Math.min(2, finalScale) : Math.max(0.5, finalScale); var speedup = Math.pow(base, 1 - k); var newCenter = tr.unproject(from.add(delta.mult(k * speedup)).mult(scale)); tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset); } this$1._fireMoveEvents(eventData); }, function (interruptingEaseId) { this$1._afterEase(eventData, interruptingEaseId); }, options); return this; }; Camera.prototype._prepareEase = function _prepareEase(eventData, noMoveStart, currently) { if (currently === void 0) currently = {}; this._moving = true; if (!noMoveStart && !currently.moving) { this.fire(new performance.Event('movestart', eventData)); } if (this._zooming && !currently.zooming) { this.fire(new performance.Event('zoomstart', eventData)); } if (this._rotating && !currently.rotating) { this.fire(new performance.Event('rotatestart', eventData)); } if (this._pitching && !currently.pitching) { this.fire(new performance.Event('pitchstart', eventData)); } }; Camera.prototype._fireMoveEvents = function _fireMoveEvents(eventData) { this.fire(new performance.Event('move', eventData)); if (this._zooming) { this.fire(new performance.Event('zoom', eventData)); } if (this._rotating) { this.fire(new performance.Event('rotate', eventData)); } if (this._pitching) { this.fire(new performance.Event('pitch', eventData)); } }; Camera.prototype._afterEase = function _afterEase(eventData, easeId) { if (this._easeId && easeId && this._easeId === easeId) { return; } delete this._easeId; var wasZooming = this._zooming; var wasRotating = this._rotating; var wasPitching = this._pitching; this._moving = false; this._zooming = false; this._rotating = false; this._pitching = false; this._padding = false; if (wasZooming) { this.fire(new performance.Event('zoomend', eventData)); } if (wasRotating) { this.fire(new performance.Event('rotateend', eventData)); } if (wasPitching) { this.fire(new performance.Event('pitchend', eventData)); } this.fire(new performance.Event('moveend', eventData)); }; Camera.prototype.flyTo = function flyTo(options, eventData) { var this$1 = this; if (!options.essential && performance.browser.prefersReducedMotion) { var coercedOptions = performance.pick(options, [ 'center', 'zoom', 'bearing', 'pitch', 'around' ]); return this.jumpTo(coercedOptions, eventData); } this.stop(); options = performance.extend({ offset: [ 0, 0 ], speed: 1.2, curve: 1.42, easing: performance.ease }, options); var tr = this.transform, startZoom = this.getZoom(), startBearing = this.getBearing(), startPitch = this.getPitch(), startPadding = this.getPadding(); var zoom = 'zoom' in options ? performance.clamp(+options.zoom, tr.minZoom, tr.maxZoom) : startZoom; var bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing; var pitch = 'pitch' in options ? +options.pitch : startPitch; var padding = 'padding' in options ? options.padding : tr.padding; var scale = tr.zoomScale(zoom - startZoom); var offsetAsPoint = performance.Point.convert(options.offset); var pointAtOffset = tr.centerPoint.add(offsetAsPoint); var locationAtOffset = tr.pointLocation(pointAtOffset); var center = performance.LngLat.convert(options.center || locationAtOffset); this._normalizeCenter(center); var from = tr.project(locationAtOffset); var delta = tr.project(center).sub(from); var rho = options.curve; var w0 = Math.max(tr.width, tr.height), w1 = w0 / scale, u1 = delta.mag(); if ('minZoom' in options) { var minZoom = performance.clamp(Math.min(options.minZoom, startZoom, zoom), tr.minZoom, tr.maxZoom); var wMax = w0 / tr.zoomScale(minZoom - startZoom); rho = Math.sqrt(wMax / u1 * 2); } var rho2 = rho * rho; function r(i) { var b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1); return Math.log(Math.sqrt(b * b + 1) - b); } function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; } function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; } function tanh(n) { return sinh(n) / cosh(n); } var r0 = r(0); var w = function (s) { return cosh(r0) / cosh(r0 + rho * s); }; var u = function (s) { return w0 * ((cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2) / u1; }; var S = (r(1) - r0) / rho; if (Math.abs(u1) < 0.000001 || !isFinite(S)) { if (Math.abs(w0 - w1) < 0.000001) { return this.easeTo(options, eventData); } var k = w1 < w0 ? -1 : 1; S = Math.abs(Math.log(w1 / w0)) / rho; u = function () { return 0; }; w = function (s) { return Math.exp(k * rho * s); }; } if ('duration' in options) { options.duration = +options.duration; } else { var V = 'screenSpeed' in options ? +options.screenSpeed / rho : +options.speed; options.duration = 1000 * S / V; } if (options.maxDuration && options.duration > options.maxDuration) { options.duration = 0; } this._zooming = true; this._rotating = startBearing !== bearing; this._pitching = pitch !== startPitch; this._padding = !tr.isPaddingEqual(padding); this._prepareEase(eventData, false); this._ease(function (k) { var s = k * S; var scale = 1 / w(s); tr.zoom = k === 1 ? zoom : startZoom + tr.scaleZoom(scale); if (this$1._rotating) { tr.bearing = performance.number(startBearing, bearing, k); } if (this$1._pitching) { tr.pitch = performance.number(startPitch, pitch, k); } if (this$1._padding) { tr.interpolatePadding(startPadding, padding, k); pointAtOffset = tr.centerPoint.add(offsetAsPoint); } var newCenter = k === 1 ? center : tr.unproject(from.add(delta.mult(u(s))).mult(scale)); tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset); this$1._fireMoveEvents(eventData); }, function () { return this$1._afterEase(eventData); }, options); return this; }; Camera.prototype.isEasing = function isEasing() { return !!this._easeFrameId; }; Camera.prototype.stop = function stop() { return this._stop(); }; Camera.prototype._stop = function _stop(allowGestures, easeId) { if (this._easeFrameId) { this._cancelRenderFrame(this._easeFrameId); delete this._easeFrameId; delete this._onEaseFrame; } if (this._onEaseEnd) { var onEaseEnd = this._onEaseEnd; delete this._onEaseEnd; onEaseEnd.call(this, easeId); } if (!allowGestures) { var handlers = this.handlers; if (handlers) { handlers.stop(false); } } return this; }; Camera.prototype._ease = function _ease(frame, finish, options) { if (options.animate === false || options.duration === 0) { frame(1); finish(); } else { this._easeStart = performance.browser.now(); this._easeOptions = options; this._onEaseFrame = frame; this._onEaseEnd = finish; this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback); } }; Camera.prototype._renderFrameCallback = function _renderFrameCallback() { var t = Math.min((performance.browser.now() - this._easeStart) / this._easeOptions.duration, 1); this._onEaseFrame(this._easeOptions.easing(t)); if (t < 1) { this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback); } else { this.stop(); } }; Camera.prototype._normalizeBearing = function _normalizeBearing(bearing, currentBearing) { bearing = performance.wrap(bearing, -180, 180); var diff = Math.abs(bearing - currentBearing); if (Math.abs(bearing - 360 - currentBearing) < diff) { bearing -= 360; } if (Math.abs(bearing + 360 - currentBearing) < diff) { bearing += 360; } return bearing; }; Camera.prototype._normalizeCenter = function _normalizeCenter(center) { var tr = this.transform; if (!tr.renderWorldCopies || tr.lngRange) { return; } var delta = center.lng - tr.center.lng; center.lng += delta > 180 ? -360 : delta < -180 ? 360 : 0; }; return Camera; }(performance.Evented); var AttributionControl = function AttributionControl(options) { if (options === void 0) options = {}; this.options = options; performance.bindAll([ '_toggleAttribution', '_updateEditLink', '_updateData', '_updateCompact' ], this); }; AttributionControl.prototype.getDefaultPosition = function getDefaultPosition() { return 'bottom-right'; }; AttributionControl.prototype.onAdd = function onAdd(map) { var compact = this.options && this.options.compact; this._map = map; this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-attrib'); this._compactButton = DOM.create('button', 'mapboxgl-ctrl-attrib-button', this._container); this._compactButton.addEventListener('click', this._toggleAttribution); this._setElementTitle(this._compactButton, 'ToggleAttribution'); this._innerContainer = DOM.create('div', 'mapboxgl-ctrl-attrib-inner', this._container); this._innerContainer.setAttribute('role', 'list'); if (compact) { this._container.classList.add('mapboxgl-compact'); } this._updateAttributions(); this._updateEditLink(); this._map.on('styledata', this._updateData); this._map.on('sourcedata', this._updateData); this._map.on('moveend', this._updateEditLink); if (compact === undefined) { this._map.on('resize', this._updateCompact); this._updateCompact(); } return this._container; }; AttributionControl.prototype.onRemove = function onRemove() { DOM.remove(this._container); this._map.off('styledata', this._updateData); this._map.off('sourcedata', this._updateData); this._map.off('moveend', this._updateEditLink); this._map.off('resize', this._updateCompact); this._map = undefined; this._attribHTML = undefined; }; AttributionControl.prototype._setElementTitle = function _setElementTitle(element, title) { var str = this._map._getUIString('AttributionControl.' + title); element.title = str; element.setAttribute('aria-label', str); }; AttributionControl.prototype._toggleAttribution = function _toggleAttribution() { if (this._container.classList.contains('mapboxgl-compact-show')) { this._container.classList.remove('mapboxgl-compact-show'); this._compactButton.setAttribute('aria-pressed', 'false'); } else { this._container.classList.add('mapboxgl-compact-show'); this._compactButton.setAttribute('aria-pressed', 'true'); } }; AttributionControl.prototype._updateEditLink = function _updateEditLink() { var editLink = this._editLink; if (!editLink) { editLink = this._editLink = this._container.querySelector('.mapbox-improve-map'); } var params = [ { key: 'owner', value: this.styleOwner }, { key: 'id', value: this.styleId }, { key: 'access_token', value: this._map._requestManager._customAccessToken || performance.config.ACCESS_TOKEN } ]; if (editLink) { var paramString = params.reduce(function (acc, next, i) { if (next.value) { acc += next.key + '=' + next.value + (i < params.length - 1 ? '&' : ''); } return acc; }, '?'); editLink.href = performance.config.FEEDBACK_URL + '/' + paramString + (this._map._hash ? this._map._hash.getHashString(true) : ''); editLink.rel = 'noopener nofollow'; this._setElementTitle(editLink, 'MapFeedback'); } }; AttributionControl.prototype._updateData = function _updateData(e) { if (e && (e.sourceDataType === 'metadata' || e.sourceDataType === 'visibility' || e.dataType === 'style')) { this._updateAttributions(); this._updateEditLink(); } }; AttributionControl.prototype._updateAttributions = function _updateAttributions() { if (!this._map.style) { return; } var attributions = []; if (this.options.customAttribution) { if (Array.isArray(this.options.customAttribution)) { attributions = attributions.concat(this.options.customAttribution.map(function (attribution) { if (typeof attribution !== 'string') { return ''; } return attribution; })); } else if (typeof this.options.customAttribution === 'string') { attributions.push(this.options.customAttribution); } } if (this._map.style.stylesheet) { var stylesheet = this._map.style.stylesheet; this.styleOwner = stylesheet.owner; this.styleId = stylesheet.id; } var sourceCaches = this._map.style.sourceCaches; for (var id in sourceCaches) { var sourceCache = sourceCaches[id]; if (sourceCache.used) { var source = sourceCache.getSource(); if (source.attribution && attributions.indexOf(source.attribution) < 0) { attributions.push(source.attribution); } } } attributions.sort(function (a, b) { return a.length - b.length; }); attributions = attributions.filter(function (attrib, i) { for (var j = i + 1; j < attributions.length; j++) { if (attributions[j].indexOf(attrib) >= 0) { return false; } } return true; }); var attribHTML = attributions.join(' | '); if (attribHTML === this._attribHTML) { return; } this._attribHTML = attribHTML; if (attributions.length) { this._innerContainer.innerHTML = attribHTML; this._container.classList.remove('mapboxgl-attrib-empty'); } else { this._container.classList.add('mapboxgl-attrib-empty'); } this._editLink = null; }; AttributionControl.prototype._updateCompact = function _updateCompact() { if (this._map.getCanvasContainer().offsetWidth <= 640) { this._container.classList.add('mapboxgl-compact'); } else { this._container.classList.remove('mapboxgl-compact', 'mapboxgl-compact-show'); } }; var LogoControl = function LogoControl() { performance.bindAll(['_updateLogo'], this); performance.bindAll(['_updateCompact'], this); }; LogoControl.prototype.onAdd = function onAdd(map) { this._map = map; this._container = DOM.create('div', 'mapboxgl-ctrl'); var anchor = DOM.create('a', 'mapboxgl-ctrl-logo'); anchor.target = '_blank'; anchor.rel = 'noopener nofollow'; anchor.href = 'https://www.mapbox.com/'; anchor.setAttribute('aria-label', this._map._getUIString('LogoControl.Title')); anchor.setAttribute('rel', 'noopener nofollow'); this._container.appendChild(anchor); this._container.style.display = 'none'; this._map.on('sourcedata', this._updateLogo); this._updateLogo(); this._map.on('resize', this._updateCompact); this._updateCompact(); return this._container; }; LogoControl.prototype.onRemove = function onRemove() { DOM.remove(this._container); this._map.off('sourcedata', this._updateLogo); this._map.off('resize', this._updateCompact); }; LogoControl.prototype.getDefaultPosition = function getDefaultPosition() { return 'bottom-left'; }; LogoControl.prototype._updateLogo = function _updateLogo(e) { if (!e || e.sourceDataType === 'metadata') { this._container.style.display = this._logoRequired() ? 'block' : 'none'; } }; LogoControl.prototype._logoRequired = function _logoRequired() { if (!this._map.style) { return; } var sourceCaches = this._map.style.sourceCaches; for (var id in sourceCaches) { var source = sourceCaches[id].getSource(); if (source.mapbox_logo) { return true; } } return false; }; LogoControl.prototype._updateCompact = function _updateCompact() { var containerChildren = this._container.children; if (containerChildren.length) { var anchor = containerChildren[0]; if (this._map.getCanvasContainer().offsetWidth < 250) { anchor.classList.add('mapboxgl-compact'); } else { anchor.classList.remove('mapboxgl-compact'); } } }; var TaskQueue = function TaskQueue() { this._queue = []; this._id = 0; this._cleared = false; this._currentlyRunning = false; }; TaskQueue.prototype.add = function add(callback) { var id = ++this._id; var queue = this._queue; queue.push({ callback: callback, id: id, cancelled: false }); return id; }; TaskQueue.prototype.remove = function remove(id) { var running = this._currentlyRunning; var queue = running ? this._queue.concat(running) : this._queue; for (var i = 0, list = queue; i < list.length; i += 1) { var task = list[i]; if (task.id === id) { task.cancelled = true; return; } } }; TaskQueue.prototype.run = function run(timeStamp) { if (timeStamp === void 0) timeStamp = 0; var queue = this._currentlyRunning = this._queue; this._queue = []; for (var i = 0, list = queue; i < list.length; i += 1) { var task = list[i]; if (task.cancelled) { continue; } task.callback(timeStamp); if (this._cleared) { break; } } this._cleared = false; this._currentlyRunning = false; }; TaskQueue.prototype.clear = function clear() { if (this._currentlyRunning) { this._cleared = true; } this._queue = []; }; var defaultLocale = { 'AttributionControl.ToggleAttribution': 'Toggle attribution', 'AttributionControl.MapFeedback': 'Map feedback', 'FullscreenControl.Enter': 'Enter fullscreen', 'FullscreenControl.Exit': 'Exit fullscreen', 'GeolocateControl.FindMyLocation': 'Find my location', 'GeolocateControl.LocationNotAvailable': 'Location not available', 'LogoControl.Title': 'Mapbox logo', 'NavigationControl.ResetBearing': 'Reset bearing to north', 'NavigationControl.ZoomIn': 'Zoom in', 'NavigationControl.ZoomOut': 'Zoom out', 'ScaleControl.Feet': 'ft', 'ScaleControl.Meters': 'm', 'ScaleControl.Kilometers': 'km', 'ScaleControl.Miles': 'mi', 'ScaleControl.NauticalMiles': 'nm' }; var HTMLImageElement = performance.window.HTMLImageElement; var HTMLElement = performance.window.HTMLElement; var ImageBitmap = performance.window.ImageBitmap; var defaultMinZoom = -2; var defaultMaxZoom = 22; var defaultMinPitch = 0; var defaultMaxPitch = 60; var defaultOptions$1 = { center: [ 0, 0 ], zoom: 0, bearing: 0, pitch: 0, minZoom: defaultMinZoom, maxZoom: defaultMaxZoom, minPitch: defaultMinPitch, maxPitch: defaultMaxPitch, interactive: true, scrollZoom: true, boxZoom: true, dragRotate: true, dragPan: true, keyboard: true, doubleClickZoom: true, touchZoomRotate: true, touchPitch: true, bearingSnap: 7, clickTolerance: 3, pitchWithRotate: true, hash: false, attributionControl: true, failIfMajorPerformanceCaveat: false, preserveDrawingBuffer: false, trackResize: true, renderWorldCopies: true, refreshExpiredTiles: true, maxTileCacheSize: null, localIdeographFontFamily: 'sans-serif', transformRequest: null, accessToken: null, fadeDuration: 300, crossSourceCollisions: true }; var Map = function (Camera) { function Map(options) { var this$1 = this; options = performance.extend({}, defaultOptions$1, options); if (options.minZoom != null && options.maxZoom != null && options.minZoom > options.maxZoom) { throw new Error('maxZoom must be greater than or equal to minZoom'); } if (options.minPitch != null && options.maxPitch != null && options.minPitch > options.maxPitch) { throw new Error('maxPitch must be greater than or equal to minPitch'); } if (options.minPitch != null && options.minPitch < defaultMinPitch) { throw new Error('minPitch must be greater than or equal to ' + defaultMinPitch); } if (options.maxPitch != null && options.maxPitch > defaultMaxPitch) { throw new Error('maxPitch must be less than or equal to ' + defaultMaxPitch); } var transform = new Transform(options.minZoom, options.maxZoom, options.minPitch, options.maxPitch, options.renderWorldCopies); Camera.call(this, transform, options); this._interactive = options.interactive; this._maxTileCacheSize = options.maxTileCacheSize; this._failIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat; this._preserveDrawingBuffer = options.preserveDrawingBuffer; this._antialias = options.antialias; this._trackResize = options.trackResize; this._bearingSnap = options.bearingSnap; this._refreshExpiredTiles = options.refreshExpiredTiles; this._fadeDuration = options.fadeDuration; this._crossSourceCollisions = options.crossSourceCollisions; this._crossFadingFactor = 1; this._collectResourceTiming = options.collectResourceTiming; this._renderTaskQueue = new TaskQueue(); this._controls = []; this._mapId = performance.uniqueId(); this._locale = performance.extend({}, defaultLocale, options.locale); this._clickTolerance = options.clickTolerance; this._requestManager = new performance.RequestManager(options.transformRequest, options.accessToken); if (typeof options.container === 'string') { this._container = performance.window.document.getElementById(options.container); if (!this._container) { throw new Error('Container \'' + options.container + '\' not found.'); } } else if (options.container instanceof HTMLElement) { this._container = options.container; } else { throw new Error('Invalid type: \'container\' must be a String or HTMLElement.'); } if (options.maxBounds) { this.setMaxBounds(options.maxBounds); } performance.bindAll([ '_onWindowOnline', '_onWindowResize', '_onMapScroll', '_contextLost', '_contextRestored' ], this); this._setupContainer(); this._setupPainter(); if (this.painter === undefined) { throw new Error('Failed to initialize WebGL.'); } this.on('move', function () { return this$1._update(false); }); this.on('moveend', function () { return this$1._update(false); }); this.on('zoom', function () { return this$1._update(true); }); if (typeof performance.window !== 'undefined') { performance.window.addEventListener('online', this._onWindowOnline, false); performance.window.addEventListener('resize', this._onWindowResize, false); performance.window.addEventListener('orientationchange', this._onWindowResize, false); } this.handlers = new HandlerManager(this, options); var hashName = typeof options.hash === 'string' && options.hash || undefined; this._hash = options.hash && new Hash(hashName).addTo(this); if (!this._hash || !this._hash._onHashChange()) { this.jumpTo({ center: options.center, zoom: options.zoom, bearing: options.bearing, pitch: options.pitch }); if (options.bounds) { this.resize(); this.fitBounds(options.bounds, performance.extend({}, options.fitBoundsOptions, { duration: 0 })); } } this.resize(); this._localIdeographFontFamily = options.localIdeographFontFamily; if (options.style) { this.setStyle(options.style, { localIdeographFontFamily: options.localIdeographFontFamily }); } if (options.attributionControl) { this.addControl(new AttributionControl({ customAttribution: options.customAttribution })); } this.addControl(new LogoControl(), options.logoPosition); this.on('style.load', function () { if (this$1.transform.unmodified) { this$1.jumpTo(this$1.style.stylesheet); } }); this.on('data', function (event) { this$1._update(event.dataType === 'style'); this$1.fire(new performance.Event(event.dataType + 'data', event)); }); this.on('dataloading', function (event) { this$1.fire(new performance.Event(event.dataType + 'dataloading', event)); }); } if (Camera) Map.__proto__ = Camera; Map.prototype = Object.create(Camera && Camera.prototype); Map.prototype.constructor = Map; var prototypeAccessors = { showTileBoundaries: { configurable: true }, showPadding: { configurable: true }, showCollisionBoxes: { configurable: true }, showOverdrawInspector: { configurable: true }, repaint: { configurable: true }, vertices: { configurable: true }, version: { configurable: true } }; Map.prototype._getMapId = function _getMapId() { return this._mapId; }; Map.prototype.addControl = function addControl(control, position) { if (position === undefined) { if (control.getDefaultPosition) { position = control.getDefaultPosition(); } else { position = 'top-right'; } } if (!control || !control.onAdd) { return this.fire(new performance.ErrorEvent(new Error('Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.'))); } var controlElement = control.onAdd(this); this._controls.push(control); var positionContainer = this._controlPositions[position]; if (position.indexOf('bottom') !== -1) { positionContainer.insertBefore(controlElement, positionContainer.firstChild); } else { positionContainer.appendChild(controlElement); } return this; }; Map.prototype.removeControl = function removeControl(control) { if (!control || !control.onRemove) { return this.fire(new performance.ErrorEvent(new Error('Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.'))); } var ci = this._controls.indexOf(control); if (ci > -1) { this._controls.splice(ci, 1); } control.onRemove(this); return this; }; Map.prototype.hasControl = function hasControl(control) { return this._controls.indexOf(control) > -1; }; Map.prototype.resize = function resize(eventData) { var ref = this._containerDimensions(); var width = ref[0]; var height = ref[1]; if (width === this.transform.width && height === this.transform.height) { return this; } this._resizeCanvas(width, height); this.transform.resize(width, height); this.painter.resize(width, height); var fireMoving = !this._moving; if (fireMoving) { this.fire(new performance.Event('movestart', eventData)).fire(new performance.Event('move', eventData)); } this.fire(new performance.Event('resize', eventData)); if (fireMoving) { this.fire(new performance.Event('moveend', eventData)); } return this; }; Map.prototype.getBounds = function getBounds() { return this.transform.getBounds(); }; Map.prototype.getMaxBounds = function getMaxBounds() { return this.transform.getMaxBounds(); }; Map.prototype.setMaxBounds = function setMaxBounds(bounds) { this.transform.setMaxBounds(performance.LngLatBounds.convert(bounds)); return this._update(); }; Map.prototype.setMinZoom = function setMinZoom(minZoom) { minZoom = minZoom === null || minZoom === undefined ? defaultMinZoom : minZoom; if (minZoom >= defaultMinZoom && minZoom <= this.transform.maxZoom) { this.transform.minZoom = minZoom; this._update(); if (this.getZoom() < minZoom) { this.setZoom(minZoom); } return this; } else { throw new Error('minZoom must be between ' + defaultMinZoom + ' and the current maxZoom, inclusive'); } }; Map.prototype.getMinZoom = function getMinZoom() { return this.transform.minZoom; }; Map.prototype.setMaxZoom = function setMaxZoom(maxZoom) { maxZoom = maxZoom === null || maxZoom === undefined ? defaultMaxZoom : maxZoom; if (maxZoom >= this.transform.minZoom) { this.transform.maxZoom = maxZoom; this._update(); if (this.getZoom() > maxZoom) { this.setZoom(maxZoom); } return this; } else { throw new Error('maxZoom must be greater than the current minZoom'); } }; Map.prototype.getMaxZoom = function getMaxZoom() { return this.transform.maxZoom; }; Map.prototype.setMinPitch = function setMinPitch(minPitch) { minPitch = minPitch === null || minPitch === undefined ? defaultMinPitch : minPitch; if (minPitch < defaultMinPitch) { throw new Error('minPitch must be greater than or equal to ' + defaultMinPitch); } if (minPitch >= defaultMinPitch && minPitch <= this.transform.maxPitch) { this.transform.minPitch = minPitch; this._update(); if (this.getPitch() < minPitch) { this.setPitch(minPitch); } return this; } else { throw new Error('minPitch must be between ' + defaultMinPitch + ' and the current maxPitch, inclusive'); } }; Map.prototype.getMinPitch = function getMinPitch() { return this.transform.minPitch; }; Map.prototype.setMaxPitch = function setMaxPitch(maxPitch) { maxPitch = maxPitch === null || maxPitch === undefined ? defaultMaxPitch : maxPitch; if (maxPitch > defaultMaxPitch) { throw new Error('maxPitch must be less than or equal to ' + defaultMaxPitch); } if (maxPitch >= this.transform.minPitch) { this.transform.maxPitch = maxPitch; this._update(); if (this.getPitch() > maxPitch) { this.setPitch(maxPitch); } return this; } else { throw new Error('maxPitch must be greater than the current minPitch'); } }; Map.prototype.getMaxPitch = function getMaxPitch() { return this.transform.maxPitch; }; Map.prototype.getRenderWorldCopies = function getRenderWorldCopies() { return this.transform.renderWorldCopies; }; Map.prototype.setRenderWorldCopies = function setRenderWorldCopies(renderWorldCopies) { this.transform.renderWorldCopies = renderWorldCopies; return this._update(); }; Map.prototype.project = function project(lnglat) { return this.transform.locationPoint(performance.LngLat.convert(lnglat)); }; Map.prototype.unproject = function unproject(point) { return this.transform.pointLocation(performance.Point.convert(point)); }; Map.prototype.isMoving = function isMoving() { return this._moving || this.handlers.isMoving(); }; Map.prototype.isZooming = function isZooming() { return this._zooming || this.handlers.isZooming(); }; Map.prototype.isRotating = function isRotating() { return this._rotating || this.handlers.isRotating(); }; Map.prototype._createDelegatedListener = function _createDelegatedListener(type, layerId, listener) { var this$1 = this; var obj; if (type === 'mouseenter' || type === 'mouseover') { var mousein = false; var mousemove = function (e) { var features = this$1.getLayer(layerId) ? this$1.queryRenderedFeatures(e.point, { layers: [layerId] }) : []; if (!features.length) { mousein = false; } else if (!mousein) { mousein = true; listener.call(this$1, new MapMouseEvent(type, this$1, e.originalEvent, { features: features })); } }; var mouseout = function () { mousein = false; }; return { layer: layerId, listener: listener, delegates: { mousemove: mousemove, mouseout: mouseout } }; } else if (type === 'mouseleave' || type === 'mouseout') { var mousein$1 = false; var mousemove$1 = function (e) { var features = this$1.getLayer(layerId) ? this$1.queryRenderedFeatures(e.point, { layers: [layerId] }) : []; if (features.length) { mousein$1 = true; } else if (mousein$1) { mousein$1 = false; listener.call(this$1, new MapMouseEvent(type, this$1, e.originalEvent)); } }; var mouseout$1 = function (e) { if (mousein$1) { mousein$1 = false; listener.call(this$1, new MapMouseEvent(type, this$1, e.originalEvent)); } }; return { layer: layerId, listener: listener, delegates: { mousemove: mousemove$1, mouseout: mouseout$1 } }; } else { var delegate = function (e) { var features = this$1.getLayer(layerId) ? this$1.queryRenderedFeatures(e.point, { layers: [layerId] }) : []; if (features.length) { e.features = features; listener.call(this$1, e); delete e.features; } }; return { layer: layerId, listener: listener, delegates: (obj = {}, obj[type] = delegate, obj) }; } }; Map.prototype.on = function on(type, layerId, listener) { if (listener === undefined) { return Camera.prototype.on.call(this, type, layerId); } var delegatedListener = this._createDelegatedListener(type, layerId, listener); this._delegatedListeners = this._delegatedListeners || {}; this._delegatedListeners[type] = this._delegatedListeners[type] || []; this._delegatedListeners[type].push(delegatedListener); for (var event in delegatedListener.delegates) { this.on(event, delegatedListener.delegates[event]); } return this; }; Map.prototype.once = function once(type, layerId, listener) { if (listener === undefined) { return Camera.prototype.once.call(this, type, layerId); } var delegatedListener = this._createDelegatedListener(type, layerId, listener); for (var event in delegatedListener.delegates) { this.once(event, delegatedListener.delegates[event]); } return this; }; Map.prototype.off = function off(type, layerId, listener) { var this$1 = this; if (listener === undefined) { return Camera.prototype.off.call(this, type, layerId); } var removeDelegatedListener = function (delegatedListeners) { var listeners = delegatedListeners[type]; for (var i = 0; i < listeners.length; i++) { var delegatedListener = listeners[i]; if (delegatedListener.layer === layerId && delegatedListener.listener === listener) { for (var event in delegatedListener.delegates) { this$1.off(event, delegatedListener.delegates[event]); } listeners.splice(i, 1); return this$1; } } }; if (this._delegatedListeners && this._delegatedListeners[type]) { removeDelegatedListener(this._delegatedListeners); } return this; }; Map.prototype.queryRenderedFeatures = function queryRenderedFeatures(geometry, options) { if (!this.style) { return []; } if (options === undefined && geometry !== undefined && !(geometry instanceof performance.Point) && !Array.isArray(geometry)) { options = geometry; geometry = undefined; } options = options || {}; geometry = geometry || [ [ 0, 0 ], [ this.transform.width, this.transform.height ] ]; var queryGeometry; if (geometry instanceof performance.Point || typeof geometry[0] === 'number') { queryGeometry = [performance.Point.convert(geometry)]; } else { var tl = performance.Point.convert(geometry[0]); var br = performance.Point.convert(geometry[1]); queryGeometry = [ tl, new performance.Point(br.x, tl.y), br, new performance.Point(tl.x, br.y), tl ]; } return this.style.queryRenderedFeatures(queryGeometry, options, this.transform); }; Map.prototype.querySourceFeatures = function querySourceFeatures(sourceId, parameters) { return this.style.querySourceFeatures(sourceId, parameters); }; Map.prototype.setStyle = function setStyle(style, options) { options = performance.extend({}, { localIdeographFontFamily: this._localIdeographFontFamily }, options); if (options.diff !== false && options.localIdeographFontFamily === this._localIdeographFontFamily && this.style && style) { this._diffStyle(style, options); return this; } else { this._localIdeographFontFamily = options.localIdeographFontFamily; return this._updateStyle(style, options); } }; Map.prototype._getUIString = function _getUIString(key) { var str = this._locale[key]; if (str == null) { throw new Error('Missing UI string \'' + key + '\''); } return str; }; Map.prototype._updateStyle = function _updateStyle(style, options) { if (this.style) { this.style.setEventedParent(null); this.style._remove(); } if (!style) { delete this.style; return this; } else { this.style = new Style(this, options || {}); } this.style.setEventedParent(this, { style: this.style }); if (typeof style === 'string') { this.style.loadURL(style); } else { this.style.loadJSON(style); } return this; }; Map.prototype._lazyInitEmptyStyle = function _lazyInitEmptyStyle() { if (!this.style) { this.style = new Style(this, {}); this.style.setEventedParent(this, { style: this.style }); this.style.loadEmpty(); } }; Map.prototype._diffStyle = function _diffStyle(style, options) { var this$1 = this; if (typeof style === 'string') { var url = this._requestManager.normalizeStyleURL(style); var request = this._requestManager.transformRequest(url, performance.ResourceType.Style); performance.getJSON(request, function (error, json) { if (error) { this$1.fire(new performance.ErrorEvent(error)); } else if (json) { this$1._updateDiff(json, options); } }); } else if (typeof style === 'object') { this._updateDiff(style, options); } }; Map.prototype._updateDiff = function _updateDiff(style, options) { try { if (this.style.setState(style)) { this._update(true); } } catch (e) { performance.warnOnce('Unable to perform style diff: ' + (e.message || e.error || e) + '. Rebuilding the style from scratch.'); this._updateStyle(style, options); } }; Map.prototype.getStyle = function getStyle() { if (this.style) { return this.style.serialize(); } }; Map.prototype.isStyleLoaded = function isStyleLoaded() { if (!this.style) { return performance.warnOnce('There is no style added to the map.'); } return this.style.loaded(); }; Map.prototype.addSource = function addSource(id, source) { this._lazyInitEmptyStyle(); this.style.addSource(id, source); return this._update(true); }; Map.prototype.isSourceLoaded = function isSourceLoaded(id) { var source = this.style && this.style.sourceCaches[id]; if (source === undefined) { this.fire(new performance.ErrorEvent(new Error('There is no source with ID \'' + id + '\''))); return; } return source.loaded(); }; Map.prototype.areTilesLoaded = function areTilesLoaded() { var sources = this.style && this.style.sourceCaches; for (var id in sources) { var source = sources[id]; var tiles = source._tiles; for (var t in tiles) { var tile = tiles[t]; if (!(tile.state === 'loaded' || tile.state === 'errored')) { return false; } } } return true; }; Map.prototype.addSourceType = function addSourceType(name, SourceType, callback) { this._lazyInitEmptyStyle(); return this.style.addSourceType(name, SourceType, callback); }; Map.prototype.removeSource = function removeSource(id) { this.style.removeSource(id); return this._update(true); }; Map.prototype.getSource = function getSource(id) { return this.style.getSource(id); }; Map.prototype.addImage = function addImage(id, image, ref) { if (ref === void 0) ref = {}; var pixelRatio = ref.pixelRatio; if (pixelRatio === void 0) pixelRatio = 1; var sdf = ref.sdf; if (sdf === void 0) sdf = false; var stretchX = ref.stretchX; var stretchY = ref.stretchY; var content = ref.content; this._lazyInitEmptyStyle(); var version = 0; if (image instanceof HTMLImageElement || ImageBitmap && image instanceof ImageBitmap) { var ref$1 = performance.browser.getImageData(image); var width = ref$1.width; var height = ref$1.height; var data = ref$1.data; this.style.addImage(id, { data: new performance.RGBAImage({ width: width, height: height }, data), pixelRatio: pixelRatio, stretchX: stretchX, stretchY: stretchY, content: content, sdf: sdf, version: version }); } else if (image.width === undefined || image.height === undefined) { return this.fire(new performance.ErrorEvent(new Error('Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' + 'or object with `width`, `height`, and `data` properties with the same format as `ImageData`'))); } else { var width$1 = image.width; var height$1 = image.height; var data$1 = image.data; var userImage = image; this.style.addImage(id, { data: new performance.RGBAImage({ width: width$1, height: height$1 }, new Uint8Array(data$1)), pixelRatio: pixelRatio, stretchX: stretchX, stretchY: stretchY, content: content, sdf: sdf, version: version, userImage: userImage }); if (userImage.onAdd) { userImage.onAdd(this, id); } } }; Map.prototype.updateImage = function updateImage(id, image) { var existingImage = this.style.getImage(id); if (!existingImage) { return this.fire(new performance.ErrorEvent(new Error('The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.'))); } var imageData = image instanceof HTMLImageElement || ImageBitmap && image instanceof ImageBitmap ? performance.browser.getImageData(image) : image; var width = imageData.width; var height = imageData.height; var data = imageData.data; if (width === undefined || height === undefined) { return this.fire(new performance.ErrorEvent(new Error('Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' + 'or object with `width`, `height`, and `data` properties with the same format as `ImageData`'))); } if (width !== existingImage.data.width || height !== existingImage.data.height) { return this.fire(new performance.ErrorEvent(new Error('The width and height of the updated image must be that same as the previous version of the image'))); } var copy = !(image instanceof HTMLImageElement || ImageBitmap && image instanceof ImageBitmap); existingImage.data.replace(data, copy); this.style.updateImage(id, existingImage); }; Map.prototype.hasImage = function hasImage(id) { if (!id) { this.fire(new performance.ErrorEvent(new Error('Missing required image id'))); return false; } return !!this.style.getImage(id); }; Map.prototype.removeImage = function removeImage(id) { this.style.removeImage(id); }; Map.prototype.loadImage = function loadImage(url, callback) { performance.getImage(this._requestManager.transformRequest(url, performance.ResourceType.Image), callback); }; Map.prototype.listImages = function listImages() { return this.style.listImages(); }; Map.prototype.addLayer = function addLayer(layer, beforeId) { this._lazyInitEmptyStyle(); this.style.addLayer(layer, beforeId); return this._update(true); }; Map.prototype.moveLayer = function moveLayer(id, beforeId) { this.style.moveLayer(id, beforeId); return this._update(true); }; Map.prototype.removeLayer = function removeLayer(id) { this.style.removeLayer(id); return this._update(true); }; Map.prototype.getLayer = function getLayer(id) { return this.style.getLayer(id); }; Map.prototype.setLayerZoomRange = function setLayerZoomRange(layerId, minzoom, maxzoom) { this.style.setLayerZoomRange(layerId, minzoom, maxzoom); return this._update(true); }; Map.prototype.setFilter = function setFilter(layerId, filter, options) { if (options === void 0) options = {}; this.style.setFilter(layerId, filter, options); return this._update(true); }; Map.prototype.getFilter = function getFilter(layerId) { return this.style.getFilter(layerId); }; Map.prototype.setPaintProperty = function setPaintProperty(layerId, name, value, options) { if (options === void 0) options = {}; this.style.setPaintProperty(layerId, name, value, options); return this._update(true); }; Map.prototype.getPaintProperty = function getPaintProperty(layerId, name) { return this.style.getPaintProperty(layerId, name); }; Map.prototype.setLayoutProperty = function setLayoutProperty(layerId, name, value, options) { if (options === void 0) options = {}; this.style.setLayoutProperty(layerId, name, value, options); return this._update(true); }; Map.prototype.getLayoutProperty = function getLayoutProperty(layerId, name) { return this.style.getLayoutProperty(layerId, name); }; Map.prototype.setLight = function setLight(light, options) { if (options === void 0) options = {}; this._lazyInitEmptyStyle(); this.style.setLight(light, options); return this._update(true); }; Map.prototype.getLight = function getLight() { return this.style.getLight(); }; Map.prototype.setFeatureState = function setFeatureState(feature, state) { this.style.setFeatureState(feature, state); return this._update(); }; Map.prototype.removeFeatureState = function removeFeatureState(target, key) { this.style.removeFeatureState(target, key); return this._update(); }; Map.prototype.getFeatureState = function getFeatureState(feature) { return this.style.getFeatureState(feature); }; Map.prototype.getContainer = function getContainer() { return this._container; }; Map.prototype.getCanvasContainer = function getCanvasContainer() { return this._canvasContainer; }; Map.prototype.getCanvas = function getCanvas() { return this._canvas; }; Map.prototype._containerDimensions = function _containerDimensions() { var width = 0; var height = 0; if (this._container) { width = this._container.clientWidth || 400; height = this._container.clientHeight || 300; } return [ width, height ]; }; Map.prototype._detectMissingCSS = function _detectMissingCSS() { var computedColor = performance.window.getComputedStyle(this._missingCSSCanary).getPropertyValue('background-color'); if (computedColor !== 'rgb(250, 128, 114)') { performance.warnOnce('This page appears to be missing CSS declarations for ' + 'Mapbox GL JS, which may cause the map to display incorrectly. ' + 'Please ensure your page includes mapbox-gl.css, as described ' + 'in https://www.mapbox.com/mapbox-gl-js/api/.'); } }; Map.prototype._setupContainer = function _setupContainer() { var container = this._container; container.classList.add('mapboxgl-map'); var missingCSSCanary = this._missingCSSCanary = DOM.create('div', 'mapboxgl-canary', container); missingCSSCanary.style.visibility = 'hidden'; this._detectMissingCSS(); var canvasContainer = this._canvasContainer = DOM.create('div', 'mapboxgl-canvas-container', container); if (this._interactive) { canvasContainer.classList.add('mapboxgl-interactive'); } this._canvas = DOM.create('canvas', 'mapboxgl-canvas', canvasContainer); this._canvas.addEventListener('webglcontextlost', this._contextLost, false); this._canvas.addEventListener('webglcontextrestored', this._contextRestored, false); this._canvas.setAttribute('tabindex', '0'); this._canvas.setAttribute('aria-label', 'Map'); this._canvas.setAttribute('role', 'region'); var dimensions = this._containerDimensions(); this._resizeCanvas(dimensions[0], dimensions[1]); var controlContainer = this._controlContainer = DOM.create('div', 'mapboxgl-control-container', container); var positions = this._controlPositions = {}; [ 'top-left', 'top-right', 'bottom-left', 'bottom-right' ].forEach(function (positionName) { positions[positionName] = DOM.create('div', 'mapboxgl-ctrl-' + positionName, controlContainer); }); this._container.addEventListener('scroll', this._onMapScroll, false); }; Map.prototype._resizeCanvas = function _resizeCanvas(width, height) { var pixelRatio = performance.browser.devicePixelRatio || 1; this._canvas.width = pixelRatio * width; this._canvas.height = pixelRatio * height; this._canvas.style.width = width + 'px'; this._canvas.style.height = height + 'px'; }; Map.prototype._setupPainter = function _setupPainter() { var attributes = performance.extend({}, mapboxGlSupported.webGLContextAttributes, { failIfMajorPerformanceCaveat: this._failIfMajorPerformanceCaveat, preserveDrawingBuffer: this._preserveDrawingBuffer, antialias: this._antialias || false }); var gl = this._canvas.getContext('webgl', attributes) || this._canvas.getContext('experimental-webgl', attributes); if (!gl) { this.fire(new performance.ErrorEvent(new Error('Failed to initialize WebGL'))); return; } this.painter = new Painter(gl, this.transform); performance.webpSupported.testSupport(gl); }; Map.prototype._contextLost = function _contextLost(event) { event.preventDefault(); if (this._frame) { this._frame.cancel(); this._frame = null; } this.fire(new performance.Event('webglcontextlost', { originalEvent: event })); }; Map.prototype._contextRestored = function _contextRestored(event) { this._setupPainter(); this.resize(); this._update(); this.fire(new performance.Event('webglcontextrestored', { originalEvent: event })); }; Map.prototype._onMapScroll = function _onMapScroll(event) { if (event.target !== this._container) { return; } this._container.scrollTop = 0; this._container.scrollLeft = 0; return false; }; Map.prototype.loaded = function loaded() { return !this._styleDirty && !this._sourcesDirty && !!this.style && this.style.loaded(); }; Map.prototype._update = function _update(updateStyle) { if (!this.style) { return this; } this._styleDirty = this._styleDirty || updateStyle; this._sourcesDirty = true; this.triggerRepaint(); return this; }; Map.prototype._requestRenderFrame = function _requestRenderFrame(callback) { this._update(); return this._renderTaskQueue.add(callback); }; Map.prototype._cancelRenderFrame = function _cancelRenderFrame(id) { this._renderTaskQueue.remove(id); }; Map.prototype._render = function _render(paintStartTimeStamp) { var this$1 = this; var gpuTimer, frameStartTime = 0; var extTimerQuery = this.painter.context.extTimerQuery; if (this.listens('gpu-timing-frame')) { gpuTimer = extTimerQuery.createQueryEXT(); extTimerQuery.beginQueryEXT(extTimerQuery.TIME_ELAPSED_EXT, gpuTimer); frameStartTime = performance.browser.now(); } this.painter.context.setDirty(); this.painter.setBaseState(); this._renderTaskQueue.run(paintStartTimeStamp); if (this._removed) { return; } var crossFading = false; if (this.style && this._styleDirty) { this._styleDirty = false; var zoom = this.transform.zoom; var now = performance.browser.now(); this.style.zoomHistory.update(zoom, now); var parameters = new performance.EvaluationParameters(zoom, { now: now, fadeDuration: this._fadeDuration, zoomHistory: this.style.zoomHistory, transition: this.style.getTransition() }); var factor = parameters.crossFadingFactor(); if (factor !== 1 || factor !== this._crossFadingFactor) { crossFading = true; this._crossFadingFactor = factor; } this.style.update(parameters); } if (this.style && this._sourcesDirty) { this._sourcesDirty = false; this.style._updateSources(this.transform); } this._placementDirty = this.style && this.style._updatePlacement(this.painter.transform, this.showCollisionBoxes, this._fadeDuration, this._crossSourceCollisions); this.painter.render(this.style, { showTileBoundaries: this.showTileBoundaries, showOverdrawInspector: this._showOverdrawInspector, rotating: this.isRotating(), zooming: this.isZooming(), moving: this.isMoving(), fadeDuration: this._fadeDuration, showPadding: this.showPadding, gpuTiming: !!this.listens('gpu-timing-layer') }); this.fire(new performance.Event('render')); if (this.loaded() && !this._loaded) { this._loaded = true; this.fire(new performance.Event('load')); } if (this.style && (this.style.hasTransitions() || crossFading)) { this._styleDirty = true; } if (this.style && !this._placementDirty) { this.style._releaseSymbolFadeTiles(); } if (this.listens('gpu-timing-frame')) { var renderCPUTime = performance.browser.now() - frameStartTime; extTimerQuery.endQueryEXT(extTimerQuery.TIME_ELAPSED_EXT, gpuTimer); setTimeout(function () { var renderGPUTime = extTimerQuery.getQueryObjectEXT(gpuTimer, extTimerQuery.QUERY_RESULT_EXT) / (1000 * 1000); extTimerQuery.deleteQueryEXT(gpuTimer); this$1.fire(new performance.Event('gpu-timing-frame', { cpuTime: renderCPUTime, gpuTime: renderGPUTime })); }, 50); } if (this.listens('gpu-timing-layer')) { var frameLayerQueries = this.painter.collectGpuTimers(); setTimeout(function () { var renderedLayerTimes = this$1.painter.queryGpuTimers(frameLayerQueries); this$1.fire(new performance.Event('gpu-timing-layer', { layerTimes: renderedLayerTimes })); }, 50); } var somethingDirty = this._sourcesDirty || this._styleDirty || this._placementDirty; if (somethingDirty || this._repaint) { this.triggerRepaint(); } else if (!this.isMoving() && this.loaded()) { this.fire(new performance.Event('idle')); } if (this._loaded && !this._fullyLoaded && !somethingDirty) { this._fullyLoaded = true; } return this; }; Map.prototype.remove = function remove() { if (this._hash) { this._hash.remove(); } for (var i = 0, list = this._controls; i < list.length; i += 1) { var control = list[i]; control.onRemove(this); } this._controls = []; if (this._frame) { this._frame.cancel(); this._frame = null; } this._renderTaskQueue.clear(); this.painter.destroy(); this.handlers.destroy(); delete this.handlers; this.setStyle(null); if (typeof performance.window !== 'undefined') { performance.window.removeEventListener('resize', this._onWindowResize, false); performance.window.removeEventListener('orientationchange', this._onWindowResize, false); performance.window.removeEventListener('online', this._onWindowOnline, false); } var extension = this.painter.context.gl.getExtension('WEBGL_lose_context'); if (extension) { extension.loseContext(); } removeNode(this._canvasContainer); removeNode(this._controlContainer); removeNode(this._missingCSSCanary); this._container.classList.remove('mapboxgl-map'); this._removed = true; this.fire(new performance.Event('remove')); }; Map.prototype.triggerRepaint = function triggerRepaint() { var this$1 = this; if (this.style && !this._frame) { this._frame = performance.browser.frame(function (paintStartTimeStamp) { this$1._frame = null; this$1._render(paintStartTimeStamp); }); } }; Map.prototype._onWindowOnline = function _onWindowOnline() { this._update(); }; Map.prototype._onWindowResize = function _onWindowResize(event) { if (this._trackResize) { this.resize({ originalEvent: event })._update(); } }; prototypeAccessors.showTileBoundaries.get = function () { return !!this._showTileBoundaries; }; prototypeAccessors.showTileBoundaries.set = function (value) { if (this._showTileBoundaries === value) { return; } this._showTileBoundaries = value; this._update(); }; prototypeAccessors.showPadding.get = function () { return !!this._showPadding; }; prototypeAccessors.showPadding.set = function (value) { if (this._showPadding === value) { return; } this._showPadding = value; this._update(); }; prototypeAccessors.showCollisionBoxes.get = function () { return !!this._showCollisionBoxes; }; prototypeAccessors.showCollisionBoxes.set = function (value) { if (this._showCollisionBoxes === value) { return; } this._showCollisionBoxes = value; if (value) { this.style._generateCollisionBoxes(); } else { this._update(); } }; prototypeAccessors.showOverdrawInspector.get = function () { return !!this._showOverdrawInspector; }; prototypeAccessors.showOverdrawInspector.set = function (value) { if (this._showOverdrawInspector === value) { return; } this._showOverdrawInspector = value; this._update(); }; prototypeAccessors.repaint.get = function () { return !!this._repaint; }; prototypeAccessors.repaint.set = function (value) { if (this._repaint !== value) { this._repaint = value; this.triggerRepaint(); } }; prototypeAccessors.vertices.get = function () { return !!this._vertices; }; prototypeAccessors.vertices.set = function (value) { this._vertices = value; this._update(); }; Map.prototype._setCacheLimits = function _setCacheLimits(limit, checkThreshold) { performance.setCacheLimits(limit, checkThreshold); }; prototypeAccessors.version.get = function () { return performance.version; }; Object.defineProperties(Map.prototype, prototypeAccessors); return Map; }(Camera); function removeNode(node) { if (node.parentNode) { node.parentNode.removeChild(node); } } var defaultOptions$2 = { showCompass: true, showZoom: true, visualizePitch: false }; var NavigationControl = function NavigationControl(options) { var this$1 = this; this.options = performance.extend({}, defaultOptions$2, options); this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-group'); this._container.addEventListener('contextmenu', function (e) { return e.preventDefault(); }); if (this.options.showZoom) { performance.bindAll([ '_setButtonTitle', '_updateZoomButtons' ], this); this._zoomInButton = this._createButton('mapboxgl-ctrl-zoom-in', function (e) { return this$1._map.zoomIn({}, { originalEvent: e }); }); DOM.create('span', 'mapboxgl-ctrl-icon', this._zoomInButton).setAttribute('aria-hidden', true); this._zoomOutButton = this._createButton('mapboxgl-ctrl-zoom-out', function (e) { return this$1._map.zoomOut({}, { originalEvent: e }); }); DOM.create('span', 'mapboxgl-ctrl-icon', this._zoomOutButton).setAttribute('aria-hidden', true); } if (this.options.showCompass) { performance.bindAll(['_rotateCompassArrow'], this); this._compass = this._createButton('mapboxgl-ctrl-compass', function (e) { if (this$1.options.visualizePitch) { this$1._map.resetNorthPitch({}, { originalEvent: e }); } else { this$1._map.resetNorth({}, { originalEvent: e }); } }); this._compassIcon = DOM.create('span', 'mapboxgl-ctrl-icon', this._compass); this._compassIcon.setAttribute('aria-hidden', true); } }; NavigationControl.prototype._updateZoomButtons = function _updateZoomButtons() { var zoom = this._map.getZoom(); var isMax = zoom === this._map.getMaxZoom(); var isMin = zoom === this._map.getMinZoom(); this._zoomInButton.disabled = isMax; this._zoomOutButton.disabled = isMin; this._zoomInButton.setAttribute('aria-disabled', isMax.toString()); this._zoomOutButton.setAttribute('aria-disabled', isMin.toString()); }; NavigationControl.prototype._rotateCompassArrow = function _rotateCompassArrow() { var rotate = this.options.visualizePitch ? 'scale(' + 1 / Math.pow(Math.cos(this._map.transform.pitch * (Math.PI / 180)), 0.5) + ') rotateX(' + this._map.transform.pitch + 'deg) rotateZ(' + this._map.transform.angle * (180 / Math.PI) + 'deg)' : 'rotate(' + this._map.transform.angle * (180 / Math.PI) + 'deg)'; this._compassIcon.style.transform = rotate; }; NavigationControl.prototype.onAdd = function onAdd(map) { this._map = map; if (this.options.showZoom) { this._setButtonTitle(this._zoomInButton, 'ZoomIn'); this._setButtonTitle(this._zoomOutButton, 'ZoomOut'); this._map.on('zoom', this._updateZoomButtons); this._updateZoomButtons(); } if (this.options.showCompass) { this._setButtonTitle(this._compass, 'ResetBearing'); if (this.options.visualizePitch) { this._map.on('pitch', this._rotateCompassArrow); } this._map.on('rotate', this._rotateCompassArrow); this._rotateCompassArrow(); this._handler = new MouseRotateWrapper(this._map, this._compass, this.options.visualizePitch); } return this._container; }; NavigationControl.prototype.onRemove = function onRemove() { DOM.remove(this._container); if (this.options.showZoom) { this._map.off('zoom', this._updateZoomButtons); } if (this.options.showCompass) { if (this.options.visualizePitch) { this._map.off('pitch', this._rotateCompassArrow); } this._map.off('rotate', this._rotateCompassArrow); this._handler.off(); delete this._handler; } delete this._map; }; NavigationControl.prototype._createButton = function _createButton(className, fn) { var a = DOM.create('button', className, this._container); a.type = 'button'; a.addEventListener('click', fn); return a; }; NavigationControl.prototype._setButtonTitle = function _setButtonTitle(button, title) { var str = this._map._getUIString('NavigationControl.' + title); button.title = str; button.setAttribute('aria-label', str); }; var MouseRotateWrapper = function MouseRotateWrapper(map, element, pitch) { if (pitch === void 0) pitch = false; this._clickTolerance = 10; this.element = element; this.mouseRotate = new MouseRotateHandler({ clickTolerance: map.dragRotate._mouseRotate._clickTolerance }); this.map = map; if (pitch) { this.mousePitch = new MousePitchHandler({ clickTolerance: map.dragRotate._mousePitch._clickTolerance }); } performance.bindAll([ 'mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend', 'reset' ], this); DOM.addEventListener(element, 'mousedown', this.mousedown); DOM.addEventListener(element, 'touchstart', this.touchstart, { passive: false }); DOM.addEventListener(element, 'touchmove', this.touchmove); DOM.addEventListener(element, 'touchend', this.touchend); DOM.addEventListener(element, 'touchcancel', this.reset); }; MouseRotateWrapper.prototype.down = function down(e, point) { this.mouseRotate.mousedown(e, point); if (this.mousePitch) { this.mousePitch.mousedown(e, point); } DOM.disableDrag(); }; MouseRotateWrapper.prototype.move = function move(e, point) { var map = this.map; var r = this.mouseRotate.mousemoveWindow(e, point); if (r && r.bearingDelta) { map.setBearing(map.getBearing() + r.bearingDelta); } if (this.mousePitch) { var p = this.mousePitch.mousemoveWindow(e, point); if (p && p.pitchDelta) { map.setPitch(map.getPitch() + p.pitchDelta); } } }; MouseRotateWrapper.prototype.off = function off() { var element = this.element; DOM.removeEventListener(element, 'mousedown', this.mousedown); DOM.removeEventListener(element, 'touchstart', this.touchstart, { passive: false }); DOM.removeEventListener(element, 'touchmove', this.touchmove); DOM.removeEventListener(element, 'touchend', this.touchend); DOM.removeEventListener(element, 'touchcancel', this.reset); this.offTemp(); }; MouseRotateWrapper.prototype.offTemp = function offTemp() { DOM.enableDrag(); DOM.removeEventListener(performance.window, 'mousemove', this.mousemove); DOM.removeEventListener(performance.window, 'mouseup', this.mouseup); }; MouseRotateWrapper.prototype.mousedown = function mousedown(e) { this.down(performance.extend({}, e, { ctrlKey: true, preventDefault: function () { return e.preventDefault(); } }), DOM.mousePos(this.element, e)); DOM.addEventListener(performance.window, 'mousemove', this.mousemove); DOM.addEventListener(performance.window, 'mouseup', this.mouseup); }; MouseRotateWrapper.prototype.mousemove = function mousemove(e) { this.move(e, DOM.mousePos(this.element, e)); }; MouseRotateWrapper.prototype.mouseup = function mouseup(e) { this.mouseRotate.mouseupWindow(e); if (this.mousePitch) { this.mousePitch.mouseupWindow(e); } this.offTemp(); }; MouseRotateWrapper.prototype.touchstart = function touchstart(e) { if (e.targetTouches.length !== 1) { this.reset(); } else { this._startPos = this._lastPos = DOM.touchPos(this.element, e.targetTouches)[0]; this.down({ type: 'mousedown', button: 0, ctrlKey: true, preventDefault: function () { return e.preventDefault(); } }, this._startPos); } }; MouseRotateWrapper.prototype.touchmove = function touchmove(e) { if (e.targetTouches.length !== 1) { this.reset(); } else { this._lastPos = DOM.touchPos(this.element, e.targetTouches)[0]; this.move({ preventDefault: function () { return e.preventDefault(); } }, this._lastPos); } }; MouseRotateWrapper.prototype.touchend = function touchend(e) { if (e.targetTouches.length === 0 && this._startPos && this._lastPos && this._startPos.dist(this._lastPos) < this._clickTolerance) { this.element.click(); } this.reset(); }; MouseRotateWrapper.prototype.reset = function reset() { this.mouseRotate.reset(); if (this.mousePitch) { this.mousePitch.reset(); } delete this._startPos; delete this._lastPos; this.offTemp(); }; function smartWrap (lngLat, priorPos, transform) { lngLat = new performance.LngLat(lngLat.lng, lngLat.lat); if (priorPos) { var left = new performance.LngLat(lngLat.lng - 360, lngLat.lat); var right = new performance.LngLat(lngLat.lng + 360, lngLat.lat); var delta = transform.locationPoint(lngLat).distSqr(priorPos); if (transform.locationPoint(left).distSqr(priorPos) < delta) { lngLat = left; } else if (transform.locationPoint(right).distSqr(priorPos) < delta) { lngLat = right; } } while (Math.abs(lngLat.lng - transform.center.lng) > 180) { var pos = transform.locationPoint(lngLat); if (pos.x >= 0 && pos.y >= 0 && pos.x <= transform.width && pos.y <= transform.height) { break; } if (lngLat.lng > transform.center.lng) { lngLat.lng -= 360; } else { lngLat.lng += 360; } } return lngLat; } var anchorTranslate = { 'center': 'translate(-50%,-50%)', 'top': 'translate(-50%,0)', 'top-left': 'translate(0,0)', 'top-right': 'translate(-100%,0)', 'bottom': 'translate(-50%,-100%)', 'bottom-left': 'translate(0,-100%)', 'bottom-right': 'translate(-100%,-100%)', 'left': 'translate(0,-50%)', 'right': 'translate(-100%,-50%)' }; function applyAnchorClass(element, anchor, prefix) { var classList = element.classList; for (var key in anchorTranslate) { classList.remove('mapboxgl-' + prefix + '-anchor-' + key); } classList.add('mapboxgl-' + prefix + '-anchor-' + anchor); } var Marker = function (Evented) { function Marker(options, legacyOptions) { Evented.call(this); if (options instanceof performance.window.HTMLElement || legacyOptions) { options = performance.extend({ element: options }, legacyOptions); } performance.bindAll([ '_update', '_onMove', '_onUp', '_addDragHandler', '_onMapClick', '_onKeyPress' ], this); this._anchor = options && options.anchor || 'center'; this._color = options && options.color || '#3FB1CE'; this._scale = options && options.scale || 1; this._draggable = options && options.draggable || false; this._clickTolerance = options && options.clickTolerance || 0; this._isDragging = false; this._state = 'inactive'; this._rotation = options && options.rotation || 0; this._rotationAlignment = options && options.rotationAlignment || 'auto'; this._pitchAlignment = options && options.pitchAlignment && options.pitchAlignment !== 'auto' ? options.pitchAlignment : this._rotationAlignment; if (!options || !options.element) { this._defaultMarker = true; this._element = DOM.create('div'); this._element.setAttribute('aria-label', 'Map marker'); var svg = DOM.createNS('http://www.w3.org/2000/svg', 'svg'); var defaultHeight = 41; var defaultWidth = 27; svg.setAttributeNS(null, 'display', 'block'); svg.setAttributeNS(null, 'height', defaultHeight + 'px'); svg.setAttributeNS(null, 'width', defaultWidth + 'px'); svg.setAttributeNS(null, 'viewBox', '0 0 ' + defaultWidth + ' ' + defaultHeight); var markerLarge = DOM.createNS('http://www.w3.org/2000/svg', 'g'); markerLarge.setAttributeNS(null, 'stroke', 'none'); markerLarge.setAttributeNS(null, 'stroke-width', '1'); markerLarge.setAttributeNS(null, 'fill', 'none'); markerLarge.setAttributeNS(null, 'fill-rule', 'evenodd'); var page1 = DOM.createNS('http://www.w3.org/2000/svg', 'g'); page1.setAttributeNS(null, 'fill-rule', 'nonzero'); var shadow = DOM.createNS('http://www.w3.org/2000/svg', 'g'); shadow.setAttributeNS(null, 'transform', 'translate(3.0, 29.0)'); shadow.setAttributeNS(null, 'fill', '#000000'); var ellipses = [ { 'rx': '10.5', 'ry': '5.25002273' }, { 'rx': '10.5', 'ry': '5.25002273' }, { 'rx': '9.5', 'ry': '4.77275007' }, { 'rx': '8.5', 'ry': '4.29549936' }, { 'rx': '7.5', 'ry': '3.81822308' }, { 'rx': '6.5', 'ry': '3.34094679' }, { 'rx': '5.5', 'ry': '2.86367051' }, { 'rx': '4.5', 'ry': '2.38636864' } ]; for (var i = 0, list = ellipses; i < list.length; i += 1) { var data = list[i]; var ellipse = DOM.createNS('http://www.w3.org/2000/svg', 'ellipse'); ellipse.setAttributeNS(null, 'opacity', '0.04'); ellipse.setAttributeNS(null, 'cx', '10.5'); ellipse.setAttributeNS(null, 'cy', '5.80029008'); ellipse.setAttributeNS(null, 'rx', data['rx']); ellipse.setAttributeNS(null, 'ry', data['ry']); shadow.appendChild(ellipse); } var background = DOM.createNS('http://www.w3.org/2000/svg', 'g'); background.setAttributeNS(null, 'fill', this._color); var bgPath = DOM.createNS('http://www.w3.org/2000/svg', 'path'); bgPath.setAttributeNS(null, 'd', 'M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z'); background.appendChild(bgPath); var border = DOM.createNS('http://www.w3.org/2000/svg', 'g'); border.setAttributeNS(null, 'opacity', '0.25'); border.setAttributeNS(null, 'fill', '#000000'); var borderPath = DOM.createNS('http://www.w3.org/2000/svg', 'path'); borderPath.setAttributeNS(null, 'd', 'M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z'); border.appendChild(borderPath); var maki = DOM.createNS('http://www.w3.org/2000/svg', 'g'); maki.setAttributeNS(null, 'transform', 'translate(6.0, 7.0)'); maki.setAttributeNS(null, 'fill', '#FFFFFF'); var circleContainer = DOM.createNS('http://www.w3.org/2000/svg', 'g'); circleContainer.setAttributeNS(null, 'transform', 'translate(8.0, 8.0)'); var circle1 = DOM.createNS('http://www.w3.org/2000/svg', 'circle'); circle1.setAttributeNS(null, 'fill', '#000000'); circle1.setAttributeNS(null, 'opacity', '0.25'); circle1.setAttributeNS(null, 'cx', '5.5'); circle1.setAttributeNS(null, 'cy', '5.5'); circle1.setAttributeNS(null, 'r', '5.4999962'); var circle2 = DOM.createNS('http://www.w3.org/2000/svg', 'circle'); circle2.setAttributeNS(null, 'fill', '#FFFFFF'); circle2.setAttributeNS(null, 'cx', '5.5'); circle2.setAttributeNS(null, 'cy', '5.5'); circle2.setAttributeNS(null, 'r', '5.4999962'); circleContainer.appendChild(circle1); circleContainer.appendChild(circle2); page1.appendChild(shadow); page1.appendChild(background); page1.appendChild(border); page1.appendChild(maki); page1.appendChild(circleContainer); svg.appendChild(page1); svg.setAttributeNS(null, 'height', defaultHeight * this._scale + 'px'); svg.setAttributeNS(null, 'width', defaultWidth * this._scale + 'px'); this._element.appendChild(svg); this._offset = performance.Point.convert(options && options.offset || [ 0, -14 ]); } else { this._element = options.element; this._offset = performance.Point.convert(options && options.offset || [ 0, 0 ]); } this._element.classList.add('mapboxgl-marker'); this._element.addEventListener('dragstart', function (e) { e.preventDefault(); }); this._element.addEventListener('mousedown', function (e) { e.preventDefault(); }); applyAnchorClass(this._element, this._anchor, 'marker'); this._popup = null; } if (Evented) Marker.__proto__ = Evented; Marker.prototype = Object.create(Evented && Evented.prototype); Marker.prototype.constructor = Marker; Marker.prototype.addTo = function addTo(map) { this.remove(); this._map = map; map.getCanvasContainer().appendChild(this._element); map.on('move', this._update); map.on('moveend', this._update); this.setDraggable(this._draggable); this._update(); this._map.on('click', this._onMapClick); return this; }; Marker.prototype.remove = function remove() { if (this._map) { this._map.off('click', this._onMapClick); this._map.off('move', this._update); this._map.off('moveend', this._update); this._map.off('mousedown', this._addDragHandler); this._map.off('touchstart', this._addDragHandler); this._map.off('mouseup', this._onUp); this._map.off('touchend', this._onUp); this._map.off('mousemove', this._onMove); this._map.off('touchmove', this._onMove); delete this._map; } DOM.remove(this._element); if (this._popup) { this._popup.remove(); } return this; }; Marker.prototype.getLngLat = function getLngLat() { return this._lngLat; }; Marker.prototype.setLngLat = function setLngLat(lnglat) { this._lngLat = performance.LngLat.convert(lnglat); this._pos = null; if (this._popup) { this._popup.setLngLat(this._lngLat); } this._update(); return this; }; Marker.prototype.getElement = function getElement() { return this._element; }; Marker.prototype.setPopup = function setPopup(popup) { if (this._popup) { this._popup.remove(); this._popup = null; this._element.removeEventListener('keypress', this._onKeyPress); if (!this._originalTabIndex) { this._element.removeAttribute('tabindex'); } } if (popup) { if (!('offset' in popup.options)) { var markerHeight = 41 - 5.8 / 2; var markerRadius = 13.5; var linearOffset = Math.sqrt(Math.pow(markerRadius, 2) / 2); popup.options.offset = this._defaultMarker ? { 'top': [ 0, 0 ], 'top-left': [ 0, 0 ], 'top-right': [ 0, 0 ], 'bottom': [ 0, -markerHeight ], 'bottom-left': [ linearOffset, (markerHeight - markerRadius + linearOffset) * -1 ], 'bottom-right': [ -linearOffset, (markerHeight - markerRadius + linearOffset) * -1 ], 'left': [ markerRadius, (markerHeight - markerRadius) * -1 ], 'right': [ -markerRadius, (markerHeight - markerRadius) * -1 ] } : this._offset; } this._popup = popup; if (this._lngLat) { this._popup.setLngLat(this._lngLat); } this._originalTabIndex = this._element.getAttribute('tabindex'); if (!this._originalTabIndex) { this._element.setAttribute('tabindex', '0'); } this._element.addEventListener('keypress', this._onKeyPress); } return this; }; Marker.prototype._onKeyPress = function _onKeyPress(e) { var code = e.code; var legacyCode = e.charCode || e.keyCode; if (code === 'Space' || code === 'Enter' || legacyCode === 32 || legacyCode === 13) { this.togglePopup(); } }; Marker.prototype._onMapClick = function _onMapClick(e) { var targetElement = e.originalEvent.target; var element = this._element; if (this._popup && (targetElement === element || element.contains(targetElement))) { this.togglePopup(); } }; Marker.prototype.getPopup = function getPopup() { return this._popup; }; Marker.prototype.togglePopup = function togglePopup() { var popup = this._popup; if (!popup) { return this; } else if (popup.isOpen()) { popup.remove(); } else { popup.addTo(this._map); } return this; }; Marker.prototype._update = function _update(e) { if (!this._map) { return; } if (this._map.transform.renderWorldCopies) { this._lngLat = smartWrap(this._lngLat, this._pos, this._map.transform); } this._pos = this._map.project(this._lngLat)._add(this._offset); var rotation = ''; if (this._rotationAlignment === 'viewport' || this._rotationAlignment === 'auto') { rotation = 'rotateZ(' + this._rotation + 'deg)'; } else if (this._rotationAlignment === 'map') { rotation = 'rotateZ(' + (this._rotation - this._map.getBearing()) + 'deg)'; } var pitch = ''; if (this._pitchAlignment === 'viewport' || this._pitchAlignment === 'auto') { pitch = 'rotateX(0deg)'; } else if (this._pitchAlignment === 'map') { pitch = 'rotateX(' + this._map.getPitch() + 'deg)'; } if (!e || e.type === 'moveend') { this._pos = this._pos.round(); } DOM.setTransform(this._element, anchorTranslate[this._anchor] + ' translate(' + this._pos.x + 'px, ' + this._pos.y + 'px) ' + pitch + ' ' + rotation); }; Marker.prototype.getOffset = function getOffset() { return this._offset; }; Marker.prototype.setOffset = function setOffset(offset) { this._offset = performance.Point.convert(offset); this._update(); return this; }; Marker.prototype._onMove = function _onMove(e) { if (!this._isDragging) { var clickTolerance = this._clickTolerance || this._map._clickTolerance; this._isDragging = e.point.dist(this._pointerdownPos) >= clickTolerance; } if (!this._isDragging) { return; } this._pos = e.point.sub(this._positionDelta); this._lngLat = this._map.unproject(this._pos); this.setLngLat(this._lngLat); this._element.style.pointerEvents = 'none'; if (this._state === 'pending') { this._state = 'active'; this.fire(new performance.Event('dragstart')); } this.fire(new performance.Event('drag')); }; Marker.prototype._onUp = function _onUp() { this._element.style.pointerEvents = 'auto'; this._positionDelta = null; this._pointerdownPos = null; this._isDragging = false; this._map.off('mousemove', this._onMove); this._map.off('touchmove', this._onMove); if (this._state === 'active') { this.fire(new performance.Event('dragend')); } this._state = 'inactive'; }; Marker.prototype._addDragHandler = function _addDragHandler(e) { if (this._element.contains(e.originalEvent.target)) { e.preventDefault(); this._positionDelta = e.point.sub(this._pos).add(this._offset); this._pointerdownPos = e.point; this._state = 'pending'; this._map.on('mousemove', this._onMove); this._map.on('touchmove', this._onMove); this._map.once('mouseup', this._onUp); this._map.once('touchend', this._onUp); } }; Marker.prototype.setDraggable = function setDraggable(shouldBeDraggable) { this._draggable = !!shouldBeDraggable; if (this._map) { if (shouldBeDraggable) { this._map.on('mousedown', this._addDragHandler); this._map.on('touchstart', this._addDragHandler); } else { this._map.off('mousedown', this._addDragHandler); this._map.off('touchstart', this._addDragHandler); } } return this; }; Marker.prototype.isDraggable = function isDraggable() { return this._draggable; }; Marker.prototype.setRotation = function setRotation(rotation) { this._rotation = rotation || 0; this._update(); return this; }; Marker.prototype.getRotation = function getRotation() { return this._rotation; }; Marker.prototype.setRotationAlignment = function setRotationAlignment(alignment) { this._rotationAlignment = alignment || 'auto'; this._update(); return this; }; Marker.prototype.getRotationAlignment = function getRotationAlignment() { return this._rotationAlignment; }; Marker.prototype.setPitchAlignment = function setPitchAlignment(alignment) { this._pitchAlignment = alignment && alignment !== 'auto' ? alignment : this._rotationAlignment; this._update(); return this; }; Marker.prototype.getPitchAlignment = function getPitchAlignment() { return this._pitchAlignment; }; return Marker; }(performance.Evented); var defaultOptions$3 = { positionOptions: { enableHighAccuracy: false, maximumAge: 0, timeout: 6000 }, fitBoundsOptions: { maxZoom: 15 }, trackUserLocation: false, showAccuracyCircle: true, showUserLocation: true }; var supportsGeolocation; function checkGeolocationSupport(callback) { if (supportsGeolocation !== undefined) { callback(supportsGeolocation); } else if (performance.window.navigator.permissions !== undefined) { performance.window.navigator.permissions.query({ name: 'geolocation' }).then(function (p) { supportsGeolocation = p.state !== 'denied'; callback(supportsGeolocation); }); } else { supportsGeolocation = !!performance.window.navigator.geolocation; callback(supportsGeolocation); } } var numberOfWatches = 0; var noTimeout = false; var GeolocateControl = function (Evented) { function GeolocateControl(options) { Evented.call(this); this.options = performance.extend({}, defaultOptions$3, options); performance.bindAll([ '_onSuccess', '_onError', '_onZoom', '_finish', '_setupUI', '_updateCamera', '_updateMarker' ], this); } if (Evented) GeolocateControl.__proto__ = Evented; GeolocateControl.prototype = Object.create(Evented && Evented.prototype); GeolocateControl.prototype.constructor = GeolocateControl; GeolocateControl.prototype.onAdd = function onAdd(map) { this._map = map; this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-group'); checkGeolocationSupport(this._setupUI); return this._container; }; GeolocateControl.prototype.onRemove = function onRemove() { if (this._geolocationWatchID !== undefined) { performance.window.navigator.geolocation.clearWatch(this._geolocationWatchID); this._geolocationWatchID = undefined; } if (this.options.showUserLocation && this._userLocationDotMarker) { this._userLocationDotMarker.remove(); } if (this.options.showAccuracyCircle && this._accuracyCircleMarker) { this._accuracyCircleMarker.remove(); } DOM.remove(this._container); this._map.off('zoom', this._onZoom); this._map = undefined; numberOfWatches = 0; noTimeout = false; }; GeolocateControl.prototype._isOutOfMapMaxBounds = function _isOutOfMapMaxBounds(position) { var bounds = this._map.getMaxBounds(); var coordinates = position.coords; return bounds && (coordinates.longitude < bounds.getWest() || coordinates.longitude > bounds.getEast() || coordinates.latitude < bounds.getSouth() || coordinates.latitude > bounds.getNorth()); }; GeolocateControl.prototype._setErrorState = function _setErrorState() { switch (this._watchState) { case 'WAITING_ACTIVE': this._watchState = 'ACTIVE_ERROR'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error'); break; case 'ACTIVE_LOCK': this._watchState = 'ACTIVE_ERROR'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); break; case 'BACKGROUND': this._watchState = 'BACKGROUND_ERROR'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background-error'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); break; } }; GeolocateControl.prototype._onSuccess = function _onSuccess(position) { if (!this._map) { return; } if (this._isOutOfMapMaxBounds(position)) { this._setErrorState(); this.fire(new performance.Event('outofmaxbounds', position)); this._updateMarker(); this._finish(); return; } if (this.options.trackUserLocation) { this._lastKnownPosition = position; switch (this._watchState) { case 'WAITING_ACTIVE': case 'ACTIVE_LOCK': case 'ACTIVE_ERROR': this._watchState = 'ACTIVE_LOCK'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active'); break; case 'BACKGROUND': case 'BACKGROUND_ERROR': this._watchState = 'BACKGROUND'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background'); break; } } if (this.options.showUserLocation && this._watchState !== 'OFF') { this._updateMarker(position); } if (!this.options.trackUserLocation || this._watchState === 'ACTIVE_LOCK') { this._updateCamera(position); } if (this.options.showUserLocation) { this._dotElement.classList.remove('mapboxgl-user-location-dot-stale'); } this.fire(new performance.Event('geolocate', position)); this._finish(); }; GeolocateControl.prototype._updateCamera = function _updateCamera(position) { var center = new performance.LngLat(position.coords.longitude, position.coords.latitude); var radius = position.coords.accuracy; var bearing = this._map.getBearing(); var options = performance.extend({ bearing: bearing }, this.options.fitBoundsOptions); this._map.fitBounds(center.toBounds(radius), options, { geolocateSource: true }); }; GeolocateControl.prototype._updateMarker = function _updateMarker(position) { if (position) { var center = new performance.LngLat(position.coords.longitude, position.coords.latitude); this._accuracyCircleMarker.setLngLat(center).addTo(this._map); this._userLocationDotMarker.setLngLat(center).addTo(this._map); this._accuracy = position.coords.accuracy; if (this.options.showUserLocation && this.options.showAccuracyCircle) { this._updateCircleRadius(); } } else { this._userLocationDotMarker.remove(); this._accuracyCircleMarker.remove(); } }; GeolocateControl.prototype._updateCircleRadius = function _updateCircleRadius() { var y = this._map._container.clientHeight / 2; var a = this._map.unproject([ 0, y ]); var b = this._map.unproject([ 1, y ]); var metersPerPixel = a.distanceTo(b); var circleDiameter = Math.ceil(2 * this._accuracy / metersPerPixel); this._circleElement.style.width = circleDiameter + 'px'; this._circleElement.style.height = circleDiameter + 'px'; }; GeolocateControl.prototype._onZoom = function _onZoom() { if (this.options.showUserLocation && this.options.showAccuracyCircle) { this._updateCircleRadius(); } }; GeolocateControl.prototype._onError = function _onError(error) { if (!this._map) { return; } if (this.options.trackUserLocation) { if (error.code === 1) { this._watchState = 'OFF'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error'); this._geolocateButton.disabled = true; var title = this._map._getUIString('GeolocateControl.LocationNotAvailable'); this._geolocateButton.title = title; this._geolocateButton.setAttribute('aria-label', title); if (this._geolocationWatchID !== undefined) { this._clearWatch(); } } else if (error.code === 3 && noTimeout) { return; } else { this._setErrorState(); } } if (this._watchState !== 'OFF' && this.options.showUserLocation) { this._dotElement.classList.add('mapboxgl-user-location-dot-stale'); } this.fire(new performance.Event('error', error)); this._finish(); }; GeolocateControl.prototype._finish = function _finish() { if (this._timeoutId) { clearTimeout(this._timeoutId); } this._timeoutId = undefined; }; GeolocateControl.prototype._setupUI = function _setupUI(supported) { var this$1 = this; this._container.addEventListener('contextmenu', function (e) { return e.preventDefault(); }); this._geolocateButton = DOM.create('button', 'mapboxgl-ctrl-geolocate', this._container); DOM.create('span', 'mapboxgl-ctrl-icon', this._geolocateButton).setAttribute('aria-hidden', true); this._geolocateButton.type = 'button'; if (supported === false) { performance.warnOnce('Geolocation support is not available so the GeolocateControl will be disabled.'); var title = this._map._getUIString('GeolocateControl.LocationNotAvailable'); this._geolocateButton.disabled = true; this._geolocateButton.title = title; this._geolocateButton.setAttribute('aria-label', title); } else { var title$1 = this._map._getUIString('GeolocateControl.FindMyLocation'); this._geolocateButton.title = title$1; this._geolocateButton.setAttribute('aria-label', title$1); } if (this.options.trackUserLocation) { this._geolocateButton.setAttribute('aria-pressed', 'false'); this._watchState = 'OFF'; } if (this.options.showUserLocation) { this._dotElement = DOM.create('div', 'mapboxgl-user-location-dot'); this._userLocationDotMarker = new Marker(this._dotElement); this._circleElement = DOM.create('div', 'mapboxgl-user-location-accuracy-circle'); this._accuracyCircleMarker = new Marker({ element: this._circleElement, pitchAlignment: 'map' }); if (this.options.trackUserLocation) { this._watchState = 'OFF'; } this._map.on('zoom', this._onZoom); } this._geolocateButton.addEventListener('click', this.trigger.bind(this)); this._setup = true; if (this.options.trackUserLocation) { this._map.on('movestart', function (event) { var fromResize = event.originalEvent && event.originalEvent.type === 'resize'; if (!event.geolocateSource && this$1._watchState === 'ACTIVE_LOCK' && !fromResize) { this$1._watchState = 'BACKGROUND'; this$1._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background'); this$1._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active'); this$1.fire(new performance.Event('trackuserlocationend')); } }); } }; GeolocateControl.prototype.trigger = function trigger() { if (!this._setup) { performance.warnOnce('Geolocate control triggered before added to a map'); return false; } if (this.options.trackUserLocation) { switch (this._watchState) { case 'OFF': this._watchState = 'WAITING_ACTIVE'; this.fire(new performance.Event('trackuserlocationstart')); break; case 'WAITING_ACTIVE': case 'ACTIVE_LOCK': case 'ACTIVE_ERROR': case 'BACKGROUND_ERROR': numberOfWatches--; noTimeout = false; this._watchState = 'OFF'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active-error'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background'); this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background-error'); this.fire(new performance.Event('trackuserlocationend')); break; case 'BACKGROUND': this._watchState = 'ACTIVE_LOCK'; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-background'); if (this._lastKnownPosition) { this._updateCamera(this._lastKnownPosition); } this.fire(new performance.Event('trackuserlocationstart')); break; } switch (this._watchState) { case 'WAITING_ACTIVE': this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active'); break; case 'ACTIVE_LOCK': this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active'); break; case 'ACTIVE_ERROR': this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-active-error'); break; case 'BACKGROUND': this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background'); break; case 'BACKGROUND_ERROR': this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-background-error'); break; } if (this._watchState === 'OFF' && this._geolocationWatchID !== undefined) { this._clearWatch(); } else if (this._geolocationWatchID === undefined) { this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.setAttribute('aria-pressed', 'true'); numberOfWatches++; var positionOptions; if (numberOfWatches > 1) { positionOptions = { maximumAge: 600000, timeout: 0 }; noTimeout = true; } else { positionOptions = this.options.positionOptions; noTimeout = false; } this._geolocationWatchID = performance.window.navigator.geolocation.watchPosition(this._onSuccess, this._onError, positionOptions); } } else { performance.window.navigator.geolocation.getCurrentPosition(this._onSuccess, this._onError, this.options.positionOptions); this._timeoutId = setTimeout(this._finish, 10000); } return true; }; GeolocateControl.prototype._clearWatch = function _clearWatch() { performance.window.navigator.geolocation.clearWatch(this._geolocationWatchID); this._geolocationWatchID = undefined; this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting'); this._geolocateButton.setAttribute('aria-pressed', 'false'); if (this.options.showUserLocation) { this._updateMarker(null); } }; return GeolocateControl; }(performance.Evented); var defaultOptions$4 = { maxWidth: 100, unit: 'metric' }; var ScaleControl = function ScaleControl(options) { this.options = performance.extend({}, defaultOptions$4, options); performance.bindAll([ '_onMove', 'setUnit' ], this); }; ScaleControl.prototype.getDefaultPosition = function getDefaultPosition() { return 'bottom-left'; }; ScaleControl.prototype._onMove = function _onMove() { updateScale(this._map, this._container, this.options); }; ScaleControl.prototype.onAdd = function onAdd(map) { this._map = map; this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-scale', map.getContainer()); this._map.on('move', this._onMove); this._onMove(); return this._container; }; ScaleControl.prototype.onRemove = function onRemove() { DOM.remove(this._container); this._map.off('move', this._onMove); this._map = undefined; }; ScaleControl.prototype.setUnit = function setUnit(unit) { this.options.unit = unit; updateScale(this._map, this._container, this.options); }; function updateScale(map, container, options) { var maxWidth = options && options.maxWidth || 100; var y = map._container.clientHeight / 2; var left = map.unproject([ 0, y ]); var right = map.unproject([ maxWidth, y ]); var maxMeters = left.distanceTo(right); if (options && options.unit === 'imperial') { var maxFeet = 3.2808 * maxMeters; if (maxFeet > 5280) { var maxMiles = maxFeet / 5280; setScale(container, maxWidth, maxMiles, map._getUIString('ScaleControl.Miles')); } else { setScale(container, maxWidth, maxFeet, map._getUIString('ScaleControl.Feet')); } } else if (options && options.unit === 'nautical') { var maxNauticals = maxMeters / 1852; setScale(container, maxWidth, maxNauticals, map._getUIString('ScaleControl.NauticalMiles')); } else if (maxMeters >= 1000) { setScale(container, maxWidth, maxMeters / 1000, map._getUIString('ScaleControl.Kilometers')); } else { setScale(container, maxWidth, maxMeters, map._getUIString('ScaleControl.Meters')); } } function setScale(container, maxWidth, maxDistance, unit) { var distance = getRoundNum(maxDistance); var ratio = distance / maxDistance; container.style.width = maxWidth * ratio + 'px'; container.innerHTML = distance + ' ' + unit; } function getDecimalRoundNum(d) { var multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10)); return Math.round(d * multiplier) / multiplier; } function getRoundNum(num) { var pow10 = Math.pow(10, ('' + Math.floor(num)).length - 1); var d = num / pow10; d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : d >= 1 ? 1 : getDecimalRoundNum(d); return pow10 * d; } var FullscreenControl = function FullscreenControl(options) { this._fullscreen = false; if (options && options.container) { if (options.container instanceof performance.window.HTMLElement) { this._container = options.container; } else { performance.warnOnce('Full screen control \'container\' must be a DOM element.'); } } performance.bindAll([ '_onClickFullscreen', '_changeIcon' ], this); if ('onfullscreenchange' in performance.window.document) { this._fullscreenchange = 'fullscreenchange'; } else if ('onmozfullscreenchange' in performance.window.document) { this._fullscreenchange = 'mozfullscreenchange'; } else if ('onwebkitfullscreenchange' in performance.window.document) { this._fullscreenchange = 'webkitfullscreenchange'; } else if ('onmsfullscreenchange' in performance.window.document) { this._fullscreenchange = 'MSFullscreenChange'; } }; FullscreenControl.prototype.onAdd = function onAdd(map) { this._map = map; if (!this._container) { this._container = this._map.getContainer(); } this._controlContainer = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-group'); if (this._checkFullscreenSupport()) { this._setupUI(); } else { this._controlContainer.style.display = 'none'; performance.warnOnce('This device does not support fullscreen mode.'); } return this._controlContainer; }; FullscreenControl.prototype.onRemove = function onRemove() { DOM.remove(this._controlContainer); this._map = null; performance.window.document.removeEventListener(this._fullscreenchange, this._changeIcon); }; FullscreenControl.prototype._checkFullscreenSupport = function _checkFullscreenSupport() { return !!(performance.window.document.fullscreenEnabled || performance.window.document.mozFullScreenEnabled || performance.window.document.msFullscreenEnabled || performance.window.document.webkitFullscreenEnabled); }; FullscreenControl.prototype._setupUI = function _setupUI() { var button = this._fullscreenButton = DOM.create('button', 'mapboxgl-ctrl-fullscreen', this._controlContainer); DOM.create('span', 'mapboxgl-ctrl-icon', button).setAttribute('aria-hidden', true); button.type = 'button'; this._updateTitle(); this._fullscreenButton.addEventListener('click', this._onClickFullscreen); performance.window.document.addEventListener(this._fullscreenchange, this._changeIcon); }; FullscreenControl.prototype._updateTitle = function _updateTitle() { var title = this._getTitle(); this._fullscreenButton.setAttribute('aria-label', title); this._fullscreenButton.title = title; }; FullscreenControl.prototype._getTitle = function _getTitle() { return this._map._getUIString(this._isFullscreen() ? 'FullscreenControl.Exit' : 'FullscreenControl.Enter'); }; FullscreenControl.prototype._isFullscreen = function _isFullscreen() { return this._fullscreen; }; FullscreenControl.prototype._changeIcon = function _changeIcon() { var fullscreenElement = performance.window.document.fullscreenElement || performance.window.document.mozFullScreenElement || performance.window.document.webkitFullscreenElement || performance.window.document.msFullscreenElement; if (fullscreenElement === this._container !== this._fullscreen) { this._fullscreen = !this._fullscreen; this._fullscreenButton.classList.toggle('mapboxgl-ctrl-shrink'); this._fullscreenButton.classList.toggle('mapboxgl-ctrl-fullscreen'); this._updateTitle(); } }; FullscreenControl.prototype._onClickFullscreen = function _onClickFullscreen() { if (this._isFullscreen()) { if (performance.window.document.exitFullscreen) { performance.window.document.exitFullscreen(); } else if (performance.window.document.mozCancelFullScreen) { performance.window.document.mozCancelFullScreen(); } else if (performance.window.document.msExitFullscreen) { performance.window.document.msExitFullscreen(); } else if (performance.window.document.webkitCancelFullScreen) { performance.window.document.webkitCancelFullScreen(); } } else if (this._container.requestFullscreen) { this._container.requestFullscreen(); } else if (this._container.mozRequestFullScreen) { this._container.mozRequestFullScreen(); } else if (this._container.msRequestFullscreen) { this._container.msRequestFullscreen(); } else if (this._container.webkitRequestFullscreen) { this._container.webkitRequestFullscreen(); } }; var defaultOptions$5 = { closeButton: true, closeOnClick: true, focusAfterOpen: true, className: '', maxWidth: '240px' }; var focusQuerySelector = [ 'a[href]', '[tabindex]:not([tabindex=\'-1\'])', '[contenteditable]:not([contenteditable=\'false\'])', 'button:not([disabled])', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])' ].join(', '); var Popup = function (Evented) { function Popup(options) { Evented.call(this); this.options = performance.extend(Object.create(defaultOptions$5), options); performance.bindAll([ '_update', '_onClose', 'remove', '_onMouseMove', '_onMouseUp', '_onDrag' ], this); } if (Evented) Popup.__proto__ = Evented; Popup.prototype = Object.create(Evented && Evented.prototype); Popup.prototype.constructor = Popup; Popup.prototype.addTo = function addTo(map) { if (this._map) { this.remove(); } this._map = map; if (this.options.closeOnClick) { this._map.on('click', this._onClose); } if (this.options.closeOnMove) { this._map.on('move', this._onClose); } this._map.on('remove', this.remove); this._update(); this._focusFirstElement(); if (this._trackPointer) { this._map.on('mousemove', this._onMouseMove); this._map.on('mouseup', this._onMouseUp); if (this._container) { this._container.classList.add('mapboxgl-popup-track-pointer'); } this._map._canvasContainer.classList.add('mapboxgl-track-pointer'); } else { this._map.on('move', this._update); } this.fire(new performance.Event('open')); return this; }; Popup.prototype.isOpen = function isOpen() { return !!this._map; }; Popup.prototype.remove = function remove() { if (this._content) { DOM.remove(this._content); } if (this._container) { DOM.remove(this._container); delete this._container; } if (this._map) { this._map.off('move', this._update); this._map.off('move', this._onClose); this._map.off('click', this._onClose); this._map.off('remove', this.remove); this._map.off('mousemove', this._onMouseMove); this._map.off('mouseup', this._onMouseUp); this._map.off('drag', this._onDrag); delete this._map; } this.fire(new performance.Event('close')); return this; }; Popup.prototype.getLngLat = function getLngLat() { return this._lngLat; }; Popup.prototype.setLngLat = function setLngLat(lnglat) { this._lngLat = performance.LngLat.convert(lnglat); this._pos = null; this._trackPointer = false; this._update(); if (this._map) { this._map.on('move', this._update); this._map.off('mousemove', this._onMouseMove); if (this._container) { this._container.classList.remove('mapboxgl-popup-track-pointer'); } this._map._canvasContainer.classList.remove('mapboxgl-track-pointer'); } return this; }; Popup.prototype.trackPointer = function trackPointer() { this._trackPointer = true; this._pos = null; this._update(); if (this._map) { this._map.off('move', this._update); this._map.on('mousemove', this._onMouseMove); this._map.on('drag', this._onDrag); if (this._container) { this._container.classList.add('mapboxgl-popup-track-pointer'); } this._map._canvasContainer.classList.add('mapboxgl-track-pointer'); } return this; }; Popup.prototype.getElement = function getElement() { return this._container; }; Popup.prototype.setText = function setText(text) { return this.setDOMContent(performance.window.document.createTextNode(text)); }; Popup.prototype.setHTML = function setHTML(html) { var frag = performance.window.document.createDocumentFragment(); var temp = performance.window.document.createElement('body'); var child; temp.innerHTML = html; while (true) { child = temp.firstChild; if (!child) { break; } frag.appendChild(child); } return this.setDOMContent(frag); }; Popup.prototype.getMaxWidth = function getMaxWidth() { return this._container && this._container.style.maxWidth; }; Popup.prototype.setMaxWidth = function setMaxWidth(maxWidth) { this.options.maxWidth = maxWidth; this._update(); return this; }; Popup.prototype.setDOMContent = function setDOMContent(htmlNode) { if (this._content) { while (this._content.hasChildNodes()) { if (this._content.firstChild) { this._content.removeChild(this._content.firstChild); } } } else { this._content = DOM.create('div', 'mapboxgl-popup-content', this._container); } this._content.appendChild(htmlNode); this._createCloseButton(); this._update(); this._focusFirstElement(); return this; }; Popup.prototype.addClassName = function addClassName(className) { if (this._container) { this._container.classList.add(className); } }; Popup.prototype.removeClassName = function removeClassName(className) { if (this._container) { this._container.classList.remove(className); } }; Popup.prototype.setOffset = function setOffset(offset) { this.options.offset = offset; this._update(); return this; }; Popup.prototype.toggleClassName = function toggleClassName(className) { if (this._container) { return this._container.classList.toggle(className); } }; Popup.prototype._createCloseButton = function _createCloseButton() { if (this.options.closeButton) { this._closeButton = DOM.create('button', 'mapboxgl-popup-close-button', this._content); this._closeButton.type = 'button'; this._closeButton.setAttribute('aria-label', 'Close popup'); this._closeButton.innerHTML = '×'; this._closeButton.addEventListener('click', this._onClose); } }; Popup.prototype._onMouseUp = function _onMouseUp(event) { this._update(event.point); }; Popup.prototype._onMouseMove = function _onMouseMove(event) { this._update(event.point); }; Popup.prototype._onDrag = function _onDrag(event) { this._update(event.point); }; Popup.prototype._update = function _update(cursor) { var this$1 = this; var hasPosition = this._lngLat || this._trackPointer; if (!this._map || !hasPosition || !this._content) { return; } if (!this._container) { this._container = DOM.create('div', 'mapboxgl-popup', this._map.getContainer()); this._tip = DOM.create('div', 'mapboxgl-popup-tip', this._container); this._container.appendChild(this._content); if (this.options.className) { this.options.className.split(' ').forEach(function (name) { return this$1._container.classList.add(name); }); } if (this._trackPointer) { this._container.classList.add('mapboxgl-popup-track-pointer'); } } if (this.options.maxWidth && this._container.style.maxWidth !== this.options.maxWidth) { this._container.style.maxWidth = this.options.maxWidth; } if (this._map.transform.renderWorldCopies && !this._trackPointer) { this._lngLat = smartWrap(this._lngLat, this._pos, this._map.transform); } if (this._trackPointer && !cursor) { return; } var pos = this._pos = this._trackPointer && cursor ? cursor : this._map.project(this._lngLat); var anchor = this.options.anchor; var offset = normalizeOffset(this.options.offset); if (!anchor) { var width = this._container.offsetWidth; var height = this._container.offsetHeight; var anchorComponents; if (pos.y + offset.bottom.y < height) { anchorComponents = ['top']; } else if (pos.y > this._map.transform.height - height) { anchorComponents = ['bottom']; } else { anchorComponents = []; } if (pos.x < width / 2) { anchorComponents.push('left'); } else if (pos.x > this._map.transform.width - width / 2) { anchorComponents.push('right'); } if (anchorComponents.length === 0) { anchor = 'bottom'; } else { anchor = anchorComponents.join('-'); } } var offsetedPos = pos.add(offset[anchor]).round(); DOM.setTransform(this._container, anchorTranslate[anchor] + ' translate(' + offsetedPos.x + 'px,' + offsetedPos.y + 'px)'); applyAnchorClass(this._container, anchor, 'popup'); }; Popup.prototype._focusFirstElement = function _focusFirstElement() { if (!this.options.focusAfterOpen || !this._container) { return; } var firstFocusable = this._container.querySelector(focusQuerySelector); if (firstFocusable) { firstFocusable.focus(); } }; Popup.prototype._onClose = function _onClose() { this.remove(); }; return Popup; }(performance.Evented); function normalizeOffset(offset) { if (!offset) { return normalizeOffset(new performance.Point(0, 0)); } else if (typeof offset === 'number') { var cornerOffset = Math.round(Math.sqrt(0.5 * Math.pow(offset, 2))); return { 'center': new performance.Point(0, 0), 'top': new performance.Point(0, offset), 'top-left': new performance.Point(cornerOffset, cornerOffset), 'top-right': new performance.Point(-cornerOffset, cornerOffset), 'bottom': new performance.Point(0, -offset), 'bottom-left': new performance.Point(cornerOffset, -cornerOffset), 'bottom-right': new performance.Point(-cornerOffset, -cornerOffset), 'left': new performance.Point(offset, 0), 'right': new performance.Point(-offset, 0) }; } else if (offset instanceof performance.Point || Array.isArray(offset)) { var convertedOffset = performance.Point.convert(offset); return { 'center': convertedOffset, 'top': convertedOffset, 'top-left': convertedOffset, 'top-right': convertedOffset, 'bottom': convertedOffset, 'bottom-left': convertedOffset, 'bottom-right': convertedOffset, 'left': convertedOffset, 'right': convertedOffset }; } else { return { 'center': performance.Point.convert(offset['center'] || [ 0, 0 ]), 'top': performance.Point.convert(offset['top'] || [ 0, 0 ]), 'top-left': performance.Point.convert(offset['top-left'] || [ 0, 0 ]), 'top-right': performance.Point.convert(offset['top-right'] || [ 0, 0 ]), 'bottom': performance.Point.convert(offset['bottom'] || [ 0, 0 ]), 'bottom-left': performance.Point.convert(offset['bottom-left'] || [ 0, 0 ]), 'bottom-right': performance.Point.convert(offset['bottom-right'] || [ 0, 0 ]), 'left': performance.Point.convert(offset['left'] || [ 0, 0 ]), 'right': performance.Point.convert(offset['right'] || [ 0, 0 ]) }; } } var exported = { version: performance.version, supported: mapboxGlSupported, setRTLTextPlugin: performance.setRTLTextPlugin, getRTLTextPluginStatus: performance.getRTLTextPluginStatus, Map: Map, NavigationControl: NavigationControl, GeolocateControl: GeolocateControl, AttributionControl: AttributionControl, ScaleControl: ScaleControl, FullscreenControl: FullscreenControl, Popup: Popup, Marker: Marker, Style: Style, LngLat: performance.LngLat, LngLatBounds: performance.LngLatBounds, Point: performance.Point, MercatorCoordinate: performance.MercatorCoordinate, Evented: performance.Evented, config: performance.config, prewarm: prewarm, clearPrewarmedResources: clearPrewarmedResources, get accessToken() { return performance.config.ACCESS_TOKEN; }, set accessToken(token) { performance.config.ACCESS_TOKEN = token; }, get baseApiUrl() { return performance.config.API_URL; }, set baseApiUrl(url) { performance.config.API_URL = url; }, get workerCount() { return WorkerPool.workerCount; }, set workerCount(count) { WorkerPool.workerCount = count; }, get maxParallelImageRequests() { return performance.config.MAX_PARALLEL_IMAGE_REQUESTS; }, set maxParallelImageRequests(numRequests) { performance.config.MAX_PARALLEL_IMAGE_REQUESTS = numRequests; }, clearStorage: function clearStorage(callback) { performance.clearTileCache(callback); }, workerUrl: '' }; return exported; }); // return mapboxgl; }))); //# sourceMappingURL=mapbox-gl-unminified.js.map