StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
41865 lines
1.4 MiB
41865 lines
1.4 MiB
/* Mapbox GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/mapbox/mapbox-gl-js/blob/v1.3.2/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); |
|
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.3.2"; |
|
|
|
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; |
|
}; |
|
|
|
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; |
|
} |
|
|
|
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 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 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; |
|
} |
|
function storageAvailable(type) { |
|
try { |
|
var storage = self[type]; |
|
storage.setItem('_mapbox_test_', 1); |
|
storage.removeItem('_mapbox_test_'); |
|
return true; |
|
} catch (e) { |
|
return false; |
|
} |
|
} |
|
function b64EncodeUnicode(str) { |
|
return self.btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { |
|
return String.fromCharCode(Number('0x' + p1)); |
|
})); |
|
} |
|
function b64DecodeUnicode(str) { |
|
return decodeURIComponent(self.atob(str).split('').map(function (c) { |
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); |
|
}).join('')); |
|
} |
|
|
|
var now = self.performance && self.performance.now ? self.performance.now.bind(self.performance) : Date.now.bind(Date); |
|
var raf = self.requestAnimationFrame || self.mozRequestAnimationFrame || self.webkitRequestAnimationFrame || self.msRequestAnimationFrame; |
|
var cancel = self.cancelAnimationFrame || self.mozCancelAnimationFrame || self.webkitCancelAnimationFrame || self.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) { |
|
var canvas = self.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(0, 0, img.width, img.height); |
|
}, |
|
resolveURL: function resolveURL(path) { |
|
if (!linkEl) { |
|
linkEl = self.document.createElement('a'); |
|
} |
|
linkEl.href = path; |
|
return linkEl.href; |
|
}, |
|
hardwareConcurrency: self.navigator.hardwareConcurrency || 4, |
|
get devicePixelRatio() { |
|
return self.devicePixelRatio; |
|
}, |
|
get prefersReducedMotion() { |
|
if (!self.matchMedia) { |
|
return false; |
|
} |
|
if (reducedMotionQuery == null) { |
|
reducedMotionQuery = self.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 (self.document) { |
|
webpImgTest = self.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, sourceURL, tileSize) { |
|
if (this._isSkuTokenExpired()) { |
|
this._createSkuToken(); |
|
} |
|
if (!sourceURL || !isMapboxURL(sourceURL)) { |
|
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; |
|
if (config.REQUIRE_ACCESS_TOKEN && (config.ACCESS_TOKEN || this._customAccessToken) && this._skuToken) { |
|
urlObject.params.push('sku=' + this._skuToken); |
|
} |
|
return this._makeAPIURL(urlObject, this._customAccessToken); |
|
}; |
|
RequestManager.prototype.canonicalizeTileURL = function canonicalizeTileURL(url) { |
|
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.filter(function (p) { |
|
return !p.match(/^access_token=/); |
|
}); |
|
if (params.length) { |
|
result += '?' + params.join('&'); |
|
} |
|
return result; |
|
}; |
|
RequestManager.prototype.canonicalizeTileset = function canonicalizeTileset(tileJSON, sourceURL) { |
|
if (!isMapboxURL(sourceURL)) { |
|
return tileJSON.tiles || []; |
|
} |
|
var canonical = []; |
|
for (var i = 0, list = tileJSON.tiles; i < list.length; i += 1) { |
|
var url = list[i]; |
|
var canonicalUrl = this.canonicalizeTileURL(url); |
|
canonical.push(canonicalUrl); |
|
} |
|
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 (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); |
|
} |
|
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 = self.localStorage.getItem(storageKey); |
|
if (data) { |
|
this.eventData = JSON.parse(data); |
|
} |
|
var uuid = self.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 { |
|
self.localStorage.setItem(uuidKey, this.anonId); |
|
if (Object.keys(this.eventData).length >= 1) { |
|
self.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; |
|
if (config.EVENTS_URL && customAccessToken || config.ACCESS_TOKEN && Array.isArray(tileUrls) && tileUrls.some(function (url) { |
|
return isMapboxURL(url) || isMapboxHTTPURL(url); |
|
})) { |
|
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 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) { |
|
if (!self.caches) { |
|
return; |
|
} |
|
var options = { |
|
status: response.status, |
|
statusText: response.statusText, |
|
headers: new self.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 self.Response(body, options); |
|
self.caches.open(CACHE_NAME).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) { |
|
if (!self.caches) { |
|
return callback(null); |
|
} |
|
var strippedURL = stripQueryParameters(request.url); |
|
self.caches.open(CACHE_NAME).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')); |
|
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) { |
|
if (!self.caches) { |
|
return; |
|
} |
|
self.caches.open(CACHE_NAME).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 = self.caches.delete(CACHE_NAME); |
|
if (callback) { |
|
promise.catch(callback).then(function () { |
|
return callback(); |
|
}); |
|
} |
|
} |
|
function setCacheLimits(limit, checkThreshold) { |
|
cacheLimit = limit; |
|
cacheCheckThreshold = checkThreshold; |
|
} |
|
|
|
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); |
|
function isWorker() { |
|
return typeof WorkerGlobalScope !== 'undefined' && typeof self !== 'undefined' && self instanceof WorkerGlobalScope; |
|
} |
|
var getReferrer = isWorker() ? function () { |
|
return self.worker && self.worker.referrer; |
|
} : function () { |
|
return (self.location.protocol === 'blob:' ? self.parent : self).location.href; |
|
}; |
|
var isFileURL = function (url) { |
|
return /^file:/.test(url) || /^file:/.test(getReferrer()) && !/^\w+:/.test(url); |
|
}; |
|
function makeFetchRequest(requestParameters, callback) { |
|
var controller = new self.AbortController(); |
|
var request = new self.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(); |
|
self.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) { |
|
return 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 self.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 (self.fetch && self.Request && self.AbortController && self.Request.prototype.hasOwnProperty('signal')) { |
|
return makeFetchRequest(requestParameters, callback); |
|
} |
|
if (isWorker() && self.worker && self.worker.actor) { |
|
return self.worker.actor.send('getResource', requestParameters, callback); |
|
} |
|
} |
|
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 = self.document.createElement('a'); |
|
a.href = url; |
|
return a.protocol === self.document.location.protocol && a.host === self.document.location.host; |
|
} |
|
var transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; |
|
var imageQueue, numImageRequests; |
|
var resetImageRequestQueue = function () { |
|
imageQueue = []; |
|
numImageRequests = 0; |
|
}; |
|
resetImageRequestQueue(); |
|
var getImage = function (requestParameters, callback) { |
|
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) { |
|
var img = new self.Image(); |
|
var URL = self.URL || self.webkitURL; |
|
img.onload = function () { |
|
callback(null, img); |
|
URL.revokeObjectURL(img.src); |
|
}; |
|
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 self.Blob([new Uint8Array(data)], { type: 'image/png' }); |
|
img.cacheControl = cacheControl; |
|
img.expires = expires; |
|
img.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl; |
|
} |
|
}); |
|
return { |
|
cancel: function () { |
|
request.cancel(); |
|
advanceImageRequestQueue(); |
|
} |
|
}; |
|
}; |
|
var getVideo = function (urls, callback) { |
|
var video = self.document.createElement('video'); |
|
video.muted = true; |
|
video.onloadstart = function () { |
|
callback(null, video); |
|
}; |
|
for (var i = 0; i < urls.length; i++) { |
|
var s = self.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" |
|
}, |
|
"*": { |
|
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" |
|
}, |
|
"*": { |
|
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" |
|
}, |
|
"*": { |
|
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 |
|
}, |
|
tolerance: { |
|
type: "number", |
|
"default": 0.375 |
|
}, |
|
cluster: { |
|
type: "boolean", |
|
"default": false |
|
}, |
|
clusterRadius: { |
|
type: "number", |
|
"default": 50, |
|
minimum: 0 |
|
}, |
|
clusterMaxZoom: { |
|
type: "number" |
|
}, |
|
clusterProperties: { |
|
type: "*" |
|
}, |
|
lineMetrics: { |
|
type: "boolean", |
|
"default": false |
|
}, |
|
generateId: { |
|
type: "boolean", |
|
"default": false |
|
} |
|
}; |
|
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: "string", |
|
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" |
|
}, |
|
{ |
|
"!": "text-variable-anchor" |
|
} |
|
], |
|
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": { |
|
} |
|
} |
|
}; |
|
var geometry_type = { |
|
type: "enum", |
|
values: { |
|
Point: { |
|
}, |
|
LineString: { |
|
}, |
|
Polygon: { |
|
} |
|
} |
|
}; |
|
var function_stop = { |
|
type: "array", |
|
minimum: 0, |
|
maximum: 22, |
|
value: [ |
|
"number", |
|
"color" |
|
], |
|
length: 2 |
|
}; |
|
var expression = { |
|
type: "array", |
|
value: "*", |
|
minimum: 1 |
|
}; |
|
var expression_name = { |
|
type: "enum", |
|
values: { |
|
"let": { |
|
group: "Variable binding" |
|
}, |
|
"var": { |
|
group: "Variable binding" |
|
}, |
|
literal: { |
|
group: "Types" |
|
}, |
|
array: { |
|
group: "Types" |
|
}, |
|
at: { |
|
group: "Lookup" |
|
}, |
|
"case": { |
|
group: "Decision" |
|
}, |
|
match: { |
|
group: "Decision" |
|
}, |
|
coalesce: { |
|
group: "Decision" |
|
}, |
|
step: { |
|
group: "Ramps, scales, curves" |
|
}, |
|
interpolate: { |
|
group: "Ramps, scales, curves" |
|
}, |
|
"interpolate-hcl": { |
|
group: "Ramps, scales, curves" |
|
}, |
|
"interpolate-lab": { |
|
group: "Ramps, scales, curves" |
|
}, |
|
ln2: { |
|
group: "Math" |
|
}, |
|
pi: { |
|
group: "Math" |
|
}, |
|
e: { |
|
group: "Math" |
|
}, |
|
"typeof": { |
|
group: "Types" |
|
}, |
|
string: { |
|
group: "Types" |
|
}, |
|
number: { |
|
group: "Types" |
|
}, |
|
boolean: { |
|
group: "Types" |
|
}, |
|
object: { |
|
group: "Types" |
|
}, |
|
collator: { |
|
group: "Types" |
|
}, |
|
format: { |
|
group: "Types" |
|
}, |
|
"number-format": { |
|
group: "Types" |
|
}, |
|
"to-string": { |
|
group: "Types" |
|
}, |
|
"to-number": { |
|
group: "Types" |
|
}, |
|
"to-boolean": { |
|
group: "Types" |
|
}, |
|
"to-rgba": { |
|
group: "Color" |
|
}, |
|
"to-color": { |
|
group: "Types" |
|
}, |
|
rgb: { |
|
group: "Color" |
|
}, |
|
rgba: { |
|
group: "Color" |
|
}, |
|
get: { |
|
group: "Lookup" |
|
}, |
|
has: { |
|
group: "Lookup" |
|
}, |
|
length: { |
|
group: "Lookup" |
|
}, |
|
properties: { |
|
group: "Feature data" |
|
}, |
|
"feature-state": { |
|
group: "Feature data" |
|
}, |
|
"geometry-type": { |
|
group: "Feature data" |
|
}, |
|
id: { |
|
group: "Feature data" |
|
}, |
|
zoom: { |
|
group: "Zoom" |
|
}, |
|
"heatmap-density": { |
|
group: "Heatmap" |
|
}, |
|
"line-progress": { |
|
group: "Feature data" |
|
}, |
|
accumulated: { |
|
group: "Feature data" |
|
}, |
|
"+": { |
|
group: "Math" |
|
}, |
|
"*": { |
|
group: "Math" |
|
}, |
|
"-": { |
|
group: "Math" |
|
}, |
|
"/": { |
|
group: "Math" |
|
}, |
|
"%": { |
|
group: "Math" |
|
}, |
|
"^": { |
|
group: "Math" |
|
}, |
|
sqrt: { |
|
group: "Math" |
|
}, |
|
log10: { |
|
group: "Math" |
|
}, |
|
ln: { |
|
group: "Math" |
|
}, |
|
log2: { |
|
group: "Math" |
|
}, |
|
sin: { |
|
group: "Math" |
|
}, |
|
cos: { |
|
group: "Math" |
|
}, |
|
tan: { |
|
group: "Math" |
|
}, |
|
asin: { |
|
group: "Math" |
|
}, |
|
acos: { |
|
group: "Math" |
|
}, |
|
atan: { |
|
group: "Math" |
|
}, |
|
min: { |
|
group: "Math" |
|
}, |
|
max: { |
|
group: "Math" |
|
}, |
|
round: { |
|
group: "Math" |
|
}, |
|
abs: { |
|
group: "Math" |
|
}, |
|
ceil: { |
|
group: "Math" |
|
}, |
|
floor: { |
|
group: "Math" |
|
}, |
|
"==": { |
|
group: "Decision" |
|
}, |
|
"!=": { |
|
group: "Decision" |
|
}, |
|
">": { |
|
group: "Decision" |
|
}, |
|
"<": { |
|
group: "Decision" |
|
}, |
|
">=": { |
|
group: "Decision" |
|
}, |
|
"<=": { |
|
group: "Decision" |
|
}, |
|
all: { |
|
group: "Decision" |
|
}, |
|
any: { |
|
group: "Decision" |
|
}, |
|
"!": { |
|
group: "Decision" |
|
}, |
|
"is-supported-script": { |
|
group: "String" |
|
}, |
|
upcase: { |
|
group: "String" |
|
}, |
|
downcase: { |
|
group: "String" |
|
}, |
|
concat: { |
|
group: "String" |
|
}, |
|
"resolved-locale": { |
|
group: "String" |
|
} |
|
} |
|
}; |
|
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: "string", |
|
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: "string", |
|
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: "string", |
|
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 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, |
|
expression_name: expression_name, |
|
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: "string", |
|
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" |
|
} |
|
} |
|
}; |
|
|
|
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 isPrimitive(value) { |
|
return value instanceof Number || value instanceof String || value instanceof Boolean; |
|
} |
|
function unbundle(value) { |
|
if (isPrimitive(value)) { |
|
return value.valueOf(); |
|
} else { |
|
return value; |
|
} |
|
} |
|
function deepUnbundle(value) { |
|
if (Array.isArray(value)) { |
|
return value.map(deepUnbundle); |
|
} else if (value instanceof Object && !isPrimitive(value)) { |
|
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' }; |
|
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) |
|
]; |
|
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.'; |
|
} |
|
|
|
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, scale, fontStack, textColor) { |
|
this.text = text; |
|
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)]); |
|
}; |
|
Formatted.prototype.toString = function toString() { |
|
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]; |
|
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; |
|
}; |
|
|
|
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 (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 (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) { |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [this.value]; |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.args.map(function (arg) { |
|
return arg.possibleOutputs(); |
|
})); |
|
}; |
|
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 < 3) { |
|
return context.error('Expected at least two arguments.'); |
|
} |
|
if ((args.length - 1) % 2 !== 0) { |
|
return context.error('Expected an even number of arguments.'); |
|
} |
|
var sections = []; |
|
for (var i = 1; i < args.length - 1; i += 2) { |
|
var text = context.parse(args[i], 1, ValueType); |
|
if (!text) { |
|
return null; |
|
} |
|
var kind = text.type.kind; |
|
if (kind !== 'string' && kind !== 'value' && kind !== 'null') { |
|
return context.error('Formatted text type must be \'string\', \'value\', or \'null\'.'); |
|
} |
|
var options = args[i + 1]; |
|
if (typeof options !== 'object' || Array.isArray(options)) { |
|
return context.error('Format options argument must be an object.'); |
|
} |
|
var scale = null; |
|
if (options['font-scale']) { |
|
scale = context.parse(options['font-scale'], 1, NumberType); |
|
if (!scale) { |
|
return null; |
|
} |
|
} |
|
var font = null; |
|
if (options['text-font']) { |
|
font = context.parse(options['text-font'], 1, array(StringType)); |
|
if (!font) { |
|
return null; |
|
} |
|
} |
|
var textColor = null; |
|
if (options['text-color']) { |
|
textColor = context.parse(options['text-color'], 1, ColorType); |
|
if (!textColor) { |
|
return null; |
|
} |
|
} |
|
sections.push({ |
|
text: text, |
|
scale: scale, |
|
font: font, |
|
textColor: textColor |
|
}); |
|
} |
|
return new FormatExpression(sections); |
|
}; |
|
FormatExpression.prototype.evaluate = function evaluate(ctx) { |
|
return new Formatted(this.sections.map(function (section) { |
|
return new FormattedSection(toString$1(section.text.evaluate(ctx)), section.scale ? section.scale.evaluate(ctx) : null, section.font ? section.font.evaluate(ctx).join(',') : null, section.textColor ? section.textColor.evaluate(ctx) : null); |
|
})); |
|
}; |
|
FormatExpression.prototype.eachChild = function eachChild(fn) { |
|
for (var i = 0, list = this.sections; i < list.length; i += 1) { |
|
var section = list[i]; |
|
fn(section.text); |
|
if (section.scale) { |
|
fn(section.scale); |
|
} |
|
if (section.font) { |
|
fn(section.font); |
|
} |
|
if (section.textColor) { |
|
fn(section.textColor); |
|
} |
|
} |
|
}; |
|
FormatExpression.prototype.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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.text.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 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 { |
|
return toString$1(this.args[0].evaluate(ctx)); |
|
} |
|
}; |
|
Coercion.prototype.eachChild = function eachChild(fn) { |
|
this.args.forEach(fn); |
|
}; |
|
Coercion.prototype.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.args.map(function (arg) { |
|
return arg.possibleOutputs(); |
|
})); |
|
}; |
|
Coercion.prototype.serialize = function serialize() { |
|
if (this.type.kind === 'formatted') { |
|
return new FormatExpression([{ |
|
text: this.args[0], |
|
scale: null, |
|
font: null, |
|
textColor: null |
|
}]).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 = {}; |
|
}; |
|
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.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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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 |
|
]; |
|
}; |
|
|
|
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; |
|
} |
|
} |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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') && (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) && 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; |
|
} |
|
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.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.outputs.map(function (output) { |
|
return output.possibleOutputs(); |
|
})); |
|
}; |
|
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({ |
|
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({ |
|
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.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.outputs.map(function (output) { |
|
return output.possibleOutputs(); |
|
})); |
|
}; |
|
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; |
|
for (var i = 0, list = this.args; i < list.length; i += 1) { |
|
var arg = list[i]; |
|
result = arg.evaluate(ctx); |
|
if (result !== null) { |
|
break; |
|
} |
|
} |
|
return result; |
|
}; |
|
Coalesce.prototype.eachChild = function eachChild(fn) { |
|
this.args.forEach(fn); |
|
}; |
|
Coalesce.prototype.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.args.map(function (arg) { |
|
return arg.possibleOutputs(); |
|
})); |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
return this.result.possibleOutputs(); |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
At.prototype.serialize = function serialize() { |
|
return [ |
|
'at', |
|
this.index.serialize(), |
|
this.input.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.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.outputs.map(function (out) { |
|
return out.possibleOutputs(); |
|
})).concat(this.otherwise.possibleOutputs()); |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
var ref; |
|
return (ref = []).concat.apply(ref, this.branches.map(function (ref) { |
|
var _ = ref[0]; |
|
var out = ref[1]; |
|
return out.possibleOutputs(); |
|
})).concat(this.otherwise.possibleOutputs()); |
|
}; |
|
Case.prototype.serialize = function serialize() { |
|
var serialized = ['case']; |
|
this.eachChild(function (child) { |
|
serialized.push(child.serialize()); |
|
}); |
|
return serialized; |
|
}; |
|
|
|
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.possibleOutputs = function possibleOutputs() { |
|
return [ |
|
true, |
|
false |
|
]; |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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, |
|
'interpolate': Interpolate, |
|
'interpolate-hcl': Interpolate, |
|
'interpolate-lab': Interpolate, |
|
'length': Length, |
|
'let': Let, |
|
'literal': Literal, |
|
'match': Match, |
|
'number': Assertion, |
|
'number-format': NumberFormat, |
|
'object': Assertion, |
|
'step': Step, |
|
'string': Assertion, |
|
'to-boolean': Coercion, |
|
'to-color': Coercion, |
|
'to-number': Coercion, |
|
'to-string': Coercion, |
|
'var': Var |
|
}; |
|
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; |
|
} |
|
], |
|
'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 (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, formattedSection) { |
|
this._evaluator.globals = globals; |
|
this._evaluator.feature = feature; |
|
this._evaluator.featureState = featureState; |
|
this._evaluator.formattedSection = formattedSection; |
|
return this.expression.evaluate(this._evaluator); |
|
}; |
|
StyleExpression.prototype.evaluate = function evaluate(globals, feature, featureState, formattedSection) { |
|
this._evaluator.globals = globals; |
|
this._evaluator.feature = feature || null; |
|
this._evaluator.featureState = featureState || null; |
|
this._evaluator.formattedSection = formattedSection || null; |
|
try { |
|
var val = this.expression.evaluate(this._evaluator); |
|
if (val === null || val === undefined) { |
|
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, formattedSection) { |
|
return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, formattedSection); |
|
}; |
|
ZoomConstantExpression.prototype.evaluate = function evaluate(globals, feature, featureState, formattedSection) { |
|
return this._styleExpression.evaluate(globals, feature, featureState, 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, formattedSection) { |
|
return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, formattedSection); |
|
}; |
|
ZoomDependentExpression.prototype.evaluate = function evaluate(globals, feature, featureState, formattedSection) { |
|
return this._styleExpression.evaluate(globals, feature, featureState, 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 |
|
}; |
|
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') { |
|
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.possibleOutputs().indexOf(undefined) !== -1) { |
|
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': |
|
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 function () { |
|
return true; |
|
}; |
|
} |
|
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 { |
|
return function (globalProperties, feature) { |
|
return compiled.value.evaluate(globalProperties, feature); |
|
}; |
|
} |
|
} |
|
function compare(a, b) { |
|
return a < b ? -1 : a > b ? 1 : 0; |
|
} |
|
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])) : 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; |
|
} |
|
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 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 |
|
}); |
|
return errors; |
|
case 'geojson': |
|
errors = validateObject({ |
|
key: key, |
|
value: value, |
|
valueSpec: styleSpec.source_geojson, |
|
style: style, |
|
styleSpec: styleSpec |
|
}); |
|
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 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 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 []; |
|
} |
|
|
|
function validateFormatted(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 |
|
}; |
|
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) { |
|
styleSpec = 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 = self.ImageData; |
|
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('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 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 (input instanceof ArrayBuffer) { |
|
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 || input instanceof ArrayBuffer || 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 charInSupportedScript(char, canRenderRTL) { |
|
if (!canRenderRTL && (char >= 1424 && char <= 2303 || unicodeBlockLookup['Arabic Presentation Forms-A'](char) || unicodeBlockLookup['Arabic Presentation Forms-B'](char))) { |
|
return false; |
|
} |
|
if (char >= 2304 && char <= 3583 || char >= 3840 && char <= 4255 || unicodeBlockLookup['Khmer'](char)) { |
|
return false; |
|
} |
|
return true; |
|
} |
|
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 pluginRequested = false; |
|
var pluginURL = null; |
|
var foregroundLoadComplete = false; |
|
var evented = new Evented(); |
|
var _completionCallback; |
|
var registerForPluginAvailability = function (callback) { |
|
if (pluginURL) { |
|
callback({ |
|
pluginURL: pluginURL, |
|
completionCallback: _completionCallback |
|
}); |
|
} else { |
|
evented.once('pluginAvailable', callback); |
|
} |
|
return callback; |
|
}; |
|
var clearRTLTextPlugin = function () { |
|
pluginRequested = false; |
|
pluginURL = null; |
|
}; |
|
var setRTLTextPlugin = function (url, callback) { |
|
if (pluginRequested) { |
|
throw new Error('setRTLTextPlugin cannot be called multiple times.'); |
|
} |
|
pluginRequested = true; |
|
pluginURL = exported.resolveURL(url); |
|
_completionCallback = function (error) { |
|
if (error) { |
|
clearRTLTextPlugin(); |
|
if (callback) { |
|
callback(error); |
|
} |
|
} else { |
|
foregroundLoadComplete = true; |
|
} |
|
}; |
|
evented.fire(new Event('pluginAvailable', { |
|
pluginURL: pluginURL, |
|
completionCallback: _completionCallback |
|
})); |
|
}; |
|
var plugin = { |
|
applyArabicShaping: null, |
|
processBidirectionalText: null, |
|
processStyledBidirectionalText: null, |
|
isLoaded: function isLoaded() { |
|
return foregroundLoadComplete || plugin.applyArabicShaping != null; |
|
} |
|
}; |
|
|
|
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) { |
|
return this.property.possiblyEvaluate(this, parameters); |
|
}; |
|
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) { |
|
var now = parameters.now || 0; |
|
var finalValue = this.value.possiblyEvaluate(parameters); |
|
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); |
|
} else { |
|
var t = (now - this.begin) / (this.end - this.begin); |
|
return this.property.interpolate(prior.possiblyEvaluate(parameters), finalValue, easeCubicInOut(t)); |
|
} |
|
}; |
|
var Transitioning = function Transitioning(properties) { |
|
this._properties = properties; |
|
this._values = Object.create(properties.defaultTransitioningPropertyValues); |
|
}; |
|
Transitioning.prototype.possiblyEvaluate = function possiblyEvaluate(parameters) { |
|
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); |
|
} |
|
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) { |
|
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); |
|
} |
|
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) { |
|
return this.property.evaluate(this.value, this.parameters, feature, featureState); |
|
}; |
|
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) { |
|
if (value.expression.kind === 'constant' || value.expression.kind === 'camera') { |
|
return new PossiblyEvaluatedPropertyValue(this, { |
|
kind: 'constant', |
|
value: value.expression.evaluate(parameters) |
|
}, 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) { |
|
if (value.kind === 'constant') { |
|
return value.value; |
|
} else { |
|
return value.evaluate(parameters, feature, featureState); |
|
} |
|
}; |
|
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) { |
|
if (value.value === undefined) { |
|
return new PossiblyEvaluatedPropertyValue(this, { |
|
kind: 'constant', |
|
value: undefined |
|
}, parameters); |
|
} else if (value.expression.kind === 'constant') { |
|
var constantValue = value.expression.evaluate(parameters); |
|
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) { |
|
if (value.kind === 'source') { |
|
var constant = value.evaluate(globals, feature, featureState); |
|
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) { |
|
if (value.value === undefined) { |
|
return undefined; |
|
} else if (value.expression.kind === 'constant') { |
|
var constant = value.expression.evaluate(parameters); |
|
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) { |
|
return !!value.expression.evaluate(parameters); |
|
}; |
|
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 = function () { |
|
return true; |
|
}; |
|
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(); |
|
} |
|
} |
|
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) { |
|
if (parameters.getCrossfadeParameters) { |
|
this._crossfadeParameters = parameters.getCrossfadeParameters(); |
|
} |
|
if (this._unevaluatedLayout) { |
|
this.layout = this._unevaluatedLayout.possiblyEvaluate(parameters); |
|
} |
|
this.paint = this._transitioningPaint.possiblyEvaluate(parameters); |
|
}; |
|
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 StructArrayLayout8ui16 = function (StructArray) { |
|
function StructArrayLayout8ui16() { |
|
StructArray.apply(this, arguments); |
|
} |
|
if (StructArray) |
|
StructArrayLayout8ui16.__proto__ = StructArray; |
|
StructArrayLayout8ui16.prototype = Object.create(StructArray && StructArray.prototype); |
|
StructArrayLayout8ui16.prototype.constructor = StructArrayLayout8ui16; |
|
StructArrayLayout8ui16.prototype._refreshViews = function _refreshViews() { |
|
this.uint8 = new Uint8Array(this.arrayBuffer); |
|
this.uint16 = new Uint16Array(this.arrayBuffer); |
|
}; |
|
StructArrayLayout8ui16.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7) { |
|
var i = this.length; |
|
this.resize(i + 1); |
|
return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7); |
|
}; |
|
StructArrayLayout8ui16.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7) { |
|
var o2 = i * 8; |
|
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; |
|
return i; |
|
}; |
|
return StructArrayLayout8ui16; |
|
}(StructArray); |
|
StructArrayLayout8ui16.prototype.bytesPerElement = 16; |
|
register('StructArrayLayout8ui16', StructArrayLayout8ui16); |
|
var StructArrayLayout4i4ui16 = function (StructArray) { |
|
function StructArrayLayout4i4ui16() { |
|
StructArray.apply(this, arguments); |
|
} |
|
if (StructArray) |
|
StructArrayLayout4i4ui16.__proto__ = StructArray; |
|
StructArrayLayout4i4ui16.prototype = Object.create(StructArray && StructArray.prototype); |
|
StructArrayLayout4i4ui16.prototype.constructor = StructArrayLayout4i4ui16; |
|
StructArrayLayout4i4ui16.prototype._refreshViews = function _refreshViews() { |
|
this.uint8 = new Uint8Array(this.arrayBuffer); |
|
this.int16 = new Int16Array(this.arrayBuffer); |
|
this.uint16 = new Uint16Array(this.arrayBuffer); |
|
}; |
|
StructArrayLayout4i4ui16.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7) { |
|
var i = this.length; |
|
this.resize(i + 1); |
|
return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7); |
|
}; |
|
StructArrayLayout4i4ui16.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7) { |
|
var o2 = i * 8; |
|
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; |
|
return i; |
|
}; |
|
return StructArrayLayout4i4ui16; |
|
}(StructArray); |
|
StructArrayLayout4i4ui16.prototype.bytesPerElement = 16; |
|
register('StructArrayLayout4i4ui16', StructArrayLayout4i4ui16); |
|
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 StructArrayLayout6i1ul2ui2i24 = function (StructArray) { |
|
function StructArrayLayout6i1ul2ui2i24() { |
|
StructArray.apply(this, arguments); |
|
} |
|
if (StructArray) |
|
StructArrayLayout6i1ul2ui2i24.__proto__ = StructArray; |
|
StructArrayLayout6i1ul2ui2i24.prototype = Object.create(StructArray && StructArray.prototype); |
|
StructArrayLayout6i1ul2ui2i24.prototype.constructor = StructArrayLayout6i1ul2ui2i24; |
|
StructArrayLayout6i1ul2ui2i24.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); |
|
}; |
|
StructArrayLayout6i1ul2ui2i24.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) { |
|
var i = this.length; |
|
this.resize(i + 1); |
|
return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); |
|
}; |
|
StructArrayLayout6i1ul2ui2i24.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) { |
|
var o2 = i * 12; |
|
var o4 = 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; |
|
this.uint32[o4 + 3] = v6; |
|
this.uint16[o2 + 8] = v7; |
|
this.uint16[o2 + 9] = v8; |
|
this.int16[o2 + 10] = v9; |
|
this.int16[o2 + 11] = v10; |
|
return i; |
|
}; |
|
return StructArrayLayout6i1ul2ui2i24; |
|
}(StructArray); |
|
StructArrayLayout6i1ul2ui2i24.prototype.bytesPerElement = 24; |
|
register('StructArrayLayout6i1ul2ui2i24', StructArrayLayout6i1ul2ui2i24); |
|
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 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 StructArrayLayout2i2ui3ul3ui2f3ub1ul44 = function (StructArray) { |
|
function StructArrayLayout2i2ui3ul3ui2f3ub1ul44() { |
|
StructArray.apply(this, arguments); |
|
} |
|
if (StructArray) |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.__proto__ = StructArray; |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype = Object.create(StructArray && StructArray.prototype); |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype.constructor = StructArrayLayout2i2ui3ul3ui2f3ub1ul44; |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.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); |
|
}; |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { |
|
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); |
|
}; |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype.emplace = function emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { |
|
var o2 = i * 22; |
|
var o4 = i * 11; |
|
var o1 = i * 44; |
|
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; |
|
return i; |
|
}; |
|
return StructArrayLayout2i2ui3ul3ui2f3ub1ul44; |
|
}(StructArray); |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype.bytesPerElement = 44; |
|
register('StructArrayLayout2i2ui3ul3ui2f3ub1ul44', StructArrayLayout2i2ui3ul3ui2f3ub1ul44); |
|
var StructArrayLayout6i11ui1ul2f48 = function (StructArray) { |
|
function StructArrayLayout6i11ui1ul2f48() { |
|
StructArray.apply(this, arguments); |
|
} |
|
if (StructArray) |
|
StructArrayLayout6i11ui1ul2f48.__proto__ = StructArray; |
|
StructArrayLayout6i11ui1ul2f48.prototype = Object.create(StructArray && StructArray.prototype); |
|
StructArrayLayout6i11ui1ul2f48.prototype.constructor = StructArrayLayout6i11ui1ul2f48; |
|
StructArrayLayout6i11ui1ul2f48.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); |
|
}; |
|
StructArrayLayout6i11ui1ul2f48.prototype.emplaceBack = function emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) { |
|
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); |
|
}; |
|
StructArrayLayout6i11ui1ul2f48.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) { |
|
var o2 = i * 24; |
|
var o4 = i * 12; |
|
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.uint16[o2 + 6] = v6; |
|
this.uint16[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.uint32[o4 + 9] = v17; |
|
this.float32[o4 + 10] = v18; |
|
this.float32[o4 + 11] = v19; |
|
return i; |
|
}; |
|
return StructArrayLayout6i11ui1ul2f48; |
|
}(StructArray); |
|
StructArrayLayout6i11ui1ul2f48.prototype.bytesPerElement = 48; |
|
register('StructArrayLayout6i11ui1ul2f48', StructArrayLayout6i11ui1ul2f48); |
|
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 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 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 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 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 }, |
|
radius: { configurable: true }, |
|
signedDistanceFromAnchor: { configurable: true }, |
|
anchorPoint: { configurable: true } |
|
}; |
|
prototypeAccessors.anchorPointX.get = function () { |
|
return this._structArray.int16[this._pos2 + 0]; |
|
}; |
|
prototypeAccessors.anchorPointX.set = function (x) { |
|
this._structArray.int16[this._pos2 + 0] = x; |
|
}; |
|
prototypeAccessors.anchorPointY.get = function () { |
|
return this._structArray.int16[this._pos2 + 1]; |
|
}; |
|
prototypeAccessors.anchorPointY.set = function (x) { |
|
this._structArray.int16[this._pos2 + 1] = x; |
|
}; |
|
prototypeAccessors.x1.get = function () { |
|
return this._structArray.int16[this._pos2 + 2]; |
|
}; |
|
prototypeAccessors.x1.set = function (x) { |
|
this._structArray.int16[this._pos2 + 2] = x; |
|
}; |
|
prototypeAccessors.y1.get = function () { |
|
return this._structArray.int16[this._pos2 + 3]; |
|
}; |
|
prototypeAccessors.y1.set = function (x) { |
|
this._structArray.int16[this._pos2 + 3] = x; |
|
}; |
|
prototypeAccessors.x2.get = function () { |
|
return this._structArray.int16[this._pos2 + 4]; |
|
}; |
|
prototypeAccessors.x2.set = function (x) { |
|
this._structArray.int16[this._pos2 + 4] = x; |
|
}; |
|
prototypeAccessors.y2.get = function () { |
|
return this._structArray.int16[this._pos2 + 5]; |
|
}; |
|
prototypeAccessors.y2.set = function (x) { |
|
this._structArray.int16[this._pos2 + 5] = x; |
|
}; |
|
prototypeAccessors.featureIndex.get = function () { |
|
return this._structArray.uint32[this._pos4 + 3]; |
|
}; |
|
prototypeAccessors.featureIndex.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 3] = x; |
|
}; |
|
prototypeAccessors.sourceLayerIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 8]; |
|
}; |
|
prototypeAccessors.sourceLayerIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 8] = x; |
|
}; |
|
prototypeAccessors.bucketIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 9]; |
|
}; |
|
prototypeAccessors.bucketIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 9] = x; |
|
}; |
|
prototypeAccessors.radius.get = function () { |
|
return this._structArray.int16[this._pos2 + 10]; |
|
}; |
|
prototypeAccessors.radius.set = function (x) { |
|
this._structArray.int16[this._pos2 + 10] = x; |
|
}; |
|
prototypeAccessors.signedDistanceFromAnchor.get = function () { |
|
return this._structArray.int16[this._pos2 + 11]; |
|
}; |
|
prototypeAccessors.signedDistanceFromAnchor.set = function (x) { |
|
this._structArray.int16[this._pos2 + 11] = x; |
|
}; |
|
prototypeAccessors.anchorPoint.get = function () { |
|
return new pointGeometry(this.anchorPointX, this.anchorPointY); |
|
}; |
|
Object.defineProperties(CollisionBoxStruct.prototype, prototypeAccessors); |
|
return CollisionBoxStruct; |
|
}(Struct); |
|
CollisionBoxStruct.prototype.size = 24; |
|
var CollisionBoxArray = function (StructArrayLayout6i1ul2ui2i24) { |
|
function CollisionBoxArray() { |
|
StructArrayLayout6i1ul2ui2i24.apply(this, arguments); |
|
} |
|
if (StructArrayLayout6i1ul2ui2i24) |
|
CollisionBoxArray.__proto__ = StructArrayLayout6i1ul2ui2i24; |
|
CollisionBoxArray.prototype = Object.create(StructArrayLayout6i1ul2ui2i24 && StructArrayLayout6i1ul2ui2i24.prototype); |
|
CollisionBoxArray.prototype.constructor = CollisionBoxArray; |
|
CollisionBoxArray.prototype.get = function get(index) { |
|
return new CollisionBoxStruct(this, index); |
|
}; |
|
return CollisionBoxArray; |
|
}(StructArrayLayout6i1ul2ui2i24); |
|
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 } |
|
}; |
|
prototypeAccessors$1.anchorX.get = function () { |
|
return this._structArray.int16[this._pos2 + 0]; |
|
}; |
|
prototypeAccessors$1.anchorX.set = function (x) { |
|
this._structArray.int16[this._pos2 + 0] = x; |
|
}; |
|
prototypeAccessors$1.anchorY.get = function () { |
|
return this._structArray.int16[this._pos2 + 1]; |
|
}; |
|
prototypeAccessors$1.anchorY.set = function (x) { |
|
this._structArray.int16[this._pos2 + 1] = x; |
|
}; |
|
prototypeAccessors$1.glyphStartIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 2]; |
|
}; |
|
prototypeAccessors$1.glyphStartIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 2] = x; |
|
}; |
|
prototypeAccessors$1.numGlyphs.get = function () { |
|
return this._structArray.uint16[this._pos2 + 3]; |
|
}; |
|
prototypeAccessors$1.numGlyphs.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 3] = x; |
|
}; |
|
prototypeAccessors$1.vertexStartIndex.get = function () { |
|
return this._structArray.uint32[this._pos4 + 2]; |
|
}; |
|
prototypeAccessors$1.vertexStartIndex.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 2] = x; |
|
}; |
|
prototypeAccessors$1.lineStartIndex.get = function () { |
|
return this._structArray.uint32[this._pos4 + 3]; |
|
}; |
|
prototypeAccessors$1.lineStartIndex.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 3] = x; |
|
}; |
|
prototypeAccessors$1.lineLength.get = function () { |
|
return this._structArray.uint32[this._pos4 + 4]; |
|
}; |
|
prototypeAccessors$1.lineLength.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 4] = x; |
|
}; |
|
prototypeAccessors$1.segment.get = function () { |
|
return this._structArray.uint16[this._pos2 + 10]; |
|
}; |
|
prototypeAccessors$1.segment.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 10] = x; |
|
}; |
|
prototypeAccessors$1.lowerSize.get = function () { |
|
return this._structArray.uint16[this._pos2 + 11]; |
|
}; |
|
prototypeAccessors$1.lowerSize.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 11] = x; |
|
}; |
|
prototypeAccessors$1.upperSize.get = function () { |
|
return this._structArray.uint16[this._pos2 + 12]; |
|
}; |
|
prototypeAccessors$1.upperSize.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 12] = x; |
|
}; |
|
prototypeAccessors$1.lineOffsetX.get = function () { |
|
return this._structArray.float32[this._pos4 + 7]; |
|
}; |
|
prototypeAccessors$1.lineOffsetX.set = function (x) { |
|
this._structArray.float32[this._pos4 + 7] = x; |
|
}; |
|
prototypeAccessors$1.lineOffsetY.get = function () { |
|
return this._structArray.float32[this._pos4 + 8]; |
|
}; |
|
prototypeAccessors$1.lineOffsetY.set = function (x) { |
|
this._structArray.float32[this._pos4 + 8] = x; |
|
}; |
|
prototypeAccessors$1.writingMode.get = function () { |
|
return this._structArray.uint8[this._pos1 + 36]; |
|
}; |
|
prototypeAccessors$1.writingMode.set = function (x) { |
|
this._structArray.uint8[this._pos1 + 36] = x; |
|
}; |
|
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; |
|
}; |
|
Object.defineProperties(PlacedSymbolStruct.prototype, prototypeAccessors$1); |
|
return PlacedSymbolStruct; |
|
}(Struct); |
|
PlacedSymbolStruct.prototype.size = 44; |
|
var PlacedSymbolArray = function (StructArrayLayout2i2ui3ul3ui2f3ub1ul44) { |
|
function PlacedSymbolArray() { |
|
StructArrayLayout2i2ui3ul3ui2f3ub1ul44.apply(this, arguments); |
|
} |
|
if (StructArrayLayout2i2ui3ul3ui2f3ub1ul44) |
|
PlacedSymbolArray.__proto__ = StructArrayLayout2i2ui3ul3ui2f3ub1ul44; |
|
PlacedSymbolArray.prototype = Object.create(StructArrayLayout2i2ui3ul3ui2f3ub1ul44 && StructArrayLayout2i2ui3ul3ui2f3ub1ul44.prototype); |
|
PlacedSymbolArray.prototype.constructor = PlacedSymbolArray; |
|
PlacedSymbolArray.prototype.get = function get(index) { |
|
return new PlacedSymbolStruct(this, index); |
|
}; |
|
return PlacedSymbolArray; |
|
}(StructArrayLayout2i2ui3ul3ui2f3ub1ul44); |
|
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 }, |
|
key: { configurable: true }, |
|
textBoxStartIndex: { configurable: true }, |
|
textBoxEndIndex: { configurable: true }, |
|
verticalTextBoxStartIndex: { configurable: true }, |
|
verticalTextBoxEndIndex: { configurable: true }, |
|
iconBoxStartIndex: { configurable: true }, |
|
iconBoxEndIndex: { configurable: true }, |
|
featureIndex: { configurable: true }, |
|
numHorizontalGlyphVertices: { configurable: true }, |
|
numVerticalGlyphVertices: { configurable: true }, |
|
numIconVertices: { configurable: true }, |
|
crossTileID: { configurable: true }, |
|
textBoxScale: { configurable: true }, |
|
radialTextOffset: { configurable: true } |
|
}; |
|
prototypeAccessors$2.anchorX.get = function () { |
|
return this._structArray.int16[this._pos2 + 0]; |
|
}; |
|
prototypeAccessors$2.anchorX.set = function (x) { |
|
this._structArray.int16[this._pos2 + 0] = x; |
|
}; |
|
prototypeAccessors$2.anchorY.get = function () { |
|
return this._structArray.int16[this._pos2 + 1]; |
|
}; |
|
prototypeAccessors$2.anchorY.set = function (x) { |
|
this._structArray.int16[this._pos2 + 1] = x; |
|
}; |
|
prototypeAccessors$2.rightJustifiedTextSymbolIndex.get = function () { |
|
return this._structArray.int16[this._pos2 + 2]; |
|
}; |
|
prototypeAccessors$2.rightJustifiedTextSymbolIndex.set = function (x) { |
|
this._structArray.int16[this._pos2 + 2] = x; |
|
}; |
|
prototypeAccessors$2.centerJustifiedTextSymbolIndex.get = function () { |
|
return this._structArray.int16[this._pos2 + 3]; |
|
}; |
|
prototypeAccessors$2.centerJustifiedTextSymbolIndex.set = function (x) { |
|
this._structArray.int16[this._pos2 + 3] = x; |
|
}; |
|
prototypeAccessors$2.leftJustifiedTextSymbolIndex.get = function () { |
|
return this._structArray.int16[this._pos2 + 4]; |
|
}; |
|
prototypeAccessors$2.leftJustifiedTextSymbolIndex.set = function (x) { |
|
this._structArray.int16[this._pos2 + 4] = x; |
|
}; |
|
prototypeAccessors$2.verticalPlacedTextSymbolIndex.get = function () { |
|
return this._structArray.int16[this._pos2 + 5]; |
|
}; |
|
prototypeAccessors$2.verticalPlacedTextSymbolIndex.set = function (x) { |
|
this._structArray.int16[this._pos2 + 5] = x; |
|
}; |
|
prototypeAccessors$2.key.get = function () { |
|
return this._structArray.uint16[this._pos2 + 6]; |
|
}; |
|
prototypeAccessors$2.key.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 6] = x; |
|
}; |
|
prototypeAccessors$2.textBoxStartIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 7]; |
|
}; |
|
prototypeAccessors$2.textBoxStartIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 7] = x; |
|
}; |
|
prototypeAccessors$2.textBoxEndIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 8]; |
|
}; |
|
prototypeAccessors$2.textBoxEndIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 8] = x; |
|
}; |
|
prototypeAccessors$2.verticalTextBoxStartIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 9]; |
|
}; |
|
prototypeAccessors$2.verticalTextBoxStartIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 9] = x; |
|
}; |
|
prototypeAccessors$2.verticalTextBoxEndIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 10]; |
|
}; |
|
prototypeAccessors$2.verticalTextBoxEndIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 10] = x; |
|
}; |
|
prototypeAccessors$2.iconBoxStartIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 11]; |
|
}; |
|
prototypeAccessors$2.iconBoxStartIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 11] = x; |
|
}; |
|
prototypeAccessors$2.iconBoxEndIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 12]; |
|
}; |
|
prototypeAccessors$2.iconBoxEndIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 12] = x; |
|
}; |
|
prototypeAccessors$2.featureIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 13]; |
|
}; |
|
prototypeAccessors$2.featureIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 13] = x; |
|
}; |
|
prototypeAccessors$2.numHorizontalGlyphVertices.get = function () { |
|
return this._structArray.uint16[this._pos2 + 14]; |
|
}; |
|
prototypeAccessors$2.numHorizontalGlyphVertices.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 14] = x; |
|
}; |
|
prototypeAccessors$2.numVerticalGlyphVertices.get = function () { |
|
return this._structArray.uint16[this._pos2 + 15]; |
|
}; |
|
prototypeAccessors$2.numVerticalGlyphVertices.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 15] = x; |
|
}; |
|
prototypeAccessors$2.numIconVertices.get = function () { |
|
return this._structArray.uint16[this._pos2 + 16]; |
|
}; |
|
prototypeAccessors$2.numIconVertices.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 16] = x; |
|
}; |
|
prototypeAccessors$2.crossTileID.get = function () { |
|
return this._structArray.uint32[this._pos4 + 9]; |
|
}; |
|
prototypeAccessors$2.crossTileID.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 9] = x; |
|
}; |
|
prototypeAccessors$2.textBoxScale.get = function () { |
|
return this._structArray.float32[this._pos4 + 10]; |
|
}; |
|
prototypeAccessors$2.textBoxScale.set = function (x) { |
|
this._structArray.float32[this._pos4 + 10] = x; |
|
}; |
|
prototypeAccessors$2.radialTextOffset.get = function () { |
|
return this._structArray.float32[this._pos4 + 11]; |
|
}; |
|
prototypeAccessors$2.radialTextOffset.set = function (x) { |
|
this._structArray.float32[this._pos4 + 11] = x; |
|
}; |
|
Object.defineProperties(SymbolInstanceStruct.prototype, prototypeAccessors$2); |
|
return SymbolInstanceStruct; |
|
}(Struct); |
|
SymbolInstanceStruct.prototype.size = 48; |
|
var SymbolInstanceArray = function (StructArrayLayout6i11ui1ul2f48) { |
|
function SymbolInstanceArray() { |
|
StructArrayLayout6i11ui1ul2f48.apply(this, arguments); |
|
} |
|
if (StructArrayLayout6i11ui1ul2f48) |
|
SymbolInstanceArray.__proto__ = StructArrayLayout6i11ui1ul2f48; |
|
SymbolInstanceArray.prototype = Object.create(StructArrayLayout6i11ui1ul2f48 && StructArrayLayout6i11ui1ul2f48.prototype); |
|
SymbolInstanceArray.prototype.constructor = SymbolInstanceArray; |
|
SymbolInstanceArray.prototype.get = function get(index) { |
|
return new SymbolInstanceStruct(this, index); |
|
}; |
|
return SymbolInstanceArray; |
|
}(StructArrayLayout6i11ui1ul2f48); |
|
register('SymbolInstanceArray', SymbolInstanceArray); |
|
var GlyphOffsetStruct = function (Struct) { |
|
function GlyphOffsetStruct() { |
|
Struct.apply(this, arguments); |
|
} |
|
if (Struct) |
|
GlyphOffsetStruct.__proto__ = Struct; |
|
GlyphOffsetStruct.prototype = Object.create(Struct && Struct.prototype); |
|
GlyphOffsetStruct.prototype.constructor = GlyphOffsetStruct; |
|
var prototypeAccessors$3 = { offsetX: { configurable: true } }; |
|
prototypeAccessors$3.offsetX.get = function () { |
|
return this._structArray.float32[this._pos4 + 0]; |
|
}; |
|
prototypeAccessors$3.offsetX.set = function (x) { |
|
this._structArray.float32[this._pos4 + 0] = x; |
|
}; |
|
Object.defineProperties(GlyphOffsetStruct.prototype, prototypeAccessors$3); |
|
return GlyphOffsetStruct; |
|
}(Struct); |
|
GlyphOffsetStruct.prototype.size = 4; |
|
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]; |
|
}; |
|
GlyphOffsetArray.prototype.get = function get(index) { |
|
return new GlyphOffsetStruct(this, index); |
|
}; |
|
return GlyphOffsetArray; |
|
}(StructArrayLayout1f4); |
|
register('GlyphOffsetArray', GlyphOffsetArray); |
|
var SymbolLineVertexStruct = function (Struct) { |
|
function SymbolLineVertexStruct() { |
|
Struct.apply(this, arguments); |
|
} |
|
if (Struct) |
|
SymbolLineVertexStruct.__proto__ = Struct; |
|
SymbolLineVertexStruct.prototype = Object.create(Struct && Struct.prototype); |
|
SymbolLineVertexStruct.prototype.constructor = SymbolLineVertexStruct; |
|
var prototypeAccessors$4 = { |
|
x: { configurable: true }, |
|
y: { configurable: true }, |
|
tileUnitDistanceFromAnchor: { configurable: true } |
|
}; |
|
prototypeAccessors$4.x.get = function () { |
|
return this._structArray.int16[this._pos2 + 0]; |
|
}; |
|
prototypeAccessors$4.x.set = function (x) { |
|
this._structArray.int16[this._pos2 + 0] = x; |
|
}; |
|
prototypeAccessors$4.y.get = function () { |
|
return this._structArray.int16[this._pos2 + 1]; |
|
}; |
|
prototypeAccessors$4.y.set = function (x) { |
|
this._structArray.int16[this._pos2 + 1] = x; |
|
}; |
|
prototypeAccessors$4.tileUnitDistanceFromAnchor.get = function () { |
|
return this._structArray.int16[this._pos2 + 2]; |
|
}; |
|
prototypeAccessors$4.tileUnitDistanceFromAnchor.set = function (x) { |
|
this._structArray.int16[this._pos2 + 2] = x; |
|
}; |
|
Object.defineProperties(SymbolLineVertexStruct.prototype, prototypeAccessors$4); |
|
return SymbolLineVertexStruct; |
|
}(Struct); |
|
SymbolLineVertexStruct.prototype.size = 6; |
|
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]; |
|
}; |
|
SymbolLineVertexArray.prototype.get = function get(index) { |
|
return new SymbolLineVertexStruct(this, index); |
|
}; |
|
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$5 = { |
|
featureIndex: { configurable: true }, |
|
sourceLayerIndex: { configurable: true }, |
|
bucketIndex: { configurable: true } |
|
}; |
|
prototypeAccessors$5.featureIndex.get = function () { |
|
return this._structArray.uint32[this._pos4 + 0]; |
|
}; |
|
prototypeAccessors$5.featureIndex.set = function (x) { |
|
this._structArray.uint32[this._pos4 + 0] = x; |
|
}; |
|
prototypeAccessors$5.sourceLayerIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 2]; |
|
}; |
|
prototypeAccessors$5.sourceLayerIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 2] = x; |
|
}; |
|
prototypeAccessors$5.bucketIndex.get = function () { |
|
return this._structArray.uint16[this._pos2 + 3]; |
|
}; |
|
prototypeAccessors$5.bucketIndex.set = function (x) { |
|
this._structArray.uint16[this._pos2 + 3] = x; |
|
}; |
|
Object.defineProperties(FeatureIndexStruct.prototype, prototypeAccessors$5); |
|
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 FeaturePositionMap = function FeaturePositionMap() { |
|
this.ids = []; |
|
this.positions = []; |
|
this.indexed = false; |
|
}; |
|
FeaturePositionMap.prototype.add = function add(id, index, start, end) { |
|
this.ids.push(id); |
|
this.positions.push(index, start, end); |
|
}; |
|
FeaturePositionMap.prototype.getPositions = function getPositions(id) { |
|
var i = 0; |
|
var j = this.ids.length - 1; |
|
while (i < j) { |
|
var m = i + j >> 1; |
|
if (this.ids[m] >= id) { |
|
j = m; |
|
} else { |
|
i = m + 1; |
|
} |
|
} |
|
var positions = []; |
|
while (this.ids[i] === id) { |
|
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); |
|
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; |
|
}; |
|
function sort(ids, positions, left, right) { |
|
if (left >= right) { |
|
return; |
|
} |
|
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); |
|
} |
|
sort(ids, positions, left, j); |
|
sort(ids, positions, j + 1, right); |
|
} |
|
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.names = names; |
|
this.uniformNames = this.names.map(function (name) { |
|
return 'u_' + name; |
|
}); |
|
this.type = type; |
|
this.maxValue = -Infinity; |
|
}; |
|
ConstantBinder.prototype.defines = function defines() { |
|
return this.names.map(function (name) { |
|
return '#define HAS_UNIFORM_u_' + name; |
|
}); |
|
}; |
|
ConstantBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions() { |
|
}; |
|
ConstantBinder.prototype.populatePaintArray = function populatePaintArray() { |
|
}; |
|
ConstantBinder.prototype.updatePaintArray = function updatePaintArray() { |
|
}; |
|
ConstantBinder.prototype.upload = function upload() { |
|
}; |
|
ConstantBinder.prototype.destroy = function destroy() { |
|
}; |
|
ConstantBinder.prototype.setUniforms = function setUniforms(context, 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); |
|
}; |
|
ConstantBinder.serialize = function serialize$1(binder) { |
|
var value = binder.value; |
|
var names = binder.names; |
|
var type = binder.type; |
|
return { |
|
value: serialize(value), |
|
names: names, |
|
type: type |
|
}; |
|
}; |
|
ConstantBinder.deserialize = function deserialize$1(serialized) { |
|
var value = serialized.value; |
|
var names = serialized.names; |
|
var type = serialized.type; |
|
return new ConstantBinder(deserialize(value), names, type); |
|
}; |
|
var CrossFadedConstantBinder = function CrossFadedConstantBinder(value, names, type) { |
|
this.value = value; |
|
this.names = names; |
|
this.uniformNames = this.names.map(function (name) { |
|
return 'u_' + name; |
|
}); |
|
this.type = type; |
|
this.maxValue = -Infinity; |
|
this.patternPositions = { |
|
patternTo: null, |
|
patternFrom: null |
|
}; |
|
}; |
|
CrossFadedConstantBinder.prototype.defines = function defines() { |
|
return this.names.map(function (name) { |
|
return '#define HAS_UNIFORM_u_' + name; |
|
}); |
|
}; |
|
CrossFadedConstantBinder.prototype.populatePaintArray = function populatePaintArray() { |
|
}; |
|
CrossFadedConstantBinder.prototype.updatePaintArray = function updatePaintArray() { |
|
}; |
|
CrossFadedConstantBinder.prototype.upload = function upload() { |
|
}; |
|
CrossFadedConstantBinder.prototype.destroy = function destroy() { |
|
}; |
|
CrossFadedConstantBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions(posTo, posFrom) { |
|
this.patternPositions.patternTo = posTo.tlbr; |
|
this.patternPositions.patternFrom = posFrom.tlbr; |
|
}; |
|
CrossFadedConstantBinder.prototype.setUniforms = function setUniforms(context, uniform, globals, currentValue, uniformName) { |
|
var pos = this.patternPositions; |
|
if (uniformName === 'u_pattern_to' && pos.patternTo) { |
|
uniform.set(pos.patternTo); |
|
} |
|
if (uniformName === 'u_pattern_from' && pos.patternFrom) { |
|
uniform.set(pos.patternFrom); |
|
} |
|
}; |
|
CrossFadedConstantBinder.prototype.getBinding = function getBinding(context, location) { |
|
return new Uniform4f(context, location); |
|
}; |
|
var SourceExpressionBinder = function SourceExpressionBinder(expression, names, type, PaintVertexArray) { |
|
this.expression = expression; |
|
this.names = names; |
|
this.type = type; |
|
this.uniformNames = this.names.map(function (name) { |
|
return 'a_' + name; |
|
}); |
|
this.maxValue = -Infinity; |
|
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.defines = function defines() { |
|
return []; |
|
}; |
|
SourceExpressionBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions() { |
|
}; |
|
SourceExpressionBinder.prototype.populatePaintArray = function populatePaintArray(newLength, feature, imagePositions, formattedSection) { |
|
var paintArray = this.paintVertexArray; |
|
var start = paintArray.length; |
|
paintArray.reserve(newLength); |
|
var value = this.expression.evaluate(new EvaluationParameters(0), feature, {}, formattedSection); |
|
if (this.type === 'color') { |
|
var color = packColor(value); |
|
for (var i = start; i < newLength; i++) { |
|
paintArray.emplaceBack(color[0], color[1]); |
|
} |
|
} else { |
|
for (var i$1 = start; i$1 < newLength; i$1++) { |
|
paintArray.emplaceBack(value); |
|
} |
|
this.maxValue = Math.max(this.maxValue, value); |
|
} |
|
}; |
|
SourceExpressionBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState) { |
|
var paintArray = this.paintVertexArray; |
|
var value = this.expression.evaluate({ zoom: 0 }, feature, featureState); |
|
if (this.type === 'color') { |
|
var color = packColor(value); |
|
for (var i = start; i < end; i++) { |
|
paintArray.emplace(i, color[0], color[1]); |
|
} |
|
} else { |
|
for (var i$1 = start; i$1 < end; i$1++) { |
|
paintArray.emplace(i$1, value); |
|
} |
|
this.maxValue = Math.max(this.maxValue, 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(); |
|
} |
|
}; |
|
SourceExpressionBinder.prototype.setUniforms = function setUniforms(context, uniform) { |
|
uniform.set(0); |
|
}; |
|
SourceExpressionBinder.prototype.getBinding = function getBinding(context, location) { |
|
return new Uniform1f(context, location); |
|
}; |
|
var CompositeExpressionBinder = function CompositeExpressionBinder(expression, names, type, useIntegerZoom, zoom, layout) { |
|
this.expression = expression; |
|
this.names = names; |
|
this.uniformNames = this.names.map(function (name) { |
|
return 'u_' + name + '_t'; |
|
}); |
|
this.type = type; |
|
this.useIntegerZoom = useIntegerZoom; |
|
this.zoom = zoom; |
|
this.maxValue = -Infinity; |
|
var PaintVertexArray = layout; |
|
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.defines = function defines() { |
|
return []; |
|
}; |
|
CompositeExpressionBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions() { |
|
}; |
|
CompositeExpressionBinder.prototype.populatePaintArray = function populatePaintArray(newLength, feature, imagePositions, formattedSection) { |
|
var paintArray = this.paintVertexArray; |
|
var start = paintArray.length; |
|
paintArray.reserve(newLength); |
|
var min = this.expression.evaluate(new EvaluationParameters(this.zoom), feature, {}, formattedSection); |
|
var max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1), feature, {}, formattedSection); |
|
if (this.type === 'color') { |
|
var minColor = packColor(min); |
|
var maxColor = packColor(max); |
|
for (var i = start; i < newLength; i++) { |
|
paintArray.emplaceBack(minColor[0], minColor[1], maxColor[0], maxColor[1]); |
|
} |
|
} else { |
|
for (var i$1 = start; i$1 < newLength; i$1++) { |
|
paintArray.emplaceBack(min, max); |
|
} |
|
this.maxValue = Math.max(this.maxValue, min, max); |
|
} |
|
}; |
|
CompositeExpressionBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState) { |
|
var paintArray = this.paintVertexArray; |
|
var min = this.expression.evaluate({ zoom: this.zoom }, feature, featureState); |
|
var max = this.expression.evaluate({ zoom: this.zoom + 1 }, feature, featureState); |
|
if (this.type === 'color') { |
|
var minColor = packColor(min); |
|
var maxColor = packColor(max); |
|
for (var i = start; i < end; i++) { |
|
paintArray.emplace(i, minColor[0], minColor[1], maxColor[0], maxColor[1]); |
|
} |
|
} else { |
|
for (var i$1 = start; i$1 < end; i$1++) { |
|
paintArray.emplace(i$1, min, max); |
|
} |
|
this.maxValue = Math.max(this.maxValue, min, 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.interpolationFactor = function interpolationFactor(currentZoom) { |
|
if (this.useIntegerZoom) { |
|
return this.expression.interpolationFactor(Math.floor(currentZoom), this.zoom, this.zoom + 1); |
|
} else { |
|
return this.expression.interpolationFactor(currentZoom, this.zoom, this.zoom + 1); |
|
} |
|
}; |
|
CompositeExpressionBinder.prototype.setUniforms = function setUniforms(context, uniform, globals) { |
|
uniform.set(this.interpolationFactor(globals.zoom)); |
|
}; |
|
CompositeExpressionBinder.prototype.getBinding = function getBinding(context, location) { |
|
return new Uniform1f(context, location); |
|
}; |
|
var CrossFadedCompositeBinder = function CrossFadedCompositeBinder(expression, names, type, useIntegerZoom, zoom, PaintVertexArray, layerId) { |
|
this.expression = expression; |
|
this.names = names; |
|
this.type = type; |
|
this.uniformNames = this.names.map(function (name) { |
|
return 'u_' + name + '_t'; |
|
}); |
|
this.useIntegerZoom = useIntegerZoom; |
|
this.zoom = zoom; |
|
this.maxValue = -Infinity; |
|
this.layerId = layerId; |
|
this.paintVertexAttributes = names.map(function (name) { |
|
return { |
|
name: 'a_' + name, |
|
type: 'Uint16', |
|
components: 4, |
|
offset: 0 |
|
}; |
|
}); |
|
this.zoomInPaintVertexArray = new PaintVertexArray(); |
|
this.zoomOutPaintVertexArray = new PaintVertexArray(); |
|
}; |
|
CrossFadedCompositeBinder.prototype.defines = function defines() { |
|
return []; |
|
}; |
|
CrossFadedCompositeBinder.prototype.setConstantPatternPositions = function setConstantPatternPositions() { |
|
}; |
|
CrossFadedCompositeBinder.prototype.populatePaintArray = function populatePaintArray(length, feature, imagePositions) { |
|
var zoomInArray = this.zoomInPaintVertexArray; |
|
var zoomOutArray = this.zoomOutPaintVertexArray; |
|
var ref = this; |
|
var layerId = ref.layerId; |
|
var start = zoomInArray.length; |
|
zoomInArray.reserve(length); |
|
zoomOutArray.reserve(length); |
|
if (imagePositions && feature.patterns && feature.patterns[layerId]) { |
|
var ref$1 = feature.patterns[layerId]; |
|
var min = ref$1.min; |
|
var mid = ref$1.mid; |
|
var max = ref$1.max; |
|
var imageMin = imagePositions[min]; |
|
var imageMid = imagePositions[mid]; |
|
var imageMax = imagePositions[max]; |
|
if (!imageMin || !imageMid || !imageMax) { |
|
return; |
|
} |
|
for (var i = start; i < length; i++) { |
|
zoomInArray.emplaceBack(imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], imageMin.tl[0], imageMin.tl[1], imageMin.br[0], imageMin.br[1]); |
|
zoomOutArray.emplaceBack(imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], imageMax.tl[0], imageMax.tl[1], imageMax.br[0], imageMax.br[1]); |
|
} |
|
} |
|
}; |
|
CrossFadedCompositeBinder.prototype.updatePaintArray = function updatePaintArray(start, end, feature, featureState, imagePositions) { |
|
var zoomInArray = this.zoomInPaintVertexArray; |
|
var zoomOutArray = this.zoomOutPaintVertexArray; |
|
var ref = this; |
|
var layerId = ref.layerId; |
|
if (imagePositions && feature.patterns && feature.patterns[layerId]) { |
|
var ref$1 = feature.patterns[layerId]; |
|
var min = ref$1.min; |
|
var mid = ref$1.mid; |
|
var max = ref$1.max; |
|
var imageMin = imagePositions[min]; |
|
var imageMid = imagePositions[mid]; |
|
var imageMax = imagePositions[max]; |
|
if (!imageMin || !imageMid || !imageMax) { |
|
return; |
|
} |
|
for (var i = start; i < end; i++) { |
|
zoomInArray.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]); |
|
zoomOutArray.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]); |
|
} |
|
} |
|
}; |
|
CrossFadedCompositeBinder.prototype.upload = function upload(context) { |
|
if (this.zoomInPaintVertexArray && this.zoomInPaintVertexArray.arrayBuffer && this.zoomOutPaintVertexArray && this.zoomOutPaintVertexArray.arrayBuffer) { |
|
this.zoomInPaintVertexBuffer = context.createVertexBuffer(this.zoomInPaintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent); |
|
this.zoomOutPaintVertexBuffer = context.createVertexBuffer(this.zoomOutPaintVertexArray, this.paintVertexAttributes, this.expression.isStateDependent); |
|
} |
|
}; |
|
CrossFadedCompositeBinder.prototype.destroy = function destroy() { |
|
if (this.zoomOutPaintVertexBuffer) { |
|
this.zoomOutPaintVertexBuffer.destroy(); |
|
} |
|
if (this.zoomInPaintVertexBuffer) { |
|
this.zoomInPaintVertexBuffer.destroy(); |
|
} |
|
}; |
|
CrossFadedCompositeBinder.prototype.setUniforms = function setUniforms(context, uniform) { |
|
uniform.set(0); |
|
}; |
|
CrossFadedCompositeBinder.prototype.getBinding = function getBinding(context, location) { |
|
return new Uniform1f(context, location); |
|
}; |
|
var ProgramConfiguration = function ProgramConfiguration() { |
|
this.binders = {}; |
|
this.cacheKey = ''; |
|
this._buffers = []; |
|
this._featureMap = new FeaturePositionMap(); |
|
this._bufferOffset = 0; |
|
}; |
|
ProgramConfiguration.createDynamic = function createDynamic(layer, zoom, filterProperties) { |
|
var self = new ProgramConfiguration(); |
|
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 type = value.property.specification.type; |
|
var useIntegerZoom = value.property.useIntegerZoom; |
|
var isCrossFaded = value.property.specification['property-type'] === 'cross-faded' || value.property.specification['property-type'] === 'cross-faded-data-driven'; |
|
if (isCrossFaded) { |
|
if (value.value.kind === 'constant') { |
|
self.binders[property] = new CrossFadedConstantBinder(value.value.value, names, type); |
|
keys.push('/u_' + property); |
|
} else { |
|
var StructArrayLayout = layoutType(property, type, 'source'); |
|
self.binders[property] = new CrossFadedCompositeBinder(value.value, names, type, useIntegerZoom, zoom, StructArrayLayout, layer.id); |
|
keys.push('/a_' + property); |
|
} |
|
} else if (value.value.kind === 'constant') { |
|
self.binders[property] = new ConstantBinder(value.value.value, names, type); |
|
keys.push('/u_' + property); |
|
} else if (value.value.kind === 'source') { |
|
var StructArrayLayout$1 = layoutType(property, type, 'source'); |
|
self.binders[property] = new SourceExpressionBinder(value.value, names, type, StructArrayLayout$1); |
|
keys.push('/a_' + property); |
|
} else { |
|
var StructArrayLayout$2 = layoutType(property, type, 'composite'); |
|
self.binders[property] = new CompositeExpressionBinder(value.value, names, type, useIntegerZoom, zoom, StructArrayLayout$2); |
|
keys.push('/z_' + property); |
|
} |
|
} |
|
self.cacheKey = keys.sort().join(''); |
|
return self; |
|
}; |
|
ProgramConfiguration.prototype.populatePaintArrays = function populatePaintArrays(newLength, feature, index, imagePositions, formattedSection) { |
|
for (var property in this.binders) { |
|
var binder = this.binders[property]; |
|
binder.populatePaintArray(newLength, feature, imagePositions, formattedSection); |
|
} |
|
if (feature.id !== undefined) { |
|
this._featureMap.add(+feature.id, index, this._bufferOffset, newLength); |
|
} |
|
this._bufferOffset = newLength; |
|
}; |
|
ProgramConfiguration.prototype.setConstantPatternPositions = function setConstantPatternPositions(posTo, posFrom) { |
|
for (var property in this.binders) { |
|
var binder = this.binders[property]; |
|
binder.setConstantPatternPositions(posTo, posFrom); |
|
} |
|
}; |
|
ProgramConfiguration.prototype.updatePaintArrays = function updatePaintArrays(featureStates, vtLayer, layer, imagePositions) { |
|
var dirty = false; |
|
for (var id in featureStates) { |
|
var positions = this._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 ConstantBinder || binder instanceof CrossFadedConstantBinder) { |
|
continue; |
|
} |
|
if (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) { |
|
result.push.apply(result, this.binders[property].defines()); |
|
} |
|
return result; |
|
}; |
|
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]; |
|
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]); |
|
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].setUniforms(context, binding, globals, properties.get(property), name); |
|
} |
|
}; |
|
ProgramConfiguration.prototype.updatePatternPaintBuffers = function updatePatternPaintBuffers(crossfade) { |
|
var buffers = []; |
|
for (var property in this.binders) { |
|
var binder = this.binders[property]; |
|
if (binder instanceof CrossFadedCompositeBinder) { |
|
var patternVertexBuffer = crossfade.fromScale === 2 ? binder.zoomInPaintVertexBuffer : binder.zoomOutPaintVertexBuffer; |
|
if (patternVertexBuffer) { |
|
buffers.push(patternVertexBuffer); |
|
} |
|
} else if ((binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder) && binder.paintVertexBuffer) { |
|
buffers.push(binder.paintVertexBuffer); |
|
} |
|
} |
|
this._buffers = buffers; |
|
}; |
|
ProgramConfiguration.prototype.upload = function upload(context) { |
|
for (var property in this.binders) { |
|
this.binders[property].upload(context); |
|
} |
|
var buffers = []; |
|
for (var property$1 in this.binders) { |
|
var binder = this.binders[property$1]; |
|
if ((binder instanceof SourceExpressionBinder || binder instanceof CompositeExpressionBinder) && binder.paintVertexBuffer) { |
|
buffers.push(binder.paintVertexBuffer); |
|
} |
|
} |
|
this._buffers = buffers; |
|
}; |
|
ProgramConfiguration.prototype.destroy = function destroy() { |
|
for (var property in this.binders) { |
|
this.binders[property].destroy(); |
|
} |
|
}; |
|
var ProgramConfigurationSet = function ProgramConfigurationSet(layoutAttributes, 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] = ProgramConfiguration.createDynamic(layer, zoom, filterProperties); |
|
this.programConfigurations[layer.id].layoutAttributes = layoutAttributes; |
|
} |
|
this.needsUpload = false; |
|
}; |
|
ProgramConfigurationSet.prototype.populatePaintArrays = function populatePaintArrays(length, feature, index, imagePositions, formattedSection) { |
|
for (var key in this.programConfigurations) { |
|
this.programConfigurations[key].populatePaintArrays(length, feature, index, imagePositions, formattedSection); |
|
} |
|
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, 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' |
|
], |
|
'fill-pattern': [ |
|
'pattern_to', |
|
'pattern_from' |
|
], |
|
'fill-extrusion-pattern': [ |
|
'pattern_to', |
|
'pattern_from' |
|
] |
|
}; |
|
return attributeNameExceptions[property] || [property.replace(type + '-', '').replace(/-/g, '_')]; |
|
} |
|
function getLayoutException(property) { |
|
var propertyExceptions = { |
|
'line-pattern': { |
|
'source': StructArrayLayout8ui16, |
|
'composite': StructArrayLayout8ui16 |
|
}, |
|
'fill-pattern': { |
|
'source': StructArrayLayout8ui16, |
|
'composite': StructArrayLayout8ui16 |
|
}, |
|
'fill-extrusion-pattern': { |
|
'source': StructArrayLayout8ui16, |
|
'composite': StructArrayLayout8ui16 |
|
} |
|
}; |
|
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 = 8192; |
|
|
|
function createBounds(bits) { |
|
return { |
|
min: -1 * Math.pow(2, bits - 1), |
|
max: Math.pow(2, bits - 1) - 1 |
|
}; |
|
} |
|
var bounds = createBounds(15); |
|
function loadGeometry(feature) { |
|
var scale = EXTENT / 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]; |
|
point.x = Math.round(point.x * scale); |
|
point.y = Math.round(point.y * scale); |
|
if (point.x < bounds.min || point.x > bounds.max || point.y < bounds.min || point.y > bounds.max) { |
|
warnOnce('Geometry exceeds allowed extent, reduce your vector tile buffer size'); |
|
point.x = clamp(point.x, bounds.min, bounds.max); |
|
point.y = clamp(point.y, bounds.min, bounds.max); |
|
} |
|
} |
|
} |
|
return geometry; |
|
} |
|
|
|
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(members, 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) { |
|
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 index = ref.index; |
|
var sourceLayerIndex = ref.sourceLayerIndex; |
|
if (this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) { |
|
var geometry = loadGeometry(feature); |
|
var sortKey = circleSortKey ? circleSortKey.evaluate(feature, {}) : undefined; |
|
var bucketFeature = { |
|
id: feature.id, |
|
properties: feature.properties, |
|
type: feature.type, |
|
sourceLayerIndex: sourceLayerIndex, |
|
index: index, |
|
geometry: geometry, |
|
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$1 = 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$1, index$1); |
|
options.featureIndex.insert(feature$1, geometry$1, 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) { |
|
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 || y < 0 || y >= EXTENT) { |
|
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, {}); |
|
}; |
|
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 { |
|
var binders = bucket.programConfigurations.get(layer.id).binders; |
|
return binders[property].maxValue; |
|
} |
|
} |
|
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; |
|
} |
|
|
|
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 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 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 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; |
|
}; |
|
}(); |
|
|
|
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(expression, colorRampEvaluationParameter) { |
|
var colorRampData = new Uint8Array(256 * 4); |
|
var evaluationGlobals = {}; |
|
for (var i = 0, j = 0; i < 256; i++, j += 4) { |
|
evaluationGlobals[colorRampEvaluationParameter] = i / 255; |
|
var pxColor = expression.evaluate(evaluationGlobals); |
|
colorRampData[j + 0] = Math.floor(pxColor.r * 255 / pxColor.a); |
|
colorRampData[j + 1] = Math.floor(pxColor.g * 255 / pxColor.a); |
|
colorRampData[j + 2] = Math.floor(pxColor.b * 255 / pxColor.a); |
|
colorRampData[j + 3] = Math.floor(pxColor.a * 255); |
|
} |
|
return new RGBAImage({ |
|
width: 256, |
|
height: 1 |
|
}, colorRampData); |
|
} |
|
|
|
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, 'heatmapDensity'); |
|
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(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, {}); |
|
var mid = patternPropertyValue.evaluate({ zoom: zoom }, patternFeature, {}); |
|
var max = patternPropertyValue.evaluate({ zoom: zoom + 1 }, patternFeature, {}); |
|
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(members$1, 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) { |
|
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 index = ref.index; |
|
var sourceLayerIndex = ref.sourceLayerIndex; |
|
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) { |
|
continue; |
|
} |
|
var geometry = loadGeometry(feature); |
|
var sortKey = fillSortKey ? fillSortKey.evaluate(feature, {}) : undefined; |
|
var bucketFeature = { |
|
id: feature.id, |
|
properties: feature.properties, |
|
type: feature.type, |
|
sourceLayerIndex: sourceLayerIndex, |
|
index: index, |
|
geometry: geometry, |
|
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$1 = 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$1, index$1, {}); |
|
} |
|
var feature$1 = features[index$1].feature; |
|
options.featureIndex.insert(feature$1, geometry$1, 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, imagePositions) { |
|
for (var i = 0, list = this.patternFeatures; i < list.length; i += 1) { |
|
var feature = list[i]; |
|
this.addFeature(feature, feature.geometry, feature.index, 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, 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); |
|
}; |
|
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) { |
|
StyleLayer.prototype.recalculate.call(this, parameters); |
|
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(members$2, 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) { |
|
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 index = ref.index; |
|
var sourceLayerIndex = ref.sourceLayerIndex; |
|
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) { |
|
continue; |
|
} |
|
var geometry = loadGeometry(feature); |
|
var patternFeature = { |
|
sourceLayerIndex: sourceLayerIndex, |
|
index: index, |
|
geometry: geometry, |
|
properties: feature.properties, |
|
type: feature.type, |
|
patterns: {} |
|
}; |
|
if (typeof feature.id !== 'undefined') { |
|
patternFeature.id = feature.id; |
|
} |
|
if (this.hasPattern) { |
|
this.features.push(addPatternDependencies('fill-extrusion', this.layers, patternFeature, this.zoom, options)); |
|
} else { |
|
this.addFeature(patternFeature, geometry, index, {}); |
|
} |
|
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index, true); |
|
} |
|
}; |
|
FillExtrusionBucket.prototype.addFeatures = function addFeatures(options, 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, 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, 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); |
|
}; |
|
register('FillExtrusionBucket', FillExtrusionBucket, { |
|
omit: [ |
|
'layers', |
|
'features' |
|
] |
|
}); |
|
function isBoundaryEdge(p1, p2) { |
|
return p1.x === p2.x && (p1.x < 0 || p1.x > EXTENT) || p1.y === p2.y && (p1.y < 0 || p1.y > EXTENT); |
|
} |
|
function isEntirelyOutside(ring) { |
|
return ring.every(function (p) { |
|
return p.x < 0; |
|
}) || ring.every(function (p) { |
|
return p.x > EXTENT; |
|
}) || ring.every(function (p) { |
|
return p.y < 0; |
|
}) || ring.every(function (p) { |
|
return p.y > EXTENT; |
|
}); |
|
} |
|
|
|
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(a, b) { |
|
return a.x * b.x + a.y * b.y; |
|
} |
|
function getIntersectionDistance(projectedQueryGeometry, projectedFace) { |
|
if (projectedQueryGeometry.length === 1) { |
|
var a = projectedFace[0]; |
|
var b = projectedFace[1]; |
|
var c = projectedFace[3]; |
|
var p = projectedQueryGeometry[0]; |
|
var ab = b.sub(a); |
|
var ac = c.sub(a); |
|
var ap = p.sub(a); |
|
var dotABAB = dot(ab, ab); |
|
var dotABAC = dot(ab, ac); |
|
var dotACAC = dot(ac, ac); |
|
var dotAPAB = dot(ap, ab); |
|
var dotAPAC = dot(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; |
|
return a.z * u + b.z * v + c.z * w; |
|
} else { |
|
var closestDistance = Infinity; |
|
for (var i = 0, list = projectedFace; i < list.length; i += 1) { |
|
var p$1 = list[i]; |
|
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 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) { |
|
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 StructArrayLayout2i4ub8(); |
|
this.indexArray = new StructArrayLayout3ui6(); |
|
this.programConfigurations = new ProgramConfigurationSet(members$3, options.layers, options.zoom); |
|
this.segments = new SegmentVector(); |
|
this.stateDependentLayerIds = this.layers.filter(function (l) { |
|
return l.isStateDependent(); |
|
}).map(function (l) { |
|
return l.id; |
|
}); |
|
}; |
|
LineBucket.prototype.populate = function populate(features, options) { |
|
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 index = ref.index; |
|
var sourceLayerIndex = ref.sourceLayerIndex; |
|
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) { |
|
continue; |
|
} |
|
var geometry = loadGeometry(feature); |
|
var sortKey = lineSortKey ? lineSortKey.evaluate(feature, {}) : undefined; |
|
var bucketFeature = { |
|
id: feature.id, |
|
properties: feature.properties, |
|
type: feature.type, |
|
sourceLayerIndex: sourceLayerIndex, |
|
index: index, |
|
geometry: geometry, |
|
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$1 = 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$1, index$1, {}); |
|
} |
|
var feature$1 = features[index$1].feature; |
|
options.featureIndex.insert(feature$1, geometry$1, 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, imagePositions) { |
|
for (var i = 0, list = this.patternFeatures; i < list.length; i += 1) { |
|
var feature = list[i]; |
|
this.addFeature(feature, feature.geometry, feature.index, 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) { |
|
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.addFeature = function addFeature(feature, geometry, index, 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'); |
|
for (var i = 0, list = geometry; i < list.length; i += 1) { |
|
var line = list[i]; |
|
this.addLine(line, feature, join, cap, miterLimit, roundLimit, index, imagePositions); |
|
} |
|
}; |
|
LineBucket.prototype.addLine = function addLine(vertices, feature, join, cap, miterLimit, roundLimit, index, imagePositions) { |
|
this.distance = 0; |
|
this.scaledDistance = 0; |
|
this.totalDistance = 0; |
|
if (!!feature.properties && feature.properties.hasOwnProperty('mapbox_clip_start') && feature.properties.hasOwnProperty('mapbox_clip_end')) { |
|
this.clipStart = +feature.properties['mapbox_clip_start']; |
|
this.clipEnd = +feature.properties['mapbox_clip_end']; |
|
for (var i = 0; i < vertices.length - 1; i++) { |
|
this.totalDistance += vertices[i].dist(vertices[i + 1]); |
|
} |
|
} |
|
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 = SHARP_CORNER_OFFSET * (EXTENT / (512 * this.overscaling)); |
|
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 = isPolygon && i$1 === len - 1 ? vertices[first + 1] : 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; |
|
} |
|
} |
|
} |
|
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions); |
|
}; |
|
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 linesofar = this.scaledDistance * 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 | (linesofar & 63) << 2, linesofar >> 6); |
|
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.updateDistance = function updateDistance(prev, next) { |
|
this.distance += prev.dist(next); |
|
this.scaledDistance = this.totalDistance > 0 ? (this.clipStart + (this.clipEnd - this.clipStart) * this.distance / this.totalDistance) * (MAX_LINE_DISTANCE - 1) : this.distance; |
|
}; |
|
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); |
|
} |
|
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') { |
|
this._updateGradient(); |
|
} |
|
}; |
|
LineStyleLayer.prototype._updateGradient = function _updateGradient() { |
|
var expression = this._transitionablePaint._values['line-gradient'].value.expression; |
|
this.gradient = renderColorRamp(expression, 'lineProgress'); |
|
this.gradientTexture = null; |
|
}; |
|
LineStyleLayer.prototype.recalculate = function recalculate(parameters) { |
|
StyleLayer.prototype.recalculate.call(this, parameters); |
|
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' |
|
} |
|
]); |
|
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' |
|
}, |
|
{ |
|
type: 'Int16', |
|
name: 'radius' |
|
}, |
|
{ |
|
type: 'Int16', |
|
name: 'signedDistanceFromAnchor' |
|
} |
|
]); |
|
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: 'Int16' |
|
}, |
|
{ |
|
name: 'a_anchor_pos', |
|
components: 2, |
|
type: 'Int16' |
|
}, |
|
{ |
|
name: 'a_extrude', |
|
components: 2, |
|
type: 'Int16' |
|
} |
|
], 4); |
|
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' |
|
} |
|
]); |
|
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: '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: 'featureIndex' |
|
}, |
|
{ |
|
type: 'Uint16', |
|
name: 'numHorizontalGlyphVertices' |
|
}, |
|
{ |
|
type: 'Uint16', |
|
name: 'numVerticalGlyphVertices' |
|
}, |
|
{ |
|
type: 'Uint16', |
|
name: 'numIconVertices' |
|
}, |
|
{ |
|
type: 'Uint32', |
|
name: 'crossTileID' |
|
}, |
|
{ |
|
type: 'Float32', |
|
name: 'textBoxScale' |
|
}, |
|
{ |
|
type: 'Float32', |
|
name: 'radialTextOffset' |
|
} |
|
]); |
|
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 WritingMode = { |
|
horizontal: 1, |
|
vertical: 2, |
|
horizontalOnly: 3 |
|
}; |
|
var TaggedString = function TaggedString() { |
|
this.text = ''; |
|
this.sectionIndex = []; |
|
this.sections = []; |
|
}; |
|
TaggedString.fromFeature = function fromFeature(text, defaultFontStack) { |
|
var result = new TaggedString(); |
|
for (var i = 0; i < text.sections.length; i++) { |
|
var section = text.sections[i]; |
|
result.sections.push({ |
|
scale: section.scale || 1, |
|
fontStack: section.fontStack || defaultFontStack |
|
}); |
|
result.text += section.text; |
|
for (var j = 0; j < section.text.length; j++) { |
|
result.sectionIndex.push(i); |
|
} |
|
} |
|
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); |
|
}; |
|
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, glyphs, defaultFontStack, maxWidth, lineHeight, textAnchor, textJustify, spacing, translate, writingMode, allowVerticalPlacement) { |
|
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, glyphs)); |
|
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, glyphs)); |
|
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, glyphs)); |
|
} |
|
var positionedGlyphs = []; |
|
var shaping = { |
|
positionedGlyphs: positionedGlyphs, |
|
text: logicalInput.toString(), |
|
top: translate[1], |
|
bottom: translate[1], |
|
left: translate[0], |
|
right: translate[0], |
|
writingMode: writingMode, |
|
lineCount: lines.length, |
|
yOffset: -17 |
|
}; |
|
shapeLines(shaping, glyphs, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement); |
|
if (!positionedGlyphs.length) { |
|
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 determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap) { |
|
var totalWidth = 0; |
|
for (var index = 0; index < logicalInput.length(); index++) { |
|
var section = logicalInput.getSection(index); |
|
var positions = glyphMap[section.fontStack]; |
|
var glyph = positions && positions[logicalInput.getCharCode(index)]; |
|
if (!glyph) { |
|
continue; |
|
} |
|
totalWidth += glyph.metrics.advance * section.scale + spacing; |
|
} |
|
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) { |
|
if (!maxWidth) { |
|
return []; |
|
} |
|
if (!logicalInput) { |
|
return []; |
|
} |
|
var potentialLineBreaks = []; |
|
var targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap); |
|
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); |
|
var positions = glyphMap[section.fontStack]; |
|
var glyph = positions && positions[codePoint]; |
|
if (glyph && !whitespace[codePoint]) { |
|
currentX += glyph.metrics.advance * section.scale + spacing; |
|
} |
|
if (i < logicalInput.length() - 1) { |
|
var ideographicBreak = charAllowsIdeographicBreaking(codePoint); |
|
if (breakable[codePoint] || ideographicBreak) { |
|
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, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement) { |
|
var x = 0; |
|
var y = shaping.yOffset; |
|
var maxLineLength = 0; |
|
var positionedGlyphs = shaping.positionedGlyphs; |
|
var justify = textJustify === 'right' ? 1 : textJustify === 'left' ? 0 : 0.5; |
|
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(); |
|
if (!line.length()) { |
|
y += lineHeight; |
|
continue; |
|
} |
|
var lineStartIndex = positionedGlyphs.length; |
|
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 = (lineMaxScale - section.scale) * 24; |
|
var positions = glyphMap[section.fontStack]; |
|
var glyph = positions && positions[codePoint]; |
|
if (!glyph) { |
|
continue; |
|
} |
|
if (writingMode === WritingMode.horizontal || !allowVerticalPlacement && !charHasUprightVerticalOrientation(codePoint) || allowVerticalPlacement && (whitespace[codePoint] || charInComplexShapingScript(codePoint))) { |
|
positionedGlyphs.push({ |
|
glyph: codePoint, |
|
x: x, |
|
y: y + baselineOffset, |
|
vertical: false, |
|
scale: section.scale, |
|
fontStack: section.fontStack, |
|
sectionIndex: sectionIndex |
|
}); |
|
x += glyph.metrics.advance * section.scale + spacing; |
|
} else { |
|
positionedGlyphs.push({ |
|
glyph: codePoint, |
|
x: x, |
|
y: y + baselineOffset, |
|
vertical: true, |
|
scale: section.scale, |
|
fontStack: section.fontStack, |
|
sectionIndex: sectionIndex |
|
}); |
|
x += ONE_EM * section.scale + spacing; |
|
} |
|
} |
|
if (positionedGlyphs.length !== lineStartIndex) { |
|
var lineLength = x - spacing; |
|
maxLineLength = Math.max(lineLength, maxLineLength); |
|
justifyLine(positionedGlyphs, glyphMap, lineStartIndex, positionedGlyphs.length - 1, justify); |
|
} |
|
x = 0; |
|
y += lineHeight * lineMaxScale; |
|
} |
|
var ref = getAnchorAlignment(textAnchor); |
|
var horizontalAlign = ref.horizontalAlign; |
|
var verticalAlign = ref.verticalAlign; |
|
align$1(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, lines.length); |
|
var height = y - shaping.yOffset; |
|
shaping.top += -verticalAlign * height; |
|
shaping.bottom = shaping.top + height; |
|
shaping.left += -horizontalAlign * maxLineLength; |
|
shaping.right = shaping.left + maxLineLength; |
|
} |
|
function justifyLine(positionedGlyphs, glyphMap, start, end, justify) { |
|
if (!justify) { |
|
return; |
|
} |
|
var lastPositionedGlyph = positionedGlyphs[end]; |
|
var positions = glyphMap[lastPositionedGlyph.fontStack]; |
|
var glyph = positions && positions[lastPositionedGlyph.glyph]; |
|
if (glyph) { |
|
var lastAdvance = glyph.metrics.advance * lastPositionedGlyph.scale; |
|
var lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify; |
|
for (var j = start; j <= end; j++) { |
|
positionedGlyphs[j].x -= lineIndent; |
|
} |
|
} |
|
} |
|
function align$1(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, lineCount) { |
|
var shiftX = (justify - horizontalAlign) * maxLineLength; |
|
var shiftY = (-verticalAlign * lineCount + 0.5) * lineHeight; |
|
for (var j = 0; j < positionedGlyphs.length; j++) { |
|
positionedGlyphs[j].x += shiftX; |
|
positionedGlyphs[j].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 |
|
}; |
|
} |
|
|
|
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 = 256; |
|
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({ |
|
getSizeData: getSizeData, |
|
evaluateSizeForFeature: evaluateSizeForFeature, |
|
evaluateSizeForZoom: evaluateSizeForZoom, |
|
SIZE_PACK_FACTOR: SIZE_PACK_FACTOR |
|
}); |
|
|
|
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) { |
|
array.emplaceBack(anchorX, anchorY, Math.round(ox * 32), Math.round(oy * 32), tx, ty, sizeVertex ? sizeVertex[0] : 0, sizeVertex ? sizeVertex[1] : 0); |
|
} |
|
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); |
|
} |
|
var SymbolBuffers = function SymbolBuffers(programConfigurations) { |
|
this.layoutVertexArray = new StructArrayLayout4i4ui16(); |
|
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.upload = function upload(context, dynamicIndexBuffer, upload$1, update) { |
|
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.hasPaintOverrides = false; |
|
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.sortFeaturesByKey = zOrder !== 'viewport-y' && sortKey.constantOr(1) !== undefined; |
|
var zOrderByViewportY = zOrder === 'viewport-y' || zOrder === 'auto' && !this.sortFeaturesByKey; |
|
this.sortFeaturesByY = zOrderByViewportY && (layout.get('text-allow-overlap') || layout.get('icon-allow-overlap') || layout.get('text-ignore-placement') || layout.get('icon-ignore-placement')); |
|
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() { |
|
var layout = this.layers[0].layout; |
|
this.hasPaintOverrides = SymbolStyleLayer.hasPaintOverrides(layout); |
|
this.text = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, function (property) { |
|
return /^text/.test(property); |
|
})); |
|
this.icon = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, function (property) { |
|
return /^icon/.test(property); |
|
})); |
|
this.collisionBox = new CollisionBuffers(StructArrayLayout2i2i2i12, collisionBoxLayout.members, StructArrayLayout2ui4); |
|
this.collisionCircle = new CollisionBuffers(StructArrayLayout2i2i2i12, collisionCircleLayout.members, StructArrayLayout3ui6); |
|
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) { |
|
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.toString().length > 0) && (textFont.value.kind !== 'constant' || textFont.value.value.length > 0); |
|
var hasIcon = iconImage.value.kind !== 'constant' || iconImage.value.value && iconImage.value.value.length > 0; |
|
var symbolSortKey = layout.get('symbol-sort-key'); |
|
this.features = []; |
|
if (!hasText && !hasIcon) { |
|
return; |
|
} |
|
var icons = options.iconDependencies; |
|
var stacks = options.glyphDependencies; |
|
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 index = ref.index; |
|
var sourceLayerIndex = ref.sourceLayerIndex; |
|
if (!layer._featureFilter(globalProperties, feature)) { |
|
continue; |
|
} |
|
var text = void 0; |
|
if (hasText) { |
|
var resolvedTokens = layer.getValueAndResolveTokens('text-field', feature); |
|
text = transformText$1(resolvedTokens instanceof Formatted ? resolvedTokens : Formatted.fromString(resolvedTokens), layer, feature); |
|
} |
|
var icon = void 0; |
|
if (hasIcon) { |
|
icon = layer.getValueAndResolveTokens('icon-image', feature); |
|
} |
|
if (!text && !icon) { |
|
continue; |
|
} |
|
var sortKey = this.sortFeaturesByKey ? symbolSortKey.evaluate(feature, {}) : undefined; |
|
var symbolFeature = { |
|
text: text, |
|
icon: icon, |
|
index: index, |
|
sourceLayerIndex: sourceLayerIndex, |
|
geometry: loadGeometry(feature), |
|
properties: feature.properties, |
|
type: vectorTileFeatureTypes$2[feature.type], |
|
sortKey: sortKey |
|
}; |
|
if (typeof feature.id !== 'undefined') { |
|
symbolFeature.id = feature.id; |
|
} |
|
this.features.push(symbolFeature); |
|
if (icon) { |
|
icons[icon] = true; |
|
} |
|
if (text) { |
|
var fontStack = textFont.evaluate(feature, {}).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]; |
|
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); |
|
} |
|
} |
|
} |
|
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; |
|
}; |
|
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.collisionBox.upload(context); |
|
this.collisionCircle.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.destroy = function destroy() { |
|
this.text.destroy(); |
|
this.icon.destroy(); |
|
this.collisionBox.destroy(); |
|
this.collisionCircle.destroy(); |
|
}; |
|
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) { |
|
var this$1 = this; |
|
var indexArray = arrays.indexArray; |
|
var layoutVertexArray = arrays.layoutVertexArray; |
|
var dynamicLayoutVertexArray = arrays.dynamicLayoutVertexArray; |
|
var segment = arrays.segments.prepareSegment(4 * quads.length, arrays.layoutVertexArray, arrays.indexArray, feature.sortKey); |
|
var glyphOffsetArrayStart = this.glyphOffsetArray.length; |
|
var vertexStartIndex = segment.vertexLength; |
|
var angle = this.allowVerticalPlacement && writingMode === WritingMode.vertical ? Math.PI / 2 : 0; |
|
var addSymbol = function (symbol) { |
|
var tl = symbol.tl, tr = symbol.tr, bl = symbol.bl, br = symbol.br, tex = symbol.tex; |
|
var index = segment.vertexLength; |
|
var y = symbol.glyphOffset[1]; |
|
addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex); |
|
addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex); |
|
addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex); |
|
addVertex$1(layoutVertexArray, labelAnchor.x, labelAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex); |
|
addDynamicAttributes(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$1.glyphOffsetArray.emplaceBack(symbol.glyphOffset[0]); |
|
}; |
|
if (feature.text && feature.text.sections) { |
|
var sections = feature.text.sections; |
|
if (this.hasPaintOverrides) { |
|
var currentSectionIndex; |
|
var populatePaintArrayForSection = function (sectionIndex, lastSection) { |
|
if (currentSectionIndex !== undefined && (currentSectionIndex !== sectionIndex || lastSection)) { |
|
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {}, sections[currentSectionIndex]); |
|
} |
|
currentSectionIndex = sectionIndex; |
|
}; |
|
for (var i = 0, list = quads; i < list.length; i += 1) { |
|
var symbol = list[i]; |
|
populatePaintArrayForSection(symbol.sectionIndex, false); |
|
addSymbol(symbol); |
|
} |
|
populatePaintArrayForSection(currentSectionIndex, true); |
|
} else { |
|
for (var i$1 = 0, list$1 = quads; i$1 < list$1.length; i$1 += 1) { |
|
var symbol$1 = list$1[i$1]; |
|
addSymbol(symbol$1); |
|
} |
|
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {}, sections[0]); |
|
} |
|
} else { |
|
for (var i$2 = 0, list$2 = quads; i$2 < list$2.length; i$2 += 1) { |
|
var symbol$2 = list$2[i$2]; |
|
addSymbol(symbol$2); |
|
} |
|
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {}); |
|
} |
|
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); |
|
}; |
|
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, isCircle) { |
|
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; |
|
if (isCircle) { |
|
var indexArray = arrays.indexArray; |
|
indexArray.emplaceBack(index, index + 1, index + 2); |
|
indexArray.emplaceBack(index, index + 2, index + 3); |
|
segment.primitiveLength += 2; |
|
} else { |
|
var indexArray$1 = arrays.indexArray; |
|
indexArray$1.emplaceBack(index, index + 1); |
|
indexArray$1.emplaceBack(index + 1, index + 2); |
|
indexArray$1.emplaceBack(index + 2, index + 3); |
|
indexArray$1.emplaceBack(index + 3, index); |
|
segment.primitiveLength += 4; |
|
} |
|
}; |
|
SymbolBucket.prototype.addDebugCollisionBoxes = function addDebugCollisionBoxes(startIndex, endIndex, symbolInstance) { |
|
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; |
|
var isCircle = box.radius > 0; |
|
this.addCollisionDebugVertices(x1, y1, x2, y2, isCircle ? this.collisionCircle : this.collisionBox, box.anchorPoint, symbolInstance, isCircle); |
|
} |
|
}; |
|
SymbolBucket.prototype.generateCollisionDebugBuffers = function generateCollisionDebugBuffers() { |
|
for (var i = 0; i < this.symbolInstances.length; i++) { |
|
var symbolInstance = this.symbolInstances.get(i); |
|
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance); |
|
this.addDebugCollisionBoxes(symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance); |
|
this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance); |
|
} |
|
}; |
|
SymbolBucket.prototype._deserializeCollisionBoxesForSymbol = function _deserializeCollisionBoxesForSymbol(collisionBoxArray, textStartIndex, textEndIndex, verticalTextStartIndex, verticalTextEndIndex, iconStartIndex, iconEndIndex) { |
|
var collisionArrays = {}; |
|
for (var k = textStartIndex; k < textEndIndex; k++) { |
|
var box = collisionBoxArray.get(k); |
|
if (box.radius === 0) { |
|
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; |
|
} else { |
|
if (!collisionArrays.textCircles) { |
|
collisionArrays.textCircles = []; |
|
collisionArrays.textFeatureIndex = box.featureIndex; |
|
} |
|
var used = 1; |
|
collisionArrays.textCircles.push(box.anchorPointX, box.anchorPointY, box.radius, box.signedDistanceFromAnchor, used); |
|
} |
|
} |
|
for (var k$1 = verticalTextStartIndex; k$1 < verticalTextEndIndex; k$1++) { |
|
var box$1 = collisionBoxArray.get(k$1); |
|
if (box$1.radius === 0) { |
|
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); |
|
if (box$2.radius === 0) { |
|
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; |
|
} |
|
} |
|
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)); |
|
} |
|
}; |
|
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.hasCollisionBoxData = function hasCollisionBoxData() { |
|
return this.collisionBox.segments.get().length > 0; |
|
}; |
|
SymbolBucket.prototype.hasCollisionCircleData = function hasCollisionCircleData() { |
|
return this.collisionCircle.segments.get().length > 0; |
|
}; |
|
SymbolBucket.prototype.addIndicesForPlacedTextSymbol = function addIndicesForPlacedTextSymbol(placedTextSymbolIndex) { |
|
var placedSymbol = this.text.placedSymbolArray.get(placedTextSymbolIndex); |
|
var endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4; |
|
for (var vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) { |
|
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); |
|
this.text.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.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.addIndicesForPlacedTextSymbol(index); |
|
} |
|
}); |
|
if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) { |
|
this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex); |
|
} |
|
var placedIcon = this.icon.placedSymbolArray.get(i); |
|
if (placedIcon.numGlyphs) { |
|
var vertexIndex = placedIcon.vertexStartIndex; |
|
this.icon.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); |
|
this.icon.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); |
|
} |
|
} |
|
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.possibleOutputs = function possibleOutputs() { |
|
return [undefined]; |
|
}; |
|
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) { |
|
StyleLayer.prototype.recalculate.call(this, parameters); |
|
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) { |
|
var value = this.layout.get(name).evaluate(feature, {}); |
|
var unevaluated = this._unevaluatedLayout._values[name]; |
|
if (!unevaluated.isDataDriven() && !isExpression(unevaluated.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; |
|
}; |
|
SymbolStyleLayer.hasPaintOverrides = function hasPaintOverrides(layout) { |
|
for (var i = 0, list = properties$6.paint.overridableProperties; i < list.length; i += 1) { |
|
var overridable = list[i]; |
|
if (SymbolStyleLayer.hasPaintOverride(layout, overridable)) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
}; |
|
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); |
|
} |
|
} |
|
|
|
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 padding = 1; |
|
var ImagePosition = function ImagePosition(paddedRect, ref) { |
|
var pixelRatio = ref.pixelRatio; |
|
var version = ref.version; |
|
this.paddedRect = paddedRect; |
|
this.pixelRatio = pixelRatio; |
|
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 + padding, |
|
this.paddedRect.y + padding |
|
]; |
|
}; |
|
prototypeAccessors.br.get = function () { |
|
return [ |
|
this.paddedRect.x + this.paddedRect.w - padding, |
|
this.paddedRect.y + this.paddedRect.h - padding |
|
]; |
|
}; |
|
prototypeAccessors.tlbr.get = function () { |
|
return this.tl.concat(this.br); |
|
}; |
|
prototypeAccessors.displaySize.get = function () { |
|
return [ |
|
(this.paddedRect.w - padding * 2) / this.pixelRatio, |
|
(this.paddedRect.h - 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 + padding, |
|
y: bin.y + 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 + padding, y = bin$1.y + 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 * padding, |
|
h: src.data.height + 2 * 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 HTMLImageElement = self.HTMLImageElement; |
|
var HTMLCanvasElement = self.HTMLCanvasElement; |
|
var HTMLVideoElement = self.HTMLVideoElement; |
|
var ImageData$1 = self.ImageData; |
|
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) { |
|
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) { |
|
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 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; |
|
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, str = readUtf8(this.buf, this.pos, end); |
|
this.pos = end; |
|
return str; |
|
}, |
|
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 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; |
|
|
|
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); |
|
} |
|
} |
|
}; |
|
|
|
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); |
|
}; |
|
Actor.prototype.send = function send(type, data, callback, targetMapId) { |
|
var this$1 = this; |
|
var id = Math.round(Math.random() * 1000000000000000000).toString(36).substring(0, 10); |
|
if (callback) { |
|
this.callbacks[id] = callback; |
|
} |
|
var buffers = []; |
|
this.target.postMessage({ |
|
id: id, |
|
type: type, |
|
hasCallback: !!callback, |
|
targetMapId: targetMapId, |
|
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: '<cancel>', |
|
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 === '<cancel>') { |
|
delete this.tasks[id]; |
|
var cancel = this.cancelCallbacks[id]; |
|
delete this.cancelCallbacks[id]; |
|
if (cancel) { |
|
cancel(); |
|
} |
|
} else { |
|
this.tasks[id] = data; |
|
this.taskQueue.push(id); |
|
this.invoker.trigger(); |
|
} |
|
}; |
|
Actor.prototype.process = function process() { |
|
var this$1 = this; |
|
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; |
|
} |
|
if (task.type === '<response>') { |
|
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 done = task.hasCallback ? function (err, data) { |
|
completed = true; |
|
delete this$1.cancelCallbacks[id]; |
|
var buffers = []; |
|
this$1.target.postMessage({ |
|
id: id, |
|
type: '<response>', |
|
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.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.every(Array.isArray)) { |
|
return this.extend(LngLatBounds.convert(obj)); |
|
} else { |
|
return this.extend(LngLat.convert(obj)); |
|
} |
|
} |
|
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.convert = function convert(input) { |
|
if (!input || input instanceof LngLatBounds) { |
|
return input; |
|
} |
|
return new LngLatBounds(input); |
|
}; |
|
|
|
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.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: <lng>, lat: <lat>}, an object {lon: <lng>, lat: <lat>}, or an array of [<lng>, <lat>]'); |
|
}; |
|
|
|
var circumferenceAtEquator = 2 * Math.PI * 6378137; |
|
function circumferenceAtLatitude(latitude) { |
|
return circumferenceAtEquator * Math.cos(latitude * Math.PI / 180); |
|
} |
|
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 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(lngLat.lng), mercatorYfromLat(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 / circumferenceAtEquator * 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, 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, (coord.y * tilesAtZoom - this.y) * EXTENT); |
|
}; |
|
var UnwrappedTileID = function UnwrappedTileID(wrap, canonical) { |
|
this.wrap = wrap; |
|
this.canonical = canonical; |
|
this.key = calculateKey(wrap, 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, 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.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, z, x, y) { |
|
wrap *= 2; |
|
if (wrap < 0) { |
|
wrap = wrap * -1 - 1; |
|
} |
|
var dim = 1 << z; |
|
return (dim * dim * wrap + dim * y + x) * 32 + z; |
|
} |
|
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".'); |
|
} |
|
var dim = this.dim = data.height; |
|
this.stride = this.dim + 2; |
|
this.data = new Int32Array(this.stride * this.stride); |
|
var pixels = data.data; |
|
var unpack = encoding === 'terrarium' ? this._unpackTerrarium : this._unpackMapbox; |
|
for (var y = 0; y < dim; y++) { |
|
for (var x = 0; x < dim; x++) { |
|
var i = y * dim + x; |
|
var j = i * 4; |
|
this.set(x, y, unpack(pixels[j], pixels[j + 1], pixels[j + 2])); |
|
} |
|
} |
|
for (var x$1 = 0; x$1 < dim; x$1++) { |
|
this.set(-1, x$1, this.get(0, x$1)); |
|
this.set(dim, x$1, this.get(dim - 1, x$1)); |
|
this.set(x$1, -1, this.get(x$1, 0)); |
|
this.set(x$1, dim, this.get(x$1, dim - 1)); |
|
} |
|
this.set(-1, -1, this.get(0, 0)); |
|
this.set(dim, -1, this.get(dim - 1, 0)); |
|
this.set(-1, dim, this.get(0, dim - 1)); |
|
this.set(dim, dim, this.get(dim - 1, dim - 1)); |
|
}; |
|
DEMData.prototype.set = function set(x, y, value) { |
|
this.data[this._idx(x, y)] = value + 65536; |
|
}; |
|
DEMData.prototype.get = function get(x, y) { |
|
return this.data[this._idx(x, y)] - 65536; |
|
}; |
|
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.set(x, y, borderTile.get(x + ox, y + oy)); |
|
} |
|
} |
|
}; |
|
register('DEMData', DEMData); |
|
|
|
var rasterBoundsAttributes = createLayout([ |
|
{ |
|
name: 'a_pos', |
|
type: 'Int16', |
|
components: 2 |
|
}, |
|
{ |
|
name: 'a_texture_pos', |
|
type: 'Int16', |
|
components: 2 |
|
} |
|
]); |
|
|
|
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) { |
|
this.type = 'Feature'; |
|
this._vectorTileFeature = vectorTileFeature; |
|
vectorTileFeature._z = z; |
|
vectorTileFeature._x = x; |
|
vectorTileFeature._y = y; |
|
this.properties = vectorTileFeature.properties; |
|
if (vectorTileFeature.id != null) { |
|
this.id = vectorTileFeature.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 && featureId >= 0) { |
|
if (this.deletedStates[sourceLayer][feature] !== null) { |
|
this.deletedStates[sourceLayer][feature] = this.deletedStates[sourceLayer][feature] || {}; |
|
this.deletedStates[sourceLayer][feature][key] = null; |
|
} |
|
} else if (featureId !== undefined && featureId >= 0) { |
|
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, grid, featureIndexArray) { |
|
this.tileID = tileID; |
|
this.x = tileID.canonical.x; |
|
this.y = tileID.canonical.y; |
|
this.z = tileID.canonical.z; |
|
this.grid = grid || new gridIndex(EXTENT, 16, 0); |
|
this.grid3D = new gridIndex(EXTENT, 16, 0); |
|
this.featureIndexArray = featureIndexArray || new FeatureIndexArray(); |
|
}; |
|
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 && bbox[1] < EXTENT && 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, sourceFeatureState) { |
|
var this$1 = this; |
|
this.loadVTLayers(); |
|
var params = args.params || {}, pixelsToTileUnits = EXTENT / 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, styleLayers, function (feature, styleLayer) { |
|
if (!featureGeometry) { |
|
featureGeometry = loadGeometry(feature); |
|
} |
|
var featureState = {}; |
|
if (feature.id) { |
|
featureState = sourceFeatureState.getState(styleLayer.sourceLayer || '_geojsonTileLayer', feature.id); |
|
} |
|
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, styleLayers, 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(new EvaluationParameters(this.tileID.overscaledZ), feature)) { |
|
return; |
|
} |
|
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 intersectionZ = !intersectionTest || intersectionTest(feature, styleLayer); |
|
if (!intersectionZ) { |
|
continue; |
|
} |
|
var geojsonFeature = new Feature(feature, this.z, this.x, this.y); |
|
geojsonFeature.layer = styleLayer.serialize(); |
|
var layerResult = result[layerID]; |
|
if (layerResult === undefined) { |
|
layerResult = result[layerID] = []; |
|
} |
|
layerResult.push({ |
|
featureIndex: featureIndex, |
|
feature: geojsonFeature, |
|
intersectionZ: intersectionZ |
|
}); |
|
} |
|
}; |
|
FeatureIndex.prototype.lookupSymbolFeatures = function lookupSymbolFeatures(symbolFeatureIndexes, bucketIndex, sourceLayerIndex, filterSpec, filterLayerIDs, 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, styleLayers); |
|
} |
|
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; |
|
}; |
|
register('FeatureIndex', FeatureIndex, { |
|
omit: [ |
|
'rawTileData', |
|
'sourceLayerCoder' |
|
] |
|
}); |
|
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.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.queryPadding = 0; |
|
for (var id$1 in this.buckets) { |
|
var bucket$1 = this.buckets[id$1]; |
|
this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id$1).queryRadius(bucket$1)); |
|
} |
|
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.unloadDEMData = function unloadDEMData() { |
|
this.dem = null; |
|
this.neighboringTiles = 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, 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, sourceFeatureState); |
|
}; |
|
Tile.prototype.querySourceFeatures = function querySourceFeatures(result, params) { |
|
if (!this.latestFeatureIndex || !this.latestFeatureIndex.rawTileData) { |
|
return; |
|
} |
|
var vtLayers = this.latestFeatureIndex.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(new EvaluationParameters(this.tileID.overscaledZ), feature)) { |
|
var geojsonFeature = new Feature(feature, z, x, y); |
|
geojsonFeature.tile = coord; |
|
result.push(geojsonFeature); |
|
} |
|
} |
|
}; |
|
Tile.prototype.clearMask = function clearMask() { |
|
if (this.segments) { |
|
this.segments.destroy(); |
|
delete this.segments; |
|
} |
|
if (this.maskedBoundsBuffer) { |
|
this.maskedBoundsBuffer.destroy(); |
|
delete this.maskedBoundsBuffer; |
|
} |
|
if (this.maskedIndexBuffer) { |
|
this.maskedIndexBuffer.destroy(); |
|
delete this.maskedIndexBuffer; |
|
} |
|
}; |
|
Tile.prototype.setMask = function setMask(mask, context) { |
|
if (deepEqual(this.mask, mask)) { |
|
return; |
|
} |
|
this.mask = mask; |
|
this.clearMask(); |
|
if (deepEqual(mask, { '0': true })) { |
|
return; |
|
} |
|
var maskedBoundsArray = new StructArrayLayout4i8(); |
|
var indexArray = new StructArrayLayout3ui6(); |
|
this.segments = new SegmentVector(); |
|
this.segments.prepareSegment(0, maskedBoundsArray, indexArray); |
|
var maskArray = Object.keys(mask); |
|
for (var i = 0; i < maskArray.length; i++) { |
|
var maskCoord = mask[+maskArray[i]]; |
|
var vertexExtent = EXTENT >> maskCoord.z; |
|
var tlVertex = new pointGeometry(maskCoord.x * vertexExtent, maskCoord.y * vertexExtent); |
|
var brVertex = new pointGeometry(tlVertex.x + vertexExtent, tlVertex.y + vertexExtent); |
|
var segment = this.segments.prepareSegment(4, maskedBoundsArray, indexArray); |
|
maskedBoundsArray.emplaceBack(tlVertex.x, tlVertex.y, tlVertex.x, tlVertex.y); |
|
maskedBoundsArray.emplaceBack(brVertex.x, tlVertex.y, brVertex.x, tlVertex.y); |
|
maskedBoundsArray.emplaceBack(tlVertex.x, brVertex.y, tlVertex.x, brVertex.y); |
|
maskedBoundsArray.emplaceBack(brVertex.x, brVertex.y, brVertex.x, brVertex.y); |
|
var offset = segment.vertexLength; |
|
indexArray.emplaceBack(offset, offset + 1, offset + 2); |
|
indexArray.emplaceBack(offset + 1, offset + 2, offset + 3); |
|
segment.vertexLength += 4; |
|
segment.primitiveLength += 2; |
|
} |
|
this.maskedBoundsBuffer = context.createVertexBuffer(maskedBoundsArray, rasterBoundsAttributes.members); |
|
this.maskedIndexBuffer = context.createIndexBuffer(indexArray); |
|
}; |
|
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) { |
|
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 || {}); |
|
if (painter && painter.style) { |
|
this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id).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; |
|
}; |
|
|
|
var refProperties = [ |
|
'type', |
|
'source', |
|
'source-layer', |
|
'minzoom', |
|
'maxzoom', |
|
'filter', |
|
'layout' |
|
]; |
|
|
|
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; |
|
} |
|
|
|
function getIconQuads(anchor, shapedIcon, layer, alongLine, shapedText, feature) { |
|
var image = shapedIcon.image; |
|
var layout = layer.layout; |
|
var border = 1; |
|
var top = shapedIcon.top - border / image.pixelRatio; |
|
var left = shapedIcon.left - border / image.pixelRatio; |
|
var bottom = shapedIcon.bottom + border / image.pixelRatio; |
|
var right = shapedIcon.right + border / image.pixelRatio; |
|
var tl, tr, br, bl; |
|
if (layout.get('icon-text-fit') !== 'none' && shapedText) { |
|
var iconWidth = right - left, iconHeight = bottom - top, size = layout.get('text-size').evaluate(feature, {}) / 24, textLeft = shapedText.left * size, textRight = shapedText.right * size, textTop = shapedText.top * size, textBottom = shapedText.bottom * size, textWidth = textRight - textLeft, textHeight = textBottom - textTop, padT = layout.get('icon-text-fit-padding')[0], padR = layout.get('icon-text-fit-padding')[1], padB = layout.get('icon-text-fit-padding')[2], padL = layout.get('icon-text-fit-padding')[3], offsetY = layout.get('icon-text-fit') === 'width' ? (textHeight - iconHeight) * 0.5 : 0, offsetX = layout.get('icon-text-fit') === 'height' ? (textWidth - iconWidth) * 0.5 : 0, width = layout.get('icon-text-fit') === 'width' || layout.get('icon-text-fit') === 'both' ? textWidth : iconWidth, height = layout.get('icon-text-fit') === 'height' || layout.get('icon-text-fit') === 'both' ? textHeight : iconHeight; |
|
tl = new pointGeometry(textLeft + offsetX - padL, textTop + offsetY - padT); |
|
tr = new pointGeometry(textLeft + offsetX + padR + width, textTop + offsetY - padT); |
|
br = new pointGeometry(textLeft + offsetX + padR + width, textTop + offsetY + padB + height); |
|
bl = new pointGeometry(textLeft + offsetX - padL, textTop + offsetY + padB + height); |
|
} else { |
|
tl = new pointGeometry(left, top); |
|
tr = new pointGeometry(right, top); |
|
br = new pointGeometry(right, bottom); |
|
bl = new pointGeometry(left, bottom); |
|
} |
|
var angle = layer.layout.get('icon-rotate').evaluate(feature, {}) * 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); |
|
} |
|
return [{ |
|
tl: tl, |
|
tr: tr, |
|
bl: bl, |
|
br: br, |
|
tex: image.paddedRect, |
|
writingMode: undefined, |
|
glyphOffset: [ |
|
0, |
|
0 |
|
], |
|
sectionIndex: 0 |
|
}]; |
|
} |
|
function getGlyphQuads(anchor, shaping, textOffset, layer, alongLine, feature, positions, allowVerticalPlacement) { |
|
var textRotate = layer.layout.get('text-rotate').evaluate(feature, {}) * Math.PI / 180; |
|
var positionedGlyphs = shaping.positionedGlyphs; |
|
var quads = []; |
|
for (var k = 0; k < positionedGlyphs.length; k++) { |
|
var positionedGlyph = positionedGlyphs[k]; |
|
var glyphPositions = positions[positionedGlyph.fontStack]; |
|
var glyph = glyphPositions && glyphPositions[positionedGlyph.glyph]; |
|
if (!glyph) { |
|
continue; |
|
} |
|
var rect = glyph.rect; |
|
if (!rect) { |
|
continue; |
|
} |
|
var glyphPadding = 1; |
|
var rectBuffer = GLYPH_PBF_BORDER + glyphPadding; |
|
var halfAdvance = glyph.metrics.advance * positionedGlyph.scale / 2; |
|
var glyphOffset = alongLine ? [ |
|
positionedGlyph.x + halfAdvance, |
|
positionedGlyph.y |
|
] : [ |
|
0, |
|
0 |
|
]; |
|
var builtInOffset = alongLine ? [ |
|
0, |
|
0 |
|
] : [ |
|
positionedGlyph.x + halfAdvance + textOffset[0], |
|
positionedGlyph.y + textOffset[1] |
|
]; |
|
var rotateVerticalGlyph = (alongLine || allowVerticalPlacement) && positionedGlyph.vertical; |
|
var verticalizedLabelOffset = [ |
|
0, |
|
0 |
|
]; |
|
if (rotateVerticalGlyph) { |
|
verticalizedLabelOffset = builtInOffset; |
|
builtInOffset = [ |
|
0, |
|
0 |
|
]; |
|
} |
|
var x1 = (glyph.metrics.left - rectBuffer) * positionedGlyph.scale - halfAdvance + builtInOffset[0]; |
|
var y1 = (-glyph.metrics.top - rectBuffer) * positionedGlyph.scale + builtInOffset[1]; |
|
var x2 = x1 + rect.w * positionedGlyph.scale; |
|
var y2 = y1 + rect.h * positionedGlyph.scale; |
|
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.yOffset); |
|
var verticalRotation = -Math.PI / 2; |
|
var xHalfWidhtOffsetcorrection = ONE_EM / 2 - halfAdvance; |
|
var xOffsetCorrection = new pointGeometry(5 - shaping.yOffset - xHalfWidhtOffsetcorrection, 0); |
|
var verticalOffsetCorrection = new (Function.prototype.bind.apply(pointGeometry, [null].concat(verticalizedLabelOffset)))(); |
|
tl._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection); |
|
tr._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection); |
|
bl._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection); |
|
br._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._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); |
|
} |
|
quads.push({ |
|
tl: tl, |
|
tr: tr, |
|
bl: bl, |
|
br: br, |
|
tex: rect, |
|
writingMode: shaping.writingMode, |
|
glyphOffset: glyphOffset, |
|
sectionIndex: positionedGlyph.sectionIndex |
|
}); |
|
} |
|
return quads; |
|
} |
|
|
|
var CollisionFeature = function CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaped, boxScale, padding, alignLine, overscaling, rotate) { |
|
var y1 = shaped.top * boxScale - padding; |
|
var y2 = shaped.bottom * boxScale + padding; |
|
var x1 = shaped.left * boxScale - padding; |
|
var x2 = shaped.right * boxScale + padding; |
|
this.boxStartIndex = collisionBoxArray.length; |
|
if (alignLine) { |
|
var height = y2 - y1; |
|
var length = x2 - x1; |
|
if (height > 0) { |
|
height = Math.max(10 * boxScale, height); |
|
this._addLineCollisionCircles(collisionBoxArray, line, anchor, anchor.segment, length, height, featureIndex, sourceLayerIndex, bucketIndex, overscaling); |
|
} |
|
} else { |
|
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, 0, 0); |
|
} |
|
this.boxEndIndex = collisionBoxArray.length; |
|
}; |
|
CollisionFeature.prototype._addLineCollisionCircles = function _addLineCollisionCircles(collisionBoxArray, line, anchor, segment, labelLength, boxSize, featureIndex, sourceLayerIndex, bucketIndex, overscaling) { |
|
var step = boxSize / 2; |
|
var nBoxes = Math.floor(labelLength / step) || 1; |
|
var overscalingPaddingFactor = 1 + 0.4 * Math.log(overscaling) / Math.LN2; |
|
var nPitchPaddingBoxes = Math.floor(nBoxes * overscalingPaddingFactor / 2); |
|
var firstBoxOffset = -boxSize / 2; |
|
var p = anchor; |
|
var index = segment + 1; |
|
var anchorDistance = firstBoxOffset; |
|
var labelStartDistance = -labelLength / 2; |
|
var paddingStartDistance = labelStartDistance - labelLength / 4; |
|
do { |
|
index--; |
|
if (index < 0) { |
|
if (anchorDistance > labelStartDistance) { |
|
return; |
|
} else { |
|
index = 0; |
|
break; |
|
} |
|
} else { |
|
anchorDistance -= line[index].dist(p); |
|
p = line[index]; |
|
} |
|
} while (anchorDistance > paddingStartDistance); |
|
var segmentLength = line[index].dist(line[index + 1]); |
|
for (var i = -nPitchPaddingBoxes; i < nBoxes + nPitchPaddingBoxes; i++) { |
|
var boxOffset = i * step; |
|
var boxDistanceToAnchor = labelStartDistance + boxOffset; |
|
if (boxOffset < 0) { |
|
boxDistanceToAnchor += boxOffset; |
|
} |
|
if (boxOffset > labelLength) { |
|
boxDistanceToAnchor += boxOffset - labelLength; |
|
} |
|
if (boxDistanceToAnchor < anchorDistance) { |
|
continue; |
|
} |
|
while (anchorDistance + segmentLength < boxDistanceToAnchor) { |
|
anchorDistance += segmentLength; |
|
index++; |
|
if (index + 1 >= line.length) { |
|
return; |
|
} |
|
segmentLength = line[index].dist(line[index + 1]); |
|
} |
|
var segmentBoxDistance = boxDistanceToAnchor - anchorDistance; |
|
var p0 = line[index]; |
|
var p1 = line[index + 1]; |
|
var boxAnchorPoint = p1.sub(p0)._unit()._mult(segmentBoxDistance)._add(p0)._round(); |
|
var paddedAnchorDistance = Math.abs(boxDistanceToAnchor - firstBoxOffset) < step ? 0 : (boxDistanceToAnchor - firstBoxOffset) * 0.8; |
|
collisionBoxArray.emplaceBack(boxAnchorPoint.x, boxAnchorPoint.y, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, featureIndex, sourceLayerIndex, bucketIndex, boxSize / 2, paddedAnchorDistance); |
|
} |
|
}; |
|
|
|
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 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 baselineOffset = 7; |
|
function evaluateRadialOffset(anchor, radialOffset) { |
|
var x = 0, y = 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 performSymbolLayout(bucket, glyphMap, glyphPositions, imageMap, imagePositions, showCollisionBoxes) { |
|
bucket.createArrays(); |
|
var tileSize = 512 * bucket.overscaling; |
|
bucket.tilePixelRatio = EXTENT / 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)), |
|
unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(maxZoom)) |
|
]; |
|
} |
|
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)), |
|
unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(maxZoom$1)) |
|
]; |
|
} |
|
sizes.layoutTextSize = unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1)); |
|
sizes.layoutIconSize = unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1)); |
|
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 loop = function () { |
|
var feature = list[i$1]; |
|
var fontstack = layout.get('text-font').evaluate(feature, {}).join(','); |
|
var glyphPositionMap = glyphPositions; |
|
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, {}) * ONE_EM; |
|
var spacingIfAllowed = allowsLetterSpacing(unformattedText) ? spacing : 0; |
|
var textAnchor = layout.get('text-anchor').evaluate(feature, {}); |
|
var variableTextAnchor = layout.get('text-variable-anchor'); |
|
var radialOffset = layout.get('text-radial-offset').evaluate(feature, {}); |
|
if (!variableTextAnchor) { |
|
if (radialOffset) { |
|
textOffset = evaluateRadialOffset(textAnchor, radialOffset * ONE_EM); |
|
} else { |
|
textOffset = layout.get('text-offset').evaluate(feature, {}).map(function (t) { |
|
return t * ONE_EM; |
|
}); |
|
} |
|
} |
|
var textJustify = textAlongLine ? 'center' : layout.get('text-justify').evaluate(feature, {}); |
|
var maxWidth = layout.get('symbol-placement') === 'point' ? layout.get('text-max-width').evaluate(feature, {}) * ONE_EM : 0; |
|
var addVerticalShapingForPointLabelIfNeeded = function () { |
|
if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) { |
|
shapedTextOrientations.vertical = shapeText(text, glyphMap, fontstack, maxWidth, lineHeight, textAnchor, 'left', spacingIfAllowed, textOffset, WritingMode.vertical, true); |
|
} |
|
}; |
|
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, fontstack, maxWidth, lineHeight, 'center', justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false); |
|
if (shaping) { |
|
shapedTextOrientations.horizontal[justification] = shaping; |
|
singleLine = shaping.lineCount === 1; |
|
} |
|
} |
|
} |
|
addVerticalShapingForPointLabelIfNeeded(); |
|
} else { |
|
if (textJustify === 'auto') { |
|
textJustify = getAnchorJustification(textAnchor); |
|
} |
|
var shaping$1 = shapeText(text, glyphMap, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed, textOffset, WritingMode.horizontal, false); |
|
if (shaping$1) { |
|
shapedTextOrientations.horizontal[textJustify] = shaping$1; |
|
} |
|
addVerticalShapingForPointLabelIfNeeded(); |
|
if (allowsVerticalWritingMode(unformattedText) && textAlongLine && keepUpright) { |
|
shapedTextOrientations.vertical = shapeText(text, glyphMap, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed, textOffset, WritingMode.vertical, false); |
|
} |
|
} |
|
} |
|
var shapedIcon = void 0; |
|
if (feature.icon) { |
|
var image = imageMap[feature.icon]; |
|
if (image) { |
|
shapedIcon = shapeIcon(imagePositions[feature.icon], layout.get('icon-offset').evaluate(feature, {}), layout.get('icon-anchor').evaluate(feature, {})); |
|
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; |
|
} |
|
} |
|
} |
|
if (Object.keys(shapedTextOrientations.horizontal).length || shapedIcon) { |
|
addFeature(bucket, feature, shapedTextOrientations, shapedIcon, glyphPositionMap, sizes, textOffset); |
|
} |
|
}; |
|
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, glyphPositionMap, sizes, textOffset) { |
|
var layoutTextSize = sizes.layoutTextSize.evaluate(feature, {}); |
|
var layoutIconSize = sizes.layoutIconSize.evaluate(feature, {}); |
|
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, {}); |
|
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 addSymbolAtAnchor = function (line, anchor) { |
|
if (anchor.x < 0 || anchor.x >= EXTENT || anchor.y < 0 || anchor.y >= EXTENT) { |
|
return; |
|
} |
|
addSymbol(bucket, anchor, line, shapedTextOrientations, shapedIcon, bucket.layers[0], bucket.collisionBoxArray, feature.index, feature.sourceLayerIndex, bucket.index, textBoxScale, textPadding, textAlongLine, textOffset, iconBoxScale, iconPadding, iconAlongLine, iconOffset, feature, glyphPositionMap, sizes); |
|
}; |
|
if (symbolPlacement === 'line') { |
|
for (var i$1 = 0, list$1 = clipLine(feature.geometry, 0, 0, EXTENT, EXTENT); 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); |
|
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_PACKED_SIZE = 65535; |
|
function addTextVertices(bucket, anchor, shapedText, layer, textAlongLine, feature, textOffset, lineArray, writingMode, placementTypes, placedTextSymbolIndices, glyphPositionMap, sizes) { |
|
var glyphQuads = getGlyphQuads(anchor, shapedText, textOffset, layer, textAlongLine, feature, glyphPositionMap, 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 >= 256. Reduce your "text-size".'); |
|
} |
|
} else if (sizeData.kind === 'composite') { |
|
textSizeData = [ |
|
SIZE_PACK_FACTOR * sizes.compositeTextSizes[0].evaluate(feature, {}), |
|
SIZE_PACK_FACTOR * sizes.compositeTextSizes[1].evaluate(feature, {}) |
|
]; |
|
if (textSizeData[0] > MAX_PACKED_SIZE || textSizeData[1] > MAX_PACKED_SIZE) { |
|
warnOnce(bucket.layerIds[0] + ': Value for "text-size" is >= 256. Reduce your "text-size".'); |
|
} |
|
} |
|
bucket.addSymbols(bucket.text, glyphQuads, textSizeData, textOffset, textAlongLine, feature, writingMode, anchor, lineArray.lineStartIndex, lineArray.lineLength); |
|
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, layer, collisionBoxArray, featureIndex, sourceLayerIndex, bucketIndex, textBoxScale, textPadding, textAlongLine, textOffset, iconBoxScale, iconPadding, iconAlongLine, iconOffset, feature, glyphPositionMap, sizes) { |
|
var lineArray = bucket.addToLineVertexArray(anchor, line); |
|
var textCollisionFeature, iconCollisionFeature, verticalTextCollisionFeature; |
|
var numIconVertices = 0; |
|
var numHorizontalGlyphVertices = 0; |
|
var numVerticalGlyphVertices = 0; |
|
var placedTextSymbolIndices = {}; |
|
var key = murmurhashJs(''); |
|
var radialTextOffset = (layer.layout.get('text-radial-offset').evaluate(feature, {}) || 0) * ONE_EM; |
|
if (bucket.allowVerticalPlacement && shapedTextOrientations.vertical) { |
|
var textRotation = layer.layout.get('text-rotate').evaluate(feature, {}); |
|
var verticalTextRotation = textRotation + 90; |
|
var verticalShaping = shapedTextOrientations.vertical; |
|
verticalTextCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, verticalShaping, textBoxScale, textPadding, textAlongLine, bucket.overscaling, verticalTextRotation); |
|
} |
|
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, {}); |
|
textCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaping, textBoxScale, textPadding, textAlongLine, bucket.overscaling, textRotate); |
|
} |
|
var singleLine = shaping.lineCount === 1; |
|
numHorizontalGlyphVertices += addTextVertices(bucket, anchor, shaping, layer, textAlongLine, feature, textOffset, lineArray, shapedTextOrientations.vertical ? WritingMode.horizontal : WritingMode.horizontalOnly, singleLine ? Object.keys(shapedTextOrientations.horizontal) : [justification], placedTextSymbolIndices, glyphPositionMap, sizes); |
|
if (singleLine) { |
|
break; |
|
} |
|
} |
|
if (shapedTextOrientations.vertical) { |
|
numVerticalGlyphVertices += addTextVertices(bucket, anchor, shapedTextOrientations.vertical, layer, textAlongLine, feature, textOffset, lineArray, WritingMode.vertical, ['vertical'], placedTextSymbolIndices, glyphPositionMap, sizes); |
|
} |
|
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; |
|
if (shapedIcon) { |
|
var iconQuads = getIconQuads(anchor, shapedIcon, layer, iconAlongLine, getDefaultHorizontalShaping(shapedTextOrientations.horizontal), feature); |
|
var iconRotate = layer.layout.get('icon-rotate').evaluate(feature, {}); |
|
iconCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, false, bucket.overscaling, 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 >= 256. Reduce your "icon-size".'); |
|
} |
|
} else if (sizeData.kind === 'composite') { |
|
iconSizeData = [ |
|
SIZE_PACK_FACTOR * sizes.compositeIconSizes[0].evaluate(feature, {}), |
|
SIZE_PACK_FACTOR * sizes.compositeIconSizes[1].evaluate(feature, {}) |
|
]; |
|
if (iconSizeData[0] > MAX_PACKED_SIZE || iconSizeData[1] > MAX_PACKED_SIZE) { |
|
warnOnce(bucket.layerIds[0] + ': Value for "icon-size" is >= 256. Reduce your "icon-size".'); |
|
} |
|
} |
|
bucket.addSymbols(bucket.icon, iconQuads, iconSizeData, iconOffset, iconAlongLine, feature, false, anchor, lineArray.lineStartIndex, lineArray.lineLength); |
|
} |
|
var iconBoxStartIndex = iconCollisionFeature ? iconCollisionFeature.boxStartIndex : bucket.collisionBoxArray.length; |
|
var iconBoxEndIndex = iconCollisionFeature ? iconCollisionFeature.boxEndIndex : bucket.collisionBoxArray.length; |
|
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'); |
|
} |
|
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, key, textBoxStartIndex, textBoxEndIndex, verticalTextBoxStartIndex, verticalTextBoxEndIndex, iconBoxStartIndex, iconBoxEndIndex, featureIndex, numHorizontalGlyphVertices, numVerticalGlyphVertices, numIconVertices, 0, textBoxScale, radialTextOffset); |
|
} |
|
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; |
|
} |
|
|
|
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; |
|
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.ProgramConfiguration = ProgramConfiguration; |
|
exports.Properties = Properties; |
|
exports.Protobuf = pbf; |
|
exports.RGBAImage = RGBAImage; |
|
exports.RequestManager = RequestManager; |
|
exports.ResourceType = ResourceType; |
|
exports.SegmentVector = SegmentVector; |
|
exports.SourceFeatureState = SourceFeatureState; |
|
exports.StructArrayLayout1ui2 = StructArrayLayout1ui2; |
|
exports.StructArrayLayout2i4 = StructArrayLayout2i4; |
|
exports.StructArrayLayout2ui4 = StructArrayLayout2ui4; |
|
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.addDynamicAttributes = addDynamicAttributes; |
|
exports.asyncAll = asyncAll; |
|
exports.bezier = bezier; |
|
exports.bindAll = bindAll; |
|
exports.browser = exported; |
|
exports.cacheEntryPossiblyAdded = cacheEntryPossiblyAdded; |
|
exports.clamp = clamp; |
|
exports.clearTileCache = clearTileCache; |
|
exports.clone = clone$1; |
|
exports.clone$1 = clone; |
|
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.deepEqual = deepEqual; |
|
exports.ease = ease; |
|
exports.emitValidationErrors = emitValidationErrors; |
|
exports.endsWith = endsWith; |
|
exports.enforceCacheSizeLimit = enforceCacheSizeLimit; |
|
exports.evaluateRadialOffset = evaluateRadialOffset; |
|
exports.evaluateSizeForFeature = evaluateSizeForFeature; |
|
exports.evaluateSizeForZoom = evaluateSizeForZoom; |
|
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.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; |
|
exports.mercatorYfromLat = mercatorYfromLat; |
|
exports.mercatorZfromAltitude = mercatorZfromAltitude; |
|
exports.multiply = multiply; |
|
exports.mvt = vectorTile; |
|
exports.number = number; |
|
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.rasterBoundsAttributes = rasterBoundsAttributes; |
|
exports.refProperties = refProperties; |
|
exports.register = register; |
|
exports.registerForPluginAvailability = registerForPluginAvailability; |
|
exports.rotate = rotate; |
|
exports.rotateX = rotateX; |
|
exports.rotateZ = rotateZ; |
|
exports.scale = scale; |
|
exports.setCacheLimits = setCacheLimits; |
|
exports.setRTLTextPlugin = setRTLTextPlugin; |
|
exports.sphericalToCartesian = sphericalToCartesian; |
|
exports.styleSpec = spec; |
|
exports.symbolSize = symbolSize; |
|
exports.transformMat3 = transformMat3; |
|
exports.transformMat4 = transformMat4; |
|
exports.translate = translate$1; |
|
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 = self; |
|
exports.wrap = wrap; |
|
|
|
}); |
|
|
|
define(['./shared'], function (symbol_layout) { '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 = symbol_layout.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] = symbol_layout.createStyleLayer(layerConfig); |
|
layer._featureFilter = symbol_layout.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(symbol_layout.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 = symbol_layout.potpack(bins); |
|
var w = ref.w; |
|
var h = ref.h; |
|
var image = new symbol_layout.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; |
|
symbol_layout.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; |
|
}; |
|
symbol_layout.register('GlyphAtlas', GlyphAtlas); |
|
|
|
var WorkerTile = function WorkerTile(params) { |
|
this.tileID = new symbol_layout.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; |
|
}; |
|
WorkerTile.prototype.parse = function parse(data, layerIndex, actor, callback) { |
|
var this$1 = this; |
|
this.status = 'parsing'; |
|
this.data = data; |
|
this.collisionBoxArray = new symbol_layout.CollisionBoxArray(); |
|
var sourceLayerCoder = new symbol_layout.DictionaryCoder(Object.keys(data.layers).sort()); |
|
var featureIndex = new symbol_layout.FeatureIndex(this.tileID); |
|
featureIndex.bucketLayerIDs = []; |
|
var buckets = {}; |
|
var options = { |
|
featureIndex: featureIndex, |
|
iconDependencies: {}, |
|
patternDependencies: {}, |
|
glyphDependencies: {} |
|
}; |
|
var layerFamilies = layerIndex.familiesBySource[this.source]; |
|
for (var sourceLayerId in layerFamilies) { |
|
var sourceLayer = data.layers[sourceLayerId]; |
|
if (!sourceLayer) { |
|
continue; |
|
} |
|
if (sourceLayer.version === 1) { |
|
symbol_layout.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); |
|
features.push({ |
|
feature: feature, |
|
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); |
|
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); |
|
featureIndex.bucketLayerIDs.push(family.map(function (l) { |
|
return l.id; |
|
})); |
|
} |
|
} |
|
var error; |
|
var glyphMap; |
|
var iconMap; |
|
var patternMap; |
|
var stacks = symbol_layout.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 }, 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 }, 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 symbol_layout.ImageAtlas(iconMap, patternMap); |
|
for (var key in buckets) { |
|
var bucket = buckets[key]; |
|
if (bucket instanceof symbol_layout.SymbolBucket) { |
|
recalculateLayers(bucket.layers, this.zoom); |
|
symbol_layout.performSymbolLayout(bucket, glyphMap, glyphAtlas.positions, iconMap, imageAtlas.iconPositions, this.showCollisionBoxes); |
|
} else if (bucket.hasPattern && (bucket instanceof symbol_layout.LineBucket || bucket instanceof symbol_layout.FillBucket || bucket instanceof symbol_layout.FillExtrusionBucket)) { |
|
recalculateLayers(bucket.layers, this.zoom); |
|
bucket.addFeatures(options, imageAtlas.patternPositions); |
|
} |
|
} |
|
this.status = 'done'; |
|
callback(null, { |
|
buckets: symbol_layout.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) { |
|
var parameters = new symbol_layout.EvaluationParameters(zoom); |
|
for (var i = 0, list = layers; i < list.length; i += 1) { |
|
var layer = list[i]; |
|
layer.recalculate(parameters); |
|
} |
|
} |
|
|
|
var performanceExists = typeof performance !== 'undefined'; |
|
var wrapper = {}; |
|
wrapper.getEntriesByName = function (url) { |
|
if (performanceExists && performance && performance.getEntriesByName) { |
|
return performance.getEntriesByName(url); |
|
} else { |
|
return false; |
|
} |
|
}; |
|
wrapper.mark = function (name) { |
|
if (performanceExists && performance && performance.mark) { |
|
return performance.mark(name); |
|
} else { |
|
return false; |
|
} |
|
}; |
|
wrapper.measure = function (name, startMark, endMark) { |
|
if (performanceExists && performance && performance.measure) { |
|
return performance.measure(name, startMark, endMark); |
|
} else { |
|
return false; |
|
} |
|
}; |
|
wrapper.clearMarks = function (name) { |
|
if (performanceExists && performance && performance.clearMarks) { |
|
return performance.clearMarks(name); |
|
} else { |
|
return false; |
|
} |
|
}; |
|
wrapper.clearMeasures = function (name) { |
|
if (performanceExists && performance && performance.clearMeasures) { |
|
return performance.clearMeasures(name); |
|
} else { |
|
return false; |
|
} |
|
}; |
|
var Performance = function Performance(request) { |
|
this._marks = { |
|
start: [ |
|
request.url, |
|
'start' |
|
].join('#'), |
|
end: [ |
|
request.url, |
|
'end' |
|
].join('#'), |
|
measure: request.url.toString() |
|
}; |
|
wrapper.mark(this._marks.start); |
|
}; |
|
Performance.prototype.finish = function finish() { |
|
wrapper.mark(this._marks.end); |
|
var resourceTimingData = wrapper.getEntriesByName(this._marks.measure); |
|
if (resourceTimingData.length === 0) { |
|
wrapper.measure(this._marks.measure, this._marks.start, this._marks.end); |
|
resourceTimingData = wrapper.getEntriesByName(this._marks.measure); |
|
wrapper.clearMarks(this._marks.start); |
|
wrapper.clearMarks(this._marks.end); |
|
wrapper.clearMeasures(this._marks.measure); |
|
} |
|
return resourceTimingData; |
|
}; |
|
wrapper.Performance = Performance; |
|
|
|
function loadVectorTile(params, callback) { |
|
var request = symbol_layout.getArrayBuffer(params.request, function (err, data, cacheControl, expires) { |
|
if (err) { |
|
callback(err); |
|
} else if (data) { |
|
callback(null, { |
|
vectorTile: new symbol_layout.vectorTile.VectorTile(new symbol_layout.pbf(data)), |
|
rawData: data, |
|
cacheControl: cacheControl, |
|
expires: expires |
|
}); |
|
} |
|
}); |
|
return function () { |
|
request.cancel(); |
|
callback(); |
|
}; |
|
} |
|
var VectorTileWorkerSource = function VectorTileWorkerSource(actor, layerIndex, loadVectorData) { |
|
this.actor = actor; |
|
this.layerIndex = layerIndex; |
|
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 wrapper.Performance(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.actor, function (err, result) { |
|
if (err || !result) { |
|
return callback(err); |
|
} |
|
callback(null, symbol_layout.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 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, 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.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 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 dem = new symbol_layout.DEMData(uid, rawImageData, encoding); |
|
this.loaded = this.loaded || {}; |
|
this.loaded[uid] = dem; |
|
callback(null, dem); |
|
}; |
|
RasterDEMTileWorkerSource.prototype.removeTile = function removeTile(params) { |
|
var loaded = this.loaded, uid = params.uid; |
|
if (loaded && loaded[uid]) { |
|
delete loaded[uid]; |
|
} |
|
}; |
|
|
|
var RADIUS = 6378137; |
|
var FLATTENING = 1 / 298.257223563; |
|
var POLAR_RADIUS = 6356752.3142; |
|
|
|
var wgs84 = { |
|
RADIUS: RADIUS, |
|
FLATTENING: FLATTENING, |
|
POLAR_RADIUS: POLAR_RADIUS |
|
}; |
|
|
|
var geometry_1 = geometry; |
|
var ring = ringArea; |
|
function geometry(_) { |
|
var area = 0, i; |
|
switch (_.type) { |
|
case 'Polygon': |
|
return polygonArea(_.coordinates); |
|
case 'MultiPolygon': |
|
for (i = 0; i < _.coordinates.length; i++) { |
|
area += polygonArea(_.coordinates[i]); |
|
} |
|
return area; |
|
case 'Point': |
|
case 'MultiPoint': |
|
case 'LineString': |
|
case 'MultiLineString': |
|
return 0; |
|
case 'GeometryCollection': |
|
for (i = 0; i < _.geometries.length; i++) { |
|
area += geometry(_.geometries[i]); |
|
} |
|
return area; |
|
} |
|
} |
|
function polygonArea(coords) { |
|
var area = 0; |
|
if (coords && coords.length > 0) { |
|
area += Math.abs(ringArea(coords[0])); |
|
for (var i = 1; i < coords.length; i++) { |
|
area -= Math.abs(ringArea(coords[i])); |
|
} |
|
} |
|
return area; |
|
} |
|
function ringArea(coords) { |
|
var p1, p2, p3, lowerIndex, middleIndex, upperIndex, i, area = 0, coordsLength = coords.length; |
|
if (coordsLength > 2) { |
|
for (i = 0; i < coordsLength; i++) { |
|
if (i === coordsLength - 2) { |
|
lowerIndex = coordsLength - 2; |
|
middleIndex = coordsLength - 1; |
|
upperIndex = 0; |
|
} else if (i === coordsLength - 1) { |
|
lowerIndex = coordsLength - 1; |
|
middleIndex = 0; |
|
upperIndex = 1; |
|
} else { |
|
lowerIndex = i; |
|
middleIndex = i + 1; |
|
upperIndex = i + 2; |
|
} |
|
p1 = coords[lowerIndex]; |
|
p2 = coords[middleIndex]; |
|
p3 = coords[upperIndex]; |
|
area += (rad(p3[0]) - rad(p1[0])) * Math.sin(rad(p2[1])); |
|
} |
|
area = area * wgs84.RADIUS * wgs84.RADIUS / 2; |
|
} |
|
return area; |
|
} |
|
function rad(_) { |
|
return _ * Math.PI / 180; |
|
} |
|
|
|
var geojsonArea = { |
|
geometry: geometry_1, |
|
ring: ring |
|
}; |
|
|
|
var geojsonRewind = rewind; |
|
function rewind(gj, outer) { |
|
switch (gj && gj.type || null) { |
|
case 'FeatureCollection': |
|
gj.features = gj.features.map(curryOuter(rewind, outer)); |
|
return gj; |
|
case 'GeometryCollection': |
|
gj.geometries = gj.geometries.map(curryOuter(rewind, outer)); |
|
return gj; |
|
case 'Feature': |
|
gj.geometry = rewind(gj.geometry, outer); |
|
return gj; |
|
case 'Polygon': |
|
case 'MultiPolygon': |
|
return correct(gj, outer); |
|
default: |
|
return gj; |
|
} |
|
} |
|
function curryOuter(a, b) { |
|
return function (_) { |
|
return a(_, b); |
|
}; |
|
} |
|
function correct(_, outer) { |
|
if (_.type === 'Polygon') { |
|
_.coordinates = correctRings(_.coordinates, outer); |
|
} else if (_.type === 'MultiPolygon') { |
|
_.coordinates = _.coordinates.map(curryOuter(correctRings, outer)); |
|
} |
|
return _; |
|
} |
|
function correctRings(_, outer) { |
|
outer = !!outer; |
|
_[0] = wind(_[0], outer); |
|
for (var i = 1; i < _.length; i++) { |
|
_[i] = wind(_[i], !outer); |
|
} |
|
return _; |
|
} |
|
function wind(_, dir) { |
|
return cw(_) === dir ? _ : _.reverse(); |
|
} |
|
function cw(_) { |
|
return geojsonArea.ring(_) >= 0; |
|
} |
|
|
|
var toGeoJSON = symbol_layout.vectorTile.VectorTileFeature.prototype.toGeoJSON; |
|
var FeatureWrapper = function FeatureWrapper(feature) { |
|
this._feature = feature; |
|
this.extent = symbol_layout.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 symbol_layout.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 symbol_layout.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 = symbol_layout.EXTENT; |
|
this.length = features.length; |
|
this._features = features; |
|
}; |
|
GeoJSONWrapper.prototype.feature = function feature(i) { |
|
return new FeatureWrapper(this._features[i]); |
|
}; |
|
|
|
var VectorTileFeature = symbol_layout.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 symbol_layout.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 symbol_layout.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, |
|
radius: 40, |
|
extent: 512, |
|
nodeSize: 64, |
|
log: 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 = clusterId >> 5; |
|
var originZoom = clusterId % 32; |
|
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 clusterZoom = clusterId % 32 - 1; |
|
while (clusterZoom <= this.options.maxZoom) { |
|
var children = this.getChildren(clusterId); |
|
clusterZoom++; |
|
if (children.length !== 1) { |
|
break; |
|
} |
|
clusterId = children[0].properties.cluster_id; |
|
} |
|
return clusterZoom; |
|
}; |
|
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 f = { |
|
type: 1, |
|
geometry: [[ |
|
Math.round(this.options.extent * (c.x * z2 - x)), |
|
Math.round(this.options.extent * (c.y * z2 - y)) |
|
]], |
|
tags: c.numPoints ? getClusterProperties(c) : this.points[c.index].properties |
|
}; |
|
var id = c.numPoints ? c.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 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 numPoints = p.numPoints || 1; |
|
var wx = p.x * numPoints; |
|
var wy = p.y * numPoints; |
|
var clusterProperties = reduce && numPoints > 1 ? this._map(p, true) : null; |
|
var id = (i << 5) + (zoom + 1); |
|
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) { |
|
continue; |
|
} |
|
b.zoom = zoom; |
|
var numPoints2 = b.numPoints || 1; |
|
wx += b.x * numPoints2; |
|
wy += b.y * numPoints2; |
|
numPoints += numPoints2; |
|
b.parentId = id; |
|
if (reduce) { |
|
if (!clusterProperties) { |
|
clusterProperties = this._map(p, true); |
|
} |
|
reduce(clusterProperties, this._map(b)); |
|
} |
|
} |
|
if (numPoints === 1) { |
|
clusters.push(p); |
|
} else { |
|
p.parentId = id; |
|
clusters.push(createCluster(wx / numPoints, wy / numPoints, id, numPoints, clusterProperties)); |
|
} |
|
} |
|
return clusters; |
|
}; |
|
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, loadGeoJSON) { |
|
VectorTileWorkerSource.call(this, actor, layerIndex, 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 wrapper.Performance(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 { |
|
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) { |
|
symbol_layout.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) { |
|
callback(null, this._geoJSONIndex.getClusterExpansionZoom(params.clusterId)); |
|
}; |
|
GeoJSONWorkerSource.prototype.getClusterChildren = function getClusterChildren(params, callback) { |
|
callback(null, this._geoJSONIndex.getChildren(params.clusterId)); |
|
}; |
|
GeoJSONWorkerSource.prototype.getClusterLeaves = function getClusterLeaves(params, callback) { |
|
callback(null, this._geoJSONIndex.getLeaves(params.clusterId, params.limit, params.offset)); |
|
}; |
|
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 = symbol_layout.createExpression(mapExpression); |
|
var reduceExpressionParsed = symbol_layout.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 symbol_layout.Actor(self, this); |
|
this.layerIndexes = {}; |
|
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 (symbol_layout.plugin.isLoaded()) { |
|
throw new Error('RTL text plugin already registered.'); |
|
} |
|
symbol_layout.plugin['applyArabicShaping'] = rtlTextPlugin.applyArabicShaping; |
|
symbol_layout.plugin['processBidirectionalText'] = rtlTextPlugin.processBidirectionalText; |
|
symbol_layout.plugin['processStyledBidirectionalText'] = rtlTextPlugin.processStyledBidirectionalText; |
|
}; |
|
}; |
|
Worker.prototype.setReferrer = function setReferrer(mapID, referrer) { |
|
this.referrer = referrer; |
|
}; |
|
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.loadRTLTextPlugin = function loadRTLTextPlugin(map, pluginURL, callback) { |
|
try { |
|
if (!symbol_layout.plugin.isLoaded()) { |
|
this.self.importScripts(pluginURL); |
|
callback(symbol_layout.plugin.isLoaded() ? null : new Error('RTL Text Plugin failed to import scripts from ' + pluginURL)); |
|
} |
|
} catch (e) { |
|
callback(e.toString()); |
|
} |
|
}; |
|
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)); |
|
} |
|
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) { |
|
symbol_layout.enforceCacheSizeLimit(limit); |
|
}; |
|
if (typeof WorkerGlobalScope !== 'undefined' && typeof symbol_layout.window !== 'undefined' && symbol_layout.window instanceof WorkerGlobalScope) { |
|
symbol_layout.window.worker = new Worker(symbol_layout.window); |
|
} |
|
|
|
return Worker; |
|
|
|
}); |
|
|
|
define(['./shared'], function (symbol_layout) { 'use strict'; |
|
|
|
var mapboxGlSupported = symbol_layout.createCommonjsModule(function (module) { |
|
if ( module.exports) { |
|
module.exports = isSupported; |
|
} else if (window) { |
|
window.mapboxgl = window.mapboxgl || {}; |
|
window.mapboxgl.supported = isSupported; |
|
} |
|
function isSupported(options) { |
|
return !!(isBrowser() && isArraySupported() && isFunctionSupported() && isObjectSupported() && isJSONSupported() && isWorkerSupported() && isUint8ClampedArraySupported() && isArrayBufferSupported() && isWebGLSupportedCached(options && options.failIfMajorPerformanceCaveat)); |
|
} |
|
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; |
|
} |
|
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 isWebGLSupported(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); |
|
} |
|
} |
|
}); |
|
|
|
var DOM = {}; |
|
DOM.create = function (tagName, className, container) { |
|
var el = symbol_layout.window.document.createElement(tagName); |
|
if (className !== undefined) { |
|
el.className = className; |
|
} |
|
if (container) { |
|
container.appendChild(el); |
|
} |
|
return el; |
|
}; |
|
DOM.createNS = function (namespaceURI, tagName) { |
|
var el = symbol_layout.window.document.createElementNS(namespaceURI, tagName); |
|
return el; |
|
}; |
|
var docStyle = symbol_layout.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; |
|
} |
|
}); |
|
symbol_layout.window.addEventListener('test', options$1, options$1); |
|
symbol_layout.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(); |
|
symbol_layout.window.removeEventListener('click', suppressClick, true); |
|
}; |
|
DOM.suppressClick = function () { |
|
symbol_layout.window.addEventListener('click', suppressClick, true); |
|
symbol_layout.window.setTimeout(function () { |
|
symbol_layout.window.removeEventListener('click', suppressClick, true); |
|
}, 0); |
|
}; |
|
DOM.mousePos = function (el, e) { |
|
var rect = el.getBoundingClientRect(); |
|
var t = symbol_layout.window.TouchEvent && e instanceof symbol_layout.window.TouchEvent ? e.touches[0] : e; |
|
return new symbol_layout.Point(t.clientX - rect.left - el.clientLeft, t.clientY - rect.top - el.clientTop); |
|
}; |
|
DOM.touchPos = function (el, e) { |
|
var rect = el.getBoundingClientRect(), points = []; |
|
var touches = e.type === 'touchend' ? e.changedTouches : e.touches; |
|
for (var i = 0; i < touches.length; i++) { |
|
points.push(new symbol_layout.Point(touches[i].clientX - rect.left - el.clientLeft, touches[i].clientY - rect.top - el.clientTop)); |
|
} |
|
return points; |
|
}; |
|
DOM.mouseButton = function (e) { |
|
if (typeof symbol_layout.window.InstallTrigger !== 'undefined' && e.button === 2 && e.ctrlKey && symbol_layout.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 = symbol_layout.browser.devicePixelRatio > 1 ? '@2x' : ''; |
|
var jsonRequest = symbol_layout.getJSON(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.json'), symbol_layout.ResourceType.SpriteJSON), function (err, data) { |
|
jsonRequest = null; |
|
if (!error) { |
|
error = err; |
|
json = data; |
|
maybeComplete(); |
|
} |
|
}); |
|
var imageRequest = symbol_layout.getImage(requestManager.transformRequest(requestManager.normalizeSpriteURL(baseURL, format, '.png'), symbol_layout.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 = symbol_layout.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 data = new symbol_layout.RGBAImage({ |
|
width: width, |
|
height: height |
|
}); |
|
symbol_layout.RGBAImage.copy(imageData, data, { |
|
x: x, |
|
y: y |
|
}, { |
|
x: 0, |
|
y: 0 |
|
}, { |
|
width: width, |
|
height: height |
|
}); |
|
result[id] = { |
|
data: data, |
|
pixelRatio: pixelRatio, |
|
sdf: sdf |
|
}; |
|
} |
|
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 symbol_layout.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) { |
|
this.images[id] = image; |
|
}; |
|
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 symbol_layout.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, |
|
hasRenderCallback: Boolean(image.userImage && image.userImage.render) |
|
}; |
|
} else { |
|
symbol_layout.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 symbol_layout.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 symbol_layout.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 = symbol_layout.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; |
|
symbol_layout.RGBAImage.copy(src, dst, { |
|
x: 0, |
|
y: 0 |
|
}, { |
|
x: x, |
|
y: y |
|
}, { |
|
width: w$1, |
|
height: h$1 |
|
}); |
|
symbol_layout.RGBAImage.copy(src, dst, { |
|
x: 0, |
|
y: h$1 - 1 |
|
}, { |
|
x: x, |
|
y: y - 1 |
|
}, { |
|
width: w$1, |
|
height: 1 |
|
}); |
|
symbol_layout.RGBAImage.copy(src, dst, { |
|
x: 0, |
|
y: 0 |
|
}, { |
|
x: x, |
|
y: y + h$1 |
|
}, { |
|
width: w$1, |
|
height: 1 |
|
}); |
|
symbol_layout.RGBAImage.copy(src, dst, { |
|
x: w$1 - 1, |
|
y: 0 |
|
}, { |
|
x: x - 1, |
|
y: y |
|
}, { |
|
width: 1, |
|
height: h$1 |
|
}); |
|
symbol_layout.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; |
|
}(symbol_layout.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), symbol_layout.ResourceType.Glyphs); |
|
symbol_layout.getArrayBuffer(request, function (err, data) { |
|
if (err) { |
|
callback(err); |
|
} else if (data) { |
|
var glyphs = {}; |
|
for (var i = 0, list = symbol_layout.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 |
|
}); |
|
} |
|
} |
|
symbol_layout.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: {} |
|
}; |
|
} |
|
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; |
|
} |
|
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]; |
|
} |
|
} |
|
} |
|
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 && (symbol_layout.isChar['CJK Unified Ideographs'](id) || symbol_layout.isChar['Hangul Syllables'](id) || symbol_layout.isChar['Hiragana'](id) || symbol_layout.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 symbol_layout.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 = symbol_layout.styleSpec.light.position; |
|
}; |
|
LightPositionProperty.prototype.possiblyEvaluate = function possiblyEvaluate(value, parameters) { |
|
return symbol_layout.sphericalToCartesian(value.expression.evaluate(parameters)); |
|
}; |
|
LightPositionProperty.prototype.interpolate = function interpolate$1(a, b, t) { |
|
return { |
|
x: symbol_layout.number(a.x, b.x, t), |
|
y: symbol_layout.number(a.y, b.y, t), |
|
z: symbol_layout.number(a.z, b.z, t) |
|
}; |
|
}; |
|
var properties = new symbol_layout.Properties({ |
|
'anchor': new symbol_layout.DataConstantProperty(symbol_layout.styleSpec.light.anchor), |
|
'position': new LightPositionProperty(), |
|
'color': new symbol_layout.DataConstantProperty(symbol_layout.styleSpec.light.color), |
|
'intensity': new symbol_layout.DataConstantProperty(symbol_layout.styleSpec.light.intensity) |
|
}); |
|
var TRANSITION_SUFFIX = '-transition'; |
|
var Light = function (Evented) { |
|
function Light(lightOptions) { |
|
Evented.call(this); |
|
this._transitionable = new symbol_layout.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(symbol_layout.validateLight, light, options)) { |
|
return; |
|
} |
|
for (var name in light) { |
|
var value = light[name]; |
|
if (symbol_layout.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 symbol_layout.emitValidationErrors(this, validate.call(symbol_layout.validateStyle, symbol_layout.extend({ |
|
value: value, |
|
style: { |
|
glyphs: true, |
|
sprite: true |
|
}, |
|
styleSpec: symbol_layout.styleSpec |
|
}))); |
|
}; |
|
return Light; |
|
}(symbol_layout.Evented); |
|
|
|
var LineAtlas = function LineAtlas(width, height) { |
|
this.width = width; |
|
this.height = height; |
|
this.nextRow = 0; |
|
this.bytes = 4; |
|
this.data = new Uint8Array(this.width * this.height * this.bytes); |
|
this.positions = {}; |
|
}; |
|
LineAtlas.prototype.getDash = function getDash(dasharray, round) { |
|
var key = dasharray.join(',') + String(round); |
|
if (!this.positions[key]) { |
|
this.positions[key] = this.addDash(dasharray, round); |
|
} |
|
return this.positions[key]; |
|
}; |
|
LineAtlas.prototype.addDash = function addDash(dasharray, round) { |
|
var n = round ? 7 : 0; |
|
var height = 2 * n + 1; |
|
var offset = 128; |
|
if (this.nextRow + height > this.height) { |
|
symbol_layout.warnOnce('LineAtlas out of space'); |
|
return null; |
|
} |
|
var length = 0; |
|
for (var i = 0; i < dasharray.length; i++) { |
|
length += dasharray[i]; |
|
} |
|
var stretch = this.width / length; |
|
var halfWidth = stretch / 2; |
|
var oddLength = dasharray.length % 2 === 1; |
|
for (var y = -n; y <= n; y++) { |
|
var row = this.nextRow + n + y; |
|
var index = this.width * row; |
|
var left = oddLength ? -dasharray[dasharray.length - 1] : 0; |
|
var right = dasharray[0]; |
|
var partIndex = 1; |
|
for (var x = 0; x < this.width; x++) { |
|
while (right < x / stretch) { |
|
left = right; |
|
right = right + dasharray[partIndex]; |
|
if (oddLength && partIndex === dasharray.length - 1) { |
|
right += dasharray[0]; |
|
} |
|
partIndex++; |
|
} |
|
var distLeft = Math.abs(x - left * stretch); |
|
var distRight = Math.abs(x - right * stretch); |
|
var dist = Math.min(distLeft, distRight); |
|
var inside = partIndex % 2 === 1; |
|
var signedDistance = void 0; |
|
if (round) { |
|
var distMiddle = n ? y / n * (halfWidth + 1) : 0; |
|
if (inside) { |
|
var distEdge = halfWidth - Math.abs(distMiddle); |
|
signedDistance = Math.sqrt(dist * dist + distEdge * distEdge); |
|
} else { |
|
signedDistance = halfWidth - Math.sqrt(dist * dist + distMiddle * distMiddle); |
|
} |
|
} else { |
|
signedDistance = (inside ? 1 : -1) * dist; |
|
} |
|
this.data[3 + (index + x) * 4] = Math.max(0, Math.min(255, signedDistance + offset)); |
|
} |
|
} |
|
var pos = { |
|
y: (this.nextRow + n + 0.5) / this.height, |
|
height: 2 * n / this.height, |
|
width: length |
|
}; |
|
this.nextRow += height; |
|
this.dirty = true; |
|
return pos; |
|
}; |
|
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.RGBA, this.width, this.height, 0, gl.RGBA, 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.RGBA, gl.UNSIGNED_BYTE, this.data); |
|
} |
|
} |
|
}; |
|
|
|
var Dispatcher = function Dispatcher(workerPool, parent) { |
|
this.workerPool = workerPool; |
|
this.actors = []; |
|
this.currentActor = 0; |
|
this.id = symbol_layout.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 () { |
|
}; |
|
symbol_layout.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 = symbol_layout.Actor; |
|
|
|
function loadTileJSON (options, requestManager, callback) { |
|
var loaded = function (err, tileJSON) { |
|
if (err) { |
|
return callback(err); |
|
} else if (tileJSON) { |
|
var result = symbol_layout.pick(symbol_layout.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; |
|
}); |
|
} |
|
if (options.url) { |
|
result.tiles = requestManager.canonicalizeTileset(result, options.url); |
|
} |
|
callback(null, result); |
|
} |
|
}; |
|
if (options.url) { |
|
return symbol_layout.getJSON(requestManager.transformRequest(requestManager.normalizeSourceURL(options.url), symbol_layout.ResourceType.Source), loaded); |
|
} else { |
|
return symbol_layout.browser.frame(function () { |
|
return loaded(null, options); |
|
}); |
|
} |
|
} |
|
|
|
var TileBounds = function TileBounds(bounds, minzoom, maxzoom) { |
|
this.bounds = symbol_layout.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(symbol_layout.mercatorXfromLng(this.bounds.getWest()) * worldSize), |
|
minY: Math.floor(symbol_layout.mercatorYfromLat(this.bounds.getNorth()) * worldSize), |
|
maxX: Math.ceil(symbol_layout.mercatorXfromLng(this.bounds.getEast()) * worldSize), |
|
maxY: Math.ceil(symbol_layout.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; |
|
symbol_layout.extend(this, symbol_layout.pick(options, [ |
|
'url', |
|
'scheme', |
|
'tileSize' |
|
])); |
|
this._options = symbol_layout.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 symbol_layout.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 symbol_layout.ErrorEvent(err)); |
|
} else if (tileJSON) { |
|
symbol_layout.extend(this$1, tileJSON); |
|
if (tileJSON.bounds) { |
|
this$1.tileBounds = new TileBounds(tileJSON.bounds, this$1.minzoom, this$1.maxzoom); |
|
} |
|
symbol_layout.postTurnstileEvent(tileJSON.tiles, this$1.map._requestManager._customAccessToken); |
|
symbol_layout.postMapLoadEvent(tileJSON.tiles, this$1.map._getMapId(), this$1.map._requestManager._skuToken, this$1.map._requestManager._customAccessToken); |
|
this$1.fire(new symbol_layout.Event('data', { |
|
dataType: 'source', |
|
sourceDataType: 'metadata' |
|
})); |
|
this$1.fire(new symbol_layout.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.onRemove = function onRemove() { |
|
if (this._tileJSONRequest) { |
|
this._tileJSONRequest.cancel(); |
|
this._tileJSONRequest = null; |
|
} |
|
}; |
|
VectorTileSource.prototype.serialize = function serialize() { |
|
return symbol_layout.extend({}, this._options); |
|
}; |
|
VectorTileSource.prototype.loadTile = function loadTile(tile, callback) { |
|
var url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), this.url, null); |
|
var params = { |
|
request: this.map._requestManager.transformRequest(url, symbol_layout.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: symbol_layout.browser.devicePixelRatio, |
|
showCollisionBoxes: this.map.showCollisionBoxes |
|
}; |
|
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); |
|
symbol_layout.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; |
|
}(symbol_layout.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 = symbol_layout.extend({ type: 'raster' }, options); |
|
symbol_layout.extend(this, symbol_layout.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 symbol_layout.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 symbol_layout.ErrorEvent(err)); |
|
} else if (tileJSON) { |
|
symbol_layout.extend(this$1, tileJSON); |
|
if (tileJSON.bounds) { |
|
this$1.tileBounds = new TileBounds(tileJSON.bounds, this$1.minzoom, this$1.maxzoom); |
|
} |
|
symbol_layout.postTurnstileEvent(tileJSON.tiles); |
|
symbol_layout.postMapLoadEvent(tileJSON.tiles, this$1.map._getMapId(), this$1.map._requestManager._skuToken); |
|
this$1.fire(new symbol_layout.Event('data', { |
|
dataType: 'source', |
|
sourceDataType: 'metadata' |
|
})); |
|
this$1.fire(new symbol_layout.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 symbol_layout.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.url, this.tileSize); |
|
tile.request = symbol_layout.getImage(this.map._requestManager.transformRequest(url, symbol_layout.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 symbol_layout.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'; |
|
symbol_layout.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; |
|
}(symbol_layout.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 = symbol_layout.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.url, this.tileSize); |
|
tile.request = symbol_layout.getImage(this.map._requestManager.transformRequest(url, symbol_layout.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 rawImageData = symbol_layout.browser.getImageData(img); |
|
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 symbol_layout.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y).key] = { backfilled: false }; |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y).key] = { backfilled: false }; |
|
if (canonical.y > 0) { |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y - 1).key] = { backfilled: false }; |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y - 1).key] = { backfilled: false }; |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y - 1).key] = { backfilled: false }; |
|
} |
|
if (canonical.y + 1 < dim) { |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y + 1).key] = { backfilled: false }; |
|
neighboringTiles[new symbol_layout.OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y + 1).key] = { backfilled: false }; |
|
neighboringTiles[new symbol_layout.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 = symbol_layout.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; |
|
} |
|
var scale = symbol_layout.EXTENT / this.tileSize; |
|
this.workerOptions = symbol_layout.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: symbol_layout.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, |
|
extent: symbol_layout.EXTENT, |
|
radius: (options.clusterRadius || 50) * scale, |
|
log: false |
|
}, |
|
clusterProperties: options.clusterProperties |
|
}, 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 symbol_layout.Event('dataloading', { dataType: 'source' })); |
|
this._updateWorkerData(function (err) { |
|
if (err) { |
|
this$1.fire(new symbol_layout.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 symbol_layout.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 symbol_layout.Event('dataloading', { dataType: 'source' })); |
|
this._updateWorkerData(function (err) { |
|
if (err) { |
|
this$1.fire(new symbol_layout.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 symbol_layout.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 = symbol_layout.extend({}, this.workerOptions); |
|
var data = this._data; |
|
if (typeof data === 'string') { |
|
options.request = this.map._requestManager.transformRequest(symbol_layout.browser.resolveURL(data), symbol_layout.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: symbol_layout.browser.devicePixelRatio, |
|
showCollisionBoxes: this.map.showCollisionBoxes |
|
}; |
|
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 symbol_layout.extend({}, this._options, { |
|
type: this.type, |
|
data: this._data |
|
}); |
|
}; |
|
GeoJSONSource.prototype.hasTransition = function hasTransition() { |
|
return false; |
|
}; |
|
return GeoJSONSource; |
|
}(symbol_layout.Evented); |
|
|
|
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 symbol_layout.Event('dataloading', { dataType: 'source' })); |
|
this.url = this.options.url; |
|
symbol_layout.getImage(this.map._requestManager.transformRequest(this.url, symbol_layout.ResourceType.Image), function (err, image) { |
|
this$1._loaded = true; |
|
if (err) { |
|
this$1.fire(new symbol_layout.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 symbol_layout.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(symbol_layout.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 symbol_layout.StructArrayLayout4i8(); |
|
this._boundsArray.emplaceBack(tileCoords[0].x, tileCoords[0].y, 0, 0); |
|
this._boundsArray.emplaceBack(tileCoords[1].x, tileCoords[1].y, symbol_layout.EXTENT, 0); |
|
this._boundsArray.emplaceBack(tileCoords[3].x, tileCoords[3].y, 0, symbol_layout.EXTENT); |
|
this._boundsArray.emplaceBack(tileCoords[2].x, tileCoords[2].y, symbol_layout.EXTENT, symbol_layout.EXTENT); |
|
if (this.boundsBuffer) { |
|
this.boundsBuffer.destroy(); |
|
delete this.boundsBuffer; |
|
} |
|
this.fire(new symbol_layout.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, symbol_layout.rasterBoundsAttributes.members); |
|
} |
|
if (!this.boundsSegments) { |
|
this.boundsSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
} |
|
if (!this.texture) { |
|
this.texture = new symbol_layout.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; |
|
}(symbol_layout.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 symbol_layout.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, symbol_layout.ResourceType.Source).url); |
|
} |
|
symbol_layout.getVideo(this.urls, function (err, video) { |
|
this$1._loaded = true; |
|
if (err) { |
|
this$1.fire(new symbol_layout.ErrorEvent(err)); |
|
} else if (video) { |
|
this$1.video = video; |
|
this$1.video.loop = true; |
|
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 symbol_layout.ErrorEvent(new symbol_layout.ValidationError('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, symbol_layout.rasterBoundsAttributes.members); |
|
} |
|
if (!this.boundsSegments) { |
|
this.boundsSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
} |
|
if (!this.texture) { |
|
this.texture = new symbol_layout.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 symbol_layout.ErrorEvent(new symbol_layout.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 symbol_layout.ErrorEvent(new symbol_layout.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 symbol_layout.ErrorEvent(new symbol_layout.ValidationError('sources.' + id, null, 'optional "animate" property must be a boolean value'))); |
|
} |
|
if (!options.canvas) { |
|
this.fire(new symbol_layout.ErrorEvent(new symbol_layout.ValidationError('sources.' + id, null, 'missing required property "canvas"'))); |
|
} else if (typeof options.canvas !== 'string' && !(options.canvas instanceof symbol_layout.window.HTMLCanvasElement)) { |
|
this.fire(new symbol_layout.ErrorEvent(new symbol_layout.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 symbol_layout.window.HTMLCanvasElement ? this.options.canvas : symbol_layout.window.document.getElementById(this.options.canvas); |
|
} |
|
this.width = this.canvas.width; |
|
this.height = this.canvas.height; |
|
if (this._hasInvalidDimensions()) { |
|
this.fire(new symbol_layout.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, symbol_layout.rasterBoundsAttributes.members); |
|
} |
|
if (!this.boundsSegments) { |
|
this.boundsSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
} |
|
if (!this.texture) { |
|
this.texture = new symbol_layout.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); |
|
} |
|
symbol_layout.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 = symbol_layout.identity([]); |
|
symbol_layout.translate(t, t, [ |
|
1, |
|
1, |
|
0 |
|
]); |
|
symbol_layout.scale(t, t, [ |
|
transform.width * 0.5, |
|
transform.height * 0.5, |
|
1 |
|
]); |
|
return symbol_layout.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, 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, 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, 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], queryData.bucketIndex, queryData.sourceLayerIndex, params.filter, params.layers, 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.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; |
|
}; |
|
|
|
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 symbol_layout.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 symbol_layout.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) { |
|
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); |
|
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); |
|
} |
|
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, symbol_layout.Color.transparent, [ |
|
false, |
|
false, |
|
false, |
|
false |
|
]); |
|
ColorMode.unblended = new ColorMode(ColorMode.Replace, symbol_layout.Color.transparent, [ |
|
true, |
|
true, |
|
true, |
|
true |
|
]); |
|
ColorMode.alphaBlended = new ColorMode([ |
|
ONE, |
|
ONE_MINUS_SRC_ALPHA |
|
], symbol_layout.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'); |
|
} |
|
}; |
|
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) { |
|
return new Framebuffer(this, width, height); |
|
}; |
|
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 (symbol_layout.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._coveredTiles = {}; |
|
this._state = new symbol_layout.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 Object.keys(this._tiles).map(Number).sort(compareKeyZoom); |
|
}; |
|
SourceCache.prototype.getRenderableIds = function getRenderableIds(symbolLayer) { |
|
var this$1 = this; |
|
var ids = []; |
|
for (var id in this._tiles) { |
|
if (this._isIdRenderable(+id, symbolLayer)) { |
|
ids.push(+id); |
|
} |
|
} |
|
if (symbolLayer) { |
|
return ids.sort(function (a_, b_) { |
|
var a = this$1._tiles[a_].tileID; |
|
var b = this$1._tiles[b_].tileID; |
|
var rotatedA = new symbol_layout.Point(a.canonical.x, a.canonical.y)._rotate(this$1.transform.angle); |
|
var rotatedB = new symbol_layout.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; |
|
}); |
|
} |
|
return ids.sort(compareKeyZoom); |
|
}; |
|
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 symbol_layout.ErrorEvent(err, { tile: tile })); |
|
} else { |
|
this.update(this.transform); |
|
} |
|
return; |
|
} |
|
tile.timeAdded = symbol_layout.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 symbol_layout.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.getZoom = function getZoom(transform) { |
|
return transform.zoom + transform.scaleZoom(transform.tileSize / this._source.tileSize); |
|
}; |
|
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) { |
|
for (var z = tileID.overscaledZ - 1; z >= minCoveringZoom; z--) { |
|
var parent = tileID.scaledTo(z); |
|
if (!parent) { |
|
return; |
|
} |
|
var id = String(parent.key); |
|
var tile = this._tiles[id]; |
|
if (tile && tile.hasData()) { |
|
return tile; |
|
} |
|
if (this._cache.has(parent)) { |
|
return this._cache.get(parent); |
|
} |
|
} |
|
}; |
|
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 symbol_layout.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 = (this._source.roundZoom ? Math.round : Math.floor)(this.getZoom(transform)); |
|
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 <= symbol_layout.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 = symbol_layout.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); |
|
} |
|
} |
|
}; |
|
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._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 symbol_layout.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 symbol_layout.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 * symbol_layout.EXTENT / tile.tileSize / scale; |
|
var tileSpaceBounds = [ |
|
tileID.getTilePoint(new symbol_layout.MercatorCoordinate(minX, minY)), |
|
tileID.getTilePoint(new symbol_layout.MercatorCoordinate(maxX, maxY)) |
|
]; |
|
if (tileSpaceBounds[0].x - queryPadding < symbol_layout.EXTENT && tileSpaceBounds[0].y - queryPadding < symbol_layout.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 >= symbol_layout.browser.now()) { |
|
return true; |
|
} |
|
} |
|
} |
|
return false; |
|
}; |
|
SourceCache.prototype.setFeatureState = function setFeatureState(sourceLayer, feature, state) { |
|
sourceLayer = sourceLayer || '_geojsonTileLayer'; |
|
this._state.updateState(sourceLayer, feature, state); |
|
}; |
|
SourceCache.prototype.removeFeatureState = function removeFeatureState(sourceLayer, feature, key) { |
|
sourceLayer = sourceLayer || '_geojsonTileLayer'; |
|
this._state.removeFeatureState(sourceLayer, feature, key); |
|
}; |
|
SourceCache.prototype.getFeatureState = function getFeatureState(sourceLayer, feature) { |
|
sourceLayer = sourceLayer || '_geojsonTileLayer'; |
|
return this._state.getState(sourceLayer, feature); |
|
}; |
|
return SourceCache; |
|
}(symbol_layout.Evented); |
|
SourceCache.maxOverzooming = 10; |
|
SourceCache.maxUnderzooming = 3; |
|
function compareKeyZoom(a, b) { |
|
return a % 32 - b % 32 || b - a; |
|
} |
|
function isRasterType(type) { |
|
return type === 'raster' || type === 'image' || type === 'video'; |
|
} |
|
|
|
function WebWorker () { |
|
return new symbol_layout.window.Worker(exported.workerUrl); |
|
} |
|
|
|
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 (Object.keys(this.active).length === 0) { |
|
this.workers.forEach(function (w) { |
|
w.terminate(); |
|
}); |
|
this.workers = null; |
|
} |
|
}; |
|
var availableLogicalProcessors = Math.floor(symbol_layout.browser.hardwareConcurrency / 2); |
|
WorkerPool.workerCount = Math.max(Math.min(availableLogicalProcessors, 6), 1); |
|
|
|
var globalWorkerPool; |
|
function getGlobalWorkerPool() { |
|
if (!globalWorkerPool) { |
|
globalWorkerPool = new WorkerPool(); |
|
} |
|
return globalWorkerPool; |
|
} |
|
|
|
function deref(layer, parent) { |
|
var result = {}; |
|
for (var k in layer) { |
|
if (k !== 'ref') { |
|
result[k] = layer[k]; |
|
} |
|
} |
|
symbol_layout.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; |
|
} |
|
|
|
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' && !symbol_layout.deepEqual(before[sourceId][prop], after[sourceId][prop])) { |
|
return false; |
|
} |
|
} |
|
for (prop in after[sourceId]) { |
|
if (!after[sourceId].hasOwnProperty(prop)) { |
|
continue; |
|
} |
|
if (prop !== 'data' && !symbol_layout.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 (!symbol_layout.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 (!symbol_layout.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 (!symbol_layout.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] || symbol_layout.deepEqual(beforeLayer, afterLayer)) { |
|
continue; |
|
} |
|
if (!symbol_layout.deepEqual(beforeLayer.source, afterLayer.source) || !symbol_layout.deepEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !symbol_layout.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 (!symbol_layout.deepEqual(beforeLayer.filter, afterLayer.filter)) { |
|
commands.push({ |
|
command: operations.setFilter, |
|
args: [ |
|
layerId, |
|
afterLayer.filter |
|
] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(beforeLayer.minzoom, afterLayer.minzoom) || !symbol_layout.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 (!symbol_layout.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 (!symbol_layout.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 (!symbol_layout.deepEqual(before.version, after.version)) { |
|
return [{ |
|
command: operations.setStyle, |
|
args: [after] |
|
}]; |
|
} |
|
if (!symbol_layout.deepEqual(before.center, after.center)) { |
|
commands.push({ |
|
command: operations.setCenter, |
|
args: [after.center] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.zoom, after.zoom)) { |
|
commands.push({ |
|
command: operations.setZoom, |
|
args: [after.zoom] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.bearing, after.bearing)) { |
|
commands.push({ |
|
command: operations.setBearing, |
|
args: [after.bearing] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.pitch, after.pitch)) { |
|
commands.push({ |
|
command: operations.setPitch, |
|
args: [after.pitch] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.sprite, after.sprite)) { |
|
commands.push({ |
|
command: operations.setSprite, |
|
args: [after.sprite] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.glyphs, after.glyphs)) { |
|
commands.push({ |
|
command: operations.setGlyphs, |
|
args: [after.glyphs] |
|
}); |
|
} |
|
if (!symbol_layout.deepEqual(before.transition, after.transition)) { |
|
commands.push({ |
|
command: operations.setTransition, |
|
args: [after.transition] |
|
}); |
|
} |
|
if (!symbol_layout.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 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 = symbol_layout.create(); |
|
if (pitchWithMap) { |
|
symbol_layout.scale(m, m, [ |
|
1 / pixelsToTileUnits, |
|
1 / pixelsToTileUnits, |
|
1 |
|
]); |
|
if (!rotateWithMap) { |
|
symbol_layout.rotateZ(m, m, transform.angle); |
|
} |
|
} else { |
|
symbol_layout.multiply(m, transform.labelPlaneMatrix, posMatrix); |
|
} |
|
return m; |
|
} |
|
function getGlCoordMatrix(posMatrix, pitchWithMap, rotateWithMap, transform, pixelsToTileUnits) { |
|
if (pitchWithMap) { |
|
var m = symbol_layout.clone(posMatrix); |
|
symbol_layout.scale(m, m, [ |
|
pixelsToTileUnits, |
|
pixelsToTileUnits, |
|
1 |
|
]); |
|
if (!rotateWithMap) { |
|
symbol_layout.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 symbol_layout.Point(pos[0] / w, pos[1] / w), |
|
signedDistanceFromCamera: w |
|
}; |
|
} |
|
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 = symbol_layout.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 === symbol_layout.WritingMode.vertical && !useVertical) { |
|
hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); |
|
continue; |
|
} |
|
useVertical = false; |
|
var anchorPos = [ |
|
symbol.anchorX, |
|
symbol.anchorY, |
|
0, |
|
1 |
|
]; |
|
symbol_layout.transformMat4(anchorPos, anchorPos, posMatrix); |
|
if (!isVisible(anchorPos, clippingBuffer)) { |
|
hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); |
|
continue; |
|
} |
|
var cameraToAnchorDistance = anchorPos[3]; |
|
var perspectiveRatio = 0.5 + 0.5 * (cameraToAnchorDistance / painter.transform.cameraToCenterDistance); |
|
var fontSize = symbol_layout.evaluateSizeForFeature(sizeData, partiallyEvaluatedSize, symbol); |
|
var pitchScaledFontSize = pitchWithMap ? fontSize * perspectiveRatio : fontSize / perspectiveRatio; |
|
var tileAnchorPoint = new symbol_layout.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, returnTileDistance) { |
|
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, returnTileDistance); |
|
if (!firstPlacedGlyph) { |
|
return null; |
|
} |
|
var lastPlacedGlyph = placeGlyphAlongLine(fontScale * lastGlyphOffset, lineOffsetX, lineOffsetY, flip, anchorPoint, tileAnchorPoint, symbol.segment, lineStartIndex, lineEndIndex, lineVertexArray, labelPlaneMatrix, projectionCache, returnTileDistance); |
|
if (!lastPlacedGlyph) { |
|
return null; |
|
} |
|
return { |
|
first: firstPlacedGlyph, |
|
last: lastPlacedGlyph |
|
}; |
|
} |
|
function requiresOrientationChange(writingMode, firstPoint, lastPoint, aspectRatio) { |
|
if (writingMode === symbol_layout.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 === symbol_layout.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, false); |
|
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, false)); |
|
} |
|
placedGlyphs.push(firstAndLastGlyph.last); |
|
} else { |
|
if (keepUpright && !flip) { |
|
var a = project(tileAnchorPoint, posMatrix).point; |
|
var tileVertexIndex = symbol.lineStartIndex + symbol.segment + 1; |
|
var tileSegmentEnd = new symbol_layout.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, false); |
|
if (!singleGlyph) { |
|
return { notEnoughRoom: true }; |
|
} |
|
placedGlyphs = [singleGlyph]; |
|
} |
|
for (var i = 0, list = placedGlyphs; i < list.length; i += 1) { |
|
var glyph = list[i]; |
|
symbol_layout.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, returnTileDistance) { |
|
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 initialIndex = currentIndex; |
|
var current = anchorPoint; |
|
var prev = anchorPoint; |
|
var distanceToPrev = 0; |
|
var currentSegmentDistance = 0; |
|
var absOffsetX = Math.abs(combinedOffsetX); |
|
while (distanceToPrev + currentSegmentDistance <= absOffsetX) { |
|
currentIndex += dir; |
|
if (currentIndex < lineStartIndex || currentIndex >= lineEndIndex) { |
|
return null; |
|
} |
|
prev = current; |
|
current = projectionCache[currentIndex]; |
|
if (current === undefined) { |
|
var currentVertex = new symbol_layout.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 symbol_layout.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); |
|
return { |
|
point: p, |
|
angle: segmentAngle, |
|
tileDistance: returnTileDistance ? { |
|
prevTileDistance: currentIndex - dir === initialIndex ? 0 : lineVertexArray.gettileUnitDistanceFromAnchor(currentIndex - dir), |
|
lastSegmentViewportDistance: absOffsetX - distanceToPrev |
|
} : null |
|
}; |
|
} |
|
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.approximateTileDistance = function approximateTileDistance(tileDistance, lastSegmentAngle, pixelsToTileUnits, cameraToAnchorDistance, pitchWithMap) { |
|
var incidenceStretch = pitchWithMap ? 1 : cameraToAnchorDistance / this.pitchfactor; |
|
var lastSegmentTile = tileDistance.lastSegmentViewportDistance * pixelsToTileUnits; |
|
return tileDistance.prevTileDistance + lastSegmentTile + (incidenceStretch - 1) * lastSegmentTile * Math.abs(Math.sin(lastSegmentAngle)); |
|
}; |
|
CollisionIndex.prototype.placeCollisionCircles = function placeCollisionCircles(collisionCircles, allowOverlap, scale, textPixelRatio, symbol, lineVertexArray, glyphOffsetArray, fontSize, posMatrix, labelPlaneMatrix, showCollisionCircles, pitchWithMap, collisionGroupPredicate) { |
|
var placedCollisionCircles = []; |
|
var projectedAnchor = this.projectAnchor(posMatrix, symbol.anchorX, symbol.anchorY); |
|
var projectionCache = {}; |
|
var fontScale = fontSize / 24; |
|
var lineOffsetX = symbol.lineOffsetX * fontSize; |
|
var lineOffsetY = symbol.lineOffsetY * fontSize; |
|
var tileUnitAnchorPoint = new symbol_layout.Point(symbol.anchorX, symbol.anchorY); |
|
var labelPlaneAnchorPoint = project(tileUnitAnchorPoint, labelPlaneMatrix).point; |
|
var firstAndLastGlyph = placeFirstAndLastGlyph(fontScale, glyphOffsetArray, lineOffsetX, lineOffsetY, false, labelPlaneAnchorPoint, tileUnitAnchorPoint, symbol, lineVertexArray, labelPlaneMatrix, projectionCache, true); |
|
var collisionDetected = false; |
|
var inGrid = false; |
|
var entirelyOffscreen = true; |
|
var tileToViewport = projectedAnchor.perspectiveRatio * textPixelRatio; |
|
var pixelsToTileUnits = 1 / (textPixelRatio * scale); |
|
var firstTileDistance = 0, lastTileDistance = 0; |
|
if (firstAndLastGlyph) { |
|
firstTileDistance = this.approximateTileDistance(firstAndLastGlyph.first.tileDistance, firstAndLastGlyph.first.angle, pixelsToTileUnits, projectedAnchor.cameraDistance, pitchWithMap); |
|
lastTileDistance = this.approximateTileDistance(firstAndLastGlyph.last.tileDistance, firstAndLastGlyph.last.angle, pixelsToTileUnits, projectedAnchor.cameraDistance, pitchWithMap); |
|
} |
|
for (var k = 0; k < collisionCircles.length; k += 5) { |
|
var anchorPointX = collisionCircles[k]; |
|
var anchorPointY = collisionCircles[k + 1]; |
|
var tileUnitRadius = collisionCircles[k + 2]; |
|
var boxSignedDistanceFromAnchor = collisionCircles[k + 3]; |
|
if (!firstAndLastGlyph || boxSignedDistanceFromAnchor < -firstTileDistance || boxSignedDistanceFromAnchor > lastTileDistance) { |
|
markCollisionCircleUsed(collisionCircles, k, false); |
|
continue; |
|
} |
|
var projectedPoint = this.projectPoint(posMatrix, anchorPointX, anchorPointY); |
|
var radius = tileUnitRadius * tileToViewport; |
|
var atLeastOneCirclePlaced = placedCollisionCircles.length > 0; |
|
if (atLeastOneCirclePlaced) { |
|
var dx = projectedPoint.x - placedCollisionCircles[placedCollisionCircles.length - 4]; |
|
var dy = projectedPoint.y - placedCollisionCircles[placedCollisionCircles.length - 3]; |
|
var placedTooDensely = radius * radius * 2 > dx * dx + dy * dy; |
|
if (placedTooDensely) { |
|
var atLeastOneMoreCircle = k + 8 < collisionCircles.length; |
|
if (atLeastOneMoreCircle) { |
|
var nextBoxDistanceToAnchor = collisionCircles[k + 8]; |
|
if (nextBoxDistanceToAnchor > -firstTileDistance && nextBoxDistanceToAnchor < lastTileDistance) { |
|
markCollisionCircleUsed(collisionCircles, k, false); |
|
continue; |
|
} |
|
} |
|
} |
|
} |
|
var collisionBoxArrayIndex = k / 5; |
|
placedCollisionCircles.push(projectedPoint.x, projectedPoint.y, radius, collisionBoxArrayIndex); |
|
markCollisionCircleUsed(collisionCircles, k, true); |
|
var x1 = projectedPoint.x - radius; |
|
var y1 = projectedPoint.y - radius; |
|
var x2 = projectedPoint.x + radius; |
|
var y2 = projectedPoint.y + radius; |
|
entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2); |
|
inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2); |
|
if (!allowOverlap) { |
|
if (this.grid.hitTestCircle(projectedPoint.x, projectedPoint.y, radius, collisionGroupPredicate)) { |
|
if (!showCollisionCircles) { |
|
return { |
|
circles: [], |
|
offscreen: false |
|
}; |
|
} else { |
|
collisionDetected = true; |
|
} |
|
} |
|
} |
|
} |
|
return { |
|
circles: collisionDetected || !inGrid ? [] : placedCollisionCircles, |
|
offscreen: entirelyOffscreen |
|
}; |
|
}; |
|
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 symbol_layout.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 symbol_layout.Point(feature.x1, feature.y1), |
|
new symbol_layout.Point(feature.x2, feature.y1), |
|
new symbol_layout.Point(feature.x2, feature.y2), |
|
new symbol_layout.Point(feature.x1, feature.y2) |
|
]; |
|
if (!symbol_layout.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.projectAnchor = function projectAnchor(posMatrix, x, y) { |
|
var p = [ |
|
x, |
|
y, |
|
0, |
|
1 |
|
]; |
|
xyTransformMat4(p, p, posMatrix); |
|
return { |
|
perspectiveRatio: 0.5 + 0.5 * (this.transform.cameraToCenterDistance / p[3]), |
|
cameraDistance: p[3] |
|
}; |
|
}; |
|
CollisionIndex.prototype.projectPoint = function projectPoint(posMatrix, x, y) { |
|
var p = [ |
|
x, |
|
y, |
|
0, |
|
1 |
|
]; |
|
xyTransformMat4(p, p, posMatrix); |
|
return new symbol_layout.Point((p[0] / p[3] + 1) / 2 * this.transform.width + viewportPadding, (-p[1] / p[3] + 1) / 2 * this.transform.height + viewportPadding); |
|
}; |
|
CollisionIndex.prototype.projectAndGetPerspectiveRatio = function projectAndGetPerspectiveRatio(posMatrix, x, y) { |
|
var p = [ |
|
x, |
|
y, |
|
0, |
|
1 |
|
]; |
|
xyTransformMat4(p, p, posMatrix); |
|
var a = new symbol_layout.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; |
|
}; |
|
function markCollisionCircleUsed(collisionCircles, index, used) { |
|
collisionCircles[index + 4] = used ? 1 : 0; |
|
} |
|
|
|
function pixelsToTileUnits (tile, pixelValue, z) { |
|
return pixelValue * (symbol_layout.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 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 calculateVariableLayoutOffset(anchor, width, height, radialOffset, textBoxScale) { |
|
var ref = symbol_layout.getAnchorAlignment(anchor); |
|
var horizontalAlign = ref.horizontalAlign; |
|
var verticalAlign = ref.verticalAlign; |
|
var shiftX = -(horizontalAlign - 0.5) * width; |
|
var shiftY = -(verticalAlign - 0.5) * height; |
|
var offset = symbol_layout.evaluateRadialOffset(anchor, radialOffset); |
|
return new symbol_layout.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 symbol_layout.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.prevPlacement = prevPlacement; |
|
if (prevPlacement) { |
|
prevPlacement.prevPlacement = undefined; |
|
} |
|
this.placedOrientations = {}; |
|
}; |
|
Placement.prototype.placeLayerTile = function placeLayerTile(styleLayer, tile, showCollisionBoxes, seenCrossTileIDs) { |
|
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 / symbol_layout.EXTENT; |
|
var posMatrix = this.transform.calculatePosMatrix(tile.tileID.toUnwrapped()); |
|
var textLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, layout.get('text-pitch-alignment') === 'map', layout.get('text-rotation-alignment') === 'map', this.transform, pixelsToTileUnits(tile, 1, this.transform.zoom)); |
|
var iconLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, layout.get('icon-pitch-alignment') === 'map', layout.get('icon-rotation-alignment') === 'map', this.transform, pixelsToTileUnits(tile, 1, this.transform.zoom)); |
|
this.retainedQueryData[symbolBucket.bucketInstanceId] = new RetainedQueryData(symbolBucket.bucketInstanceId, bucketFeatureIndex, symbolBucket.sourceLayerIndex, symbolBucket.index, tile.tileID); |
|
this.placeLayerBucket(symbolBucket, posMatrix, textLabelPlaneMatrix, iconLabelPlaneMatrix, scale, textPixelRatio, showCollisionBoxes, tile.holdingForFade(), seenCrossTileIDs, collisionBoxArray); |
|
}; |
|
Placement.prototype.attemptAnchorPlacement = function attemptAnchorPlacement(anchor, textBox, width, height, radialTextOffset, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, textAllowOverlap, symbolInstance, bucket, orientation) { |
|
var shift = calculateVariableLayoutOffset(anchor, width, height, radialTextOffset, textBoxScale); |
|
var placedGlyphBoxes = this.collisionIndex.placeCollisionBox(shiftVariableCollisionBox(textBox, shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle), textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); |
|
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] = { |
|
radialOffset: radialTextOffset, |
|
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 placedGlyphBoxes; |
|
} |
|
}; |
|
Placement.prototype.placeLayerBucket = function placeLayerBucket(bucket, posMatrix, textLabelPlaneMatrix, iconLabelPlaneMatrix, scale, textPixelRatio, showCollisionBoxes, holdingForFade, seenCrossTileIDs, collisionBoxArray) { |
|
var this$1 = this; |
|
var layout = bucket.layers[0].layout; |
|
var partiallyEvaluatedTextSize = symbol_layout.evaluateSizeForZoom(bucket.textSizeData, this.transform.zoom); |
|
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 alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || iconOptional); |
|
var alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || textOptional); |
|
var collisionGroup = this.collisionGroups.get(bucket.sourceID); |
|
var rotateWithMap = layout.get('text-rotation-alignment') === 'map'; |
|
var pitchWithMap = layout.get('text-pitch-alignment') === 'map'; |
|
var zOrderByViewportY = layout.get('symbol-z-order') === 'viewport-y'; |
|
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 placed = { |
|
box: null, |
|
offscreen: null |
|
}; |
|
var placedVertical = { |
|
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; |
|
} |
|
if (collisionArrays.verticalTextFeatureIndex) { |
|
verticalTextFeatureIndex = collisionArrays.verticalTextFeatureIndex; |
|
} |
|
var textBox = collisionArrays.textBox; |
|
if (textBox) { |
|
var updatePreviousOrientationIfNotPlaced = function (isPlaced) { |
|
var previousOrientation = symbol_layout.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 === symbol_layout.WritingMode.vertical) { |
|
placed = placeVerticalFn(); |
|
placedVertical = 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, layout.get('text-allow-overlap'), 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, symbol_layout.WritingMode.horizontal); |
|
}; |
|
var placeVertical = function () { |
|
var verticalTextBox = collisionArrays.verticalTextBox; |
|
if (bucket.allowVerticalPlacement && symbolInstance.numVerticalGlyphVertices > 0 && verticalTextBox) { |
|
return placeBox(verticalTextBox, symbol_layout.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, orientation) { |
|
var width = collisionTextBox.x2 - collisionTextBox.x1; |
|
var height = collisionTextBox.y2 - collisionTextBox.y1; |
|
var textBoxScale = symbolInstance.textBoxScale; |
|
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; |
|
placedBox = this$1.attemptAnchorPlacement(anchor, collisionTextBox, width, height, symbolInstance.radialTextOffset, textBoxScale, rotateWithMap, pitchWithMap, textPixelRatio, posMatrix, collisionGroup, allowOverlap, symbolInstance, bucket, orientation); |
|
if (placedBox && placedBox.box && placedBox.box.length) { |
|
placeText = true; |
|
break; |
|
} |
|
} |
|
return placedBox; |
|
}; |
|
var placeHorizontal$1 = function () { |
|
return placeBoxForVariableAnchors(textBox, symbol_layout.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, symbol_layout.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; |
|
var textCircles = collisionArrays.textCircles; |
|
if (textCircles) { |
|
var placedSymbol = bucket.text.placedSymbolArray.get(symbolInstance.centerJustifiedTextSymbolIndex); |
|
var fontSize = symbol_layout.evaluateSizeForFeature(bucket.textSizeData, partiallyEvaluatedTextSize, placedSymbol); |
|
placedGlyphCircles = this$1.collisionIndex.placeCollisionCircles(textCircles, layout.get('text-allow-overlap'), scale, textPixelRatio, placedSymbol, bucket.lineVertexArray, bucket.glyphOffsetArray, fontSize, posMatrix, textLabelPlaneMatrix, showCollisionBoxes, pitchWithMap, collisionGroup.predicate); |
|
placeText = layout.get('text-allow-overlap') || placedGlyphCircles.circles.length > 0; |
|
offscreen = offscreen && placedGlyphCircles.offscreen; |
|
} |
|
if (collisionArrays.iconFeatureIndex) { |
|
iconFeatureIndex = collisionArrays.iconFeatureIndex; |
|
} |
|
if (collisionArrays.iconBox) { |
|
placedIconBoxes = this$1.collisionIndex.placeCollisionBox(collisionArrays.iconBox, layout.get('icon-allow-overlap'), textPixelRatio, posMatrix, collisionGroup.predicate); |
|
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 (placedVertical && placedVertical.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 (placeText && placedGlyphCircles) { |
|
this$1.collisionIndex.insertCollisionCircles(placedGlyphCircles.circles, layout.get('text-ignore-placement'), bucket.bucketInstanceId, textFeatureIndex, collisionGroup.ID); |
|
} |
|
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 = 0; i$1 < bucket.symbolInstances.length; ++i$1) { |
|
placeSymbol(bucket.symbolInstances.get(i$1), bucket.collisionArrays[i$1]); |
|
} |
|
} |
|
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 === symbol_layout.WritingMode.vertical) { |
|
autoIndex = symbolInstance.verticalPlacedTextSymbolIndex; |
|
} else { |
|
autoIndex = justifications[symbol_layout.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 === symbol_layout.WritingMode.horizontal || orientation === symbol_layout.WritingMode.horizontalOnly ? orientation : 0; |
|
var vertical = orientation === symbol_layout.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; |
|
var prevPlacement = this.prevPlacement; |
|
var placementChanged = false; |
|
var increment = prevPlacement && this.fadeDuration !== 0 ? (this.commitTime - prevPlacement.commitTime) / this.fadeDuration : 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) { |
|
if (bucket.hasTextData()) { |
|
bucket.text.opacityVertexArray.clear(); |
|
} |
|
if (bucket.hasIconData()) { |
|
bucket.icon.opacityVertexArray.clear(); |
|
} |
|
if (bucket.hasCollisionBoxData()) { |
|
bucket.collisionBox.collisionVertexArray.clear(); |
|
} |
|
if (bucket.hasCollisionCircleData()) { |
|
bucket.collisionCircle.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 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.hasCollisionBoxData() || bucket.hasCollisionCircleData())) { |
|
bucket.deserializeCollisionBoxes(collisionBoxArray); |
|
} |
|
for (var s = 0; s < bucket.symbolInstances.length; 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.opacities[crossTileID]; |
|
if (isDuplicate) { |
|
opacityState = duplicateOpacityState; |
|
} else if (!opacityState) { |
|
opacityState = defaultOpacityState; |
|
this.opacities[crossTileID] = opacityState; |
|
} |
|
seenCrossTileIDs[crossTileID] = true; |
|
var hasText = numHorizontalGlyphVertices > 0 || numVerticalGlyphVertices > 0; |
|
var hasIcon = symbolInstance.numIconVertices > 0; |
|
if (hasText) { |
|
var packedOpacity = packOpacity(opacityState.text); |
|
var opacityEntryCount = (numHorizontalGlyphVertices + numVerticalGlyphVertices) / 4; |
|
for (var i = 0; i < opacityEntryCount; i++) { |
|
bucket.text.opacityVertexArray.emplaceBack(packedOpacity); |
|
} |
|
var symbolHidden = opacityState.text.isHidden() ? 1 : 0; |
|
var placedOrientation = this.placedOrientations[symbolInstance.crossTileID]; |
|
var verticalHidden = placedOrientation === symbol_layout.WritingMode.horizontal || placedOrientation === symbol_layout.WritingMode.horizontalOnly ? 1 : 0; |
|
var horizontalHidden = placedOrientation === symbol_layout.WritingMode.vertical ? 1 : 0; |
|
[ |
|
symbolInstance.rightJustifiedTextSymbolIndex, |
|
symbolInstance.centerJustifiedTextSymbolIndex, |
|
symbolInstance.leftJustifiedTextSymbolIndex |
|
].forEach(function (index) { |
|
if (index >= 0) { |
|
bucket.text.placedSymbolArray.get(index).hidden = symbolHidden || horizontalHidden; |
|
} |
|
}); |
|
if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) { |
|
bucket.text.placedSymbolArray.get(symbolInstance.verticalPlacedTextSymbolIndex).hidden = symbolHidden || verticalHidden; |
|
} |
|
var prevOffset = this.variableOffsets[symbolInstance.crossTileID]; |
|
if (prevOffset) { |
|
this.markUsedJustification(bucket, prevOffset.anchor, symbolInstance, placedOrientation); |
|
} |
|
var prevOrientation = this.placedOrientations[symbolInstance.crossTileID]; |
|
if (prevOrientation) { |
|
this.markUsedJustification(bucket, 'left', symbolInstance, prevOrientation); |
|
this.markUsedOrientation(bucket, prevOrientation, symbolInstance); |
|
} |
|
} |
|
if (hasIcon) { |
|
var packedOpacity$1 = packOpacity(opacityState.icon); |
|
for (var i$1 = 0; i$1 < symbolInstance.numIconVertices / 4; i$1++) { |
|
bucket.icon.opacityVertexArray.emplaceBack(packedOpacity$1); |
|
} |
|
bucket.icon.placedSymbolArray.get(s).hidden = opacityState.icon.isHidden(); |
|
} |
|
if (bucket.hasCollisionBoxData() || bucket.hasCollisionCircleData()) { |
|
var collisionArrays = bucket.collisionArrays[s]; |
|
if (collisionArrays) { |
|
if (collisionArrays.textBox) { |
|
var shift = new symbol_layout.Point(0, 0); |
|
var used = true; |
|
if (variablePlacement) { |
|
var variableOffset = this.variableOffsets[crossTileID]; |
|
if (variableOffset) { |
|
shift = calculateVariableLayoutOffset(variableOffset.anchor, variableOffset.width, variableOffset.height, variableOffset.radialOffset, variableOffset.textBoxScale); |
|
if (rotateWithMap) { |
|
shift._rotate(pitchWithMap ? this.transform.angle : -this.transform.angle); |
|
} |
|
} else { |
|
used = false; |
|
} |
|
} |
|
updateCollisionVertices(bucket.collisionBox.collisionVertexArray, opacityState.text.placed, !used, shift.x, shift.y); |
|
} |
|
if (collisionArrays.iconBox) { |
|
updateCollisionVertices(bucket.collisionBox.collisionVertexArray, opacityState.icon.placed, false); |
|
} |
|
var textCircles = collisionArrays.textCircles; |
|
if (textCircles && bucket.hasCollisionCircleData()) { |
|
for (var k = 0; k < textCircles.length; k += 5) { |
|
var notUsed = isDuplicate || textCircles[k + 4] === 0; |
|
updateCollisionVertices(bucket.collisionCircle.collisionVertexArray, opacityState.text.placed, notUsed); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
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.hasCollisionBoxData() && bucket.collisionBox.collisionVertexBuffer) { |
|
bucket.collisionBox.collisionVertexBuffer.updateData(bucket.collisionBox.collisionVertexArray); |
|
} |
|
if (bucket.hasCollisionCircleData() && bucket.collisionCircle.collisionVertexBuffer) { |
|
bucket.collisionCircle.collisionVertexBuffer.updateData(bucket.collisionCircle.collisionVertexArray); |
|
} |
|
}; |
|
Placement.prototype.symbolFadeChange = function symbolFadeChange(now) { |
|
return this.fadeDuration === 0 ? 1 : (now - this.commitTime) / this.fadeDuration; |
|
}; |
|
Placement.prototype.hasTransitions = function hasTransitions(now) { |
|
return this.stale || now - this.lastPlacementChangeTime < this.fadeDuration; |
|
}; |
|
Placement.prototype.stillRecent = function stillRecent(now) { |
|
return this.commitTime + this.fadeDuration > 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 LayerPlacement = function LayerPlacement() { |
|
this._currentTileIndex = 0; |
|
this._seenCrossTileIDs = {}; |
|
}; |
|
LayerPlacement.prototype.continuePlacement = function continuePlacement(tiles, placement, showCollisionBoxes, styleLayer, shouldPausePlacement) { |
|
while (this._currentTileIndex < tiles.length) { |
|
var tile = tiles[this._currentTileIndex]; |
|
placement.placeLayerTile(styleLayer, tile, showCollisionBoxes, this._seenCrossTileIDs); |
|
this._currentTileIndex++; |
|
if (shouldPausePlacement()) { |
|
return true; |
|
} |
|
} |
|
}; |
|
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 = symbol_layout.browser.now(); |
|
var shouldPausePlacement = function () { |
|
var elapsedTime = symbol_layout.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(); |
|
} |
|
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 / symbol_layout.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 * symbol_layout.EXTENT + symbolInstance.anchorX) * scale), |
|
y: Math.floor((childTileID.canonical.y * symbol_layout.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 symbol_layout.emitValidationErrors(evented, errors && errors.filter(function (error) { |
|
return error.identifier !== 'source.canvas'; |
|
})); |
|
}; |
|
var supportedDiffOperations = symbol_layout.pick(operations, [ |
|
'addLayer', |
|
'removeLayer', |
|
'setPaintProperty', |
|
'setLayoutProperty', |
|
'setFilter', |
|
'addSource', |
|
'removeSource', |
|
'setLayerZoomRange', |
|
'setLight', |
|
'setTransition', |
|
'setGeoJSONSourceData' |
|
]); |
|
var ignoredDiffOperations = symbol_layout.pick(operations, [ |
|
'setCenter', |
|
'setZoom', |
|
'setBearing', |
|
'setPitch' |
|
]); |
|
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._order = []; |
|
this.sourceCaches = {}; |
|
this.zoomHistory = new symbol_layout.ZoomHistory(); |
|
this._loaded = false; |
|
this._resetUpdates(); |
|
this.dispatcher.broadcast('setReferrer', symbol_layout.getReferrer()); |
|
var self = this; |
|
this._rtlTextPluginCallback = Style.registerForPluginAvailability(function (args) { |
|
self.dispatcher.broadcast('loadRTLTextPlugin', args.pluginURL, args.completionCallback); |
|
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 symbol_layout.Event('dataloading', { dataType: 'style' })); |
|
var validate = typeof options.validate === 'boolean' ? options.validate : !symbol_layout.isMapboxURL(url); |
|
url = this.map._requestManager.normalizeStyleURL(url, options.accessToken); |
|
var request = this.map._requestManager.transformRequest(url, symbol_layout.ResourceType.Style); |
|
this._request = symbol_layout.getJSON(request, function (error, json) { |
|
this$1._request = null; |
|
if (error) { |
|
this$1.fire(new symbol_layout.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 symbol_layout.Event('dataloading', { dataType: 'style' })); |
|
this._request = symbol_layout.browser.frame(function () { |
|
this$1._request = null; |
|
this$1._load(json, options.validate !== false); |
|
}); |
|
}; |
|
Style.prototype._load = function _load(json, validate) { |
|
var this$1 = this; |
|
if (validate && emitValidationErrors(this, symbol_layout.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._spriteRequest = loadSprite(json.sprite, this.map._requestManager, function (err, images) { |
|
this$1._spriteRequest = null; |
|
if (err) { |
|
this$1.fire(new symbol_layout.ErrorEvent(err)); |
|
} else if (images) { |
|
for (var id in images) { |
|
this$1.imageManager.addImage(id, images[id]); |
|
} |
|
} |
|
this$1.imageManager.setLoaded(true); |
|
this$1.fire(new symbol_layout.Event('data', { dataType: 'style' })); |
|
}); |
|
} 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 = {}; |
|
for (var i = 0, list = layers; i < list.length; i += 1) { |
|
var layer = list[i]; |
|
layer = symbol_layout.createStyleLayer(layer); |
|
layer.setEventedParent(this, { layer: { id: layer.id } }); |
|
this._layers[layer.id] = layer; |
|
} |
|
this.dispatcher.broadcast('setLayers', this._serializeLayers(this._order)); |
|
this.light = new Light(this.stylesheet.light); |
|
this.fire(new symbol_layout.Event('data', { dataType: 'style' })); |
|
this.fire(new symbol_layout.Event('style.load')); |
|
}; |
|
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 symbol_layout.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); |
|
} |
|
} |
|
for (var id$1 in this._updatedPaintProps) { |
|
this._layers[id$1].updateTransitions(parameters); |
|
} |
|
this.light.updateTransitions(parameters); |
|
this._resetUpdates(); |
|
} |
|
for (var sourceId in this.sourceCaches) { |
|
this.sourceCaches[sourceId].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); |
|
if (!layer.isHidden(parameters.zoom) && layer.source) { |
|
this.sourceCaches[layer.source].used = true; |
|
} |
|
} |
|
this.light.recalculate(parameters); |
|
this.z = parameters.zoom; |
|
if (changed) { |
|
this.fire(new symbol_layout.Event('data', { dataType: 'style' })); |
|
} |
|
}; |
|
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 = {}; |
|
}; |
|
Style.prototype.setState = function setState(nextState) { |
|
var this$1 = this; |
|
this._checkLoaded(); |
|
if (emitValidationErrors(this, symbol_layout.validateStyle(nextState))) { |
|
return false; |
|
} |
|
nextState = symbol_layout.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 symbol_layout.ErrorEvent(new Error('An image with this name already exists.'))); |
|
} |
|
this.imageManager.addImage(id, image); |
|
this.fire(new symbol_layout.Event('data', { dataType: 'style' })); |
|
}; |
|
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 symbol_layout.ErrorEvent(new Error('No image with this name exists.'))); |
|
} |
|
this.imageManager.removeImage(id); |
|
this.fire(new symbol_layout.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 the 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(symbol_layout.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 symbol_layout.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 symbol_layout.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 symbol_layout.ErrorEvent(new Error('Layer with id "' + id + '" already exists on this map'))); |
|
return; |
|
} |
|
var layer; |
|
if (layerObject.type === 'custom') { |
|
if (emitValidationErrors(this, symbol_layout.validateCustomStyleLayer(layerObject))) { |
|
return; |
|
} |
|
layer = symbol_layout.createStyleLayer(layerObject); |
|
} else { |
|
if (typeof layerObject.source === 'object') { |
|
this.addSource(id, layerObject.source); |
|
layerObject = symbol_layout.clone$1(layerObject); |
|
layerObject = symbol_layout.extend(layerObject, { source: id }); |
|
} |
|
if (this._validate(symbol_layout.validateStyle.layer, 'layers.' + id, layerObject, { arrayIndex: -1 }, options)) { |
|
return; |
|
} |
|
layer = symbol_layout.createStyleLayer(layerObject); |
|
this._validateLayer(layer); |
|
layer.setEventedParent(this, { layer: { id: id } }); |
|
} |
|
var index = before ? this._order.indexOf(before) : this._order.length; |
|
if (before && index === -1) { |
|
this.fire(new symbol_layout.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 symbol_layout.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 symbol_layout.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 symbol_layout.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._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.setLayerZoomRange = function setLayerZoomRange(layerId, minzoom, maxzoom) { |
|
this._checkLoaded(); |
|
var layer = this.getLayer(layerId); |
|
if (!layer) { |
|
this.fire(new symbol_layout.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 symbol_layout.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be filtered.'))); |
|
return; |
|
} |
|
if (symbol_layout.deepEqual(layer.filter, filter)) { |
|
return; |
|
} |
|
if (filter === null || filter === undefined) { |
|
layer.filter = undefined; |
|
this._updateLayer(layer); |
|
return; |
|
} |
|
if (this._validate(symbol_layout.validateStyle.filter, 'layers.' + layer.id + '.filter', filter, null, options)) { |
|
return; |
|
} |
|
layer.filter = symbol_layout.clone$1(filter); |
|
this._updateLayer(layer); |
|
}; |
|
Style.prototype.getFilter = function getFilter(layer) { |
|
return symbol_layout.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 symbol_layout.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be styled.'))); |
|
return; |
|
} |
|
if (symbol_layout.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 symbol_layout.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 symbol_layout.ErrorEvent(new Error('The layer \'' + layerId + '\' does not exist in the map\'s style and cannot be styled.'))); |
|
return; |
|
} |
|
if (symbol_layout.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(feature, state) { |
|
this._checkLoaded(); |
|
var sourceId = feature.source; |
|
var sourceLayer = feature.sourceLayer; |
|
var sourceCache = this.sourceCaches[sourceId]; |
|
var featureId = parseInt(feature.id, 10); |
|
if (sourceCache === undefined) { |
|
this.fire(new symbol_layout.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 symbol_layout.ErrorEvent(new Error('GeoJSON sources cannot have a sourceLayer parameter.'))); |
|
return; |
|
} |
|
if (sourceType === 'vector' && !sourceLayer) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); |
|
return; |
|
} |
|
if (isNaN(featureId) || featureId < 0) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('The feature id parameter must be provided and non-negative.'))); |
|
return; |
|
} |
|
sourceCache.setFeatureState(sourceLayer, featureId, 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 symbol_layout.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; |
|
var featureId = parseInt(target.id, 10); |
|
if (sourceType === 'vector' && !sourceLayer) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); |
|
return; |
|
} |
|
if (target.id !== undefined && isNaN(featureId) || featureId < 0) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('The feature id parameter must be non-negative.'))); |
|
return; |
|
} |
|
if (key && (typeof target.id !== 'string' && typeof target.id !== 'number')) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('A feature id is requred to remove its specific state property.'))); |
|
return; |
|
} |
|
sourceCache.removeFeatureState(sourceLayer, featureId, key); |
|
}; |
|
Style.prototype.getFeatureState = function getFeatureState(feature) { |
|
this._checkLoaded(); |
|
var sourceId = feature.source; |
|
var sourceLayer = feature.sourceLayer; |
|
var sourceCache = this.sourceCaches[sourceId]; |
|
var featureId = parseInt(feature.id, 10); |
|
if (sourceCache === undefined) { |
|
this.fire(new symbol_layout.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 symbol_layout.ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.'))); |
|
return; |
|
} |
|
if (isNaN(featureId) || featureId < 0) { |
|
this.fire(new symbol_layout.ErrorEvent(new Error('The feature id parameter must be provided and non-negative.'))); |
|
return; |
|
} |
|
return sourceCache.getFeatureState(sourceLayer, featureId); |
|
}; |
|
Style.prototype.getTransition = function getTransition() { |
|
return symbol_layout.extend({ |
|
duration: 300, |
|
delay: 0 |
|
}, this.stylesheet && this.stylesheet.transition); |
|
}; |
|
Style.prototype.serialize = function serialize() { |
|
return symbol_layout.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: symbol_layout.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._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(symbol_layout.validateStyle.filter, 'queryRenderedFeatures.filter', params.filter, null, params); |
|
} |
|
var includedSources = {}; |
|
if (params && params.layers) { |
|
if (!Array.isArray(params.layers)) { |
|
this.fire(new symbol_layout.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 symbol_layout.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 = []; |
|
for (var id in this.sourceCaches) { |
|
if (params.layers && !includedSources[id]) { |
|
continue; |
|
} |
|
sourceResults.push(queryRenderedFeatures(this.sourceCaches[id], this._layers, queryGeometry, params, transform)); |
|
} |
|
if (this.placement) { |
|
sourceResults.push(queryRenderedSymbols(this._layers, 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(symbol_layout.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 (!symbol_layout.deepEqual(lightOptions[key], light[key])) { |
|
_update = true; |
|
break; |
|
} |
|
} |
|
if (!_update) { |
|
return; |
|
} |
|
var parameters = { |
|
now: symbol_layout.browser.now(), |
|
transition: symbol_layout.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(symbol_layout.validateStyle, symbol_layout.extend({ |
|
key: key, |
|
style: this.serialize(), |
|
value: value, |
|
styleSpec: symbol_layout.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; |
|
} |
|
symbol_layout.evented.off('pluginAvailable', this._rtlTextPluginCallback); |
|
for (var id in this.sourceCaches) { |
|
this.sourceCaches[id].clearTiles(); |
|
} |
|
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) { |
|
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); |
|
var forceFullPlacement = this._layerOrderChanged || fadeDuration === 0; |
|
if (forceFullPlacement || !this.pauseablePlacement || this.pauseablePlacement.isDone() && !this.placement.stillRecent(symbol_layout.browser.now())) { |
|
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(symbol_layout.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(symbol_layout.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); |
|
}; |
|
Style.prototype.getGlyphs = function getGlyphs(mapId, params, callback) { |
|
this.glyphManager.getGlyphs(params.stacks, callback); |
|
}; |
|
Style.prototype.getResource = function getResource(mapId, params, callback) { |
|
return symbol_layout.makeRequest(params, callback); |
|
}; |
|
return Style; |
|
}(symbol_layout.Evented); |
|
Style.getSourceType = getType; |
|
Style.setSourceType = setType; |
|
Style.registerForPluginAvailability = symbol_layout.registerForPluginAvailability; |
|
|
|
var posAttributes = symbol_layout.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 = "uniform float u_overscale_factor;varying float v_placed;varying float v_notUsed;varying float v_radius;varying vec2 v_extrude;varying vec2 v_extrude_scale;void main() {float alpha=0.5;vec4 color=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {color=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {color*=.2;}float extrude_scale_length=length(v_extrude_scale);float extrude_length=length(v_extrude)*extrude_scale_length;float stroke_width=15.0*extrude_scale_length/u_overscale_factor;float radius=v_radius*extrude_scale_length;float distance_to_edge=abs(extrude_length-radius);float opacity_t=smoothstep(-stroke_width,0.0,-distance_to_edge);gl_FragColor=opacity_t*color;}"; |
|
|
|
var collisionCircleVert = "attribute vec2 a_pos;attribute vec2 a_anchor_pos;attribute vec2 a_extrude;attribute vec2 a_placed;uniform mat4 u_matrix;uniform vec2 u_extrude_scale;uniform float u_camera_to_center_distance;varying float v_placed;varying float v_notUsed;varying float v_radius;varying vec2 v_extrude;varying vec2 v_extrude_scale;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);highp float padding_factor=1.2;gl_Position.xy+=a_extrude*u_extrude_scale*padding_factor*gl_Position.w*collision_perspective_ratio;v_placed=a_placed.x;v_notUsed=a_placed.y;v_radius=abs(a_extrude.y);v_extrude=a_extrude*padding_factor;v_extrude_scale=u_extrude_scale*u_camera_to_center_distance*collision_perspective_ratio;}"; |
|
|
|
var debugFrag = "uniform highp vec4 u_color;void main() {gl_FragColor=u_color;}"; |
|
|
|
var debugVert = "attribute vec2 a_pos;uniform mat4 u_matrix;void main() {gl_Position=u_matrix*vec4(a_pos,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 vec4 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\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;float pixelRatio=u_scale.x;float tileRatio=u_scale.y;float fromScale=u_scale.z;float toScale=u_scale.w;gl_Position=u_matrix*vec4(a_pos,0,1);vec2 display_size_a=vec2((pattern_br_a.x-pattern_tl_a.x)/pixelRatio,(pattern_br_a.y-pattern_tl_a.y)/pixelRatio);vec2 display_size_b=vec2((pattern_br_b.x-pattern_tl_b.x)/pixelRatio,(pattern_br_b.y-pattern_tl_b.y)/pixelRatio);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 vec4 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\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;float pixelRatio=u_scale.x;float tileZoomRatio=u_scale.y;float fromScale=u_scale.z;float toScale=u_scale.w;vec2 display_size_a=vec2((pattern_br_a.x-pattern_tl_a.x)/pixelRatio,(pattern_br_a.y-pattern_tl_a.y)/pixelRatio);vec2 display_size_b=vec2((pattern_br_b.x-pattern_tl_b.x)/pixelRatio,(pattern_br_b.y-pattern_tl_b.y)/pixelRatio);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\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\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 vec4 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\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\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 pixelRatio=u_scale.x;float tileRatio=u_scale.y;float fromScale=u_scale.z;float toScale=u_scale.w;vec3 normal=a_normal_ed.xyz;float edgedistance=a_normal_ed.w;vec2 display_size_a=vec2((pattern_br_a.x-pattern_tl_a.x)/pixelRatio,(pattern_br_a.y-pattern_tl_a.y)/pixelRatio);vec2 display_size_b=vec2((pattern_br_b.x-pattern_tl_b.x)/pixelRatio,(pattern_br_b.y-pattern_tl_b.y)/pixelRatio);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 float u_maxzoom;float getElevation(vec2 coord,float bias) {vec4 data=texture2D(u_image,coord)*255.0;return (data.r+data.g*256.0+data.b*256.0*256.0)/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 exaggeration=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))/ pow(2.0,(u_zoom-u_maxzoom)*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 float v_lineprogress;\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,vec2(v_lineprogress,0.5));gl_FragColor=color*(alpha*opacity);\n#ifdef OVERDRAW_INSPECTOR\ngl_FragColor=vec4(1.0);\n#endif\n}"; |
|
|
|
var lineGradientVert = "\n#define MAX_LINE_DISTANCE 32767.0\n#define scale 0.015873016\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_units_to_pixels;varying vec2 v_normal;varying vec2 v_width2;varying float v_gamma_scale;varying highp float v_lineprogress;\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;v_lineprogress=(floor(a_data.z/4.0)+a_data.w*64.0)*2.0/MAX_LINE_DISTANCE;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 vec4 u_scale;uniform sampler2D u_image;varying vec2 v_normal;varying vec2 v_width2;varying float v_linesofar;varying float v_gamma_scale;\n#pragma mapbox: define lowp vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_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 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 pixelRatio=u_scale.x;float tileZoomRatio=u_scale.y;float fromScale=u_scale.z;float toScale=u_scale.w;vec2 display_size_a=vec2((pattern_br_a.x-pattern_tl_a.x)/pixelRatio,(pattern_br_a.y-pattern_tl_a.y)/pixelRatio);vec2 display_size_b=vec2((pattern_br_b.x-pattern_tl_b.x)/pixelRatio,(pattern_br_b.y-pattern_tl_b.y)/pixelRatio);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 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,1.0);float x_b=mod(v_linesofar/pattern_size_b.x,1.0);float y_a=0.5+(v_normal.y*clamp(v_width2.s,0.0,(pattern_size_a.y+2.0)/2.0)/pattern_size_a.y);float y_b=0.5+(v_normal.y*clamp(v_width2.s,0.0,(pattern_size_b.y+2.0)/2.0)/pattern_size_b.y);vec2 pos_a=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,vec2(x_a,y_a));vec2 pos_b=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,vec2(x_b,y_b));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;\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 vec4 pattern_from\n#pragma mapbox: define lowp vec4 pattern_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 mediump vec4 pattern_from\n#pragma mapbox: initialize mediump vec4 pattern_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);}"; |
|
|
|
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 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;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[0],a_size[1],u_size_t)/256.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size[0]/256.0;} else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {size=u_size;} 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),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 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;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[0],a_size[1],u_size_t)/256.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size[0]/256.0;} else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {size=u_size;} 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),0.0,1.0);float gamma_scale=gl_Position.w;vec2 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;float interpolated_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));v_data0=vec2(tex.x,tex.y);v_data1=vec3(gamma_scale,size,interpolated_fade_opacity);}"; |
|
|
|
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); |
|
function compile(fragmentSource, vertexSource) { |
|
var re = /#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g; |
|
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 |
|
}; |
|
} |
|
|
|
var shaders = /*#__PURE__*/Object.freeze({ |
|
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 |
|
}); |
|
|
|
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; |
|
} |
|
}; |
|
|
|
var Program$1 = function Program(context, source, configuration, fixedUniforms, showOverdrawInspector) { |
|
var gl = context.gl; |
|
this.program = gl.createProgram(); |
|
var defines = 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); |
|
gl.shaderSource(fragmentShader, fragmentSource); |
|
gl.compileShader(fragmentShader); |
|
gl.attachShader(this.program, fragmentShader); |
|
var vertexShader = gl.createShader(gl.VERTEX_SHADER); |
|
gl.shaderSource(vertexShader, vertexSource); |
|
gl.compileShader(vertexShader); |
|
gl.attachShader(this.program, vertexShader); |
|
var layoutAttributes = configuration.layoutAttributes || []; |
|
for (var i = 0; i < layoutAttributes.length; i++) { |
|
gl.bindAttribLocation(this.program, i, layoutAttributes[i].name); |
|
} |
|
gl.linkProgram(this.program); |
|
this.numAttributes = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES); |
|
this.attributes = {}; |
|
var uniformLocations = {}; |
|
for (var i$1 = 0; i$1 < this.numAttributes; i$1++) { |
|
var attribute = gl.getActiveAttrib(this.program, i$1); |
|
if (attribute) { |
|
this.attributes[attribute.name] = gl.getAttribLocation(this.program, attribute.name); |
|
} |
|
} |
|
var numUniforms = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS); |
|
for (var i$2 = 0; i$2 < numUniforms; i$2++) { |
|
var uniform = gl.getActiveUniform(this.program, i$2); |
|
if (uniform) { |
|
uniformLocations[uniform.name] = gl.getUniformLocation(this.program, uniform.name); |
|
} |
|
} |
|
this.fixedUniforms = fixedUniforms(context, uniformLocations); |
|
this.binderUniforms = 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; |
|
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': [ |
|
symbol_layout.browser.devicePixelRatio, |
|
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); |
|
var imagePosB = painter.imageManager.getPattern(image.to); |
|
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 symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_lightpos': new symbol_layout.Uniform3f(context, locations.u_lightpos), |
|
'u_lightintensity': new symbol_layout.Uniform1f(context, locations.u_lightintensity), |
|
'u_lightcolor': new symbol_layout.Uniform3f(context, locations.u_lightcolor), |
|
'u_vertical_gradient': new symbol_layout.Uniform1f(context, locations.u_vertical_gradient), |
|
'u_opacity': new symbol_layout.Uniform1f(context, locations.u_opacity) |
|
}; |
|
}; |
|
var fillExtrusionPatternUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_lightpos': new symbol_layout.Uniform3f(context, locations.u_lightpos), |
|
'u_lightintensity': new symbol_layout.Uniform1f(context, locations.u_lightintensity), |
|
'u_lightcolor': new symbol_layout.Uniform3f(context, locations.u_lightcolor), |
|
'u_vertical_gradient': new symbol_layout.Uniform1f(context, locations.u_vertical_gradient), |
|
'u_height_factor': new symbol_layout.Uniform1f(context, locations.u_height_factor), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_pixel_coord_upper': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_upper), |
|
'u_pixel_coord_lower': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_lower), |
|
'u_scale': new symbol_layout.Uniform4f(context, locations.u_scale), |
|
'u_fade': new symbol_layout.Uniform1f(context, locations.u_fade), |
|
'u_opacity': new symbol_layout.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 = symbol_layout.create$1(); |
|
if (light.properties.get('anchor') === 'viewport') { |
|
symbol_layout.fromRotation(lightMat, -painter.transform.angle); |
|
} |
|
symbol_layout.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 symbol_layout.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 symbol_layout.UniformMatrix4f(context, locations.u_matrix) }; |
|
}; |
|
var fillPatternUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_pixel_coord_upper': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_upper), |
|
'u_pixel_coord_lower': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_lower), |
|
'u_scale': new symbol_layout.Uniform4f(context, locations.u_scale), |
|
'u_fade': new symbol_layout.Uniform1f(context, locations.u_fade) |
|
}; |
|
}; |
|
var fillOutlineUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_world': new symbol_layout.Uniform2f(context, locations.u_world) |
|
}; |
|
}; |
|
var fillOutlinePatternUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_world': new symbol_layout.Uniform2f(context, locations.u_world), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_pixel_coord_upper': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_upper), |
|
'u_pixel_coord_lower': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_lower), |
|
'u_scale': new symbol_layout.Uniform4f(context, locations.u_scale), |
|
'u_fade': new symbol_layout.Uniform1f(context, locations.u_fade) |
|
}; |
|
}; |
|
var fillUniformValues = function (matrix) { |
|
return { 'u_matrix': matrix }; |
|
}; |
|
var fillPatternUniformValues = function (matrix, painter, crossfade, tile) { |
|
return symbol_layout.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 symbol_layout.extend(fillPatternUniformValues(matrix, painter, crossfade, tile), { 'u_world': drawingBufferSize }); |
|
}; |
|
|
|
var circleUniforms = function (context, locations) { |
|
return { |
|
'u_camera_to_center_distance': new symbol_layout.Uniform1f(context, locations.u_camera_to_center_distance), |
|
'u_scale_with_map': new symbol_layout.Uniform1i(context, locations.u_scale_with_map), |
|
'u_pitch_with_map': new symbol_layout.Uniform1i(context, locations.u_pitch_with_map), |
|
'u_extrude_scale': new symbol_layout.Uniform2f(context, locations.u_extrude_scale), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_matrix': new symbol_layout.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': symbol_layout.browser.devicePixelRatio, |
|
'u_extrude_scale': extrudeScale |
|
}; |
|
}; |
|
|
|
var collisionUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_camera_to_center_distance': new symbol_layout.Uniform1f(context, locations.u_camera_to_center_distance), |
|
'u_pixels_to_tile_units': new symbol_layout.Uniform1f(context, locations.u_pixels_to_tile_units), |
|
'u_extrude_scale': new symbol_layout.Uniform2f(context, locations.u_extrude_scale), |
|
'u_overscale_factor': new symbol_layout.Uniform1f(context, locations.u_overscale_factor) |
|
}; |
|
}; |
|
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 debugUniforms = function (context, locations) { |
|
return { |
|
'u_color': new symbol_layout.UniformColor(context, locations.u_color), |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix) |
|
}; |
|
}; |
|
var debugUniformValues = function (matrix, color) { |
|
return { |
|
'u_matrix': matrix, |
|
'u_color': color |
|
}; |
|
}; |
|
|
|
var clippingMaskUniforms = function (context, locations) { |
|
return { 'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix) }; |
|
}; |
|
var clippingMaskUniformValues = function (matrix) { |
|
return { 'u_matrix': matrix }; |
|
}; |
|
|
|
var heatmapUniforms = function (context, locations) { |
|
return { |
|
'u_extrude_scale': new symbol_layout.Uniform1f(context, locations.u_extrude_scale), |
|
'u_intensity': new symbol_layout.Uniform1f(context, locations.u_intensity), |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix) |
|
}; |
|
}; |
|
var heatmapTextureUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_world': new symbol_layout.Uniform2f(context, locations.u_world), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_color_ramp': new symbol_layout.Uniform1i(context, locations.u_color_ramp), |
|
'u_opacity': new symbol_layout.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 = symbol_layout.create(); |
|
symbol_layout.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 symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_latrange': new symbol_layout.Uniform2f(context, locations.u_latrange), |
|
'u_light': new symbol_layout.Uniform2f(context, locations.u_light), |
|
'u_shadow': new symbol_layout.UniformColor(context, locations.u_shadow), |
|
'u_highlight': new symbol_layout.UniformColor(context, locations.u_highlight), |
|
'u_accent': new symbol_layout.UniformColor(context, locations.u_accent) |
|
}; |
|
}; |
|
var hillshadePrepareUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_dimension': new symbol_layout.Uniform2f(context, locations.u_dimension), |
|
'u_zoom': new symbol_layout.Uniform1f(context, locations.u_zoom), |
|
'u_maxzoom': new symbol_layout.Uniform1f(context, locations.u_maxzoom) |
|
}; |
|
}; |
|
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 (tile, maxzoom) { |
|
var stride = tile.dem.stride; |
|
var matrix = symbol_layout.create(); |
|
symbol_layout.ortho(matrix, 0, symbol_layout.EXTENT, -symbol_layout.EXTENT, 0, 0, 1); |
|
symbol_layout.translate(matrix, matrix, [ |
|
0, |
|
-symbol_layout.EXTENT, |
|
0 |
|
]); |
|
return { |
|
'u_matrix': matrix, |
|
'u_image': 1, |
|
'u_dimension': [ |
|
stride, |
|
stride |
|
], |
|
'u_zoom': tile.tileID.overscaledZ, |
|
'u_maxzoom': maxzoom |
|
}; |
|
}; |
|
function getTileLatRange(painter, tileID) { |
|
var tilesAtZoom = Math.pow(2, tileID.canonical.z); |
|
var y = tileID.canonical.y; |
|
return [ |
|
new symbol_layout.MercatorCoordinate(0, y / tilesAtZoom).toLngLat().lat, |
|
new symbol_layout.MercatorCoordinate(0, (y + 1) / tilesAtZoom).toLngLat().lat |
|
]; |
|
} |
|
|
|
var lineUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_ratio': new symbol_layout.Uniform1f(context, locations.u_ratio), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_units_to_pixels': new symbol_layout.Uniform2f(context, locations.u_units_to_pixels) |
|
}; |
|
}; |
|
var lineGradientUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_ratio': new symbol_layout.Uniform1f(context, locations.u_ratio), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_units_to_pixels': new symbol_layout.Uniform2f(context, locations.u_units_to_pixels), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image) |
|
}; |
|
}; |
|
var linePatternUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_ratio': new symbol_layout.Uniform1f(context, locations.u_ratio), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_units_to_pixels': new symbol_layout.Uniform2f(context, locations.u_units_to_pixels), |
|
'u_scale': new symbol_layout.Uniform4f(context, locations.u_scale), |
|
'u_fade': new symbol_layout.Uniform1f(context, locations.u_fade) |
|
}; |
|
}; |
|
var lineSDFUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_ratio': new symbol_layout.Uniform1f(context, locations.u_ratio), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_units_to_pixels': new symbol_layout.Uniform2f(context, locations.u_units_to_pixels), |
|
'u_patternscale_a': new symbol_layout.Uniform2f(context, locations.u_patternscale_a), |
|
'u_patternscale_b': new symbol_layout.Uniform2f(context, locations.u_patternscale_b), |
|
'u_sdfgamma': new symbol_layout.Uniform1f(context, locations.u_sdfgamma), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_tex_y_a': new symbol_layout.Uniform1f(context, locations.u_tex_y_a), |
|
'u_tex_y_b': new symbol_layout.Uniform1f(context, locations.u_tex_y_b), |
|
'u_mix': new symbol_layout.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': symbol_layout.browser.devicePixelRatio, |
|
'u_units_to_pixels': [ |
|
1 / transform.pixelsToGLUnits[0], |
|
1 / transform.pixelsToGLUnits[1] |
|
] |
|
}; |
|
}; |
|
var lineGradientUniformValues = function (painter, tile, layer) { |
|
return symbol_layout.extend(lineUniformValues(painter, tile, layer), { 'u_image': 0 }); |
|
}; |
|
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': symbol_layout.browser.devicePixelRatio, |
|
'u_image': 0, |
|
'u_scale': [ |
|
symbol_layout.browser.devicePixelRatio, |
|
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 symbol_layout.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 * symbol_layout.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 symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_tl_parent': new symbol_layout.Uniform2f(context, locations.u_tl_parent), |
|
'u_scale_parent': new symbol_layout.Uniform1f(context, locations.u_scale_parent), |
|
'u_buffer_scale': new symbol_layout.Uniform1f(context, locations.u_buffer_scale), |
|
'u_fade_t': new symbol_layout.Uniform1f(context, locations.u_fade_t), |
|
'u_opacity': new symbol_layout.Uniform1f(context, locations.u_opacity), |
|
'u_image0': new symbol_layout.Uniform1i(context, locations.u_image0), |
|
'u_image1': new symbol_layout.Uniform1i(context, locations.u_image1), |
|
'u_brightness_low': new symbol_layout.Uniform1f(context, locations.u_brightness_low), |
|
'u_brightness_high': new symbol_layout.Uniform1f(context, locations.u_brightness_high), |
|
'u_saturation_factor': new symbol_layout.Uniform1f(context, locations.u_saturation_factor), |
|
'u_contrast_factor': new symbol_layout.Uniform1f(context, locations.u_contrast_factor), |
|
'u_spin_weights': new symbol_layout.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 symbol_layout.Uniform1i(context, locations.u_is_size_zoom_constant), |
|
'u_is_size_feature_constant': new symbol_layout.Uniform1i(context, locations.u_is_size_feature_constant), |
|
'u_size_t': new symbol_layout.Uniform1f(context, locations.u_size_t), |
|
'u_size': new symbol_layout.Uniform1f(context, locations.u_size), |
|
'u_camera_to_center_distance': new symbol_layout.Uniform1f(context, locations.u_camera_to_center_distance), |
|
'u_pitch': new symbol_layout.Uniform1f(context, locations.u_pitch), |
|
'u_rotate_symbol': new symbol_layout.Uniform1i(context, locations.u_rotate_symbol), |
|
'u_aspect_ratio': new symbol_layout.Uniform1f(context, locations.u_aspect_ratio), |
|
'u_fade_change': new symbol_layout.Uniform1f(context, locations.u_fade_change), |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_label_plane_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_label_plane_matrix), |
|
'u_coord_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_coord_matrix), |
|
'u_is_text': new symbol_layout.Uniform1f(context, locations.u_is_text), |
|
'u_pitch_with_map': new symbol_layout.Uniform1i(context, locations.u_pitch_with_map), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_texture': new symbol_layout.Uniform1i(context, locations.u_texture) |
|
}; |
|
}; |
|
var symbolSDFUniforms = function (context, locations) { |
|
return { |
|
'u_is_size_zoom_constant': new symbol_layout.Uniform1i(context, locations.u_is_size_zoom_constant), |
|
'u_is_size_feature_constant': new symbol_layout.Uniform1i(context, locations.u_is_size_feature_constant), |
|
'u_size_t': new symbol_layout.Uniform1f(context, locations.u_size_t), |
|
'u_size': new symbol_layout.Uniform1f(context, locations.u_size), |
|
'u_camera_to_center_distance': new symbol_layout.Uniform1f(context, locations.u_camera_to_center_distance), |
|
'u_pitch': new symbol_layout.Uniform1f(context, locations.u_pitch), |
|
'u_rotate_symbol': new symbol_layout.Uniform1i(context, locations.u_rotate_symbol), |
|
'u_aspect_ratio': new symbol_layout.Uniform1f(context, locations.u_aspect_ratio), |
|
'u_fade_change': new symbol_layout.Uniform1f(context, locations.u_fade_change), |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_label_plane_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_label_plane_matrix), |
|
'u_coord_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_coord_matrix), |
|
'u_is_text': new symbol_layout.Uniform1f(context, locations.u_is_text), |
|
'u_pitch_with_map': new symbol_layout.Uniform1i(context, locations.u_pitch_with_map), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_texture': new symbol_layout.Uniform1i(context, locations.u_texture), |
|
'u_gamma_scale': new symbol_layout.Uniform1f(context, locations.u_gamma_scale), |
|
'u_device_pixel_ratio': new symbol_layout.Uniform1f(context, locations.u_device_pixel_ratio), |
|
'u_is_halo': new symbol_layout.Uniform1f(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 symbol_layout.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': symbol_layout.browser.devicePixelRatio, |
|
'u_is_halo': +isHalo |
|
}); |
|
}; |
|
|
|
var backgroundUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_opacity': new symbol_layout.Uniform1f(context, locations.u_opacity), |
|
'u_color': new symbol_layout.UniformColor(context, locations.u_color) |
|
}; |
|
}; |
|
var backgroundPatternUniforms = function (context, locations) { |
|
return { |
|
'u_matrix': new symbol_layout.UniformMatrix4f(context, locations.u_matrix), |
|
'u_opacity': new symbol_layout.Uniform1f(context, locations.u_opacity), |
|
'u_image': new symbol_layout.Uniform1i(context, locations.u_image), |
|
'u_pattern_tl_a': new symbol_layout.Uniform2f(context, locations.u_pattern_tl_a), |
|
'u_pattern_br_a': new symbol_layout.Uniform2f(context, locations.u_pattern_br_a), |
|
'u_pattern_tl_b': new symbol_layout.Uniform2f(context, locations.u_pattern_tl_b), |
|
'u_pattern_br_b': new symbol_layout.Uniform2f(context, locations.u_pattern_br_b), |
|
'u_texsize': new symbol_layout.Uniform2f(context, locations.u_texsize), |
|
'u_mix': new symbol_layout.Uniform1f(context, locations.u_mix), |
|
'u_pattern_size_a': new symbol_layout.Uniform2f(context, locations.u_pattern_size_a), |
|
'u_pattern_size_b': new symbol_layout.Uniform2f(context, locations.u_pattern_size_b), |
|
'u_scale_a': new symbol_layout.Uniform1f(context, locations.u_scale_a), |
|
'u_scale_b': new symbol_layout.Uniform1f(context, locations.u_scale_b), |
|
'u_pixel_coord_upper': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_upper), |
|
'u_pixel_coord_lower': new symbol_layout.Uniform2f(context, locations.u_pixel_coord_lower), |
|
'u_tile_units_to_pixels': new symbol_layout.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 symbol_layout.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: collisionUniforms, |
|
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, |
|
background: backgroundUniforms, |
|
backgroundPattern: backgroundPatternUniforms |
|
}; |
|
|
|
function updateTileMasks (renderableTiles, context) { |
|
var sortedRenderables = renderableTiles.sort(function (a, b) { |
|
return a.tileID.isLessThan(b.tileID) ? -1 : b.tileID.isLessThan(a.tileID) ? 1 : 0; |
|
}); |
|
for (var i = 0; i < sortedRenderables.length; i++) { |
|
var mask = {}; |
|
var tile = sortedRenderables[i]; |
|
var childArray = sortedRenderables.slice(i + 1); |
|
computeTileMasks(tile.tileID.wrapped(), tile.tileID, childArray, new symbol_layout.OverscaledTileID(0, tile.tileID.wrap + 1, 0, 0, 0), mask); |
|
tile.setMask(mask, context); |
|
} |
|
} |
|
function computeTileMasks(rootTile, ref, childArray, lowerBound, mask) { |
|
for (var i = 0; i < childArray.length; i++) { |
|
var childTile = childArray[i]; |
|
if (lowerBound.isLessThan(childTile.tileID)) { |
|
break; |
|
} |
|
if (ref.key === childTile.tileID.key) { |
|
return; |
|
} else if (childTile.tileID.isChildOf(ref)) { |
|
var children = ref.children(Infinity); |
|
for (var j = 0; j < children.length; j++) { |
|
var child = children[j]; |
|
computeTileMasks(rootTile, child, childArray.slice(i), lowerBound, mask); |
|
} |
|
return; |
|
} |
|
} |
|
var diffZ = ref.overscaledZ - rootTile.overscaledZ; |
|
var maskTileId = new symbol_layout.CanonicalTileID(diffZ, ref.canonical.x - (rootTile.canonical.x << diffZ), ref.canonical.y - (rootTile.canonical.y << diffZ)); |
|
mask[maskTileId.key] = mask[maskTileId.key] || maskTileId; |
|
} |
|
|
|
function drawCollisionDebugGeometry(painter, sourceCache, layer, coords, drawCircles) { |
|
var context = painter.context; |
|
var gl = context.gl; |
|
var program = drawCircles ? painter.useProgram('collisionCircle') : painter.useProgram('collisionBox'); |
|
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 buffers = drawCircles ? bucket.collisionCircle : bucket.collisionBox; |
|
if (!buffers) { |
|
continue; |
|
} |
|
program.draw(context, drawCircles ? gl.TRIANGLES : gl.LINES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, collisionUniformValues(coord.posMatrix, painter.transform, tile), layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, buffers.segments, null, painter.transform.zoom, null, null, buffers.collisionVertexBuffer); |
|
} |
|
} |
|
function drawCollisionDebug(painter, sourceCache, layer, coords) { |
|
drawCollisionDebugGeometry(painter, sourceCache, layer, coords, false); |
|
drawCollisionDebugGeometry(painter, sourceCache, layer, coords, true); |
|
} |
|
|
|
var identityMat4 = symbol_layout.identity(new Float32Array(16)); |
|
function drawSymbols(painter, sourceCache, layer, coords, variableOffsets) { |
|
if (painter.renderPass !== 'translucent') { |
|
return; |
|
} |
|
var stencilMode = StencilMode.disabled; |
|
var colorMode = painter.colorModeForRenderPass(); |
|
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, variableOffsets); |
|
} |
|
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, variableOffsets); |
|
} |
|
if (sourceCache.map.showCollisionBoxes) { |
|
drawCollisionDebug(painter, sourceCache, layer, coords); |
|
} |
|
} |
|
function calculateVariableRenderShift(anchor, width, height, radialOffset, textBoxScale, renderTextSize) { |
|
var ref = symbol_layout.getAnchorAlignment(anchor); |
|
var horizontalAlign = ref.horizontalAlign; |
|
var verticalAlign = ref.verticalAlign; |
|
var shiftX = -(horizontalAlign - 0.5) * width; |
|
var shiftY = -(verticalAlign - 0.5) * height; |
|
var offset = symbol_layout.evaluateRadialOffset(anchor, radialOffset); |
|
return new symbol_layout.Point((shiftX / textBoxScale + offset[0]) * renderTextSize, (shiftY / textBoxScale + offset[1]) * renderTextSize); |
|
} |
|
function updateVariableAnchors(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, transform, labelPlaneMatrix, posMatrix, tileScale, size) { |
|
var placedSymbols = bucket.text.placedSymbolArray; |
|
var dynamicLayoutVertexArray = bucket.text.dynamicLayoutVertexArray; |
|
dynamicLayoutVertexArray.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, dynamicLayoutVertexArray); |
|
} else { |
|
var tileAnchor = new symbol_layout.Point(symbol.anchorX, symbol.anchorY); |
|
var projectedAnchor = project(tileAnchor, pitchWithMap ? posMatrix : labelPlaneMatrix); |
|
var perspectiveRatio = 0.5 + 0.5 * (transform.cameraToCenterDistance / projectedAnchor.signedDistanceFromCamera); |
|
var renderTextSize = symbolSize.evaluateSizeForFeature(bucket.textSizeData, size, symbol) * perspectiveRatio / symbol_layout.ONE_EM; |
|
if (pitchWithMap) { |
|
renderTextSize *= bucket.tilePixelRatio / tileScale; |
|
} |
|
var width = variableOffset.width; |
|
var height = variableOffset.height; |
|
var radialOffset = variableOffset.radialOffset; |
|
var textBoxScale = variableOffset.textBoxScale; |
|
var shift = calculateVariableRenderShift(variableOffset.anchor, width, height, radialOffset, 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 === symbol_layout.WritingMode.vertical ? Math.PI / 2 : 0; |
|
for (var g = 0; g < symbol.numGlyphs; g++) { |
|
symbol_layout.addDynamicAttributes(dynamicLayoutVertexArray, shiftedAnchor, angle); |
|
} |
|
} |
|
} |
|
bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray); |
|
} |
|
function updateVerticalLabels(bucket) { |
|
var placedSymbols = bucket.text.placedSymbolArray; |
|
var dynamicLayoutVertexArray = bucket.text.dynamicLayoutVertexArray; |
|
dynamicLayoutVertexArray.clear(); |
|
for (var s = 0; s < placedSymbols.length; s++) { |
|
var symbol = placedSymbols.get(s); |
|
var shouldHide = symbol.hidden || !symbol.placedOrientation; |
|
if (shouldHide) { |
|
hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray); |
|
} else { |
|
var tileAnchor = new symbol_layout.Point(symbol.anchorX, symbol.anchorY); |
|
var angle = bucket.allowVerticalPlacement && symbol.placedOrientation === symbol_layout.WritingMode.vertical ? Math.PI / 2 : 0; |
|
for (var g = 0; g < symbol.numGlyphs; g++) { |
|
symbol_layout.addDynamicAttributes(dynamicLayoutVertexArray, tileAnchor, angle); |
|
} |
|
} |
|
} |
|
bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray); |
|
} |
|
function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode, variableOffsets) { |
|
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 sortFeaturesByKey = layer.layout.get('symbol-sort-key').constantOr(1) !== undefined; |
|
var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); |
|
var program; |
|
var size; |
|
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; |
|
if (!program) { |
|
program = painter.useProgram(isSDF ? 'symbolSDF' : 'symbolIcon', programConfiguration); |
|
size = symbol_layout.evaluateSizeForZoom(sizeData, tr.zoom); |
|
} |
|
context.activeTexture.set(gl.TEXTURE0); |
|
var texSize = void 0; |
|
var atlasTexture = void 0; |
|
var atlasInterpolation = void 0; |
|
if (isText) { |
|
atlasTexture = tile.glyphAtlasTexture; |
|
atlasInterpolation = gl.LINEAR; |
|
texSize = tile.glyphAtlasTexture.size; |
|
} else { |
|
var iconScaled = layer.layout.get('icon-size').constantOr(0) !== 1 || bucket.iconsNeedLinear; |
|
var iconTransformed = pitchWithMap || tr.pitch !== 0; |
|
atlasTexture = tile.imageAtlasTexture; |
|
atlasInterpolation = isSDF || painter.options.rotating || painter.options.zooming || iconScaled || iconTransformed ? 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); |
|
if (alongLine) { |
|
updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright); |
|
} else if (isText && size && variablePlacement) { |
|
var tileScale = Math.pow(2, tr.zoom - tile.tileID.overscaledZ); |
|
updateVariableAnchors(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbol_layout.symbolSize, tr, labelPlaneMatrix, coord.posMatrix, tileScale, size); |
|
} else if (isText && size && bucket.allowVerticalPlacement) { |
|
updateVerticalLabels(bucket); |
|
} |
|
var matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), uLabelPlaneMatrix = alongLine || isText && variablePlacement ? 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) { |
|
uniformValues = symbolSDFUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix, uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true); |
|
} else { |
|
uniformValues = symbolIconUniformValues(sizeData.kind, size, rotateInShader, pitchWithMap, painter, matrix, uLabelPlaneMatrix, uglCoordMatrix, isText, texSize); |
|
} |
|
var state = { |
|
program: program, |
|
buffers: buffers, |
|
uniformValues: uniformValues, |
|
atlasTexture: atlasTexture, |
|
atlasInterpolation: atlasInterpolation, |
|
isSDF: isSDF, |
|
hasHalo: hasHalo |
|
}; |
|
if (sortFeaturesByKey) { |
|
var oldSegments = buffers.segments.get(); |
|
for (var i = 0, list = oldSegments; i < list.length; i += 1) { |
|
var segment = list[i]; |
|
tileRenderState.push({ |
|
segments: new symbol_layout.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; |
|
state$1.atlasTexture.bind(state$1.atlasInterpolation, 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 symbol_layout.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 depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); |
|
var stencilMode = StencilMode.disabled; |
|
var colorMode = new ColorMode([ |
|
gl.ONE, |
|
gl.ONE |
|
], symbol_layout.Color.transparent, [ |
|
true, |
|
true, |
|
true, |
|
true |
|
]); |
|
bindFramebuffer(context, painter, layer); |
|
context.clear({ color: symbol_layout.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, 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); |
|
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; |
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, painter.width / 4, painter.height / 4, 0, gl.RGBA, context.extTextureHalfFloat ? context.extTextureHalfFloat.HALF_FLOAT_OES : gl.UNSIGNED_BYTE, null); |
|
fbo.colorAttachment.set(texture); |
|
if (context.extTextureHalfFloat && gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { |
|
context.extTextureHalfFloat = null; |
|
fbo.colorAttachment.setDirty(); |
|
bindTextureToFramebuffer(context, painter, texture, fbo); |
|
} |
|
} |
|
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 symbol_layout.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 = dasharray ? 'lineSDF' : image ? 'linePattern' : gradient ? 'lineGradient' : 'line'; |
|
var context = painter.context; |
|
var gl = context.gl; |
|
var firstTile = true; |
|
if (gradient) { |
|
context.activeTexture.set(gl.TEXTURE0); |
|
var gradientTexture = layer.gradientTexture; |
|
if (!layer.gradient) { |
|
return; |
|
} |
|
if (!gradientTexture) { |
|
gradientTexture = layer.gradientTexture = new symbol_layout.Texture(context, layer.gradient, gl.RGBA); |
|
} |
|
gradientTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); |
|
} |
|
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 posTo = tile.imageAtlas.patternPositions[constantPattern.to]; |
|
var posFrom = tile.imageAtlas.patternPositions[constantPattern.from]; |
|
if (posTo && posFrom) { |
|
programConfiguration.setConstantPatternPositions(posTo, posFrom); |
|
} |
|
} |
|
var uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray, crossfade) : image ? linePatternUniformValues(painter, tile, layer, crossfade) : gradient ? lineGradientUniformValues(painter, tile, layer) : lineUniformValues(painter, tile, layer); |
|
if (dasharray && (programChanged || painter.lineAtlas.dirty)) { |
|
context.activeTexture.set(gl.TEXTURE0); |
|
painter.lineAtlas.bind(context); |
|
} else if (image) { |
|
context.activeTexture.set(gl.TEXTURE0); |
|
tile.imageAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); |
|
programConfiguration.updatePatternPaintBuffers(crossfade); |
|
} |
|
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); |
|
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(symbol_layout.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.updatePatternPaintBuffers(crossfade); |
|
} |
|
var constantPattern = patternProperty.constantOr(null); |
|
if (constantPattern && tile.imageAtlas) { |
|
var posTo = tile.imageAtlas.patternPositions[constantPattern.to]; |
|
var posFrom = tile.imageAtlas.patternPositions[constantPattern.from]; |
|
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.updatePatternPaintBuffers(crossfade); |
|
} |
|
var constantPattern = patternProperty.constantOr(null); |
|
if (constantPattern && tile.imageAtlas) { |
|
var posTo = tile.imageAtlas.patternPositions[constantPattern.to]; |
|
var posFrom = tile.imageAtlas.patternPositions[constantPattern.from]; |
|
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 sourceMaxZoom = sourceCache.getSource().maxzoom; |
|
var depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); |
|
var stencilMode = StencilMode.disabled; |
|
var colorMode = painter.colorModeForRenderPass(); |
|
for (var i = 0, list = tileIDs; i < list.length; i += 1) { |
|
var tileID = list[i]; |
|
var tile = sourceCache.getTile(tileID); |
|
if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { |
|
prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stencilMode, colorMode); |
|
continue; |
|
} else if (painter.renderPass === 'translucent') { |
|
renderHillshade(painter, tile, layer, depthMode, stencilMode, 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); |
|
if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { |
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, tile.maskedBoundsBuffer, tile.maskedIndexBuffer, tile.segments); |
|
} else { |
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); |
|
} |
|
} |
|
function prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stencilMode, colorMode) { |
|
var context = painter.context; |
|
var gl = context.gl; |
|
if (tile.dem && tile.dem.data) { |
|
var tileSize = tile.dem.dim; |
|
var textureStride = tile.dem.stride; |
|
var pixelData = tile.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 symbol_layout.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 symbol_layout.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); |
|
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, sourceMaxZoom), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); |
|
tile.needsHillshadePrepare = false; |
|
} |
|
} |
|
|
|
function drawRaster(painter, sourceCache, layer, coords) { |
|
if (painter.renderPass !== 'translucent') { |
|
return; |
|
} |
|
if (layer.paint.get('raster-opacity') === 0) { |
|
return; |
|
} |
|
var context = painter.context; |
|
var gl = context.gl; |
|
var source = sourceCache.getSource(); |
|
var program = painter.useProgram('raster'); |
|
var stencilMode = StencilMode.disabled; |
|
var colorMode = painter.colorModeForRenderPass(); |
|
var minTileZ = coords.length && coords[0].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, colorMode, CullFaceMode.disabled, uniformValues, layer.id, source.boundsBuffer, painter.quadTriangleIndexBuffer, source.boundsSegments); |
|
} else if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { |
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, tile.maskedBoundsBuffer, tile.maskedIndexBuffer, tile.segments, layer.paint, painter.transform.zoom); |
|
} else { |
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, 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 = symbol_layout.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 : symbol_layout.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); |
|
} |
|
} |
|
|
|
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'; |
|
program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled, debugUniformValues(posMatrix, symbol_layout.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); |
|
var vertices = createTextVertices(coord.toString() + ' ' + tileSizeKb + 'kb', 50, 200 * scaleRatio, 5 * scaleRatio); |
|
var debugTextArray = new symbol_layout.StructArrayLayout2i4(); |
|
var debugTextIndices = new symbol_layout.StructArrayLayout2ui4(); |
|
for (var v = 0; v < vertices.length; v += 2) { |
|
debugTextArray.emplaceBack(vertices[v], vertices[v + 1]); |
|
debugTextIndices.emplaceBack(v, v + 1); |
|
} |
|
var debugTextBuffer = context.createVertexBuffer(debugTextArray, posAttributes.members); |
|
var debugTextIndexBuffer = context.createIndexBuffer(debugTextIndices); |
|
var debugTextSegment = symbol_layout.SegmentVector.simpleSegment(0, 0, debugTextArray.length / 2, debugTextArray.length / 2); |
|
var onePixel = symbol_layout.EXTENT / (Math.pow(2, painter.transform.zoom - coord.overscaledZ) * tileSize * scaleRatio); |
|
var haloWidth = 1; |
|
var translations = []; |
|
for (var x = -haloWidth; x <= haloWidth; x++) { |
|
for (var y = -haloWidth; y <= haloWidth; y++) { |
|
if (x === 0 && y === 0) { |
|
break; |
|
} |
|
translations.push([ |
|
x, |
|
y |
|
]); |
|
} |
|
} |
|
for (var i = 0; i < translations.length; i++) { |
|
var translation = translations[i]; |
|
program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, debugUniformValues(symbol_layout.translate([], posMatrix, [ |
|
onePixel * translation[0], |
|
onePixel * translation[1], |
|
0 |
|
]), symbol_layout.Color.white), id, debugTextBuffer, debugTextIndexBuffer, debugTextSegment); |
|
} |
|
program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, debugUniformValues(posMatrix, symbol_layout.Color.black), id, debugTextBuffer, debugTextIndexBuffer, debugTextSegment); |
|
} |
|
var simplexFont = { |
|
' ': [ |
|
16, |
|
[] |
|
], |
|
'!': [ |
|
10, |
|
[ |
|
5, |
|
21, |
|
5, |
|
7, |
|
-1, |
|
-1, |
|
5, |
|
2, |
|
4, |
|
1, |
|
5, |
|
0, |
|
6, |
|
1, |
|
5, |
|
2 |
|
] |
|
], |
|
'"': [ |
|
16, |
|
[ |
|
4, |
|
21, |
|
4, |
|
14, |
|
-1, |
|
-1, |
|
12, |
|
21, |
|
12, |
|
14 |
|
] |
|
], |
|
'#': [ |
|
21, |
|
[ |
|
11, |
|
25, |
|
4, |
|
-7, |
|
-1, |
|
-1, |
|
17, |
|
25, |
|
10, |
|
-7, |
|
-1, |
|
-1, |
|
4, |
|
12, |
|
18, |
|
12, |
|
-1, |
|
-1, |
|
3, |
|
6, |
|
17, |
|
6 |
|
] |
|
], |
|
'$': [ |
|
20, |
|
[ |
|
8, |
|
25, |
|
8, |
|
-4, |
|
-1, |
|
-1, |
|
12, |
|
25, |
|
12, |
|
-4, |
|
-1, |
|
-1, |
|
17, |
|
18, |
|
15, |
|
20, |
|
12, |
|
21, |
|
8, |
|
21, |
|
5, |
|
20, |
|
3, |
|
18, |
|
3, |
|
16, |
|
4, |
|
14, |
|
5, |
|
13, |
|
7, |
|
12, |
|
13, |
|
10, |
|
15, |
|
9, |
|
16, |
|
8, |
|
17, |
|
6, |
|
17, |
|
3, |
|
15, |
|
1, |
|
12, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
3, |
|
3 |
|
] |
|
], |
|
'%': [ |
|
24, |
|
[ |
|
21, |
|
21, |
|
3, |
|
0, |
|
-1, |
|
-1, |
|
8, |
|
21, |
|
10, |
|
19, |
|
10, |
|
17, |
|
9, |
|
15, |
|
7, |
|
14, |
|
5, |
|
14, |
|
3, |
|
16, |
|
3, |
|
18, |
|
4, |
|
20, |
|
6, |
|
21, |
|
8, |
|
21, |
|
10, |
|
20, |
|
13, |
|
19, |
|
16, |
|
19, |
|
19, |
|
20, |
|
21, |
|
21, |
|
-1, |
|
-1, |
|
17, |
|
7, |
|
15, |
|
6, |
|
14, |
|
4, |
|
14, |
|
2, |
|
16, |
|
0, |
|
18, |
|
0, |
|
20, |
|
1, |
|
21, |
|
3, |
|
21, |
|
5, |
|
19, |
|
7, |
|
17, |
|
7 |
|
] |
|
], |
|
'&': [ |
|
26, |
|
[ |
|
23, |
|
12, |
|
23, |
|
13, |
|
22, |
|
14, |
|
21, |
|
14, |
|
20, |
|
13, |
|
19, |
|
11, |
|
17, |
|
6, |
|
15, |
|
3, |
|
13, |
|
1, |
|
11, |
|
0, |
|
7, |
|
0, |
|
5, |
|
1, |
|
4, |
|
2, |
|
3, |
|
4, |
|
3, |
|
6, |
|
4, |
|
8, |
|
5, |
|
9, |
|
12, |
|
13, |
|
13, |
|
14, |
|
14, |
|
16, |
|
14, |
|
18, |
|
13, |
|
20, |
|
11, |
|
21, |
|
9, |
|
20, |
|
8, |
|
18, |
|
8, |
|
16, |
|
9, |
|
13, |
|
11, |
|
10, |
|
16, |
|
3, |
|
18, |
|
1, |
|
20, |
|
0, |
|
22, |
|
0, |
|
23, |
|
1, |
|
23, |
|
2 |
|
] |
|
], |
|
'\'': [ |
|
10, |
|
[ |
|
5, |
|
19, |
|
4, |
|
20, |
|
5, |
|
21, |
|
6, |
|
20, |
|
6, |
|
18, |
|
5, |
|
16, |
|
4, |
|
15 |
|
] |
|
], |
|
'(': [ |
|
14, |
|
[ |
|
11, |
|
25, |
|
9, |
|
23, |
|
7, |
|
20, |
|
5, |
|
16, |
|
4, |
|
11, |
|
4, |
|
7, |
|
5, |
|
2, |
|
7, |
|
-2, |
|
9, |
|
-5, |
|
11, |
|
-7 |
|
] |
|
], |
|
')': [ |
|
14, |
|
[ |
|
3, |
|
25, |
|
5, |
|
23, |
|
7, |
|
20, |
|
9, |
|
16, |
|
10, |
|
11, |
|
10, |
|
7, |
|
9, |
|
2, |
|
7, |
|
-2, |
|
5, |
|
-5, |
|
3, |
|
-7 |
|
] |
|
], |
|
'*': [ |
|
16, |
|
[ |
|
8, |
|
21, |
|
8, |
|
9, |
|
-1, |
|
-1, |
|
3, |
|
18, |
|
13, |
|
12, |
|
-1, |
|
-1, |
|
13, |
|
18, |
|
3, |
|
12 |
|
] |
|
], |
|
'+': [ |
|
26, |
|
[ |
|
13, |
|
18, |
|
13, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
9, |
|
22, |
|
9 |
|
] |
|
], |
|
',': [ |
|
10, |
|
[ |
|
6, |
|
1, |
|
5, |
|
0, |
|
4, |
|
1, |
|
5, |
|
2, |
|
6, |
|
1, |
|
6, |
|
-1, |
|
5, |
|
-3, |
|
4, |
|
-4 |
|
] |
|
], |
|
'-': [ |
|
26, |
|
[ |
|
4, |
|
9, |
|
22, |
|
9 |
|
] |
|
], |
|
'.': [ |
|
10, |
|
[ |
|
5, |
|
2, |
|
4, |
|
1, |
|
5, |
|
0, |
|
6, |
|
1, |
|
5, |
|
2 |
|
] |
|
], |
|
'/': [ |
|
22, |
|
[ |
|
20, |
|
25, |
|
2, |
|
-7 |
|
] |
|
], |
|
'0': [ |
|
20, |
|
[ |
|
9, |
|
21, |
|
6, |
|
20, |
|
4, |
|
17, |
|
3, |
|
12, |
|
3, |
|
9, |
|
4, |
|
4, |
|
6, |
|
1, |
|
9, |
|
0, |
|
11, |
|
0, |
|
14, |
|
1, |
|
16, |
|
4, |
|
17, |
|
9, |
|
17, |
|
12, |
|
16, |
|
17, |
|
14, |
|
20, |
|
11, |
|
21, |
|
9, |
|
21 |
|
] |
|
], |
|
'1': [ |
|
20, |
|
[ |
|
6, |
|
17, |
|
8, |
|
18, |
|
11, |
|
21, |
|
11, |
|
0 |
|
] |
|
], |
|
'2': [ |
|
20, |
|
[ |
|
4, |
|
16, |
|
4, |
|
17, |
|
5, |
|
19, |
|
6, |
|
20, |
|
8, |
|
21, |
|
12, |
|
21, |
|
14, |
|
20, |
|
15, |
|
19, |
|
16, |
|
17, |
|
16, |
|
15, |
|
15, |
|
13, |
|
13, |
|
10, |
|
3, |
|
0, |
|
17, |
|
0 |
|
] |
|
], |
|
'3': [ |
|
20, |
|
[ |
|
5, |
|
21, |
|
16, |
|
21, |
|
10, |
|
13, |
|
13, |
|
13, |
|
15, |
|
12, |
|
16, |
|
11, |
|
17, |
|
8, |
|
17, |
|
6, |
|
16, |
|
3, |
|
14, |
|
1, |
|
11, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
4, |
|
2, |
|
3, |
|
4 |
|
] |
|
], |
|
'4': [ |
|
20, |
|
[ |
|
13, |
|
21, |
|
3, |
|
7, |
|
18, |
|
7, |
|
-1, |
|
-1, |
|
13, |
|
21, |
|
13, |
|
0 |
|
] |
|
], |
|
'5': [ |
|
20, |
|
[ |
|
15, |
|
21, |
|
5, |
|
21, |
|
4, |
|
12, |
|
5, |
|
13, |
|
8, |
|
14, |
|
11, |
|
14, |
|
14, |
|
13, |
|
16, |
|
11, |
|
17, |
|
8, |
|
17, |
|
6, |
|
16, |
|
3, |
|
14, |
|
1, |
|
11, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
4, |
|
2, |
|
3, |
|
4 |
|
] |
|
], |
|
'6': [ |
|
20, |
|
[ |
|
16, |
|
18, |
|
15, |
|
20, |
|
12, |
|
21, |
|
10, |
|
21, |
|
7, |
|
20, |
|
5, |
|
17, |
|
4, |
|
12, |
|
4, |
|
7, |
|
5, |
|
3, |
|
7, |
|
1, |
|
10, |
|
0, |
|
11, |
|
0, |
|
14, |
|
1, |
|
16, |
|
3, |
|
17, |
|
6, |
|
17, |
|
7, |
|
16, |
|
10, |
|
14, |
|
12, |
|
11, |
|
13, |
|
10, |
|
13, |
|
7, |
|
12, |
|
5, |
|
10, |
|
4, |
|
7 |
|
] |
|
], |
|
'7': [ |
|
20, |
|
[ |
|
17, |
|
21, |
|
7, |
|
0, |
|
-1, |
|
-1, |
|
3, |
|
21, |
|
17, |
|
21 |
|
] |
|
], |
|
'8': [ |
|
20, |
|
[ |
|
8, |
|
21, |
|
5, |
|
20, |
|
4, |
|
18, |
|
4, |
|
16, |
|
5, |
|
14, |
|
7, |
|
13, |
|
11, |
|
12, |
|
14, |
|
11, |
|
16, |
|
9, |
|
17, |
|
7, |
|
17, |
|
4, |
|
16, |
|
2, |
|
15, |
|
1, |
|
12, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
4, |
|
2, |
|
3, |
|
4, |
|
3, |
|
7, |
|
4, |
|
9, |
|
6, |
|
11, |
|
9, |
|
12, |
|
13, |
|
13, |
|
15, |
|
14, |
|
16, |
|
16, |
|
16, |
|
18, |
|
15, |
|
20, |
|
12, |
|
21, |
|
8, |
|
21 |
|
] |
|
], |
|
'9': [ |
|
20, |
|
[ |
|
16, |
|
14, |
|
15, |
|
11, |
|
13, |
|
9, |
|
10, |
|
8, |
|
9, |
|
8, |
|
6, |
|
9, |
|
4, |
|
11, |
|
3, |
|
14, |
|
3, |
|
15, |
|
4, |
|
18, |
|
6, |
|
20, |
|
9, |
|
21, |
|
10, |
|
21, |
|
13, |
|
20, |
|
15, |
|
18, |
|
16, |
|
14, |
|
16, |
|
9, |
|
15, |
|
4, |
|
13, |
|
1, |
|
10, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
4, |
|
3 |
|
] |
|
], |
|
':': [ |
|
10, |
|
[ |
|
5, |
|
14, |
|
4, |
|
13, |
|
5, |
|
12, |
|
6, |
|
13, |
|
5, |
|
14, |
|
-1, |
|
-1, |
|
5, |
|
2, |
|
4, |
|
1, |
|
5, |
|
0, |
|
6, |
|
1, |
|
5, |
|
2 |
|
] |
|
], |
|
';': [ |
|
10, |
|
[ |
|
5, |
|
14, |
|
4, |
|
13, |
|
5, |
|
12, |
|
6, |
|
13, |
|
5, |
|
14, |
|
-1, |
|
-1, |
|
6, |
|
1, |
|
5, |
|
0, |
|
4, |
|
1, |
|
5, |
|
2, |
|
6, |
|
1, |
|
6, |
|
-1, |
|
5, |
|
-3, |
|
4, |
|
-4 |
|
] |
|
], |
|
'<': [ |
|
24, |
|
[ |
|
20, |
|
18, |
|
4, |
|
9, |
|
20, |
|
0 |
|
] |
|
], |
|
'=': [ |
|
26, |
|
[ |
|
4, |
|
12, |
|
22, |
|
12, |
|
-1, |
|
-1, |
|
4, |
|
6, |
|
22, |
|
6 |
|
] |
|
], |
|
'>': [ |
|
24, |
|
[ |
|
4, |
|
18, |
|
20, |
|
9, |
|
4, |
|
0 |
|
] |
|
], |
|
'?': [ |
|
18, |
|
[ |
|
3, |
|
16, |
|
3, |
|
17, |
|
4, |
|
19, |
|
5, |
|
20, |
|
7, |
|
21, |
|
11, |
|
21, |
|
13, |
|
20, |
|
14, |
|
19, |
|
15, |
|
17, |
|
15, |
|
15, |
|
14, |
|
13, |
|
13, |
|
12, |
|
9, |
|
10, |
|
9, |
|
7, |
|
-1, |
|
-1, |
|
9, |
|
2, |
|
8, |
|
1, |
|
9, |
|
0, |
|
10, |
|
1, |
|
9, |
|
2 |
|
] |
|
], |
|
'@': [ |
|
27, |
|
[ |
|
18, |
|
13, |
|
17, |
|
15, |
|
15, |
|
16, |
|
12, |
|
16, |
|
10, |
|
15, |
|
9, |
|
14, |
|
8, |
|
11, |
|
8, |
|
8, |
|
9, |
|
6, |
|
11, |
|
5, |
|
14, |
|
5, |
|
16, |
|
6, |
|
17, |
|
8, |
|
-1, |
|
-1, |
|
12, |
|
16, |
|
10, |
|
14, |
|
9, |
|
11, |
|
9, |
|
8, |
|
10, |
|
6, |
|
11, |
|
5, |
|
-1, |
|
-1, |
|
18, |
|
16, |
|
17, |
|
8, |
|
17, |
|
6, |
|
19, |
|
5, |
|
21, |
|
5, |
|
23, |
|
7, |
|
24, |
|
10, |
|
24, |
|
12, |
|
23, |
|
15, |
|
22, |
|
17, |
|
20, |
|
19, |
|
18, |
|
20, |
|
15, |
|
21, |
|
12, |
|
21, |
|
9, |
|
20, |
|
7, |
|
19, |
|
5, |
|
17, |
|
4, |
|
15, |
|
3, |
|
12, |
|
3, |
|
9, |
|
4, |
|
6, |
|
5, |
|
4, |
|
7, |
|
2, |
|
9, |
|
1, |
|
12, |
|
0, |
|
15, |
|
0, |
|
18, |
|
1, |
|
20, |
|
2, |
|
21, |
|
3, |
|
-1, |
|
-1, |
|
19, |
|
16, |
|
18, |
|
8, |
|
18, |
|
6, |
|
19, |
|
5 |
|
] |
|
], |
|
'A': [ |
|
18, |
|
[ |
|
9, |
|
21, |
|
1, |
|
0, |
|
-1, |
|
-1, |
|
9, |
|
21, |
|
17, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
7, |
|
14, |
|
7 |
|
] |
|
], |
|
'B': [ |
|
21, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
13, |
|
21, |
|
16, |
|
20, |
|
17, |
|
19, |
|
18, |
|
17, |
|
18, |
|
15, |
|
17, |
|
13, |
|
16, |
|
12, |
|
13, |
|
11, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
13, |
|
11, |
|
16, |
|
10, |
|
17, |
|
9, |
|
18, |
|
7, |
|
18, |
|
4, |
|
17, |
|
2, |
|
16, |
|
1, |
|
13, |
|
0, |
|
4, |
|
0 |
|
] |
|
], |
|
'C': [ |
|
21, |
|
[ |
|
18, |
|
16, |
|
17, |
|
18, |
|
15, |
|
20, |
|
13, |
|
21, |
|
9, |
|
21, |
|
7, |
|
20, |
|
5, |
|
18, |
|
4, |
|
16, |
|
3, |
|
13, |
|
3, |
|
8, |
|
4, |
|
5, |
|
5, |
|
3, |
|
7, |
|
1, |
|
9, |
|
0, |
|
13, |
|
0, |
|
15, |
|
1, |
|
17, |
|
3, |
|
18, |
|
5 |
|
] |
|
], |
|
'D': [ |
|
21, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
11, |
|
21, |
|
14, |
|
20, |
|
16, |
|
18, |
|
17, |
|
16, |
|
18, |
|
13, |
|
18, |
|
8, |
|
17, |
|
5, |
|
16, |
|
3, |
|
14, |
|
1, |
|
11, |
|
0, |
|
4, |
|
0 |
|
] |
|
], |
|
'E': [ |
|
19, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
17, |
|
21, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
12, |
|
11, |
|
-1, |
|
-1, |
|
4, |
|
0, |
|
17, |
|
0 |
|
] |
|
], |
|
'F': [ |
|
18, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
17, |
|
21, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
12, |
|
11 |
|
] |
|
], |
|
'G': [ |
|
21, |
|
[ |
|
18, |
|
16, |
|
17, |
|
18, |
|
15, |
|
20, |
|
13, |
|
21, |
|
9, |
|
21, |
|
7, |
|
20, |
|
5, |
|
18, |
|
4, |
|
16, |
|
3, |
|
13, |
|
3, |
|
8, |
|
4, |
|
5, |
|
5, |
|
3, |
|
7, |
|
1, |
|
9, |
|
0, |
|
13, |
|
0, |
|
15, |
|
1, |
|
17, |
|
3, |
|
18, |
|
5, |
|
18, |
|
8, |
|
-1, |
|
-1, |
|
13, |
|
8, |
|
18, |
|
8 |
|
] |
|
], |
|
'H': [ |
|
22, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
18, |
|
21, |
|
18, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
18, |
|
11 |
|
] |
|
], |
|
'I': [ |
|
8, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0 |
|
] |
|
], |
|
'J': [ |
|
16, |
|
[ |
|
12, |
|
21, |
|
12, |
|
5, |
|
11, |
|
2, |
|
10, |
|
1, |
|
8, |
|
0, |
|
6, |
|
0, |
|
4, |
|
1, |
|
3, |
|
2, |
|
2, |
|
5, |
|
2, |
|
7 |
|
] |
|
], |
|
'K': [ |
|
21, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
18, |
|
21, |
|
4, |
|
7, |
|
-1, |
|
-1, |
|
9, |
|
12, |
|
18, |
|
0 |
|
] |
|
], |
|
'L': [ |
|
17, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
0, |
|
16, |
|
0 |
|
] |
|
], |
|
'M': [ |
|
24, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
12, |
|
0, |
|
-1, |
|
-1, |
|
20, |
|
21, |
|
12, |
|
0, |
|
-1, |
|
-1, |
|
20, |
|
21, |
|
20, |
|
0 |
|
] |
|
], |
|
'N': [ |
|
22, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
18, |
|
0, |
|
-1, |
|
-1, |
|
18, |
|
21, |
|
18, |
|
0 |
|
] |
|
], |
|
'O': [ |
|
22, |
|
[ |
|
9, |
|
21, |
|
7, |
|
20, |
|
5, |
|
18, |
|
4, |
|
16, |
|
3, |
|
13, |
|
3, |
|
8, |
|
4, |
|
5, |
|
5, |
|
3, |
|
7, |
|
1, |
|
9, |
|
0, |
|
13, |
|
0, |
|
15, |
|
1, |
|
17, |
|
3, |
|
18, |
|
5, |
|
19, |
|
8, |
|
19, |
|
13, |
|
18, |
|
16, |
|
17, |
|
18, |
|
15, |
|
20, |
|
13, |
|
21, |
|
9, |
|
21 |
|
] |
|
], |
|
'P': [ |
|
21, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
13, |
|
21, |
|
16, |
|
20, |
|
17, |
|
19, |
|
18, |
|
17, |
|
18, |
|
14, |
|
17, |
|
12, |
|
16, |
|
11, |
|
13, |
|
10, |
|
4, |
|
10 |
|
] |
|
], |
|
'Q': [ |
|
22, |
|
[ |
|
9, |
|
21, |
|
7, |
|
20, |
|
5, |
|
18, |
|
4, |
|
16, |
|
3, |
|
13, |
|
3, |
|
8, |
|
4, |
|
5, |
|
5, |
|
3, |
|
7, |
|
1, |
|
9, |
|
0, |
|
13, |
|
0, |
|
15, |
|
1, |
|
17, |
|
3, |
|
18, |
|
5, |
|
19, |
|
8, |
|
19, |
|
13, |
|
18, |
|
16, |
|
17, |
|
18, |
|
15, |
|
20, |
|
13, |
|
21, |
|
9, |
|
21, |
|
-1, |
|
-1, |
|
12, |
|
4, |
|
18, |
|
-2 |
|
] |
|
], |
|
'R': [ |
|
21, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
21, |
|
13, |
|
21, |
|
16, |
|
20, |
|
17, |
|
19, |
|
18, |
|
17, |
|
18, |
|
15, |
|
17, |
|
13, |
|
16, |
|
12, |
|
13, |
|
11, |
|
4, |
|
11, |
|
-1, |
|
-1, |
|
11, |
|
11, |
|
18, |
|
0 |
|
] |
|
], |
|
'S': [ |
|
20, |
|
[ |
|
17, |
|
18, |
|
15, |
|
20, |
|
12, |
|
21, |
|
8, |
|
21, |
|
5, |
|
20, |
|
3, |
|
18, |
|
3, |
|
16, |
|
4, |
|
14, |
|
5, |
|
13, |
|
7, |
|
12, |
|
13, |
|
10, |
|
15, |
|
9, |
|
16, |
|
8, |
|
17, |
|
6, |
|
17, |
|
3, |
|
15, |
|
1, |
|
12, |
|
0, |
|
8, |
|
0, |
|
5, |
|
1, |
|
3, |
|
3 |
|
] |
|
], |
|
'T': [ |
|
16, |
|
[ |
|
8, |
|
21, |
|
8, |
|
0, |
|
-1, |
|
-1, |
|
1, |
|
21, |
|
15, |
|
21 |
|
] |
|
], |
|
'U': [ |
|
22, |
|
[ |
|
4, |
|
21, |
|
4, |
|
6, |
|
5, |
|
3, |
|
7, |
|
1, |
|
10, |
|
0, |
|
12, |
|
0, |
|
15, |
|
1, |
|
17, |
|
3, |
|
18, |
|
6, |
|
18, |
|
21 |
|
] |
|
], |
|
'V': [ |
|
18, |
|
[ |
|
1, |
|
21, |
|
9, |
|
0, |
|
-1, |
|
-1, |
|
17, |
|
21, |
|
9, |
|
0 |
|
] |
|
], |
|
'W': [ |
|
24, |
|
[ |
|
2, |
|
21, |
|
7, |
|
0, |
|
-1, |
|
-1, |
|
12, |
|
21, |
|
7, |
|
0, |
|
-1, |
|
-1, |
|
12, |
|
21, |
|
17, |
|
0, |
|
-1, |
|
-1, |
|
22, |
|
21, |
|
17, |
|
0 |
|
] |
|
], |
|
'X': [ |
|
20, |
|
[ |
|
3, |
|
21, |
|
17, |
|
0, |
|
-1, |
|
-1, |
|
17, |
|
21, |
|
3, |
|
0 |
|
] |
|
], |
|
'Y': [ |
|
18, |
|
[ |
|
1, |
|
21, |
|
9, |
|
11, |
|
9, |
|
0, |
|
-1, |
|
-1, |
|
17, |
|
21, |
|
9, |
|
11 |
|
] |
|
], |
|
'Z': [ |
|
20, |
|
[ |
|
17, |
|
21, |
|
3, |
|
0, |
|
-1, |
|
-1, |
|
3, |
|
21, |
|
17, |
|
21, |
|
-1, |
|
-1, |
|
3, |
|
0, |
|
17, |
|
0 |
|
] |
|
], |
|
'[': [ |
|
14, |
|
[ |
|
4, |
|
25, |
|
4, |
|
-7, |
|
-1, |
|
-1, |
|
5, |
|
25, |
|
5, |
|
-7, |
|
-1, |
|
-1, |
|
4, |
|
25, |
|
11, |
|
25, |
|
-1, |
|
-1, |
|
4, |
|
-7, |
|
11, |
|
-7 |
|
] |
|
], |
|
'\\': [ |
|
14, |
|
[ |
|
0, |
|
21, |
|
14, |
|
-3 |
|
] |
|
], |
|
']': [ |
|
14, |
|
[ |
|
9, |
|
25, |
|
9, |
|
-7, |
|
-1, |
|
-1, |
|
10, |
|
25, |
|
10, |
|
-7, |
|
-1, |
|
-1, |
|
3, |
|
25, |
|
10, |
|
25, |
|
-1, |
|
-1, |
|
3, |
|
-7, |
|
10, |
|
-7 |
|
] |
|
], |
|
'^': [ |
|
16, |
|
[ |
|
6, |
|
15, |
|
8, |
|
18, |
|
10, |
|
15, |
|
-1, |
|
-1, |
|
3, |
|
12, |
|
8, |
|
17, |
|
13, |
|
12, |
|
-1, |
|
-1, |
|
8, |
|
17, |
|
8, |
|
0 |
|
] |
|
], |
|
'_': [ |
|
16, |
|
[ |
|
0, |
|
-2, |
|
16, |
|
-2 |
|
] |
|
], |
|
'`': [ |
|
10, |
|
[ |
|
6, |
|
21, |
|
5, |
|
20, |
|
4, |
|
18, |
|
4, |
|
16, |
|
5, |
|
15, |
|
6, |
|
16, |
|
5, |
|
17 |
|
] |
|
], |
|
'a': [ |
|
19, |
|
[ |
|
15, |
|
14, |
|
15, |
|
0, |
|
-1, |
|
-1, |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'b': [ |
|
19, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
6, |
|
13, |
|
8, |
|
14, |
|
11, |
|
14, |
|
13, |
|
13, |
|
15, |
|
11, |
|
16, |
|
8, |
|
16, |
|
6, |
|
15, |
|
3, |
|
13, |
|
1, |
|
11, |
|
0, |
|
8, |
|
0, |
|
6, |
|
1, |
|
4, |
|
3 |
|
] |
|
], |
|
'c': [ |
|
18, |
|
[ |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'd': [ |
|
19, |
|
[ |
|
15, |
|
21, |
|
15, |
|
0, |
|
-1, |
|
-1, |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'e': [ |
|
18, |
|
[ |
|
3, |
|
8, |
|
15, |
|
8, |
|
15, |
|
10, |
|
14, |
|
12, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'f': [ |
|
12, |
|
[ |
|
10, |
|
21, |
|
8, |
|
21, |
|
6, |
|
20, |
|
5, |
|
17, |
|
5, |
|
0, |
|
-1, |
|
-1, |
|
2, |
|
14, |
|
9, |
|
14 |
|
] |
|
], |
|
'g': [ |
|
19, |
|
[ |
|
15, |
|
14, |
|
15, |
|
-2, |
|
14, |
|
-5, |
|
13, |
|
-6, |
|
11, |
|
-7, |
|
8, |
|
-7, |
|
6, |
|
-6, |
|
-1, |
|
-1, |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'h': [ |
|
19, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
10, |
|
7, |
|
13, |
|
9, |
|
14, |
|
12, |
|
14, |
|
14, |
|
13, |
|
15, |
|
10, |
|
15, |
|
0 |
|
] |
|
], |
|
'i': [ |
|
8, |
|
[ |
|
3, |
|
21, |
|
4, |
|
20, |
|
5, |
|
21, |
|
4, |
|
22, |
|
3, |
|
21, |
|
-1, |
|
-1, |
|
4, |
|
14, |
|
4, |
|
0 |
|
] |
|
], |
|
'j': [ |
|
10, |
|
[ |
|
5, |
|
21, |
|
6, |
|
20, |
|
7, |
|
21, |
|
6, |
|
22, |
|
5, |
|
21, |
|
-1, |
|
-1, |
|
6, |
|
14, |
|
6, |
|
-3, |
|
5, |
|
-6, |
|
3, |
|
-7, |
|
1, |
|
-7 |
|
] |
|
], |
|
'k': [ |
|
17, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
14, |
|
14, |
|
4, |
|
4, |
|
-1, |
|
-1, |
|
8, |
|
8, |
|
15, |
|
0 |
|
] |
|
], |
|
'l': [ |
|
8, |
|
[ |
|
4, |
|
21, |
|
4, |
|
0 |
|
] |
|
], |
|
'm': [ |
|
30, |
|
[ |
|
4, |
|
14, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
10, |
|
7, |
|
13, |
|
9, |
|
14, |
|
12, |
|
14, |
|
14, |
|
13, |
|
15, |
|
10, |
|
15, |
|
0, |
|
-1, |
|
-1, |
|
15, |
|
10, |
|
18, |
|
13, |
|
20, |
|
14, |
|
23, |
|
14, |
|
25, |
|
13, |
|
26, |
|
10, |
|
26, |
|
0 |
|
] |
|
], |
|
'n': [ |
|
19, |
|
[ |
|
4, |
|
14, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
10, |
|
7, |
|
13, |
|
9, |
|
14, |
|
12, |
|
14, |
|
14, |
|
13, |
|
15, |
|
10, |
|
15, |
|
0 |
|
] |
|
], |
|
'o': [ |
|
19, |
|
[ |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3, |
|
16, |
|
6, |
|
16, |
|
8, |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14 |
|
] |
|
], |
|
'p': [ |
|
19, |
|
[ |
|
4, |
|
14, |
|
4, |
|
-7, |
|
-1, |
|
-1, |
|
4, |
|
11, |
|
6, |
|
13, |
|
8, |
|
14, |
|
11, |
|
14, |
|
13, |
|
13, |
|
15, |
|
11, |
|
16, |
|
8, |
|
16, |
|
6, |
|
15, |
|
3, |
|
13, |
|
1, |
|
11, |
|
0, |
|
8, |
|
0, |
|
6, |
|
1, |
|
4, |
|
3 |
|
] |
|
], |
|
'q': [ |
|
19, |
|
[ |
|
15, |
|
14, |
|
15, |
|
-7, |
|
-1, |
|
-1, |
|
15, |
|
11, |
|
13, |
|
13, |
|
11, |
|
14, |
|
8, |
|
14, |
|
6, |
|
13, |
|
4, |
|
11, |
|
3, |
|
8, |
|
3, |
|
6, |
|
4, |
|
3, |
|
6, |
|
1, |
|
8, |
|
0, |
|
11, |
|
0, |
|
13, |
|
1, |
|
15, |
|
3 |
|
] |
|
], |
|
'r': [ |
|
13, |
|
[ |
|
4, |
|
14, |
|
4, |
|
0, |
|
-1, |
|
-1, |
|
4, |
|
8, |
|
5, |
|
11, |
|
7, |
|
13, |
|
9, |
|
14, |
|
12, |
|
14 |
|
] |
|
], |
|
's': [ |
|
17, |
|
[ |
|
14, |
|
11, |
|
13, |
|
13, |
|
10, |
|
14, |
|
7, |
|
14, |
|
4, |
|
13, |
|
3, |
|
11, |
|
4, |
|
9, |
|
6, |
|
8, |
|
11, |
|
7, |
|
13, |
|
6, |
|
14, |
|
4, |
|
14, |
|
3, |
|
13, |
|
1, |
|
10, |
|
0, |
|
7, |
|
0, |
|
4, |
|
1, |
|
3, |
|
3 |
|
] |
|
], |
|
't': [ |
|
12, |
|
[ |
|
5, |
|
21, |
|
5, |
|
4, |
|
6, |
|
1, |
|
8, |
|
0, |
|
10, |
|
0, |
|
-1, |
|
-1, |
|
2, |
|
14, |
|
9, |
|
14 |
|
] |
|
], |
|
'u': [ |
|
19, |
|
[ |
|
4, |
|
14, |
|
4, |
|
4, |
|
5, |
|
1, |
|
7, |
|
0, |
|
10, |
|
0, |
|
12, |
|
1, |
|
15, |
|
4, |
|
-1, |
|
-1, |
|
15, |
|
14, |
|
15, |
|
0 |
|
] |
|
], |
|
'v': [ |
|
16, |
|
[ |
|
2, |
|
14, |
|
8, |
|
0, |
|
-1, |
|
-1, |
|
14, |
|
14, |
|
8, |
|
0 |
|
] |
|
], |
|
'w': [ |
|
22, |
|
[ |
|
3, |
|
14, |
|
7, |
|
0, |
|
-1, |
|
-1, |
|
11, |
|
14, |
|
7, |
|
0, |
|
-1, |
|
-1, |
|
11, |
|
14, |
|
15, |
|
0, |
|
-1, |
|
-1, |
|
19, |
|
14, |
|
15, |
|
0 |
|
] |
|
], |
|
'x': [ |
|
17, |
|
[ |
|
3, |
|
14, |
|
14, |
|
0, |
|
-1, |
|
-1, |
|
14, |
|
14, |
|
3, |
|
0 |
|
] |
|
], |
|
'y': [ |
|
16, |
|
[ |
|
2, |
|
14, |
|
8, |
|
0, |
|
-1, |
|
-1, |
|
14, |
|
14, |
|
8, |
|
0, |
|
6, |
|
-4, |
|
4, |
|
-6, |
|
2, |
|
-7, |
|
1, |
|
-7 |
|
] |
|
], |
|
'z': [ |
|
17, |
|
[ |
|
14, |
|
14, |
|
3, |
|
0, |
|
-1, |
|
-1, |
|
3, |
|
14, |
|
14, |
|
14, |
|
-1, |
|
-1, |
|
3, |
|
0, |
|
14, |
|
0 |
|
] |
|
], |
|
'{': [ |
|
14, |
|
[ |
|
9, |
|
25, |
|
7, |
|
24, |
|
6, |
|
23, |
|
5, |
|
21, |
|
5, |
|
19, |
|
6, |
|
17, |
|
7, |
|
16, |
|
8, |
|
14, |
|
8, |
|
12, |
|
6, |
|
10, |
|
-1, |
|
-1, |
|
7, |
|
24, |
|
6, |
|
22, |
|
6, |
|
20, |
|
7, |
|
18, |
|
8, |
|
17, |
|
9, |
|
15, |
|
9, |
|
13, |
|
8, |
|
11, |
|
4, |
|
9, |
|
8, |
|
7, |
|
9, |
|
5, |
|
9, |
|
3, |
|
8, |
|
1, |
|
7, |
|
0, |
|
6, |
|
-2, |
|
6, |
|
-4, |
|
7, |
|
-6, |
|
-1, |
|
-1, |
|
6, |
|
8, |
|
8, |
|
6, |
|
8, |
|
4, |
|
7, |
|
2, |
|
6, |
|
1, |
|
5, |
|
-1, |
|
5, |
|
-3, |
|
6, |
|
-5, |
|
7, |
|
-6, |
|
9, |
|
-7 |
|
] |
|
], |
|
'|': [ |
|
8, |
|
[ |
|
4, |
|
25, |
|
4, |
|
-7 |
|
] |
|
], |
|
'}': [ |
|
14, |
|
[ |
|
5, |
|
25, |
|
7, |
|
24, |
|
8, |
|
23, |
|
9, |
|
21, |
|
9, |
|
19, |
|
8, |
|
17, |
|
7, |
|
16, |
|
6, |
|
14, |
|
6, |
|
12, |
|
8, |
|
10, |
|
-1, |
|
-1, |
|
7, |
|
24, |
|
8, |
|
22, |
|
8, |
|
20, |
|
7, |
|
18, |
|
6, |
|
17, |
|
5, |
|
15, |
|
5, |
|
13, |
|
6, |
|
11, |
|
10, |
|
9, |
|
6, |
|
7, |
|
5, |
|
5, |
|
5, |
|
3, |
|
6, |
|
1, |
|
7, |
|
0, |
|
8, |
|
-2, |
|
8, |
|
-4, |
|
7, |
|
-6, |
|
-1, |
|
-1, |
|
8, |
|
8, |
|
6, |
|
6, |
|
6, |
|
4, |
|
7, |
|
2, |
|
8, |
|
1, |
|
9, |
|
-1, |
|
9, |
|
-3, |
|
8, |
|
-5, |
|
7, |
|
-6, |
|
5, |
|
-7 |
|
] |
|
], |
|
'~': [ |
|
24, |
|
[ |
|
3, |
|
6, |
|
3, |
|
8, |
|
4, |
|
11, |
|
6, |
|
12, |
|
8, |
|
12, |
|
10, |
|
11, |
|
14, |
|
8, |
|
16, |
|
7, |
|
18, |
|
7, |
|
20, |
|
8, |
|
21, |
|
10, |
|
-1, |
|
-1, |
|
3, |
|
8, |
|
4, |
|
10, |
|
6, |
|
11, |
|
8, |
|
11, |
|
10, |
|
10, |
|
14, |
|
7, |
|
16, |
|
6, |
|
18, |
|
6, |
|
20, |
|
7, |
|
21, |
|
10, |
|
21, |
|
12 |
|
] |
|
] |
|
}; |
|
function createTextVertices(text, left, baseline, scale) { |
|
scale = scale || 1; |
|
var strokes = []; |
|
var i, len, j, len2, glyph, x, y, prev; |
|
for (i = 0, len = text.length; i < len; i++) { |
|
glyph = simplexFont[text[i]]; |
|
if (!glyph) { |
|
continue; |
|
} |
|
prev = null; |
|
for (j = 0, len2 = glyph[1].length; j < len2; j += 2) { |
|
if (glyph[1][j] === -1 && glyph[1][j + 1] === -1) { |
|
prev = null; |
|
} else { |
|
x = left + glyph[1][j] * scale; |
|
y = baseline - glyph[1][j + 1] * scale; |
|
if (prev) { |
|
strokes.push(prev.x, prev.y, x, y); |
|
} |
|
prev = { |
|
x: x, |
|
y: y |
|
}; |
|
} |
|
} |
|
left += glyph[0] * scale; |
|
} |
|
return strokes; |
|
} |
|
|
|
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.depthRboNeedsClear = true; |
|
this.emptyProgramConfiguration = new symbol_layout.ProgramConfiguration(); |
|
this.crossTileSymbolIndex = new CrossTileSymbolIndex(); |
|
}; |
|
Painter.prototype.resize = function resize(width, height) { |
|
var gl = this.context.gl; |
|
this.width = width * symbol_layout.browser.devicePixelRatio; |
|
this.height = height * symbol_layout.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(); |
|
} |
|
} |
|
if (this.depthRbo) { |
|
gl.deleteRenderbuffer(this.depthRbo); |
|
this.depthRbo = null; |
|
} |
|
}; |
|
Painter.prototype.setup = function setup() { |
|
var context = this.context; |
|
var tileExtentArray = new symbol_layout.StructArrayLayout2i4(); |
|
tileExtentArray.emplaceBack(0, 0); |
|
tileExtentArray.emplaceBack(symbol_layout.EXTENT, 0); |
|
tileExtentArray.emplaceBack(0, symbol_layout.EXTENT); |
|
tileExtentArray.emplaceBack(symbol_layout.EXTENT, symbol_layout.EXTENT); |
|
this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray, posAttributes.members); |
|
this.tileExtentSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
var debugArray = new symbol_layout.StructArrayLayout2i4(); |
|
debugArray.emplaceBack(0, 0); |
|
debugArray.emplaceBack(symbol_layout.EXTENT, 0); |
|
debugArray.emplaceBack(0, symbol_layout.EXTENT); |
|
debugArray.emplaceBack(symbol_layout.EXTENT, symbol_layout.EXTENT); |
|
this.debugBuffer = context.createVertexBuffer(debugArray, posAttributes.members); |
|
this.debugSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 5); |
|
var rasterBoundsArray = new symbol_layout.StructArrayLayout4i8(); |
|
rasterBoundsArray.emplaceBack(0, 0, 0, 0); |
|
rasterBoundsArray.emplaceBack(symbol_layout.EXTENT, 0, symbol_layout.EXTENT, 0); |
|
rasterBoundsArray.emplaceBack(0, symbol_layout.EXTENT, 0, symbol_layout.EXTENT); |
|
rasterBoundsArray.emplaceBack(symbol_layout.EXTENT, symbol_layout.EXTENT, symbol_layout.EXTENT, symbol_layout.EXTENT); |
|
this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray, symbol_layout.rasterBoundsAttributes.members); |
|
this.rasterBoundsSegments = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
var viewportArray = new symbol_layout.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 = symbol_layout.SegmentVector.simpleSegment(0, 0, 4, 2); |
|
var tileLineStripIndices = new symbol_layout.StructArrayLayout1ui2(); |
|
tileLineStripIndices.emplaceBack(0); |
|
tileLineStripIndices.emplaceBack(1); |
|
tileLineStripIndices.emplaceBack(3); |
|
tileLineStripIndices.emplaceBack(2); |
|
tileLineStripIndices.emplaceBack(0); |
|
this.tileBorderIndexBuffer = context.createIndexBuffer(tileLineStripIndices); |
|
var quadTriangleIndices = new symbol_layout.StructArrayLayout3ui6(); |
|
quadTriangleIndices.emplaceBack(0, 1, 2); |
|
quadTriangleIndices.emplaceBack(2, 1, 3); |
|
this.quadTriangleIndexBuffer = context.createIndexBuffer(quadTriangleIndices); |
|
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 = symbol_layout.create(); |
|
symbol_layout.ortho(matrix, 0, this.width, this.height, 0, 0, 1); |
|
symbol_layout.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.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 symbol_layout.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) { |
|
this.style = style; |
|
this.options = options; |
|
this.lineAtlas = style.lineAtlas; |
|
this.imageManager = style.imageManager; |
|
this.glyphManager = style.glyphManager; |
|
this.symbolFadeChange = style.placement.symbolFadeChange(symbol_layout.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(); |
|
} |
|
for (var id$2 in sourceCaches) { |
|
var sourceCache$2 = sourceCaches[id$2]; |
|
var source = sourceCache$2.getSource(); |
|
if (source.type !== 'raster' && source.type !== 'raster-dem') { |
|
continue; |
|
} |
|
var visibleTiles = []; |
|
for (var i$1 = 0, list = coordsAscending[id$2]; i$1 < list.length; i$1 += 1) { |
|
var coord = list[i$1]; |
|
visibleTiles.push(sourceCache$2.getTile(coord)); |
|
} |
|
updateTileMasks(visibleTiles, this.context); |
|
} |
|
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'; |
|
this.depthRboNeedsClear = true; |
|
for (var i$2 = 0, list$1 = layerIds; i$2 < list$1.length; i$2 += 1) { |
|
var layerId$1 = list$1[i$2]; |
|
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 ? symbol_layout.Color.black : symbol_layout.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$3 = sourceCaches[layer$1.source]; |
|
var coords$1 = coordsAscending[layer$1.source]; |
|
this._renderTileClippingMasks(layer$1, coords$1); |
|
this.renderLayer(this, sourceCache$3, 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$4 = 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$4, layer$2, coords$2); |
|
} |
|
if (this.options.showTileBoundaries) { |
|
for (var id$3 in sourceCaches) { |
|
draw$1.debug(this, sourceCaches[id$3], coordsAscending[id$3]); |
|
break; |
|
} |
|
} |
|
this.context.setDefault(); |
|
}; |
|
Painter.prototype.setupOffscreenDepthRenderbuffer = function setupOffscreenDepthRenderbuffer() { |
|
var context = this.context; |
|
if (!this.depthRbo) { |
|
this.depthRbo = context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, this.width, this.height); |
|
} |
|
}; |
|
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; |
|
draw$1[layer.type](painter, sourceCache, layer, coords, this.style.placement.variableOffsets); |
|
}; |
|
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); |
|
symbol_layout.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; |
|
} |
|
var imagePosA = this.imageManager.getPattern(image.from); |
|
var imagePosB = this.imageManager.getPattern(image.to); |
|
return !imagePosA || !imagePosB; |
|
}; |
|
Painter.prototype.useProgram = function useProgram(name, programConfiguration) { |
|
if (programConfiguration === void 0) |
|
programConfiguration = this.emptyProgramConfiguration; |
|
this.cache = this.cache || {}; |
|
var key = '' + name + (programConfiguration.cacheKey || '') + (this._showOverdrawInspector ? '/overdraw' : ''); |
|
if (!this.cache[key]) { |
|
this.cache[key] = new Program$1(this.context, 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); |
|
}; |
|
|
|
function tileCover(z, bounds, actualZ, renderWorldCopies) { |
|
if (renderWorldCopies === undefined) { |
|
renderWorldCopies = true; |
|
} |
|
var tiles = 1 << z; |
|
var t = {}; |
|
function scanLine(x0, x1, y) { |
|
var x, w, wx, coord; |
|
if (y >= 0 && y <= tiles) { |
|
for (x = x0; x < x1; x++) { |
|
w = Math.floor(x / tiles); |
|
wx = (x % tiles + tiles) % tiles; |
|
if (w === 0 || renderWorldCopies === true) { |
|
coord = new symbol_layout.OverscaledTileID(actualZ, w, z, wx, y); |
|
t[coord.key] = coord; |
|
} |
|
} |
|
} |
|
} |
|
var zoomedBounds = bounds.map(function (coord) { |
|
return new symbol_layout.Point(coord.x, coord.y)._mult(tiles); |
|
}); |
|
scanTriangle(zoomedBounds[0], zoomedBounds[1], zoomedBounds[2], 0, tiles, scanLine); |
|
scanTriangle(zoomedBounds[2], zoomedBounds[3], zoomedBounds[0], 0, tiles, scanLine); |
|
return Object.keys(t).map(function (id) { |
|
return t[id]; |
|
}); |
|
} |
|
function edge(a, b) { |
|
if (a.y > b.y) { |
|
var t = a; |
|
a = b; |
|
b = t; |
|
} |
|
return { |
|
x0: a.x, |
|
y0: a.y, |
|
x1: b.x, |
|
y1: b.y, |
|
dx: b.x - a.x, |
|
dy: b.y - a.y |
|
}; |
|
} |
|
function scanSpans(e0, e1, ymin, ymax, scanLine) { |
|
var y0 = Math.max(ymin, Math.floor(e1.y0)); |
|
var y1 = Math.min(ymax, Math.ceil(e1.y1)); |
|
if (e0.x0 === e1.x0 && e0.y0 === e1.y0 ? e0.x0 + e1.dy / e0.dy * e0.dx < e1.x1 : e0.x1 - e1.dy / e0.dy * e0.dx < e1.x0) { |
|
var t = e0; |
|
e0 = e1; |
|
e1 = t; |
|
} |
|
var m0 = e0.dx / e0.dy; |
|
var m1 = e1.dx / e1.dy; |
|
var d0 = e0.dx > 0; |
|
var d1 = e1.dx < 0; |
|
for (var y = y0; y < y1; y++) { |
|
var x0 = m0 * Math.max(0, Math.min(e0.dy, y + d0 - e0.y0)) + e0.x0; |
|
var x1 = m1 * Math.max(0, Math.min(e1.dy, y + d1 - e1.y0)) + e1.x0; |
|
scanLine(Math.floor(x1), Math.ceil(x0), y); |
|
} |
|
} |
|
function scanTriangle(a, b, c, ymin, ymax, scanLine) { |
|
var ab = edge(a, b), bc = edge(b, c), ca = edge(c, a); |
|
var t; |
|
if (ab.dy > bc.dy) { |
|
t = ab; |
|
ab = bc; |
|
bc = t; |
|
} |
|
if (ab.dy > ca.dy) { |
|
t = ab; |
|
ab = ca; |
|
ca = t; |
|
} |
|
if (bc.dy > ca.dy) { |
|
t = bc; |
|
bc = ca; |
|
ca = t; |
|
} |
|
if (ab.dy) { |
|
scanSpans(ca, ab, ymin, ymax, scanLine); |
|
} |
|
if (bc.dy) { |
|
scanSpans(ca, bc, ymin, ymax, scanLine); |
|
} |
|
} |
|
|
|
var Transform = function Transform(minZoom, maxZoom, renderWorldCopies) { |
|
this.tileSize = 512; |
|
this.maxValidLatitude = 85.051129; |
|
this._renderWorldCopies = renderWorldCopies === undefined ? true : renderWorldCopies; |
|
this._minZoom = minZoom || 0; |
|
this._maxZoom = maxZoom || 22; |
|
this.setMaxBounds(); |
|
this.width = 0; |
|
this.height = 0; |
|
this._center = new symbol_layout.LngLat(0, 0); |
|
this.zoom = 0; |
|
this.angle = 0; |
|
this._fov = 0.6435011087932844; |
|
this._pitch = 0; |
|
this._unmodified = true; |
|
this._posMatrixCache = {}; |
|
this._alignedPosMatrixCache = {}; |
|
}; |
|
var prototypeAccessors = { |
|
minZoom: { configurable: true }, |
|
maxZoom: { configurable: true }, |
|
renderWorldCopies: { configurable: true }, |
|
worldSize: { configurable: true }, |
|
centerPoint: { configurable: true }, |
|
size: { configurable: true }, |
|
bearing: { configurable: true }, |
|
pitch: { configurable: true }, |
|
fov: { configurable: true }, |
|
zoom: { configurable: true }, |
|
center: { configurable: true }, |
|
unmodified: { configurable: true }, |
|
point: { configurable: true } |
|
}; |
|
Transform.prototype.clone = function clone() { |
|
var clone = new Transform(this._minZoom, this._maxZoom, 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._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.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.centerPoint.get = function () { |
|
return this.size._div(2); |
|
}; |
|
prototypeAccessors.size.get = function () { |
|
return new symbol_layout.Point(this.width, this.height); |
|
}; |
|
prototypeAccessors.bearing.get = function () { |
|
return -this.angle / Math.PI * 180; |
|
}; |
|
prototypeAccessors.bearing.set = function (bearing) { |
|
var b = -symbol_layout.wrap(bearing, -180, 180) * Math.PI / 180; |
|
if (this.angle === b) { |
|
return; |
|
} |
|
this._unmodified = false; |
|
this.angle = b; |
|
this._calcMatrices(); |
|
this.rotationMatrix = symbol_layout.create$2(); |
|
symbol_layout.rotate(this.rotationMatrix, this.rotationMatrix, this.angle); |
|
}; |
|
prototypeAccessors.pitch.get = function () { |
|
return this._pitch / Math.PI * 180; |
|
}; |
|
prototypeAccessors.pitch.set = function (pitch) { |
|
var p = symbol_layout.clamp(pitch, 0, 60) / 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(); |
|
}; |
|
Transform.prototype.coveringZoomLevel = function coveringZoomLevel(options) { |
|
return (options.roundZoom ? Math.round : Math.floor)(this.zoom + this.scaleZoom(this.tileSize / options.tileSize)); |
|
}; |
|
Transform.prototype.getVisibleUnwrappedCoordinates = function getVisibleUnwrappedCoordinates(tileID) { |
|
var result = [new symbol_layout.UnwrappedTileID(0, tileID)]; |
|
if (this._renderWorldCopies) { |
|
var utl = this.pointCoordinate(new symbol_layout.Point(0, 0)); |
|
var utr = this.pointCoordinate(new symbol_layout.Point(this.width, 0)); |
|
var ubl = this.pointCoordinate(new symbol_layout.Point(this.width, this.height)); |
|
var ubr = this.pointCoordinate(new symbol_layout.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 symbol_layout.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 = symbol_layout.MercatorCoordinate.fromLngLat(this.center); |
|
var numTiles = Math.pow(2, z); |
|
var centerPoint = new symbol_layout.Point(numTiles * centerCoord.x - 0.5, numTiles * centerCoord.y - 0.5); |
|
var cornerCoords = [ |
|
this.pointCoordinate(new symbol_layout.Point(0, 0)), |
|
this.pointCoordinate(new symbol_layout.Point(this.width, 0)), |
|
this.pointCoordinate(new symbol_layout.Point(this.width, this.height)), |
|
this.pointCoordinate(new symbol_layout.Point(0, this.height)) |
|
]; |
|
return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies).sort(function (a, b) { |
|
return centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical); |
|
}); |
|
}; |
|
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 = symbol_layout.clamp(lnglat.lat, -this.maxValidLatitude, this.maxValidLatitude); |
|
return new symbol_layout.Point(symbol_layout.mercatorXfromLng(lnglat.lng) * this.worldSize, symbol_layout.mercatorYfromLat(lat) * this.worldSize); |
|
}; |
|
Transform.prototype.unproject = function unproject(point) { |
|
return new symbol_layout.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 symbol_layout.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 symbol_layout.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 |
|
]; |
|
symbol_layout.transformMat4(coord0, coord0, this.pixelMatrixInverse); |
|
symbol_layout.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 symbol_layout.MercatorCoordinate(symbol_layout.number(x0, x1, t) / this.worldSize, symbol_layout.number(y0, y1, t) / this.worldSize); |
|
}; |
|
Transform.prototype.coordinatePoint = function coordinatePoint(coord) { |
|
var p = [ |
|
coord.x * this.worldSize, |
|
coord.y * this.worldSize, |
|
0, |
|
1 |
|
]; |
|
symbol_layout.transformMat4(p, p, this.pixelMatrix); |
|
return new symbol_layout.Point(p[0] / p[3], p[1] / p[3]); |
|
}; |
|
Transform.prototype.getBounds = function getBounds() { |
|
return new symbol_layout.LngLatBounds().extend(this.pointLocation(new symbol_layout.Point(0, 0))).extend(this.pointLocation(new symbol_layout.Point(this.width, 0))).extend(this.pointLocation(new symbol_layout.Point(this.width, this.height))).extend(this.pointLocation(new symbol_layout.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 symbol_layout.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 = symbol_layout.identity(new Float64Array(16)); |
|
symbol_layout.translate(posMatrix, posMatrix, [ |
|
unwrappedX * scale, |
|
canonical.y * scale, |
|
0 |
|
]); |
|
symbol_layout.scale(posMatrix, posMatrix, [ |
|
scale / symbol_layout.EXTENT, |
|
scale / symbol_layout.EXTENT, |
|
1 |
|
]); |
|
symbol_layout.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 = symbol_layout.mercatorYfromLat(latRange[1]) * this.worldSize; |
|
maxY = symbol_layout.mercatorYfromLat(latRange[0]) * this.worldSize; |
|
sy = maxY - minY < size.y ? size.y / (maxY - minY) : 0; |
|
} |
|
if (this.lngRange) { |
|
var lngRange = this.lngRange; |
|
minX = symbol_layout.mercatorXfromLng(lngRange[0]) * this.worldSize; |
|
maxX = symbol_layout.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 symbol_layout.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 symbol_layout.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; |
|
} |
|
this.cameraToCenterDistance = 0.5 / Math.tan(this._fov / 2) * this.height; |
|
var halfFov = this._fov / 2; |
|
var groundAngle = Math.PI / 2 + this._pitch; |
|
var topHalfSurfaceDistance = Math.sin(halfFov) * this.cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov); |
|
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); |
|
symbol_layout.perspective(m, this._fov, this.width / this.height, nearZ, farZ); |
|
symbol_layout.scale(m, m, [ |
|
1, |
|
-1, |
|
1 |
|
]); |
|
symbol_layout.translate(m, m, [ |
|
0, |
|
0, |
|
-this.cameraToCenterDistance |
|
]); |
|
symbol_layout.rotateX(m, m, this._pitch); |
|
symbol_layout.rotateZ(m, m, this.angle); |
|
symbol_layout.translate(m, m, [ |
|
-x, |
|
-y, |
|
0 |
|
]); |
|
this.mercatorMatrix = symbol_layout.scale([], m, [ |
|
this.worldSize, |
|
this.worldSize, |
|
this.worldSize |
|
]); |
|
symbol_layout.scale(m, m, [ |
|
1, |
|
1, |
|
symbol_layout.mercatorZfromAltitude(1, this.center.lat) * this.worldSize, |
|
1 |
|
]); |
|
this.projMatrix = m; |
|
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); |
|
symbol_layout.translate(alignedM, alignedM, [ |
|
dx > 0.5 ? dx - 1 : dx, |
|
dy > 0.5 ? dy - 1 : dy, |
|
0 |
|
]); |
|
this.alignedProjMatrix = alignedM; |
|
m = symbol_layout.create(); |
|
symbol_layout.scale(m, m, [ |
|
this.width / 2, |
|
-this.height / 2, |
|
1 |
|
]); |
|
symbol_layout.translate(m, m, [ |
|
1, |
|
-1, |
|
0 |
|
]); |
|
this.labelPlaneMatrix = m; |
|
m = symbol_layout.create(); |
|
symbol_layout.scale(m, m, [ |
|
1, |
|
-1, |
|
1 |
|
]); |
|
symbol_layout.translate(m, m, [ |
|
-1, |
|
-1, |
|
0 |
|
]); |
|
symbol_layout.scale(m, m, [ |
|
2 / this.width, |
|
2 / this.height, |
|
1 |
|
]); |
|
this.glCoordMatrix = m; |
|
this.pixelMatrix = symbol_layout.multiply(new Float64Array(16), this.labelPlaneMatrix, this.projMatrix); |
|
m = symbol_layout.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 symbol_layout.Point(0, 0)); |
|
var p = [ |
|
coord.x * this.worldSize, |
|
coord.y * this.worldSize, |
|
0, |
|
1 |
|
]; |
|
var topPoint = symbol_layout.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 symbol_layout.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 symbol_layout.Point(minX, minY), |
|
new symbol_layout.Point(maxX, minY), |
|
new symbol_layout.Point(maxX, maxY), |
|
new symbol_layout.Point(minX, maxY), |
|
new symbol_layout.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() { |
|
symbol_layout.bindAll([ |
|
'_onHashChange', |
|
'_updateHash' |
|
], this); |
|
this._updateHash = throttle(this._updateHashUnthrottled.bind(this), 30 * 1000 / 100); |
|
}; |
|
Hash.prototype.addTo = function addTo(map) { |
|
this._map = map; |
|
symbol_layout.window.addEventListener('hashchange', this._onHashChange, false); |
|
this._map.on('moveend', this._updateHash); |
|
return this; |
|
}; |
|
Hash.prototype.remove = function remove() { |
|
symbol_layout.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); |
|
} |
|
return hash; |
|
}; |
|
Hash.prototype._onHashChange = function _onHashChange() { |
|
var loc = symbol_layout.window.location.hash.replace('#', '').split('/'); |
|
if (loc.length >= 3) { |
|
this._map.jumpTo({ |
|
center: [ |
|
+loc[2], |
|
+loc[1] |
|
], |
|
zoom: +loc[0], |
|
bearing: +(loc[3] || 0), |
|
pitch: +(loc[4] || 0) |
|
}); |
|
return true; |
|
} |
|
return false; |
|
}; |
|
Hash.prototype._updateHashUnthrottled = function _updateHashUnthrottled() { |
|
var hash = this.getHashString(); |
|
try { |
|
symbol_layout.window.history.replaceState(symbol_layout.window.history.state, '', hash); |
|
} catch (SecurityError) { |
|
} |
|
}; |
|
|
|
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, symbol_layout.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; |
|
}(symbol_layout.Event); |
|
var MapTouchEvent = function (Event) { |
|
function MapTouchEvent(type, map, originalEvent) { |
|
var points = DOM.touchPos(map.getCanvasContainer(), originalEvent); |
|
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 symbol_layout.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; |
|
}(symbol_layout.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; |
|
}(symbol_layout.Event); |
|
|
|
var wheelZoomDelta = 4.000244140625; |
|
var defaultZoomRate = 1 / 100; |
|
var wheelZoomRate = 1 / 450; |
|
var maxScalePerFrame = 2; |
|
var ScrollZoomHandler = function ScrollZoomHandler(map) { |
|
this._map = map; |
|
this._el = map.getCanvasContainer(); |
|
this._delta = 0; |
|
this._defaultZoomRate = defaultZoomRate; |
|
this._wheelZoomRate = wheelZoomRate; |
|
symbol_layout.bindAll([ |
|
'_onWheel', |
|
'_onTimeout', |
|
'_onScrollFrame', |
|
'_onScrollFinished' |
|
], 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; |
|
}; |
|
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.onWheel = function onWheel(e) { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
var value = e.deltaMode === symbol_layout.window.WheelEvent.DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY; |
|
var now = symbol_layout.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.isActive()) { |
|
this._start(e); |
|
} |
|
} |
|
e.preventDefault(); |
|
}; |
|
ScrollZoomHandler.prototype._onTimeout = function _onTimeout(initialEvent) { |
|
this._type = 'wheel'; |
|
this._delta -= this._lastValue; |
|
if (!this.isActive()) { |
|
this._start(initialEvent); |
|
} |
|
}; |
|
ScrollZoomHandler.prototype._start = function _start(e) { |
|
if (!this._delta) { |
|
return; |
|
} |
|
if (this._frameId) { |
|
this._map._cancelRenderFrame(this._frameId); |
|
this._frameId = null; |
|
} |
|
this._active = true; |
|
if (!this.isZooming()) { |
|
this._zooming = true; |
|
this._map.fire(new symbol_layout.Event('movestart', { originalEvent: e })); |
|
this._map.fire(new symbol_layout.Event('zoomstart', { originalEvent: e })); |
|
} |
|
if (this._finishTimeout) { |
|
clearTimeout(this._finishTimeout); |
|
} |
|
var pos = DOM.mousePos(this._el, e); |
|
this._around = symbol_layout.LngLat.convert(this._aroundCenter ? this._map.getCenter() : this._map.unproject(pos)); |
|
this._aroundPoint = this._map.transform.locationPoint(this._around); |
|
if (!this._frameId) { |
|
this._frameId = this._map._requestRenderFrame(this._onScrollFrame); |
|
} |
|
}; |
|
ScrollZoomHandler.prototype._onScrollFrame = function _onScrollFrame() { |
|
var this$1 = this; |
|
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; |
|
if (this._type === 'wheel' && startZoom && easing) { |
|
var t = Math.min((symbol_layout.browser.now() - this._lastWheelEventTime) / 200, 1); |
|
var k = easing(t); |
|
tr.zoom = symbol_layout.number(startZoom, targetZoom, k); |
|
if (t < 1) { |
|
if (!this._frameId) { |
|
this._frameId = this._map._requestRenderFrame(this._onScrollFrame); |
|
} |
|
} else { |
|
finished = true; |
|
} |
|
} else { |
|
tr.zoom = targetZoom; |
|
finished = true; |
|
} |
|
tr.setLocationAtPoint(this._around, this._aroundPoint); |
|
this._map.fire(new symbol_layout.Event('move', { originalEvent: this._lastWheelEvent })); |
|
this._map.fire(new symbol_layout.Event('zoom', { originalEvent: this._lastWheelEvent })); |
|
if (finished) { |
|
this._active = false; |
|
this._finishTimeout = setTimeout(function () { |
|
this$1._zooming = false; |
|
this$1._map.fire(new symbol_layout.Event('zoomend', { originalEvent: this$1._lastWheelEvent })); |
|
this$1._map.fire(new symbol_layout.Event('moveend', { originalEvent: this$1._lastWheelEvent })); |
|
delete this$1._targetZoom; |
|
}, 200); |
|
} |
|
}; |
|
ScrollZoomHandler.prototype._smoothOutEasing = function _smoothOutEasing(duration) { |
|
var easing = symbol_layout.ease; |
|
if (this._prevEase) { |
|
var ease = this._prevEase, t = (symbol_layout.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 = symbol_layout.bezier(x, y, 0.25, 1); |
|
} |
|
this._prevEase = { |
|
start: symbol_layout.browser.now(), |
|
duration: duration, |
|
easing: easing |
|
}; |
|
return easing; |
|
}; |
|
|
|
var BoxZoomHandler = function BoxZoomHandler(map, options) { |
|
this._map = map; |
|
this._el = map.getCanvasContainer(); |
|
this._container = map.getContainer(); |
|
this._clickTolerance = options.clickTolerance || 1; |
|
symbol_layout.bindAll([ |
|
'_onMouseMove', |
|
'_onMouseUp', |
|
'_onKeyDown' |
|
], this); |
|
}; |
|
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.onMouseDown = function onMouseDown(e) { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
if (!(e.shiftKey && e.button === 0)) { |
|
return; |
|
} |
|
symbol_layout.window.document.addEventListener('mousemove', this._onMouseMove, false); |
|
symbol_layout.window.document.addEventListener('keydown', this._onKeyDown, false); |
|
symbol_layout.window.document.addEventListener('mouseup', this._onMouseUp, false); |
|
DOM.disableDrag(); |
|
this._startPos = this._lastPos = DOM.mousePos(this._el, e); |
|
this._active = true; |
|
}; |
|
BoxZoomHandler.prototype._onMouseMove = function _onMouseMove(e) { |
|
var pos = DOM.mousePos(this._el, e); |
|
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._onMouseUp = function _onMouseUp(e) { |
|
if (e.button !== 0) { |
|
return; |
|
} |
|
var p0 = this._startPos, p1 = DOM.mousePos(this._el, e); |
|
this._finish(); |
|
DOM.suppressClick(); |
|
if (p0.x === p1.x && p0.y === p1.y) { |
|
this._fireEvent('boxzoomcancel', e); |
|
} else { |
|
this._map.fitScreenCoordinates(p0, p1, this._map.getBearing(), { linear: true }).fire(new symbol_layout.Event('boxzoomend', { originalEvent: e })); |
|
} |
|
}; |
|
BoxZoomHandler.prototype._onKeyDown = function _onKeyDown(e) { |
|
if (e.keyCode === 27) { |
|
this._finish(); |
|
this._fireEvent('boxzoomcancel', e); |
|
} |
|
}; |
|
BoxZoomHandler.prototype._finish = function _finish() { |
|
this._active = false; |
|
symbol_layout.window.document.removeEventListener('mousemove', this._onMouseMove, false); |
|
symbol_layout.window.document.removeEventListener('keydown', this._onKeyDown, false); |
|
symbol_layout.window.document.removeEventListener('mouseup', this._onMouseUp, 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 symbol_layout.Event(type, { originalEvent: e })); |
|
}; |
|
|
|
var inertiaLinearity = 0.25, inertiaEasing = symbol_layout.bezier(0, 0, inertiaLinearity, 1), inertiaMaxSpeed = 180, inertiaDeceleration = 720; |
|
var DragRotateHandler = function DragRotateHandler(map, options) { |
|
this._map = map; |
|
this._el = options.element || map.getCanvasContainer(); |
|
this._state = 'disabled'; |
|
this._button = options.button || 'right'; |
|
this._bearingSnap = options.bearingSnap || 0; |
|
this._pitchWithRotate = options.pitchWithRotate !== false; |
|
symbol_layout.bindAll([ |
|
'onMouseDown', |
|
'_onMouseMove', |
|
'_onMouseUp', |
|
'_onBlur', |
|
'_onDragFrame' |
|
], this); |
|
}; |
|
DragRotateHandler.prototype.isEnabled = function isEnabled() { |
|
return this._state !== 'disabled'; |
|
}; |
|
DragRotateHandler.prototype.isActive = function isActive() { |
|
return this._state === 'active'; |
|
}; |
|
DragRotateHandler.prototype.enable = function enable() { |
|
if (this.isEnabled()) { |
|
return; |
|
} |
|
this._state = 'enabled'; |
|
}; |
|
DragRotateHandler.prototype.disable = function disable() { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'disabled'; |
|
this._unbind(); |
|
this._deactivate(); |
|
this._fireEvent('rotateend'); |
|
if (this._pitchWithRotate) { |
|
this._fireEvent('pitchend'); |
|
} |
|
this._fireEvent('moveend'); |
|
break; |
|
case 'pending': |
|
this._state = 'disabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
this._state = 'disabled'; |
|
break; |
|
} |
|
}; |
|
DragRotateHandler.prototype.onMouseDown = function onMouseDown(e) { |
|
if (this._state !== 'enabled') { |
|
return; |
|
} |
|
var touchEvent = e.type === 'touchstart'; |
|
if (touchEvent) { |
|
this._startTime = Date.now(); |
|
} else { |
|
if (this._button === 'right') { |
|
this._eventButton = DOM.mouseButton(e); |
|
if (this._eventButton !== (e.ctrlKey ? 0 : 2)) { |
|
return; |
|
} |
|
} else { |
|
if (e.ctrlKey || DOM.mouseButton(e) !== 0) { |
|
return; |
|
} |
|
this._eventButton = 0; |
|
} |
|
} |
|
DOM.disableDrag(); |
|
if (touchEvent) { |
|
symbol_layout.window.document.addEventListener('touchmove', this._onMouseMove, { capture: true }); |
|
symbol_layout.window.document.addEventListener('touchend', this._onMouseUp); |
|
} else { |
|
symbol_layout.window.document.addEventListener('mousemove', this._onMouseMove, { capture: true }); |
|
symbol_layout.window.document.addEventListener('mouseup', this._onMouseUp); |
|
} |
|
symbol_layout.window.addEventListener('blur', this._onBlur); |
|
this._state = 'pending'; |
|
this._inertia = [[ |
|
symbol_layout.browser.now(), |
|
this._map.getBearing() |
|
]]; |
|
this._startPos = this._prevPos = this._lastPos = DOM.mousePos(this._el, e); |
|
this._center = this._map.transform.centerPoint; |
|
e.preventDefault(); |
|
}; |
|
DragRotateHandler.prototype._onMouseMove = function _onMouseMove(e) { |
|
var pos = DOM.mousePos(this._el, e); |
|
if (this._lastPos.equals(pos)) { |
|
return; |
|
} |
|
this._lastMoveEvent = e; |
|
this._lastPos = pos; |
|
if (this._state === 'pending') { |
|
this._state = 'active'; |
|
this._fireEvent('rotatestart', e); |
|
this._fireEvent('movestart', e); |
|
if (this._pitchWithRotate) { |
|
this._fireEvent('pitchstart', e); |
|
} |
|
} |
|
if (!this._frameId) { |
|
this._frameId = this._map._requestRenderFrame(this._onDragFrame); |
|
} |
|
}; |
|
DragRotateHandler.prototype._onDragFrame = function _onDragFrame() { |
|
this._frameId = null; |
|
var e = this._lastMoveEvent; |
|
if (!e) { |
|
return; |
|
} |
|
var tr = this._map.transform; |
|
var p1 = this._prevPos, p2 = this._lastPos, bearingDiff = (p1.x - p2.x) * 0.8, pitchDiff = (p1.y - p2.y) * -0.5, bearing = tr.bearing - bearingDiff, pitch = tr.pitch - pitchDiff, inertia = this._inertia, last = inertia[inertia.length - 1]; |
|
this._drainInertiaBuffer(); |
|
inertia.push([ |
|
symbol_layout.browser.now(), |
|
this._map._normalizeBearing(bearing, last[1]) |
|
]); |
|
tr.bearing = bearing; |
|
if (this._pitchWithRotate) { |
|
this._fireEvent('pitch', e); |
|
tr.pitch = pitch; |
|
} |
|
this._fireEvent('rotate', e); |
|
this._fireEvent('move', e); |
|
delete this._lastMoveEvent; |
|
this._prevPos = this._lastPos; |
|
}; |
|
DragRotateHandler.prototype._onMouseUp = function _onMouseUp(e) { |
|
var touchEvent = e.type === 'touchend'; |
|
if (touchEvent && this._startPos === this._lastPos && Date.now() - this._startTime < 300) { |
|
this._el.click(); |
|
} |
|
if (DOM.mouseButton(e) !== this._eventButton) { |
|
return; |
|
} |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'enabled'; |
|
DOM.suppressClick(); |
|
this._unbind(); |
|
this._deactivate(); |
|
this._inertialRotate(e); |
|
break; |
|
case 'pending': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
break; |
|
} |
|
}; |
|
DragRotateHandler.prototype._onBlur = function _onBlur(e) { |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
this._deactivate(); |
|
this._fireEvent('rotateend', e); |
|
if (this._pitchWithRotate) { |
|
this._fireEvent('pitchend', e); |
|
} |
|
this._fireEvent('moveend', e); |
|
break; |
|
case 'pending': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
break; |
|
} |
|
}; |
|
DragRotateHandler.prototype._unbind = function _unbind() { |
|
symbol_layout.window.document.removeEventListener('mousemove', this._onMouseMove, { capture: true }); |
|
symbol_layout.window.document.removeEventListener('mouseup', this._onMouseUp); |
|
symbol_layout.window.document.removeEventListener('touchmove', this._onMouseMove, { capture: true }); |
|
symbol_layout.window.document.removeEventListener('touchend', this._onMouseUp); |
|
symbol_layout.window.removeEventListener('blur', this._onBlur); |
|
DOM.enableDrag(); |
|
}; |
|
DragRotateHandler.prototype._deactivate = function _deactivate() { |
|
if (this._frameId) { |
|
this._map._cancelRenderFrame(this._frameId); |
|
this._frameId = null; |
|
} |
|
delete this._lastMoveEvent; |
|
delete this._startPos; |
|
delete this._prevPos; |
|
delete this._lastPos; |
|
}; |
|
DragRotateHandler.prototype._inertialRotate = function _inertialRotate(e) { |
|
var this$1 = this; |
|
this._fireEvent('rotateend', e); |
|
this._drainInertiaBuffer(); |
|
var map = this._map, mapBearing = map.getBearing(), inertia = this._inertia; |
|
var finish = function () { |
|
if (Math.abs(mapBearing) < this$1._bearingSnap) { |
|
map.resetNorth({ noMoveStart: true }, { originalEvent: e }); |
|
} else { |
|
this$1._fireEvent('moveend', e); |
|
} |
|
if (this$1._pitchWithRotate) { |
|
this$1._fireEvent('pitchend', e); |
|
} |
|
}; |
|
if (inertia.length < 2) { |
|
finish(); |
|
return; |
|
} |
|
var first = inertia[0], last = inertia[inertia.length - 1], previous = inertia[inertia.length - 2]; |
|
var bearing = map._normalizeBearing(mapBearing, previous[1]); |
|
var flingDiff = last[1] - first[1], sign = flingDiff < 0 ? -1 : 1, flingDuration = (last[0] - first[0]) / 1000; |
|
if (flingDiff === 0 || flingDuration === 0) { |
|
finish(); |
|
return; |
|
} |
|
var speed = Math.abs(flingDiff * (inertiaLinearity / flingDuration)); |
|
if (speed > inertiaMaxSpeed) { |
|
speed = inertiaMaxSpeed; |
|
} |
|
var duration = speed / (inertiaDeceleration * inertiaLinearity), offset = sign * speed * (duration / 2); |
|
bearing += offset; |
|
if (Math.abs(map._normalizeBearing(bearing, 0)) < this._bearingSnap) { |
|
bearing = map._normalizeBearing(0, bearing); |
|
} |
|
map.rotateTo(bearing, { |
|
duration: duration * 1000, |
|
easing: inertiaEasing, |
|
noMoveStart: true |
|
}, { originalEvent: e }); |
|
}; |
|
DragRotateHandler.prototype._fireEvent = function _fireEvent(type, e) { |
|
return this._map.fire(new symbol_layout.Event(type, e ? { originalEvent: e } : {})); |
|
}; |
|
DragRotateHandler.prototype._drainInertiaBuffer = function _drainInertiaBuffer() { |
|
var inertia = this._inertia, now = symbol_layout.browser.now(), cutoff = 160; |
|
while (inertia.length > 0 && now - inertia[0][0] > cutoff) { |
|
inertia.shift(); |
|
} |
|
}; |
|
|
|
var inertiaLinearity$1 = 0.3, inertiaEasing$1 = symbol_layout.bezier(0, 0, inertiaLinearity$1, 1), inertiaMaxSpeed$1 = 1400, inertiaDeceleration$1 = 2500; |
|
var DragPanHandler = function DragPanHandler(map, options) { |
|
this._map = map; |
|
this._el = map.getCanvasContainer(); |
|
this._state = 'disabled'; |
|
this._clickTolerance = options.clickTolerance || 1; |
|
symbol_layout.bindAll([ |
|
'_onMove', |
|
'_onMouseUp', |
|
'_onTouchEnd', |
|
'_onBlur', |
|
'_onDragFrame' |
|
], this); |
|
}; |
|
DragPanHandler.prototype.isEnabled = function isEnabled() { |
|
return this._state !== 'disabled'; |
|
}; |
|
DragPanHandler.prototype.isActive = function isActive() { |
|
return this._state === 'active'; |
|
}; |
|
DragPanHandler.prototype.enable = function enable() { |
|
if (this.isEnabled()) { |
|
return; |
|
} |
|
this._el.classList.add('mapboxgl-touch-drag-pan'); |
|
this._state = 'enabled'; |
|
}; |
|
DragPanHandler.prototype.disable = function disable() { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
this._el.classList.remove('mapboxgl-touch-drag-pan'); |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'disabled'; |
|
this._unbind(); |
|
this._deactivate(); |
|
this._fireEvent('dragend'); |
|
this._fireEvent('moveend'); |
|
break; |
|
case 'pending': |
|
this._state = 'disabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
this._state = 'disabled'; |
|
break; |
|
} |
|
}; |
|
DragPanHandler.prototype.onMouseDown = function onMouseDown(e) { |
|
if (this._state !== 'enabled') { |
|
return; |
|
} |
|
if (e.ctrlKey || DOM.mouseButton(e) !== 0) { |
|
return; |
|
} |
|
DOM.addEventListener(symbol_layout.window.document, 'mousemove', this._onMove, { capture: true }); |
|
DOM.addEventListener(symbol_layout.window.document, 'mouseup', this._onMouseUp); |
|
this._start(e); |
|
}; |
|
DragPanHandler.prototype.onTouchStart = function onTouchStart(e) { |
|
if (this._state !== 'enabled') { |
|
return; |
|
} |
|
if (e.touches.length > 1) { |
|
return; |
|
} |
|
DOM.addEventListener(symbol_layout.window.document, 'touchmove', this._onMove, { |
|
capture: true, |
|
passive: false |
|
}); |
|
DOM.addEventListener(symbol_layout.window.document, 'touchend', this._onTouchEnd); |
|
this._start(e); |
|
}; |
|
DragPanHandler.prototype._start = function _start(e) { |
|
symbol_layout.window.addEventListener('blur', this._onBlur); |
|
this._state = 'pending'; |
|
this._startPos = this._mouseDownPos = this._prevPos = this._lastPos = DOM.mousePos(this._el, e); |
|
this._inertia = [[ |
|
symbol_layout.browser.now(), |
|
this._startPos |
|
]]; |
|
}; |
|
DragPanHandler.prototype._onMove = function _onMove(e) { |
|
e.preventDefault(); |
|
var pos = DOM.mousePos(this._el, e); |
|
if (this._lastPos.equals(pos) || this._state === 'pending' && pos.dist(this._mouseDownPos) < this._clickTolerance) { |
|
return; |
|
} |
|
this._lastMoveEvent = e; |
|
this._lastPos = pos; |
|
this._drainInertiaBuffer(); |
|
this._inertia.push([ |
|
symbol_layout.browser.now(), |
|
this._lastPos |
|
]); |
|
if (this._state === 'pending') { |
|
this._state = 'active'; |
|
this._fireEvent('dragstart', e); |
|
this._fireEvent('movestart', e); |
|
} |
|
if (!this._frameId) { |
|
this._frameId = this._map._requestRenderFrame(this._onDragFrame); |
|
} |
|
}; |
|
DragPanHandler.prototype._onDragFrame = function _onDragFrame() { |
|
this._frameId = null; |
|
var e = this._lastMoveEvent; |
|
if (!e) { |
|
return; |
|
} |
|
var tr = this._map.transform; |
|
tr.setLocationAtPoint(tr.pointLocation(this._prevPos), this._lastPos); |
|
this._fireEvent('drag', e); |
|
this._fireEvent('move', e); |
|
this._prevPos = this._lastPos; |
|
delete this._lastMoveEvent; |
|
}; |
|
DragPanHandler.prototype._onMouseUp = function _onMouseUp(e) { |
|
if (DOM.mouseButton(e) !== 0) { |
|
return; |
|
} |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'enabled'; |
|
DOM.suppressClick(); |
|
this._unbind(); |
|
this._deactivate(); |
|
this._inertialPan(e); |
|
break; |
|
case 'pending': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
break; |
|
} |
|
}; |
|
DragPanHandler.prototype._onTouchEnd = function _onTouchEnd(e) { |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
this._deactivate(); |
|
this._inertialPan(e); |
|
break; |
|
case 'pending': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
break; |
|
} |
|
}; |
|
DragPanHandler.prototype._onBlur = function _onBlur(e) { |
|
switch (this._state) { |
|
case 'active': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
this._deactivate(); |
|
this._fireEvent('dragend', e); |
|
this._fireEvent('moveend', e); |
|
break; |
|
case 'pending': |
|
this._state = 'enabled'; |
|
this._unbind(); |
|
break; |
|
default: |
|
break; |
|
} |
|
}; |
|
DragPanHandler.prototype._unbind = function _unbind() { |
|
DOM.removeEventListener(symbol_layout.window.document, 'touchmove', this._onMove, { |
|
capture: true, |
|
passive: false |
|
}); |
|
DOM.removeEventListener(symbol_layout.window.document, 'touchend', this._onTouchEnd); |
|
DOM.removeEventListener(symbol_layout.window.document, 'mousemove', this._onMove, { capture: true }); |
|
DOM.removeEventListener(symbol_layout.window.document, 'mouseup', this._onMouseUp); |
|
DOM.removeEventListener(symbol_layout.window, 'blur', this._onBlur); |
|
}; |
|
DragPanHandler.prototype._deactivate = function _deactivate() { |
|
if (this._frameId) { |
|
this._map._cancelRenderFrame(this._frameId); |
|
this._frameId = null; |
|
} |
|
delete this._lastMoveEvent; |
|
delete this._startPos; |
|
delete this._prevPos; |
|
delete this._mouseDownPos; |
|
delete this._lastPos; |
|
}; |
|
DragPanHandler.prototype._inertialPan = function _inertialPan(e) { |
|
this._fireEvent('dragend', e); |
|
this._drainInertiaBuffer(); |
|
var inertia = this._inertia; |
|
if (inertia.length < 2) { |
|
this._fireEvent('moveend', e); |
|
return; |
|
} |
|
var last = inertia[inertia.length - 1], first = inertia[0], flingOffset = last[1].sub(first[1]), flingDuration = (last[0] - first[0]) / 1000; |
|
if (flingDuration === 0 || last[1].equals(first[1])) { |
|
this._fireEvent('moveend', e); |
|
return; |
|
} |
|
var velocity = flingOffset.mult(inertiaLinearity$1 / flingDuration); |
|
var speed = velocity.mag(); |
|
if (speed > inertiaMaxSpeed$1) { |
|
speed = inertiaMaxSpeed$1; |
|
velocity._unit()._mult(speed); |
|
} |
|
var duration = speed / (inertiaDeceleration$1 * inertiaLinearity$1), offset = velocity.mult(-duration / 2); |
|
this._map.panBy(offset, { |
|
duration: duration * 1000, |
|
easing: inertiaEasing$1, |
|
noMoveStart: true |
|
}, { originalEvent: e }); |
|
}; |
|
DragPanHandler.prototype._fireEvent = function _fireEvent(type, e) { |
|
return this._map.fire(new symbol_layout.Event(type, e ? { originalEvent: e } : {})); |
|
}; |
|
DragPanHandler.prototype._drainInertiaBuffer = function _drainInertiaBuffer() { |
|
var inertia = this._inertia, now = symbol_layout.browser.now(), cutoff = 160; |
|
while (inertia.length > 0 && now - inertia[0][0] > cutoff) { |
|
inertia.shift(); |
|
} |
|
}; |
|
|
|
var panStep = 100, bearingStep = 15, pitchStep = 10; |
|
var KeyboardHandler = function KeyboardHandler(map) { |
|
this._map = map; |
|
this._el = map.getCanvasContainer(); |
|
symbol_layout.bindAll(['_onKeyDown'], this); |
|
}; |
|
KeyboardHandler.prototype.isEnabled = function isEnabled() { |
|
return !!this._enabled; |
|
}; |
|
KeyboardHandler.prototype.enable = function enable() { |
|
if (this.isEnabled()) { |
|
return; |
|
} |
|
this._el.addEventListener('keydown', this._onKeyDown, false); |
|
this._enabled = true; |
|
}; |
|
KeyboardHandler.prototype.disable = function disable() { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
this._el.removeEventListener('keydown', this._onKeyDown); |
|
this._enabled = false; |
|
}; |
|
KeyboardHandler.prototype._onKeyDown = function _onKeyDown(e) { |
|
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 { |
|
yDir = 1; |
|
e.preventDefault(); |
|
} |
|
break; |
|
default: |
|
return; |
|
} |
|
var map = this._map; |
|
var zoom = map.getZoom(); |
|
var easeOptions = { |
|
duration: 300, |
|
delayEndEvents: 500, |
|
easing: easeOut, |
|
zoom: zoomDir ? Math.round(zoom) + zoomDir * (e.shiftKey ? 2 : 1) : zoom, |
|
bearing: map.getBearing() + bearingDir * bearingStep, |
|
pitch: map.getPitch() + pitchDir * pitchStep, |
|
offset: [ |
|
-xDir * panStep, |
|
-yDir * panStep |
|
], |
|
center: map.getCenter() |
|
}; |
|
map.easeTo(easeOptions, { originalEvent: e }); |
|
}; |
|
function easeOut(t) { |
|
return t * (2 - t); |
|
} |
|
|
|
var maxDist = 30; |
|
var DoubleClickZoomHandler = function DoubleClickZoomHandler(map) { |
|
this._map = map; |
|
symbol_layout.bindAll([ |
|
'_onDblClick', |
|
'_onZoomEnd' |
|
], this); |
|
}; |
|
DoubleClickZoomHandler.prototype.isEnabled = function isEnabled() { |
|
return !!this._enabled; |
|
}; |
|
DoubleClickZoomHandler.prototype.isActive = function isActive() { |
|
return !!this._active; |
|
}; |
|
DoubleClickZoomHandler.prototype.enable = function enable() { |
|
if (this.isEnabled()) { |
|
return; |
|
} |
|
this._enabled = true; |
|
}; |
|
DoubleClickZoomHandler.prototype.disable = function disable() { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
this._enabled = false; |
|
}; |
|
DoubleClickZoomHandler.prototype.onTouchStart = function onTouchStart(e) { |
|
var this$1 = this; |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
if (e.points.length > 1) { |
|
return; |
|
} |
|
if (!this._tapped) { |
|
this._tappedPoint = e.points[0]; |
|
this._tapped = setTimeout(function () { |
|
this$1._tapped = null; |
|
this$1._tappedPoint = null; |
|
}, 300); |
|
} else { |
|
var newTap = e.points[0]; |
|
var firstTap = this._tappedPoint; |
|
if (firstTap && firstTap.dist(newTap) <= maxDist) { |
|
e.originalEvent.preventDefault(); |
|
var onTouchEnd = function () { |
|
if (this$1._tapped) { |
|
this$1._zoom(e); |
|
} |
|
this$1._map.off('touchcancel', onTouchCancel); |
|
this$1._resetTapped(); |
|
}; |
|
var onTouchCancel = function () { |
|
this$1._map.off('touchend', onTouchEnd); |
|
this$1._resetTapped(); |
|
}; |
|
this._map.once('touchend', onTouchEnd); |
|
this._map.once('touchcancel', onTouchCancel); |
|
} else { |
|
this._resetTapped(); |
|
} |
|
} |
|
}; |
|
DoubleClickZoomHandler.prototype._resetTapped = function _resetTapped() { |
|
clearTimeout(this._tapped); |
|
this._tapped = null; |
|
this._tappedPoint = null; |
|
}; |
|
DoubleClickZoomHandler.prototype.onDblClick = function onDblClick(e) { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
e.originalEvent.preventDefault(); |
|
this._zoom(e); |
|
}; |
|
DoubleClickZoomHandler.prototype._zoom = function _zoom(e) { |
|
this._active = true; |
|
this._map.on('zoomend', this._onZoomEnd); |
|
this._map.zoomTo(this._map.getZoom() + (e.originalEvent.shiftKey ? -1 : 1), { around: e.lngLat }, e); |
|
}; |
|
DoubleClickZoomHandler.prototype._onZoomEnd = function _onZoomEnd() { |
|
this._active = false; |
|
this._map.off('zoomend', this._onZoomEnd); |
|
}; |
|
|
|
var inertiaLinearity$2 = 0.15, inertiaEasing$2 = symbol_layout.bezier(0, 0, inertiaLinearity$2, 1), inertiaDeceleration$2 = 12, inertiaMaxSpeed$2 = 2.5, significantScaleThreshold = 0.15, significantRotateThreshold = 10; |
|
var TouchZoomRotateHandler = function TouchZoomRotateHandler(map) { |
|
this._map = map; |
|
this._el = map.getCanvasContainer(); |
|
symbol_layout.bindAll([ |
|
'_onMove', |
|
'_onEnd', |
|
'_onTouchFrame' |
|
], this); |
|
}; |
|
TouchZoomRotateHandler.prototype.isEnabled = function isEnabled() { |
|
return !!this._enabled; |
|
}; |
|
TouchZoomRotateHandler.prototype.enable = function enable(options) { |
|
if (this.isEnabled()) { |
|
return; |
|
} |
|
this._el.classList.add('mapboxgl-touch-zoom-rotate'); |
|
this._enabled = true; |
|
this._aroundCenter = !!options && options.around === 'center'; |
|
}; |
|
TouchZoomRotateHandler.prototype.disable = function disable() { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
this._el.classList.remove('mapboxgl-touch-zoom-rotate'); |
|
this._enabled = false; |
|
}; |
|
TouchZoomRotateHandler.prototype.disableRotation = function disableRotation() { |
|
this._rotationDisabled = true; |
|
}; |
|
TouchZoomRotateHandler.prototype.enableRotation = function enableRotation() { |
|
this._rotationDisabled = false; |
|
}; |
|
TouchZoomRotateHandler.prototype.onStart = function onStart(e) { |
|
if (!this.isEnabled()) { |
|
return; |
|
} |
|
if (e.touches.length !== 2) { |
|
return; |
|
} |
|
var p0 = DOM.mousePos(this._el, e.touches[0]), p1 = DOM.mousePos(this._el, e.touches[1]), center = p0.add(p1).div(2); |
|
this._startVec = p0.sub(p1); |
|
this._startAround = this._map.transform.pointLocation(center); |
|
this._gestureIntent = undefined; |
|
this._inertia = []; |
|
DOM.addEventListener(symbol_layout.window.document, 'touchmove', this._onMove, { passive: false }); |
|
DOM.addEventListener(symbol_layout.window.document, 'touchend', this._onEnd); |
|
}; |
|
TouchZoomRotateHandler.prototype._getTouchEventData = function _getTouchEventData(e) { |
|
var p0 = DOM.mousePos(this._el, e.touches[0]), p1 = DOM.mousePos(this._el, e.touches[1]); |
|
var vec = p0.sub(p1); |
|
return { |
|
vec: vec, |
|
center: p0.add(p1).div(2), |
|
scale: vec.mag() / this._startVec.mag(), |
|
bearing: this._rotationDisabled ? 0 : vec.angleWith(this._startVec) * 180 / Math.PI |
|
}; |
|
}; |
|
TouchZoomRotateHandler.prototype._onMove = function _onMove(e) { |
|
if (e.touches.length !== 2) { |
|
return; |
|
} |
|
var ref = this._getTouchEventData(e); |
|
var vec = ref.vec; |
|
var scale = ref.scale; |
|
var bearing = ref.bearing; |
|
if (!this._gestureIntent) { |
|
var scalingSignificantly = this._rotationDisabled && scale !== 1 || Math.abs(1 - scale) > significantScaleThreshold, rotatingSignificantly = Math.abs(bearing) > significantRotateThreshold; |
|
if (rotatingSignificantly) { |
|
this._gestureIntent = 'rotate'; |
|
} else if (scalingSignificantly) { |
|
this._gestureIntent = 'zoom'; |
|
} |
|
if (this._gestureIntent) { |
|
this._map.fire(new symbol_layout.Event(this._gestureIntent + 'start', { originalEvent: e })); |
|
this._map.fire(new symbol_layout.Event('movestart', { originalEvent: e })); |
|
this._startVec = vec; |
|
} |
|
} |
|
this._lastTouchEvent = e; |
|
if (!this._frameId) { |
|
this._frameId = this._map._requestRenderFrame(this._onTouchFrame); |
|
} |
|
e.preventDefault(); |
|
}; |
|
TouchZoomRotateHandler.prototype._onTouchFrame = function _onTouchFrame() { |
|
this._frameId = null; |
|
var gestureIntent = this._gestureIntent; |
|
if (!gestureIntent) { |
|
return; |
|
} |
|
var tr = this._map.transform; |
|
if (!this._startScale) { |
|
this._startScale = tr.scale; |
|
this._startBearing = tr.bearing; |
|
} |
|
var ref = this._getTouchEventData(this._lastTouchEvent); |
|
var center = ref.center; |
|
var bearing = ref.bearing; |
|
var scale = ref.scale; |
|
var around = tr.pointLocation(center); |
|
var aroundPoint = tr.locationPoint(around); |
|
if (gestureIntent === 'rotate') { |
|
tr.bearing = this._startBearing + bearing; |
|
} |
|
tr.zoom = tr.scaleZoom(this._startScale * scale); |
|
tr.setLocationAtPoint(this._startAround, aroundPoint); |
|
this._map.fire(new symbol_layout.Event(gestureIntent, { originalEvent: this._lastTouchEvent })); |
|
this._map.fire(new symbol_layout.Event('move', { originalEvent: this._lastTouchEvent })); |
|
this._drainInertiaBuffer(); |
|
this._inertia.push([ |
|
symbol_layout.browser.now(), |
|
scale, |
|
center |
|
]); |
|
}; |
|
TouchZoomRotateHandler.prototype._onEnd = function _onEnd(e) { |
|
DOM.removeEventListener(symbol_layout.window.document, 'touchmove', this._onMove, { passive: false }); |
|
DOM.removeEventListener(symbol_layout.window.document, 'touchend', this._onEnd); |
|
var gestureIntent = this._gestureIntent; |
|
var startScale = this._startScale; |
|
if (this._frameId) { |
|
this._map._cancelRenderFrame(this._frameId); |
|
this._frameId = null; |
|
} |
|
delete this._gestureIntent; |
|
delete this._startScale; |
|
delete this._startBearing; |
|
delete this._lastTouchEvent; |
|
if (!gestureIntent) { |
|
return; |
|
} |
|
this._map.fire(new symbol_layout.Event(gestureIntent + 'end', { originalEvent: e })); |
|
this._drainInertiaBuffer(); |
|
var inertia = this._inertia, map = this._map; |
|
if (inertia.length < 2) { |
|
map.snapToNorth({}, { originalEvent: e }); |
|
return; |
|
} |
|
var last = inertia[inertia.length - 1], first = inertia[0], lastScale = map.transform.scaleZoom(startScale * last[1]), firstScale = map.transform.scaleZoom(startScale * first[1]), scaleOffset = lastScale - firstScale, scaleDuration = (last[0] - first[0]) / 1000, p = last[2]; |
|
if (scaleDuration === 0 || lastScale === firstScale) { |
|
map.snapToNorth({}, { originalEvent: e }); |
|
return; |
|
} |
|
var speed = scaleOffset * inertiaLinearity$2 / scaleDuration; |
|
if (Math.abs(speed) > inertiaMaxSpeed$2) { |
|
if (speed > 0) { |
|
speed = inertiaMaxSpeed$2; |
|
} else { |
|
speed = -inertiaMaxSpeed$2; |
|
} |
|
} |
|
var duration = Math.abs(speed / (inertiaDeceleration$2 * inertiaLinearity$2)) * 1000; |
|
var targetScale = lastScale + speed * duration / 2000; |
|
if (targetScale < 0) { |
|
targetScale = 0; |
|
} |
|
map.easeTo({ |
|
zoom: targetScale, |
|
duration: duration, |
|
easing: inertiaEasing$2, |
|
around: this._aroundCenter ? map.getCenter() : map.unproject(p), |
|
noMoveStart: true |
|
}, { originalEvent: e }); |
|
}; |
|
TouchZoomRotateHandler.prototype._drainInertiaBuffer = function _drainInertiaBuffer() { |
|
var inertia = this._inertia, now = symbol_layout.browser.now(), cutoff = 160; |
|
while (inertia.length > 2 && now - inertia[0][0] > cutoff) { |
|
inertia.shift(); |
|
} |
|
}; |
|
|
|
var handlers = { |
|
scrollZoom: ScrollZoomHandler, |
|
boxZoom: BoxZoomHandler, |
|
dragRotate: DragRotateHandler, |
|
dragPan: DragPanHandler, |
|
keyboard: KeyboardHandler, |
|
doubleClickZoom: DoubleClickZoomHandler, |
|
touchZoomRotate: TouchZoomRotateHandler |
|
}; |
|
function bindHandlers(map, options) { |
|
var el = map.getCanvasContainer(); |
|
var contextMenuEvent = null; |
|
var mouseDown = false; |
|
var startPos = null; |
|
for (var name in handlers) { |
|
map[name] = new handlers[name](map, options); |
|
if (options.interactive && options[name]) { |
|
map[name].enable(options[name]); |
|
} |
|
} |
|
DOM.addEventListener(el, 'mouseout', onMouseOut); |
|
DOM.addEventListener(el, 'mousedown', onMouseDown); |
|
DOM.addEventListener(el, 'mouseup', onMouseUp); |
|
DOM.addEventListener(el, 'mousemove', onMouseMove); |
|
DOM.addEventListener(el, 'mouseover', onMouseOver); |
|
DOM.addEventListener(el, 'touchstart', onTouchStart, { passive: false }); |
|
DOM.addEventListener(el, 'touchmove', onTouchMove, { passive: false }); |
|
DOM.addEventListener(el, 'touchend', onTouchEnd); |
|
DOM.addEventListener(el, 'touchcancel', onTouchCancel); |
|
DOM.addEventListener(el, 'click', onClick); |
|
DOM.addEventListener(el, 'dblclick', onDblClick); |
|
DOM.addEventListener(el, 'contextmenu', onContextMenu); |
|
DOM.addEventListener(el, 'wheel', onWheel, { passive: false }); |
|
function onMouseDown(e) { |
|
mouseDown = true; |
|
startPos = DOM.mousePos(el, e); |
|
var mapEvent = new MapMouseEvent('mousedown', map, e); |
|
map.fire(mapEvent); |
|
if (mapEvent.defaultPrevented) { |
|
return; |
|
} |
|
if (options.interactive && !map.doubleClickZoom.isActive()) { |
|
map.stop(); |
|
} |
|
map.boxZoom.onMouseDown(e); |
|
if (!map.boxZoom.isActive() && !map.dragPan.isActive()) { |
|
map.dragRotate.onMouseDown(e); |
|
} |
|
if (!map.boxZoom.isActive() && !map.dragRotate.isActive()) { |
|
map.dragPan.onMouseDown(e); |
|
} |
|
} |
|
function onMouseUp(e) { |
|
var rotating = map.dragRotate.isActive(); |
|
if (contextMenuEvent && !rotating) { |
|
map.fire(new MapMouseEvent('contextmenu', map, contextMenuEvent)); |
|
} |
|
contextMenuEvent = null; |
|
mouseDown = false; |
|
map.fire(new MapMouseEvent('mouseup', map, e)); |
|
} |
|
function onMouseMove(e) { |
|
if (map.dragPan.isActive()) { |
|
return; |
|
} |
|
if (map.dragRotate.isActive()) { |
|
return; |
|
} |
|
var target = e.target; |
|
while (target && target !== el) { |
|
target = target.parentNode; |
|
} |
|
if (target !== el) { |
|
return; |
|
} |
|
map.fire(new MapMouseEvent('mousemove', map, e)); |
|
} |
|
function onMouseOver(e) { |
|
var target = e.target; |
|
while (target && target !== el) { |
|
target = target.parentNode; |
|
} |
|
if (target !== el) { |
|
return; |
|
} |
|
map.fire(new MapMouseEvent('mouseover', map, e)); |
|
} |
|
function onMouseOut(e) { |
|
map.fire(new MapMouseEvent('mouseout', map, e)); |
|
} |
|
function onTouchStart(e) { |
|
var mapEvent = new MapTouchEvent('touchstart', map, e); |
|
map.fire(mapEvent); |
|
if (mapEvent.defaultPrevented) { |
|
return; |
|
} |
|
if (options.interactive) { |
|
map.stop(); |
|
} |
|
if (!map.boxZoom.isActive() && !map.dragRotate.isActive()) { |
|
map.dragPan.onTouchStart(e); |
|
} |
|
map.touchZoomRotate.onStart(e); |
|
map.doubleClickZoom.onTouchStart(mapEvent); |
|
} |
|
function onTouchMove(e) { |
|
map.fire(new MapTouchEvent('touchmove', map, e)); |
|
} |
|
function onTouchEnd(e) { |
|
map.fire(new MapTouchEvent('touchend', map, e)); |
|
} |
|
function onTouchCancel(e) { |
|
map.fire(new MapTouchEvent('touchcancel', map, e)); |
|
} |
|
function onClick(e) { |
|
var pos = DOM.mousePos(el, e); |
|
if (!startPos || pos.equals(startPos) || pos.dist(startPos) < options.clickTolerance) { |
|
map.fire(new MapMouseEvent('click', map, e)); |
|
} |
|
} |
|
function onDblClick(e) { |
|
var mapEvent = new MapMouseEvent('dblclick', map, e); |
|
map.fire(mapEvent); |
|
if (mapEvent.defaultPrevented) { |
|
return; |
|
} |
|
map.doubleClickZoom.onDblClick(mapEvent); |
|
} |
|
function onContextMenu(e) { |
|
var rotating = map.dragRotate.isActive(); |
|
if (!mouseDown && !rotating) { |
|
map.fire(new MapMouseEvent('contextmenu', map, e)); |
|
} else if (mouseDown) { |
|
contextMenuEvent = e; |
|
} |
|
if (map.dragRotate.isEnabled() || map.listens('contextmenu')) { |
|
e.preventDefault(); |
|
} |
|
} |
|
function onWheel(e) { |
|
if (options.interactive) { |
|
map.stop(); |
|
} |
|
var mapEvent = new MapWheelEvent('wheel', map, e); |
|
map.fire(mapEvent); |
|
if (mapEvent.defaultPrevented) { |
|
return; |
|
} |
|
map.scrollZoom.onWheel(e); |
|
} |
|
} |
|
|
|
var Camera = function (Evented) { |
|
function Camera(transform, options) { |
|
Evented.call(this); |
|
this._moving = false; |
|
this._zooming = false; |
|
this.transform = transform; |
|
this._bearingSnap = options.bearingSnap; |
|
symbol_layout.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 symbol_layout.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 = symbol_layout.Point.convert(offset).mult(-1); |
|
return this.panTo(this.transform.center, symbol_layout.extend({ offset: offset }, options), eventData); |
|
}; |
|
Camera.prototype.panTo = function panTo(lnglat, options, eventData) { |
|
return this.easeTo(symbol_layout.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(symbol_layout.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.rotateTo = function rotateTo(bearing, options, eventData) { |
|
return this.easeTo(symbol_layout.extend({ bearing: bearing }, options), eventData); |
|
}; |
|
Camera.prototype.resetNorth = function resetNorth(options, eventData) { |
|
this.rotateTo(0, symbol_layout.extend({ duration: 1000 }, options), eventData); |
|
return this; |
|
}; |
|
Camera.prototype.resetNorthPitch = function resetNorthPitch(options, eventData) { |
|
this.easeTo(symbol_layout.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 = symbol_layout.LngLatBounds.convert(bounds); |
|
return this._cameraForBoxAndBearing(bounds.getNorthWest(), bounds.getSouthEast(), 0, options); |
|
}; |
|
Camera.prototype._cameraForBoxAndBearing = function _cameraForBoxAndBearing(p0, p1, bearing, options) { |
|
options = symbol_layout.extend({ |
|
padding: { |
|
top: 0, |
|
bottom: 0, |
|
right: 0, |
|
left: 0 |
|
}, |
|
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 |
|
}; |
|
} |
|
if (!symbol_layout.deepEqual(Object.keys(options.padding).sort(function (a, b) { |
|
if (a < b) { |
|
return -1; |
|
} |
|
if (a > b) { |
|
return 1; |
|
} |
|
return 0; |
|
}), [ |
|
'bottom', |
|
'left', |
|
'right', |
|
'top' |
|
])) { |
|
symbol_layout.warnOnce('options.padding must be a positive number, or an Object with keys \'bottom\', \'left\', \'right\', \'top\''); |
|
return; |
|
} |
|
var tr = this.transform; |
|
var p0world = tr.project(symbol_layout.LngLat.convert(p0)); |
|
var p1world = tr.project(symbol_layout.LngLat.convert(p1)); |
|
var p0rotated = p0world.rotate(-bearing * Math.PI / 180); |
|
var p1rotated = p1world.rotate(-bearing * Math.PI / 180); |
|
var upperRight = new symbol_layout.Point(Math.max(p0rotated.x, p1rotated.x), Math.max(p0rotated.y, p1rotated.y)); |
|
var lowerLeft = new symbol_layout.Point(Math.min(p0rotated.x, p1rotated.x), Math.min(p0rotated.y, p1rotated.y)); |
|
var size = upperRight.sub(lowerLeft); |
|
var scaleX = (tr.width - options.padding.left - options.padding.right) / size.x; |
|
var scaleY = (tr.height - options.padding.top - options.padding.bottom) / size.y; |
|
if (scaleY < 0 || scaleX < 0) { |
|
symbol_layout.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 = symbol_layout.Point.convert(options.offset); |
|
var paddingOffsetX = (options.padding.left - options.padding.right) / 2; |
|
var paddingOffsetY = (options.padding.top - options.padding.bottom) / 2; |
|
var offsetAtInitialZoom = new symbol_layout.Point(offset.x + paddingOffsetX, offset.y + paddingOffsetY); |
|
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(symbol_layout.Point.convert(p0)), this.transform.pointLocation(symbol_layout.Point.convert(p1)), bearing, options), options, eventData); |
|
}; |
|
Camera.prototype._fitInternal = function _fitInternal(calculatedOptions, options, eventData) { |
|
if (!calculatedOptions) { |
|
return this; |
|
} |
|
options = symbol_layout.extend(calculatedOptions, options); |
|
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 = symbol_layout.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; |
|
} |
|
this.fire(new symbol_layout.Event('movestart', eventData)).fire(new symbol_layout.Event('move', eventData)); |
|
if (zoomChanged) { |
|
this.fire(new symbol_layout.Event('zoomstart', eventData)).fire(new symbol_layout.Event('zoom', eventData)).fire(new symbol_layout.Event('zoomend', eventData)); |
|
} |
|
if (bearingChanged) { |
|
this.fire(new symbol_layout.Event('rotatestart', eventData)).fire(new symbol_layout.Event('rotate', eventData)).fire(new symbol_layout.Event('rotateend', eventData)); |
|
} |
|
if (pitchChanged) { |
|
this.fire(new symbol_layout.Event('pitchstart', eventData)).fire(new symbol_layout.Event('pitch', eventData)).fire(new symbol_layout.Event('pitchend', eventData)); |
|
} |
|
return this.fire(new symbol_layout.Event('moveend', eventData)); |
|
}; |
|
Camera.prototype.easeTo = function easeTo(options, eventData) { |
|
var this$1 = this; |
|
this.stop(); |
|
options = symbol_layout.extend({ |
|
offset: [ |
|
0, |
|
0 |
|
], |
|
duration: 500, |
|
easing: symbol_layout.ease |
|
}, options); |
|
if (options.animate === false || symbol_layout.browser.prefersReducedMotion) { |
|
options.duration = 0; |
|
} |
|
var tr = this.transform, startZoom = this.getZoom(), startBearing = this.getBearing(), startPitch = this.getPitch(), zoom = 'zoom' in options ? +options.zoom : startZoom, bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing, pitch = 'pitch' in options ? +options.pitch : startPitch; |
|
var pointAtOffset = tr.centerPoint.add(symbol_layout.Point.convert(options.offset)); |
|
var locationAtOffset = tr.pointLocation(pointAtOffset); |
|
var center = symbol_layout.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 = symbol_layout.LngLat.convert(options.around); |
|
aroundPoint = tr.locationPoint(around); |
|
} |
|
this._zooming = zoom !== startZoom; |
|
this._rotating = startBearing !== bearing; |
|
this._pitching = pitch !== startPitch; |
|
this._prepareEase(eventData, options.noMoveStart); |
|
clearTimeout(this._easeEndTimeoutID); |
|
this._ease(function (k) { |
|
if (this$1._zooming) { |
|
tr.zoom = symbol_layout.number(startZoom, zoom, k); |
|
} |
|
if (this$1._rotating) { |
|
tr.bearing = symbol_layout.number(startBearing, bearing, k); |
|
} |
|
if (this$1._pitching) { |
|
tr.pitch = symbol_layout.number(startPitch, pitch, k); |
|
} |
|
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 () { |
|
if (options.delayEndEvents) { |
|
this$1._easeEndTimeoutID = setTimeout(function () { |
|
return this$1._afterEase(eventData); |
|
}, options.delayEndEvents); |
|
} else { |
|
this$1._afterEase(eventData); |
|
} |
|
}, options); |
|
return this; |
|
}; |
|
Camera.prototype._prepareEase = function _prepareEase(eventData, noMoveStart) { |
|
this._moving = true; |
|
if (!noMoveStart) { |
|
this.fire(new symbol_layout.Event('movestart', eventData)); |
|
} |
|
if (this._zooming) { |
|
this.fire(new symbol_layout.Event('zoomstart', eventData)); |
|
} |
|
if (this._rotating) { |
|
this.fire(new symbol_layout.Event('rotatestart', eventData)); |
|
} |
|
if (this._pitching) { |
|
this.fire(new symbol_layout.Event('pitchstart', eventData)); |
|
} |
|
}; |
|
Camera.prototype._fireMoveEvents = function _fireMoveEvents(eventData) { |
|
this.fire(new symbol_layout.Event('move', eventData)); |
|
if (this._zooming) { |
|
this.fire(new symbol_layout.Event('zoom', eventData)); |
|
} |
|
if (this._rotating) { |
|
this.fire(new symbol_layout.Event('rotate', eventData)); |
|
} |
|
if (this._pitching) { |
|
this.fire(new symbol_layout.Event('pitch', eventData)); |
|
} |
|
}; |
|
Camera.prototype._afterEase = function _afterEase(eventData) { |
|
var wasZooming = this._zooming; |
|
var wasRotating = this._rotating; |
|
var wasPitching = this._pitching; |
|
this._moving = false; |
|
this._zooming = false; |
|
this._rotating = false; |
|
this._pitching = false; |
|
if (wasZooming) { |
|
this.fire(new symbol_layout.Event('zoomend', eventData)); |
|
} |
|
if (wasRotating) { |
|
this.fire(new symbol_layout.Event('rotateend', eventData)); |
|
} |
|
if (wasPitching) { |
|
this.fire(new symbol_layout.Event('pitchend', eventData)); |
|
} |
|
this.fire(new symbol_layout.Event('moveend', eventData)); |
|
}; |
|
Camera.prototype.flyTo = function flyTo(options, eventData) { |
|
var this$1 = this; |
|
if (symbol_layout.browser.prefersReducedMotion) { |
|
var coercedOptions = symbol_layout.pick(options, [ |
|
'center', |
|
'zoom', |
|
'bearing', |
|
'pitch', |
|
'around' |
|
]); |
|
return this.jumpTo(coercedOptions, eventData); |
|
} |
|
this.stop(); |
|
options = symbol_layout.extend({ |
|
offset: [ |
|
0, |
|
0 |
|
], |
|
speed: 1.2, |
|
curve: 1.42, |
|
easing: symbol_layout.ease |
|
}, options); |
|
var tr = this.transform, startZoom = this.getZoom(), startBearing = this.getBearing(), startPitch = this.getPitch(); |
|
var zoom = 'zoom' in options ? symbol_layout.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 scale = tr.zoomScale(zoom - startZoom); |
|
var pointAtOffset = tr.centerPoint.add(symbol_layout.Point.convert(options.offset)); |
|
var locationAtOffset = tr.pointLocation(pointAtOffset); |
|
var center = symbol_layout.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 = symbol_layout.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._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 = symbol_layout.number(startBearing, bearing, k); |
|
} |
|
if (this$1._pitching) { |
|
tr.pitch = symbol_layout.number(startPitch, pitch, k); |
|
} |
|
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() { |
|
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); |
|
} |
|
return this; |
|
}; |
|
Camera.prototype._ease = function _ease(frame, finish, options) { |
|
if (options.animate === false || options.duration === 0) { |
|
frame(1); |
|
finish(); |
|
} else { |
|
this._easeStart = symbol_layout.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((symbol_layout.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 = symbol_layout.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; |
|
}(symbol_layout.Evented); |
|
|
|
var AttributionControl = function AttributionControl(options) { |
|
if (options === void 0) |
|
options = {}; |
|
this.options = options; |
|
symbol_layout.bindAll([ |
|
'_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._innerContainer = DOM.create('div', 'mapboxgl-ctrl-attrib-inner', this._container); |
|
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; |
|
}; |
|
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 || symbol_layout.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 = symbol_layout.config.FEEDBACK_URL + '/' + paramString + (this._map._hash ? this._map._hash.getHashString(true) : ''); |
|
editLink.rel = 'noopener nofollow'; |
|
} |
|
}; |
|
AttributionControl.prototype._updateData = function _updateData(e) { |
|
if (e && (e.sourceDataType === 'metadata' || 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'); |
|
} |
|
}; |
|
|
|
var LogoControl = function LogoControl() { |
|
symbol_layout.bindAll(['_updateLogo'], this); |
|
symbol_layout.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', 'Mapbox logo'); |
|
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() { |
|
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(); |
|
if (this._cleared) { |
|
break; |
|
} |
|
} |
|
this._cleared = false; |
|
this._currentlyRunning = false; |
|
}; |
|
TaskQueue.prototype.clear = function clear() { |
|
if (this._currentlyRunning) { |
|
this._cleared = true; |
|
} |
|
this._queue = []; |
|
}; |
|
|
|
var HTMLImageElement = symbol_layout.window.HTMLImageElement; |
|
var HTMLElement = symbol_layout.window.HTMLElement; |
|
var defaultMinZoom = 0; |
|
var defaultMaxZoom = 22; |
|
var defaultOptions = { |
|
center: [ |
|
0, |
|
0 |
|
], |
|
zoom: 0, |
|
bearing: 0, |
|
pitch: 0, |
|
minZoom: defaultMinZoom, |
|
maxZoom: defaultMaxZoom, |
|
interactive: true, |
|
scrollZoom: true, |
|
boxZoom: true, |
|
dragRotate: true, |
|
dragPan: true, |
|
keyboard: true, |
|
doubleClickZoom: true, |
|
touchZoomRotate: true, |
|
bearingSnap: 7, |
|
clickTolerance: 3, |
|
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 = symbol_layout.extend({}, defaultOptions, options); |
|
if (options.minZoom != null && options.maxZoom != null && options.minZoom > options.maxZoom) { |
|
throw new Error('maxZoom must be greater than minZoom'); |
|
} |
|
var transform = new Transform(options.minZoom, options.maxZoom, 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 = symbol_layout.uniqueId(); |
|
this._requestManager = new symbol_layout.RequestManager(options.transformRequest, options.accessToken); |
|
if (typeof options.container === 'string') { |
|
this._container = symbol_layout.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); |
|
} |
|
symbol_layout.bindAll([ |
|
'_onWindowOnline', |
|
'_onWindowResize', |
|
'_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 symbol_layout.window !== 'undefined') { |
|
symbol_layout.window.addEventListener('online', this._onWindowOnline, false); |
|
symbol_layout.window.addEventListener('resize', this._onWindowResize, false); |
|
} |
|
bindHandlers(this, options); |
|
this._hash = options.hash && new Hash().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, symbol_layout.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 symbol_layout.Event(event.dataType + 'data', event)); |
|
}); |
|
this.on('dataloading', function (event) { |
|
this$1.fire(new symbol_layout.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 }, |
|
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 && control.getDefaultPosition) { |
|
position = control.getDefaultPosition(); |
|
} |
|
if (position === undefined) { |
|
position = 'top-right'; |
|
} |
|
if (!control || !control.onAdd) { |
|
return this.fire(new symbol_layout.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 symbol_layout.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.resize = function resize(eventData) { |
|
var dimensions = this._containerDimensions(); |
|
var width = dimensions[0]; |
|
var height = dimensions[1]; |
|
this._resizeCanvas(width, height); |
|
this.transform.resize(width, height); |
|
this.painter.resize(width, height); |
|
this.fire(new symbol_layout.Event('movestart', eventData)).fire(new symbol_layout.Event('move', eventData)).fire(new symbol_layout.Event('resize', eventData)).fire(new symbol_layout.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(symbol_layout.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.getRenderWorldCopies = function getRenderWorldCopies() { |
|
return this.transform.renderWorldCopies; |
|
}; |
|
Map.prototype.setRenderWorldCopies = function setRenderWorldCopies(renderWorldCopies) { |
|
this.transform.renderWorldCopies = renderWorldCopies; |
|
return this._update(); |
|
}; |
|
Map.prototype.getMaxZoom = function getMaxZoom() { |
|
return this.transform.maxZoom; |
|
}; |
|
Map.prototype.project = function project(lnglat) { |
|
return this.transform.locationPoint(symbol_layout.LngLat.convert(lnglat)); |
|
}; |
|
Map.prototype.unproject = function unproject(point) { |
|
return this.transform.pointLocation(symbol_layout.Point.convert(point)); |
|
}; |
|
Map.prototype.isMoving = function isMoving() { |
|
return this._moving || this.dragPan.isActive() || this.dragRotate.isActive() || this.scrollZoom.isActive(); |
|
}; |
|
Map.prototype.isZooming = function isZooming() { |
|
return this._zooming || this.scrollZoom.isZooming(); |
|
}; |
|
Map.prototype.isRotating = function isRotating() { |
|
return this._rotating || this.dragRotate.isActive(); |
|
}; |
|
Map.prototype.on = function on(type, layerId, listener) { |
|
var this$1 = this; |
|
if (listener === undefined) { |
|
return Camera.prototype.on.call(this, type, layerId); |
|
} |
|
var delegatedListener = function () { |
|
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) |
|
}; |
|
} |
|
}(); |
|
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.off = function off(type, layerId, listener) { |
|
if (listener === undefined) { |
|
return Camera.prototype.off.call(this, type, layerId); |
|
} |
|
if (this._delegatedListeners && this._delegatedListeners[type]) { |
|
var listeners = this._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.off(event, delegatedListener.delegates[event]); |
|
} |
|
listeners.splice(i, 1); |
|
return this; |
|
} |
|
} |
|
} |
|
return this; |
|
}; |
|
Map.prototype.queryRenderedFeatures = function queryRenderedFeatures(geometry, options) { |
|
if (!this.style) { |
|
return []; |
|
} |
|
if (options === undefined && geometry !== undefined && !(geometry instanceof symbol_layout.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 symbol_layout.Point || typeof geometry[0] === 'number') { |
|
queryGeometry = [symbol_layout.Point.convert(geometry)]; |
|
} else { |
|
var tl = symbol_layout.Point.convert(geometry[0]); |
|
var br = symbol_layout.Point.convert(geometry[1]); |
|
queryGeometry = [ |
|
tl, |
|
new symbol_layout.Point(br.x, tl.y), |
|
br, |
|
new symbol_layout.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 = symbol_layout.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._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._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, symbol_layout.ResourceType.Style); |
|
symbol_layout.getJSON(request, function (error, json) { |
|
if (error) { |
|
this$1.fire(new symbol_layout.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) { |
|
symbol_layout.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 symbol_layout.warnOnce('There is no style added to the map.'); |
|
} |
|
return this.style.loaded(); |
|
}; |
|
Map.prototype.addSource = function addSource(id, source) { |
|
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 symbol_layout.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) { |
|
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 version = 0; |
|
if (image instanceof HTMLImageElement) { |
|
var ref$1 = symbol_layout.browser.getImageData(image); |
|
var width = ref$1.width; |
|
var height = ref$1.height; |
|
var data = ref$1.data; |
|
this.style.addImage(id, { |
|
data: new symbol_layout.RGBAImage({ |
|
width: width, |
|
height: height |
|
}, data), |
|
pixelRatio: pixelRatio, |
|
sdf: sdf, |
|
version: version |
|
}); |
|
} else if (image.width === undefined || image.height === undefined) { |
|
return this.fire(new symbol_layout.ErrorEvent(new Error('Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' + '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 symbol_layout.RGBAImage({ |
|
width: width$1, |
|
height: height$1 |
|
}, new Uint8Array(data$1)), |
|
pixelRatio: pixelRatio, |
|
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 symbol_layout.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 ? symbol_layout.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 symbol_layout.ErrorEvent(new Error('Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' + '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 symbol_layout.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); |
|
existingImage.data.replace(data, copy); |
|
this.style.updateImage(id, existingImage); |
|
}; |
|
Map.prototype.hasImage = function hasImage(id) { |
|
if (!id) { |
|
this.fire(new symbol_layout.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) { |
|
symbol_layout.getImage(this._requestManager.transformRequest(url, symbol_layout.ResourceType.Image), callback); |
|
}; |
|
Map.prototype.listImages = function listImages() { |
|
return this.style.listImages(); |
|
}; |
|
Map.prototype.addLayer = function addLayer(layer, beforeId) { |
|
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.setFilter = function setFilter(layerId, filter, options) { |
|
if (options === void 0) |
|
options = {}; |
|
this.style.setFilter(layerId, filter, options); |
|
return this._update(true); |
|
}; |
|
Map.prototype.setLayerZoomRange = function setLayerZoomRange(layerId, minzoom, maxzoom) { |
|
this.style.setLayerZoomRange(layerId, minzoom, maxzoom); |
|
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.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 = symbol_layout.window.getComputedStyle(this._missingCSSCanary).getPropertyValue('background-color'); |
|
if (computedColor !== 'rgb(250, 128, 114)') { |
|
symbol_layout.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.style.position = 'absolute'; |
|
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'); |
|
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); |
|
}); |
|
}; |
|
Map.prototype._resizeCanvas = function _resizeCanvas(width, height) { |
|
var pixelRatio = symbol_layout.window.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 = symbol_layout.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 symbol_layout.ErrorEvent(new Error('Failed to initialize WebGL'))); |
|
return; |
|
} |
|
this.painter = new Painter(gl, this.transform); |
|
symbol_layout.webpSupported.testSupport(gl); |
|
}; |
|
Map.prototype._contextLost = function _contextLost(event) { |
|
event.preventDefault(); |
|
if (this._frame) { |
|
this._frame.cancel(); |
|
this._frame = null; |
|
} |
|
this.fire(new symbol_layout.Event('webglcontextlost', { originalEvent: event })); |
|
}; |
|
Map.prototype._contextRestored = function _contextRestored(event) { |
|
this._setupPainter(); |
|
this.resize(); |
|
this._update(); |
|
this.fire(new symbol_layout.Event('webglcontextrestored', { originalEvent: event })); |
|
}; |
|
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() { |
|
this.painter.context.setDirty(); |
|
this.painter.setBaseState(); |
|
this._renderTaskQueue.run(); |
|
var crossFading = false; |
|
if (this.style && this._styleDirty) { |
|
this._styleDirty = false; |
|
var zoom = this.transform.zoom; |
|
var now = symbol_layout.browser.now(); |
|
this.style.zoomHistory.update(zoom, now); |
|
var parameters = new symbol_layout.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 |
|
}); |
|
this.fire(new symbol_layout.Event('render')); |
|
if (this.loaded() && !this._loaded) { |
|
this._loaded = true; |
|
this.fire(new symbol_layout.Event('load')); |
|
} |
|
if (this.style && (this.style.hasTransitions() || crossFading)) { |
|
this._styleDirty = true; |
|
} |
|
if (this.style && !this._placementDirty) { |
|
this.style._releaseSymbolFadeTiles(); |
|
} |
|
if (this._sourcesDirty || this._repaint || this._styleDirty || this._placementDirty) { |
|
this.triggerRepaint(); |
|
} else if (!this.isMoving() && this.loaded()) { |
|
this.fire(new symbol_layout.Event('idle')); |
|
} |
|
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.setStyle(null); |
|
if (typeof symbol_layout.window !== 'undefined') { |
|
symbol_layout.window.removeEventListener('resize', this._onWindowResize, false); |
|
symbol_layout.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.fire(new symbol_layout.Event('remove')); |
|
}; |
|
Map.prototype.triggerRepaint = function triggerRepaint() { |
|
var this$1 = this; |
|
if (this.style && !this._frame) { |
|
this._frame = symbol_layout.browser.frame(function () { |
|
this$1._frame = null; |
|
this$1._render(); |
|
}); |
|
} |
|
}; |
|
Map.prototype._onWindowOnline = function _onWindowOnline() { |
|
this._update(); |
|
}; |
|
Map.prototype._onWindowResize = function _onWindowResize() { |
|
if (this._trackResize) { |
|
this.resize()._update(); |
|
} |
|
}; |
|
prototypeAccessors.showTileBoundaries.get = function () { |
|
return !!this._showTileBoundaries; |
|
}; |
|
prototypeAccessors.showTileBoundaries.set = function (value) { |
|
if (this._showTileBoundaries === value) { |
|
return; |
|
} |
|
this._showTileBoundaries = 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) { |
|
symbol_layout.setCacheLimits(limit, checkThreshold); |
|
}; |
|
prototypeAccessors.version.get = function () { |
|
return symbol_layout.version; |
|
}; |
|
Object.defineProperties(Map.prototype, prototypeAccessors); |
|
return Map; |
|
}(Camera); |
|
function removeNode(node) { |
|
if (node.parentNode) { |
|
node.parentNode.removeChild(node); |
|
} |
|
} |
|
|
|
var defaultOptions$1 = { |
|
showCompass: true, |
|
showZoom: true, |
|
visualizePitch: false |
|
}; |
|
var NavigationControl = function NavigationControl(options) { |
|
var this$1 = this; |
|
this.options = symbol_layout.extend({}, defaultOptions$1, options); |
|
this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-group'); |
|
this._container.addEventListener('contextmenu', function (e) { |
|
return e.preventDefault(); |
|
}); |
|
if (this.options.showZoom) { |
|
symbol_layout.bindAll(['_updateZoomButtons'], this); |
|
this._zoomInButton = this._createButton('mapboxgl-ctrl-icon mapboxgl-ctrl-zoom-in', 'Zoom in', function () { |
|
return this$1._map.zoomIn(); |
|
}); |
|
this._zoomOutButton = this._createButton('mapboxgl-ctrl-icon mapboxgl-ctrl-zoom-out', 'Zoom out', function () { |
|
return this$1._map.zoomOut(); |
|
}); |
|
} |
|
if (this.options.showCompass) { |
|
symbol_layout.bindAll(['_rotateCompassArrow'], this); |
|
this._compass = this._createButton('mapboxgl-ctrl-icon mapboxgl-ctrl-compass', 'Reset bearing to north', function () { |
|
if (this$1.options.visualizePitch) { |
|
this$1._map.resetNorthPitch(); |
|
} else { |
|
this$1._map.resetNorth(); |
|
} |
|
}); |
|
this._compassArrow = DOM.create('span', 'mapboxgl-ctrl-compass-arrow', this._compass); |
|
} |
|
}; |
|
NavigationControl.prototype._updateZoomButtons = function _updateZoomButtons() { |
|
var zoom = this._map.getZoom(); |
|
if (zoom === this._map.getMaxZoom()) { |
|
this._zoomInButton.classList.add('mapboxgl-ctrl-icon-disabled'); |
|
} else { |
|
this._zoomInButton.classList.remove('mapboxgl-ctrl-icon-disabled'); |
|
} |
|
if (zoom === this._map.getMinZoom()) { |
|
this._zoomOutButton.classList.add('mapboxgl-ctrl-icon-disabled'); |
|
} else { |
|
this._zoomOutButton.classList.remove('mapboxgl-ctrl-icon-disabled'); |
|
} |
|
}; |
|
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._compassArrow.style.transform = rotate; |
|
}; |
|
NavigationControl.prototype.onAdd = function onAdd(map) { |
|
this._map = map; |
|
if (this.options.showZoom) { |
|
this._map.on('zoom', this._updateZoomButtons); |
|
this._updateZoomButtons(); |
|
} |
|
if (this.options.showCompass) { |
|
if (this.options.visualizePitch) { |
|
this._map.on('pitch', this._rotateCompassArrow); |
|
} |
|
this._map.on('rotate', this._rotateCompassArrow); |
|
this._rotateCompassArrow(); |
|
this._handler = new DragRotateHandler(map, { |
|
button: 'left', |
|
element: this._compass |
|
}); |
|
DOM.addEventListener(this._compass, 'mousedown', this._handler.onMouseDown); |
|
DOM.addEventListener(this._compass, 'touchstart', this._handler.onMouseDown, { passive: false }); |
|
this._handler.enable(); |
|
} |
|
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); |
|
DOM.removeEventListener(this._compass, 'mousedown', this._handler.onMouseDown); |
|
DOM.removeEventListener(this._compass, 'touchstart', this._handler.onMouseDown, { passive: false }); |
|
this._handler.disable(); |
|
delete this._handler; |
|
} |
|
delete this._map; |
|
}; |
|
NavigationControl.prototype._createButton = function _createButton(className, ariaLabel, fn) { |
|
var a = DOM.create('button', className, this._container); |
|
a.type = 'button'; |
|
a.title = ariaLabel; |
|
a.setAttribute('aria-label', ariaLabel); |
|
a.addEventListener('click', fn); |
|
return a; |
|
}; |
|
|
|
function smartWrap (lngLat, priorPos, transform) { |
|
lngLat = new symbol_layout.LngLat(lngLat.lng, lngLat.lat); |
|
if (priorPos) { |
|
var left = new symbol_layout.LngLat(lngLat.lng - 360, lngLat.lat); |
|
var right = new symbol_layout.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 symbol_layout.window.HTMLElement || legacyOptions) { |
|
options = symbol_layout.extend({ element: options }, legacyOptions); |
|
} |
|
symbol_layout.bindAll([ |
|
'_update', |
|
'_onMove', |
|
'_onUp', |
|
'_addDragHandler', |
|
'_onMapClick' |
|
], this); |
|
this._anchor = options && options.anchor || 'center'; |
|
this._color = options && options.color || '#3FB1CE'; |
|
this._draggable = options && options.draggable || false; |
|
this._state = 'inactive'; |
|
if (!options || !options.element) { |
|
this._defaultMarker = true; |
|
this._element = DOM.create('div'); |
|
var svg = DOM.createNS('http://www.w3.org/2000/svg', 'svg'); |
|
svg.setAttributeNS(null, 'display', 'block'); |
|
svg.setAttributeNS(null, 'height', '41px'); |
|
svg.setAttributeNS(null, 'width', '27px'); |
|
svg.setAttributeNS(null, 'viewBox', '0 0 27 41'); |
|
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); |
|
this._element.appendChild(svg); |
|
this._offset = symbol_layout.Point.convert(options && options.offset || [ |
|
0, |
|
-14 |
|
]); |
|
} else { |
|
this._element = options.element; |
|
this._offset = symbol_layout.Point.convert(options && options.offset || [ |
|
0, |
|
0 |
|
]); |
|
} |
|
this._element.classList.add('mapboxgl-marker'); |
|
this._element.addEventListener('dragstart', 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 = symbol_layout.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; |
|
} |
|
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); |
|
} |
|
} |
|
return this; |
|
}; |
|
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); |
|
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)'); |
|
}; |
|
Marker.prototype.getOffset = function getOffset() { |
|
return this._offset; |
|
}; |
|
Marker.prototype.setOffset = function setOffset(offset) { |
|
this._offset = symbol_layout.Point.convert(offset); |
|
this._update(); |
|
return this; |
|
}; |
|
Marker.prototype._onMove = function _onMove(e) { |
|
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 symbol_layout.Event('dragstart')); |
|
} |
|
this.fire(new symbol_layout.Event('drag')); |
|
}; |
|
Marker.prototype._onUp = function _onUp() { |
|
this._element.style.pointerEvents = 'auto'; |
|
this._positionDelta = null; |
|
this._map.off('mousemove', this._onMove); |
|
this._map.off('touchmove', this._onMove); |
|
if (this._state === 'active') { |
|
this.fire(new symbol_layout.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._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; |
|
}; |
|
return Marker; |
|
}(symbol_layout.Evented); |
|
|
|
var defaultOptions$2 = { |
|
positionOptions: { |
|
enableHighAccuracy: false, |
|
maximumAge: 0, |
|
timeout: 6000 |
|
}, |
|
fitBoundsOptions: { maxZoom: 15 }, |
|
trackUserLocation: false, |
|
showUserLocation: true |
|
}; |
|
var className = 'mapboxgl-ctrl'; |
|
var supportsGeolocation; |
|
function checkGeolocationSupport(callback) { |
|
if (supportsGeolocation !== undefined) { |
|
callback(supportsGeolocation); |
|
} else if (symbol_layout.window.navigator.permissions !== undefined) { |
|
symbol_layout.window.navigator.permissions.query({ name: 'geolocation' }).then(function (p) { |
|
supportsGeolocation = p.state !== 'denied'; |
|
callback(supportsGeolocation); |
|
}); |
|
} else { |
|
supportsGeolocation = !!symbol_layout.window.navigator.geolocation; |
|
callback(supportsGeolocation); |
|
} |
|
} |
|
var GeolocateControl = function (Evented) { |
|
function GeolocateControl(options) { |
|
Evented.call(this); |
|
this.options = symbol_layout.extend({}, defaultOptions$2, options); |
|
symbol_layout.bindAll([ |
|
'_onSuccess', |
|
'_onError', |
|
'_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', className + ' ' + className + '-group'); |
|
checkGeolocationSupport(this._setupUI); |
|
return this._container; |
|
}; |
|
GeolocateControl.prototype.onRemove = function onRemove() { |
|
if (this._geolocationWatchID !== undefined) { |
|
symbol_layout.window.navigator.geolocation.clearWatch(this._geolocationWatchID); |
|
this._geolocationWatchID = undefined; |
|
} |
|
if (this.options.showUserLocation && this._userLocationDotMarker) { |
|
this._userLocationDotMarker.remove(); |
|
} |
|
DOM.remove(this._container); |
|
this._map = undefined; |
|
}; |
|
GeolocateControl.prototype._onSuccess = function _onSuccess(position) { |
|
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; |
|
default: |
|
} |
|
} |
|
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 symbol_layout.Event('geolocate', position)); |
|
this._finish(); |
|
}; |
|
GeolocateControl.prototype._updateCamera = function _updateCamera(position) { |
|
var center = new symbol_layout.LngLat(position.coords.longitude, position.coords.latitude); |
|
var radius = position.coords.accuracy; |
|
var bearing = this._map.getBearing(); |
|
var options = symbol_layout.extend({ bearing: bearing }, this.options.fitBoundsOptions); |
|
this._map.fitBounds(center.toBounds(radius), options, { geolocateSource: true }); |
|
}; |
|
GeolocateControl.prototype._updateMarker = function _updateMarker(position) { |
|
if (position) { |
|
this._userLocationDotMarker.setLngLat([ |
|
position.coords.longitude, |
|
position.coords.latitude |
|
]).addTo(this._map); |
|
} else { |
|
this._userLocationDotMarker.remove(); |
|
} |
|
}; |
|
GeolocateControl.prototype._onError = function _onError(error) { |
|
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'); |
|
if (this._geolocationWatchID !== undefined) { |
|
this._clearWatch(); |
|
} |
|
} else { |
|
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; |
|
case 'ACTIVE_ERROR': |
|
break; |
|
default: |
|
} |
|
} |
|
} |
|
if (this._watchState !== 'OFF' && this.options.showUserLocation) { |
|
this._dotElement.classList.add('mapboxgl-user-location-dot-stale'); |
|
} |
|
this.fire(new symbol_layout.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; |
|
if (supported === false) { |
|
symbol_layout.warnOnce('Geolocation support is not available, the GeolocateControl will not be visible.'); |
|
return; |
|
} |
|
this._container.addEventListener('contextmenu', function (e) { |
|
return e.preventDefault(); |
|
}); |
|
this._geolocateButton = DOM.create('button', className + '-icon ' + className + '-geolocate', this._container); |
|
this._geolocateButton.type = 'button'; |
|
this._geolocateButton.setAttribute('aria-label', 'Geolocate'); |
|
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); |
|
if (this.options.trackUserLocation) { |
|
this._watchState = 'OFF'; |
|
} |
|
} |
|
this._geolocateButton.addEventListener('click', this.trigger.bind(this)); |
|
this._setup = true; |
|
if (this.options.trackUserLocation) { |
|
this._map.on('movestart', function (event) { |
|
if (!event.geolocateSource && this$1._watchState === 'ACTIVE_LOCK') { |
|
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 symbol_layout.Event('trackuserlocationend')); |
|
} |
|
}); |
|
} |
|
}; |
|
GeolocateControl.prototype.trigger = function trigger() { |
|
if (!this._setup) { |
|
symbol_layout.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 symbol_layout.Event('trackuserlocationstart')); |
|
break; |
|
case 'WAITING_ACTIVE': |
|
case 'ACTIVE_LOCK': |
|
case 'ACTIVE_ERROR': |
|
case 'BACKGROUND_ERROR': |
|
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 symbol_layout.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 symbol_layout.Event('trackuserlocationstart')); |
|
break; |
|
default: |
|
} |
|
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; |
|
case 'OFF': |
|
break; |
|
default: |
|
} |
|
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'); |
|
this._geolocationWatchID = symbol_layout.window.navigator.geolocation.watchPosition(this._onSuccess, this._onError, this.options.positionOptions); |
|
} |
|
} else { |
|
symbol_layout.window.navigator.geolocation.getCurrentPosition(this._onSuccess, this._onError, this.options.positionOptions); |
|
this._timeoutId = setTimeout(this._finish, 10000); |
|
} |
|
return true; |
|
}; |
|
GeolocateControl.prototype._clearWatch = function _clearWatch() { |
|
symbol_layout.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; |
|
}(symbol_layout.Evented); |
|
|
|
var defaultOptions$3 = { |
|
maxWidth: 100, |
|
unit: 'metric' |
|
}; |
|
var ScaleControl = function ScaleControl(options) { |
|
this.options = symbol_layout.extend({}, defaultOptions$3, options); |
|
symbol_layout.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 maxMeters = getDistance(map.unproject([ |
|
0, |
|
y |
|
]), map.unproject([ |
|
maxWidth, |
|
y |
|
])); |
|
if (options && options.unit === 'imperial') { |
|
var maxFeet = 3.2808 * maxMeters; |
|
if (maxFeet > 5280) { |
|
var maxMiles = maxFeet / 5280; |
|
setScale(container, maxWidth, maxMiles, 'mi'); |
|
} else { |
|
setScale(container, maxWidth, maxFeet, 'ft'); |
|
} |
|
} else if (options && options.unit === 'nautical') { |
|
var maxNauticals = maxMeters / 1852; |
|
setScale(container, maxWidth, maxNauticals, 'nm'); |
|
} else { |
|
setScale(container, maxWidth, maxMeters, 'm'); |
|
} |
|
} |
|
function setScale(container, maxWidth, maxDistance, unit) { |
|
var distance = getRoundNum(maxDistance); |
|
var ratio = distance / maxDistance; |
|
if (unit === 'm' && distance >= 1000) { |
|
distance = distance / 1000; |
|
unit = 'km'; |
|
} |
|
container.style.width = maxWidth * ratio + 'px'; |
|
container.innerHTML = distance + unit; |
|
} |
|
function getDistance(latlng1, latlng2) { |
|
var R = 6371000; |
|
var rad = Math.PI / 180, lat1 = latlng1.lat * rad, lat2 = latlng2.lat * rad, a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlng2.lng - latlng1.lng) * rad); |
|
var maxMeters = R * Math.acos(Math.min(a, 1)); |
|
return maxMeters; |
|
} |
|
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 symbol_layout.window.HTMLElement) { |
|
this._container = options.container; |
|
} else { |
|
symbol_layout.warnOnce('Full screen control \'container\' must be a DOM element.'); |
|
} |
|
} |
|
symbol_layout.bindAll([ |
|
'_onClickFullscreen', |
|
'_changeIcon' |
|
], this); |
|
if ('onfullscreenchange' in symbol_layout.window.document) { |
|
this._fullscreenchange = 'fullscreenchange'; |
|
} else if ('onmozfullscreenchange' in symbol_layout.window.document) { |
|
this._fullscreenchange = 'mozfullscreenchange'; |
|
} else if ('onwebkitfullscreenchange' in symbol_layout.window.document) { |
|
this._fullscreenchange = 'webkitfullscreenchange'; |
|
} else if ('onmsfullscreenchange' in symbol_layout.window.document) { |
|
this._fullscreenchange = 'MSFullscreenChange'; |
|
} |
|
this._className = 'mapboxgl-ctrl'; |
|
}; |
|
FullscreenControl.prototype.onAdd = function onAdd(map) { |
|
this._map = map; |
|
if (!this._container) { |
|
this._container = this._map.getContainer(); |
|
} |
|
this._controlContainer = DOM.create('div', this._className + ' mapboxgl-ctrl-group'); |
|
if (this._checkFullscreenSupport()) { |
|
this._setupUI(); |
|
} else { |
|
this._controlContainer.style.display = 'none'; |
|
symbol_layout.warnOnce('This device does not support fullscreen mode.'); |
|
} |
|
return this._controlContainer; |
|
}; |
|
FullscreenControl.prototype.onRemove = function onRemove() { |
|
DOM.remove(this._controlContainer); |
|
this._map = null; |
|
symbol_layout.window.document.removeEventListener(this._fullscreenchange, this._changeIcon); |
|
}; |
|
FullscreenControl.prototype._checkFullscreenSupport = function _checkFullscreenSupport() { |
|
return !!(symbol_layout.window.document.fullscreenEnabled || symbol_layout.window.document.mozFullScreenEnabled || symbol_layout.window.document.msFullscreenEnabled || symbol_layout.window.document.webkitFullscreenEnabled); |
|
}; |
|
FullscreenControl.prototype._setupUI = function _setupUI() { |
|
var button = this._fullscreenButton = DOM.create('button', this._className + '-icon ' + this._className + '-fullscreen', this._controlContainer); |
|
button.type = 'button'; |
|
this._updateTitle(); |
|
this._fullscreenButton.addEventListener('click', this._onClickFullscreen); |
|
symbol_layout.window.document.addEventListener(this._fullscreenchange, this._changeIcon); |
|
}; |
|
FullscreenControl.prototype._updateTitle = function _updateTitle() { |
|
var title = this._isFullscreen() ? 'Exit fullscreen' : 'Enter fullscreen'; |
|
this._fullscreenButton.setAttribute('aria-label', title); |
|
this._fullscreenButton.title = title; |
|
}; |
|
FullscreenControl.prototype._isFullscreen = function _isFullscreen() { |
|
return this._fullscreen; |
|
}; |
|
FullscreenControl.prototype._changeIcon = function _changeIcon() { |
|
var fullscreenElement = symbol_layout.window.document.fullscreenElement || symbol_layout.window.document.mozFullScreenElement || symbol_layout.window.document.webkitFullscreenElement || symbol_layout.window.document.msFullscreenElement; |
|
if (fullscreenElement === this._container !== this._fullscreen) { |
|
this._fullscreen = !this._fullscreen; |
|
this._fullscreenButton.classList.toggle(this._className + '-shrink'); |
|
this._fullscreenButton.classList.toggle(this._className + '-fullscreen'); |
|
this._updateTitle(); |
|
} |
|
}; |
|
FullscreenControl.prototype._onClickFullscreen = function _onClickFullscreen() { |
|
if (this._isFullscreen()) { |
|
if (symbol_layout.window.document.exitFullscreen) { |
|
symbol_layout.window.document.exitFullscreen(); |
|
} else if (symbol_layout.window.document.mozCancelFullScreen) { |
|
symbol_layout.window.document.mozCancelFullScreen(); |
|
} else if (symbol_layout.window.document.msExitFullscreen) { |
|
symbol_layout.window.document.msExitFullscreen(); |
|
} else if (symbol_layout.window.document.webkitCancelFullScreen) { |
|
symbol_layout.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$4 = { |
|
closeButton: true, |
|
closeOnClick: true, |
|
className: '', |
|
maxWidth: '240px' |
|
}; |
|
var Popup = function (Evented) { |
|
function Popup(options) { |
|
Evented.call(this); |
|
this.options = symbol_layout.extend(Object.create(defaultOptions$4), options); |
|
symbol_layout.bindAll([ |
|
'_update', |
|
'_onClickClose', |
|
'remove' |
|
], this); |
|
} |
|
if (Evented) |
|
Popup.__proto__ = Evented; |
|
Popup.prototype = Object.create(Evented && Evented.prototype); |
|
Popup.prototype.constructor = Popup; |
|
Popup.prototype.addTo = function addTo(map) { |
|
var this$1 = this; |
|
this._map = map; |
|
if (this.options.closeOnClick) { |
|
this._map.on('click', this._onClickClose); |
|
} |
|
this._map.on('remove', this.remove); |
|
this._update(); |
|
if (this._trackPointer) { |
|
this._map.on('mousemove', function (e) { |
|
this$1._update(e.point); |
|
}); |
|
this._map.on('mouseup', function (e) { |
|
this$1._update(e.point); |
|
}); |
|
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 symbol_layout.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('click', this._onClickClose); |
|
this._map.off('remove', this.remove); |
|
this._map.off('mousemove'); |
|
delete this._map; |
|
} |
|
this.fire(new symbol_layout.Event('close')); |
|
return this; |
|
}; |
|
Popup.prototype.getLngLat = function getLngLat() { |
|
return this._lngLat; |
|
}; |
|
Popup.prototype.setLngLat = function setLngLat(lnglat) { |
|
this._lngLat = symbol_layout.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._container.classList.remove('mapboxgl-popup-track-pointer'); |
|
this._map._canvasContainer.classList.remove('mapboxgl-track-pointer'); |
|
} |
|
return this; |
|
}; |
|
Popup.prototype.trackPointer = function trackPointer() { |
|
var this$1 = this; |
|
this._trackPointer = true; |
|
this._pos = null; |
|
if (this._map) { |
|
this._map.off('move', this._update); |
|
this._map.on('mousemove', function (e) { |
|
this$1._update(e.point); |
|
}); |
|
this._map.on('drag', function (e) { |
|
this$1._update(e.point); |
|
}); |
|
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(symbol_layout.window.document.createTextNode(text)); |
|
}; |
|
Popup.prototype.setHTML = function setHTML(html) { |
|
var frag = symbol_layout.window.document.createDocumentFragment(); |
|
var temp = symbol_layout.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.style.maxWidth; |
|
}; |
|
Popup.prototype.setMaxWidth = function setMaxWidth(maxWidth) { |
|
this.options.maxWidth = maxWidth; |
|
this._update(); |
|
return this; |
|
}; |
|
Popup.prototype.setDOMContent = function setDOMContent(htmlNode) { |
|
this._createContent(); |
|
this._content.appendChild(htmlNode); |
|
this._update(); |
|
return this; |
|
}; |
|
Popup.prototype._createContent = function _createContent() { |
|
if (this._content) { |
|
DOM.remove(this._content); |
|
} |
|
this._content = DOM.create('div', 'mapboxgl-popup-content', this._container); |
|
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._onClickClose); |
|
} |
|
}; |
|
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.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._onClickClose = function _onClickClose() { |
|
this.remove(); |
|
}; |
|
return Popup; |
|
}(symbol_layout.Evented); |
|
function normalizeOffset(offset) { |
|
if (!offset) { |
|
return normalizeOffset(new symbol_layout.Point(0, 0)); |
|
} else if (typeof offset === 'number') { |
|
var cornerOffset = Math.round(Math.sqrt(0.5 * Math.pow(offset, 2))); |
|
return { |
|
'center': new symbol_layout.Point(0, 0), |
|
'top': new symbol_layout.Point(0, offset), |
|
'top-left': new symbol_layout.Point(cornerOffset, cornerOffset), |
|
'top-right': new symbol_layout.Point(-cornerOffset, cornerOffset), |
|
'bottom': new symbol_layout.Point(0, -offset), |
|
'bottom-left': new symbol_layout.Point(cornerOffset, -cornerOffset), |
|
'bottom-right': new symbol_layout.Point(-cornerOffset, -cornerOffset), |
|
'left': new symbol_layout.Point(offset, 0), |
|
'right': new symbol_layout.Point(-offset, 0) |
|
}; |
|
} else if (offset instanceof symbol_layout.Point || Array.isArray(offset)) { |
|
var convertedOffset = symbol_layout.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': symbol_layout.Point.convert(offset['center'] || [ |
|
0, |
|
0 |
|
]), |
|
'top': symbol_layout.Point.convert(offset['top'] || [ |
|
0, |
|
0 |
|
]), |
|
'top-left': symbol_layout.Point.convert(offset['top-left'] || [ |
|
0, |
|
0 |
|
]), |
|
'top-right': symbol_layout.Point.convert(offset['top-right'] || [ |
|
0, |
|
0 |
|
]), |
|
'bottom': symbol_layout.Point.convert(offset['bottom'] || [ |
|
0, |
|
0 |
|
]), |
|
'bottom-left': symbol_layout.Point.convert(offset['bottom-left'] || [ |
|
0, |
|
0 |
|
]), |
|
'bottom-right': symbol_layout.Point.convert(offset['bottom-right'] || [ |
|
0, |
|
0 |
|
]), |
|
'left': symbol_layout.Point.convert(offset['left'] || [ |
|
0, |
|
0 |
|
]), |
|
'right': symbol_layout.Point.convert(offset['right'] || [ |
|
0, |
|
0 |
|
]) |
|
}; |
|
} |
|
} |
|
|
|
var exported = { |
|
version: symbol_layout.version, |
|
supported: mapboxGlSupported, |
|
setRTLTextPlugin: symbol_layout.setRTLTextPlugin, |
|
Map: Map, |
|
NavigationControl: NavigationControl, |
|
GeolocateControl: GeolocateControl, |
|
AttributionControl: AttributionControl, |
|
ScaleControl: ScaleControl, |
|
FullscreenControl: FullscreenControl, |
|
Popup: Popup, |
|
Marker: Marker, |
|
Style: Style, |
|
LngLat: symbol_layout.LngLat, |
|
LngLatBounds: symbol_layout.LngLatBounds, |
|
Point: symbol_layout.Point, |
|
MercatorCoordinate: symbol_layout.MercatorCoordinate, |
|
Evented: symbol_layout.Evented, |
|
config: symbol_layout.config, |
|
get accessToken() { |
|
return symbol_layout.config.ACCESS_TOKEN; |
|
}, |
|
set accessToken(token) { |
|
symbol_layout.config.ACCESS_TOKEN = token; |
|
}, |
|
get baseApiUrl() { |
|
return symbol_layout.config.API_URL; |
|
}, |
|
set baseApiUrl(url) { |
|
symbol_layout.config.API_URL = url; |
|
}, |
|
get workerCount() { |
|
return WorkerPool.workerCount; |
|
}, |
|
set workerCount(count) { |
|
WorkerPool.workerCount = count; |
|
}, |
|
get maxParallelImageRequests() { |
|
return symbol_layout.config.MAX_PARALLEL_IMAGE_REQUESTS; |
|
}, |
|
set maxParallelImageRequests(numRequests) { |
|
symbol_layout.config.MAX_PARALLEL_IMAGE_REQUESTS = numRequests; |
|
}, |
|
clearStorage: function clearStorage(callback) { |
|
symbol_layout.clearTileCache(callback); |
|
}, |
|
workerUrl: '' |
|
}; |
|
|
|
return exported; |
|
|
|
}); |
|
|
|
// |
|
|
|
return mapboxgl; |
|
|
|
})); |
|
//# sourceMappingURL=mapbox-gl-unminified.js.map
|