From 0de0f973b78fa1d5e8202d1a3e14f7b535fe82e6 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Mon, 14 Aug 2017 14:04:06 +0530 Subject: [PATCH 1/2] fix outdated code --- .gitignore | 2 + dist/mapbox-gl-topojson.js | 12092 -------------- dist/mapbox-gl.js | 29518 ----------------------------------- index.html | 8 +- mapbox-gl.js | 1 - package-lock.json | 1573 ++ package.json | 6 +- topojson_source.js | 14 +- topojson_worker.js | 31 +- 9 files changed, 1597 insertions(+), 41648 deletions(-) create mode 100644 .gitignore delete mode 100644 dist/mapbox-gl-topojson.js delete mode 100644 dist/mapbox-gl.js delete mode 100644 mapbox-gl.js create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76add87 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist \ No newline at end of file diff --git a/dist/mapbox-gl-topojson.js b/dist/mapbox-gl-topojson.js deleted file mode 100644 index 295f3a1..0000000 --- a/dist/mapbox-gl-topojson.js +++ /dev/null @@ -1,12092 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.mapboxgl || (g.mapboxgl = {})).TopoJSONSource = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -// when used in node, this will actually load the util module we depend on -// versus loading the builtin util module as happens otherwise -// this is a bug in node module loading as far as I am concerned -var util = require('util/'); - -var pSlice = Array.prototype.slice; -var hasOwn = Object.prototype.hasOwnProperty; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } - else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = stackStartFunction.name; - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (util.isUndefined(value)) { - return '' + value; - } - if (util.isNumber(value) && !isFinite(value)) { - return value.toString(); - } - if (util.isFunction(value) || util.isRegExp(value)) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (util.isString(s)) { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -function getMessage(self) { - return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + - self.operator + ' ' + - truncate(JSON.stringify(self.expected, replacer), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (util.isBuffer(actual) && util.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!util.isObject(actual) && !util.isObject(expected)) { - return actual == expected; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) { - return a === b; - } - var aIsArgs = isArguments(a), - bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - var ka = objectKeys(a), - kb = objectKeys(b), - key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (util.isString(expected)) { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -},{"util/":5}],2:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],3:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -(function () { - try { - cachedSetTimeout = setTimeout; - } catch (e) { - cachedSetTimeout = function () { - throw new Error('setTimeout is not defined'); - } - } - try { - cachedClearTimeout = clearTimeout; - } catch (e) { - cachedClearTimeout = function () { - throw new Error('clearTimeout is not defined'); - } - } -} ()) -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = cachedSetTimeout.call(null, cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - cachedClearTimeout.call(null, timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - cachedSetTimeout.call(null, drainQueue, 0); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],4:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],5:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(require,module,exports){ -'use strict'; - -module.exports = 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) return triangles; - - var minX, minY, maxX, maxY, x, y, size; - - if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); - - // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - 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; - } - - // minX, minY and size are later used to transform coords into integers for z-order calculation - size = Math.max(maxX - minX, maxY - minY); - } - - earcutLinked(outerNode, triangles, dim, minX, minY, size); - - return triangles; -} - -// create a circular doubly linked list from polygon points in the specified winding order -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; -} - -// eliminate colinear or duplicate points -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) return null; - again = true; - - } else { - p = p.next; - } - } while (again || p !== end); - - return end; -} - -// main ear slicing loop which triangulates a polygon (given as a linked list) -function earcutLinked(ear, triangles, dim, minX, minY, size, pass) { - if (!ear) return; - - // interlink polygon nodes in z-order - if (!pass && size) indexCurve(ear, minX, minY, size); - - var stop = ear, - prev, next; - - // iterate through ears, slicing them one by one - while (ear.prev !== ear.next) { - prev = ear.prev; - next = ear.next; - - if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) { - // cut off the triangle - triangles.push(prev.i / dim); - triangles.push(ear.i / dim); - triangles.push(next.i / dim); - - removeNode(ear); - - // skipping the next vertice leads to less sliver triangles - ear = next.next; - stop = next.next; - - continue; - } - - ear = next; - - // if we looped through the whole remaining polygon and can't find any more ears - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1); - - // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(ear, triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, size, 2); - - // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, size); - } - - break; - } - } -} - -// check whether a polygon node forms a valid ear with adjacent nodes -function isEar(ear) { - var a = ear.prev, - b = ear, - c = ear.next; - - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - - // now make sure we don't have other points inside the potential ear - 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, size) { - var a = ear.prev, - b = ear, - c = ear.next; - - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - - // triangle bbox; min & max are calculated like this for speed - 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); - - // z-order range for the current triangle bbox; - var minZ = zOrder(minTX, minTY, minX, minY, size), - maxZ = zOrder(maxTX, maxTY, minX, minY, size); - - // first look for points inside the triangle in increasing z-order - var p = ear.nextZ; - - while (p && p.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.nextZ; - } - - // then look for points in decreasing z-order - p = ear.prevZ; - - 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; - } - - return true; -} - -// go through all polygon nodes and cure small local self-intersections -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); - - // remove two nodes involved - removeNode(p); - removeNode(p.next); - - p = start = b; - } - p = p.next; - } while (p !== start); - - return p; -} - -// try splitting polygon into two and triangulate them independently -function splitEarcut(start, triangles, dim, minX, minY, size) { - // look for a valid diagonal that divides the polygon into two - var a = start; - do { - var b = a.next.next; - while (b !== a.prev) { - if (a.i !== b.i && isValidDiagonal(a, b)) { - // split the polygon in two by the diagonal - var c = splitPolygon(a, b); - - // filter colinear points around the cuts - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); - - // run earcut on each half - earcutLinked(a, triangles, dim, minX, minY, size); - earcutLinked(c, triangles, dim, minX, minY, size); - return; - } - b = b.next; - } - a = a.next; - } while (a !== start); -} - -// link every hole into the outer loop, producing a single-ring polygon without holes -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); - - // process holes from left to right - 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; -} - -// find a bridge between vertices that connects hole with an outer ring and and link it -function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - if (outerNode) { - var b = splitPolygon(outerNode, hole); - filterPoints(b, b.next); - } -} - -// David Eberly's algorithm for finding a bridge between hole and outer polygon -function findHoleBridge(hole, outerNode) { - var p = outerNode, - hx = hole.x, - hy = hole.y, - qx = -Infinity, - m; - - // find a segment intersected by a ray from the hole's leftmost point to the left; - // segment's endpoint with lesser x will be potential connection point - do { - if (hy <= p.y && hy >= p.next.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.prev; // hole touches outer segment; pick lower endpoint - - // look for points inside the triangle of hole point, segment intersection and endpoint; - // if there are no points found, we have a valid connection; - // otherwise choose the point of the minimum angle with the ray as connection point - - var stop = m, - mx = m.x, - my = m.y, - tanMin = Infinity, - tan; - - p = m.next; - - while (p !== stop) { - if (hx >= p.x && p.x >= mx && - 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); // tangential - - if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { - m = p; - tanMin = tan; - } - } - - p = p.next; - } - - return m; -} - -// interlink polygon nodes in z-order -function indexCurve(start, minX, minY, size) { - var p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); - - p.prevZ.nextZ = null; - p.prevZ = null; - - sortLinked(p); -} - -// Simon Tatham's linked list merge sort algorithm -// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html -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) { - e = q; - q = q.nextZ; - qSize--; - } else if (qSize === 0 || !q) { - e = p; - p = p.nextZ; - pSize--; - } else if (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; -} - -// z-order of a point given coords and size of the data bounding box -function zOrder(x, y, minX, minY, size) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) / size; - y = 32767 * (y - minY) / size; - - x = (x | (x << 8)) & 0x00FF00FF; - x = (x | (x << 4)) & 0x0F0F0F0F; - x = (x | (x << 2)) & 0x33333333; - x = (x | (x << 1)) & 0x55555555; - - y = (y | (y << 8)) & 0x00FF00FF; - y = (y | (y << 4)) & 0x0F0F0F0F; - y = (y | (y << 2)) & 0x33333333; - y = (y | (y << 1)) & 0x55555555; - - return x | (y << 1); -} - -// find the leftmost node of a polygon ring -function getLeftmost(start) { - var p = start, - leftmost = start; - do { - if (p.x < leftmost.x) leftmost = p; - p = p.next; - } while (p !== start); - - return leftmost; -} - -// check if a point lies within a convex triangle -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; -} - -// check if a diagonal between two polygon nodes is valid (lies in polygon interior) -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); -} - -// signed area of a triangle -function area(p, q, r) { - return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); -} - -// check if two points are equal -function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; -} - -// check if two segments intersect -function intersects(p1, q1, p2, q2) { - if ((equals(p1, q1) && equals(p2, q2)) || - (equals(p1, q2) && equals(p2, q1))) return true; - return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && - area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; -} - -// check if a polygon diagonal intersects any polygon segments -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; -} - -// check if a polygon diagonal is locally inside the polygon -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; -} - -// check if the middle point of a polygon diagonal is inside the polygon -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)) && (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; -} - -// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; -// if one belongs to the outer ring and another to a hole, it merges it into a single ring -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; -} - -// create a node and optionally link it with previous one (in a circular doubly linked list) -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) { - // vertice index in coordinates array - this.i = i; - - // vertex coordinates - this.x = x; - this.y = y; - - // previous and next vertice nodes in a polygon ring - this.prev = null; - this.next = null; - - // z-order curve value - this.z = null; - - // previous and next nodes in z-order - this.prevZ = null; - this.nextZ = null; - - // indicates whether this is a steiner point - this.steiner = false; -} - -// return a percentage difference between the polygon area and its triangulation area; -// used to verify correctness of triangulation -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; -} - -// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts -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; -}; - -},{}],7:[function(require,module,exports){ -'use strict'; - -module.exports = createFilter; - -var types = ['Unknown', 'Point', 'LineString', 'Polygon']; - -/** - * Given a filter expressed as nested arrays, return a new function - * that evaluates whether a given feature (with a .properties or .tags property) - * passes its test. - * - * @param {Array} filter mapbox gl filter - * @returns {Function} filter-evaluating function - */ -function createFilter(filter) { - return new Function('f', 'var p = (f && f.properties || {}); return ' + compile(filter)); -} - -function compile(filter) { - if (!filter) return 'true'; - var op = filter[0]; - if (filter.length <= 1) return op === 'any' ? 'false' : 'true'; - var str = - op === '==' ? compileComparisonOp(filter[1], filter[2], '===', false) : - op === '!=' ? compileComparisonOp(filter[1], filter[2], '!==', false) : - op === '<' || - op === '>' || - op === '<=' || - op === '>=' ? compileComparisonOp(filter[1], filter[2], op, true) : - op === 'any' ? compileLogicalOp(filter.slice(1), '||') : - op === 'all' ? compileLogicalOp(filter.slice(1), '&&') : - op === 'none' ? compileNegation(compileLogicalOp(filter.slice(1), '||')) : - op === 'in' ? compileInOp(filter[1], filter.slice(2)) : - op === '!in' ? compileNegation(compileInOp(filter[1], filter.slice(2))) : - op === 'has' ? compileHasOp(filter[1]) : - op === '!has' ? compileNegation(compileHasOp([filter[1]])) : - 'true'; - return '(' + str + ')'; -} - -function compilePropertyReference(property) { - return property === '$type' ? 'f.type' : - property === '$id' ? 'f.id' : - 'p[' + JSON.stringify(property) + ']'; -} - -function compileComparisonOp(property, value, op, checkType) { - var left = compilePropertyReference(property); - var right = property === '$type' ? types.indexOf(value) : JSON.stringify(value); - return (checkType ? 'typeof ' + left + '=== typeof ' + right + '&&' : '') + left + op + right; -} - -function compileLogicalOp(expressions, op) { - return expressions.map(compile).join(op); -} - -function compileInOp(property, values) { - if (property === '$type') values = values.map(function(value) { return types.indexOf(value); }); - var left = JSON.stringify(values.sort(compare)); - var right = compilePropertyReference(property); - - if (values.length <= 200) return left + '.indexOf(' + right + ') !== -1'; - - return 'function(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; }(' + right + ', ' + left + ',0,' + (values.length - 1) + ')'; -} - -function compileHasOp(property) { - return JSON.stringify(property) + ' in p'; -} - -function compileNegation(expression) { - return '!(' + expression + ')'; -} - -// Comparison function to sort numbers and strings -function compare(a, b) { - return a < b ? -1 : a > b ? 1 : 0; -} - -},{}],8:[function(require,module,exports){ -var wgs84 = require('wgs84'); - -module.exports.geometry = geometry; -module.exports.ring = ringArea; - -function geometry(_) { - if (_.type === 'Polygon') return polygonArea(_.coordinates); - else if (_.type === 'MultiPolygon') { - var area = 0; - for (var i = 0; i < _.coordinates.length; i++) { - area += polygonArea(_.coordinates[i]); - } - return area; - } else { - return null; - } -} - -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; -} - -/** - * Calculate the approximate area of the polygon were it projected onto - * the earth. Note that this area will be positive if ring is oriented - * clockwise, otherwise it will be negative. - * - * Reference: - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409 - * - * Returns: - * {float} The approximate signed geodesic area of the polygon in square - * meters. - */ - -function ringArea(coords) { - var area = 0; - - if (coords.length > 2) { - var p1, p2; - for (var i = 0; i < coords.length - 1; i++) { - p1 = coords[i]; - p2 = coords[i + 1]; - area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1]))); - } - - area = area * wgs84.RADIUS * wgs84.RADIUS / 2; - } - - return area; -} - -function rad(_) { - return _ * Math.PI / 180; -} - -},{"wgs84":80}],9:[function(require,module,exports){ -var geojsonArea = require('geojson-area'); - -module.exports = rewind; - -function rewind(gj, outer) { - switch ((gj && gj.type) || null) { - case 'FeatureCollection': - gj.features = gj.features.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; -} - -},{"geojson-area":8}],10:[function(require,module,exports){ -'use strict'; - -module.exports = clip; - -var createFeature = require('./feature'); - -/* clip features between two axis-parallel lines: - * | | - * ___|___ | / - * / | \____|____/ - * | | - */ - -function clip(features, scale, k1, k2, axis, intersect, minAll, maxAll) { - - k1 /= scale; - k2 /= scale; - - if (minAll >= k1 && maxAll <= k2) return features; // trivial accept - else if (minAll > k2 || maxAll < k1) return null; // trivial reject - - var clipped = []; - - for (var i = 0; i < features.length; i++) { - - var feature = features[i], - geometry = feature.geometry, - type = feature.type, - min, max; - - min = feature.min[axis]; - max = feature.max[axis]; - - if (min >= k1 && max <= k2) { // trivial accept - clipped.push(feature); - continue; - } else if (min > k2 || max < k1) continue; // trivial reject - - var slices = type === 1 ? - clipPoints(geometry, k1, k2, axis) : - clipGeometry(geometry, k1, k2, axis, intersect, type === 3); - - if (slices.length) { - // if a feature got clipped, it will likely get clipped on the next zoom level as well, - // so there's no need to recalculate bboxes - clipped.push(createFeature(feature.tags, type, slices, feature.id)); - } - } - - return clipped.length ? clipped : null; -} - -function clipPoints(geometry, k1, k2, axis) { - var slice = []; - - for (var i = 0; i < geometry.length; i++) { - var a = geometry[i], - ak = a[axis]; - - if (ak >= k1 && ak <= k2) slice.push(a); - } - return slice; -} - -function clipGeometry(geometry, k1, k2, axis, intersect, closed) { - - var slices = []; - - for (var i = 0; i < geometry.length; i++) { - - var ak = 0, - bk = 0, - b = null, - points = geometry[i], - area = points.area, - dist = points.dist, - outer = points.outer, - len = points.length, - a, j, last; - - var slice = []; - - for (j = 0; j < len - 1; j++) { - a = b || points[j]; - b = points[j + 1]; - ak = bk || a[axis]; - bk = b[axis]; - - if (ak < k1) { - - if ((bk > k2)) { // ---|-----|--> - slice.push(intersect(a, b, k1), intersect(a, b, k2)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk >= k1) slice.push(intersect(a, b, k1)); // ---|--> | - - } else if (ak > k2) { - - if ((bk < k1)) { // <--|-----|--- - slice.push(intersect(a, b, k2), intersect(a, b, k1)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk <= k2) slice.push(intersect(a, b, k2)); // | <--|--- - - } else { - - slice.push(a); - - if (bk < k1) { // <--|--- | - slice.push(intersect(a, b, k1)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk > k2) { // | ---|--> - slice.push(intersect(a, b, k2)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - } - // | --> | - } - } - - // add the last point - a = points[len - 1]; - ak = a[axis]; - if (ak >= k1 && ak <= k2) slice.push(a); - - // close the polygon if its endpoints are not the same after clipping - - last = slice[slice.length - 1]; - if (closed && last && (slice[0][0] !== last[0] || slice[0][1] !== last[1])) slice.push(slice[0]); - - // add the final slice - newSlice(slices, slice, area, dist, outer); - } - - return slices; -} - -function newSlice(slices, slice, area, dist, outer) { - if (slice.length) { - // we don't recalculate the area/length of the unclipped geometry because the case where it goes - // below the visibility threshold as a result of clipping is rare, so we avoid doing unnecessary work - slice.area = area; - slice.dist = dist; - if (outer !== undefined) slice.outer = outer; - - slices.push(slice); - } - return []; -} - -},{"./feature":12}],11:[function(require,module,exports){ -'use strict'; - -module.exports = convert; - -var simplify = require('./simplify'); -var createFeature = require('./feature'); - -// converts GeoJSON feature into an intermediate projected JSON vector format with simplification data - -function convert(data, tolerance) { - var features = []; - - if (data.type === 'FeatureCollection') { - for (var i = 0; i < data.features.length; i++) { - convertFeature(features, data.features[i], tolerance); - } - } else if (data.type === 'Feature') { - convertFeature(features, data, tolerance); - - } else { - // single geometry or a geometry collection - convertFeature(features, {geometry: data}, tolerance); - } - return features; -} - -function convertFeature(features, feature, tolerance) { - if (feature.geometry === null) { - // ignore features with null geometry - return; - } - - var geom = feature.geometry, - type = geom.type, - coords = geom.coordinates, - tags = feature.properties, - id = feature.id, - i, j, rings, projectedRing; - - if (type === 'Point') { - features.push(createFeature(tags, 1, [projectPoint(coords)], id)); - - } else if (type === 'MultiPoint') { - features.push(createFeature(tags, 1, project(coords), id)); - - } else if (type === 'LineString') { - features.push(createFeature(tags, 2, [project(coords, tolerance)], id)); - - } else if (type === 'MultiLineString' || type === 'Polygon') { - rings = []; - for (i = 0; i < coords.length; i++) { - projectedRing = project(coords[i], tolerance); - if (type === 'Polygon') projectedRing.outer = (i === 0); - rings.push(projectedRing); - } - features.push(createFeature(tags, type === 'Polygon' ? 3 : 2, rings, id)); - - } else if (type === 'MultiPolygon') { - rings = []; - for (i = 0; i < coords.length; i++) { - for (j = 0; j < coords[i].length; j++) { - projectedRing = project(coords[i][j], tolerance); - projectedRing.outer = (j === 0); - rings.push(projectedRing); - } - } - features.push(createFeature(tags, 3, rings, id)); - - } else if (type === 'GeometryCollection') { - for (i = 0; i < geom.geometries.length; i++) { - convertFeature(features, { - geometry: geom.geometries[i], - properties: tags - }, tolerance); - } - - } else { - throw new Error('Input data is not a valid GeoJSON object.'); - } -} - -function project(lonlats, tolerance) { - var projected = []; - for (var i = 0; i < lonlats.length; i++) { - projected.push(projectPoint(lonlats[i])); - } - if (tolerance) { - simplify(projected, tolerance); - calcSize(projected); - } - return projected; -} - -function projectPoint(p) { - var sin = Math.sin(p[1] * Math.PI / 180), - x = (p[0] / 360 + 0.5), - y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI); - - y = y < 0 ? 0 : - y > 1 ? 1 : y; - - return [x, y, 0]; -} - -// calculate area and length of the poly -function calcSize(points) { - var area = 0, - dist = 0; - - for (var i = 0, a, b; i < points.length - 1; i++) { - a = b || points[i]; - b = points[i + 1]; - - area += a[0] * b[1] - b[0] * a[1]; - - // use Manhattan distance instead of Euclidian one to avoid expensive square root computation - dist += Math.abs(b[0] - a[0]) + Math.abs(b[1] - a[1]); - } - points.area = Math.abs(area / 2); - points.dist = dist; -} - -},{"./feature":12,"./simplify":14}],12:[function(require,module,exports){ -'use strict'; - -module.exports = createFeature; - -function createFeature(tags, type, geom, id) { - var feature = { - id: id || null, - type: type, - geometry: geom, - tags: tags || null, - min: [Infinity, Infinity], // initial bbox values - max: [-Infinity, -Infinity] - }; - calcBBox(feature); - return feature; -} - -// calculate the feature bounding box for faster clipping later -function calcBBox(feature) { - var geometry = feature.geometry, - min = feature.min, - max = feature.max; - - if (feature.type === 1) { - calcRingBBox(min, max, geometry); - } else { - for (var i = 0; i < geometry.length; i++) { - calcRingBBox(min, max, geometry[i]); - } - } - - return feature; -} - -function calcRingBBox(min, max, points) { - for (var i = 0, p; i < points.length; i++) { - p = points[i]; - min[0] = Math.min(p[0], min[0]); - max[0] = Math.max(p[0], max[0]); - min[1] = Math.min(p[1], min[1]); - max[1] = Math.max(p[1], max[1]); - } -} - -},{}],13:[function(require,module,exports){ -'use strict'; - -module.exports = geojsonvt; - -var convert = require('./convert'), // GeoJSON conversion and preprocessing - transform = require('./transform'), // coordinate transformation - clip = require('./clip'), // stripe clipping algorithm - wrap = require('./wrap'), // date line processing - createTile = require('./tile'); // final simplified tile generation - - -function geojsonvt(data, options) { - return new GeoJSONVT(data, options); -} - -function GeoJSONVT(data, options) { - options = this.options = extend(Object.create(this.options), options); - - var debug = options.debug; - - if (debug) console.time('preprocess data'); - - var z2 = 1 << options.maxZoom, // 2^z - features = convert(data, options.tolerance / (z2 * options.extent)); - - 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.buffer / options.extent, intersectX); - - // start slicing from the top tile down - 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, // max zoom to preserve detail on - indexMaxZoom: 5, // max zoom in the tile index - indexMaxPoints: 100000, // max number of points per tile in the tile index - solidChildren: false, // whether to tile solid square tiles further - tolerance: 3, // simplification tolerance (higher means simpler) - extent: 4096, // tile extent - buffer: 64, // tile buffer on each side - debug: 0 // logging level (0, 1 or 2) -}; - -GeoJSONVT.prototype.splitTile = function (features, z, x, y, cz, cx, cy) { - - var stack = [features, z, x, y], - options = this.options, - debug = options.debug, - solid = null; - - // avoid recursion by using a processing queue - 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], - tileTolerance = z === options.maxZoom ? 0 : options.tolerance / (z2 * options.extent); - - if (!tile) { - if (debug > 1) console.time('creation'); - - tile = this.tiles[id] = createTile(features, z2, x, y, tileTolerance, z === options.maxZoom); - 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++; - } - } - - // save reference to original geometry in tile so that we can drill down later if we stop now - tile.source = features; - - // if it's the first-pass tiling - if (!cz) { - // stop tiling if we reached max zoom, or if the tile is too simple - if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints) continue; - - // if a drilldown to a specific tile - } else { - // stop tiling if we reached base zoom or our target tile zoom - if (z === options.maxZoom || z === cz) continue; - - // stop tiling if it's not an ancestor of the target tile - var m = 1 << (cz - z); - if (x !== Math.floor(cx / m) || y !== Math.floor(cy / m)) continue; - } - - // stop tiling if the tile is solid clipped square - if (!options.solidChildren && isClippedSquare(tile, options.extent, options.buffer)) { - if (cz) solid = z; // and remember the zoom if we're drilling down - continue; - } - - // if we slice further down, no need to keep source geometry - tile.source = null; - - if (debug > 1) console.time('clipping'); - - // values we'll use for 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, intersectX, tile.min[0], tile.max[0]); - right = clip(features, z2, x + k2, x + k4, 0, intersectX, tile.min[0], tile.max[0]); - - if (left) { - tl = clip(left, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]); - bl = clip(left, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]); - } - - if (right) { - tr = clip(right, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]); - br = clip(right, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]); - } - - if (debug > 1) console.timeEnd('clipping'); - - if (features.length) { - 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); - } - } - - return solid; -}; - -GeoJSONVT.prototype.getTile = function (z, x, y) { - var options = this.options, - extent = options.extent, - debug = options.debug; - - var z2 = 1 << z; - x = ((x % z2) + z2) % z2; // wrap tile x coordinate - - var id = toID(z, x, y); - if (this.tiles[id]) return transform.tile(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 we found a parent tile containing the original geometry, we can drill down from it - if (debug > 1) console.log('found parent tile z%d-%d-%d', z0, x0, y0); - - // it parent tile is a solid clipped square, return it instead since it's identical - if (isClippedSquare(parent, extent, options.buffer)) return transform.tile(parent, extent); - - if (debug > 1) console.time('drilling down'); - var solid = this.splitTile(parent.source, z0, x0, y0, z, x, y); - if (debug > 1) console.timeEnd('drilling down'); - - // one of the parent tiles was a solid clipped square - if (solid !== null) { - var m = 1 << (z - solid); - id = toID(solid, Math.floor(x / m), Math.floor(y / m)); - } - - return this.tiles[id] ? transform.tile(this.tiles[id], extent) : null; -}; - -function toID(z, x, y) { - return (((1 << z) * y + x) * 32) + z; -} - -function intersectX(a, b, x) { - return [x, (x - a[0]) * (b[1] - a[1]) / (b[0] - a[0]) + a[1], 1]; -} -function intersectY(a, b, y) { - return [(y - a[1]) * (b[0] - a[0]) / (b[1] - a[1]) + a[0], y, 1]; -} - -function extend(dest, src) { - for (var i in src) dest[i] = src[i]; - return dest; -} - -// checks whether a tile is a whole-area fill after clipping; if it is, there's no sense slicing it further -function isClippedSquare(tile, extent, buffer) { - - var features = tile.source; - if (features.length !== 1) return false; - - var feature = features[0]; - if (feature.type !== 3 || feature.geometry.length > 1) return false; - - var len = feature.geometry[0].length; - if (len !== 5) return false; - - for (var i = 0; i < len; i++) { - var p = transform.point(feature.geometry[0][i], extent, tile.z2, tile.x, tile.y); - if ((p[0] !== -buffer && p[0] !== extent + buffer) || - (p[1] !== -buffer && p[1] !== extent + buffer)) return false; - } - - return true; -} - -},{"./clip":10,"./convert":11,"./tile":15,"./transform":16,"./wrap":17}],14:[function(require,module,exports){ -'use strict'; - -module.exports = simplify; - -// calculate simplification data using optimized Douglas-Peucker algorithm - -function simplify(points, tolerance) { - - var sqTolerance = tolerance * tolerance, - len = points.length, - first = 0, - last = len - 1, - stack = [], - i, maxSqDist, sqDist, index; - - // always retain the endpoints (1 is the max value) - points[first][2] = 1; - points[last][2] = 1; - - // avoid recursion by using a stack - while (last) { - - maxSqDist = 0; - - for (i = first + 1; i < last; i++) { - sqDist = getSqSegDist(points[i], points[first], points[last]); - - if (sqDist > maxSqDist) { - index = i; - maxSqDist = sqDist; - } - } - - if (maxSqDist > sqTolerance) { - points[index][2] = maxSqDist; // save the point importance in squared pixels as a z coordinate - stack.push(first); - stack.push(index); - first = index; - - } else { - last = stack.pop(); - first = stack.pop(); - } - } -} - -// square distance from a point to a segment -function getSqSegDist(p, a, b) { - - var x = a[0], y = a[1], - bx = b[0], by = b[1], - px = p[0], py = p[1], - dx = bx - x, - 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; -} - -},{}],15:[function(require,module,exports){ -'use strict'; - -module.exports = createTile; - -function createTile(features, z2, tx, ty, tolerance, noSimplify) { - var tile = { - features: [], - numPoints: 0, - numSimplified: 0, - numFeatures: 0, - source: null, - x: tx, - y: ty, - z2: z2, - transformed: false, - min: [2, 1], - max: [-1, 0] - }; - for (var i = 0; i < features.length; i++) { - tile.numFeatures++; - addFeature(tile, features[i], tolerance, noSimplify); - - var min = features[i].min, - max = features[i].max; - - if (min[0] < tile.min[0]) tile.min[0] = min[0]; - if (min[1] < tile.min[1]) tile.min[1] = min[1]; - if (max[0] > tile.max[0]) tile.max[0] = max[0]; - if (max[1] > tile.max[1]) tile.max[1] = max[1]; - } - return tile; -} - -function addFeature(tile, feature, tolerance, noSimplify) { - - var geom = feature.geometry, - type = feature.type, - simplified = [], - sqTolerance = tolerance * tolerance, - i, j, ring, p; - - if (type === 1) { - for (i = 0; i < geom.length; i++) { - simplified.push(geom[i]); - tile.numPoints++; - tile.numSimplified++; - } - - } else { - - // simplify and transform projected coordinates for tile geometry - for (i = 0; i < geom.length; i++) { - ring = geom[i]; - - // filter out tiny polylines & polygons - if (!noSimplify && ((type === 2 && ring.dist < tolerance) || - (type === 3 && ring.area < sqTolerance))) { - tile.numPoints += ring.length; - continue; - } - - var simplifiedRing = []; - - for (j = 0; j < ring.length; j++) { - p = ring[j]; - // keep points with importance > tolerance - if (noSimplify || p[2] > sqTolerance) { - simplifiedRing.push(p); - tile.numSimplified++; - } - tile.numPoints++; - } - - if (type === 3) rewind(simplifiedRing, ring.outer); - - simplified.push(simplifiedRing); - } - } - - if (simplified.length) { - var tileFeature = { - geometry: simplified, - type: type, - tags: feature.tags || null - }; - if (feature.id !== null) { - tileFeature.id = feature.id; - } - tile.features.push(tileFeature); - } -} - -function rewind(ring, clockwise) { - var area = signedArea(ring); - if (area < 0 === clockwise) ring.reverse(); -} - -function signedArea(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[0] - p1[0]) * (p1[1] + p2[1]); - } - return sum; -} - -},{}],16:[function(require,module,exports){ -'use strict'; - -exports.tile = transformTile; -exports.point = transformPoint; - -// Transforms the coordinates of each feature in the given tile from -// mercator-projected space into (extent x extent) tile space. -function transformTile(tile, extent) { - if (tile.transformed) return tile; - - var z2 = tile.z2, - 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; - - if (type === 1) { - for (j = 0; j < geom.length; j++) geom[j] = transformPoint(geom[j], extent, z2, tx, ty); - - } else { - for (j = 0; j < geom.length; j++) { - var ring = geom[j]; - for (k = 0; k < ring.length; k++) ring[k] = transformPoint(ring[k], extent, z2, tx, ty); - } - } - } - - tile.transformed = true; - - return tile; -} - -function transformPoint(p, extent, z2, tx, ty) { - var x = Math.round(extent * (p[0] * z2 - tx)), - y = Math.round(extent * (p[1] * z2 - ty)); - return [x, y]; -} - -},{}],17:[function(require,module,exports){ -'use strict'; - -var clip = require('./clip'); -var createFeature = require('./feature'); - -module.exports = wrap; - -function wrap(features, buffer, intersectX) { - var merged = features, - left = clip(features, 1, -1 - buffer, buffer, 0, intersectX, -1, 2), // left world copy - right = clip(features, 1, 1 - buffer, 2 + buffer, 0, intersectX, -1, 2); // right world copy - - if (left || right) { - merged = clip(features, 1, -buffer, 1 + buffer, 0, intersectX, -1, 2) || []; // center world copy - - if (left) merged = shiftFeatureCoords(left, 1).concat(merged); // merge left into center - if (right) merged = merged.concat(shiftFeatureCoords(right, -1)); // merge right into center - } - - 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 === 1) { - newGeometry = shiftCoords(feature.geometry, offset); - } else { - newGeometry = []; - for (var j = 0; j < feature.geometry.length; j++) { - newGeometry.push(shiftCoords(feature.geometry[j], offset)); - } - } - - newFeatures.push(createFeature(feature.tags, type, newGeometry, feature.id)); - } - - return newFeatures; -} - -function shiftCoords(points, offset) { - var newPoints = []; - newPoints.area = points.area; - newPoints.dist = points.dist; - - for (var i = 0; i < points.length; i++) { - newPoints.push([points[i][0] + offset, points[i][1], points[i][2]]); - } - return newPoints; -} - -},{"./clip":10,"./feature":12}],18:[function(require,module,exports){ -'use strict'; - -module.exports = 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) { - var min = this.min; - var max = this.max; - if (x1 <= min && y1 <= min && max <= x2 && max <= y2) { - // We use `Array#slice` because `this.keys` may be a `Int32Array` and - // some browsers (Safari and IE) do not support `TypedArray#slice` - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice#Browser_compatibility - return Array.prototype.slice.call(this.keys); - - } else { - var result = []; - var seenUids = {}; - this._forEachCell(x1, y1, x2, y2, this._queryCell, result, seenUids); - return result; - } -}; - -GridIndex.prototype._queryCell = function(x1, y1, x2, y2, cellIndex, result, seenUids) { - 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 ((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) { - 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 (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2)) return; - } - } -}; - -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; -}; - -},{}],19:[function(require,module,exports){ -exports.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) -} - -exports.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 & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],20:[function(require,module,exports){ -'use strict'; - -var sort = require('./sort'); -var range = require('./range'); -var within = require('./within'); - -module.exports = kdbush; - -function kdbush(points, getX, getY, nodeSize, ArrayType) { - return new KDBush(points, getX, getY, nodeSize, ArrayType); -} - -function KDBush(points, getX, getY, nodeSize, ArrayType) { - getX = getX || defaultGetX; - getY = getY || defaultGetY; - ArrayType = ArrayType || Array; - - this.nodeSize = nodeSize || 64; - this.points = points; - - this.ids = new ArrayType(points.length); - this.coords = new ArrayType(points.length * 2); - - for (var i = 0; i < points.length; i++) { - this.ids[i] = i; - this.coords[2 * i] = getX(points[i]); - this.coords[2 * i + 1] = getY(points[i]); - } - - sort(this.ids, this.coords, this.nodeSize, 0, this.ids.length - 1, 0); -} - -KDBush.prototype = { - range: function (minX, minY, maxX, maxY) { - return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize); - }, - - within: function (x, y, r) { - return within(this.ids, this.coords, x, y, r, this.nodeSize); - } -}; - -function defaultGetX(p) { return p[0]; } -function defaultGetY(p) { return p[1]; } - -},{"./range":21,"./sort":22,"./within":23}],21:[function(require,module,exports){ -'use strict'; - -module.exports = range; - -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; -} - -},{}],22:[function(require,module,exports){ -'use strict'; - -module.exports = sortKD; - -function sortKD(ids, coords, nodeSize, left, right, depth) { - if (right - left <= nodeSize) return; - - var m = Math.floor((left + right) / 2); - - 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; -} - -},{}],23:[function(require,module,exports){ -'use strict'; - -module.exports = within; - -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; -} - -},{}],24:[function(require,module,exports){ -'use strict'; - -var util = require('../util/util'); - -module.exports = ArrayGroup; - -/** - * A class that manages vertex and element arrays for a range of features. It handles initialization, - * serialization for transfer to the main thread, and certain intervening mutations. - * - * Array elements are broken into array groups based on inherent limits of WebGL. Within a group is: - * - * * A "layout" vertex array, with fixed layout, containing values calculated from layout properties. - * * Zero, one, or two element arrays, with fixed layout, typically for eventual use in - * `gl.drawElements(gl.TRIANGLES, ...)`. - * * Zero or more "paint" vertex arrays keyed by layer ID, each with a dynamic layout which depends - * on which paint properties of that layer use data-driven-functions (property functions or - * property-and-zoom functions). Values are calculated by evaluating those functions. - * - * @private - */ -function ArrayGroup(arrayTypes) { - var LayoutVertexArrayType = arrayTypes.layoutVertexArrayType; - this.layoutVertexArray = new LayoutVertexArrayType(); - - var ElementArrayType = arrayTypes.elementArrayType; - if (ElementArrayType) this.elementArray = new ElementArrayType(); - - var ElementArrayType2 = arrayTypes.elementArrayType2; - if (ElementArrayType2) this.elementArray2 = new ElementArrayType2(); - - this.paintVertexArrays = util.mapObject(arrayTypes.paintVertexArrayTypes, function (PaintVertexArrayType) { - return new PaintVertexArrayType(); - }); -} - -/** - * The maximum size of a vertex array. This limit is imposed by WebGL's 16 bit - * addressing of vertex buffers. - * @private - * @readonly - */ -ArrayGroup.MAX_VERTEX_ARRAY_LENGTH = Math.pow(2, 16) - 1; - -ArrayGroup.prototype.hasCapacityFor = function(numVertices) { - return this.layoutVertexArray.length + numVertices <= ArrayGroup.MAX_VERTEX_ARRAY_LENGTH; -}; - -ArrayGroup.prototype.isEmpty = function() { - return this.layoutVertexArray.length === 0; -}; - -ArrayGroup.prototype.trim = function() { - this.layoutVertexArray.trim(); - - if (this.elementArray) { - this.elementArray.trim(); - } - - if (this.elementArray2) { - this.elementArray2.trim(); - } - - for (var layerName in this.paintVertexArrays) { - this.paintVertexArrays[layerName].trim(); - } -}; - -ArrayGroup.prototype.serialize = function() { - return { - layoutVertexArray: this.layoutVertexArray.serialize(), - elementArray: this.elementArray && this.elementArray.serialize(), - elementArray2: this.elementArray2 && this.elementArray2.serialize(), - paintVertexArrays: util.mapObject(this.paintVertexArrays, function(array) { - return array.serialize(); - }) - }; -}; - -ArrayGroup.prototype.getTransferables = function(transferables) { - transferables.push(this.layoutVertexArray.arrayBuffer); - - if (this.elementArray) { - transferables.push(this.elementArray.arrayBuffer); - } - - if (this.elementArray2) { - transferables.push(this.elementArray2.arrayBuffer); - } - - for (var layerName in this.paintVertexArrays) { - transferables.push(this.paintVertexArrays[layerName].arrayBuffer); - } -}; - -},{"../util/util":62}],25:[function(require,module,exports){ -'use strict'; - -var featureFilter = require('feature-filter'); -var ArrayGroup = require('./array_group'); -var BufferGroup = require('./buffer_group'); -var util = require('../util/util'); -var StructArrayType = require('../util/struct_array'); -var assert = require('assert'); - -module.exports = Bucket; - -/** - * Instantiate the appropriate subclass of `Bucket` for `options`. - * @private - * @param options See `Bucket` constructor options - * @returns {Bucket} - */ -Bucket.create = function(options) { - var Classes = { - fill: require('./bucket/fill_bucket'), - line: require('./bucket/line_bucket'), - circle: require('./bucket/circle_bucket'), - symbol: require('./bucket/symbol_bucket') - }; - return new Classes[options.layer.type](options); -}; - - -/** - * The maximum extent of a feature that can be safely stored in the buffer. - * In practice, all features are converted to this extent before being added. - * - * Positions are stored as signed 16bit integers. - * One bit is lost for signedness to support featuers extending past the left edge of the tile. - * One bit is lost because the line vertex buffer packs 1 bit of other data into the int. - * One bit is lost to support features extending past the extent on the right edge of the tile. - * This leaves us with 2^13 = 8192 - * - * @private - * @readonly - */ -Bucket.EXTENT = 8192; - -/** - * The `Bucket` class is the single point of knowledge about turning vector - * tiles into WebGL buffers. - * - * `Bucket` is an abstract class. A subclass exists for each Mapbox GL - * style spec layer type. Because `Bucket` is an abstract class, - * instances should be created via the `Bucket.create` method. - * - * @class Bucket - * @private - * @param options - * @param {number} options.zoom Zoom level of the buffers being built. May be - * a fractional zoom level. - * @param options.layer A Mapbox style layer object - * @param {Object.} options.buffers The set of `Buffer`s being - * built for this tile. This object facilitates sharing of `Buffer`s be - between `Bucket`s. - */ -function Bucket(options) { - this.zoom = options.zoom; - this.overscaling = options.overscaling; - this.layer = options.layer; - this.childLayers = options.childLayers; - - this.type = this.layer.type; - this.features = []; - this.id = this.layer.id; - this.index = options.index; - this.sourceLayer = this.layer.sourceLayer; - this.sourceLayerIndex = options.sourceLayerIndex; - this.minZoom = this.layer.minzoom; - this.maxZoom = this.layer.maxzoom; - - this.paintAttributes = createPaintAttributes(this); - - if (options.arrays) { - var programInterfaces = this.programInterfaces; - this.bufferGroups = util.mapObject(options.arrays, function(programArrayGroups, programName) { - var programInterface = programInterfaces[programName]; - var paintVertexArrayTypes = options.paintVertexArrayTypes[programName]; - return programArrayGroups.map(function(arrayGroup) { - return new BufferGroup(arrayGroup, { - layoutVertexArrayType: programInterface.layoutVertexArrayType.serialize(), - elementArrayType: programInterface.elementArrayType && programInterface.elementArrayType.serialize(), - elementArrayType2: programInterface.elementArrayType2 && programInterface.elementArrayType2.serialize(), - paintVertexArrayTypes: paintVertexArrayTypes - }); - }); - }); - } -} - -/** - * Build the arrays! Features are set directly to the `features` property. - * @private - */ -Bucket.prototype.populateArrays = function() { - this.createArrays(); - this.recalculateStyleLayers(); - - for (var i = 0; i < this.features.length; i++) { - this.addFeature(this.features[i]); - } - - this.trimArrays(); -}; - -/** - * Check if there is enough space available in the current array group for - * `vertexLength` vertices. If not, append a new array group. Should be called - * by `populateArrays` and its callees. - * - * Array groups are added to this.arrayGroups[programName]. - * - * @private - * @param {string} programName the name of the program associated with the buffer that will receive the vertices - * @param {number} vertexLength The number of vertices that will be inserted to the buffer. - * @returns The current array group - */ -Bucket.prototype.prepareArrayGroup = function(programName, numVertices) { - var groups = this.arrayGroups[programName]; - var currentGroup = groups.length && groups[groups.length - 1]; - - if (!currentGroup || !currentGroup.hasCapacityFor(numVertices)) { - currentGroup = new ArrayGroup({ - layoutVertexArrayType: this.programInterfaces[programName].layoutVertexArrayType, - elementArrayType: this.programInterfaces[programName].elementArrayType, - elementArrayType2: this.programInterfaces[programName].elementArrayType2, - paintVertexArrayTypes: this.paintVertexArrayTypes[programName] - }); - - currentGroup.index = groups.length; - - groups.push(currentGroup); - } - - return currentGroup; -}; - -/** - * Sets up `this.paintVertexArrayTypes` as { [programName]: { [layerName]: PaintArrayType, ... }, ... } - * - * And `this.arrayGroups` as { [programName]: [], ... }; these get populated - * with array group structure over in `prepareArrayGroup`. - * - * @private - */ -Bucket.prototype.createArrays = function() { - this.arrayGroups = {}; - this.paintVertexArrayTypes = {}; - - for (var programName in this.programInterfaces) { - this.arrayGroups[programName] = []; - - var paintVertexArrayTypes = this.paintVertexArrayTypes[programName] = {}; - var layerPaintAttributes = this.paintAttributes[programName]; - - for (var layerName in layerPaintAttributes) { - paintVertexArrayTypes[layerName] = new Bucket.VertexArrayType(layerPaintAttributes[layerName].attributes); - } - } -}; - -Bucket.prototype.destroy = function(gl) { - for (var programName in this.bufferGroups) { - var programBufferGroups = this.bufferGroups[programName]; - for (var i = 0; i < programBufferGroups.length; i++) { - programBufferGroups[i].destroy(gl); - } - } -}; - -Bucket.prototype.trimArrays = function() { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - arrayGroups[i].trim(); - } - } -}; - -Bucket.prototype.isEmpty = function() { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - if (!arrayGroups[i].isEmpty()) { - return false; - } - } - } - return true; -}; - -Bucket.prototype.getTransferables = function(transferables) { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - arrayGroups[i].getTransferables(transferables); - } - } -}; - -Bucket.prototype.setUniforms = function(gl, programName, program, layer, globalProperties) { - var uniforms = this.paintAttributes[programName][layer.id].uniforms; - for (var i = 0; i < uniforms.length; i++) { - var uniform = uniforms[i]; - var uniformLocation = program[uniform.name]; - gl['uniform' + uniform.components + 'fv'](uniformLocation, uniform.getValue(layer, globalProperties)); - } -}; - -Bucket.prototype.serialize = function() { - return { - layerId: this.layer.id, - zoom: this.zoom, - arrays: util.mapObject(this.arrayGroups, function(programArrayGroups) { - return programArrayGroups.map(function(arrayGroup) { - return arrayGroup.serialize(); - }); - }), - paintVertexArrayTypes: util.mapObject(this.paintVertexArrayTypes, function(arrayTypes) { - return util.mapObject(arrayTypes, function(arrayType) { - return arrayType.serialize(); - }); - }), - - childLayerIds: this.childLayers.map(function(layer) { - return layer.id; - }) - }; -}; - -Bucket.prototype.createFilter = function() { - if (!this.filter) { - this.filter = featureFilter(this.layer.filter); - } -}; - -var FAKE_ZOOM_HISTORY = { lastIntegerZoom: Infinity, lastIntegerZoomTime: 0, lastZoom: 0 }; -Bucket.prototype.recalculateStyleLayers = function() { - for (var i = 0; i < this.childLayers.length; i++) { - this.childLayers[i].recalculate(this.zoom, FAKE_ZOOM_HISTORY); - } -}; - -Bucket.prototype.populatePaintArrays = function(interfaceName, globalProperties, featureProperties, startGroup, startIndex) { - for (var l = 0; l < this.childLayers.length; l++) { - var layer = this.childLayers[l]; - var groups = this.arrayGroups[interfaceName]; - for (var g = startGroup.index; g < groups.length; g++) { - var group = groups[g]; - var length = group.layoutVertexArray.length; - var paintArray = group.paintVertexArrays[layer.id]; - paintArray.resize(length); - - var attributes = this.paintAttributes[interfaceName][layer.id].attributes; - for (var m = 0; m < attributes.length; m++) { - var attribute = attributes[m]; - - var value = attribute.getValue(layer, globalProperties, featureProperties); - var multiplier = attribute.multiplier || 1; - var components = attribute.components || 1; - - var start = g === startGroup.index ? startIndex : 0; - for (var i = start; i < length; i++) { - var vertex = paintArray.get(i); - for (var c = 0; c < components; c++) { - var memberName = components > 1 ? (attribute.name + c) : attribute.name; - vertex[memberName] = value[c] * multiplier; - } - } - } - } - } -}; - -/** - * A vertex array stores data for each vertex in a geometry. Elements are aligned to 4 byte - * boundaries for best performance in WebGL. - * @private - */ -Bucket.VertexArrayType = function (members) { - return new StructArrayType({ - members: members, - alignment: 4 - }); -}; - -/** - * An element array stores Uint16 indicies of vertexes in a corresponding vertex array. With no - * arguments, it defaults to three components per element, forming triangles. - * @private - */ -Bucket.ElementArrayType = function (components) { - return new StructArrayType({ - members: [{ - type: 'Uint16', - name: 'vertices', - components: components || 3 - }] - }); -}; - -function createPaintAttributes(bucket) { - var attributes = {}; - for (var interfaceName in bucket.programInterfaces) { - var layerPaintAttributes = attributes[interfaceName] = {}; - - for (var c = 0; c < bucket.childLayers.length; c++) { - var childLayer = bucket.childLayers[c]; - - layerPaintAttributes[childLayer.id] = { - attributes: [], - uniforms: [], - defines: [], - vertexPragmas: { define: {}, initialize: {} }, - fragmentPragmas: { define: {}, initialize: {} } - }; - } - - var interface_ = bucket.programInterfaces[interfaceName]; - if (!interface_.paintAttributes) continue; - - // These tokens are replaced by arguments to the pragma - // https://github.com/mapbox/mapbox-gl-shaders#pragmas - var attributePrecision = '{precision}'; - var attributeType = '{type}'; - - for (var i = 0; i < interface_.paintAttributes.length; i++) { - var attribute = interface_.paintAttributes[i]; - attribute.multiplier = attribute.multiplier || 1; - - for (var j = 0; j < bucket.childLayers.length; j++) { - var layer = bucket.childLayers[j]; - var paintAttributes = layerPaintAttributes[layer.id]; - - var attributeInputName = attribute.name; - assert(attribute.name.slice(0, 2) === 'a_'); - var attributeInnerName = attribute.name.slice(2); - var attributeVaryingDefinition; - - paintAttributes.fragmentPragmas.initialize[attributeInnerName] = ''; - - if (layer.isPaintValueFeatureConstant(attribute.paintProperty)) { - paintAttributes.uniforms.push(attribute); - - paintAttributes.fragmentPragmas.define[attributeInnerName] = paintAttributes.vertexPragmas.define[attributeInnerName] = [ - 'uniform', - attributePrecision, - attributeType, - attributeInputName - ].join(' ') + ';'; - - paintAttributes.fragmentPragmas.initialize[attributeInnerName] = paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributePrecision, - attributeType, - attributeInnerName, - '=', - attributeInputName - ].join(' ') + ';\n'; - - } else if (layer.isPaintValueZoomConstant(attribute.paintProperty)) { - paintAttributes.attributes.push(util.extend({}, attribute, { - name: attributeInputName - })); - - attributeVaryingDefinition = [ - 'varying', - attributePrecision, - attributeType, - attributeInnerName - ].join(' ') + ';\n'; - - var attributeAttributeDefinition = [ - paintAttributes.fragmentPragmas.define[attributeInnerName], - 'attribute', - attributePrecision, - attributeType, - attributeInputName - ].join(' ') + ';\n'; - - paintAttributes.fragmentPragmas.define[attributeInnerName] = attributeVaryingDefinition; - - paintAttributes.vertexPragmas.define[attributeInnerName] = attributeVaryingDefinition + attributeAttributeDefinition; - - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - '=', - attributeInputName, - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - - } else { - - var tName = 'u_' + attributeInputName.slice(2) + '_t'; - var zoomLevels = layer.getPaintValueStopZoomLevels(attribute.paintProperty); - - // Pick the index of the first offset to add to the buffers. - // Find the four closest stops, ideally with two on each side of the zoom level. - var numStops = 0; - while (numStops < zoomLevels.length && zoomLevels[numStops] < bucket.zoom) numStops++; - var stopOffset = Math.max(0, Math.min(zoomLevels.length - 4, numStops - 2)); - - var fourZoomLevels = []; - for (var s = 0; s < 4; s++) { - fourZoomLevels.push(zoomLevels[Math.min(stopOffset + s, zoomLevels.length - 1)]); - } - - attributeVaryingDefinition = [ - 'varying', - attributePrecision, - attributeType, - attributeInnerName - ].join(' ') + ';\n'; - - paintAttributes.vertexPragmas.define[attributeInnerName] = attributeVaryingDefinition + [ - 'uniform', - 'lowp', - 'float', - tName - ].join(' ') + ';\n'; - paintAttributes.fragmentPragmas.define[attributeInnerName] = attributeVaryingDefinition; - - paintAttributes.uniforms.push(util.extend({}, attribute, { - name: tName, - getValue: createGetUniform(attribute, stopOffset), - components: 1 - })); - - var components = attribute.components; - if (components === 1) { - - paintAttributes.attributes.push(util.extend({}, attribute, { - getValue: createFunctionGetValue(attribute, fourZoomLevels), - isFunction: true, - components: components * 4 - })); - - paintAttributes.vertexPragmas.define[attributeInnerName] += [ - 'attribute', - attributePrecision, - 'vec4', - attributeInputName - ].join(' ') + ';\n'; - - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - '=', - 'evaluate_zoom_function_1(' + attributeInputName + ', ' + tName + ')', - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - - } else { - - var attributeInputNames = []; - for (var k = 0; k < 4; k++) { - attributeInputNames.push(attributeInputName + k); - paintAttributes.attributes.push(util.extend({}, attribute, { - getValue: createFunctionGetValue(attribute, [fourZoomLevels[k]]), - isFunction: true, - name: attributeInputName + k - })); - paintAttributes.vertexPragmas.define[attributeInnerName] += [ - 'attribute', - attributePrecision, - attributeType, - attributeInputName + k - ].join(' ') + ';\n'; - } - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - ' = ', - 'evaluate_zoom_function_4(' + attributeInputNames.join(', ') + ', ' + tName + ')', - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - } - } - } - } - } - return attributes; -} - -function createFunctionGetValue(attribute, stopZoomLevels) { - return function(layer, globalProperties, featureProperties) { - if (stopZoomLevels.length === 1) { - // return one multi-component value like color0 - return attribute.getValue(layer, util.extend({}, globalProperties, { zoom: stopZoomLevels[0] }), featureProperties); - } else { - // pack multiple single-component values into a four component attribute - var values = []; - for (var z = 0; z < stopZoomLevels.length; z++) { - var stopZoomLevel = stopZoomLevels[z]; - values.push(attribute.getValue(layer, util.extend({}, globalProperties, { zoom: stopZoomLevel }), featureProperties)[0]); - } - return values; - } - }; -} - -function createGetUniform(attribute, stopOffset) { - return function(layer, globalProperties) { - // stopInterp indicates which stops need to be interpolated. - // If stopInterp is 3.5 then interpolate half way between stops 3 and 4. - var stopInterp = layer.getPaintInterpolationT(attribute.paintProperty, globalProperties.zoom); - // We can only store four stop values in the buffers. stopOffset is the number of stops that come - // before the stops that were added to the buffers. - return [Math.max(0, Math.min(4, stopInterp - stopOffset))]; - }; -} - -},{"../util/struct_array":60,"../util/util":62,"./array_group":24,"./bucket/circle_bucket":26,"./bucket/fill_bucket":27,"./bucket/line_bucket":28,"./bucket/symbol_bucket":29,"./buffer_group":31,"assert":1,"feature-filter":7}],26:[function(require,module,exports){ -'use strict'; - -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var EXTENT = Bucket.EXTENT; - -module.exports = CircleBucket; - -/** - * Circles are represented by two triangles. - * - * Each corner has a pos that is the center of the circle and an extrusion - * vector that is where it points. - * @private - */ -function CircleBucket() { - Bucket.apply(this, arguments); -} - -CircleBucket.prototype = util.inherit(Bucket, {}); - -CircleBucket.prototype.addCircleVertex = function(layoutVertexArray, x, y, extrudeX, extrudeY) { - return layoutVertexArray.emplaceBack( - (x * 2) + ((extrudeX + 1) / 2), - (y * 2) + ((extrudeY + 1) / 2)); -}; - -CircleBucket.prototype.programInterfaces = { - circle: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }]), - elementArrayType: new Bucket.ElementArrayType(), - - paintAttributes: [{ - name: 'a_color', - components: 4, - type: 'Uint8', - getValue: function(layer, globalProperties, featureProperties) { - return layer.getPaintValue("circle-color", globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'circle-color' - }, { - name: 'a_radius', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function(layer, globalProperties, featureProperties) { - return [layer.getPaintValue("circle-radius", globalProperties, featureProperties)]; - }, - multiplier: 10, - paintProperty: 'circle-radius' - }, { - name: 'a_blur', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function(layer, globalProperties, featureProperties) { - return [layer.getPaintValue("circle-blur", globalProperties, featureProperties)]; - }, - multiplier: 10, - paintProperty: 'circle-blur' - }, { - name: 'a_opacity', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function(layer, globalProperties, featureProperties) { - return [layer.getPaintValue("circle-opacity", globalProperties, featureProperties)]; - }, - multiplier: 255, - paintProperty: 'circle-opacity' - }] - } -}; - -CircleBucket.prototype.addFeature = function(feature) { - var globalProperties = {zoom: this.zoom}; - var geometries = loadGeometry(feature); - - var startGroup = this.prepareArrayGroup('circle', 0); - var startIndex = startGroup.layoutVertexArray.length; - - for (var j = 0; j < geometries.length; j++) { - for (var k = 0; k < geometries[j].length; k++) { - - var x = geometries[j][k].x; - var y = geometries[j][k].y; - - // Do not include points that are outside the tile boundaries. - if (x < 0 || x >= EXTENT || y < 0 || y >= EXTENT) continue; - - // this geometry will be of the Point type, and we'll derive - // two triangles from it. - // - // ┌─────────┐ - // │ 3 2 │ - // │ │ - // │ 0 1 │ - // └─────────┘ - - var group = this.prepareArrayGroup('circle', 4); - var layoutVertexArray = group.layoutVertexArray; - - var index = this.addCircleVertex(layoutVertexArray, x, y, -1, -1); - this.addCircleVertex(layoutVertexArray, x, y, 1, -1); - this.addCircleVertex(layoutVertexArray, x, y, 1, 1); - this.addCircleVertex(layoutVertexArray, x, y, -1, 1); - - group.elementArray.emplaceBack(index, index + 1, index + 2); - group.elementArray.emplaceBack(index, index + 3, index + 2); - } - } - - this.populatePaintArrays('circle', globalProperties, feature.properties, startGroup, startIndex); -}; - -},{"../../util/util":62,"../bucket":25,"../load_geometry":33}],27:[function(require,module,exports){ -'use strict'; - -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var earcut = require('earcut'); -var classifyRings = require('../../util/classify_rings'); -var EARCUT_MAX_RINGS = 500; - -module.exports = FillBucket; - -function FillBucket() { - Bucket.apply(this, arguments); -} - -FillBucket.prototype = util.inherit(Bucket, {}); - -FillBucket.prototype.programInterfaces = { - fill: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }]), - elementArrayType: new Bucket.ElementArrayType(1), - elementArrayType2: new Bucket.ElementArrayType(2), - - paintAttributes: [{ - name: 'a_color', - components: 4, - type: 'Uint8', - getValue: function(layer, globalProperties, featureProperties) { - return layer.getPaintValue("fill-color", globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'fill-color' - }, { - name: 'a_outline_color', - components: 4, - type: 'Uint8', - getValue: function(layer, globalProperties, featureProperties) { - return layer.getPaintValue("fill-outline-color", globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'fill-outline-color' - }, { - name: 'a_opacity', - components: 1, - type: 'Uint8', - getValue: function(layer, globalProperties, featureProperties) { - return [layer.getPaintValue("fill-opacity", globalProperties, featureProperties)]; - }, - multiplier: 255, - paintProperty: 'fill-opacity' - }] - } -}; - -FillBucket.prototype.addFeature = function(feature) { - var lines = loadGeometry(feature); - var polygons = classifyRings(lines, EARCUT_MAX_RINGS); - - var startGroup = this.prepareArrayGroup('fill', 0); - var startIndex = startGroup.layoutVertexArray.length; - - for (var i = 0; i < polygons.length; i++) { - this.addPolygon(polygons[i]); - } - - this.populatePaintArrays('fill', {zoom: this.zoom}, feature.properties, startGroup, startIndex); -}; - -FillBucket.prototype.addPolygon = function(polygon) { - var numVertices = 0; - for (var k = 0; k < polygon.length; k++) { - numVertices += polygon[k].length; - } - - var group = this.prepareArrayGroup('fill', numVertices); - var flattened = []; - var holeIndices = []; - var startIndex = group.layoutVertexArray.length; - - for (var r = 0; r < polygon.length; r++) { - var ring = polygon[r]; - - if (r > 0) holeIndices.push(flattened.length / 2); - - for (var v = 0; v < ring.length; v++) { - var vertex = ring[v]; - - var index = group.layoutVertexArray.emplaceBack(vertex.x, vertex.y); - - if (v >= 1) { - group.elementArray2.emplaceBack(index - 1, index); - } - - // convert to format used by earcut - flattened.push(vertex.x); - flattened.push(vertex.y); - } - } - - var triangleIndices = earcut(flattened, holeIndices); - - for (var i = 0; i < triangleIndices.length; i++) { - group.elementArray.emplaceBack(triangleIndices[i] + startIndex); - } -}; - -},{"../../util/classify_rings":55,"../../util/util":62,"../bucket":25,"../load_geometry":33,"earcut":6}],28:[function(require,module,exports){ -'use strict'; - -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var EXTENT = Bucket.EXTENT; - -// NOTE ON EXTRUDE SCALE: -// scale the extrusion vector so that the normal length is this value. -// contains the "texture" normals (-1..1). this is distinct from the extrude -// normals for line joins, because the x-value remains 0 for the texture -// normal array, while the extrude normal actually moves the vertex to create -// the acute/bevelled line join. -var EXTRUDE_SCALE = 63; - -/* - * Sharp corners cause dashed lines to tilt because the distance along the line - * is the same at both the inner and outer corners. To improve the appearance of - * dashed lines we add extra points near sharp corners so that a smaller part - * of the line is tilted. - * - * COS_HALF_SHARP_CORNER controls how sharp a corner has to be for us to add an - * extra vertex. The default is 75 degrees. - * - * The newly created vertices are placed SHARP_CORNER_OFFSET pixels from the corner. - */ -var COS_HALF_SHARP_CORNER = Math.cos(75 / 2 * (Math.PI / 180)); -var SHARP_CORNER_OFFSET = 15; - -// The number of bits that is used to store the line distance in the buffer. -var LINE_DISTANCE_BUFFER_BITS = 15; - -// We don't have enough bits for the line distance as we'd like to have, so -// use this value to scale the line distance (in tile units) down to a smaller -// value. This lets us store longer distances while sacrificing precision. -var LINE_DISTANCE_SCALE = 1 / 2; - -// The maximum line distance, in tile units, that fits in the buffer. -var MAX_LINE_DISTANCE = Math.pow(2, LINE_DISTANCE_BUFFER_BITS - 1) / LINE_DISTANCE_SCALE; - - -module.exports = LineBucket; - -/** - * @private - */ -function LineBucket() { - Bucket.apply(this, arguments); -} - -LineBucket.prototype = util.inherit(Bucket, {}); - -LineBucket.prototype.addLineVertex = function(layoutVertexBuffer, point, extrude, tx, ty, dir, linesofar) { - return layoutVertexBuffer.emplaceBack( - // a_pos - (point.x << 1) | tx, - (point.y << 1) | ty, - // a_data - // add 128 to store an byte in an unsigned byte - Math.round(EXTRUDE_SCALE * extrude.x) + 128, - Math.round(EXTRUDE_SCALE * extrude.y) + 128, - // Encode the -1/0/1 direction value into the first two bits of .z of a_data. - // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make - // room for the direction value). The upper 8 bits of `linesofar` are placed in - // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that - // we can store longer distances while sacrificing precision. - ((dir === 0 ? 0 : (dir < 0 ? -1 : 1)) + 1) | (((linesofar * LINE_DISTANCE_SCALE) & 0x3F) << 2), - (linesofar * LINE_DISTANCE_SCALE) >> 6); -}; - -LineBucket.prototype.programInterfaces = { - line: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }, { - name: 'a_data', - components: 4, - type: 'Uint8' - }]), - elementArrayType: new Bucket.ElementArrayType() - } -}; - -LineBucket.prototype.addFeature = function(feature) { - var lines = loadGeometry(feature, LINE_DISTANCE_BUFFER_BITS); - for (var i = 0; i < lines.length; i++) { - this.addLine( - lines[i], - this.layer.layout['line-join'], - this.layer.layout['line-cap'], - this.layer.layout['line-miter-limit'], - this.layer.layout['line-round-limit'] - ); - } -}; - -LineBucket.prototype.addLine = function(vertices, join, cap, miterLimit, roundLimit) { - - var len = vertices.length; - // If the line has duplicate vertices at the end, adjust length to remove them. - while (len > 2 && vertices[len - 1].equals(vertices[len - 2])) { - len--; - } - - // a line must have at least two vertices - if (vertices.length < 2) return; - - if (join === 'bevel') miterLimit = 1.05; - - var sharpCornerOffset = SHARP_CORNER_OFFSET * (EXTENT / (512 * this.overscaling)); - - var firstVertex = vertices[0], - lastVertex = vertices[len - 1], - closed = firstVertex.equals(lastVertex); - - // we could be more precise, but it would only save a negligible amount of space - this.prepareArrayGroup('line', len * 10); - - // a line may not have coincident points - if (len === 2 && closed) return; - - this.distance = 0; - - var beginCap = cap, - endCap = closed ? 'butt' : cap, - startOfLine = true, - currentVertex, prevVertex, nextVertex, prevNormal, nextNormal, offsetA, offsetB; - - // the last three vertices added - this.e1 = this.e2 = this.e3 = -1; - - if (closed) { - currentVertex = vertices[len - 2]; - nextNormal = firstVertex.sub(currentVertex)._unit()._perp(); - } - - for (var i = 0; i < len; i++) { - - nextVertex = closed && i === len - 1 ? - vertices[1] : // if the line is closed, we treat the last vertex like the first - vertices[i + 1]; // just the next vertex - - // if two consecutive vertices exist, skip the current one - if (nextVertex && vertices[i].equals(nextVertex)) continue; - - if (nextNormal) prevNormal = nextNormal; - if (currentVertex) prevVertex = currentVertex; - - currentVertex = vertices[i]; - - // Calculate the normal towards the next vertex in this line. In case - // there is no next vertex, pretend that the line is continuing straight, - // meaning that we are just using the previous normal. - nextNormal = nextVertex ? nextVertex.sub(currentVertex)._unit()._perp() : prevNormal; - - // If we still don't have a previous normal, this is the beginning of a - // non-closed line, so we're doing a straight "join". - prevNormal = prevNormal || nextNormal; - - // Determine the normal of the join extrusion. It is the angle bisector - // of the segments between the previous line and the next line. - var joinNormal = prevNormal.add(nextNormal)._unit(); - - /* joinNormal prevNormal - * ↖ ↑ - * .________. prevVertex - * | - * nextNormal ← | currentVertex - * | - * nextVertex ! - * - */ - - // Calculate the length of the miter (the ratio of the miter to the width). - // Find the cosine of the angle between the next and join normals - // using dot product. The inverse of that is the miter length. - var cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y; - var miterLength = 1 / cosHalfAngle; - - var isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex; - - if (isSharpCorner && i > 0) { - var prevSegmentLength = currentVertex.dist(prevVertex); - if (prevSegmentLength > 2 * sharpCornerOffset) { - var newPrevVertex = currentVertex.sub(currentVertex.sub(prevVertex)._mult(sharpCornerOffset / prevSegmentLength)._round()); - this.distance += newPrevVertex.dist(prevVertex); - this.addCurrentVertex(newPrevVertex, this.distance, prevNormal.mult(1), 0, 0, false); - prevVertex = newPrevVertex; - } - } - - // The join if a middle vertex, otherwise the cap. - var middleVertex = prevVertex && nextVertex; - var currentJoin = middleVertex ? join : nextVertex ? beginCap : endCap; - - 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') { - // The maximum extrude length is 128 / 63 = 2 times the width of the line - // so if miterLength >= 2 we need to draw a different type of bevel where. - if (miterLength > 2) currentJoin = 'flipbevel'; - - // If the miterLength is really small and the line bevel wouldn't be visible, - // just draw a miter join to save a triangle. - if (miterLength < miterLimit) currentJoin = 'miter'; - } - - // Calculate how far along the line the currentVertex is - if (prevVertex) this.distance += currentVertex.dist(prevVertex); - - if (currentJoin === 'miter') { - - joinNormal._mult(miterLength); - this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false); - - } else if (currentJoin === 'flipbevel') { - // miter is too big, flip the direction to make a beveled join - - if (miterLength > 100) { - // Almost parallel lines - joinNormal = nextNormal.clone(); - - } else { - var direction = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0 ? -1 : 1; - var bevelLength = miterLength * prevNormal.add(nextNormal).mag() / prevNormal.sub(nextNormal).mag(); - joinNormal._perp()._mult(bevelLength * direction); - } - this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false); - this.addCurrentVertex(currentVertex, this.distance, joinNormal.mult(-1), 0, 0, false); - - } else if (currentJoin === 'bevel' || currentJoin === 'fakeround') { - var lineTurnsLeft = (prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x) > 0; - var offset = -Math.sqrt(miterLength * miterLength - 1); - if (lineTurnsLeft) { - offsetB = 0; - offsetA = offset; - } else { - offsetA = 0; - offsetB = offset; - } - - // Close previous segment with a bevel - if (!startOfLine) { - this.addCurrentVertex(currentVertex, this.distance, prevNormal, offsetA, offsetB, false); - } - - if (currentJoin === 'fakeround') { - // The join angle is sharp enough that a round join would be visible. - // Bevel joins fill the gap between segments with a single pie slice triangle. - // Create a round join by adding multiple pie slices. The join isn't actually round, but - // it looks like it is at the sizes we render lines at. - - // Add more triangles for sharper angles. - // This math is just a good enough approximation. It isn't "correct". - var n = Math.floor((0.5 - (cosHalfAngle - 0.5)) * 8); - var approxFractionalJoinNormal; - - for (var m = 0; m < n; m++) { - approxFractionalJoinNormal = nextNormal.mult((m + 1) / (n + 1))._add(prevNormal)._unit(); - this.addPieSliceVertex(currentVertex, this.distance, approxFractionalJoinNormal, lineTurnsLeft); - } - - this.addPieSliceVertex(currentVertex, this.distance, joinNormal, lineTurnsLeft); - - for (var k = n - 1; k >= 0; k--) { - approxFractionalJoinNormal = prevNormal.mult((k + 1) / (n + 1))._add(nextNormal)._unit(); - this.addPieSliceVertex(currentVertex, this.distance, approxFractionalJoinNormal, lineTurnsLeft); - } - } - - // Start next segment - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -offsetA, -offsetB, false); - } - - } else if (currentJoin === 'butt') { - if (!startOfLine) { - // Close previous segment with a butt - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false); - } - - // Start next segment with a butt - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false); - } - - } else if (currentJoin === 'square') { - - if (!startOfLine) { - // Close previous segment with a square cap - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, false); - - // The segment is done. Unset vertices to disconnect segments. - this.e1 = this.e2 = -1; - } - - // Start next segment - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, false); - } - - } else if (currentJoin === 'round') { - - if (!startOfLine) { - // Close previous segment with butt - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false); - - // Add round cap or linejoin at end of segment - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, true); - - // The segment is done. Unset vertices to disconnect segments. - this.e1 = this.e2 = -1; - } - - - // Start next segment with a butt - if (nextVertex) { - // Add round cap before first segment - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, true); - - this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false); - } - } - - if (isSharpCorner && i < len - 1) { - var nextSegmentLength = currentVertex.dist(nextVertex); - if (nextSegmentLength > 2 * sharpCornerOffset) { - var newCurrentVertex = currentVertex.add(nextVertex.sub(currentVertex)._mult(sharpCornerOffset / nextSegmentLength)._round()); - this.distance += newCurrentVertex.dist(currentVertex); - this.addCurrentVertex(newCurrentVertex, this.distance, nextNormal.mult(1), 0, 0, false); - currentVertex = newCurrentVertex; - } - } - - startOfLine = false; - } - -}; - -/** - * Add two vertices to the buffers. - * - * @param {Object} currentVertex the line vertex to add buffer vertices for - * @param {number} distance the distance from the beginning of the line to the vertex - * @param {number} endLeft extrude to shift the left vertex along the line - * @param {number} endRight extrude to shift the left vertex along the line - * @param {boolean} round whether this is a round cap - * @private - */ -LineBucket.prototype.addCurrentVertex = function(currentVertex, distance, normal, endLeft, endRight, round) { - var tx = round ? 1 : 0; - var extrude; - var arrayGroup = this.arrayGroups.line[this.arrayGroups.line.length - 1]; - var layoutVertexArray = arrayGroup.layoutVertexArray; - var elementArray = arrayGroup.elementArray; - - extrude = normal.clone(); - if (endLeft) extrude._sub(normal.perp()._mult(endLeft)); - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 0, endLeft, distance); - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - this.e1 = this.e2; - this.e2 = this.e3; - - extrude = normal.mult(-1); - if (endRight) extrude._sub(normal.perp()._mult(endRight)); - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 1, -endRight, distance); - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - this.e1 = this.e2; - this.e2 = this.e3; - - // There is a maximum "distance along the line" that we can store in the buffers. - // When we get close to the distance, reset it to zero and add the vertex again with - // a distance of zero. The max distance is determined by the number of bits we allocate - // to `linesofar`. - if (distance > MAX_LINE_DISTANCE / 2) { - this.distance = 0; - this.addCurrentVertex(currentVertex, this.distance, normal, endLeft, endRight, round); - } -}; - -/** - * Add a single new vertex and a triangle using two previous vertices. - * This adds a pie slice triangle near a join to simulate round joins - * - * @param {Object} currentVertex the line vertex to add buffer vertices for - * @param {number} distance the distance from the beggining of the line to the vertex - * @param {Object} extrude the offset of the new vertex from the currentVertex - * @param {boolean} whether the line is turning left or right at this angle - * @private - */ -LineBucket.prototype.addPieSliceVertex = function(currentVertex, distance, extrude, lineTurnsLeft) { - var ty = lineTurnsLeft ? 1 : 0; - extrude = extrude.mult(lineTurnsLeft ? -1 : 1); - var arrayGroup = this.arrayGroups.line[this.arrayGroups.line.length - 1]; - var layoutVertexArray = arrayGroup.layoutVertexArray; - var elementArray = arrayGroup.elementArray; - - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, 0, ty, 0, distance); - - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - - if (lineTurnsLeft) { - this.e2 = this.e3; - } else { - this.e1 = this.e3; - } -}; - -},{"../../util/util":62,"../bucket":25,"../load_geometry":33}],29:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -var Bucket = require('../bucket'); -var Anchor = require('../../symbol/anchor'); -var getAnchors = require('../../symbol/get_anchors'); -var resolveTokens = require('../../util/token'); -var Quads = require('../../symbol/quads'); -var Shaping = require('../../symbol/shaping'); -var resolveText = require('../../symbol/resolve_text'); -var mergeLines = require('../../symbol/mergelines'); -var clipLine = require('../../symbol/clip_line'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var CollisionFeature = require('../../symbol/collision_feature'); - -var shapeText = Shaping.shapeText; -var shapeIcon = Shaping.shapeIcon; -var getGlyphQuads = Quads.getGlyphQuads; -var getIconQuads = Quads.getIconQuads; - -var EXTENT = Bucket.EXTENT; - -module.exports = SymbolBucket; - -function SymbolBucket(options) { - Bucket.apply(this, arguments); - this.showCollisionBoxes = options.showCollisionBoxes; - this.overscaling = options.overscaling; - this.collisionBoxArray = options.collisionBoxArray; - this.symbolQuadsArray = options.symbolQuadsArray; - this.symbolInstancesArray = options.symbolInstancesArray; - - this.sdfIcons = options.sdfIcons; - this.iconsNeedLinear = options.iconsNeedLinear; - this.adjustedTextSize = options.adjustedTextSize; - this.adjustedIconSize = options.adjustedIconSize; - this.fontstack = options.fontstack; -} - -// this constant is based on the size of the glyphQuadEndIndex and iconQuadEndIndex -// in the symbol_instances StructArrayType -// eg the max valid UInt16 is 65,535 -SymbolBucket.MAX_QUADS = 65535; - -SymbolBucket.prototype = util.inherit(Bucket, {}); - -SymbolBucket.prototype.serialize = function() { - var serialized = Bucket.prototype.serialize.apply(this); - serialized.sdfIcons = this.sdfIcons; - serialized.iconsNeedLinear = this.iconsNeedLinear; - serialized.adjustedTextSize = this.adjustedTextSize; - serialized.adjustedIconSize = this.adjustedIconSize; - serialized.fontstack = this.fontstack; - return serialized; -}; - -var layoutVertexArrayType = new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' -}, { - name: 'a_offset', - components: 2, - type: 'Int16' -}, { - name: 'a_texture_pos', - components: 2, - type: 'Uint16' -}, { - name: 'a_data', - components: 4, - type: 'Uint8' -}]); - -var elementArrayType = new Bucket.ElementArrayType(); - -function addVertex(array, x, y, ox, oy, tx, ty, minzoom, maxzoom, labelminzoom, labelangle) { - return array.emplaceBack( - // a_pos - x, - y, - - // a_offset - Math.round(ox * 64), - Math.round(oy * 64), - - // a_texture_pos - tx / 4, // x coordinate of symbol on glyph atlas texture - ty / 4, // y coordinate of symbol on glyph atlas texture - - // a_data - (labelminzoom || 0) * 10, // labelminzoom - labelangle, // labelangle - (minzoom || 0) * 10, // minzoom - Math.min(maxzoom || 25, 25) * 10); // maxzoom -} - -SymbolBucket.prototype.addCollisionBoxVertex = function(layoutVertexArray, point, extrude, maxZoom, placementZoom) { - return layoutVertexArray.emplaceBack( - // pos - point.x, - point.y, - // extrude - Math.round(extrude.x), - Math.round(extrude.y), - // data - maxZoom * 10, - placementZoom * 10); -}; - -SymbolBucket.prototype.programInterfaces = { - - glyph: { - layoutVertexArrayType: layoutVertexArrayType, - elementArrayType: elementArrayType - }, - - icon: { - layoutVertexArrayType: layoutVertexArrayType, - elementArrayType: elementArrayType - }, - - collisionBox: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }, { - name: 'a_extrude', - components: 2, - type: 'Int16' - }, { - name: 'a_data', - components: 2, - type: 'Uint8' - }]) - } -}; - -SymbolBucket.prototype.populateArrays = function(collisionTile, stacks, icons) { - - // To reduce the number of labels that jump around when zooming we need - // to use a text-size value that is the same for all zoom levels. - // This calculates text-size at a high zoom level so that all tiles can - // use the same value when calculating anchor positions. - var zoomHistory = { lastIntegerZoom: Infinity, lastIntegerZoomTime: 0, lastZoom: 0 }; - this.adjustedTextMaxSize = this.layer.getLayoutValue('text-size', {zoom: 18, zoomHistory: zoomHistory}); - this.adjustedTextSize = this.layer.getLayoutValue('text-size', {zoom: this.zoom + 1, zoomHistory: zoomHistory}); - this.adjustedIconMaxSize = this.layer.getLayoutValue('icon-size', {zoom: 18, zoomHistory: zoomHistory}); - this.adjustedIconSize = this.layer.getLayoutValue('icon-size', {zoom: this.zoom + 1, zoomHistory: zoomHistory}); - - var tileSize = 512 * this.overscaling; - this.tilePixelRatio = EXTENT / tileSize; - this.compareText = {}; - this.iconsNeedLinear = false; - this.symbolInstancesStartIndex = this.symbolInstancesArray.length; - - var layout = this.layer.layout; - var features = this.features; - var textFeatures = this.textFeatures; - - var horizontalAlign = 0.5, - verticalAlign = 0.5; - - switch (layout['text-anchor']) { - case 'right': - case 'top-right': - case 'bottom-right': - horizontalAlign = 1; - break; - case 'left': - case 'top-left': - case 'bottom-left': - horizontalAlign = 0; - break; - } - - switch (layout['text-anchor']) { - case 'bottom': - case 'bottom-right': - case 'bottom-left': - verticalAlign = 1; - break; - case 'top': - case 'top-right': - case 'top-left': - verticalAlign = 0; - break; - } - - var justify = layout['text-justify'] === 'right' ? 1 : - layout['text-justify'] === 'left' ? 0 : - 0.5; - - var oneEm = 24; - var lineHeight = layout['text-line-height'] * oneEm; - var maxWidth = layout['symbol-placement'] !== 'line' ? layout['text-max-width'] * oneEm : 0; - var spacing = layout['text-letter-spacing'] * oneEm; - var textOffset = [layout['text-offset'][0] * oneEm, layout['text-offset'][1] * oneEm]; - var fontstack = this.fontstack = layout['text-font'].join(','); - - var geometries = []; - for (var g = 0; g < features.length; g++) { - geometries.push(loadGeometry(features[g])); - } - - if (layout['symbol-placement'] === 'line') { - // Merge adjacent lines with the same text to improve labelling. - // It's better to place labels on one long line than on many short segments. - var merged = mergeLines(features, textFeatures, geometries); - - geometries = merged.geometries; - features = merged.features; - textFeatures = merged.textFeatures; - } - - var shapedText, shapedIcon; - - for (var k = 0; k < features.length; k++) { - if (!geometries[k]) continue; - - if (textFeatures[k]) { - shapedText = shapeText(textFeatures[k], stacks[fontstack], maxWidth, - lineHeight, horizontalAlign, verticalAlign, justify, spacing, textOffset); - } else { - shapedText = null; - } - - if (layout['icon-image']) { - var iconName = resolveTokens(features[k].properties, layout['icon-image']); - var image = icons[iconName]; - shapedIcon = shapeIcon(image, layout); - - if (image) { - if (this.sdfIcons === undefined) { - this.sdfIcons = image.sdf; - } else if (this.sdfIcons !== image.sdf) { - util.warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer'); - } - if (image.pixelRatio !== 1) { - this.iconsNeedLinear = true; - } else if (layout['icon-rotate'] !== 0 || !this.layer.isLayoutValueFeatureConstant('icon-rotate')) { - this.iconsNeedLinear = true; - } - } - } else { - shapedIcon = null; - } - - if (shapedText || shapedIcon) { - this.addFeature(geometries[k], shapedText, shapedIcon, features[k]); - } - } - this.symbolInstancesEndIndex = this.symbolInstancesArray.length; - this.placeFeatures(collisionTile, this.showCollisionBoxes); - - this.trimArrays(); -}; - -SymbolBucket.prototype.addFeature = function(lines, shapedText, shapedIcon, feature) { - var layout = this.layer.layout; - - var glyphSize = 24; - - var fontScale = this.adjustedTextSize / glyphSize, - textMaxSize = this.adjustedTextMaxSize !== undefined ? this.adjustedTextMaxSize : this.adjustedTextSize, - textBoxScale = this.tilePixelRatio * fontScale, - textMaxBoxScale = this.tilePixelRatio * textMaxSize / glyphSize, - iconBoxScale = this.tilePixelRatio * this.adjustedIconSize, - symbolMinDistance = this.tilePixelRatio * layout['symbol-spacing'], - avoidEdges = layout['symbol-avoid-edges'], - textPadding = layout['text-padding'] * this.tilePixelRatio, - iconPadding = layout['icon-padding'] * this.tilePixelRatio, - textMaxAngle = layout['text-max-angle'] / 180 * Math.PI, - textAlongLine = layout['text-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line', - iconAlongLine = layout['icon-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line', - mayOverlap = layout['text-allow-overlap'] || layout['icon-allow-overlap'] || - layout['text-ignore-placement'] || layout['icon-ignore-placement'], - isLine = layout['symbol-placement'] === 'line', - textRepeatDistance = symbolMinDistance / 2; - - if (isLine) { - lines = clipLine(lines, 0, 0, EXTENT, EXTENT); - } - - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - - // Calculate the anchor points around which you want to place labels - var anchors; - if (isLine) { - anchors = getAnchors( - line, - symbolMinDistance, - textMaxAngle, - shapedText, - shapedIcon, - glyphSize, - textMaxBoxScale, - this.overscaling, - EXTENT - ); - } else { - anchors = [ new Anchor(line[0].x, line[0].y, 0) ]; - } - - // For each potential label, create the placement features used to check for collisions, and the quads use for rendering. - for (var j = 0, len = anchors.length; j < len; j++) { - var anchor = anchors[j]; - - if (shapedText && isLine) { - if (this.anchorIsTooClose(shapedText.text, textRepeatDistance, anchor)) { - continue; - } - } - - var inside = !(anchor.x < 0 || anchor.x > EXTENT || anchor.y < 0 || anchor.y > EXTENT); - - if (avoidEdges && !inside) continue; - - // Normally symbol layers are drawn across tile boundaries. Only symbols - // with their anchors within the tile boundaries are added to the buffers - // to prevent symbols from being drawn twice. - // - // Symbols in layers with overlap are sorted in the y direction so that - // symbols lower on the canvas are drawn on top of symbols near the top. - // To preserve this order across tile boundaries these symbols can't - // be drawn across tile boundaries. Instead they need to be included in - // the buffers for both tiles and clipped to tile boundaries at draw time. - var addToBuffers = inside || mayOverlap; - this.addSymbolInstance(anchor, line, shapedText, shapedIcon, this.layer, - addToBuffers, this.symbolInstancesArray.length, this.collisionBoxArray, feature.index, this.sourceLayerIndex, this.index, - textBoxScale, textPadding, textAlongLine, - iconBoxScale, iconPadding, iconAlongLine, {zoom: this.zoom}, feature.properties); - } - } -}; - -SymbolBucket.prototype.anchorIsTooClose = function(text, repeatDistance, anchor) { - var compareText = this.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) { - // If it's within repeatDistance of one anchor, stop looking - return true; - } - } - } - // If anchor is not within repeatDistance of any other anchor, add to array - compareText[text].push(anchor); - return false; -}; - -SymbolBucket.prototype.placeFeatures = function(collisionTile, showCollisionBoxes) { - this.recalculateStyleLayers(); - - // Calculate which labels can be shown and when they can be shown and - // create the bufers used for rendering. - - this.createArrays(); - - var layout = this.layer.layout; - - var maxScale = collisionTile.maxScale; - - var textAlongLine = layout['text-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line'; - var iconAlongLine = layout['icon-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line'; - - var mayOverlap = layout['text-allow-overlap'] || layout['icon-allow-overlap'] || - layout['text-ignore-placement'] || layout['icon-ignore-placement']; - - // Sort symbols by their y position on the canvas so that the lower symbols - // are drawn on top of higher symbols. - // Don't sort symbols that won't overlap because it isn't necessary and - // because it causes more labels to pop in and out when rotating. - if (mayOverlap) { - // Only need the symbol instances from the current tile to sort, so convert those instances into an array - // of `StructType`s to enable sorting - var symbolInstancesStructTypeArray = this.symbolInstancesArray.toArray(this.symbolInstancesStartIndex, this.symbolInstancesEndIndex); - - var angle = collisionTile.angle; - - var sin = Math.sin(angle), - cos = Math.cos(angle); - - this.sortedSymbolInstances = symbolInstancesStructTypeArray.sort(function(a, b) { - var aRotated = (sin * a.anchorPointX + cos * a.anchorPointY) | 0; - var bRotated = (sin * b.anchorPointX + cos * b.anchorPointY) | 0; - return (aRotated - bRotated) || (b.index - a.index); - }); - } - - for (var p = this.symbolInstancesStartIndex; p < this.symbolInstancesEndIndex; p++) { - var symbolInstance = this.sortedSymbolInstances ? this.sortedSymbolInstances[p - this.symbolInstancesStartIndex] : this.symbolInstancesArray.get(p); - var textCollisionFeature = { - boxStartIndex: symbolInstance.textBoxStartIndex, - boxEndIndex: symbolInstance.textBoxEndIndex - }; - var iconCollisionFeature = { - boxStartIndex: symbolInstance.iconBoxStartIndex, - boxEndIndex: symbolInstance.iconBoxEndIndex - }; - - var hasText = !(symbolInstance.textBoxStartIndex === symbolInstance.textBoxEndIndex); - var hasIcon = !(symbolInstance.iconBoxStartIndex === symbolInstance.iconBoxEndIndex); - - var iconWithoutText = layout['text-optional'] || !hasText, - textWithoutIcon = layout['icon-optional'] || !hasIcon; - - - // Calculate the scales at which the text and icon can be placed without collision. - - var glyphScale = hasText ? - collisionTile.placeCollisionFeature(textCollisionFeature, - layout['text-allow-overlap'], layout['symbol-avoid-edges']) : - collisionTile.minScale; - - var iconScale = hasIcon ? - collisionTile.placeCollisionFeature(iconCollisionFeature, - layout['icon-allow-overlap'], layout['symbol-avoid-edges']) : - collisionTile.minScale; - - - // Combine the scales for icons and text. - - if (!iconWithoutText && !textWithoutIcon) { - iconScale = glyphScale = Math.max(iconScale, glyphScale); - } else if (!textWithoutIcon && glyphScale) { - glyphScale = Math.max(iconScale, glyphScale); - } else if (!iconWithoutText && iconScale) { - iconScale = Math.max(iconScale, glyphScale); - } - - - // Insert final placement into collision tree and add glyphs/icons to buffers - - if (hasText) { - collisionTile.insertCollisionFeature(textCollisionFeature, glyphScale, layout['text-ignore-placement']); - if (glyphScale <= maxScale) { - this.addSymbols('glyph', symbolInstance.glyphQuadStartIndex, symbolInstance.glyphQuadEndIndex, glyphScale, layout['text-keep-upright'], textAlongLine, collisionTile.angle); - } - } - - if (hasIcon) { - collisionTile.insertCollisionFeature(iconCollisionFeature, iconScale, layout['icon-ignore-placement']); - if (iconScale <= maxScale) { - this.addSymbols('icon', symbolInstance.iconQuadStartIndex, symbolInstance.iconQuadEndIndex, iconScale, layout['icon-keep-upright'], iconAlongLine, collisionTile.angle); - } - } - - } - - if (showCollisionBoxes) this.addToDebugBuffers(collisionTile); -}; - -SymbolBucket.prototype.addSymbols = function(programName, quadsStart, quadsEnd, scale, keepUpright, alongLine, placementAngle) { - - var group = this.prepareArrayGroup(programName, 4 * (quadsEnd - quadsStart)); - - var elementArray = group.elementArray; - var layoutVertexArray = group.layoutVertexArray; - - var zoom = this.zoom; - var placementZoom = Math.max(Math.log(scale) / Math.LN2 + zoom, 0); - - for (var k = quadsStart; k < quadsEnd; k++) { - - var symbol = this.symbolQuadsArray.get(k).SymbolQuad; - - // drop upside down versions of glyphs - var a = (symbol.anchorAngle + placementAngle + Math.PI) % (Math.PI * 2); - if (keepUpright && alongLine && (a <= Math.PI / 2 || a > Math.PI * 3 / 2)) continue; - - var tl = symbol.tl, - tr = symbol.tr, - bl = symbol.bl, - br = symbol.br, - tex = symbol.tex, - anchorPoint = symbol.anchorPoint, - - minZoom = Math.max(zoom + Math.log(symbol.minScale) / Math.LN2, placementZoom), - maxZoom = Math.min(zoom + Math.log(symbol.maxScale) / Math.LN2, 25); - - if (maxZoom <= minZoom) continue; - - // Lower min zoom so that while fading out the label it can be shown outside of collision-free zoom levels - if (minZoom === placementZoom) minZoom = 0; - - // Encode angle of glyph - var glyphAngle = Math.round((symbol.glyphAngle / (Math.PI * 2)) * 256); - - var index = addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle); - - elementArray.emplaceBack(index, index + 1, index + 2); - elementArray.emplaceBack(index + 1, index + 2, index + 3); - } - -}; - -SymbolBucket.prototype.updateIcons = function(icons) { - this.recalculateStyleLayers(); - var iconValue = this.layer.layout['icon-image']; - if (!iconValue) return; - - for (var i = 0; i < this.features.length; i++) { - var iconName = resolveTokens(this.features[i].properties, iconValue); - if (iconName) - icons[iconName] = true; - } -}; - -SymbolBucket.prototype.updateFont = function(stacks) { - this.recalculateStyleLayers(); - var fontName = this.layer.layout['text-font'], - stack = stacks[fontName] = stacks[fontName] || {}; - - this.textFeatures = resolveText(this.features, this.layer.layout, stack); -}; - -SymbolBucket.prototype.addToDebugBuffers = function(collisionTile) { - var group = this.prepareArrayGroup('collisionBox', 0); - var layoutVertexArray = group.layoutVertexArray; - var angle = -collisionTile.angle; - var yStretch = collisionTile.yStretch; - - for (var j = this.symbolInstancesStartIndex; j < this.symbolInstancesEndIndex; j++) { - var symbolInstance = this.symbolInstancesArray.get(j); - symbolInstance.textCollisionFeature = {boxStartIndex: symbolInstance.textBoxStartIndex, boxEndIndex: symbolInstance.textBoxEndIndex}; - symbolInstance.iconCollisionFeature = {boxStartIndex: symbolInstance.iconBoxStartIndex, boxEndIndex: symbolInstance.iconBoxEndIndex}; - - for (var i = 0; i < 2; i++) { - var feature = symbolInstance[i === 0 ? 'textCollisionFeature' : 'iconCollisionFeature']; - if (!feature) continue; - - for (var b = feature.boxStartIndex; b < feature.boxEndIndex; b++) { - var box = this.collisionBoxArray.get(b); - var anchorPoint = box.anchorPoint; - - var tl = new Point(box.x1, box.y1 * yStretch)._rotate(angle); - var tr = new Point(box.x2, box.y1 * yStretch)._rotate(angle); - var bl = new Point(box.x1, box.y2 * yStretch)._rotate(angle); - var br = new Point(box.x2, box.y2 * yStretch)._rotate(angle); - - var maxZoom = Math.max(0, Math.min(25, this.zoom + Math.log(box.maxScale) / Math.LN2)); - var placementZoom = Math.max(0, Math.min(25, this.zoom + Math.log(box.placementScale) / Math.LN2)); - - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tr, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tr, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, br, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, br, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, bl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, bl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tl, maxZoom, placementZoom); - } - } - } -}; - -SymbolBucket.prototype.addSymbolInstance = function(anchor, line, shapedText, shapedIcon, layer, addToBuffers, index, collisionBoxArray, featureIndex, sourceLayerIndex, bucketIndex, - textBoxScale, textPadding, textAlongLine, - iconBoxScale, iconPadding, iconAlongLine, globalProperties, featureProperties) { - - var glyphQuadStartIndex, glyphQuadEndIndex, iconQuadStartIndex, iconQuadEndIndex, textCollisionFeature, iconCollisionFeature, glyphQuads, iconQuads; - if (shapedText) { - glyphQuads = addToBuffers ? getGlyphQuads(anchor, shapedText, textBoxScale, line, layer, textAlongLine) : []; - textCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedText, textBoxScale, textPadding, textAlongLine, false); - } - - glyphQuadStartIndex = this.symbolQuadsArray.length; - if (glyphQuads && glyphQuads.length) { - for (var i = 0; i < glyphQuads.length; i++) { - this.addSymbolQuad(glyphQuads[i]); - } - } - glyphQuadEndIndex = this.symbolQuadsArray.length; - - var textBoxStartIndex = textCollisionFeature ? textCollisionFeature.boxStartIndex : this.collisionBoxArray.length; - var textBoxEndIndex = textCollisionFeature ? textCollisionFeature.boxEndIndex : this.collisionBoxArray.length; - - if (shapedIcon) { - iconQuads = addToBuffers ? getIconQuads(anchor, shapedIcon, iconBoxScale, line, layer, iconAlongLine, shapedText, globalProperties, featureProperties) : []; - iconCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, iconAlongLine, true); - } - - iconQuadStartIndex = this.symbolQuadsArray.length; - if (iconQuads && iconQuads.length === 1) { - this.addSymbolQuad(iconQuads[0]); - } - iconQuadEndIndex = this.symbolQuadsArray.length; - - var iconBoxStartIndex = iconCollisionFeature ? iconCollisionFeature.boxStartIndex : this.collisionBoxArray.length; - var iconBoxEndIndex = iconCollisionFeature ? iconCollisionFeature.boxEndIndex : this.collisionBoxArray.length; - if (iconQuadEndIndex > SymbolBucket.MAX_QUADS) util.warnOnce("Too many symbols being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"); - if (glyphQuadEndIndex > SymbolBucket.MAX_QUADS) util.warnOnce("Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"); - - return this.symbolInstancesArray.emplaceBack( - textBoxStartIndex, - textBoxEndIndex, - iconBoxStartIndex, - iconBoxEndIndex, - glyphQuadStartIndex, - glyphQuadEndIndex, - iconQuadStartIndex, - iconQuadEndIndex, - anchor.x, - anchor.y, - index); -}; - -SymbolBucket.prototype.addSymbolQuad = function(symbolQuad) { - return this.symbolQuadsArray.emplaceBack( - // anchorPoints - symbolQuad.anchorPoint.x, - symbolQuad.anchorPoint.y, - // corners - symbolQuad.tl.x, - symbolQuad.tl.y, - symbolQuad.tr.x, - symbolQuad.tr.y, - symbolQuad.bl.x, - symbolQuad.bl.y, - symbolQuad.br.x, - symbolQuad.br.y, - // texture - symbolQuad.tex.h, - symbolQuad.tex.w, - symbolQuad.tex.x, - symbolQuad.tex.y, - //angle - symbolQuad.anchorAngle, - symbolQuad.glyphAngle, - // scales - symbolQuad.maxScale, - symbolQuad.minScale); -}; - -},{"../../symbol/anchor":41,"../../symbol/clip_line":43,"../../symbol/collision_feature":45,"../../symbol/get_anchors":47,"../../symbol/mergelines":48,"../../symbol/quads":49,"../../symbol/resolve_text":50,"../../symbol/shaping":51,"../../util/token":61,"../../util/util":62,"../bucket":25,"../load_geometry":33,"point-geometry":66}],30:[function(require,module,exports){ -'use strict'; - -module.exports = Buffer; - -/** - * The `Buffer` class turns a `StructArray` into a WebGL buffer. Each member of the StructArray's - * Struct type is converted to a WebGL atribute. - * - * @class Buffer - * @private - * @param {object} array A serialized StructArray. - * @param {object} arrayType A serialized StructArrayType. - * @param {BufferType} type - */ -function Buffer(array, arrayType, type) { - this.arrayBuffer = array.arrayBuffer; - this.length = array.length; - this.attributes = arrayType.members; - this.itemSize = arrayType.bytesPerElement; - this.type = type; - this.arrayType = arrayType; -} - -/** - * Bind this buffer to a WebGL context. - * @private - * @param gl The WebGL context - */ -Buffer.prototype.bind = function(gl) { - var type = gl[this.type]; - - if (!this.buffer) { - this.buffer = gl.createBuffer(); - gl.bindBuffer(type, this.buffer); - gl.bufferData(type, this.arrayBuffer, gl.STATIC_DRAW); - - // dump array buffer once it's bound to gl - this.arrayBuffer = null; - } else { - gl.bindBuffer(type, this.buffer); - } -}; - -/** - * @enum {string} AttributeType - * @private - * @readonly - */ -var AttributeType = { - Int8: 'BYTE', - Uint8: 'UNSIGNED_BYTE', - Int16: 'SHORT', - Uint16: 'UNSIGNED_SHORT' -}; - -/** - * Set the attribute pointers in a WebGL context - * @private - * @param gl The WebGL context - * @param program The active WebGL program - */ -Buffer.prototype.setVertexAttribPointers = function(gl, program) { - for (var j = 0; j < this.attributes.length; j++) { - var member = this.attributes[j]; - var attribIndex = program[member.name]; - - if (attribIndex !== undefined) { - gl.vertexAttribPointer( - attribIndex, - member.components, - gl[AttributeType[member.type]], - false, - this.arrayType.bytesPerElement, - member.offset - ); - } - } -}; - -/** - * Destroy the GL buffer bound to the given WebGL context - * @private - * @param gl The WebGL context - */ -Buffer.prototype.destroy = function(gl) { - if (this.buffer) { - gl.deleteBuffer(this.buffer); - } -}; - -/** - * @enum {string} BufferType - * @private - * @readonly - */ -Buffer.BufferType = { - VERTEX: 'ARRAY_BUFFER', - ELEMENT: 'ELEMENT_ARRAY_BUFFER' -}; - -},{}],31:[function(require,module,exports){ -'use strict'; - -var util = require('../util/util'); -var Buffer = require('./buffer'); -var VertexArrayObject = require('../render/vertex_array_object'); - -module.exports = BufferGroup; - -function BufferGroup(arrayGroup, arrayTypes) { - this.layoutVertexBuffer = new Buffer(arrayGroup.layoutVertexArray, - arrayTypes.layoutVertexArrayType, Buffer.BufferType.VERTEX); - - if (arrayGroup.elementArray) { - this.elementBuffer = new Buffer(arrayGroup.elementArray, - arrayTypes.elementArrayType, Buffer.BufferType.ELEMENT); - } - - var vaos = this.vaos = {}; - var secondVaos; - - if (arrayGroup.elementArray2) { - this.elementBuffer2 = new Buffer(arrayGroup.elementArray2, - arrayTypes.elementArrayType2, Buffer.BufferType.ELEMENT); - secondVaos = this.secondVaos = {}; - } - - this.paintVertexBuffers = util.mapObject(arrayGroup.paintVertexArrays, function(array, name) { - vaos[name] = new VertexArrayObject(); - if (arrayGroup.elementArray2) { - secondVaos[name] = new VertexArrayObject(); - } - return new Buffer(array, arrayTypes.paintVertexArrayTypes[name], Buffer.BufferType.VERTEX); - }); -} - -BufferGroup.prototype.destroy = function(gl) { - this.layoutVertexBuffer.destroy(gl); - if (this.elementBuffer) { - this.elementBuffer.destroy(gl); - } - if (this.elementBuffer2) { - this.elementBuffer2.destroy(gl); - } - for (var n in this.paintVertexBuffers) { - this.paintVertexBuffers[n].destroy(gl); - } - for (var j in this.vaos) { - this.vaos[j].destroy(gl); - } - for (var k in this.secondVaos) { - this.secondVaos[k].destroy(gl); - } -}; - -},{"../render/vertex_array_object":35,"../util/util":62,"./buffer":30}],32:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); -var loadGeometry = require('./load_geometry'); -var EXTENT = require('./bucket').EXTENT; -var featureFilter = require('feature-filter'); -var StructArrayType = require('../util/struct_array'); -var Grid = require('grid-index'); -var DictionaryCoder = require('../util/dictionary_coder'); -var vt = require('vector-tile'); -var Protobuf = require('pbf'); -var GeoJSONFeature = require('../util/vectortile_to_geojson'); -var arraysIntersect = require('../util/util').arraysIntersect; - -var intersection = require('../util/intersection_tests'); -var multiPolygonIntersectsBufferedMultiPoint = intersection.multiPolygonIntersectsBufferedMultiPoint; -var multiPolygonIntersectsMultiPolygon = intersection.multiPolygonIntersectsMultiPolygon; -var multiPolygonIntersectsBufferedMultiLine = intersection.multiPolygonIntersectsBufferedMultiLine; - - -var FeatureIndexArray = new StructArrayType({ - members: [ - // the index of the feature in the original vectortile - { type: 'Uint32', name: 'featureIndex' }, - // the source layer the feature appears in - { type: 'Uint16', name: 'sourceLayerIndex' }, - // the bucket the feature appears in - { type: 'Uint16', name: 'bucketIndex' } - ]}); - -module.exports = FeatureIndex; - -function FeatureIndex(coord, overscaling, collisionTile) { - if (coord.grid) { - var serialized = coord; - var rawTileData = overscaling; - coord = serialized.coord; - overscaling = serialized.overscaling; - this.grid = new Grid(serialized.grid); - this.featureIndexArray = new FeatureIndexArray(serialized.featureIndexArray); - this.rawTileData = rawTileData; - this.bucketLayerIDs = serialized.bucketLayerIDs; - } else { - this.grid = new Grid(EXTENT, 16, 0); - this.featureIndexArray = new FeatureIndexArray(); - } - this.coord = coord; - this.overscaling = overscaling; - this.x = coord.x; - this.y = coord.y; - this.z = coord.z - Math.log(overscaling) / Math.LN2; - this.setCollisionTile(collisionTile); -} - -FeatureIndex.prototype.insert = function(feature, featureIndex, sourceLayerIndex, bucketIndex) { - var key = this.featureIndexArray.length; - this.featureIndexArray.emplaceBack(featureIndex, sourceLayerIndex, bucketIndex); - var geometry = loadGeometry(feature); - - 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); - } - - this.grid.insert(key, bbox[0], bbox[1], bbox[2], bbox[3]); - } -}; - -FeatureIndex.prototype.setCollisionTile = function(collisionTile) { - this.collisionTile = collisionTile; -}; - -FeatureIndex.prototype.serialize = function() { - var data = { - coord: this.coord, - overscaling: this.overscaling, - grid: this.grid.toArrayBuffer(), - featureIndexArray: this.featureIndexArray.serialize(), - bucketLayerIDs: this.bucketLayerIDs - }; - return { - data: data, - transferables: [data.grid, data.featureIndexArray.arrayBuffer] - }; -}; - -function translateDistance(translate) { - return Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]); -} - -// Finds features in this tile at a particular position. -FeatureIndex.prototype.query = function(args, styleLayers) { - if (!this.vtLayers) { - this.vtLayers = new vt.VectorTile(new Protobuf(new Uint8Array(this.rawTileData))).layers; - this.sourceLayerCoder = new DictionaryCoder(this.vtLayers ? Object.keys(this.vtLayers).sort() : ['_geojsonTileLayer']); - } - - var result = {}; - - var params = args.params || {}, - pixelsToTileUnits = EXTENT / args.tileSize / args.scale, - filter = featureFilter(params.filter); - - // Features are indexed their original geometries. The rendered geometries may - // be buffered, translated or offset. Figure out how much the search radius needs to be - // expanded by to include these features. - var additionalRadius = 0; - for (var id in styleLayers) { - var styleLayer = styleLayers[id]; - var paint = styleLayer.paint; - - var styleLayerDistance = 0; - if (styleLayer.type === 'line') { - styleLayerDistance = getLineWidth(paint) / 2 + Math.abs(paint['line-offset']) + translateDistance(paint['line-translate']); - } else if (styleLayer.type === 'fill') { - styleLayerDistance = translateDistance(paint['fill-translate']); - } else if (styleLayer.type === 'circle') { - styleLayerDistance = paint['circle-radius'] + translateDistance(paint['circle-translate']); - } - additionalRadius = Math.max(additionalRadius, styleLayerDistance * pixelsToTileUnits); - } - - var queryGeometry = args.queryGeometry.map(function(q) { - return q.map(function(p) { - return new Point(p.x, p.y); - }); - }); - - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - for (var i = 0; i < queryGeometry.length; i++) { - var ring = queryGeometry[i]; - for (var k = 0; k < ring.length; k++) { - var p = ring[k]; - 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 matching = this.grid.query(minX - additionalRadius, minY - additionalRadius, maxX + additionalRadius, maxY + additionalRadius); - matching.sort(topDownFeatureComparator); - this.filterMatching(result, matching, this.featureIndexArray, queryGeometry, filter, params.layers, styleLayers, args.bearing, pixelsToTileUnits); - - var matchingSymbols = this.collisionTile.queryRenderedSymbols(minX, minY, maxX, maxY, args.scale); - matchingSymbols.sort(); - this.filterMatching(result, matchingSymbols, this.collisionTile.collisionBoxArray, queryGeometry, filter, params.layers, styleLayers, args.bearing, pixelsToTileUnits); - - return result; -}; - -function topDownFeatureComparator(a, b) { - return b - a; -} - -function getLineWidth(paint) { - if (paint['line-gap-width'] > 0) { - return paint['line-gap-width'] + 2 * paint['line-width']; - } else { - return paint['line-width']; - } -} - -FeatureIndex.prototype.filterMatching = function(result, matching, array, queryGeometry, filter, filterLayerIDs, styleLayers, bearing, pixelsToTileUnits) { - var previousIndex; - for (var k = 0; k < matching.length; k++) { - var index = matching[k]; - - // don't check the same feature more than once - if (index === previousIndex) continue; - previousIndex = index; - - var match = array.get(index); - - var layerIDs = this.bucketLayerIDs[match.bucketIndex]; - if (filterLayerIDs && !arraysIntersect(filterLayerIDs, layerIDs)) continue; - - var sourceLayerName = this.sourceLayerCoder.decode(match.sourceLayerIndex); - var sourceLayer = this.vtLayers[sourceLayerName]; - var feature = sourceLayer.feature(match.featureIndex); - - if (!filter(feature)) continue; - - var geometry = null; - - 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 translatedPolygon; - if (styleLayer.type !== 'symbol') { - // all symbols already match the style - - if (!geometry) geometry = loadGeometry(feature); - - var paint = styleLayer.paint; - - if (styleLayer.type === 'line') { - translatedPolygon = translate(queryGeometry, - paint['line-translate'], paint['line-translate-anchor'], - bearing, pixelsToTileUnits); - var halfWidth = getLineWidth(paint) / 2 * pixelsToTileUnits; - if (paint['line-offset']) { - geometry = offsetLine(geometry, paint['line-offset'] * pixelsToTileUnits); - } - if (!multiPolygonIntersectsBufferedMultiLine(translatedPolygon, geometry, halfWidth)) continue; - - } else if (styleLayer.type === 'fill') { - translatedPolygon = translate(queryGeometry, - paint['fill-translate'], paint['fill-translate-anchor'], - bearing, pixelsToTileUnits); - if (!multiPolygonIntersectsMultiPolygon(translatedPolygon, geometry)) continue; - - } else if (styleLayer.type === 'circle') { - translatedPolygon = translate(queryGeometry, - paint['circle-translate'], paint['circle-translate-anchor'], - bearing, pixelsToTileUnits); - var circleRadius = paint['circle-radius'] * pixelsToTileUnits; - if (!multiPolygonIntersectsBufferedMultiPoint(translatedPolygon, geometry, circleRadius)) continue; - } - } - - var geojsonFeature = new GeoJSONFeature(feature, this.z, this.x, this.y); - geojsonFeature.layer = styleLayer.serialize({ - includeRefProperties: true - }); - var layerResult = result[layerID]; - if (layerResult === undefined) { - layerResult = result[layerID] = []; - } - layerResult.push(geojsonFeature); - } - } -}; - -function translate(queryGeometry, translate, translateAnchor, bearing, pixelsToTileUnits) { - if (!translate[0] && !translate[1]) { - return queryGeometry; - } - - translate = Point.convert(translate); - - if (translateAnchor === "viewport") { - translate._rotate(-bearing); - } - - var translated = []; - for (var i = 0; i < queryGeometry.length; i++) { - var ring = queryGeometry[i]; - var translatedRing = []; - for (var k = 0; k < ring.length; k++) { - translatedRing.push(ring[k].sub(translate._mult(pixelsToTileUnits))); - } - translated.push(translatedRing); - } - return translated; -} - -function offsetLine(rings, offset) { - var newRings = []; - var zero = new Point(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; -} - -},{"../util/dictionary_coder":56,"../util/intersection_tests":59,"../util/struct_array":60,"../util/util":62,"../util/vectortile_to_geojson":63,"./bucket":25,"./load_geometry":33,"feature-filter":7,"grid-index":18,"pbf":65,"point-geometry":66,"vector-tile":72}],33:[function(require,module,exports){ -'use strict'; - -var util = require('../util/util'); -var EXTENT = require('./bucket').EXTENT; -var assert = require('assert'); - - -// These bounds define the minimum and maximum supported coordinate values. -// While visible coordinates are within [0, EXTENT], tiles may theoretically -// contain cordinates within [-Infinity, Infinity]. Our range is limited by the -// number of bits used to represent the coordinate. -function createBounds(bits) { - return { - min: -1 * Math.pow(2, bits - 1), - max: Math.pow(2, bits - 1) - 1 - }; -} - -var boundsLookup = { - 15: createBounds(15), - 16: createBounds(16) -}; - -/** - * Loads a geometry from a VectorTileFeature and scales it to the common extent - * used internally. - * @param {VectorTileFeature} feature - * @param {number} [bits=16] The number of signed integer bits available to store - * each coordinate. A warning will be issued if any coordinate will not fits - * in the specified number of bits. - * @private - */ -module.exports = function loadGeometry(feature, bits) { - var bounds = boundsLookup[bits || 16]; - assert(bounds); - - 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]; - // round here because mapbox-gl-native uses integers to represent - // points and we need to do the same to avoid renering differences. - 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) { - util.warnOnce('Geometry exceeds allowed extent, reduce your vector tile buffer size'); - } - } - } - return geometry; -}; - -},{"../util/util":62,"./bucket":25,"assert":1}],34:[function(require,module,exports){ -'use strict'; - -module.exports = Coordinate; - -/** - * A coordinate is a column, row, zoom combination, often used - * as the data component of a tile. - * - * @param {number} column - * @param {number} row - * @param {number} zoom - * @private - */ -function Coordinate(column, row, zoom) { - this.column = column; - this.row = row; - this.zoom = zoom; -} - -Coordinate.prototype = { - - /** - * Create a clone of this coordinate that can be mutated without - * changing the original coordinate - * - * @returns {Coordinate} clone - * @private - * var coord = new Coordinate(0, 0, 0); - * var c2 = coord.clone(); - * // since coord is cloned, modifying a property of c2 does - * // not modify it. - * c2.zoom = 2; - */ - clone: function() { - return new Coordinate(this.column, this.row, this.zoom); - }, - - /** - * Zoom this coordinate to a given zoom level. This returns a new - * coordinate object, not mutating the old one. - * - * @param {number} zoom - * @returns {Coordinate} zoomed coordinate - * @private - * @example - * var coord = new Coordinate(0, 0, 0); - * var c2 = coord.zoomTo(1); - * c2 // equals new Coordinate(0, 0, 1); - */ - zoomTo: function(zoom) { return this.clone()._zoomTo(zoom); }, - - /** - * Subtract the column and row values of this coordinate from those - * of another coordinate. The other coordinat will be zoomed to the - * same level as `this` before the subtraction occurs - * - * @param {Coordinate} c other coordinate - * @returns {Coordinate} result - * @private - */ - sub: function(c) { return this.clone()._sub(c); }, - - _zoomTo: function(zoom) { - var scale = Math.pow(2, zoom - this.zoom); - this.column *= scale; - this.row *= scale; - this.zoom = zoom; - return this; - }, - - _sub: function(c) { - c = c.zoomTo(this.zoom); - this.column -= c.column; - this.row -= c.row; - return this; - } -}; - -},{}],35:[function(require,module,exports){ -'use strict'; - -var assert = require('assert'); - -module.exports = VertexArrayObject; - -function VertexArrayObject() { - this.boundProgram = null; - this.boundVertexBuffer = null; - this.boundVertexBuffer2 = null; - this.boundElementBuffer = null; - this.vao = null; -} - -VertexArrayObject.prototype.bind = function(gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2) { - - if (gl.extVertexArrayObject === undefined) { - gl.extVertexArrayObject = gl.getExtension("OES_vertex_array_object"); - } - - var isFreshBindRequired = ( - !this.vao || - this.boundProgram !== program || - this.boundVertexBuffer !== layoutVertexBuffer || - this.boundVertexBuffer2 !== vertexBuffer2 || - this.boundElementBuffer !== elementBuffer - ); - - if (!gl.extVertexArrayObject || isFreshBindRequired) { - this.freshBind(gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2); - } else { - gl.extVertexArrayObject.bindVertexArrayOES(this.vao); - } -}; - -VertexArrayObject.prototype.freshBind = function(gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2) { - var numPrevAttributes; - var numNextAttributes = program.numAttributes; - - if (gl.extVertexArrayObject) { - if (this.vao) this.destroy(gl); - this.vao = gl.extVertexArrayObject.createVertexArrayOES(); - gl.extVertexArrayObject.bindVertexArrayOES(this.vao); - numPrevAttributes = 0; - - // store the arguments so that we can verify them when the vao is bound again - this.boundProgram = program; - this.boundVertexBuffer = layoutVertexBuffer; - this.boundVertexBuffer2 = vertexBuffer2; - this.boundElementBuffer = elementBuffer; - - } else { - numPrevAttributes = gl.currentNumAttributes || 0; - - // Disable all attributes from the previous program that aren't used in - // the new program. Note: attribute indices are *not* program specific! - for (var i = numNextAttributes; i < numPrevAttributes; i++) { - // WebGL breaks if you disable attribute 0. - // http://stackoverflow.com/questions/20305231 - assert(i !== 0); - gl.disableVertexAttribArray(i); - } - } - - // Enable all attributes for the new program. - for (var j = numPrevAttributes; j < numNextAttributes; j++) { - gl.enableVertexAttribArray(j); - } - - layoutVertexBuffer.bind(gl); - layoutVertexBuffer.setVertexAttribPointers(gl, program); - if (vertexBuffer2) { - vertexBuffer2.bind(gl); - vertexBuffer2.setVertexAttribPointers(gl, program); - } - if (elementBuffer) { - elementBuffer.bind(gl); - } - - gl.currentNumAttributes = numNextAttributes; -}; - -VertexArrayObject.prototype.unbind = function(gl) { - var ext = gl.extVertexArrayObject; - if (ext) { - ext.bindVertexArrayOES(null); - } -}; - -VertexArrayObject.prototype.destroy = function(gl) { - var ext = gl.extVertexArrayObject; - if (ext && this.vao) { - ext.deleteVertexArrayOES(this.vao); - this.vao = null; - } -}; - -},{"assert":1}],36:[function(require,module,exports){ -'use strict'; - -var Evented = require('../util/evented'); -var util = require('../util/util'); -var urlResolve = require('resolve-url'); -var EXTENT = require('../data/bucket').EXTENT; - -module.exports = GeoJSONSource; - -/** - * A source containing GeoJSON. - * - * @class GeoJSONSource - * @param {Object} [options] - * @param {Object|string} [options.data] A GeoJSON data object or a URL to one. The latter is preferable in the case of large GeoJSON objects. - * @param {number} [options.maxzoom=18] The maximum zoom level at which to preserve detail (1-20). - * @param {number} [options.buffer=128] The tile buffer, measured in pixels. The buffer extends each - * tile's data just past its visible edges, helping to ensure seamless rendering across tile boundaries. - * The default value, 128, is a safe value for label layers, preventing text clipping at boundaries. - * You can read more about buffers and clipping in the - * [Mapbox Vector Tile Specification](https://www.mapbox.com/vector-tiles/specification/#clipping). - * @param {number} [options.tolerance=0.375] The simplification tolerance, measured in pixels. - * This value is passed into a modified [Ramer–Douglas–Peucker algorithm](https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm) - * to simplify (i.e. reduce the number of points) in curves. Higher values result in greater simplification. - * @param {boolean} [options.cluster] If `true`, a collection of point features will be clustered into groups, - * according to `options.clusterRadius`. - * @param {number} [options.clusterRadius=50] The radius of each cluster when clustering points, measured in pixels. - * @param {number} [options.clusterMaxZoom] The maximum zoom level to cluster points in. By default, this value is - * one zoom level less than the map's `maxzoom`, so that at the highest zoom level features are not clustered. - * - * @example - * map.addSource('some id', { - * data: 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_ports.geojson' - * }); - * - * @example - * map.addSource('some id', { - * type: 'geojson', - * data: { - * "type": "FeatureCollection", - * "features": [{ - * "type": "Feature", - * "geometry": { - * "type": "Point", - * "coordinates": [ - * -76.53063297271729, - * 39.18174077994108 - * ] - * } - * }] - * } - * }); - * - * @example - * map.getSource('some id').setData({ - * data: { - * "type": "FeatureCollection", - * "features": [{ - * "type": "Feature", - * "properties": { "name": "Null Island" }, - * "geometry": { - * "type": "Point", - * "coordinates": [ 0, 0 ] - * } - * }] - * } - * }); - */ -function GeoJSONSource(id, options, dispatcher) { - options = options || {}; - this.id = id; - this.dispatcher = dispatcher; - - this._data = options.data; - - if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom; - if (options.type) this.type = options.type; - - var scale = EXTENT / this.tileSize; - - // sent to the worker, along with `url: ...` or `data: literal geojson`, - // so that it can load/parse/index the geojson data - // extending with `options.workerOptions` helps to make it easy for - // third-party sources to hack/reuse GeoJSONSource. - this.workerOptions = util.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: EXTENT, - maxZoom: this.maxzoom - }, - superclusterOptions: { - maxZoom: Math.min(options.clusterMaxZoom, this.maxzoom - 1) || (this.maxzoom - 1), - extent: EXTENT, - radius: (options.clusterRadius || 50) * scale, - log: false - } - }, options.workerOptions); - - this._updateWorkerData(function done(err) { - if (err) { - this.fire('error', {error: err}); - return; - } - this.fire('load'); - }.bind(this)); -} - -GeoJSONSource.prototype = util.inherit(Evented, /** @lends GeoJSONSource.prototype */ { - // `type` is a property rather than a constant to make it easy for 3rd - // parties to use GeoJSONSource to build their own source types. - type: 'geojson', - minzoom: 0, - maxzoom: 18, - tileSize: 512, - isTileClipped: true, - reparseOverscaled: true, - - onAdd: function (map) { - this.map = map; - }, - - /** - * Sets the GeoJSON data and re-renders the map. - * - * @param {Object|string} data A GeoJSON data object or a URL to one. The latter is preferable in the case of large GeoJSON files. - * @returns {GeoJSONSource} this - */ - setData: function(data) { - this._data = data; - - this._updateWorkerData(function (err) { - if (err) { - return this.fire('error', { error: err }); - } - this.fire('change'); - }.bind(this)); - - return this; - }, - - /* - * Responsible for invoking WorkerSource's geojson.loadData target, which - * handles loading the geojson data and preparing to serve it up as tiles, - * using geojson-vt or supercluster as appropriate. - */ - _updateWorkerData: function(callback) { - var options = util.extend({}, this.workerOptions); - var data = this._data; - if (typeof data === 'string') { - options.url = typeof window != 'undefined' ? urlResolve(window.location.href, data) : data; - } else { - options.data = JSON.stringify(data); - } - - // target {this.type}.loadData rather than literally geojson.loadData, - // so that other geojson-like source types can easily reuse this - // implementation - this.workerID = this.dispatcher.send(this.type + '.loadData', options, function(err) { - this._loaded = true; - callback(err); - - }.bind(this)); - }, - - loadTile: function (tile, callback) { - var overscaling = tile.coord.z > this.maxzoom ? Math.pow(2, tile.coord.z - this.maxzoom) : 1; - var params = { - type: this.type, - uid: tile.uid, - coord: tile.coord, - zoom: tile.coord.z, - maxZoom: this.maxzoom, - tileSize: this.tileSize, - source: this.id, - overscaling: overscaling, - angle: this.map.transform.angle, - pitch: this.map.transform.pitch, - showCollisionBoxes: this.map.showCollisionBoxes - }; - - tile.workerID = this.dispatcher.send('load tile', params, function(err, data) { - - tile.unloadVectorData(this.map.painter); - - if (tile.aborted) - return; - - if (err) { - return callback(err); - } - - tile.loadVectorData(data, this.map.style); - - if (tile.redoWhenDone) { - tile.redoWhenDone = false; - tile.redoPlacement(this); - } - - return callback(null); - - }.bind(this), this.workerID); - }, - - abortTile: function(tile) { - tile.aborted = true; - }, - - unloadTile: function(tile) { - tile.unloadVectorData(this.map.painter); - this.dispatcher.send('remove tile', { uid: tile.uid, source: this.id }, function() {}, tile.workerID); - }, - - serialize: function() { - return { - type: this.type, - data: this._data - }; - } -}); - -},{"../data/bucket":25,"../util/evented":57,"../util/util":62,"resolve-url":68}],37:[function(require,module,exports){ -'use strict'; - -var util = require('../util/util'); -var ajax = require('../util/ajax'); -var rewind = require('geojson-rewind'); -var GeoJSONWrapper = require('./geojson_wrapper'); -var vtpbf = require('vt-pbf'); -var supercluster = require('supercluster'); -var geojsonvt = require('geojson-vt'); - -var VectorTileWorkerSource = require('./vector_tile_worker_source'); - -module.exports = GeoJSONWorkerSource; - -/** - * The {@link WorkerSource} implementation that supports {@link GeoJSONSource}. - * This class is designed to be easily reused to support custom source types - * for data formats that can be parsed/converted into an in-memory GeoJSON - * representation. To do so, create it with - * `new GeoJSONWorkerSource(actor, styleLayers, customLoadGeoJSONFunction)`. For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson). - * - * @class GeoJSONWorkerSource - * @private - * @param {Function} [loadGeoJSON] Optional method for custom loading/parsing of GeoJSON based on parameters passed from the main-thread Source. See {@link GeoJSONWorkerSource#loadGeoJSON}. - */ -function GeoJSONWorkerSource (actor, styleLayers, loadGeoJSON) { - if (loadGeoJSON) { this.loadGeoJSON = loadGeoJSON; } - VectorTileWorkerSource.call(this, actor, styleLayers); -} - -GeoJSONWorkerSource.prototype = util.inherit(VectorTileWorkerSource, /** @lends GeoJSONWorkerSource.prototype */ { - // object mapping source ids to geojson-vt-like tile indexes - _geoJSONIndexes: {}, - - /** - * See {@link VectorTileWorkerSource#loadTile}. - */ - loadVectorData: function (params, callback) { - var source = params.source, - coord = params.coord; - - if (!this._geoJSONIndexes[source]) return callback(null, null); // we couldn't load the file - - var geoJSONTile = this._geoJSONIndexes[source].getTile(Math.min(coord.z, params.maxZoom), coord.x, coord.y); - if (geoJSONTile) { - var geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features); - geojsonWrapper.name = '_geojsonTileLayer'; - var pbf = vtpbf({ layers: { '_geojsonTileLayer': geojsonWrapper }}); - if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) { - // Compatibility with node Buffer (https://github.com/mapbox/pbf/issues/35) - pbf = new Uint8Array(pbf); - } - callback(null, { tile: geojsonWrapper, rawTileData: pbf.buffer }); - // tile.parse(geojsonWrapper, this.layerFamilies, this.actor, rawTileData, callback); - } else { - return callback(null, null); // nothing in the given tile - } - }, - - /** - * Fetches (if appropriate), parses, and index geojson data into tiles. This - * preparatory method must be called before {@link GeoJSONWorkerSource#loadTile} - * can correctly serve up tiles. - * - * Defers to {@link GeoJSONWorkerSource#loadGeoJSON} for the fetching/parsing, - * expecting `callback(error, data)` to be called with either an error or a - * parsed GeoJSON object. - * @param {object} params - * @param {string} params.source The id of the source. - * @param {Function} callback - */ - loadData: function (params, callback) { - var handleData = function(err, data) { - if (err) return callback(err); - if (typeof data != 'object') { - return callback(new Error("Input data is not a valid GeoJSON object.")); - } - rewind(data, true); - this._indexData(data, params, function (err, indexed) { - if (err) { return callback(err); } - this._geoJSONIndexes[params.source] = indexed; - callback(null); - }.bind(this)); - }.bind(this); - - this.loadGeoJSON(params, handleData); - }, - - /** - * Fetch and parse GeoJSON according to the given params. Calls `callback` - * with `(err, data)`, where `data` is a parsed GeoJSON object. - * - * GeoJSON is loaded and parsed from `params.url` if it exists, or else - * expected as a literal (string or object) `params.data`. - * - * @param {object} params - * @param {string} [params.url] A URL to the remote GeoJSON data. - * @param {object} [params.data] Literal GeoJSON data. Must be provided if `params.url` is not. - */ - loadGeoJSON: function (params, callback) { - // Because of same origin issues, urls must either include an explicit - // origin or absolute path. - // ie: /foo/bar.json or http://example.com/bar.json - // but not ../foo/bar.json - if (params.url) { - ajax.getJSON(params.url, callback); - } else if (typeof params.data === 'string') { - try { - return callback(null, JSON.parse(params.data)); - } catch (e) { - return callback(new Error("Input data is not a valid GeoJSON object.")); - } - } else { - return callback(new Error("Input data is not a valid GeoJSON object.")); - } - }, - - /** - * Index the data using either geojson-vt or supercluster - * @param {GeoJSON} data - * @param {object} params forwarded from loadTile. - * @param {callback} (err, indexedData) - * @private - */ - _indexData: function (data, params, callback) { - try { - if (params.cluster) { - callback(null, supercluster(params.superclusterOptions).load(data.features)); - } else { - callback(null, geojsonvt(data, params.geojsonVtOptions)); - } - } catch (err) { - return callback(err); - } - } -}); - -},{"../util/ajax":54,"../util/util":62,"./geojson_wrapper":38,"./vector_tile_worker_source":39,"geojson-rewind":9,"geojson-vt":13,"supercluster":69,"vt-pbf":76}],38:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); -var VectorTileFeature = require('vector-tile').VectorTileFeature; -var EXTENT = require('../data/bucket').EXTENT; - -module.exports = GeoJSONWrapper; - -// conform to vectortile api -function GeoJSONWrapper(features) { - this.features = features; - this.length = features.length; - this.extent = EXTENT; -} - -GeoJSONWrapper.prototype.feature = function(i) { - return new FeatureWrapper(this.features[i]); -}; - -function FeatureWrapper(feature) { - this.type = feature.type; - if (feature.type === 1) { - this.rawGeometry = []; - for (var i = 0; i < feature.geometry.length; i++) { - this.rawGeometry.push([feature.geometry[i]]); - } - } else { - this.rawGeometry = feature.geometry; - } - this.properties = feature.tags; - this.extent = EXTENT; -} - -FeatureWrapper.prototype.loadGeometry = function() { - var rings = this.rawGeometry; - this.geometry = []; - - for (var i = 0; i < rings.length; i++) { - var ring = rings[i], - newRing = []; - for (var j = 0; j < ring.length; j++) { - newRing.push(new Point(ring[j][0], ring[j][1])); - } - this.geometry.push(newRing); - } - return this.geometry; -}; - -FeatureWrapper.prototype.bbox = function() { - if (!this.geometry) this.loadGeometry(); - - var rings = this.geometry, - x1 = Infinity, - x2 = -Infinity, - y1 = Infinity, - 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.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON; - -},{"../data/bucket":25,"point-geometry":66,"vector-tile":72}],39:[function(require,module,exports){ -'use strict'; -var ajax = require('../util/ajax'); -var vt = require('vector-tile'); -var Protobuf = require('pbf'); -var WorkerTile = require('./worker_tile'); - -module.exports = VectorTileWorkerSource; - -/** - * The {@link WorkerSource} implementation that supports {@link VectorTileSource}. - * This class is designed to be easily reused to support custom source types - * for data formats that can be parsed/converted into an in-memory VectorTile - * representation. To do so, create it with - * `new VectorTileWorkerSource(actor, styleLayers, customLoadVectorDataFunction)`. - * - * @class VectorTileWorkerSource - * @private - * @param {Function} [loadVectorData] Optional method for custom loading of a VectorTile object based on parameters passed from the main-thread Source. See {@link VectorTileWorkerSource#loadTile}. The default implementation simply loads the pbf at `params.url`. - */ -function VectorTileWorkerSource (actor, styleLayers, loadVectorData) { - this.actor = actor; - this.styleLayers = styleLayers; - - if (loadVectorData) { this.loadVectorData = loadVectorData; } - - this.loading = {}; - this.loaded = {}; -} - -VectorTileWorkerSource.prototype = { - /** - * Implements {@link WorkerSource#loadTile}. Delegates to {@link VectorTileWorkerSource#loadVectorData} (which by default expects a `params.url` property) for fetching and producing a VectorTile object. - * - * @param {object} params - * @param {string} params.source The id of the source for which we're loading this tile. - * @param {string} params.uid The UID for this tile. - * @param {TileCoord} params.coord - * @param {number} params.zoom - * @param {number} params.overscaling - * @param {number} params.angle - * @param {number} params.pitch - * @param {boolean} params.showCollisionBoxes - */ - loadTile: function(params, callback) { - var source = params.source, - uid = params.uid; - - if (!this.loading[source]) - this.loading[source] = {}; - - var tile = this.loading[source][uid] = new WorkerTile(params); - tile.abort = this.loadVectorData(params, done.bind(this)); - - function done(err, data) { - delete this.loading[source][uid]; - - if (err) return callback(err); - if (!data) return callback(null, null); - - tile.data = data.tile; - tile.parse(tile.data, this.styleLayers.getLayerFamilies(), this.actor, data.rawTileData, callback); - - this.loaded[source] = this.loaded[source] || {}; - this.loaded[source][uid] = tile; - } - }, - - /** - * Implements {@link WorkerSource#reloadTile}. - * - * @param {object} params - * @param {string} params.source The id of the source for which we're loading this tile. - * @param {string} params.uid The UID for this tile. - */ - reloadTile: function(params, callback) { - var loaded = this.loaded[params.source], - uid = params.uid; - if (loaded && loaded[uid]) { - var tile = loaded[uid]; - tile.parse(tile.data, this.styleLayers.getLayerFamilies(), this.actor, params.rawTileData, callback); - } - }, - - /** - * Implements {@link WorkerSource#abortTile}. - * - * @param {object} params - * @param {string} params.source The id of the source for which we're loading this tile. - * @param {string} params.uid The UID for this tile. - */ - abortTile: function(params) { - var loading = this.loading[params.source], - uid = params.uid; - if (loading && loading[uid] && loading[uid].abort) { - loading[uid].abort(); - delete loading[uid]; - } - }, - - /** - * Implements {@link WorkerSource#removeTile}. - * - * @param {object} params - * @param {string} params.source The id of the source for which we're loading this tile. - * @param {string} params.uid The UID for this tile. - */ - removeTile: function(params) { - var loaded = this.loaded[params.source], - uid = params.uid; - if (loaded && loaded[uid]) { - delete loaded[uid]; - } - }, - - /** - * @param {object} params - * @param {string} params.url The URL of the tile PBF to load. - */ - loadVectorData: function (params, callback) { - var xhr = ajax.getArrayBuffer(params.url, done.bind(this)); - return function abort () { xhr.abort(); }; - function done(err, data) { - if (err) { return callback(err); } - var tile = new vt.VectorTile(new Protobuf(new Uint8Array(data))); - callback(err, { tile: tile, rawTileData: data }); - } - }, - - redoPlacement: function(params, callback) { - var loaded = this.loaded[params.source], - loading = this.loading[params.source], - uid = params.uid; - - if (loaded && loaded[uid]) { - var tile = loaded[uid]; - var result = tile.redoPlacement(params.angle, params.pitch, params.showCollisionBoxes); - - if (result.result) { - callback(null, result.result, result.transferables); - } - - } else if (loading && loading[uid]) { - loading[uid].angle = params.angle; - } - } -}; - -},{"../util/ajax":54,"./worker_tile":40,"pbf":65,"vector-tile":72}],40:[function(require,module,exports){ -'use strict'; - -var FeatureIndex = require('../data/feature_index'); -var CollisionTile = require('../symbol/collision_tile'); -var Bucket = require('../data/bucket'); -var CollisionBoxArray = require('../symbol/collision_box'); -var DictionaryCoder = require('../util/dictionary_coder'); -var util = require('../util/util'); -var SymbolInstancesArray = require('../symbol/symbol_instances'); -var SymbolQuadsArray = require('../symbol/symbol_quads'); - -module.exports = WorkerTile; - -function WorkerTile(params) { - this.coord = params.coord; - this.uid = params.uid; - this.zoom = params.zoom; - this.tileSize = params.tileSize; - this.source = params.source; - this.overscaling = params.overscaling; - this.angle = params.angle; - this.pitch = params.pitch; - this.showCollisionBoxes = params.showCollisionBoxes; -} - -WorkerTile.prototype.parse = function(data, layerFamilies, actor, rawTileData, callback) { - - this.status = 'parsing'; - this.data = data; - - this.collisionBoxArray = new CollisionBoxArray(); - this.symbolInstancesArray = new SymbolInstancesArray(); - this.symbolQuadsArray = new SymbolQuadsArray(); - var collisionTile = new CollisionTile(this.angle, this.pitch, this.collisionBoxArray); - var featureIndex = new FeatureIndex(this.coord, this.overscaling, collisionTile, data.layers); - var sourceLayerCoder = new DictionaryCoder(data.layers ? Object.keys(data.layers).sort() : ['_geojsonTileLayer']); - - var tile = this; - var bucketsById = {}; - var bucketsBySourceLayer = {}; - var i; - var layer; - var sourceLayerId; - var bucket; - - // Map non-ref layers to buckets. - var bucketIndex = 0; - for (var layerId in layerFamilies) { - layer = layerFamilies[layerId][0]; - - if (layer.source !== this.source) continue; - if (layer.ref) continue; - if (layer.minzoom && this.zoom < layer.minzoom) continue; - if (layer.maxzoom && this.zoom >= layer.maxzoom) continue; - if (layer.layout && layer.layout.visibility === 'none') continue; - if (data.layers && !data.layers[layer.sourceLayer]) continue; - - bucket = Bucket.create({ - layer: layer, - index: bucketIndex++, - childLayers: layerFamilies[layerId], - zoom: this.zoom, - overscaling: this.overscaling, - showCollisionBoxes: this.showCollisionBoxes, - collisionBoxArray: this.collisionBoxArray, - symbolQuadsArray: this.symbolQuadsArray, - symbolInstancesArray: this.symbolInstancesArray, - sourceLayerIndex: sourceLayerCoder.encode(layer.sourceLayer || '_geojsonTileLayer') - }); - bucket.createFilter(); - - bucketsById[layer.id] = bucket; - - if (data.layers) { // vectortile - sourceLayerId = layer.sourceLayer; - bucketsBySourceLayer[sourceLayerId] = bucketsBySourceLayer[sourceLayerId] || {}; - bucketsBySourceLayer[sourceLayerId][layer.id] = bucket; - } - } - - // read each layer, and sort its features into buckets - if (data.layers) { // vectortile - for (sourceLayerId in bucketsBySourceLayer) { - if (layer.version === 1) { - util.warnOnce( - 'Vector tile source "' + this.source + '" layer "' + - sourceLayerId + '" does not use vector tile spec v2 ' + - 'and therefore may have some rendering errors.' - ); - } - layer = data.layers[sourceLayerId]; - if (layer) { - sortLayerIntoBuckets(layer, bucketsBySourceLayer[sourceLayerId]); - } - } - } else { // geojson - sortLayerIntoBuckets(data, bucketsById); - } - - function sortLayerIntoBuckets(layer, buckets) { - for (var i = 0; i < layer.length; i++) { - var feature = layer.feature(i); - feature.index = i; - for (var id in buckets) { - if (buckets[id].filter(feature)) - buckets[id].features.push(feature); - } - } - } - - var buckets = [], - symbolBuckets = this.symbolBuckets = [], - otherBuckets = []; - - featureIndex.bucketLayerIDs = {}; - - for (var id in bucketsById) { - bucket = bucketsById[id]; - if (bucket.features.length === 0) continue; - - featureIndex.bucketLayerIDs[bucket.index] = bucket.childLayers.map(getLayerId); - - buckets.push(bucket); - - if (bucket.type === 'symbol') - symbolBuckets.push(bucket); - else - otherBuckets.push(bucket); - } - - var icons = {}; - var stacks = {}; - var deps = 0; - - - if (symbolBuckets.length > 0) { - - // Get dependencies for symbol buckets - for (i = symbolBuckets.length - 1; i >= 0; i--) { - symbolBuckets[i].updateIcons(icons); - symbolBuckets[i].updateFont(stacks); - } - - for (var fontName in stacks) { - stacks[fontName] = Object.keys(stacks[fontName]).map(Number); - } - icons = Object.keys(icons); - - actor.send('get glyphs', {uid: this.uid, stacks: stacks}, function(err, newStacks) { - stacks = newStacks; - gotDependency(err); - }); - - if (icons.length) { - actor.send('get icons', {icons: icons}, function(err, newIcons) { - icons = newIcons; - gotDependency(err); - }); - } else { - gotDependency(); - } - } - - // immediately parse non-symbol buckets (they have no dependencies) - for (i = otherBuckets.length - 1; i >= 0; i--) { - parseBucket(this, otherBuckets[i]); - } - - if (symbolBuckets.length === 0) - return done(); - - function gotDependency(err) { - if (err) return callback(err); - deps++; - if (deps === 2) { - // all symbol bucket dependencies fetched; parse them in proper order - for (var i = symbolBuckets.length - 1; i >= 0; i--) { - parseBucket(tile, symbolBuckets[i]); - } - done(); - } - } - - function parseBucket(tile, bucket) { - bucket.populateArrays(collisionTile, stacks, icons); - - - if (bucket.type !== 'symbol') { - for (var i = 0; i < bucket.features.length; i++) { - var feature = bucket.features[i]; - featureIndex.insert(feature, feature.index, bucket.sourceLayerIndex, bucket.index); - } - } - - bucket.features = null; - } - - function done() { - tile.status = 'done'; - - if (tile.redoPlacementAfterDone) { - tile.redoPlacement(tile.angle, tile.pitch, null); - tile.redoPlacementAfterDone = false; - } - - var featureIndex_ = featureIndex.serialize(); - var collisionTile_ = collisionTile.serialize(); - var collisionBoxArray = tile.collisionBoxArray.serialize(); - var symbolInstancesArray = tile.symbolInstancesArray.serialize(); - var symbolQuadsArray = tile.symbolQuadsArray.serialize(); - var transferables = [rawTileData].concat(featureIndex_.transferables).concat(collisionTile_.transferables); - var nonEmptyBuckets = buckets.filter(isBucketNonEmpty); - - callback(null, { - buckets: nonEmptyBuckets.map(serializeBucket), - featureIndex: featureIndex_.data, - collisionTile: collisionTile_.data, - collisionBoxArray: collisionBoxArray, - symbolInstancesArray: symbolInstancesArray, - symbolQuadsArray: symbolQuadsArray, - rawTileData: rawTileData - }, getTransferables(nonEmptyBuckets).concat(transferables)); - } -}; - -WorkerTile.prototype.redoPlacement = function(angle, pitch, showCollisionBoxes) { - if (this.status !== 'done') { - this.redoPlacementAfterDone = true; - this.angle = angle; - return {}; - } - - var collisionTile = new CollisionTile(angle, pitch, this.collisionBoxArray); - - var buckets = this.symbolBuckets; - - for (var i = buckets.length - 1; i >= 0; i--) { - buckets[i].placeFeatures(collisionTile, showCollisionBoxes); - } - - var collisionTile_ = collisionTile.serialize(); - var nonEmptyBuckets = buckets.filter(isBucketNonEmpty); - - return { - result: { - buckets: nonEmptyBuckets.map(serializeBucket), - collisionTile: collisionTile_.data - }, - transferables: getTransferables(nonEmptyBuckets).concat(collisionTile_.transferables) - }; -}; - -function isBucketNonEmpty(bucket) { - return !bucket.isEmpty(); -} - -function serializeBucket(bucket) { - return bucket.serialize(); -} - -function getTransferables(buckets) { - var transferables = []; - for (var i in buckets) { - buckets[i].getTransferables(transferables); - } - return transferables; -} - -function getLayerId(layer) { - return layer.id; -} - -},{"../data/bucket":25,"../data/feature_index":32,"../symbol/collision_box":44,"../symbol/collision_tile":46,"../symbol/symbol_instances":52,"../symbol/symbol_quads":53,"../util/dictionary_coder":56,"../util/util":62}],41:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -module.exports = Anchor; - -function Anchor(x, y, angle, segment) { - this.x = x; - this.y = y; - this.angle = angle; - - if (segment !== undefined) { - this.segment = segment; - } -} - -Anchor.prototype = Object.create(Point.prototype); - -Anchor.prototype.clone = function() { - return new Anchor(this.x, this.y, this.angle, this.segment); -}; - -},{"point-geometry":66}],42:[function(require,module,exports){ -'use strict'; - -module.exports = checkMaxAngle; - -/** - * Labels placed around really sharp angles aren't readable. Check if any - * part of the potential label has a combined angle that is too big. - * - * @param {Array} line - * @param {Anchor} anchor The point on the line around which the label is anchored. - * @param {number} labelLength The length of the label in geometry units. - * @param {number} windowSize The check fails if the combined angles within a part of the line that is `windowSize` long is too big. - * @param {number} maxAngle The maximum combined angle that any window along the label is allowed to have. - * - * @returns {boolean} whether the label should be placed - * @private - */ -function checkMaxAngle(line, anchor, labelLength, windowSize, maxAngle) { - - // horizontal labels always pass - if (anchor.segment === undefined) return true; - - var p = anchor; - var index = anchor.segment + 1; - var anchorDistance = 0; - - // move backwards along the line to the first segment the label appears on - while (anchorDistance > -labelLength / 2) { - index--; - - // there isn't enough room for the label after the beginning of the line - if (index < 0) return false; - - anchorDistance -= line[index].dist(p); - p = line[index]; - } - - anchorDistance += line[index].dist(line[index + 1]); - index++; - - // store recent corners and their total angle difference - var recentCorners = []; - var recentAngleDelta = 0; - - // move forwards by the length of the label and check angles along the way - while (anchorDistance < labelLength / 2) { - var prev = line[index - 1]; - var current = line[index]; - var next = line[index + 1]; - - // there isn't enough room for the label before the end of the line - if (!next) return false; - - var angleDelta = prev.angleTo(current) - current.angleTo(next); - // restrict angle to -pi..pi range - angleDelta = Math.abs(((angleDelta + 3 * Math.PI) % (Math.PI * 2)) - Math.PI); - - recentCorners.push({ - distance: anchorDistance, - angleDelta: angleDelta - }); - recentAngleDelta += angleDelta; - - // remove corners that are far enough away from the list of recent anchors - while (anchorDistance - recentCorners[0].distance > windowSize) { - recentAngleDelta -= recentCorners.shift().angleDelta; - } - - // the sum of angles within the window area exceeds the maximum allowed value. check fails. - if (recentAngleDelta > maxAngle) return false; - - index++; - anchorDistance += current.dist(next); - } - - // no part of the line had an angle greater than the maximum allowed. check passes. - return true; -} - -},{}],43:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -module.exports = clipLine; - -/** - * Returns the part of a multiline that intersects with the provided rectangular box. - * - * @param {Array>} lines - * @param {number} x1 the left edge of the box - * @param {number} y1 the top edge of the box - * @param {number} x2 the right edge of the box - * @param {number} y2 the bottom edge of the box - * @returns {Array>} lines - * @private - */ -function clipLine(lines, x1, y1, x2, y2) { - var clippedLines = []; - - for (var l = 0; l < lines.length; l++) { - var line = lines[l]; - var clippedLine; - - 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 Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round(); - } else if (p1.x < x1) { - p1 = new Point(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 Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round(); - } else if (p1.y < y1) { - p1 = new Point(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 Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round(); - } else if (p1.x >= x2) { - p1 = new Point(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 Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round(); - } else if (p1.y >= y2) { - p1 = new Point(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; -} - -},{"point-geometry":66}],44:[function(require,module,exports){ -'use strict'; - -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); - -/** - * A collision box represents an area of the map that that is covered by a - * label. CollisionFeature uses one or more of these collision boxes to - * represent all the area covered by a single label. They are used to - * prevent collisions between labels. - * - * A collision box actually represents a 3d volume. The first two dimensions, - * x and y, are specified with `anchor` along with `x1`, `y1`, `x2`, `y2`. - * The third dimension, zoom, is limited by `maxScale` which determines - * how far in the z dimensions the box extends. - * - * As you zoom in on a map, all points on the map get further and further apart - * but labels stay roughly the same size. Labels cover less real world area on - * the map at higher zoom levels than they do at lower zoom levels. This is why - * areas are are represented with an anchor point and offsets from that point - * instead of just using four absolute points. - * - * Line labels are represented by a set of these boxes spaced out along a line. - * When you zoom in, line labels cover less real world distance along the line - * than they used to. Collision boxes near the edges that used to cover label - * no longer do. If a box doesn't cover the label anymore it should be ignored - * when doing collision checks. `maxScale` is how much you can scale the map - * before the label isn't within the box anymore. - * For example - * lower zoom: - * https://cloud.githubusercontent.com/assets/1421652/8060094/4d975f76-0e91-11e5-84b1-4edeb30a5875.png - * slightly higher zoom: - * https://cloud.githubusercontent.com/assets/1421652/8060061/26ae1c38-0e91-11e5-8c5a-9f380bf29f0a.png - * In the zoomed in image the two grey boxes on either side don't cover the - * label anymore. Their maxScale is smaller than the current scale. - * - * - * @class CollisionBoxArray - * @private - */ - -var CollisionBoxArray = module.exports = new StructArrayType({ - members: [ - // the box is centered around the anchor point - { type: 'Int16', name: 'anchorPointX' }, - { type: 'Int16', name: 'anchorPointY' }, - - // distances to the edges from the anchor - { type: 'Int16', name: 'x1' }, - { type: 'Int16', name: 'y1' }, - { type: 'Int16', name: 'x2' }, - { type: 'Int16', name: 'y2' }, - - // the box is only valid for scales < maxScale. - // The box does not block other boxes at scales >= maxScale; - { type: 'Float32', name: 'maxScale' }, - - // the index of the feature in the original vectortile - { type: 'Uint32', name: 'featureIndex' }, - // the source layer the feature appears in - { type: 'Uint16', name: 'sourceLayerIndex' }, - // the bucket the feature appears in - { type: 'Uint16', name: 'bucketIndex' }, - - // rotated and scaled bbox used for indexing - { type: 'Int16', name: 'bbox0' }, - { type: 'Int16', name: 'bbox1' }, - { type: 'Int16', name: 'bbox2' }, - { type: 'Int16', name: 'bbox3' }, - - { type: 'Float32', name: 'placementScale' } - ]}); - -util.extendAll(CollisionBoxArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - } -}); - -},{"../util/struct_array":60,"../util/util":62,"point-geometry":66}],45:[function(require,module,exports){ -'use strict'; - -module.exports = CollisionFeature; - -/** - * A CollisionFeature represents the area of the tile covered by a single label. - * It is used with CollisionTile to check if the label overlaps with any - * previous labels. A CollisionFeature is mostly just a set of CollisionBox - * objects. - * - * @class CollisionFeature - * @param {Array} line The geometry the label is placed on. - * @param {Anchor} anchor The point along the line around which the label is anchored. - * @param {VectorTileFeature} feature The VectorTileFeature that this CollisionFeature was created for. - * @param {Array} layerIDs The IDs of the layers that this CollisionFeature is a part of. - * @param {Object} shaped The text or icon shaping results. - * @param {number} boxScale A magic number used to convert from glyph metrics units to geometry units. - * @param {number} padding The amount of padding to add around the label edges. - * @param {boolean} alignLine Whether the label is aligned with the line or the viewport. - * - * @private - */ -function CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaped, boxScale, padding, alignLine, straight) { - - 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) { - // set minimum box height to avoid very many small labels - height = Math.max(10 * boxScale, height); - - if (straight) { - // used for icon labels that are aligned with the line, but don't curve along it - var vector = line[anchor.segment + 1].sub(line[anchor.segment])._unit()._mult(length); - var straightLine = [anchor.sub(vector), anchor.add(vector)]; - this._addLineCollisionBoxes(collisionBoxArray, straightLine, anchor, 0, length, height, featureIndex, sourceLayerIndex, bucketIndex); - } else { - // used for text labels that curve along a line - this._addLineCollisionBoxes(collisionBoxArray, line, anchor, anchor.segment, length, height, featureIndex, sourceLayerIndex, bucketIndex); - } - } - - } else { - collisionBoxArray.emplaceBack(anchor.x, anchor.y, x1, y1, x2, y2, Infinity, featureIndex, sourceLayerIndex, bucketIndex, - 0, 0, 0, 0, 0); - } - - this.boxEndIndex = collisionBoxArray.length; -} - -/** - * Create a set of CollisionBox objects for a line. - * - * @param {Array} line - * @param {Anchor} anchor - * @param {number} labelLength The length of the label in geometry units. - * @param {Anchor} anchor The point along the line around which the label is anchored. - * @param {VectorTileFeature} feature The VectorTileFeature that this CollisionFeature was created for. - * @param {number} boxSize The size of the collision boxes that will be created. - * - * @private - */ -CollisionFeature.prototype._addLineCollisionBoxes = function(collisionBoxArray, line, anchor, segment, labelLength, boxSize, featureIndex, sourceLayerIndex, bucketIndex) { - var step = boxSize / 2; - var nBoxes = Math.floor(labelLength / step); - - // offset the center of the first box by half a box so that the edge of the - // box is at the edge of the label. - var firstBoxOffset = -boxSize / 2; - - var bboxes = this.boxes; - - var p = anchor; - var index = segment + 1; - var anchorDistance = firstBoxOffset; - - // move backwards along the line to the first segment the label appears on - do { - index--; - - // there isn't enough room for the label after the beginning of the line - // checkMaxAngle should have already caught this - if (index < 0) return bboxes; - - anchorDistance -= line[index].dist(p); - p = line[index]; - } while (anchorDistance > -labelLength / 2); - - var segmentLength = line[index].dist(line[index + 1]); - - for (var i = 0; i < nBoxes; i++) { - // the distance the box will be from the anchor - var boxDistanceToAnchor = -labelLength / 2 + i * step; - - // the box is not on the current segment. Move to the next segment. - while (anchorDistance + segmentLength < boxDistanceToAnchor) { - anchorDistance += segmentLength; - index++; - - // There isn't enough room before the end of the line. - if (index + 1 >= line.length) return bboxes; - - segmentLength = line[index].dist(line[index + 1]); - } - - // the distance the box will be from the beginning of the segment - 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 distanceToInnerEdge = Math.max(Math.abs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0); - var maxScale = labelLength / 2 / distanceToInnerEdge; - - collisionBoxArray.emplaceBack(boxAnchorPoint.x, boxAnchorPoint.y, - -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale, - featureIndex, sourceLayerIndex, bucketIndex, - 0, 0, 0, 0, 0); - } - - return bboxes; -}; - -},{}],46:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); -var EXTENT = require('../data/bucket').EXTENT; -var Grid = require('grid-index'); - -module.exports = CollisionTile; - -/** - * A collision tile used to prevent symbols from overlapping. It keep tracks of - * where previous symbols have been placed and is used to check if a new - * symbol overlaps with any previously added symbols. - * - * @class CollisionTile - * @param {number} angle - * @param {number} pitch - * @private - */ -function CollisionTile(angle, pitch, collisionBoxArray) { - if (typeof angle === 'object') { - var serialized = angle; - collisionBoxArray = pitch; - angle = serialized.angle; - pitch = serialized.pitch; - this.grid = new Grid(serialized.grid); - this.ignoredGrid = new Grid(serialized.ignoredGrid); - } else { - this.grid = new Grid(EXTENT, 12, 6); - this.ignoredGrid = new Grid(EXTENT, 12, 0); - } - - this.angle = angle; - this.pitch = pitch; - - var sin = Math.sin(angle), - cos = Math.cos(angle); - this.rotationMatrix = [cos, -sin, sin, cos]; - this.reverseRotationMatrix = [cos, sin, -sin, cos]; - - // Stretch boxes in y direction to account for the map tilt. - this.yStretch = 1 / Math.cos(pitch / 180 * Math.PI); - - // The amount the map is squished depends on the y position. - // Sort of account for this by making all boxes a bit bigger. - this.yStretch = Math.pow(this.yStretch, 1.3); - - this.collisionBoxArray = collisionBoxArray; - if (collisionBoxArray.length === 0) { - // the first collisionBoxArray is passed to a CollisionTile - - // tempCollisionBox - collisionBoxArray.emplaceBack(); - - var maxInt16 = 32767; - //left - collisionBoxArray.emplaceBack(0, 0, 0, -maxInt16, 0, maxInt16, maxInt16, - 0, 0, 0, 0, 0, 0, 0, 0, - 0); - // right - collisionBoxArray.emplaceBack(EXTENT, 0, 0, -maxInt16, 0, maxInt16, maxInt16, - 0, 0, 0, 0, 0, 0, 0, 0, - 0); - // top - collisionBoxArray.emplaceBack(0, 0, -maxInt16, 0, maxInt16, 0, maxInt16, - 0, 0, 0, 0, 0, 0, 0, 0, - 0); - // bottom - collisionBoxArray.emplaceBack(0, EXTENT, -maxInt16, 0, maxInt16, 0, maxInt16, - 0, 0, 0, 0, 0, 0, 0, 0, - 0); - } - - this.tempCollisionBox = collisionBoxArray.get(0); - this.edges = [ - collisionBoxArray.get(1), - collisionBoxArray.get(2), - collisionBoxArray.get(3), - collisionBoxArray.get(4) - ]; -} - -CollisionTile.prototype.serialize = function() { - var data = { - angle: this.angle, - pitch: this.pitch, - grid: this.grid.toArrayBuffer(), - ignoredGrid: this.ignoredGrid.toArrayBuffer() - }; - return { - data: data, - transferables: [data.grid, data.ignoredGrid] - }; -}; - -CollisionTile.prototype.minScale = 0.25; -CollisionTile.prototype.maxScale = 2; - - -/** - * Find the scale at which the collisionFeature can be shown without - * overlapping with other features. - * - * @param {CollisionFeature} collisionFeature - * @returns {number} placementScale - * @private - */ -CollisionTile.prototype.placeCollisionFeature = function(collisionFeature, allowOverlap, avoidEdges) { - - var collisionBoxArray = this.collisionBoxArray; - var minPlacementScale = this.minScale; - var rotationMatrix = this.rotationMatrix; - var yStretch = this.yStretch; - - for (var b = collisionFeature.boxStartIndex; b < collisionFeature.boxEndIndex; b++) { - - var box = collisionBoxArray.get(b); - - var anchorPoint = box.anchorPoint._matMult(rotationMatrix); - var x = anchorPoint.x; - var y = anchorPoint.y; - - var x1 = x + box.x1; - var y1 = y + box.y1 * yStretch; - var x2 = x + box.x2; - var y2 = y + box.y2 * yStretch; - - box.bbox0 = x1; - box.bbox1 = y1; - box.bbox2 = x2; - box.bbox3 = y2; - - if (!allowOverlap) { - var blockingBoxes = this.grid.query(x1, y1, x2, y2); - - for (var i = 0; i < blockingBoxes.length; i++) { - var blocking = collisionBoxArray.get(blockingBoxes[i]); - var blockingAnchorPoint = blocking.anchorPoint._matMult(rotationMatrix); - - minPlacementScale = this.getPlacementScale(minPlacementScale, anchorPoint, box, blockingAnchorPoint, blocking); - if (minPlacementScale >= this.maxScale) { - return minPlacementScale; - } - } - } - - if (avoidEdges) { - var rotatedCollisionBox; - - if (this.angle) { - var reverseRotationMatrix = this.reverseRotationMatrix; - var tl = new Point(box.x1, box.y1).matMult(reverseRotationMatrix); - var tr = new Point(box.x2, box.y1).matMult(reverseRotationMatrix); - var bl = new Point(box.x1, box.y2).matMult(reverseRotationMatrix); - var br = new Point(box.x2, box.y2).matMult(reverseRotationMatrix); - - rotatedCollisionBox = this.tempCollisionBox; - rotatedCollisionBox.anchorPointX = box.anchorPoint.x; - rotatedCollisionBox.anchorPointY = box.anchorPoint.y; - rotatedCollisionBox.x1 = Math.min(tl.x, tr.x, bl.x, br.x); - rotatedCollisionBox.y1 = Math.min(tl.y, tr.x, bl.x, br.x); - rotatedCollisionBox.x2 = Math.max(tl.x, tr.x, bl.x, br.x); - rotatedCollisionBox.y2 = Math.max(tl.y, tr.x, bl.x, br.x); - rotatedCollisionBox.maxScale = box.maxScale; - } else { - rotatedCollisionBox = box; - } - - for (var k = 0; k < this.edges.length; k++) { - var edgeBox = this.edges[k]; - minPlacementScale = this.getPlacementScale(minPlacementScale, box.anchorPoint, rotatedCollisionBox, edgeBox.anchorPoint, edgeBox); - if (minPlacementScale >= this.maxScale) { - return minPlacementScale; - } - } - } - } - - return minPlacementScale; -}; - -CollisionTile.prototype.queryRenderedSymbols = function(minX, minY, maxX, maxY, scale) { - var sourceLayerFeatures = {}; - var result = []; - - var collisionBoxArray = this.collisionBoxArray; - var rotationMatrix = this.rotationMatrix; - var anchorPoint = new Point(minX, minY)._matMult(rotationMatrix); - - var queryBox = this.tempCollisionBox; - queryBox.anchorX = anchorPoint.x; - queryBox.anchorY = anchorPoint.y; - queryBox.x1 = 0; - queryBox.y1 = 0; - queryBox.x2 = maxX - minX; - queryBox.y2 = maxY - minY; - queryBox.maxScale = scale; - - // maxScale is stored using a Float32. Convert `scale` to the stored Float32 value. - scale = queryBox.maxScale; - - var searchBox = [ - anchorPoint.x + queryBox.x1 / scale, - anchorPoint.y + queryBox.y1 / scale * this.yStretch, - anchorPoint.x + queryBox.x2 / scale, - anchorPoint.y + queryBox.y2 / scale * this.yStretch - ]; - - var blockingBoxKeys = this.grid.query(searchBox[0], searchBox[1], searchBox[2], searchBox[3]); - var blockingBoxKeys2 = this.ignoredGrid.query(searchBox[0], searchBox[1], searchBox[2], searchBox[3]); - for (var k = 0; k < blockingBoxKeys2.length; k++) { - blockingBoxKeys.push(blockingBoxKeys2[k]); - } - - for (var i = 0; i < blockingBoxKeys.length; i++) { - var blocking = collisionBoxArray.get(blockingBoxKeys[i]); - - var sourceLayer = blocking.sourceLayerIndex; - var featureIndex = blocking.featureIndex; - if (sourceLayerFeatures[sourceLayer] === undefined) { - sourceLayerFeatures[sourceLayer] = {}; - } - - if (!sourceLayerFeatures[sourceLayer][featureIndex]) { - var blockingAnchorPoint = blocking.anchorPoint.matMult(rotationMatrix); - var minPlacementScale = this.getPlacementScale(this.minScale, anchorPoint, queryBox, blockingAnchorPoint, blocking); - if (minPlacementScale >= scale) { - sourceLayerFeatures[sourceLayer][featureIndex] = true; - result.push(blockingBoxKeys[i]); - } - } - } - - return result; -}; - -CollisionTile.prototype.getPlacementScale = function(minPlacementScale, anchorPoint, box, blockingAnchorPoint, blocking) { - - // Find the lowest scale at which the two boxes can fit side by side without overlapping. - // Original algorithm: - var anchorDiffX = anchorPoint.x - blockingAnchorPoint.x; - var anchorDiffY = anchorPoint.y - blockingAnchorPoint.y; - var s1 = (blocking.x1 - box.x2) / anchorDiffX; // scale at which new box is to the left of old box - var s2 = (blocking.x2 - box.x1) / anchorDiffX; // scale at which new box is to the right of old box - var s3 = (blocking.y1 - box.y2) * this.yStretch / anchorDiffY; // scale at which new box is to the top of old box - var s4 = (blocking.y2 - box.y1) * this.yStretch / anchorDiffY; // scale at which new box is to the bottom of old box - - if (isNaN(s1) || isNaN(s2)) s1 = s2 = 1; - if (isNaN(s3) || isNaN(s4)) s3 = s4 = 1; - - var collisionFreeScale = Math.min(Math.max(s1, s2), Math.max(s3, s4)); - var blockingMaxScale = blocking.maxScale; - var boxMaxScale = box.maxScale; - - if (collisionFreeScale > blockingMaxScale) { - // After a box's maxScale the label has shrunk enough that the box is no longer needed to cover it, - // so unblock the new box at the scale that the old box disappears. - collisionFreeScale = blockingMaxScale; - } - - if (collisionFreeScale > boxMaxScale) { - // If the box can only be shown after it is visible, then the box can never be shown. - // But the label can be shown after this box is not visible. - collisionFreeScale = boxMaxScale; - } - - if (collisionFreeScale > minPlacementScale && - collisionFreeScale >= blocking.placementScale) { - // If this collision occurs at a lower scale than previously found collisions - // and the collision occurs while the other label is visible - - // this this is the lowest scale at which the label won't collide with anything - minPlacementScale = collisionFreeScale; - } - - return minPlacementScale; -}; - - -/** - * Remember this collisionFeature and what scale it was placed at to block - * later features from overlapping with it. - * - * @param {CollisionFeature} collisionFeature - * @param {number} minPlacementScale - * @private - */ -CollisionTile.prototype.insertCollisionFeature = function(collisionFeature, minPlacementScale, ignorePlacement) { - - var grid = ignorePlacement ? this.ignoredGrid : this.grid; - var collisionBoxArray = this.collisionBoxArray; - - for (var k = collisionFeature.boxStartIndex; k < collisionFeature.boxEndIndex; k++) { - var box = collisionBoxArray.get(k); - box.placementScale = minPlacementScale; - if (minPlacementScale < this.maxScale) { - grid.insert(k, box.bbox0, box.bbox1, box.bbox2, box.bbox3); - } - } -}; - -},{"../data/bucket":25,"grid-index":18,"point-geometry":66}],47:[function(require,module,exports){ -'use strict'; - -var interpolate = require('../util/interpolate'); -var Anchor = require('../symbol/anchor'); -var checkMaxAngle = require('./check_max_angle'); - -module.exports = getAnchors; - -function getAnchors(line, spacing, maxAngle, shapedText, shapedIcon, glyphSize, boxScale, overscaling, tileExtent) { - - // Resample a line to get anchor points for labels and check that each - // potential label passes text-max-angle check and has enough froom to fit - // on the line. - - var angleWindowSize = shapedText ? - 3 / 5 * glyphSize * boxScale : - 0; - - var labelLength = Math.max( - shapedText ? shapedText.right - shapedText.left : 0, - shapedIcon ? shapedIcon.right - shapedIcon.left : 0); - - // Is the line continued from outside the tile boundary? - var isLineContinued = line[0].x === 0 || line[0].x === tileExtent || line[0].y === 0 || line[0].y === tileExtent; - - // Is the label long, relative to the spacing? - // If so, adjust the spacing so there is always a minimum space of `spacing / 4` between label edges. - if (spacing - labelLength * boxScale < spacing / 4) { - spacing = labelLength * boxScale + spacing / 4; - } - - // Offset the first anchor by: - // Either half the label length plus a fixed extra offset if the line is not continued - // Or half the spacing if the line is continued. - - // For non-continued lines, add a bit of fixed extra offset to avoid collisions at T intersections. - var fixedExtraOffset = glyphSize * 2; - - var offset = !isLineContinued ? - ((labelLength / 2 + fixedExtraOffset) * boxScale * overscaling) % spacing : - (spacing / 2 * overscaling) % spacing; - - return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength * boxScale, isLineContinued, false, tileExtent); -} - - -function resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, placeAtMiddle, tileExtent) { - - var halfLabelLength = labelLength / 2; - var lineLength = 0; - for (var k = 0; k < line.length - 1; k++) { - lineLength += line[k].dist(line[k + 1]); - } - - 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 = interpolate(a.x, b.x, t), - y = interpolate(a.y, b.y, t); - - // Check that the point is within the tile boundaries and that - // the label would fit before the beginning and end of the line - // if placed at this point. - if (x >= 0 && x < tileExtent && y >= 0 && y < tileExtent && - markedDistance - halfLabelLength >= 0 && - markedDistance + halfLabelLength <= lineLength) { - var anchor = new Anchor(x, y, angle, i)._round(); - - if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) { - anchors.push(anchor); - } - } - } - - distance += segmentDist; - } - - if (!placeAtMiddle && !anchors.length && !isLineContinued) { - // The first attempt at finding anchors at which labels can be placed failed. - // Try again, but this time just try placing one anchor at the middle of the line. - // This has the most effect for short lines in overscaled tiles, since the - // initial offset used in overscaled tiles is calculated to align labels with positions in - // parent tiles instead of placing the label as close to the beginning as possible. - anchors = resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, true, tileExtent); - } - - return anchors; -} - -},{"../symbol/anchor":41,"../util/interpolate":58,"./check_max_angle":42}],48:[function(require,module,exports){ -'use strict'; - -module.exports = function (features, textFeatures, geometries) { - - var leftIndex = {}, - rightIndex = {}, - mergedFeatures = [], - mergedGeom = [], - mergedTexts = [], - mergedIndex = 0, - k; - - function add(k) { - mergedFeatures.push(features[k]); - mergedGeom.push(geometries[k]); - mergedTexts.push(textFeatures[k]); - mergedIndex++; - } - - function mergeFromRight(leftKey, rightKey, geom) { - var i = rightIndex[leftKey]; - delete rightIndex[leftKey]; - rightIndex[rightKey] = i; - - mergedGeom[i][0].pop(); - mergedGeom[i][0] = mergedGeom[i][0].concat(geom[0]); - return i; - } - - function mergeFromLeft(leftKey, rightKey, geom) { - var i = leftIndex[rightKey]; - delete leftIndex[rightKey]; - leftIndex[leftKey] = i; - - mergedGeom[i][0].shift(); - mergedGeom[i][0] = geom[0].concat(mergedGeom[i][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 (k = 0; k < features.length; k++) { - var geom = geometries[k], - text = textFeatures[k]; - - 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])) { - // found lines with the same text adjacent to both ends of the current line, merge all three - var j = mergeFromLeft(leftKey, rightKey, geom); - var i = mergeFromRight(leftKey, rightKey, mergedGeom[j]); - - delete leftIndex[leftKey]; - delete rightIndex[rightKey]; - - rightIndex[getKey(text, mergedGeom[i], true)] = i; - mergedGeom[j] = null; - - } else if (leftKey in rightIndex) { - // found mergeable line adjacent to the start of the current line, merge - mergeFromRight(leftKey, rightKey, geom); - - } else if (rightKey in leftIndex) { - // found mergeable line adjacent to the end of the current line, merge - mergeFromLeft(leftKey, rightKey, geom); - - } else { - // no adjacent lines, add as a new item - add(k); - leftIndex[leftKey] = mergedIndex - 1; - rightIndex[rightKey] = mergedIndex - 1; - } - } - - return { - features: mergedFeatures, - textFeatures: mergedTexts, - geometries: mergedGeom - }; -}; - -},{}],49:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -module.exports = { - getIconQuads: getIconQuads, - getGlyphQuads: getGlyphQuads, - SymbolQuad: SymbolQuad -}; - -var minScale = 0.5; // underscale by 1 zoom level - -/** - * A textured quad for rendering a single icon or glyph. - * - * The zoom range the glyph can be shown is defined by minScale and maxScale. - * - * @param {Point} anchorPoint the point the symbol is anchored around - * @param {Point} tl The offset of the top left corner from the anchor. - * @param {Point} tr The offset of the top right corner from the anchor. - * @param {Point} bl The offset of the bottom left corner from the anchor. - * @param {Point} br The offset of the bottom right corner from the anchor. - * @param {Object} tex The texture coordinates. - * @param {number} anchorAngle The angle of the label at it's center, not the angle of this quad. - * @param {number} glyphAngle The angle of the glyph to be positioned in the quad. - * @param {number} minScale The minimum scale, relative to the tile's intended scale, that the glyph can be shown at. - * @param {number} maxScale The maximum scale, relative to the tile's intended scale, that the glyph can be shown at. - * - * @class SymbolQuad - * @private - */ -function SymbolQuad(anchorPoint, tl, tr, bl, br, tex, anchorAngle, glyphAngle, minScale, maxScale) { - this.anchorPoint = anchorPoint; - this.tl = tl; - this.tr = tr; - this.bl = bl; - this.br = br; - this.tex = tex; - this.anchorAngle = anchorAngle; - this.glyphAngle = glyphAngle; - this.minScale = minScale; - this.maxScale = maxScale; -} - -/** - * Create the quads used for rendering an icon. - * - * @param {Anchor} anchor - * @param {PositionedIcon} shapedIcon - * @param {number} boxScale A magic number for converting glyph metric units to geometry units. - * @param {Array>} line - * @param {StyleLayer} layer - * @param {boolean} alongLine Whether the icon should be placed along the line. - * @param {Shaping} shapedText Shaping for corresponding text - * @returns {Array} - * @private - */ -function getIconQuads(anchor, shapedIcon, boxScale, line, layer, alongLine, shapedText, globalProperties, featureProperties) { - var rect = shapedIcon.image.rect; - var layout = layer.layout; - - var border = 1; - var left = shapedIcon.left - border; - var right = left + rect.w / shapedIcon.image.pixelRatio; - var top = shapedIcon.top - border; - var bottom = top + rect.h / shapedIcon.image.pixelRatio; - var tl, tr, br, bl; - - // text-fit mode - if (layout['icon-text-fit'] !== 'none' && shapedText) { - var iconWidth = (right - left), - iconHeight = (bottom - top), - size = layout['text-size'] / 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['icon-text-fit-padding'][0], - padR = layout['icon-text-fit-padding'][1], - padB = layout['icon-text-fit-padding'][2], - padL = layout['icon-text-fit-padding'][3], - offsetY = layout['icon-text-fit'] === 'width' ? (textHeight - iconHeight) * 0.5 : 0, - offsetX = layout['icon-text-fit'] === 'height' ? (textWidth - iconWidth) * 0.5 : 0, - width = layout['icon-text-fit'] === 'width' || layout['icon-text-fit'] === 'both' ? textWidth : iconWidth, - height = layout['icon-text-fit'] === 'height' || layout['icon-text-fit'] === 'both' ? textHeight : iconHeight; - tl = new Point(textLeft + offsetX - padL, textTop + offsetY - padT); - tr = new Point(textLeft + offsetX + padR + width, textTop + offsetY - padT); - br = new Point(textLeft + offsetX + padR + width, textTop + offsetY + padB + height); - bl = new Point(textLeft + offsetX - padL, textTop + offsetY + padB + height); - // Normal icon size mode - } else { - tl = new Point(left, top); - tr = new Point(right, top); - br = new Point(right, bottom); - bl = new Point(left, bottom); - } - - var angle = layer.getLayoutValue('icon-rotate', globalProperties, featureProperties) * Math.PI / 180; - if (alongLine) { - var prev = line[anchor.segment]; - if (anchor.y === prev.y && anchor.x === prev.x && anchor.segment + 1 < line.length) { - var next = line[anchor.segment + 1]; - angle += Math.atan2(anchor.y - next.y, anchor.x - next.x) + Math.PI; - } else { - angle += Math.atan2(anchor.y - prev.y, anchor.x - prev.x); - } - } - - if (angle) { - var sin = Math.sin(angle), - cos = Math.cos(angle), - matrix = [cos, -sin, sin, cos]; - - tl = tl.matMult(matrix); - tr = tr.matMult(matrix); - bl = bl.matMult(matrix); - br = br.matMult(matrix); - } - - return [new SymbolQuad(new Point(anchor.x, anchor.y), tl, tr, bl, br, shapedIcon.image.rect, 0, 0, minScale, Infinity)]; -} - -/** - * Create the quads used for rendering a text label. - * - * @param {Anchor} anchor - * @param {Shaping} shaping - * @param {number} boxScale A magic number for converting from glyph metric units to geometry units. - * @param {Array>} line - * @param {StyleLayer} layer - * @param {boolean} alongLine Whether the label should be placed along the line. - * @returns {Array} - * @private - */ -function getGlyphQuads(anchor, shaping, boxScale, line, layer, alongLine) { - - var textRotate = layer.layout['text-rotate'] * Math.PI / 180; - var keepUpright = layer.layout['text-keep-upright']; - - var positionedGlyphs = shaping.positionedGlyphs; - var quads = []; - - for (var k = 0; k < positionedGlyphs.length; k++) { - var positionedGlyph = positionedGlyphs[k]; - var glyph = positionedGlyph.glyph; - var rect = glyph.rect; - - if (!rect) continue; - - var centerX = (positionedGlyph.x + glyph.advance / 2) * boxScale; - - var glyphInstances; - var labelMinScale = minScale; - if (alongLine) { - glyphInstances = []; - labelMinScale = getSegmentGlyphs(glyphInstances, anchor, centerX, line, anchor.segment, true); - if (keepUpright) { - labelMinScale = Math.min(labelMinScale, getSegmentGlyphs(glyphInstances, anchor, centerX, line, anchor.segment, false)); - } - - } else { - glyphInstances = [{ - anchorPoint: new Point(anchor.x, anchor.y), - offset: 0, - angle: 0, - maxScale: Infinity, - minScale: minScale - }]; - } - - var x1 = positionedGlyph.x + glyph.left, - y1 = positionedGlyph.y - glyph.top, - x2 = x1 + rect.w, - y2 = y1 + rect.h, - - otl = new Point(x1, y1), - otr = new Point(x2, y1), - obl = new Point(x1, y2), - obr = new Point(x2, y2); - - for (var i = 0; i < glyphInstances.length; i++) { - - var instance = glyphInstances[i], - tl = otl, - tr = otr, - bl = obl, - br = obr; - - if (textRotate) { - var sin = Math.sin(textRotate), - cos = Math.cos(textRotate), - matrix = [cos, -sin, sin, cos]; - - tl = tl.matMult(matrix); - tr = tr.matMult(matrix); - bl = bl.matMult(matrix); - br = br.matMult(matrix); - } - - // Prevent label from extending past the end of the line - var glyphMinScale = Math.max(instance.minScale, labelMinScale); - - var anchorAngle = (anchor.angle + instance.offset + 2 * Math.PI) % (2 * Math.PI); - var glyphAngle = (instance.angle + instance.offset + 2 * Math.PI) % (2 * Math.PI); - quads.push(new SymbolQuad(instance.anchorPoint, tl, tr, bl, br, rect, anchorAngle, glyphAngle, glyphMinScale, instance.maxScale)); - } - } - - return quads; -} - -/** - * We can only render glyph quads that slide along a straight line. To draw - * curved lines we need an instance of a glyph for each segment it appears on. - * This creates all the instances of a glyph that are necessary to render a label. - * - * We need a - * @param {Array} glyphInstances An empty array that glyphInstances are added to. - * @param {Anchor} anchor - * @param {number} offset The glyph's offset from the center of the label. - * @param {Array} line - * @param {number} segment The index of the segment of the line on which the anchor exists. - * @param {boolean} forward If true get the glyphs that come later on the line, otherwise get the glyphs that come earlier. - * - * @returns {Array} glyphInstances - * @private - */ -function getSegmentGlyphs(glyphs, anchor, offset, line, segment, forward) { - var upsideDown = !forward; - - if (offset < 0) forward = !forward; - - if (forward) segment++; - - var newAnchorPoint = new Point(anchor.x, anchor.y); - var end = line[segment]; - var prevScale = Infinity; - - offset = Math.abs(offset); - - var placementScale = minScale; - - while (true) { - var distance = newAnchorPoint.dist(end); - var scale = offset / distance; - - // Get the angle of the line segment - var angle = Math.atan2(end.y - newAnchorPoint.y, end.x - newAnchorPoint.x); - if (!forward) angle += Math.PI; - - glyphs.push({ - anchorPoint: newAnchorPoint, - offset: upsideDown ? Math.PI : 0, - minScale: scale, - maxScale: prevScale, - angle: (angle + 2 * Math.PI) % (2 * Math.PI) - }); - - if (scale <= placementScale) break; - - newAnchorPoint = end; - - // skip duplicate nodes - while (newAnchorPoint.equals(end)) { - segment += forward ? 1 : -1; - end = line[segment]; - if (!end) { - return scale; - } - } - - var unit = end.sub(newAnchorPoint)._unit(); - newAnchorPoint = newAnchorPoint.sub(unit._mult(distance)); - - prevScale = scale; - } - - return placementScale; -} - -},{"point-geometry":66}],50:[function(require,module,exports){ -'use strict'; - -var resolveTokens = require('../util/token'); - -module.exports = resolveText; - -/** - * For an array of features determine what glyphs need to be loaded - * and apply any text preprocessing. The remaining users of text should - * use the `textFeatures` key returned by this function rather than accessing - * feature text directly. - * @private - */ -function resolveText(features, layoutProperties, codepoints) { - var textFeatures = []; - - for (var i = 0, fl = features.length; i < fl; i++) { - var text = resolveTokens(features[i].properties, layoutProperties['text-field']); - if (!text) { - textFeatures[i] = null; - continue; - } - text = text.toString(); - - var transform = layoutProperties['text-transform']; - if (transform === 'uppercase') { - text = text.toLocaleUpperCase(); - } else if (transform === 'lowercase') { - text = text.toLocaleLowerCase(); - } - - for (var j = 0; j < text.length; j++) { - codepoints[text.charCodeAt(j)] = true; - } - - // Track indexes of features with text. - textFeatures[i] = text; - } - - return textFeatures; -} - -},{"../util/token":61}],51:[function(require,module,exports){ -'use strict'; - -module.exports = { - shapeText: shapeText, - shapeIcon: shapeIcon -}; - - -// The position of a glyph relative to the text's anchor point. -function PositionedGlyph(codePoint, x, y, glyph) { - this.codePoint = codePoint; - this.x = x; - this.y = y; - this.glyph = glyph; -} - -// A collection of positioned glyphs and some metadata -function Shaping(positionedGlyphs, text, top, bottom, left, right) { - this.positionedGlyphs = positionedGlyphs; - this.text = text; - this.top = top; - this.bottom = bottom; - this.left = left; - this.right = right; -} - -function shapeText(text, glyphs, maxWidth, lineHeight, horizontalAlign, verticalAlign, justify, spacing, translate) { - - var positionedGlyphs = []; - var shaping = new Shaping(positionedGlyphs, text, translate[1], translate[1], translate[0], translate[0]); - - // the y offset *should* be part of the font metadata - var yOffset = -17; - - var x = 0; - var y = yOffset; - - for (var i = 0; i < text.length; i++) { - var codePoint = text.charCodeAt(i); - var glyph = glyphs[codePoint]; - - if (!glyph) continue; - - positionedGlyphs.push(new PositionedGlyph(codePoint, x, y, glyph)); - x += glyph.advance + spacing; - } - - if (!positionedGlyphs.length) return false; - - linewrap(shaping, glyphs, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate); - - return shaping; -} - -var invisible = { - 0x20: true, // space - 0x200b: true // zero-width space -}; - -var breakable = { - 0x20: true, // space - 0x26: true, // ampersand - 0x2b: true, // plus sign - 0x2d: true, // hyphen-minus - 0x2f: true, // solidus - 0xad: true, // soft hyphen - 0xb7: true, // middle dot - 0x200b: true, // zero-width space - 0x2010: true, // hyphen - 0x2013: true // en dash -}; - -function linewrap(shaping, glyphs, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate) { - var lastSafeBreak = null; - - var lengthBeforeCurrentLine = 0; - var lineStartIndex = 0; - var line = 0; - - var maxLineLength = 0; - - var positionedGlyphs = shaping.positionedGlyphs; - - if (maxWidth) { - for (var i = 0; i < positionedGlyphs.length; i++) { - var positionedGlyph = positionedGlyphs[i]; - - positionedGlyph.x -= lengthBeforeCurrentLine; - positionedGlyph.y += lineHeight * line; - - if (positionedGlyph.x > maxWidth && lastSafeBreak !== null) { - - var lineLength = positionedGlyphs[lastSafeBreak + 1].x; - maxLineLength = Math.max(lineLength, maxLineLength); - - for (var k = lastSafeBreak + 1; k <= i; k++) { - positionedGlyphs[k].y += lineHeight; - positionedGlyphs[k].x -= lineLength; - } - - if (justify) { - // Collapse invisible characters. - var lineEnd = lastSafeBreak; - if (invisible[positionedGlyphs[lastSafeBreak].codePoint]) { - lineEnd--; - } - - justifyLine(positionedGlyphs, glyphs, lineStartIndex, lineEnd, justify); - } - - lineStartIndex = lastSafeBreak + 1; - lastSafeBreak = null; - lengthBeforeCurrentLine += lineLength; - line++; - } - - if (breakable[positionedGlyph.codePoint]) { - lastSafeBreak = i; - } - } - } - - var lastPositionedGlyph = positionedGlyphs[positionedGlyphs.length - 1]; - var lastLineLength = lastPositionedGlyph.x + glyphs[lastPositionedGlyph.codePoint].advance; - maxLineLength = Math.max(maxLineLength, lastLineLength); - - var height = (line + 1) * lineHeight; - - justifyLine(positionedGlyphs, glyphs, lineStartIndex, positionedGlyphs.length - 1, justify); - align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate); - - // Calculate the bounding box - shaping.top += -verticalAlign * height; - shaping.bottom = shaping.top + height; - shaping.left += -horizontalAlign * maxLineLength; - shaping.right = shaping.left + maxLineLength; -} - -function justifyLine(positionedGlyphs, glyphs, start, end, justify) { - var lastAdvance = glyphs[positionedGlyphs[end].codePoint].advance; - var lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify; - - for (var j = start; j <= end; j++) { - positionedGlyphs[j].x -= lineIndent; - } - -} - -function align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate) { - var shiftX = (justify - horizontalAlign) * maxLineLength + translate[0]; - var shiftY = (-verticalAlign * (line + 1) + 0.5) * lineHeight + translate[1]; - - for (var j = 0; j < positionedGlyphs.length; j++) { - positionedGlyphs[j].x += shiftX; - positionedGlyphs[j].y += shiftY; - } -} - - -function shapeIcon(image, layout) { - if (!image || !image.rect) return null; - - var dx = layout['icon-offset'][0]; - var dy = layout['icon-offset'][1]; - var x1 = dx - image.width / 2; - var x2 = x1 + image.width; - var y1 = dy - image.height / 2; - var y2 = y1 + image.height; - - return new PositionedIcon(image, y1, y2, x1, x2); -} - -function PositionedIcon(image, top, bottom, left, right) { - this.image = image; - this.top = top; - this.bottom = bottom; - this.left = left; - this.right = right; -} - -},{}],52:[function(require,module,exports){ -'use strict'; - -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); - -/* - * - * A StructArray implementation of symbolInstances from data/bucket/symbol_bucket.js - * this will allow symbolInstances to be transferred between the worker and main threads - * - * @class SymbolInstanceArray - * @private - */ - -var SymbolInstancesArray = module.exports = new StructArrayType({ - members: [ - - { type: 'Uint16', name: 'textBoxStartIndex' }, - { type: 'Uint16', name: 'textBoxEndIndex' }, - { type: 'Uint16', name: 'iconBoxStartIndex' }, - { type: 'Uint16', name: 'iconBoxEndIndex' }, - { type: 'Uint16', name: 'glyphQuadStartIndex' }, - { type: 'Uint16', name: 'glyphQuadEndIndex' }, - { type: 'Uint16', name: 'iconQuadStartIndex' }, - { type: 'Uint16', name: 'iconQuadEndIndex' }, - - // each symbolInstance is centered around the anchor point - { type: 'Int16', name: 'anchorPointX' }, - { type: 'Int16', name: 'anchorPointY' }, - - // index -- not sure if we need this -@mollymerp - { type: 'Int8', name: 'index' } - ] -}); - -util.extendAll(SymbolInstancesArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - } -}); - - - -},{"../util/struct_array":60,"../util/util":62,"point-geometry":66}],53:[function(require,module,exports){ -'use strict'; - -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); -var SymbolQuad = require('./quads').SymbolQuad; - -// notes from ansis on slack: -// it would be best if they are added to a buffer in advance so that they are only created once. There would be a separate buffer with all the individual collision boxes and then SymbolInstance would store the beginning and end indexes of a feature's collisionboxes. CollisionFeature wouldn't really exist as a standalone thing, it would just be a range of boxes in the big collision box buffer - -/* - * - * A StructArray implementation of glyphQuad from symbol/quads - * this will allow glyph quads to be transferred between the worker and main threads along with the rest of - * the symbolInstances - * - * @class SymbolQuadsArray - * @private - */ - -var SymbolQuadsArray = module.exports = new StructArrayType({ - members: [ - // the quad is centered around the anchor point - { type: 'Int16', name: 'anchorPointX' }, - { type: 'Int16', name: 'anchorPointY' }, - - // the offsets of the tl (top-left), tr, bl, br corners from the anchor point - // do these need to be floats? - { type: 'Float32', name: 'tlX' }, - { type: 'Float32', name: 'tlY' }, - { type: 'Float32', name: 'trX' }, - { type: 'Float32', name: 'trY' }, - { type: 'Float32', name: 'blX' }, - { type: 'Float32', name: 'blY' }, - { type: 'Float32', name: 'brX' }, - { type: 'Float32', name: 'brY' }, - - // texture coordinates (height, width, x, and y) - { type: 'Int16', name: 'texH' }, - { type: 'Int16', name: 'texW' }, - { type: 'Int16', name: 'texX' }, - { type: 'Int16', name: 'texY' }, - - // the angle of the label at it's center, not the angle of this quad. - { type: 'Float32', name: 'anchorAngle' }, - // the angle of this quad. - { type: 'Float32', name: 'glyphAngle' }, - - // quad is only valid for scales < maxScale && scale > minScale. - { type: 'Float32', name: 'maxScale' }, - { type: 'Float32', name: 'minScale' } - ] -}); - -util.extendAll(SymbolQuadsArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - }, - get SymbolQuad() { - return new SymbolQuad(this.anchorPoint, - new Point(this.tlX, this.tlY), - new Point(this.trX, this.trY), - new Point(this.blX, this.blY), - new Point(this.brX, this.brY), - { x: this.texX, y: this.texY, h: this.texH, w: this.texW, height: this.texH, width: this.texW }, - this.anchorAngle, - this.glyphAngle, - this.minScale, - this.maxScale); - } -}); - - -},{"../util/struct_array":60,"../util/util":62,"./quads":49,"point-geometry":66}],54:[function(require,module,exports){ -'use strict'; - -exports.getJSON = function(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.setRequestHeader('Accept', 'application/json'); - xhr.onerror = function(e) { - callback(e); - }; - xhr.onload = function() { - if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { - var data; - try { - data = JSON.parse(xhr.response); - } catch (err) { - return callback(err); - } - callback(null, data); - } else { - callback(new Error(xhr.statusText)); - } - }; - xhr.send(); - return xhr; -}; - -exports.getArrayBuffer = function(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onerror = function(e) { - callback(e); - }; - xhr.onload = function() { - if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { - callback(null, xhr.response); - } else { - callback(new Error(xhr.statusText)); - } - }; - xhr.send(); - return xhr; -}; - -function sameOrigin(url) { - var a = document.createElement('a'); - a.href = url; - return a.protocol === document.location.protocol && a.host === document.location.host; -} - -exports.getImage = function(url, callback) { - return exports.getArrayBuffer(url, function(err, imgData) { - if (err) return callback(err); - var img = new Image(); - img.onload = function() { - callback(null, img); - (window.URL || window.webkitURL).revokeObjectURL(img.src); - }; - var blob = new Blob([new Uint8Array(imgData)], { type: 'image/png' }); - img.src = (window.URL || window.webkitURL).createObjectURL(blob); - img.getData = function() { - var canvas = document.createElement('canvas'); - var context = canvas.getContext('2d'); - canvas.width = img.width; - canvas.height = img.height; - context.drawImage(img, 0, 0); - return context.getImageData(0, 0, img.width, img.height).data; - }; - return img; - }); -}; - -exports.getVideo = function(urls, callback) { - var video = document.createElement('video'); - video.onloadstart = function() { - callback(null, video); - }; - for (var i = 0; i < urls.length; i++) { - var s = document.createElement('source'); - if (!sameOrigin(urls[i])) { - video.crossOrigin = 'Anonymous'; - } - s.src = urls[i]; - video.appendChild(s); - } - video.getData = function() { return video; }; - return video; -}; - -},{}],55:[function(require,module,exports){ -'use strict'; - -var quickselect = require('quickselect'); - -// classifies an array of rings into polygons with outer rings and holes -module.exports = function classifyRings(rings, maxRings) { - var len = rings.length; - - if (len <= 1) return [rings]; - - var polygons = [], - 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); - - // Earcut performance degrages with the # of rings in a polygon. For this - // reason, we limit strip out all but the `maxRings` largest rings. - 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 calculateSignedArea(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; -} - -},{"quickselect":67}],56:[function(require,module,exports){ -'use strict'; - -var assert = require('assert'); - -module.exports = 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(string) { - assert(string in this._stringToNumber); - return this._stringToNumber[string]; -}; - -DictionaryCoder.prototype.decode = function(n) { - assert(n < this._numberToString.length); - return this._numberToString[n]; -}; - -},{"assert":1}],57:[function(require,module,exports){ -'use strict'; - -var util = require('./util'); - -/** - * Methods mixed in to other classes for event capabilities. - * - * @mixin Evented - */ -var Evented = { - - /** - * Adds a listener to a specified event type. - * - * @param {string} type The event type to add a listen for. - * @param {Function} listener The function to be called when the event is fired. - * The listener function is called with the data object passed to `fire`, - * extended with `target` and `type` properties. - * @returns {Object} `this` - */ - on: function(type, listener) { - this._events = this._events || {}; - this._events[type] = this._events[type] || []; - this._events[type].push(listener); - - return this; - }, - - /** - * Removes a previously registered event listener. - * - * @param {string} [type] The event type to remove listeners for. - * If none is specified, listeners will be removed for all event types. - * @param {Function} [listener] The listener function to remove. - * If none is specified, all listeners will be removed for the event type. - * @returns {Object} `this` - */ - off: function(type, listener) { - if (!type) { - // clear all listeners if no arguments specified - delete this._events; - return this; - } - - if (!this.listens(type)) return this; - - if (listener) { - var idx = this._events[type].indexOf(listener); - if (idx >= 0) { - this._events[type].splice(idx, 1); - } - if (!this._events[type].length) { - delete this._events[type]; - } - } else { - delete this._events[type]; - } - - return this; - }, - - /** - * Adds a listener that will be called only once to a specified event type. - * - * The listener will be called first time the event fires after the listener is registered. - * - * @param {string} type The event type to listen for. - * @param {Function} listener The function to be called when the event is fired the first time. - * @returns {Object} `this` - */ - once: function(type, listener) { - var wrapper = function(data) { - this.off(type, wrapper); - listener.call(this, data); - }.bind(this); - this.on(type, wrapper); - return this; - }, - - /** - * Fires an event of the specified type. - * - * @param {string} type The type of event to fire. - * @param {Object} [data] Data to be passed to any listeners. - * @returns {Object} `this` - */ - fire: function(type, data) { - if (!this.listens(type)) { - // To ensure that no error events are dropped, print them to the - // console if they have no listeners. - if (util.endsWith(type, 'error')) { - console.error((data && data.error) || data || 'Empty error event'); - } - return this; - } - - data = util.extend({}, data); - util.extend(data, {type: type, target: this}); - - // make sure adding/removing listeners inside other listeners won't cause infinite loop - var listeners = this._events[type].slice(); - - for (var i = 0; i < listeners.length; i++) { - listeners[i].call(this, data); - } - - return this; - }, - - /** - * Returns a Boolean indicating whether any listeners are registered for a specified event type. - * - * @param {string} type The event type to check. - * @returns {boolean} `true` if there is at least one registered listener for specified event type. - */ - listens: function(type) { - return !!(this._events && this._events[type]); - } -}; - -module.exports = Evented; - -},{"./util":62}],58:[function(require,module,exports){ -'use strict'; - -module.exports = interpolate; - -function interpolate(a, b, t) { - return (a * (1 - t)) + (b * t); -} - -interpolate.number = interpolate; - -interpolate.vec2 = function(from, to, t) { - return [ - interpolate(from[0], to[0], t), - interpolate(from[1], to[1], t) - ]; -}; - -/* - * Interpolate between two colors given as 4-element arrays. - * - * @param {Color} from - * @param {Color} to - * @param {number} t interpolation factor between 0 and 1 - * @returns {Color} interpolated color - */ -interpolate.color = function(from, to, t) { - return [ - interpolate(from[0], to[0], t), - interpolate(from[1], to[1], t), - interpolate(from[2], to[2], t), - interpolate(from[3], to[3], t) - ]; -}; - -interpolate.array = function(from, to, t) { - return from.map(function(d, i) { - return interpolate(d, to[i], t); - }); -}; - -},{}],59:[function(require,module,exports){ -'use strict'; - -module.exports = { - multiPolygonIntersectsBufferedMultiPoint: multiPolygonIntersectsBufferedMultiPoint, - multiPolygonIntersectsMultiPolygon: multiPolygonIntersectsMultiPolygon, - multiPolygonIntersectsBufferedMultiLine: multiPolygonIntersectsBufferedMultiLine -}; - -function multiPolygonIntersectsBufferedMultiPoint(multiPolygon, rings, radius) { - for (var j = 0; j < multiPolygon.length; j++) { - var polygon = multiPolygon[j]; - for (var i = 0; i < rings.length; i++) { - var ring = rings[i]; - for (var k = 0; k < ring.length; k++) { - var point = ring[k]; - if (polygonContainsPoint(polygon, point)) return true; - if (pointIntersectsBufferedLine(point, polygon, radius)) return true; - } - } - } - return false; -} - -function multiPolygonIntersectsMultiPolygon(multiPolygonA, multiPolygonB) { - - if (multiPolygonA.length === 1 && multiPolygonA[0].length === 1) { - return multiPolygonContainsPoint(multiPolygonB, multiPolygonA[0][0]); - } - - for (var m = 0; m < multiPolygonB.length; m++) { - var ring = multiPolygonB[m]; - for (var n = 0; n < ring.length; n++) { - if (multiPolygonContainsPoint(multiPolygonA, ring[n])) return true; - } - } - - for (var j = 0; j < multiPolygonA.length; j++) { - var polygon = multiPolygonA[j]; - for (var i = 0; i < polygon.length; i++) { - if (multiPolygonContainsPoint(multiPolygonB, polygon[i])) return true; - } - - for (var k = 0; k < multiPolygonB.length; k++) { - if (lineIntersectsLine(polygon, multiPolygonB[k])) return true; - } - } - - return false; -} - -function multiPolygonIntersectsBufferedMultiLine(multiPolygon, multiLine, radius) { - for (var i = 0; i < multiLine.length; i++) { - var line = multiLine[i]; - - for (var j = 0; j < multiPolygon.length; j++) { - var polygon = multiPolygon[j]; - - 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; - - // Check whether any point in either line is within radius of the other line - 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) { - 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; -} - - -// http://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/ -function isCounterClockwise(a, b, c) { - return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x); -} - -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++) { - // Find line segments that have a distance <= radius^2 to p - // In that case, we treat the line as "containing point p". - var v = line[i - 1], w = line[i]; - if (distToSegmentSquared(p, v, w) < radiusSquared) return true; - } - return false; -} - -// Code from http://stackoverflow.com/a/1501725/331379. -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)); -} - -// point in polygon ray casting algorithm -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; -} - -},{}],60:[function(require,module,exports){ -'use strict'; - -// Note: all "sizes" are measured in bytes - -var assert = require('assert'); - -module.exports = StructArrayType; - -var viewTypes = { - 'Int8': Int8Array, - 'Uint8': Uint8Array, - 'Uint8Clamped': Uint8ClampedArray, - 'Int16': Int16Array, - 'Uint16': Uint16Array, - 'Int32': Int32Array, - 'Uint32': Uint32Array, - 'Float32': Float32Array, - 'Float64': Float64Array -}; - -/** - * @typedef StructMember - * @private - * @property {string} name - * @property {string} type - * @property {number} components - */ - -var structArrayTypeCache = {}; - -/** - * `StructArrayType` is used to create new `StructArray` types. - * - * `StructArray` provides an abstraction over `ArrayBuffer` and `TypedArray` making it behave like - * an array of typed structs. A StructArray is comprised of elements. Each element has a set of - * members that are defined when the `StructArrayType` is created. - * - * StructArrays useful for creating large arrays that: - * - can be transferred from workers as a Transferable object - * - can be copied cheaply - * - use less memory for lower-precision members - * - can be used as buffers in WebGL. - * - * @class StructArrayType - * @param {Array.} - * @param options - * @param {number} options.alignment Use `4` to align members to 4 byte boundaries. Default is 1. - * - * @example - * - * var PointArrayType = new StructArrayType({ - * members: [ - * { type: 'Int16', name: 'x' }, - * { type: 'Int16', name: 'y' } - * ]}); - * - * var pointArray = new PointArrayType(); - * pointArray.emplaceBack(10, 15); - * pointArray.emplaceBack(20, 35); - * - * point = pointArray.get(0); - * assert(point.x === 10); - * assert(point.y === 15); - * - * @private - */ -function StructArrayType(options) { - - var key = JSON.stringify(options); - if (structArrayTypeCache[key]) { - return structArrayTypeCache[key]; - } - - if (options.alignment === undefined) options.alignment = 1; - - function StructType() { - Struct.apply(this, arguments); - } - - StructType.prototype = Object.create(Struct.prototype); - - var offset = 0; - var maxSize = 0; - var usedTypes = ['Uint8']; - - StructType.prototype.members = options.members.map(function(member) { - member = { - name: member.name, - type: member.type, - components: member.components || 1 - }; - - assert(member.name.length); - assert(member.type in viewTypes); - - if (usedTypes.indexOf(member.type) < 0) usedTypes.push(member.type); - - var typeSize = sizeOf(member.type); - maxSize = Math.max(maxSize, typeSize); - member.offset = offset = align(offset, Math.max(options.alignment, typeSize)); - - for (var c = 0; c < member.components; c++) { - Object.defineProperty(StructType.prototype, member.name + (member.components === 1 ? '' : c), { - get: createGetter(member, c), - set: createSetter(member, c) - }); - } - - offset += typeSize * member.components; - - return member; - }); - - StructType.prototype.alignment = options.alignment; - StructType.prototype.size = align(offset, Math.max(maxSize, options.alignment)); - - function StructArrayType() { - StructArray.apply(this, arguments); - this.members = StructType.prototype.members; - } - - StructArrayType.serialize = serializeStructArrayType; - - StructArrayType.prototype = Object.create(StructArray.prototype); - StructArrayType.prototype.StructType = StructType; - StructArrayType.prototype.bytesPerElement = StructType.prototype.size; - StructArrayType.prototype.emplaceBack = createEmplaceBack(StructType.prototype.members, StructType.prototype.size); - StructArrayType.prototype._usedTypes = usedTypes; - - - structArrayTypeCache[key] = StructArrayType; - - return StructArrayType; -} - -/** - * Serialize the StructArray type. This serializes the *type* not an instance of the type. - * @private - */ -function serializeStructArrayType() { - return { - members: this.prototype.StructType.prototype.members, - alignment: this.prototype.StructType.prototype.alignment, - bytesPerElement: this.prototype.bytesPerElement - }; -} - - -function align(offset, size) { - return Math.ceil(offset / size) * size; -} - -function sizeOf(type) { - return viewTypes[type].BYTES_PER_ELEMENT; -} - -function getArrayViewName(type) { - return type.toLowerCase(); -} - - -/* - * > I saw major perf gains by shortening the source of these generated methods (i.e. renaming - * > elementIndex to i) (likely due to v8 inlining heuristics). - * - lucaswoj - */ -function createEmplaceBack(members, bytesPerElement) { - var usedTypeSizes = []; - var argNames = []; - var body = '' + - 'var i = this.length;\n' + - 'this.resize(this.length + 1);\n'; - - for (var m = 0; m < members.length; m++) { - var member = members[m]; - var size = sizeOf(member.type); - - // array offsets to the end of current data for each type size - // var o{SIZE} = i * ROUNDED(bytesPerElement / size); - if (usedTypeSizes.indexOf(size) < 0) { - usedTypeSizes.push(size); - body += 'var o' + size.toFixed(0) + ' = i * ' + (bytesPerElement / size).toFixed(0) + ';\n'; - } - - for (var c = 0; c < member.components; c++) { - // arguments v0, v1, v2, ... are, in order, the components of - // member 0, then the components of member 1, etc. - var argName = 'v' + argNames.length; - // The index for `member` component `c` into the appropriate type array is: - // this.{TYPE}[o{SIZE} + MEMBER_OFFSET + {c}] = v{X} - // where MEMBER_OFFSET = ROUND(member.offset / size) is the per-element - // offset of this member into the array - var index = 'o' + size.toFixed(0) + ' + ' + (member.offset / size + c).toFixed(0); - body += 'this.' + getArrayViewName(member.type) + '[' + index + '] = ' + argName + ';\n'; - argNames.push(argName); - } - } - - body += 'return i;'; - - return new Function(argNames, body); -} - -function createMemberComponentString(member, component) { - var elementOffset = 'this._pos' + sizeOf(member.type).toFixed(0); - var componentOffset = (member.offset / sizeOf(member.type) + component).toFixed(0); - var index = elementOffset + ' + ' + componentOffset; - return 'this._structArray.' + getArrayViewName(member.type) + '[' + index + ']'; - -} - -function createGetter(member, c) { - return new Function([], 'return ' + createMemberComponentString(member, c) + ';'); -} - -function createSetter(member, c) { - return new Function(['x'], createMemberComponentString(member, c) + ' = x;'); -} - -/** - * @class Struct - * @param {StructArray} structArray The StructArray the struct is stored in - * @param {number} index The index of the struct in the StructArray. - * @private - */ -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; -} - -/** - * @class StructArray - * The StructArray class is inherited by the custom StructArrayType classes created with - * `new StructArrayType(members, options)`. - * @private - */ -function StructArray(serialized) { - if (serialized !== undefined) { - // Create from an serialized StructArray - this.arrayBuffer = serialized.arrayBuffer; - this.length = serialized.length; - this.capacity = this.arrayBuffer.byteLength / this.bytesPerElement; - this._refreshViews(); - - // Create a new StructArray - } else { - this.capacity = -1; - this.resize(0); - } -} - -/** - * @property {number} - * @private - * @readonly - */ -StructArray.prototype.DEFAULT_CAPACITY = 128; - -/** - * @property {number} - * @private - * @readonly - */ -StructArray.prototype.RESIZE_MULTIPLIER = 5; - -/** - * Serialize this StructArray instance - * @private - */ -StructArray.prototype.serialize = function() { - this.trim(); - return { - length: this.length, - arrayBuffer: this.arrayBuffer - }; -}; - -/** - * Return the Struct at the given location in the array. - * @private - * @param {number} index The index of the element. - */ -StructArray.prototype.get = function(index) { - return new this.StructType(this, index); -}; - -/** - * Resize the array to discard unused capacity. - * @private - */ -StructArray.prototype.trim = function() { - if (this.length !== this.capacity) { - this.capacity = this.length; - this.arrayBuffer = this.arrayBuffer.slice(0, this.length * this.bytesPerElement); - this._refreshViews(); - } -}; - -/** - * Resize the array. - * If `n` is greater than the current length then additional elements with undefined values are added. - * If `n` is less than the current length then the array will be reduced to the first `n` elements. - * @param {number} n The new size of the array. - */ -StructArray.prototype.resize = function(n) { - this.length = n; - if (n > this.capacity) { - this.capacity = Math.max(n, Math.floor(this.capacity * this.RESIZE_MULTIPLIER), this.DEFAULT_CAPACITY); - this.arrayBuffer = new ArrayBuffer(this.capacity * this.bytesPerElement); - - var oldUint8Array = this.uint8; - this._refreshViews(); - if (oldUint8Array) this.uint8.set(oldUint8Array); - } -}; - -/** - * Create TypedArray views for the current ArrayBuffer. - * @private - */ -StructArray.prototype._refreshViews = function() { - for (var t = 0; t < this._usedTypes.length; t++) { - var type = this._usedTypes[t]; - this[getArrayViewName(type)] = new viewTypes[type](this.arrayBuffer); - } -}; - -/** - * Output the `StructArray` between indices `startIndex` and `endIndex` as an array of `StructTypes` to enable sorting - * @param {number} startIndex - * @param {number} endIndex - * @private - */ -StructArray.prototype.toArray = function(startIndex, endIndex) { - var array = []; - - for (var i = startIndex; i < endIndex; i++) { - var struct = this.get(i); - array.push(struct); - } - - return array; -}; - -},{"assert":1}],61:[function(require,module,exports){ -'use strict'; - -module.exports = resolveTokens; - -/** - * Replace tokens in a string template with values in an object - * - * @param {Object} properties a key/value relationship between tokens and replacements - * @param {string} text the template string - * @returns {string} the template with tokens replaced - * @private - */ -function resolveTokens(properties, text) { - return text.replace(/{([^{}]+)}/g, function(match, key) { - return key in properties ? properties[key] : ''; - }); -} - -},{}],62:[function(require,module,exports){ -'use strict'; - -var UnitBezier = require('unitbezier'); -var Coordinate = require('../geo/coordinate'); - -/** - * Given a value `t` that varies between 0 and 1, return - * an interpolation function that eases between 0 and 1 in a pleasing - * cubic in-out fashion. - * - * @param {number} t input - * @returns {number} input - * @private - */ -exports.easeCubicInOut = function (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); -}; - -/** - * Given given (x, y), (x1, y1) control points for a bezier curve, - * return a function that interpolates along that curve. - * - * @param {number} p1x control point 1 x coordinate - * @param {number} p1y control point 1 y coordinate - * @param {number} p2x control point 2 x coordinate - * @param {number} p2y control point 2 y coordinate - * @returns {Function} interpolator: receives number value, returns - * number value. - * @private - */ -exports.bezier = function(p1x, p1y, p2x, p2y) { - var bezier = new UnitBezier(p1x, p1y, p2x, p2y); - return function(t) { - return bezier.solve(t); - }; -}; - -/** - * A default bezier-curve powered easing function with - * control points (0.25, 0.1) and (0.25, 1) - * - * @param {number} t - * @returns {number} output - * @private - */ -exports.ease = exports.bezier(0.25, 0.1, 0.25, 1); - -/** - * constrain n to the given range via min + max - * - * @param {number} n value - * @param {number} min the minimum value to be returned - * @param {number} max the maximum value to be returned - * @returns {number} the clamped value - * @private - */ -exports.clamp = function (n, min, max) { - return Math.min(max, Math.max(min, n)); -}; - -/* - * constrain n to the given range, excluding the minimum, via modular arithmetic - * @param {number} n value - * @param {number} min the minimum value to be returned, exclusive - * @param {number} max the maximum value to be returned, inclusive - * @returns {number} constrained number - * @private - */ -exports.wrap = function (n, min, max) { - var d = max - min; - var w = ((n - min) % d + d) % d + min; - return (w === min) ? max : w; -}; - -/* - * return the first non-null and non-undefined argument to this function. - * @returns {*} argument - * @private - */ -exports.coalesce = function() { - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - if (arg !== null && arg !== undefined) - return arg; - } -}; - -/* - * Call an asynchronous function on an array of arguments, - * calling `callback` with the completed results of all calls. - * - * @param {Array<*>} array input to each call of the async function. - * @param {Function} fn an async function with signature (data, callback) - * @param {Function} callback a callback run after all async work is done. - * called with an array, containing the results of each async call. - * @returns {undefined} - * @private - */ -exports.asyncAll = function (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); - }); - }); -}; - -/* - * Compute the difference between the keys in one object and the keys - * in another object. - * - * @param {Object} obj - * @param {Object} other - * @returns {Array} keys difference - * @private - */ -exports.keysDifference = function (obj, other) { - var difference = []; - for (var i in obj) { - if (!(i in other)) { - difference.push(i); - } - } - return difference; -}; - -/** - * Given a destination object and optionally many source objects, - * copy all properties from the source objects into the destination. - * The last source object given overrides properties from previous - * source objects. - * @param {Object} dest destination object - * @param {...Object} sources sources from which properties are pulled - * @returns {Object} dest - * @private - */ -exports.extend = function (dest) { - for (var i = 1; i < arguments.length; i++) { - var src = arguments[i]; - for (var k in src) { - dest[k] = src[k]; - } - } - return dest; -}; - -/** - * Extend a destination object with all properties of the src object, - * using defineProperty instead of simple assignment. - * @param {Object} dest - * @param {Object} src - * @returns {Object} dest - * @private - */ -exports.extendAll = function (dest, src) { - for (var i in src) { - Object.defineProperty(dest, i, Object.getOwnPropertyDescriptor(src, i)); - } - return dest; -}; - -/** - * Extend a parent's prototype with all properties in a properties - * object. - * - * @param {Object} parent - * @param {Object} props - * @returns {Object} - * @private - */ -exports.inherit = function (parent, props) { - var parentProto = typeof parent === 'function' ? parent.prototype : parent, - proto = Object.create(parentProto); - exports.extendAll(proto, props); - return proto; -}; - -/** - * Given an object and a number of properties as strings, return version - * of that object with only those properties. - * - * @param {Object} src the object - * @param {Array} properties an array of property names chosen - * to appear on the resulting object. - * @returns {Object} object with limited properties. - * @example - * var foo = { name: 'Charlie', age: 10 }; - * var justName = pick(foo, ['name']); - * // justName = { name: 'Charlie' } - * @private - */ -exports.pick = function (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; - -/** - * Return a unique numeric id, starting at 1 and incrementing with - * each call. - * - * @returns {number} unique numeric id. - * @private - */ -exports.uniqueId = function () { - return id++; -}; - -/** - * Create a version of `fn` that is only called `time` milliseconds - * after its last invocation - * - * @param {Function} fn the function to be debounced - * @param {number} time millseconds after which the function will be invoked - * @returns {Function} debounced function - * @private - */ -exports.debounce = function(fn, time) { - var timer, args; - - return function() { - args = arguments; - clearTimeout(timer); - - timer = setTimeout(function() { - fn.apply(null, args); - }, time); - }; -}; - -/** - * Given an array of member function names as strings, replace all of them - * with bound versions that will always refer to `context` as `this`. This - * is useful for classes where otherwise event bindings would reassign - * `this` to the evented object or some other value: this lets you ensure - * the `this` value always. - * - * @param {Array} fns list of member function names - * @param {*} context the context value - * @returns {undefined} changes functions in-place - * @example - * function MyClass() { - * bindAll(['ontimer'], this); - * this.name = 'Tom'; - * } - * MyClass.prototype.ontimer = function() { - * alert(this.name); - * }; - * var myClass = new MyClass(); - * setTimeout(myClass.ontimer, 100); - * @private - */ -exports.bindAll = function(fns, context) { - fns.forEach(function(fn) { - if (!context[fn]) { return; } - context[fn] = context[fn].bind(context); - }); -}; - -/** - * Given a class, bind all of the methods that look like handlers: that - * begin with _on, and bind them to the class. - * - * @param {Object} context an object with methods - * @private - */ -exports.bindHandlers = function(context) { - for (var i in context) { - if (typeof context[i] === 'function' && i.indexOf('_on') === 0) { - context[i] = context[i].bind(context); - } - } -}; - -/** - * Set the 'options' property on `obj` with properties - * from the `options` argument. Properties in the `options` - * object will override existing properties. - * - * @param {Object} obj destination object - * @param {Object} options object of override options - * @returns {Object} derived options object. - * @private - */ -exports.setOptions = function(obj, options) { - if (!obj.hasOwnProperty('options')) { - obj.options = obj.options ? Object.create(obj.options) : {}; - } - for (var i in options) { - obj.options[i] = options[i]; - } - return obj.options; -}; - -/** - * Given a list of coordinates, get their center as a coordinate. - * @param {Array} coords - * @returns {Coordinate} centerpoint - * @private - */ -exports.getCoordinatesCenter = function(coords) { - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - - for (var i = 0; i < coords.length; i++) { - minX = Math.min(minX, coords[i].column); - minY = Math.min(minY, coords[i].row); - maxX = Math.max(maxX, coords[i].column); - maxY = Math.max(maxY, coords[i].row); - } - - var dx = maxX - minX; - var dy = maxY - minY; - var dMax = Math.max(dx, dy); - return new Coordinate((minX + maxX) / 2, (minY + maxY) / 2, 0) - .zoomTo(Math.floor(-Math.log(dMax) / Math.LN2)); -}; - -/** - * Determine if a string ends with a particular substring - * @param {string} string - * @param {string} suffix - * @returns {boolean} - * @private - */ -exports.endsWith = function(string, suffix) { - return string.indexOf(suffix, string.length - suffix.length) !== -1; -}; - -/** - * Determine if a string starts with a particular substring - * @param {string} string - * @param {string} prefix - * @returns {boolean} - * @private - */ -exports.startsWith = function(string, prefix) { - return string.indexOf(prefix) === 0; -}; - -/** - * Create an object by mapping all the values of an existing object while - * preserving their keys. - * @param {Object} input - * @param {Function} iterator - * @returns {Object} - * @private - */ -exports.mapObject = function(input, iterator, context) { - var output = {}; - for (var key in input) { - output[key] = iterator.call(context || this, input[key], key, input); - } - return output; -}; - -/** - * Create an object by filtering out values of an existing object - * @param {Object} input - * @param {Function} iterator - * @returns {Object} - * @private - */ -exports.filterObject = function(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; -}; - -/** - * Deeply compares two object literals. - * @param {Object} obj1 - * @param {Object} obj2 - * @returns {boolean} - * @private - */ -exports.deepEqual = 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; -}; - -/** - * Deeply clones two objects. - * @param {Object} obj1 - * @param {Object} obj2 - * @returns {boolean} - * @private - */ -exports.clone = function deepEqual(input) { - if (Array.isArray(input)) { - return input.map(exports.clone); - } else if (typeof input === 'object') { - return exports.mapObject(input, exports.clone); - } else { - return input; - } -}; - -/** - * Check if two arrays have at least one common element. - * @param {Array} a - * @param {Array} b - * @returns {boolean} - * @private - */ -exports.arraysIntersect = function(a, b) { - for (var l = 0; l < a.length; l++) { - if (b.indexOf(a[l]) >= 0) return true; - } - return false; -}; - -var warnOnceHistory = {}; -exports.warnOnce = function(message) { - if (!warnOnceHistory[message]) { - // console isn't defined in some WebWorkers, see #2558 - if (typeof console !== "undefined") console.warn(message); - warnOnceHistory[message] = true; - } -}; - -},{"../geo/coordinate":34,"unitbezier":71}],63:[function(require,module,exports){ -'use strict'; - -module.exports = Feature; - -function Feature(vectorTileFeature, z, x, y) { - this._vectorTileFeature = vectorTileFeature; - vectorTileFeature._z = z; - vectorTileFeature._x = x; - vectorTileFeature._y = y; - - this.properties = vectorTileFeature.properties; - - if (vectorTileFeature.id != null) { - this.id = vectorTileFeature.id; - } -} - -Feature.prototype = { - type: "Feature", - - get geometry() { - if (this._geometry === undefined) { - this._geometry = this._vectorTileFeature.toGeoJSON( - this._vectorTileFeature._x, - this._vectorTileFeature._y, - this._vectorTileFeature._z).geometry; - } - return this._geometry; - }, - - set geometry(g) { - this._geometry = g; - }, - - toJSON: function() { - var json = {}; - for (var i in this) { - if (i === '_geometry' || i === '_vectorTileFeature' || i === 'toJSON') continue; - json[i] = this[i]; - } - return json; - } -}; - -},{}],64:[function(require,module,exports){ -'use strict'; - -// lightweight Buffer shim for pbf browser build -// based on code from github.com/feross/buffer (MIT-licensed) - -module.exports = Buffer; - -var ieee754 = require('ieee754'); - -var BufferMethods; - -function Buffer(length) { - var arr; - if (length && length.length) { - arr = length; - length = arr.length; - } - var buf = new Uint8Array(length || 0); - if (arr) buf.set(arr); - - buf.readUInt32LE = BufferMethods.readUInt32LE; - buf.writeUInt32LE = BufferMethods.writeUInt32LE; - buf.readInt32LE = BufferMethods.readInt32LE; - buf.writeInt32LE = BufferMethods.writeInt32LE; - buf.readFloatLE = BufferMethods.readFloatLE; - buf.writeFloatLE = BufferMethods.writeFloatLE; - buf.readDoubleLE = BufferMethods.readDoubleLE; - buf.writeDoubleLE = BufferMethods.writeDoubleLE; - buf.toString = BufferMethods.toString; - buf.write = BufferMethods.write; - buf.slice = BufferMethods.slice; - buf.copy = BufferMethods.copy; - - buf._isBuffer = true; - return buf; -} - -var lastStr, lastStrEncoded; - -BufferMethods = { - readUInt32LE: function(pos) { - return ((this[pos]) | - (this[pos + 1] << 8) | - (this[pos + 2] << 16)) + - (this[pos + 3] * 0x1000000); - }, - - writeUInt32LE: function(val, pos) { - this[pos] = val; - this[pos + 1] = (val >>> 8); - this[pos + 2] = (val >>> 16); - this[pos + 3] = (val >>> 24); - }, - - readInt32LE: function(pos) { - return ((this[pos]) | - (this[pos + 1] << 8) | - (this[pos + 2] << 16)) + - (this[pos + 3] << 24); - }, - - readFloatLE: function(pos) { return ieee754.read(this, pos, true, 23, 4); }, - readDoubleLE: function(pos) { return ieee754.read(this, pos, true, 52, 8); }, - - writeFloatLE: function(val, pos) { return ieee754.write(this, val, pos, true, 23, 4); }, - writeDoubleLE: function(val, pos) { return ieee754.write(this, val, pos, true, 52, 8); }, - - toString: function(encoding, start, end) { - var str = '', - tmp = ''; - - start = start || 0; - end = Math.min(this.length, end || this.length); - - for (var i = start; i < end; i++) { - var ch = this[i]; - if (ch <= 0x7F) { - str += decodeURIComponent(tmp) + String.fromCharCode(ch); - tmp = ''; - } else { - tmp += '%' + ch.toString(16); - } - } - - str += decodeURIComponent(tmp); - - return str; - }, - - write: function(str, pos) { - var bytes = str === lastStr ? lastStrEncoded : encodeString(str); - for (var i = 0; i < bytes.length; i++) { - this[pos + i] = bytes[i]; - } - }, - - slice: function(start, end) { - return this.subarray(start, end); - }, - - copy: function(buf, pos) { - pos = pos || 0; - for (var i = 0; i < this.length; i++) { - buf[pos + i] = this[i]; - } - } -}; - -BufferMethods.writeInt32LE = BufferMethods.writeUInt32LE; - -Buffer.byteLength = function(str) { - lastStr = str; - lastStrEncoded = encodeString(str); - return lastStrEncoded.length; -}; - -Buffer.isBuffer = function(buf) { - return !!(buf && buf._isBuffer); -}; - -function encodeString(str) { - var length = str.length, - bytes = []; - - for (var i = 0, c, lead; i < length; i++) { - c = str.charCodeAt(i); // code point - - if (c > 0xD7FF && c < 0xE000) { - - if (lead) { - if (c < 0xDC00) { - bytes.push(0xEF, 0xBF, 0xBD); - lead = c; - continue; - - } else { - c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000; - lead = null; - } - - } else { - if (c > 0xDBFF || (i + 1 === length)) bytes.push(0xEF, 0xBF, 0xBD); - else lead = c; - - continue; - } - - } else if (lead) { - bytes.push(0xEF, 0xBF, 0xBD); - lead = null; - } - - if (c < 0x80) bytes.push(c); - else if (c < 0x800) bytes.push(c >> 0x6 | 0xC0, c & 0x3F | 0x80); - else if (c < 0x10000) bytes.push(c >> 0xC | 0xE0, c >> 0x6 & 0x3F | 0x80, c & 0x3F | 0x80); - else bytes.push(c >> 0x12 | 0xF0, c >> 0xC & 0x3F | 0x80, c >> 0x6 & 0x3F | 0x80, c & 0x3F | 0x80); - } - return bytes; -} - -},{"ieee754":19}],65:[function(require,module,exports){ -(function (global){ -'use strict'; - -module.exports = Pbf; - -var Buffer = global.Buffer || require('./buffer'); - -function Pbf(buf) { - this.buf = !Buffer.isBuffer(buf) ? new Buffer(buf || 0) : buf; - this.pos = 0; - this.length = this.buf.length; -} - -Pbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum -Pbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64 -Pbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields -Pbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32 - -var SHIFT_LEFT_32 = (1 << 16) * (1 << 16), - SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32, - POW_2_63 = Math.pow(2, 63); - -Pbf.prototype = { - - destroy: function() { - this.buf = null; - }, - - // === READING ================================================================= - - readFields: function(readField, result, end) { - end = end || this.length; - - while (this.pos < end) { - var val = this.readVarint(), - tag = val >> 3, - startPos = this.pos; - - 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 = this.buf.readUInt32LE(this.pos); - this.pos += 4; - return val; - }, - - readSFixed32: function() { - var val = this.buf.readInt32LE(this.pos); - this.pos += 4; - return val; - }, - - // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed) - - readFixed64: function() { - var val = this.buf.readUInt32LE(this.pos) + this.buf.readUInt32LE(this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - - readSFixed64: function() { - var val = this.buf.readUInt32LE(this.pos) + this.buf.readInt32LE(this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - - readFloat: function() { - var val = this.buf.readFloatLE(this.pos); - this.pos += 4; - return val; - }, - - readDouble: function() { - var val = this.buf.readDoubleLE(this.pos); - this.pos += 8; - return val; - }, - - readVarint: function() { - var buf = this.buf, - val, b; - - b = buf[this.pos++]; val = b & 0x7f; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 7; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val; - - return readVarintRemainder(val, this); - }, - - readVarint64: function() { - var startPos = this.pos, - val = this.readVarint(); - - if (val < POW_2_63) return val; - - var pos = this.pos - 2; - while (this.buf[pos] === 0xff) pos--; - if (pos < startPos) pos = startPos; - - val = 0; - for (var i = 0; i < pos - startPos + 1; i++) { - var b = ~this.buf[startPos + i] & 0x7f; - val += i < 4 ? b << i * 7 : b * Math.pow(2, i * 7); - } - - return -val - 1; - }, - - readSVarint: function() { - var num = this.readVarint(); - return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding - }, - - readBoolean: function() { - return Boolean(this.readVarint()); - }, - - readString: function() { - var end = this.readVarint() + this.pos, - str = this.buf.toString('utf8', this.pos, end); - this.pos = end; - return str; - }, - - readBytes: function() { - var end = this.readVarint() + this.pos, - buffer = this.buf.slice(this.pos, end); - this.pos = end; - return buffer; - }, - - // verbose for performance reasons; doesn't affect gzipped size - - readPackedVarint: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readVarint()); - return arr; - }, - readPackedSVarint: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSVarint()); - return arr; - }, - readPackedBoolean: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readBoolean()); - return arr; - }, - readPackedFloat: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFloat()); - return arr; - }, - readPackedDouble: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readDouble()); - return arr; - }, - readPackedFixed32: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFixed32()); - return arr; - }, - readPackedSFixed32: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSFixed32()); - return arr; - }, - readPackedFixed64: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFixed64()); - return arr; - }, - readPackedSFixed64: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSFixed64()); - return arr; - }, - - skip: function(val) { - var type = val & 0x7; - if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {} - 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); - }, - - // === WRITING ================================================================= - - 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 Buffer(length); - this.buf.copy(buf); - this.buf = buf; - this.length = length; - } - }, - - finish: function() { - this.length = this.pos; - this.pos = 0; - return this.buf.slice(0, this.length); - }, - - writeFixed32: function(val) { - this.realloc(4); - this.buf.writeUInt32LE(val, this.pos); - this.pos += 4; - }, - - writeSFixed32: function(val) { - this.realloc(4); - this.buf.writeInt32LE(val, this.pos); - this.pos += 4; - }, - - writeFixed64: function(val) { - this.realloc(8); - this.buf.writeInt32LE(val & -1, this.pos); - this.buf.writeUInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - - writeSFixed64: function(val) { - this.realloc(8); - this.buf.writeInt32LE(val & -1, this.pos); - this.buf.writeInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - - writeVarint: function(val) { - val = +val; - - if (val > 0xfffffff) { - writeBigVarint(val, this); - return; - } - - this.realloc(4); - - this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = (val >>> 7) & 0x7f; - }, - - 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); - var bytes = Buffer.byteLength(str); - this.writeVarint(bytes); - this.realloc(bytes); - this.buf.write(str, this.pos); - this.pos += bytes; - }, - - writeFloat: function(val) { - this.realloc(4); - this.buf.writeFloatLE(val, this.pos); - this.pos += 4; - }, - - writeDouble: function(val) { - this.realloc(8); - this.buf.writeDoubleLE(val, this.pos); - 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++; // reserve 1 byte for short message length - - // write the message directly to the buffer and see how much was written - var startPos = this.pos; - fn(obj, this); - var len = this.pos - startPos; - - if (len >= 0x80) reallocForRawMessage(startPos, len, this); - - // finally, write the message length in the reserved place and restore the position - 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) { this.writeMessage(tag, writePackedVarint, arr); }, - writePackedSVarint: function(tag, arr) { this.writeMessage(tag, writePackedSVarint, arr); }, - writePackedBoolean: function(tag, arr) { this.writeMessage(tag, writePackedBoolean, arr); }, - writePackedFloat: function(tag, arr) { this.writeMessage(tag, writePackedFloat, arr); }, - writePackedDouble: function(tag, arr) { this.writeMessage(tag, writePackedDouble, arr); }, - writePackedFixed32: function(tag, arr) { this.writeMessage(tag, writePackedFixed32, arr); }, - writePackedSFixed32: function(tag, arr) { this.writeMessage(tag, writePackedSFixed32, arr); }, - writePackedFixed64: function(tag, arr) { this.writeMessage(tag, writePackedFixed64, arr); }, - writePackedSFixed64: function(tag, arr) { 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(val, pbf) { - var buf = pbf.buf, b; - - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x10000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x800000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x40000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x2000000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x100000000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x8000000000000000; if (b < 0x80) return val; - - throw new Error('Expected varint not more than 10 bytes'); -} - -function writeBigVarint(val, pbf) { - pbf.realloc(10); - - var maxPos = pbf.pos + 10; - - while (val >= 1) { - if (pbf.pos >= maxPos) throw new Error('Given varint doesn\'t fit into 10 bytes'); - var b = val & 0xff; - pbf.buf[pbf.pos++] = b | (val >= 0x80 ? 0x80 : 0); - val /= 0x80; - } -} - -function reallocForRawMessage(startPos, len, pbf) { - var extraLen = - len <= 0x3fff ? 1 : - len <= 0x1fffff ? 2 : - len <= 0xfffffff ? 3 : Math.ceil(Math.log(len) / (Math.LN2 * 7)); - - // if 1 byte isn't enough for encoding message length, shift the data to the right - 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]); } - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./buffer":64}],66:[function(require,module,exports){ -'use strict'; - -module.exports = 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); }, - mult: function(k) { return this.clone()._mult(k); }, - div: function(k) { return this.clone()._div(k); }, - rotate: function(a) { return this.clone()._rotate(a); }, - 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(p) { - return this.x === p.x && - this.y === p.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); - }, - - // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. - 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; - }, - - _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; - }, - - _round: function() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } -}; - -// constructs Point from an array if necessary -Point.convert = function (a) { - if (a instanceof Point) { - return a; - } - if (Array.isArray(a)) { - return new Point(a[0], a[1]); - } - return a; -}; - -},{}],67:[function(require,module,exports){ -'use strict'; - -module.exports = partialSort; - -// Floyd-Rivest selection algorithm: -// Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right]; -// The k-th element will have the (k - left + 1)th smallest value in [left, right] - -function partialSort(arr, k, left, right, compare) { - left = left || 0; - right = right || (arr.length - 1); - compare = compare || defaultCompare; - - 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)); - partialSort(arr, k, newLeft, newRight, compare); - } - - var t = arr[k]; - var i = left; - var j = right; - - swap(arr, left, k); - if (compare(arr[right], t) > 0) swap(arr, left, right); - - while (i < j) { - swap(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(arr, left, j); - else { - j++; - swap(arr, j, right); - } - - if (j <= k) left = j + 1; - if (k <= j) right = j - 1; - } -} - -function swap(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; -} - -},{}],68:[function(require,module,exports){ -// Copyright 2014 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) - -void (function(root, factory) { - if (typeof define === "function" && define.amd) { - define(factory) - } else if (typeof exports === "object") { - module.exports = factory() - } else { - root.resolveUrl = factory() - } -}(this, function() { - - function resolveUrl(/* ...urls */) { - var numUrls = arguments.length - - if (numUrls === 0) { - throw new Error("resolveUrl requires at least one argument; got none.") - } - - var base = document.createElement("base") - base.href = arguments[0] - - if (numUrls === 1) { - return base.href - } - - var head = document.getElementsByTagName("head")[0] - head.insertBefore(base, head.firstChild) - - var a = document.createElement("a") - var resolved - - for (var index = 1; index < numUrls; index++) { - a.href = arguments[index] - resolved = a.href - base.href = resolved - } - - head.removeChild(base) - - return resolved - } - - return resolveUrl - -})); - -},{}],69:[function(require,module,exports){ -'use strict'; - -var kdbush = require('kdbush'); - -module.exports = supercluster; - -function supercluster(options) { - return new SuperCluster(options); -} - -function SuperCluster(options) { - this.options = extend(Object.create(this.options), options); - this.trees = new Array(this.options.maxZoom + 1); -} - -SuperCluster.prototype = { - options: { - minZoom: 0, // min zoom to generate clusters on - maxZoom: 16, // max zoom level to cluster the points on - radius: 40, // cluster radius in pixels - extent: 512, // tile extent (radius is calculated relative to it) - nodeSize: 64, // size of the KD-tree leaf node, affects performance - log: false // whether to log timing info - }, - - load: function (points) { - var log = this.options.log; - - if (log) console.time('total time'); - - var timerId = 'prepare ' + points.length + ' points'; - if (log) console.time(timerId); - - this.points = points; - - // generate a cluster object for each point - var clusters = points.map(createPointCluster); - if (log) console.timeEnd(timerId); - - // cluster points on max zoom, then cluster the results on previous zoom, etc.; - // results in a cluster hierarchy across zoom levels - for (var z = this.options.maxZoom; z >= this.options.minZoom; z--) { - var now = +Date.now(); - - // index input points into a KD-tree - this.trees[z + 1] = kdbush(clusters, getX, getY, this.options.nodeSize, Float32Array); - - clusters = this._cluster(clusters, z); // create a new set of clusters for the zoom - - if (log) console.log('z%d: %d clusters in %dms', z, clusters.length, +Date.now() - now); - } - - // index top-level clusters - this.trees[this.options.minZoom] = kdbush(clusters, getX, getY, this.options.nodeSize, Float32Array); - - if (log) console.timeEnd('total time'); - - return this; - }, - - getClusters: function (bbox, zoom) { - var tree = this.trees[this._limitZoom(zoom)]; - var ids = tree.range(lngX(bbox[0]), latY(bbox[3]), lngX(bbox[2]), latY(bbox[1])); - var clusters = []; - for (var i = 0; i < ids.length; i++) { - var c = tree.points[ids[i]]; - clusters.push(c.id !== -1 ? this.points[c.id] : getClusterJSON(c)); - } - return clusters; - }, - - getTile: function (z, x, y) { - var z2 = Math.pow(2, z); - var extent = this.options.extent; - var p = this.options.radius / extent; - var tree = this.trees[this._limitZoom(z)]; - var ids = tree.range( - (x - p) / z2, - (y - p) / z2, - (x + 1 + p) / z2, - (y + 1 + p) / z2); - - if (!ids.length) return null; - - var tile = { - features: [] - }; - for (var i = 0; i < ids.length; i++) { - var c = tree.points[ids[i]]; - var feature = { - type: 1, - geometry: [[ - Math.round(extent * (c.x * z2 - x)), - Math.round(extent * (c.y * z2 - y)) - ]], - tags: c.id !== -1 ? this.points[c.id].properties : getClusterProperties(c) - }; - tile.features.push(feature); - } - return tile; - }, - - _limitZoom: function (z) { - return Math.max(this.options.minZoom, Math.min(z, this.options.maxZoom + 1)); - }, - - _cluster: function (points, zoom) { - var clusters = []; - var r = this.options.radius / (this.options.extent * Math.pow(2, zoom)); - - // loop through each point - for (var i = 0; i < points.length; i++) { - var p = points[i]; - // if we've already visited the point at this zoom level, skip it - if (p.zoom <= zoom) continue; - p.zoom = zoom; - - // find all nearby points - var tree = this.trees[zoom + 1]; - var neighborIds = tree.within(p.x, p.y, r); - - var foundNeighbors = false; - var numPoints = p.numPoints; - var wx = p.x * numPoints; - var wy = p.y * numPoints; - - for (var j = 0; j < neighborIds.length; j++) { - var b = tree.points[neighborIds[j]]; - // filter out neighbors that are too far or already processed - if (zoom < b.zoom) { - foundNeighbors = true; - b.zoom = zoom; // save the zoom (so it doesn't get processed twice) - wx += b.x * b.numPoints; // accumulate coordinates for calculating weighted center - wy += b.y * b.numPoints; - numPoints += b.numPoints; - } - } - - clusters.push(foundNeighbors ? createCluster(wx / numPoints, wy / numPoints, numPoints, -1) : p); - } - - return clusters; - } -}; - -function createCluster(x, y, numPoints, id) { - return { - x: x, // weighted cluster center - y: y, - zoom: Infinity, // the last zoom the cluster was processed at - id: id, // index of the source feature in the original input array - numPoints: numPoints - }; -} - -function createPointCluster(p, i) { - var coords = p.geometry.coordinates; - return createCluster(lngX(coords[0]), latY(coords[1]), 1, i); -} - -function getClusterJSON(cluster) { - return { - type: 'Feature', - 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 { - cluster: true, - point_count: count, - point_count_abbreviated: abbrev - }; -} - -// longitude/latitude to spherical mercator in [0..1] range -function lngX(lng) { - return lng / 360 + 0.5; -} -function latY(lat) { - var sin = Math.sin(lat * Math.PI / 180), - y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI); - return y < 0 ? 0 : - y > 1 ? 1 : y; -} - -// spherical mercator to longitude/latitude -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; -} - -},{"kdbush":20}],70:[function(require,module,exports){ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.topojson = global.topojson || {}))); -}(this, function (exports) { 'use strict'; - - function noop() {} - - function transformAbsolute(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - point[0] = (x0 += point[0]) * kx + dx; - point[1] = (y0 += point[1]) * ky + dy; - }; - } - - function transformRelative(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - var x1 = Math.round((point[0] - dx) / kx), - y1 = Math.round((point[1] - dy) / ky); - point[0] = x1 - x0; - point[1] = y1 - y0; - x0 = x1; - y0 = y1; - }; - } - - function reverse(array, n) { - var t, j = array.length, i = j - n; - while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; - } - - function bisect(a, x) { - var lo = 0, hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (a[mid] < x) lo = mid + 1; - else hi = mid; - } - return lo; - } - - function feature(topology, o) { - return o.type === "GeometryCollection" ? { - type: "FeatureCollection", - features: o.geometries.map(function(o) { return feature$1(topology, o); }) - } : feature$1(topology, o); - } - - function feature$1(topology, o) { - var f = { - type: "Feature", - id: o.id, - properties: o.properties || {}, - geometry: object(topology, o) - }; - if (o.id == null) delete f.id; - return f; - } - - function object(topology, o) { - var absolute = transformAbsolute(topology.transform), - arcs = topology.arcs; - - function arc(i, points) { - if (points.length) points.pop(); - for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { - points.push(p = a[k].slice()); - absolute(p, k); - } - if (i < 0) reverse(points, n); - } - - function point(p) { - p = p.slice(); - absolute(p, 0); - return p; - } - - function line(arcs) { - var points = []; - for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); - if (points.length < 2) points.push(points[0].slice()); - return points; - } - - function ring(arcs) { - var points = line(arcs); - while (points.length < 4) points.push(points[0].slice()); - return points; - } - - function polygon(arcs) { - return arcs.map(ring); - } - - function geometry(o) { - var t = o.type; - return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} - : t in geometryType ? {type: t, coordinates: geometryType[t](o)} - : null; - } - - var geometryType = { - Point: function(o) { return point(o.coordinates); }, - MultiPoint: function(o) { return o.coordinates.map(point); }, - LineString: function(o) { return line(o.arcs); }, - MultiLineString: function(o) { return o.arcs.map(line); }, - Polygon: function(o) { return polygon(o.arcs); }, - MultiPolygon: function(o) { return o.arcs.map(polygon); } - }; - - return geometry(o); - } - - function stitchArcs(topology, arcs) { - var stitchedArcs = {}, - fragmentByStart = {}, - fragmentByEnd = {}, - fragments = [], - emptyIndex = -1; - - // Stitch empty arcs first, since they may be subsumed by other arcs. - arcs.forEach(function(i, j) { - var arc = topology.arcs[i < 0 ? ~i : i], t; - if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { - t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; - } - }); - - arcs.forEach(function(i) { - var e = ends(i), - start = e[0], - end = e[1], - f, g; - - if (f = fragmentByEnd[start]) { - delete fragmentByEnd[f.end]; - f.push(i); - f.end = end; - if (g = fragmentByStart[end]) { - delete fragmentByStart[g.start]; - var fg = g === f ? f : f.concat(g); - fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; - } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; - } - } else if (f = fragmentByStart[end]) { - delete fragmentByStart[f.start]; - f.unshift(i); - f.start = start; - if (g = fragmentByEnd[start]) { - delete fragmentByEnd[g.end]; - var gf = g === f ? f : g.concat(f); - fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; - } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; - } - } else { - f = [i]; - fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; - } - }); - - function ends(i) { - var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; - if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); - else p1 = arc[arc.length - 1]; - return i < 0 ? [p1, p0] : [p0, p1]; - } - - function flush(fragmentByEnd, fragmentByStart) { - for (var k in fragmentByEnd) { - var f = fragmentByEnd[k]; - delete fragmentByStart[f.start]; - delete f.start; - delete f.end; - f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); - fragments.push(f); - } - } - - flush(fragmentByEnd, fragmentByStart); - flush(fragmentByStart, fragmentByEnd); - arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); - - return fragments; - } - - function mesh(topology) { - return object(topology, meshArcs.apply(this, arguments)); - } - - function meshArcs(topology, o, filter) { - var arcs = []; - - function arc(i) { - var j = i < 0 ? ~i : i; - (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); - } - - function line(arcs) { - arcs.forEach(arc); - } - - function polygon(arcs) { - arcs.forEach(line); - } - - function geometry(o) { - if (o.type === "GeometryCollection") o.geometries.forEach(geometry); - else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); - } - - if (arguments.length > 1) { - var geomsByArc = [], - geom; - - var geometryType = { - LineString: line, - MultiLineString: polygon, - Polygon: polygon, - MultiPolygon: function(arcs) { arcs.forEach(polygon); } - }; - - geometry(o); - - geomsByArc.forEach(arguments.length < 3 - ? function(geoms) { arcs.push(geoms[0].i); } - : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); - } else { - for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); - } - - return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; - } - - function cartesianTriangleArea(triangle) { - var a = triangle[0], b = triangle[1], c = triangle[2]; - return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); - } - - function ring(ring) { - var i = -1, - n = ring.length, - a, - b = ring[n - 1], - area = 0; - - while (++i < n) { - a = b; - b = ring[i]; - area += a[0] * b[1] - a[1] * b[0]; - } - - return area / 2; - } - - function merge(topology) { - return object(topology, mergeArcs.apply(this, arguments)); - } - - function mergeArcs(topology, objects) { - var polygonsByArc = {}, - polygons = [], - components = []; - - objects.forEach(function(o) { - if (o.type === "Polygon") register(o.arcs); - else if (o.type === "MultiPolygon") o.arcs.forEach(register); - }); - - function register(polygon) { - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); - }); - }); - polygons.push(polygon); - } - - function area(ring$$) { - return Math.abs(ring(object(topology, {type: "Polygon", arcs: [ring$$]}).coordinates[0])); - } - - polygons.forEach(function(polygon) { - if (!polygon._) { - var component = [], - neighbors = [polygon]; - polygon._ = 1; - components.push(component); - while (polygon = neighbors.pop()) { - component.push(polygon); - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { - if (!polygon._) { - polygon._ = 1; - neighbors.push(polygon); - } - }); - }); - }); - } - } - }); - - polygons.forEach(function(polygon) { - delete polygon._; - }); - - return { - type: "MultiPolygon", - arcs: components.map(function(polygons) { - var arcs = [], n; - - // Extract the exterior (unique) arcs. - polygons.forEach(function(polygon) { - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { - arcs.push(arc); - } - }); - }); - }); - - // Stitch the arcs into one or more rings. - arcs = stitchArcs(topology, arcs); - - // If more than one ring is returned, - // at most one of these rings can be the exterior; - // choose the one with the greatest absolute area. - if ((n = arcs.length) > 1) { - for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) { - if ((ki = area(arcs[i])) > k) { - t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki; - } - } - } - - return arcs; - }) - }; - } - - function neighbors(objects) { - var indexesByArc = {}, // arc index -> array of object indexes - neighbors = objects.map(function() { return []; }); - - function line(arcs, i) { - arcs.forEach(function(a) { - if (a < 0) a = ~a; - var o = indexesByArc[a]; - if (o) o.push(i); - else indexesByArc[a] = [i]; - }); - } - - function polygon(arcs, i) { - arcs.forEach(function(arc) { line(arc, i); }); - } - - function geometry(o, i) { - if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); - else if (o.type in geometryType) geometryType[o.type](o.arcs, i); - } - - var geometryType = { - LineString: line, - MultiLineString: polygon, - Polygon: polygon, - MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } - }; - - objects.forEach(geometry); - - for (var i in indexesByArc) { - for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { - for (var k = j + 1; k < m; ++k) { - var ij = indexes[j], ik = indexes[k], n; - if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); - if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); - } - } - } - - return neighbors; - } - - function compareArea(a, b) { - return a[1][2] - b[1][2]; - } - - function minAreaHeap() { - var heap = {}, - array = [], - size = 0; - - heap.push = function(object) { - up(array[object._ = size] = object, size++); - return size; - }; - - heap.pop = function() { - if (size <= 0) return; - var removed = array[0], object; - if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); - return removed; - }; - - heap.remove = function(removed) { - var i = removed._, object; - if (array[i] !== removed) return; // invalid request - if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); - return i; - }; - - function up(object, i) { - while (i > 0) { - var j = ((i + 1) >> 1) - 1, - parent = array[j]; - if (compareArea(object, parent) >= 0) break; - array[parent._ = i] = parent; - array[object._ = i = j] = object; - } - } - - function down(object, i) { - while (true) { - var r = (i + 1) << 1, - l = r - 1, - j = i, - child = array[j]; - if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; - if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; - if (j === i) break; - array[child._ = i] = child; - array[object._ = i = j] = object; - } - } - - return heap; - } - - function presimplify(topology, triangleArea) { - var absolute = transformAbsolute(topology.transform), - relative = transformRelative(topology.transform), - heap = minAreaHeap(); - - if (!triangleArea) triangleArea = cartesianTriangleArea; - - topology.arcs.forEach(function(arc) { - var triangles = [], - maxArea = 0, - triangle, - i, - n, - p; - - // To store each point’s effective area, we create a new array rather than - // extending the passed-in point to workaround a Chrome/V8 bug (getting - // stuck in smi mode). For midpoints, the initial effective area of - // Infinity will be computed in the next step. - for (i = 0, n = arc.length; i < n; ++i) { - p = arc[i]; - absolute(arc[i] = [p[0], p[1], Infinity], i); - } - - for (i = 1, n = arc.length - 1; i < n; ++i) { - triangle = arc.slice(i - 1, i + 2); - triangle[1][2] = triangleArea(triangle); - triangles.push(triangle); - heap.push(triangle); - } - - for (i = 0, n = triangles.length; i < n; ++i) { - triangle = triangles[i]; - triangle.previous = triangles[i - 1]; - triangle.next = triangles[i + 1]; - } - - while (triangle = heap.pop()) { - var previous = triangle.previous, - next = triangle.next; - - // If the area of the current point is less than that of the previous point - // to be eliminated, use the latter's area instead. This ensures that the - // current point cannot be eliminated without eliminating previously- - // eliminated points. - if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; - else maxArea = triangle[1][2]; - - if (previous) { - previous.next = next; - previous[2] = triangle[2]; - update(previous); - } - - if (next) { - next.previous = previous; - next[0] = triangle[0]; - update(next); - } - } - - arc.forEach(relative); - }); - - function update(triangle) { - heap.remove(triangle); - triangle[1][2] = triangleArea(triangle); - heap.push(triangle); - } - - return topology; - } - - var version = "1.6.26"; - - exports.version = version; - exports.mesh = mesh; - exports.meshArcs = meshArcs; - exports.merge = merge; - exports.mergeArcs = mergeArcs; - exports.feature = feature; - exports.neighbors = neighbors; - exports.presimplify = presimplify; - -})); -},{}],71:[function(require,module,exports){ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Ported from Webkit - * http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h - */ - -module.exports = UnitBezier; - -function UnitBezier(p1x, p1y, p2x, p2y) { - // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). - this.cx = 3.0 * p1x; - this.bx = 3.0 * (p2x - p1x) - this.cx; - this.ax = 1.0 - this.cx - this.bx; - - this.cy = 3.0 * p1y; - this.by = 3.0 * (p2y - p1y) - this.cy; - this.ay = 1.0 - this.cy - this.by; - - this.p1x = p1x; - this.p1y = p2y; - this.p2x = p2x; - this.p2y = p2y; -} - -UnitBezier.prototype.sampleCurveX = function(t) { - // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. - 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.0 * this.ax * t + 2.0 * this.bx) * t + this.cx; -}; - -UnitBezier.prototype.solveCurveX = function(x, epsilon) { - if (typeof epsilon === 'undefined') epsilon = 1e-6; - - var t0, t1, t2, x2, i; - - // First try a few iterations of Newton's method -- normally very fast. - 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) < 1e-6) break; - - t2 = t2 - x2 / d2; - } - - // Fall back to the bisection method for reliability. - t0 = 0.0; - t1 = 1.0; - 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; - } - - // Failure. - return t2; -}; - -UnitBezier.prototype.solve = function(x, epsilon) { - return this.sampleCurveY(this.solveCurveX(x, epsilon)); -}; - -},{}],72:[function(require,module,exports){ -module.exports.VectorTile = require('./lib/vectortile.js'); -module.exports.VectorTileFeature = require('./lib/vectortilefeature.js'); -module.exports.VectorTileLayer = require('./lib/vectortilelayer.js'); - -},{"./lib/vectortile.js":73,"./lib/vectortilefeature.js":74,"./lib/vectortilelayer.js":75}],73:[function(require,module,exports){ -'use strict'; - -var VectorTileLayer = require('./vectortilelayer'); - -module.exports = 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; - } -} - - -},{"./vectortilelayer":75}],74:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -module.exports = VectorTileFeature; - -function VectorTileFeature(pbf, end, extent, keys, values) { - // Public - this.properties = {}; - this.extent = extent; - this.type = 0; - - // Private - 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) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - length = cmdLen >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += pbf.readSVarint(); - y += pbf.readSVarint(); - - if (cmd === 1) { // moveTo - if (line) lines.push(line); - line = []; - } - - line.push(new Point(x, y)); - - } else if (cmd === 7) { - - // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90 - if (line) { - line.push(line[0].clone()); // closePolygon - } - - } 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) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - 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(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; -}; - -// classifies an array of rings into polygons with outer rings and holes - -function classifyRings(rings) { - var len = rings.length; - - if (len <= 1) return [rings]; - - var polygons = [], - polygon, - ccw; - - for (var i = 0; i < len; i++) { - var area = signedArea(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(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; -} - -},{"point-geometry":66}],75:[function(require,module,exports){ -'use strict'; - -var VectorTileFeature = require('./vectortilefeature.js'); - -module.exports = VectorTileLayer; - -function VectorTileLayer(pbf, end) { - // Public - this.version = 1; - this.name = null; - this.extent = 4096; - this.length = 0; - - // Private - 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; -} - -// return feature `i` from this layer as a `VectorTileFeature` -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); -}; - -},{"./vectortilefeature.js":74}],76:[function(require,module,exports){ -var Pbf = require('pbf') -var vtpb = require('./vector-tile-pb') -var GeoJSONWrapper = require('./lib/geojson_wrapper') - -module.exports = fromVectorTileJs -module.exports.fromVectorTileJs = fromVectorTileJs -module.exports.fromGeojsonVt = fromGeojsonVt -module.exports.GeoJSONWrapper = GeoJSONWrapper - -/** - * Serialize a vector-tile-js-created tile to pbf - * - * @param {Object} tile - * @return {Buffer} uncompressed, pbf-serialized tile data - */ -function fromVectorTileJs (tile) { - var layers = [] - for (var l in tile.layers) { - layers.push(prepareLayer(tile.layers[l])) - } - - var out = new Pbf() - vtpb.tile.write({ layers: layers }, out) - return out.finish() -} - -/** - * Serialized a geojson-vt-created tile to pbf. - * - * @param {Object} layers - An object mapping layer names to geojson-vt-created vector tile objects - * @return {Buffer} uncompressed, pbf-serialized tile data - */ -function fromGeojsonVt (layers) { - var l = {} - for (var k in layers) { - l[k] = new GeoJSONWrapper(layers[k].features) - l[k].name = k - } - return fromVectorTileJs({layers: l}) -} - -/** - * Prepare the given layer to be serialized by the auto-generated pbf - * serializer by encoding the feature geometry and properties. - */ -function prepareLayer (layer) { - var preparedLayer = { - name: layer.name || '', - version: layer.version || 1, - extent: layer.extent || 4096, - keys: [], - values: [], - features: [] - } - - var keycache = {} - var valuecache = {} - - for (var i = 0; i < layer.length; i++) { - var feature = layer.feature(i) - feature.geometry = encodeGeometry(feature.loadGeometry()) - - var tags = [] - for (var key in feature.properties) { - var keyIndex = keycache[key] - if (typeof keyIndex === 'undefined') { - preparedLayer.keys.push(key) - keyIndex = preparedLayer.keys.length - 1 - keycache[key] = keyIndex - } - var value = wrapValue(feature.properties[key]) - var valueIndex = valuecache[value.key] - if (typeof valueIndex === 'undefined') { - preparedLayer.values.push(value) - valueIndex = preparedLayer.values.length - 1 - valuecache[value.key] = valueIndex - } - tags.push(keyIndex) - tags.push(valueIndex) - } - - feature.tags = tags - preparedLayer.features.push(feature) - } - - return preparedLayer -} - -function command (cmd, length) { - return (length << 3) + (cmd & 0x7) -} - -function zigzag (num) { - return (num << 1) ^ (num >> 31) -} - -/** - * Encode a polygon's geometry into an array ready to be serialized - * to mapbox vector tile specified geometry data. - * - * @param {Array} Rings, each being an array of [x, y] tile-space coordinates - * @return {Array} encoded geometry - */ -function encodeGeometry (geometry) { - var encoded = [] - var x = 0 - var y = 0 - var rings = geometry.length - for (var r = 0; r < rings; r++) { - var ring = geometry[r] - encoded.push(command(1, 1)) // moveto - for (var i = 0; i < ring.length; i++) { - if (i === 1) { - encoded.push(command(2, ring.length - 1)) // lineto - } - var dx = ring[i].x - x - var dy = ring[i].y - y - encoded.push(zigzag(dx), zigzag(dy)) - x += dx - y += dy - } - } - - return encoded -} - -/** - * Wrap a property value according to its type. The returned object - * is of the form { xxxx_value: primitiveValue }, which is what the generated - * protobuf serializer expects. - */ -function wrapValue (value) { - var result - var type = typeof value - if (type === 'string') { - result = { string_value: value } - } else if (type === 'boolean') { - result = { bool_value: value } - } else if (type === 'number') { - if (value % 1 !== 0) { - result = { double_value: value } - } else if (value < 0) { - result = { sint_value: value } - } else { - result = { uint_value: value } - } - } else { - value = JSON.stringify(value) - result = { string_value: value } - } - - result.key = type + ':' + value - return result -} - -},{"./lib/geojson_wrapper":77,"./vector-tile-pb":78,"pbf":65}],77:[function(require,module,exports){ -'use strict' - -var Point = require('point-geometry') -var VectorTileFeature = require('vector-tile').VectorTileFeature - -module.exports = GeoJSONWrapper - -// conform to vectortile api -function GeoJSONWrapper (features) { - this.features = features - this.length = features.length -} - -GeoJSONWrapper.prototype.feature = function (i) { - return new FeatureWrapper(this.features[i]) -} - -function FeatureWrapper (feature) { - 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 = 4096 -} - -FeatureWrapper.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 Point(ring[j][0], ring[j][1])) - } - this.geometry.push(newRing) - } - return this.geometry -} - -FeatureWrapper.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.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON - -},{"point-geometry":66,"vector-tile":72}],78:[function(require,module,exports){ -'use strict'; - -// tile ======================================== - -var tile = exports.tile = {read: readTile, write: writeTile}; - -tile.GeomType = { - "Unknown": 0, - "Point": 1, - "LineString": 2, - "Polygon": 3 -}; - -function readTile(pbf, end) { - return pbf.readFields(readTileField, {"layers": []}, end); -} - -function readTileField(tag, tile, pbf) { - if (tag === 3) tile.layers.push(readLayer(pbf, pbf.readVarint() + pbf.pos)); -} - -function writeTile(tile, pbf) { - var i; - if (tile.layers !== undefined) for (i = 0; i < tile.layers.length; i++) pbf.writeMessage(3, writeLayer, tile.layers[i]); -} - -// value ======================================== - -tile.value = {read: readValue, write: writeValue}; - -function readValue(pbf, end) { - return pbf.readFields(readValueField, {}, end); -} - -function readValueField(tag, value, pbf) { - if (tag === 1) value.string_value = pbf.readString(); - else if (tag === 2) value.float_value = pbf.readFloat(); - else if (tag === 3) value.double_value = pbf.readDouble(); - else if (tag === 4) value.int_value = pbf.readVarint(); - else if (tag === 5) value.uint_value = pbf.readVarint(); - else if (tag === 6) value.sint_value = pbf.readSVarint(); - else if (tag === 7) value.bool_value = pbf.readBoolean(); -} - -function writeValue(value, pbf) { - if (value.string_value !== undefined) pbf.writeStringField(1, value.string_value); - if (value.float_value !== undefined) pbf.writeFloatField(2, value.float_value); - if (value.double_value !== undefined) pbf.writeDoubleField(3, value.double_value); - if (value.int_value !== undefined) pbf.writeVarintField(4, value.int_value); - if (value.uint_value !== undefined) pbf.writeVarintField(5, value.uint_value); - if (value.sint_value !== undefined) pbf.writeSVarintField(6, value.sint_value); - if (value.bool_value !== undefined) pbf.writeBooleanField(7, value.bool_value); -} - -// feature ======================================== - -tile.feature = {read: readFeature, write: writeFeature}; - -function readFeature(pbf, end) { - var feature = pbf.readFields(readFeatureField, {}, end); - if (feature.type === undefined) feature.type = "Unknown"; - return feature; -} - -function readFeatureField(tag, feature, pbf) { - if (tag === 1) feature.id = pbf.readVarint(); - else if (tag === 2) feature.tags = pbf.readPackedVarint(); - else if (tag === 3) feature.type = pbf.readVarint(); - else if (tag === 4) feature.geometry = pbf.readPackedVarint(); -} - -function writeFeature(feature, pbf) { - if (feature.id !== undefined) pbf.writeVarintField(1, feature.id); - if (feature.tags !== undefined) pbf.writePackedVarint(2, feature.tags); - if (feature.type !== undefined) pbf.writeVarintField(3, feature.type); - if (feature.geometry !== undefined) pbf.writePackedVarint(4, feature.geometry); -} - -// layer ======================================== - -tile.layer = {read: readLayer, write: writeLayer}; - -function readLayer(pbf, end) { - return pbf.readFields(readLayerField, {"features": [], "keys": [], "values": []}, end); -} - -function readLayerField(tag, layer, pbf) { - if (tag === 15) layer.version = pbf.readVarint(); - else if (tag === 1) layer.name = pbf.readString(); - else if (tag === 2) layer.features.push(readFeature(pbf, pbf.readVarint() + pbf.pos)); - else if (tag === 3) layer.keys.push(pbf.readString()); - else if (tag === 4) layer.values.push(readValue(pbf, pbf.readVarint() + pbf.pos)); - else if (tag === 5) layer.extent = pbf.readVarint(); -} - -function writeLayer(layer, pbf) { - if (layer.version !== undefined) pbf.writeVarintField(15, layer.version); - if (layer.name !== undefined) pbf.writeStringField(1, layer.name); - var i; - if (layer.features !== undefined) for (i = 0; i < layer.features.length; i++) pbf.writeMessage(2, writeFeature, layer.features[i]); - if (layer.keys !== undefined) for (i = 0; i < layer.keys.length; i++) pbf.writeStringField(3, layer.keys[i]); - if (layer.values !== undefined) for (i = 0; i < layer.values.length; i++) pbf.writeMessage(4, writeValue, layer.values[i]); - if (layer.extent !== undefined) pbf.writeVarintField(5, layer.extent); -} - -},{}],79:[function(require,module,exports){ -var bundleFn = arguments[3]; -var sources = arguments[4]; -var cache = arguments[5]; - -var stringify = JSON.stringify; - -module.exports = function (fn, options) { - var wkey; - var cacheKeys = Object.keys(cache); - - for (var i = 0, l = cacheKeys.length; i < l; i++) { - var key = cacheKeys[i]; - var exp = cache[key].exports; - // Using babel as a transpiler to use esmodule, the export will always - // be an object with the default export as a property of it. To ensure - // the existing api and babel esmodule exports are both supported we - // check for both - if (exp === fn || exp && exp.default === fn) { - wkey = key; - break; - } - } - - if (!wkey) { - wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16); - var wcache = {}; - for (var i = 0, l = cacheKeys.length; i < l; i++) { - var key = cacheKeys[i]; - wcache[key] = key; - } - sources[wkey] = [ - Function(['require','module','exports'], '(' + fn + ')(self)'), - wcache - ]; - } - var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16); - - var scache = {}; scache[wkey] = wkey; - sources[skey] = [ - Function(['require'], ( - // try to call default if defined to also support babel esmodule - // exports - 'var f = require(' + stringify(wkey) + ');' + - '(f.default ? f.default : f)(self);' - )), - scache - ]; - - var src = '(' + bundleFn + ')({' - + Object.keys(sources).map(function (key) { - return stringify(key) + ':[' - + sources[key][0] - + ',' + stringify(sources[key][1]) + ']' - ; - }).join(',') - + '},{},[' + stringify(skey) + '])' - ; - - var URL = window.URL || window.webkitURL || window.mozURL || window.msURL; - - var blob = new Blob([src], { type: 'text/javascript' }); - if (options && options.bare) { return blob; } - var workerUrl = URL.createObjectURL(blob); - var worker = new Worker(workerUrl); - worker.objectURL = workerUrl; - return worker; -}; - -},{}],80:[function(require,module,exports){ -module.exports.RADIUS = 6378137; -module.exports.FLATTENING = 1/298.257223563; -module.exports.POLAR_RADIUS = 6356752.3142; - -},{}],81:[function(require,module,exports){ -var util = require('mapbox-gl/js/util/util') -var GeoJSONSource = require('mapbox-gl/js/source/geojson_source') -var webworkify = require('webworkify') - -module.exports = TopoJSONSource - -function TopoJSONSource (id, options, dispatcher) { - GeoJSONSource.call(this, id, options, dispatcher) -} - -TopoJSONSource.prototype = util.inherit(GeoJSONSource, { - type: 'topojson' -}) - -TopoJSONSource.workerSourceURL = URL.createObjectURL(webworkify(require('./topojson_worker.js'), {bare: true})) - - -},{"./topojson_worker.js":82,"mapbox-gl/js/source/geojson_source":36,"mapbox-gl/js/util/util":62,"webworkify":79}],82:[function(require,module,exports){ -var util = require('mapbox-gl/js/util/util') -var topojson = require('topojson') -var GeoJSONWorkerSource = require('mapbox-gl/js/source/geojson_worker_source') - -function loadGeoJSON (params, callback) { - // defer to the default implementation to grab / JSON.parse the data, which - // is actually expected to be topojson in our case. - GeoJSONWorkerSource.prototype.loadGeoJSON.call(this, params, function (err, topo) { - if (err) { return callback(err) } - // once we have it, convert the layer specified in `params` to geojson. - var data = topojson.feature(topo, topo.objects[params.layer]) - console.log('data', data, params, topo) - callback(null, data) - }) -} - -function TopoJSONWorkerSource (actor, style) { - GeoJSONWorkerSource.call(this, actor, style, loadGeoJSON) -} - -TopoJSONWorkerSource.prototype = util.inherit(GeoJSONWorkerSource) - -module.exports = function (self) { - self.registerWorkerSource('topojson', TopoJSONWorkerSource) -} - -},{"mapbox-gl/js/source/geojson_worker_source":37,"mapbox-gl/js/util/util":62,"topojson":70}]},{},[81])(81) -}); \ No newline at end of file diff --git a/dist/mapbox-gl.js b/dist/mapbox-gl.js deleted file mode 100644 index 8f1396d..0000000 --- a/dist/mapbox-gl.js +++ /dev/null @@ -1,29518 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.mapboxgl = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":3}],3:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -(function () { - try { - cachedSetTimeout = setTimeout; - } catch (e) { - cachedSetTimeout = function () { - throw new Error('setTimeout is not defined'); - } - } - try { - cachedClearTimeout = clearTimeout; - } catch (e) { - cachedClearTimeout = function () { - throw new Error('clearTimeout is not defined'); - } - } -} ()) -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = cachedSetTimeout.call(null, cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - cachedClearTimeout.call(null, timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - cachedSetTimeout.call(null, drainQueue, 0); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],4:[function(require,module,exports){ -(function (global){ -/*! https://mths.be/punycode v1.4.1 by @mathias */ -;(function(root) { - - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports && - !exports.nodeType && exports; - var freeModule = typeof module == 'object' && module && - !module.nodeType && module; - var freeGlobal = typeof global == 'object' && global; - if ( - freeGlobal.global === freeGlobal || - freeGlobal.window === freeGlobal || - freeGlobal.self === freeGlobal - ) { - root = freeGlobal; - } - - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators - - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw new RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - var result = []; - while (length--) { - result[length] = fn(array[length]); - } - return result; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings or email - * addresses. - * @private - * @param {String} domain The domain name or email address. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - var parts = string.split('@'); - var result = ''; - if (parts.length > 1) { - // In email addresses, only the domain name should be punycoded. Leave - // the local part (i.e. everything up to `@`) intact. - result = parts[0] + '@'; - string = parts[1]; - } - // Avoid `split(regex)` for IE8 compatibility. See #17. - string = string.replace(regexSeparators, '\x2E'); - var labels = string.split('.'); - var encoded = map(labels, fn).join('.'); - return result + encoded; - } - - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * https://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode symbols (e.g. a domain name label) to a - * Punycode string of ASCII-only symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name or an email address - * to Unicode. Only the Punycoded parts of the input will be converted, i.e. - * it doesn't matter if you call it on a string that has already been - * converted to Unicode. - * @memberOf punycode - * @param {String} input The Punycoded domain name or email address to - * convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(input) { - return mapDomain(input, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name or an email address to - * Punycode. Only the non-ASCII parts of the domain name will be converted, - * i.e. it doesn't matter if you call it with a domain that's already in - * ASCII. - * @memberOf punycode - * @param {String} input The domain name or email address to convert, as a - * Unicode string. - * @returns {String} The Punycode representation of the given domain name or - * email address. - */ - function toASCII(input) { - return mapDomain(input, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.4.1', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && freeModule) { - if (module.exports == freeExports) { - // in Node.js, io.js, or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { - // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { - // in Rhino or a web browser - root.punycode = punycode; - } - -}(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],5:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } - - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); - - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } - } - - return obj; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{}],6:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - - case 'boolean': - return v ? 'true' : 'false'; - - case 'number': - return isFinite(v) ? v : ''; - - default: - return ''; - } -}; - -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return map(obj[k], function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); - - } - - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} - -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; - -},{}],7:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); - -},{"./decode":5,"./encode":6}],8:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var punycode = require('punycode'); -var util = require('./util'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; - -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} - -// Reference: RFC 3986, RFC 1808, RFC 2396 - -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, - - // Special case for a simple path URL - simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, - - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], - - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), - - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = require('querystring'); - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && util.isObject(url) && url instanceof Url) return url; - - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} - -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!util.isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); - } - - // Copy chrome, IE, opera backslash-handling behavior. - // Back slashes before the query string get converted to forward slashes - // See: https://code.google.com/p/chromium/issues/detail?id=25916 - var queryIndex = url.indexOf('?'), - splitter = - (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', - uSplit = url.split(splitter), - slashRegex = /\\/g; - uSplit[0] = uSplit[0].replace(slashRegex, '/'); - url = uSplit.join(splitter); - - var rest = url; - - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); - - if (!slashesDenoteHost && url.split('#').length === 1) { - // Try fast path regexp - var simplePath = simplePathPattern.exec(rest); - if (simplePath) { - this.path = rest; - this.href = rest; - this.pathname = simplePath[1]; - if (simplePath[2]) { - this.search = simplePath[2]; - if (parseQueryString) { - this.query = querystring.parse(this.search.substr(1)); - } else { - this.query = this.search.substr(1); - } - } else if (parseQueryString) { - this.search = ''; - this.query = {}; - } - return this; - } - } - - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); - } - - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { - - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c - - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); - } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); - } - - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); - } - - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; - - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); - - // pull out port. - this.parseHost(); - - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; - - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; - - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } - - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); - } - - if (!ipv6Hostname) { - // IDNA Support: Returns a punycoded representation of "domain". - // It only converts parts of the domain name that - // have non-ASCII characters, i.e. it doesn't matter if - // you call it with a domain that already is ASCII-only. - this.hostname = punycode.toASCII(this.hostname); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; - - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } - - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { - - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - if (rest.indexOf(ae) === -1) - continue; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); - } - rest = rest.split(ae).join(esc); - } - } - - - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); - } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; - } - - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; - } - - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; - -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (util.isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} - -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; - } - - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query && - util.isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); - } - - var search = this.search || (query && ('?' + query)) || ''; - - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; - - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; - - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); - - return protocol + host + pathname + search + hash; -}; - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} - -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} - -Url.prototype.resolveObject = function(relative) { - if (util.isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - var tkeys = Object.keys(this); - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } - - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; - - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; - } - - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - var rkeys = Object.keys(relative); - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; - if (rkey !== 'protocol') - result[rkey] = relative[rkey]; - } - - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - var keys = Object.keys(relative); - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; - result[k] = relative[k]; - } - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; - - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; - } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!util.isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; - //to support http.request - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - result.href = result.format(); - return result; - } - - // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = ( - (result.host || relative.host || srcPath.length > 1) && - (last === '.' || last === '..') || last === ''); - - // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last === '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); - - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || (result.host && srcPath.length); - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } - - //to support request.http - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; - -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); - } - host = host.substr(0, host.length - port.length); - } - if (host) this.hostname = host; -}; - -},{"./util":9,"punycode":4,"querystring":7}],9:[function(require,module,exports){ -'use strict'; - -module.exports = { - isString: function(arg) { - return typeof(arg) === 'string'; - }, - isObject: function(arg) { - return typeof(arg) === 'object' && arg !== null; - }, - isNull: function(arg) { - return arg === null; - }, - isNullOrUndefined: function(arg) { - return arg == null; - } -}; - -},{}],10:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],11:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":10,"_process":3,"inherits":1}],12:[function(require,module,exports){ -module.exports = require('mapbox-gl') - -},{"mapbox-gl":83}],13:[function(require,module,exports){ -// (c) Dean McNamee , 2012. -// -// https://github.com/deanm/css-color-parser-js -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -// http://www.w3.org/TR/css3-color/ -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) { // Clamp to integer 0 .. 255. - i = Math.round(i); // Seems to be what Chrome does (vs truncation). - return i < 0 ? 0 : i > 255 ? 255 : i; -} - -function clamp_css_float(f) { // Clamp to float 0.0 .. 1.0. - return f < 0 ? 0 : f > 1 ? 1 : f; -} - -function parse_css_int(str) { // int or percentage. - if (str[str.length - 1] === '%') - return clamp_css_byte(parseFloat(str) / 100 * 255); - return clamp_css_byte(parseInt(str)); -} - -function parse_css_float(str) { // float or percentage. - 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) { - // Remove all whitespace, not compliant, but should just be more accepting. - var str = css_str.replace(/ /g, '').toLowerCase(); - - // Color keywords (and transparent) lookup. - if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup. - - // #abc and #abc123 syntax. - if (str[0] === '#') { - if (str.length === 4) { - var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. - if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN. - return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), - (iv & 0xf0) | ((iv & 0xf0) >> 4), - (iv & 0xf) | ((iv & 0xf) << 4), - 1]; - } else if (str.length === 7) { - var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. - if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN. - return [(iv & 0xff0000) >> 16, - (iv & 0xff00) >> 8, - iv & 0xff, - 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; // To allow case fallthrough. - switch (fname) { - case 'rgba': - if (params.length !== 4) return null; - alpha = parse_css_float(params.pop()); - // Fall through. - 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()); - // Fall through. - case 'hsl': - if (params.length !== 3) return null; - var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1 - // NOTE(deanm): According to the CSS spec s/l should only be - // percentages, but we don't bother and let float or percentage. - 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) { } - -},{}],14:[function(require,module,exports){ -'use strict'; - -module.exports = 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) return triangles; - - var minX, minY, maxX, maxY, x, y, size; - - if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); - - // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - 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; - } - - // minX, minY and size are later used to transform coords into integers for z-order calculation - size = Math.max(maxX - minX, maxY - minY); - } - - earcutLinked(outerNode, triangles, dim, minX, minY, size); - - return triangles; -} - -// create a circular doubly linked list from polygon points in the specified winding order -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; -} - -// eliminate colinear or duplicate points -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) return null; - again = true; - - } else { - p = p.next; - } - } while (again || p !== end); - - return end; -} - -// main ear slicing loop which triangulates a polygon (given as a linked list) -function earcutLinked(ear, triangles, dim, minX, minY, size, pass) { - if (!ear) return; - - // interlink polygon nodes in z-order - if (!pass && size) indexCurve(ear, minX, minY, size); - - var stop = ear, - prev, next; - - // iterate through ears, slicing them one by one - while (ear.prev !== ear.next) { - prev = ear.prev; - next = ear.next; - - if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) { - // cut off the triangle - triangles.push(prev.i / dim); - triangles.push(ear.i / dim); - triangles.push(next.i / dim); - - removeNode(ear); - - // skipping the next vertice leads to less sliver triangles - ear = next.next; - stop = next.next; - - continue; - } - - ear = next; - - // if we looped through the whole remaining polygon and can't find any more ears - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1); - - // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(ear, triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, size, 2); - - // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, size); - } - - break; - } - } -} - -// check whether a polygon node forms a valid ear with adjacent nodes -function isEar(ear) { - var a = ear.prev, - b = ear, - c = ear.next; - - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - - // now make sure we don't have other points inside the potential ear - 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, size) { - var a = ear.prev, - b = ear, - c = ear.next; - - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - - // triangle bbox; min & max are calculated like this for speed - 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); - - // z-order range for the current triangle bbox; - var minZ = zOrder(minTX, minTY, minX, minY, size), - maxZ = zOrder(maxTX, maxTY, minX, minY, size); - - // first look for points inside the triangle in increasing z-order - var p = ear.nextZ; - - while (p && p.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.nextZ; - } - - // then look for points in decreasing z-order - p = ear.prevZ; - - 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; - } - - return true; -} - -// go through all polygon nodes and cure small local self-intersections -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); - - // remove two nodes involved - removeNode(p); - removeNode(p.next); - - p = start = b; - } - p = p.next; - } while (p !== start); - - return p; -} - -// try splitting polygon into two and triangulate them independently -function splitEarcut(start, triangles, dim, minX, minY, size) { - // look for a valid diagonal that divides the polygon into two - var a = start; - do { - var b = a.next.next; - while (b !== a.prev) { - if (a.i !== b.i && isValidDiagonal(a, b)) { - // split the polygon in two by the diagonal - var c = splitPolygon(a, b); - - // filter colinear points around the cuts - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); - - // run earcut on each half - earcutLinked(a, triangles, dim, minX, minY, size); - earcutLinked(c, triangles, dim, minX, minY, size); - return; - } - b = b.next; - } - a = a.next; - } while (a !== start); -} - -// link every hole into the outer loop, producing a single-ring polygon without holes -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); - - // process holes from left to right - 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; -} - -// find a bridge between vertices that connects hole with an outer ring and and link it -function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - if (outerNode) { - var b = splitPolygon(outerNode, hole); - filterPoints(b, b.next); - } -} - -// David Eberly's algorithm for finding a bridge between hole and outer polygon -function findHoleBridge(hole, outerNode) { - var p = outerNode, - hx = hole.x, - hy = hole.y, - qx = -Infinity, - m; - - // find a segment intersected by a ray from the hole's leftmost point to the left; - // segment's endpoint with lesser x will be potential connection point - do { - if (hy <= p.y && hy >= p.next.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.prev; // hole touches outer segment; pick lower endpoint - - // look for points inside the triangle of hole point, segment intersection and endpoint; - // if there are no points found, we have a valid connection; - // otherwise choose the point of the minimum angle with the ray as connection point - - var stop = m, - mx = m.x, - my = m.y, - tanMin = Infinity, - tan; - - p = m.next; - - while (p !== stop) { - if (hx >= p.x && p.x >= mx && - 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); // tangential - - if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { - m = p; - tanMin = tan; - } - } - - p = p.next; - } - - return m; -} - -// interlink polygon nodes in z-order -function indexCurve(start, minX, minY, size) { - var p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); - - p.prevZ.nextZ = null; - p.prevZ = null; - - sortLinked(p); -} - -// Simon Tatham's linked list merge sort algorithm -// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html -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) { - e = q; - q = q.nextZ; - qSize--; - } else if (qSize === 0 || !q) { - e = p; - p = p.nextZ; - pSize--; - } else if (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; -} - -// z-order of a point given coords and size of the data bounding box -function zOrder(x, y, minX, minY, size) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) / size; - y = 32767 * (y - minY) / size; - - x = (x | (x << 8)) & 0x00FF00FF; - x = (x | (x << 4)) & 0x0F0F0F0F; - x = (x | (x << 2)) & 0x33333333; - x = (x | (x << 1)) & 0x55555555; - - y = (y | (y << 8)) & 0x00FF00FF; - y = (y | (y << 4)) & 0x0F0F0F0F; - y = (y | (y << 2)) & 0x33333333; - y = (y | (y << 1)) & 0x55555555; - - return x | (y << 1); -} - -// find the leftmost node of a polygon ring -function getLeftmost(start) { - var p = start, - leftmost = start; - do { - if (p.x < leftmost.x) leftmost = p; - p = p.next; - } while (p !== start); - - return leftmost; -} - -// check if a point lies within a convex triangle -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; -} - -// check if a diagonal between two polygon nodes is valid (lies in polygon interior) -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); -} - -// signed area of a triangle -function area(p, q, r) { - return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); -} - -// check if two points are equal -function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; -} - -// check if two segments intersect -function intersects(p1, q1, p2, q2) { - if ((equals(p1, q1) && equals(p2, q2)) || - (equals(p1, q2) && equals(p2, q1))) return true; - return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && - area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; -} - -// check if a polygon diagonal intersects any polygon segments -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; -} - -// check if a polygon diagonal is locally inside the polygon -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; -} - -// check if the middle point of a polygon diagonal is inside the polygon -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)) && (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; -} - -// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; -// if one belongs to the outer ring and another to a hole, it merges it into a single ring -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; -} - -// create a node and optionally link it with previous one (in a circular doubly linked list) -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) { - // vertice index in coordinates array - this.i = i; - - // vertex coordinates - this.x = x; - this.y = y; - - // previous and next vertice nodes in a polygon ring - this.prev = null; - this.next = null; - - // z-order curve value - this.z = null; - - // previous and next nodes in z-order - this.prevZ = null; - this.nextZ = null; - - // indicates whether this is a steiner point - this.steiner = false; -} - -// return a percentage difference between the polygon area and its triangulation area; -// used to verify correctness of triangulation -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; -} - -// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts -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; -}; - -},{}],15:[function(require,module,exports){ -'use strict'; - -module.exports = createFilter; - -var types = ['Unknown', 'Point', 'LineString', 'Polygon']; - -/** - * Given a filter expressed as nested arrays, return a new function - * that evaluates whether a given feature (with a .properties or .tags property) - * passes its test. - * - * @param {Array} filter mapbox gl filter - * @returns {Function} filter-evaluating function - */ -function createFilter(filter) { - return new Function('f', 'var p = (f && f.properties || {}); return ' + compile(filter)); -} - -function compile(filter) { - if (!filter) return 'true'; - var op = filter[0]; - if (filter.length <= 1) return op === 'any' ? 'false' : 'true'; - var str = - op === '==' ? compileComparisonOp(filter[1], filter[2], '===', false) : - op === '!=' ? compileComparisonOp(filter[1], filter[2], '!==', false) : - op === '<' || - op === '>' || - op === '<=' || - op === '>=' ? compileComparisonOp(filter[1], filter[2], op, true) : - op === 'any' ? compileLogicalOp(filter.slice(1), '||') : - op === 'all' ? compileLogicalOp(filter.slice(1), '&&') : - op === 'none' ? compileNegation(compileLogicalOp(filter.slice(1), '||')) : - op === 'in' ? compileInOp(filter[1], filter.slice(2)) : - op === '!in' ? compileNegation(compileInOp(filter[1], filter.slice(2))) : - op === 'has' ? compileHasOp(filter[1]) : - op === '!has' ? compileNegation(compileHasOp([filter[1]])) : - 'true'; - return '(' + str + ')'; -} - -function compilePropertyReference(property) { - return property === '$type' ? 'f.type' : - property === '$id' ? 'f.id' : - 'p[' + JSON.stringify(property) + ']'; -} - -function compileComparisonOp(property, value, op, checkType) { - var left = compilePropertyReference(property); - var right = property === '$type' ? types.indexOf(value) : JSON.stringify(value); - return (checkType ? 'typeof ' + left + '=== typeof ' + right + '&&' : '') + left + op + right; -} - -function compileLogicalOp(expressions, op) { - return expressions.map(compile).join(op); -} - -function compileInOp(property, values) { - if (property === '$type') values = values.map(function(value) { return types.indexOf(value); }); - var left = JSON.stringify(values.sort(compare)); - var right = compilePropertyReference(property); - - if (values.length <= 200) return left + '.indexOf(' + right + ') !== -1'; - - return 'function(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; }(' + right + ', ' + left + ',0,' + (values.length - 1) + ')'; -} - -function compileHasOp(property) { - return JSON.stringify(property) + ' in p'; -} - -function compileNegation(expression) { - return '!(' + expression + ')'; -} - -// Comparison function to sort numbers and strings -function compare(a, b) { - return a < b ? -1 : a > b ? 1 : 0; -} - -},{}],16:[function(require,module,exports){ -var wgs84 = require('wgs84'); - -module.exports.geometry = geometry; -module.exports.ring = ringArea; - -function geometry(_) { - if (_.type === 'Polygon') return polygonArea(_.coordinates); - else if (_.type === 'MultiPolygon') { - var area = 0; - for (var i = 0; i < _.coordinates.length; i++) { - area += polygonArea(_.coordinates[i]); - } - return area; - } else { - return null; - } -} - -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; -} - -/** - * Calculate the approximate area of the polygon were it projected onto - * the earth. Note that this area will be positive if ring is oriented - * clockwise, otherwise it will be negative. - * - * Reference: - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409 - * - * Returns: - * {float} The approximate signed geodesic area of the polygon in square - * meters. - */ - -function ringArea(coords) { - var area = 0; - - if (coords.length > 2) { - var p1, p2; - for (var i = 0; i < coords.length - 1; i++) { - p1 = coords[i]; - p2 = coords[i + 1]; - area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1]))); - } - - area = area * wgs84.RADIUS * wgs84.RADIUS / 2; - } - - return area; -} - -function rad(_) { - return _ * Math.PI / 180; -} - -},{"wgs84":201}],17:[function(require,module,exports){ -var geojsonArea = require('geojson-area'); - -module.exports = rewind; - -function rewind(gj, outer) { - switch ((gj && gj.type) || null) { - case 'FeatureCollection': - gj.features = gj.features.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; -} - -},{"geojson-area":16}],18:[function(require,module,exports){ -'use strict'; - -module.exports = clip; - -var createFeature = require('./feature'); - -/* clip features between two axis-parallel lines: - * | | - * ___|___ | / - * / | \____|____/ - * | | - */ - -function clip(features, scale, k1, k2, axis, intersect, minAll, maxAll) { - - k1 /= scale; - k2 /= scale; - - if (minAll >= k1 && maxAll <= k2) return features; // trivial accept - else if (minAll > k2 || maxAll < k1) return null; // trivial reject - - var clipped = []; - - for (var i = 0; i < features.length; i++) { - - var feature = features[i], - geometry = feature.geometry, - type = feature.type, - min, max; - - min = feature.min[axis]; - max = feature.max[axis]; - - if (min >= k1 && max <= k2) { // trivial accept - clipped.push(feature); - continue; - } else if (min > k2 || max < k1) continue; // trivial reject - - var slices = type === 1 ? - clipPoints(geometry, k1, k2, axis) : - clipGeometry(geometry, k1, k2, axis, intersect, type === 3); - - if (slices.length) { - // if a feature got clipped, it will likely get clipped on the next zoom level as well, - // so there's no need to recalculate bboxes - clipped.push(createFeature(feature.tags, type, slices, feature.id)); - } - } - - return clipped.length ? clipped : null; -} - -function clipPoints(geometry, k1, k2, axis) { - var slice = []; - - for (var i = 0; i < geometry.length; i++) { - var a = geometry[i], - ak = a[axis]; - - if (ak >= k1 && ak <= k2) slice.push(a); - } - return slice; -} - -function clipGeometry(geometry, k1, k2, axis, intersect, closed) { - - var slices = []; - - for (var i = 0; i < geometry.length; i++) { - - var ak = 0, - bk = 0, - b = null, - points = geometry[i], - area = points.area, - dist = points.dist, - outer = points.outer, - len = points.length, - a, j, last; - - var slice = []; - - for (j = 0; j < len - 1; j++) { - a = b || points[j]; - b = points[j + 1]; - ak = bk || a[axis]; - bk = b[axis]; - - if (ak < k1) { - - if ((bk > k2)) { // ---|-----|--> - slice.push(intersect(a, b, k1), intersect(a, b, k2)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk >= k1) slice.push(intersect(a, b, k1)); // ---|--> | - - } else if (ak > k2) { - - if ((bk < k1)) { // <--|-----|--- - slice.push(intersect(a, b, k2), intersect(a, b, k1)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk <= k2) slice.push(intersect(a, b, k2)); // | <--|--- - - } else { - - slice.push(a); - - if (bk < k1) { // <--|--- | - slice.push(intersect(a, b, k1)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - - } else if (bk > k2) { // | ---|--> - slice.push(intersect(a, b, k2)); - if (!closed) slice = newSlice(slices, slice, area, dist, outer); - } - // | --> | - } - } - - // add the last point - a = points[len - 1]; - ak = a[axis]; - if (ak >= k1 && ak <= k2) slice.push(a); - - // close the polygon if its endpoints are not the same after clipping - - last = slice[slice.length - 1]; - if (closed && last && (slice[0][0] !== last[0] || slice[0][1] !== last[1])) slice.push(slice[0]); - - // add the final slice - newSlice(slices, slice, area, dist, outer); - } - - return slices; -} - -function newSlice(slices, slice, area, dist, outer) { - if (slice.length) { - // we don't recalculate the area/length of the unclipped geometry because the case where it goes - // below the visibility threshold as a result of clipping is rare, so we avoid doing unnecessary work - slice.area = area; - slice.dist = dist; - if (outer !== undefined) slice.outer = outer; - - slices.push(slice); - } - return []; -} - -},{"./feature":20}],19:[function(require,module,exports){ -'use strict'; - -module.exports = convert; - -var simplify = require('./simplify'); -var createFeature = require('./feature'); - -// converts GeoJSON feature into an intermediate projected JSON vector format with simplification data - -function convert(data, tolerance) { - var features = []; - - if (data.type === 'FeatureCollection') { - for (var i = 0; i < data.features.length; i++) { - convertFeature(features, data.features[i], tolerance); - } - } else if (data.type === 'Feature') { - convertFeature(features, data, tolerance); - - } else { - // single geometry or a geometry collection - convertFeature(features, {geometry: data}, tolerance); - } - return features; -} - -function convertFeature(features, feature, tolerance) { - if (feature.geometry === null) { - // ignore features with null geometry - return; - } - - var geom = feature.geometry, - type = geom.type, - coords = geom.coordinates, - tags = feature.properties, - id = feature.id, - i, j, rings, projectedRing; - - if (type === 'Point') { - features.push(createFeature(tags, 1, [projectPoint(coords)], id)); - - } else if (type === 'MultiPoint') { - features.push(createFeature(tags, 1, project(coords), id)); - - } else if (type === 'LineString') { - features.push(createFeature(tags, 2, [project(coords, tolerance)], id)); - - } else if (type === 'MultiLineString' || type === 'Polygon') { - rings = []; - for (i = 0; i < coords.length; i++) { - projectedRing = project(coords[i], tolerance); - if (type === 'Polygon') projectedRing.outer = (i === 0); - rings.push(projectedRing); - } - features.push(createFeature(tags, type === 'Polygon' ? 3 : 2, rings, id)); - - } else if (type === 'MultiPolygon') { - rings = []; - for (i = 0; i < coords.length; i++) { - for (j = 0; j < coords[i].length; j++) { - projectedRing = project(coords[i][j], tolerance); - projectedRing.outer = (j === 0); - rings.push(projectedRing); - } - } - features.push(createFeature(tags, 3, rings, id)); - - } else if (type === 'GeometryCollection') { - for (i = 0; i < geom.geometries.length; i++) { - convertFeature(features, { - geometry: geom.geometries[i], - properties: tags - }, tolerance); - } - - } else { - throw new Error('Input data is not a valid GeoJSON object.'); - } -} - -function project(lonlats, tolerance) { - var projected = []; - for (var i = 0; i < lonlats.length; i++) { - projected.push(projectPoint(lonlats[i])); - } - if (tolerance) { - simplify(projected, tolerance); - calcSize(projected); - } - return projected; -} - -function projectPoint(p) { - var sin = Math.sin(p[1] * Math.PI / 180), - x = (p[0] / 360 + 0.5), - y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI); - - y = y < 0 ? 0 : - y > 1 ? 1 : y; - - return [x, y, 0]; -} - -// calculate area and length of the poly -function calcSize(points) { - var area = 0, - dist = 0; - - for (var i = 0, a, b; i < points.length - 1; i++) { - a = b || points[i]; - b = points[i + 1]; - - area += a[0] * b[1] - b[0] * a[1]; - - // use Manhattan distance instead of Euclidian one to avoid expensive square root computation - dist += Math.abs(b[0] - a[0]) + Math.abs(b[1] - a[1]); - } - points.area = Math.abs(area / 2); - points.dist = dist; -} - -},{"./feature":20,"./simplify":22}],20:[function(require,module,exports){ -'use strict'; - -module.exports = createFeature; - -function createFeature(tags, type, geom, id) { - var feature = { - id: id || null, - type: type, - geometry: geom, - tags: tags || null, - min: [Infinity, Infinity], // initial bbox values - max: [-Infinity, -Infinity] - }; - calcBBox(feature); - return feature; -} - -// calculate the feature bounding box for faster clipping later -function calcBBox(feature) { - var geometry = feature.geometry, - min = feature.min, - max = feature.max; - - if (feature.type === 1) { - calcRingBBox(min, max, geometry); - } else { - for (var i = 0; i < geometry.length; i++) { - calcRingBBox(min, max, geometry[i]); - } - } - - return feature; -} - -function calcRingBBox(min, max, points) { - for (var i = 0, p; i < points.length; i++) { - p = points[i]; - min[0] = Math.min(p[0], min[0]); - max[0] = Math.max(p[0], max[0]); - min[1] = Math.min(p[1], min[1]); - max[1] = Math.max(p[1], max[1]); - } -} - -},{}],21:[function(require,module,exports){ -'use strict'; - -module.exports = geojsonvt; - -var convert = require('./convert'), // GeoJSON conversion and preprocessing - transform = require('./transform'), // coordinate transformation - clip = require('./clip'), // stripe clipping algorithm - wrap = require('./wrap'), // date line processing - createTile = require('./tile'); // final simplified tile generation - - -function geojsonvt(data, options) { - return new GeoJSONVT(data, options); -} - -function GeoJSONVT(data, options) { - options = this.options = extend(Object.create(this.options), options); - - var debug = options.debug; - - if (debug) console.time('preprocess data'); - - var z2 = 1 << options.maxZoom, // 2^z - features = convert(data, options.tolerance / (z2 * options.extent)); - - 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.buffer / options.extent, intersectX); - - // start slicing from the top tile down - 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, // max zoom to preserve detail on - indexMaxZoom: 5, // max zoom in the tile index - indexMaxPoints: 100000, // max number of points per tile in the tile index - solidChildren: false, // whether to tile solid square tiles further - tolerance: 3, // simplification tolerance (higher means simpler) - extent: 4096, // tile extent - buffer: 64, // tile buffer on each side - debug: 0 // logging level (0, 1 or 2) -}; - -GeoJSONVT.prototype.splitTile = function (features, z, x, y, cz, cx, cy) { - - var stack = [features, z, x, y], - options = this.options, - debug = options.debug, - solid = null; - - // avoid recursion by using a processing queue - 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], - tileTolerance = z === options.maxZoom ? 0 : options.tolerance / (z2 * options.extent); - - if (!tile) { - if (debug > 1) console.time('creation'); - - tile = this.tiles[id] = createTile(features, z2, x, y, tileTolerance, z === options.maxZoom); - 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++; - } - } - - // save reference to original geometry in tile so that we can drill down later if we stop now - tile.source = features; - - // if it's the first-pass tiling - if (!cz) { - // stop tiling if we reached max zoom, or if the tile is too simple - if (z === options.indexMaxZoom || tile.numPoints <= options.indexMaxPoints) continue; - - // if a drilldown to a specific tile - } else { - // stop tiling if we reached base zoom or our target tile zoom - if (z === options.maxZoom || z === cz) continue; - - // stop tiling if it's not an ancestor of the target tile - var m = 1 << (cz - z); - if (x !== Math.floor(cx / m) || y !== Math.floor(cy / m)) continue; - } - - // stop tiling if the tile is solid clipped square - if (!options.solidChildren && isClippedSquare(tile, options.extent, options.buffer)) { - if (cz) solid = z; // and remember the zoom if we're drilling down - continue; - } - - // if we slice further down, no need to keep source geometry - tile.source = null; - - if (debug > 1) console.time('clipping'); - - // values we'll use for 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, intersectX, tile.min[0], tile.max[0]); - right = clip(features, z2, x + k2, x + k4, 0, intersectX, tile.min[0], tile.max[0]); - - if (left) { - tl = clip(left, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]); - bl = clip(left, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]); - } - - if (right) { - tr = clip(right, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]); - br = clip(right, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]); - } - - if (debug > 1) console.timeEnd('clipping'); - - if (features.length) { - 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); - } - } - - return solid; -}; - -GeoJSONVT.prototype.getTile = function (z, x, y) { - var options = this.options, - extent = options.extent, - debug = options.debug; - - var z2 = 1 << z; - x = ((x % z2) + z2) % z2; // wrap tile x coordinate - - var id = toID(z, x, y); - if (this.tiles[id]) return transform.tile(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 we found a parent tile containing the original geometry, we can drill down from it - if (debug > 1) console.log('found parent tile z%d-%d-%d', z0, x0, y0); - - // it parent tile is a solid clipped square, return it instead since it's identical - if (isClippedSquare(parent, extent, options.buffer)) return transform.tile(parent, extent); - - if (debug > 1) console.time('drilling down'); - var solid = this.splitTile(parent.source, z0, x0, y0, z, x, y); - if (debug > 1) console.timeEnd('drilling down'); - - // one of the parent tiles was a solid clipped square - if (solid !== null) { - var m = 1 << (z - solid); - id = toID(solid, Math.floor(x / m), Math.floor(y / m)); - } - - return this.tiles[id] ? transform.tile(this.tiles[id], extent) : null; -}; - -function toID(z, x, y) { - return (((1 << z) * y + x) * 32) + z; -} - -function intersectX(a, b, x) { - return [x, (x - a[0]) * (b[1] - a[1]) / (b[0] - a[0]) + a[1], 1]; -} -function intersectY(a, b, y) { - return [(y - a[1]) * (b[0] - a[0]) / (b[1] - a[1]) + a[0], y, 1]; -} - -function extend(dest, src) { - for (var i in src) dest[i] = src[i]; - return dest; -} - -// checks whether a tile is a whole-area fill after clipping; if it is, there's no sense slicing it further -function isClippedSquare(tile, extent, buffer) { - - var features = tile.source; - if (features.length !== 1) return false; - - var feature = features[0]; - if (feature.type !== 3 || feature.geometry.length > 1) return false; - - var len = feature.geometry[0].length; - if (len !== 5) return false; - - for (var i = 0; i < len; i++) { - var p = transform.point(feature.geometry[0][i], extent, tile.z2, tile.x, tile.y); - if ((p[0] !== -buffer && p[0] !== extent + buffer) || - (p[1] !== -buffer && p[1] !== extent + buffer)) return false; - } - - return true; -} - -},{"./clip":18,"./convert":19,"./tile":23,"./transform":24,"./wrap":25}],22:[function(require,module,exports){ -'use strict'; - -module.exports = simplify; - -// calculate simplification data using optimized Douglas-Peucker algorithm - -function simplify(points, tolerance) { - - var sqTolerance = tolerance * tolerance, - len = points.length, - first = 0, - last = len - 1, - stack = [], - i, maxSqDist, sqDist, index; - - // always retain the endpoints (1 is the max value) - points[first][2] = 1; - points[last][2] = 1; - - // avoid recursion by using a stack - while (last) { - - maxSqDist = 0; - - for (i = first + 1; i < last; i++) { - sqDist = getSqSegDist(points[i], points[first], points[last]); - - if (sqDist > maxSqDist) { - index = i; - maxSqDist = sqDist; - } - } - - if (maxSqDist > sqTolerance) { - points[index][2] = maxSqDist; // save the point importance in squared pixels as a z coordinate - stack.push(first); - stack.push(index); - first = index; - - } else { - last = stack.pop(); - first = stack.pop(); - } - } -} - -// square distance from a point to a segment -function getSqSegDist(p, a, b) { - - var x = a[0], y = a[1], - bx = b[0], by = b[1], - px = p[0], py = p[1], - dx = bx - x, - 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; -} - -},{}],23:[function(require,module,exports){ -'use strict'; - -module.exports = createTile; - -function createTile(features, z2, tx, ty, tolerance, noSimplify) { - var tile = { - features: [], - numPoints: 0, - numSimplified: 0, - numFeatures: 0, - source: null, - x: tx, - y: ty, - z2: z2, - transformed: false, - min: [2, 1], - max: [-1, 0] - }; - for (var i = 0; i < features.length; i++) { - tile.numFeatures++; - addFeature(tile, features[i], tolerance, noSimplify); - - var min = features[i].min, - max = features[i].max; - - if (min[0] < tile.min[0]) tile.min[0] = min[0]; - if (min[1] < tile.min[1]) tile.min[1] = min[1]; - if (max[0] > tile.max[0]) tile.max[0] = max[0]; - if (max[1] > tile.max[1]) tile.max[1] = max[1]; - } - return tile; -} - -function addFeature(tile, feature, tolerance, noSimplify) { - - var geom = feature.geometry, - type = feature.type, - simplified = [], - sqTolerance = tolerance * tolerance, - i, j, ring, p; - - if (type === 1) { - for (i = 0; i < geom.length; i++) { - simplified.push(geom[i]); - tile.numPoints++; - tile.numSimplified++; - } - - } else { - - // simplify and transform projected coordinates for tile geometry - for (i = 0; i < geom.length; i++) { - ring = geom[i]; - - // filter out tiny polylines & polygons - if (!noSimplify && ((type === 2 && ring.dist < tolerance) || - (type === 3 && ring.area < sqTolerance))) { - tile.numPoints += ring.length; - continue; - } - - var simplifiedRing = []; - - for (j = 0; j < ring.length; j++) { - p = ring[j]; - // keep points with importance > tolerance - if (noSimplify || p[2] > sqTolerance) { - simplifiedRing.push(p); - tile.numSimplified++; - } - tile.numPoints++; - } - - if (type === 3) rewind(simplifiedRing, ring.outer); - - simplified.push(simplifiedRing); - } - } - - if (simplified.length) { - var tileFeature = { - geometry: simplified, - type: type, - tags: feature.tags || null - }; - if (feature.id !== null) { - tileFeature.id = feature.id; - } - tile.features.push(tileFeature); - } -} - -function rewind(ring, clockwise) { - var area = signedArea(ring); - if (area < 0 === clockwise) ring.reverse(); -} - -function signedArea(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[0] - p1[0]) * (p1[1] + p2[1]); - } - return sum; -} - -},{}],24:[function(require,module,exports){ -'use strict'; - -exports.tile = transformTile; -exports.point = transformPoint; - -// Transforms the coordinates of each feature in the given tile from -// mercator-projected space into (extent x extent) tile space. -function transformTile(tile, extent) { - if (tile.transformed) return tile; - - var z2 = tile.z2, - 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; - - if (type === 1) { - for (j = 0; j < geom.length; j++) geom[j] = transformPoint(geom[j], extent, z2, tx, ty); - - } else { - for (j = 0; j < geom.length; j++) { - var ring = geom[j]; - for (k = 0; k < ring.length; k++) ring[k] = transformPoint(ring[k], extent, z2, tx, ty); - } - } - } - - tile.transformed = true; - - return tile; -} - -function transformPoint(p, extent, z2, tx, ty) { - var x = Math.round(extent * (p[0] * z2 - tx)), - y = Math.round(extent * (p[1] * z2 - ty)); - return [x, y]; -} - -},{}],25:[function(require,module,exports){ -'use strict'; - -var clip = require('./clip'); -var createFeature = require('./feature'); - -module.exports = wrap; - -function wrap(features, buffer, intersectX) { - var merged = features, - left = clip(features, 1, -1 - buffer, buffer, 0, intersectX, -1, 2), // left world copy - right = clip(features, 1, 1 - buffer, 2 + buffer, 0, intersectX, -1, 2); // right world copy - - if (left || right) { - merged = clip(features, 1, -buffer, 1 + buffer, 0, intersectX, -1, 2) || []; // center world copy - - if (left) merged = shiftFeatureCoords(left, 1).concat(merged); // merge left into center - if (right) merged = merged.concat(shiftFeatureCoords(right, -1)); // merge right into center - } - - 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 === 1) { - newGeometry = shiftCoords(feature.geometry, offset); - } else { - newGeometry = []; - for (var j = 0; j < feature.geometry.length; j++) { - newGeometry.push(shiftCoords(feature.geometry[j], offset)); - } - } - - newFeatures.push(createFeature(feature.tags, type, newGeometry, feature.id)); - } - - return newFeatures; -} - -function shiftCoords(points, offset) { - var newPoints = []; - newPoints.area = points.area; - newPoints.dist = points.dist; - - for (var i = 0; i < points.length; i++) { - newPoints.push([points[i][0] + offset, points[i][1], points[i][2]]); - } - return newPoints; -} - -},{"./clip":18,"./feature":20}],26:[function(require,module,exports){ -/** - * @fileoverview gl-matrix - High performance matrix and vector operations - * @author Brandon Jones - * @author Colin MacKenzie IV - * @version 2.3.2 - */ - -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ -// END HEADER - -exports.glMatrix = require("./gl-matrix/common.js"); -exports.mat2 = require("./gl-matrix/mat2.js"); -exports.mat2d = require("./gl-matrix/mat2d.js"); -exports.mat3 = require("./gl-matrix/mat3.js"); -exports.mat4 = require("./gl-matrix/mat4.js"); -exports.quat = require("./gl-matrix/quat.js"); -exports.vec2 = require("./gl-matrix/vec2.js"); -exports.vec3 = require("./gl-matrix/vec3.js"); -exports.vec4 = require("./gl-matrix/vec4.js"); -},{"./gl-matrix/common.js":27,"./gl-matrix/mat2.js":28,"./gl-matrix/mat2d.js":29,"./gl-matrix/mat3.js":30,"./gl-matrix/mat4.js":31,"./gl-matrix/quat.js":32,"./gl-matrix/vec2.js":33,"./gl-matrix/vec3.js":34,"./gl-matrix/vec4.js":35}],27:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -/** - * @class Common utilities - * @name glMatrix - */ -var glMatrix = {}; - -// Configuration Constants -glMatrix.EPSILON = 0.000001; -glMatrix.ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array; -glMatrix.RANDOM = Math.random; -glMatrix.ENABLE_SIMD = false; - -// Capability detection -glMatrix.SIMD_AVAILABLE = (glMatrix.ARRAY_TYPE === Float32Array) && ('SIMD' in this); -glMatrix.USE_SIMD = glMatrix.ENABLE_SIMD && glMatrix.SIMD_AVAILABLE; - -/** - * Sets the type of array used when creating new vectors and matrices - * - * @param {Type} type Array type, such as Float32Array or Array - */ -glMatrix.setMatrixArrayType = function(type) { - glMatrix.ARRAY_TYPE = type; -} - -var degree = Math.PI / 180; - -/** -* Convert Degree To Radian -* -* @param {Number} Angle in Degrees -*/ -glMatrix.toRadian = function(a){ - return a * degree; -} - -/** - * Tests whether or not the arguments have approximately the same value, within an absolute - * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less - * than or equal to 1.0, and a relative tolerance is used for larger values) - * - * @param {Number} a The first number to test. - * @param {Number} b The second number to test. - * @returns {Boolean} True if the numbers are approximately equal, false otherwise. - */ -glMatrix.equals = function(a, b) { - return Math.abs(a - b) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a), Math.abs(b)); -} - -module.exports = glMatrix; - -},{}],28:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 2x2 Matrix - * @name mat2 - */ -var mat2 = {}; - -/** - * Creates a new identity mat2 - * - * @returns {mat2} a new 2x2 matrix - */ -mat2.create = function() { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -}; - -/** - * Creates a new mat2 initialized with values from an existing matrix - * - * @param {mat2} a matrix to clone - * @returns {mat2} a new 2x2 matrix - */ -mat2.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - return out; -}; - -/** - * Copy the values from one mat2 to another - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out - */ -mat2.copy = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - return out; -}; - -/** - * Set a mat2 to the identity matrix - * - * @param {mat2} out the receiving matrix - * @returns {mat2} out - */ -mat2.identity = function(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -}; - -/** - * Create a new mat2 with the given values - * - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m10 Component in column 1, row 0 position (index 2) - * @param {Number} m11 Component in column 1, row 1 position (index 3) - * @returns {mat2} out A new 2x2 matrix - */ -mat2.fromValues = function(m00, m01, m10, m11) { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = m00; - out[1] = m01; - out[2] = m10; - out[3] = m11; - return out; -}; - -/** - * Set the components of a mat2 to the given values - * - * @param {mat2} out the receiving matrix - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m10 Component in column 1, row 0 position (index 2) - * @param {Number} m11 Component in column 1, row 1 position (index 3) - * @returns {mat2} out - */ -mat2.set = function(out, m00, m01, m10, m11) { - out[0] = m00; - out[1] = m01; - out[2] = m10; - out[3] = m11; - return out; -}; - - -/** - * Transpose the values of a mat2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out - */ -mat2.transpose = function(out, a) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (out === a) { - var a1 = a[1]; - out[1] = a[2]; - out[2] = a1; - } else { - out[0] = a[0]; - out[1] = a[2]; - out[2] = a[1]; - out[3] = a[3]; - } - - return out; -}; - -/** - * Inverts a mat2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out - */ -mat2.invert = function(out, a) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], - - // Calculate the determinant - det = a0 * a3 - a2 * a1; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = a3 * det; - out[1] = -a1 * det; - out[2] = -a2 * det; - out[3] = a0 * det; - - return out; -}; - -/** - * Calculates the adjugate of a mat2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out - */ -mat2.adjoint = function(out, a) { - // Caching this value is nessecary if out == a - var a0 = a[0]; - out[0] = a[3]; - out[1] = -a[1]; - out[2] = -a[2]; - out[3] = a0; - - return out; -}; - -/** - * Calculates the determinant of a mat2 - * - * @param {mat2} a the source matrix - * @returns {Number} determinant of a - */ -mat2.determinant = function (a) { - return a[0] * a[3] - a[2] * a[1]; -}; - -/** - * Multiplies two mat2's - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -mat2.multiply = function (out, a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; - out[0] = a0 * b0 + a2 * b1; - out[1] = a1 * b0 + a3 * b1; - out[2] = a0 * b2 + a2 * b3; - out[3] = a1 * b2 + a3 * b3; - return out; -}; - -/** - * Alias for {@link mat2.multiply} - * @function - */ -mat2.mul = mat2.multiply; - -/** - * Rotates a mat2 by the given angle - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2} out - */ -mat2.rotate = function (out, a, rad) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], - s = Math.sin(rad), - 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; -}; - -/** - * Scales the mat2 by the dimensions in the given vec2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat2} out - **/ -mat2.scale = function(out, a, v) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], - v0 = v[0], v1 = v[1]; - out[0] = a0 * v0; - out[1] = a1 * v0; - out[2] = a2 * v1; - out[3] = a3 * v1; - return out; -}; - -/** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat2.identity(dest); - * mat2.rotate(dest, dest, rad); - * - * @param {mat2} out mat2 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2} out - */ -mat2.fromRotation = function(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - out[0] = c; - out[1] = s; - out[2] = -s; - out[3] = c; - return out; -} - -/** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat2.identity(dest); - * mat2.scale(dest, dest, vec); - * - * @param {mat2} out mat2 receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat2} out - */ -mat2.fromScaling = function(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - out[3] = v[1]; - return out; -} - -/** - * Returns a string representation of a mat2 - * - * @param {mat2} mat matrix to represent as a string - * @returns {String} string representation of the matrix - */ -mat2.str = function (a) { - return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; -}; - -/** - * Returns Frobenius norm of a mat2 - * - * @param {mat2} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm - */ -mat2.frob = function (a) { - return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2))) -}; - -/** - * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix - * @param {mat2} L the lower triangular matrix - * @param {mat2} D the diagonal matrix - * @param {mat2} U the upper triangular matrix - * @param {mat2} a the input matrix to factorize - */ - -mat2.LDU = function (L, D, U, a) { - L[2] = a[2]/a[0]; - U[0] = a[0]; - U[1] = a[1]; - U[3] = a[3] - L[2] * U[1]; - return [L, D, U]; -}; - -/** - * Adds two mat2's - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -mat2.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - return out; -}; - -/** - * Subtracts matrix b from matrix a - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -mat2.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - return out; -}; - -/** - * Alias for {@link mat2.subtract} - * @function - */ -mat2.sub = mat2.subtract; - -/** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat2.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; -}; - -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat2.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && - Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3))); -}; - -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat2} out - */ -mat2.multiplyScalar = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - return out; -}; - -/** - * Adds two mat2's after multiplying each element of the second operand by a scalar value. - * - * @param {mat2} out the receiving vector - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat2} out - */ -mat2.multiplyScalarAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - out[3] = a[3] + (b[3] * scale); - return out; -}; - -module.exports = mat2; - -},{"./common.js":27}],29:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 2x3 Matrix - * @name mat2d - * - * @description - * A mat2d contains six elements defined as: - *
- * [a, c, tx,
- *  b, d, ty]
- * 
- * This is a short form for the 3x3 matrix: - *
- * [a, c, tx,
- *  b, d, ty,
- *  0, 0, 1]
- * 
- * The last row is ignored so the array is shorter and operations are faster. - */ -var mat2d = {}; - -/** - * Creates a new identity mat2d - * - * @returns {mat2d} a new 2x3 matrix - */ -mat2d.create = function() { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = 0; - out[5] = 0; - return out; -}; - -/** - * Creates a new mat2d initialized with values from an existing matrix - * - * @param {mat2d} a matrix to clone - * @returns {mat2d} a new 2x3 matrix - */ -mat2d.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - return out; -}; - -/** - * Copy the values from one mat2d to another - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the source matrix - * @returns {mat2d} out - */ -mat2d.copy = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - return out; -}; - -/** - * Set a mat2d to the identity matrix - * - * @param {mat2d} out the receiving matrix - * @returns {mat2d} out - */ -mat2d.identity = function(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = 0; - out[5] = 0; - return out; -}; - -/** - * Create a new mat2d with the given values - * - * @param {Number} a Component A (index 0) - * @param {Number} b Component B (index 1) - * @param {Number} c Component C (index 2) - * @param {Number} d Component D (index 3) - * @param {Number} tx Component TX (index 4) - * @param {Number} ty Component TY (index 5) - * @returns {mat2d} A new mat2d - */ -mat2d.fromValues = function(a, b, c, d, tx, ty) { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = a; - out[1] = b; - out[2] = c; - out[3] = d; - out[4] = tx; - out[5] = ty; - return out; -}; - -/** - * Set the components of a mat2d to the given values - * - * @param {mat2d} out the receiving matrix - * @param {Number} a Component A (index 0) - * @param {Number} b Component B (index 1) - * @param {Number} c Component C (index 2) - * @param {Number} d Component D (index 3) - * @param {Number} tx Component TX (index 4) - * @param {Number} ty Component TY (index 5) - * @returns {mat2d} out - */ -mat2d.set = function(out, a, b, c, d, tx, ty) { - out[0] = a; - out[1] = b; - out[2] = c; - out[3] = d; - out[4] = tx; - out[5] = ty; - return out; -}; - -/** - * Inverts a mat2d - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the source matrix - * @returns {mat2d} out - */ -mat2d.invert = function(out, a) { - var aa = a[0], ab = a[1], ac = a[2], ad = a[3], - atx = a[4], aty = a[5]; - - var det = aa * ad - ab * ac; - if(!det){ - return null; - } - det = 1.0 / det; - - out[0] = ad * det; - out[1] = -ab * det; - out[2] = -ac * det; - out[3] = aa * det; - out[4] = (ac * aty - ad * atx) * det; - out[5] = (ab * atx - aa * aty) * det; - return out; -}; - -/** - * Calculates the determinant of a mat2d - * - * @param {mat2d} a the source matrix - * @returns {Number} determinant of a - */ -mat2d.determinant = function (a) { - return a[0] * a[3] - a[1] * a[2]; -}; - -/** - * Multiplies two mat2d's - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -mat2d.multiply = function (out, a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], - b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; - out[0] = a0 * b0 + a2 * b1; - out[1] = a1 * b0 + a3 * b1; - out[2] = a0 * b2 + a2 * b3; - out[3] = a1 * b2 + a3 * b3; - out[4] = a0 * b4 + a2 * b5 + a4; - out[5] = a1 * b4 + a3 * b5 + a5; - return out; -}; - -/** - * Alias for {@link mat2d.multiply} - * @function - */ -mat2d.mul = mat2d.multiply; - -/** - * Rotates a mat2d by the given angle - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2d} out - */ -mat2d.rotate = function (out, a, rad) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], - s = Math.sin(rad), - 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; - out[4] = a4; - out[5] = a5; - return out; -}; - -/** - * Scales the mat2d by the dimensions in the given vec2 - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to translate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat2d} out - **/ -mat2d.scale = function(out, a, v) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], - v0 = v[0], v1 = v[1]; - out[0] = a0 * v0; - out[1] = a1 * v0; - out[2] = a2 * v1; - out[3] = a3 * v1; - out[4] = a4; - out[5] = a5; - return out; -}; - -/** - * Translates the mat2d by the dimensions in the given vec2 - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to translate - * @param {vec2} v the vec2 to translate the matrix by - * @returns {mat2d} out - **/ -mat2d.translate = function(out, a, v) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], - v0 = v[0], v1 = v[1]; - out[0] = a0; - out[1] = a1; - out[2] = a2; - out[3] = a3; - out[4] = a0 * v0 + a2 * v1 + a4; - out[5] = a1 * v0 + a3 * v1 + a5; - return out; -}; - -/** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.rotate(dest, dest, rad); - * - * @param {mat2d} out mat2d receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2d} out - */ -mat2d.fromRotation = function(out, rad) { - var s = Math.sin(rad), c = Math.cos(rad); - out[0] = c; - out[1] = s; - out[2] = -s; - out[3] = c; - out[4] = 0; - out[5] = 0; - return out; -} - -/** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.scale(dest, dest, vec); - * - * @param {mat2d} out mat2d receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat2d} out - */ -mat2d.fromScaling = function(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - out[3] = v[1]; - out[4] = 0; - out[5] = 0; - return out; -} - -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.translate(dest, dest, vec); - * - * @param {mat2d} out mat2d receiving operation result - * @param {vec2} v Translation vector - * @returns {mat2d} out - */ -mat2d.fromTranslation = function(out, v) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = v[0]; - out[5] = v[1]; - return out; -} - -/** - * Returns a string representation of a mat2d - * - * @param {mat2d} a matrix to represent as a string - * @returns {String} string representation of the matrix - */ -mat2d.str = function (a) { - return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + - a[3] + ', ' + a[4] + ', ' + a[5] + ')'; -}; - -/** - * Returns Frobenius norm of a mat2d - * - * @param {mat2d} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm - */ -mat2d.frob = function (a) { - return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1)) -}; - -/** - * Adds two mat2d's - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -mat2d.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - return out; -}; - -/** - * Subtracts matrix b from matrix a - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -mat2d.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - out[4] = a[4] - b[4]; - out[5] = a[5] - b[5]; - return out; -}; - -/** - * Alias for {@link mat2d.subtract} - * @function - */ -mat2d.sub = mat2d.subtract; - -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat2d} out - */ -mat2d.multiplyScalar = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - out[4] = a[4] * b; - out[5] = a[5] * b; - return out; -}; - -/** - * Adds two mat2d's after multiplying each element of the second operand by a scalar value. - * - * @param {mat2d} out the receiving vector - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat2d} out - */ -mat2d.multiplyScalarAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - out[3] = a[3] + (b[3] * scale); - out[4] = a[4] + (b[4] * scale); - out[5] = a[5] + (b[5] * scale); - return out; -}; - -/** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat2d} a The first matrix. - * @param {mat2d} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat2d.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; -}; - -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat2d} a The first matrix. - * @param {mat2d} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat2d.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && - Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3)) && - Math.abs(a4 - b4) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a4), Math.abs(b4)) && - Math.abs(a5 - b5) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a5), Math.abs(b5))); -}; - -module.exports = mat2d; - -},{"./common.js":27}],30:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 3x3 Matrix - * @name mat3 - */ -var mat3 = {}; - -/** - * Creates a new identity mat3 - * - * @returns {mat3} a new 3x3 matrix - */ -mat3.create = function() { - var out = new glMatrix.ARRAY_TYPE(9); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -}; - -/** - * Copies the upper-left 3x3 values into the given mat3. - * - * @param {mat3} out the receiving 3x3 matrix - * @param {mat4} a the source 4x4 matrix - * @returns {mat3} out - */ -mat3.fromMat4 = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[4]; - out[4] = a[5]; - out[5] = a[6]; - out[6] = a[8]; - out[7] = a[9]; - out[8] = a[10]; - return out; -}; - -/** - * Creates a new mat3 initialized with values from an existing matrix - * - * @param {mat3} a matrix to clone - * @returns {mat3} a new 3x3 matrix - */ -mat3.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(9); - 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]; - return out; -}; - -/** - * Copy the values from one mat3 to another - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -mat3.copy = function(out, a) { - 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]; - return out; -}; - -/** - * Create a new mat3 with the given values - * - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m10 Component in column 1, row 0 position (index 3) - * @param {Number} m11 Component in column 1, row 1 position (index 4) - * @param {Number} m12 Component in column 1, row 2 position (index 5) - * @param {Number} m20 Component in column 2, row 0 position (index 6) - * @param {Number} m21 Component in column 2, row 1 position (index 7) - * @param {Number} m22 Component in column 2, row 2 position (index 8) - * @returns {mat3} A new mat3 - */ -mat3.fromValues = function(m00, m01, m02, m10, m11, m12, m20, m21, m22) { - var out = new glMatrix.ARRAY_TYPE(9); - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m10; - out[4] = m11; - out[5] = m12; - out[6] = m20; - out[7] = m21; - out[8] = m22; - return out; -}; - -/** - * Set the components of a mat3 to the given values - * - * @param {mat3} out the receiving matrix - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m10 Component in column 1, row 0 position (index 3) - * @param {Number} m11 Component in column 1, row 1 position (index 4) - * @param {Number} m12 Component in column 1, row 2 position (index 5) - * @param {Number} m20 Component in column 2, row 0 position (index 6) - * @param {Number} m21 Component in column 2, row 1 position (index 7) - * @param {Number} m22 Component in column 2, row 2 position (index 8) - * @returns {mat3} out - */ -mat3.set = function(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m10; - out[4] = m11; - out[5] = m12; - out[6] = m20; - out[7] = m21; - out[8] = m22; - return out; -}; - -/** - * Set a mat3 to the identity matrix - * - * @param {mat3} out the receiving matrix - * @returns {mat3} out - */ -mat3.identity = function(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -}; - -/** - * Transpose the values of a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -mat3.transpose = function(out, a) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (out === a) { - var a01 = a[1], a02 = a[2], a12 = a[5]; - out[1] = a[3]; - out[2] = a[6]; - out[3] = a01; - out[5] = a[7]; - out[6] = a02; - out[7] = a12; - } else { - out[0] = a[0]; - out[1] = a[3]; - out[2] = a[6]; - out[3] = a[1]; - out[4] = a[4]; - out[5] = a[7]; - out[6] = a[2]; - out[7] = a[5]; - out[8] = a[8]; - } - - return out; -}; - -/** - * Inverts a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -mat3.invert = function(out, a) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8], - - b01 = a22 * a11 - a12 * a21, - b11 = -a22 * a10 + a12 * a20, - b21 = a21 * a10 - a11 * a20, - - // Calculate the determinant - det = a00 * b01 + a01 * b11 + a02 * b21; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = b01 * det; - out[1] = (-a22 * a01 + a02 * a21) * det; - out[2] = (a12 * a01 - a02 * a11) * det; - out[3] = b11 * det; - out[4] = (a22 * a00 - a02 * a20) * det; - out[5] = (-a12 * a00 + a02 * a10) * det; - out[6] = b21 * det; - out[7] = (-a21 * a00 + a01 * a20) * det; - out[8] = (a11 * a00 - a01 * a10) * det; - return out; -}; - -/** - * Calculates the adjugate of a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -mat3.adjoint = function(out, a) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8]; - - out[0] = (a11 * a22 - a12 * a21); - out[1] = (a02 * a21 - a01 * a22); - out[2] = (a01 * a12 - a02 * a11); - out[3] = (a12 * a20 - a10 * a22); - out[4] = (a00 * a22 - a02 * a20); - out[5] = (a02 * a10 - a00 * a12); - out[6] = (a10 * a21 - a11 * a20); - out[7] = (a01 * a20 - a00 * a21); - out[8] = (a00 * a11 - a01 * a10); - return out; -}; - -/** - * Calculates the determinant of a mat3 - * - * @param {mat3} a the source matrix - * @returns {Number} determinant of a - */ -mat3.determinant = function (a) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8]; - - return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); -}; - -/** - * Multiplies two mat3's - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -mat3.multiply = function (out, a, b) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8], - - b00 = b[0], b01 = b[1], b02 = b[2], - b10 = b[3], b11 = b[4], b12 = b[5], - b20 = b[6], b21 = b[7], b22 = b[8]; - - out[0] = b00 * a00 + b01 * a10 + b02 * a20; - out[1] = b00 * a01 + b01 * a11 + b02 * a21; - out[2] = b00 * a02 + b01 * a12 + b02 * a22; - - out[3] = b10 * a00 + b11 * a10 + b12 * a20; - out[4] = b10 * a01 + b11 * a11 + b12 * a21; - out[5] = b10 * a02 + b11 * a12 + b12 * a22; - - out[6] = b20 * a00 + b21 * a10 + b22 * a20; - out[7] = b20 * a01 + b21 * a11 + b22 * a21; - out[8] = b20 * a02 + b21 * a12 + b22 * a22; - return out; -}; - -/** - * Alias for {@link mat3.multiply} - * @function - */ -mat3.mul = mat3.multiply; - -/** - * Translate a mat3 by the given vector - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to translate - * @param {vec2} v vector to translate by - * @returns {mat3} out - */ -mat3.translate = function(out, a, v) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8], - x = v[0], y = v[1]; - - out[0] = a00; - out[1] = a01; - out[2] = a02; - - out[3] = a10; - out[4] = a11; - out[5] = a12; - - out[6] = x * a00 + y * a10 + a20; - out[7] = x * a01 + y * a11 + a21; - out[8] = x * a02 + y * a12 + a22; - return out; -}; - -/** - * Rotates a mat3 by the given angle - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat3} out - */ -mat3.rotate = function (out, a, rad) { - var a00 = a[0], a01 = a[1], a02 = a[2], - a10 = a[3], a11 = a[4], a12 = a[5], - a20 = a[6], a21 = a[7], a22 = a[8], - - s = Math.sin(rad), - c = Math.cos(rad); - - out[0] = c * a00 + s * a10; - out[1] = c * a01 + s * a11; - out[2] = c * a02 + s * a12; - - out[3] = c * a10 - s * a00; - out[4] = c * a11 - s * a01; - out[5] = c * a12 - s * a02; - - out[6] = a20; - out[7] = a21; - out[8] = a22; - return out; -}; - -/** - * Scales the mat3 by the dimensions in the given vec2 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat3} out - **/ -mat3.scale = function(out, a, v) { - var x = v[0], y = v[1]; - - out[0] = x * a[0]; - out[1] = x * a[1]; - out[2] = x * a[2]; - - out[3] = y * a[3]; - out[4] = y * a[4]; - out[5] = y * a[5]; - - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - return out; -}; - -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.translate(dest, dest, vec); - * - * @param {mat3} out mat3 receiving operation result - * @param {vec2} v Translation vector - * @returns {mat3} out - */ -mat3.fromTranslation = function(out, v) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = v[0]; - out[7] = v[1]; - out[8] = 1; - return out; -} - -/** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.rotate(dest, dest, rad); - * - * @param {mat3} out mat3 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat3} out - */ -mat3.fromRotation = function(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; -} - -/** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.scale(dest, dest, vec); - * - * @param {mat3} out mat3 receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat3} out - */ -mat3.fromScaling = function(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - - out[3] = 0; - out[4] = v[1]; - out[5] = 0; - - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -} - -/** - * Copies the values from a mat2d into a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat2d} a the matrix to copy - * @returns {mat3} out - **/ -mat3.fromMat2d = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = 0; - - out[3] = a[2]; - out[4] = a[3]; - out[5] = 0; - - out[6] = a[4]; - out[7] = a[5]; - out[8] = 1; - return out; -}; - -/** -* Calculates a 3x3 matrix from the given quaternion -* -* @param {mat3} out mat3 receiving operation result -* @param {quat} q Quaternion to create matrix from -* -* @returns {mat3} out -*/ -mat3.fromQuat = function (out, q) { - var x = q[0], y = q[1], z = q[2], w = q[3], - x2 = x + x, - y2 = y + y, - z2 = z + z, - - xx = x * x2, - yx = y * x2, - yy = y * y2, - zx = z * x2, - zy = z * y2, - zz = z * z2, - wx = w * x2, - wy = w * y2, - wz = w * z2; - - out[0] = 1 - yy - zz; - out[3] = yx - wz; - out[6] = zx + wy; - - out[1] = yx + wz; - out[4] = 1 - xx - zz; - out[7] = zy - wx; - - out[2] = zx - wy; - out[5] = zy + wx; - out[8] = 1 - xx - yy; - - return out; -}; - -/** -* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix -* -* @param {mat3} out mat3 receiving operation result -* @param {mat4} a Mat4 to derive the normal matrix from -* -* @returns {mat3} out -*/ -mat3.normalFromMat4 = function (out, a) { - var 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], - a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], - - b00 = a00 * a11 - a01 * a10, - b01 = a00 * a12 - a02 * a10, - b02 = a00 * a13 - a03 * a10, - b03 = a01 * a12 - a02 * a11, - b04 = a01 * a13 - a03 * a11, - b05 = a02 * a13 - a03 * a12, - b06 = a20 * a31 - a21 * a30, - b07 = a20 * a32 - a22 * a30, - b08 = a20 * a33 - a23 * a30, - b09 = a21 * a32 - a22 * a31, - b10 = a21 * a33 - a23 * a31, - b11 = a22 * a33 - a23 * a32, - - // Calculate the determinant - det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; - out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; - out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; - - out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; - out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; - out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; - - out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; - out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; - out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; - - return out; -}; - -/** - * Returns a string representation of a mat3 - * - * @param {mat3} mat matrix to represent as a string - * @returns {String} string representation of the matrix - */ -mat3.str = function (a) { - return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + - a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + - a[6] + ', ' + a[7] + ', ' + a[8] + ')'; -}; - -/** - * Returns Frobenius norm of a mat3 - * - * @param {mat3} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm - */ -mat3.frob = function (a) { - return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2))) -}; - -/** - * Adds two mat3's - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -mat3.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - out[6] = a[6] + b[6]; - out[7] = a[7] + b[7]; - out[8] = a[8] + b[8]; - return out; -}; - -/** - * Subtracts matrix b from matrix a - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -mat3.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - out[4] = a[4] - b[4]; - out[5] = a[5] - b[5]; - out[6] = a[6] - b[6]; - out[7] = a[7] - b[7]; - out[8] = a[8] - b[8]; - return out; -}; - -/** - * Alias for {@link mat3.subtract} - * @function - */ -mat3.sub = mat3.subtract; - -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat3} out - */ -mat3.multiplyScalar = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - out[4] = a[4] * b; - out[5] = a[5] * b; - out[6] = a[6] * b; - out[7] = a[7] * b; - out[8] = a[8] * b; - return out; -}; - -/** - * Adds two mat3's after multiplying each element of the second operand by a scalar value. - * - * @param {mat3} out the receiving vector - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat3} out - */ -mat3.multiplyScalarAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - out[3] = a[3] + (b[3] * scale); - out[4] = a[4] + (b[4] * scale); - out[5] = a[5] + (b[5] * scale); - out[6] = a[6] + (b[6] * scale); - out[7] = a[7] + (b[7] * scale); - out[8] = a[8] + (b[8] * scale); - return out; -}; - -/* - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat3} a The first matrix. - * @param {mat3} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat3.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && - a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && - a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; -}; - -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat3} a The first matrix. - * @param {mat3} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat3.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7], a8 = a[8]; - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = a[6], b7 = b[7], b8 = b[8]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && - Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3)) && - Math.abs(a4 - b4) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a4), Math.abs(b4)) && - Math.abs(a5 - b5) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a5), Math.abs(b5)) && - Math.abs(a6 - b6) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a6), Math.abs(b6)) && - Math.abs(a7 - b7) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a7), Math.abs(b7)) && - Math.abs(a8 - b8) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a8), Math.abs(b8))); -}; - - -module.exports = mat3; - -},{"./common.js":27}],31:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 4x4 Matrix - * @name mat4 - */ -var mat4 = { - scalar: {}, - SIMD: {}, -}; - -/** - * Creates a new identity mat4 - * - * @returns {mat4} a new 4x4 matrix - */ -mat4.create = function() { - var out = new glMatrix.ARRAY_TYPE(16); - 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; -}; - -/** - * Creates a new mat4 initialized with values from an existing matrix - * - * @param {mat4} a matrix to clone - * @returns {mat4} a new 4x4 matrix - */ -mat4.clone = function(a) { - var out = new glMatrix.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; -}; - -/** - * Copy the values from one mat4 to another - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.copy = function(out, a) { - 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; -}; - -/** - * Create a new mat4 with the given values - * - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m03 Component in column 0, row 3 position (index 3) - * @param {Number} m10 Component in column 1, row 0 position (index 4) - * @param {Number} m11 Component in column 1, row 1 position (index 5) - * @param {Number} m12 Component in column 1, row 2 position (index 6) - * @param {Number} m13 Component in column 1, row 3 position (index 7) - * @param {Number} m20 Component in column 2, row 0 position (index 8) - * @param {Number} m21 Component in column 2, row 1 position (index 9) - * @param {Number} m22 Component in column 2, row 2 position (index 10) - * @param {Number} m23 Component in column 2, row 3 position (index 11) - * @param {Number} m30 Component in column 3, row 0 position (index 12) - * @param {Number} m31 Component in column 3, row 1 position (index 13) - * @param {Number} m32 Component in column 3, row 2 position (index 14) - * @param {Number} m33 Component in column 3, row 3 position (index 15) - * @returns {mat4} A new mat4 - */ -mat4.fromValues = function(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { - var out = new glMatrix.ARRAY_TYPE(16); - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - return out; -}; - -/** - * Set the components of a mat4 to the given values - * - * @param {mat4} out the receiving matrix - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m03 Component in column 0, row 3 position (index 3) - * @param {Number} m10 Component in column 1, row 0 position (index 4) - * @param {Number} m11 Component in column 1, row 1 position (index 5) - * @param {Number} m12 Component in column 1, row 2 position (index 6) - * @param {Number} m13 Component in column 1, row 3 position (index 7) - * @param {Number} m20 Component in column 2, row 0 position (index 8) - * @param {Number} m21 Component in column 2, row 1 position (index 9) - * @param {Number} m22 Component in column 2, row 2 position (index 10) - * @param {Number} m23 Component in column 2, row 3 position (index 11) - * @param {Number} m30 Component in column 3, row 0 position (index 12) - * @param {Number} m31 Component in column 3, row 1 position (index 13) - * @param {Number} m32 Component in column 3, row 2 position (index 14) - * @param {Number} m33 Component in column 3, row 3 position (index 15) - * @returns {mat4} out - */ -mat4.set = function(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - return out; -}; - - -/** - * Set a mat4 to the identity matrix - * - * @param {mat4} out the receiving matrix - * @returns {mat4} out - */ -mat4.identity = function(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; -}; - -/** - * Transpose the values of a mat4 not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.scalar.transpose = function(out, a) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (out === a) { - var a01 = a[1], a02 = a[2], a03 = a[3], - a12 = a[6], a13 = a[7], - a23 = a[11]; - - out[1] = a[4]; - out[2] = a[8]; - out[3] = a[12]; - out[4] = a01; - out[6] = a[9]; - out[7] = a[13]; - out[8] = a02; - out[9] = a12; - out[11] = a[14]; - out[12] = a03; - out[13] = a13; - out[14] = a23; - } else { - out[0] = a[0]; - out[1] = a[4]; - out[2] = a[8]; - out[3] = a[12]; - out[4] = a[1]; - out[5] = a[5]; - out[6] = a[9]; - out[7] = a[13]; - out[8] = a[2]; - out[9] = a[6]; - out[10] = a[10]; - out[11] = a[14]; - out[12] = a[3]; - out[13] = a[7]; - out[14] = a[11]; - out[15] = a[15]; - } - - return out; -}; - -/** - * Transpose the values of a mat4 using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.SIMD.transpose = function(out, a) { - var a0, a1, a2, a3, - tmp01, tmp23, - out0, out1, out2, out3; - - a0 = SIMD.Float32x4.load(a, 0); - a1 = SIMD.Float32x4.load(a, 4); - a2 = SIMD.Float32x4.load(a, 8); - a3 = SIMD.Float32x4.load(a, 12); - - tmp01 = SIMD.Float32x4.shuffle(a0, a1, 0, 1, 4, 5); - tmp23 = SIMD.Float32x4.shuffle(a2, a3, 0, 1, 4, 5); - out0 = SIMD.Float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6); - out1 = SIMD.Float32x4.shuffle(tmp01, tmp23, 1, 3, 5, 7); - SIMD.Float32x4.store(out, 0, out0); - SIMD.Float32x4.store(out, 4, out1); - - tmp01 = SIMD.Float32x4.shuffle(a0, a1, 2, 3, 6, 7); - tmp23 = SIMD.Float32x4.shuffle(a2, a3, 2, 3, 6, 7); - out2 = SIMD.Float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6); - out3 = SIMD.Float32x4.shuffle(tmp01, tmp23, 1, 3, 5, 7); - SIMD.Float32x4.store(out, 8, out2); - SIMD.Float32x4.store(out, 12, out3); - - return out; -}; - -/** - * Transpse a mat4 using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.transpose = glMatrix.USE_SIMD ? mat4.SIMD.transpose : mat4.scalar.transpose; - -/** - * Inverts a mat4 not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.scalar.invert = function(out, a) { - var 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], - a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], - - b00 = a00 * a11 - a01 * a10, - b01 = a00 * a12 - a02 * a10, - b02 = a00 * a13 - a03 * a10, - b03 = a01 * a12 - a02 * a11, - b04 = a01 * a13 - a03 * a11, - b05 = a02 * a13 - a03 * a12, - b06 = a20 * a31 - a21 * a30, - b07 = a20 * a32 - a22 * a30, - b08 = a20 * a33 - a23 * a30, - b09 = a21 * a32 - a22 * a31, - b10 = a21 * a33 - a23 * a31, - b11 = a22 * a33 - a23 * a32, - - // Calculate the determinant - det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; - - if (!det) { - return null; - } - det = 1.0 / 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; -}; - -/** - * Inverts a mat4 using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.SIMD.invert = function(out, a) { - var row0, row1, row2, row3, - tmp1, - minor0, minor1, minor2, minor3, - det, - a0 = SIMD.Float32x4.load(a, 0), - a1 = SIMD.Float32x4.load(a, 4), - a2 = SIMD.Float32x4.load(a, 8), - a3 = SIMD.Float32x4.load(a, 12); - - // Compute matrix adjugate - tmp1 = SIMD.Float32x4.shuffle(a0, a1, 0, 1, 4, 5); - row1 = SIMD.Float32x4.shuffle(a2, a3, 0, 1, 4, 5); - row0 = SIMD.Float32x4.shuffle(tmp1, row1, 0, 2, 4, 6); - row1 = SIMD.Float32x4.shuffle(row1, tmp1, 1, 3, 5, 7); - tmp1 = SIMD.Float32x4.shuffle(a0, a1, 2, 3, 6, 7); - row3 = SIMD.Float32x4.shuffle(a2, a3, 2, 3, 6, 7); - row2 = SIMD.Float32x4.shuffle(tmp1, row3, 0, 2, 4, 6); - row3 = SIMD.Float32x4.shuffle(row3, tmp1, 1, 3, 5, 7); - - tmp1 = SIMD.Float32x4.mul(row2, row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor0 = SIMD.Float32x4.mul(row1, tmp1); - minor1 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row1, tmp1), minor0); - minor1 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor1); - minor1 = SIMD.Float32x4.swizzle(minor1, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(row1, row2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor0 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor0); - minor3 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(minor0, SIMD.Float32x4.mul(row3, tmp1)); - minor3 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor3); - minor3 = SIMD.Float32x4.swizzle(minor3, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(row1, 2, 3, 0, 1), row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - row2 = SIMD.Float32x4.swizzle(row2, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row2, tmp1), minor0); - minor2 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(minor0, SIMD.Float32x4.mul(row2, tmp1)); - minor2 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor2); - minor2 = SIMD.Float32x4.swizzle(minor2, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(row0, row1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor2 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor2); - minor3 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row2, tmp1), minor3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor2 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row3, tmp1), minor2); - minor3 = SIMD.Float32x4.sub(minor3, SIMD.Float32x4.mul(row2, tmp1)); - - tmp1 = SIMD.Float32x4.mul(row0, row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor1 = SIMD.Float32x4.sub(minor1, SIMD.Float32x4.mul(row2, tmp1)); - minor2 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row1, tmp1), minor2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor1 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row2, tmp1), minor1); - minor2 = SIMD.Float32x4.sub(minor2, SIMD.Float32x4.mul(row1, tmp1)); - - tmp1 = SIMD.Float32x4.mul(row0, row2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor1 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor1); - minor3 = SIMD.Float32x4.sub(minor3, SIMD.Float32x4.mul(row1, tmp1)); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor1 = SIMD.Float32x4.sub(minor1, SIMD.Float32x4.mul(row3, tmp1)); - minor3 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row1, tmp1), minor3); - - // Compute matrix determinant - det = SIMD.Float32x4.mul(row0, minor0); - det = SIMD.Float32x4.add(SIMD.Float32x4.swizzle(det, 2, 3, 0, 1), det); - det = SIMD.Float32x4.add(SIMD.Float32x4.swizzle(det, 1, 0, 3, 2), det); - tmp1 = SIMD.Float32x4.reciprocalApproximation(det); - det = SIMD.Float32x4.sub( - SIMD.Float32x4.add(tmp1, tmp1), - SIMD.Float32x4.mul(det, SIMD.Float32x4.mul(tmp1, tmp1))); - det = SIMD.Float32x4.swizzle(det, 0, 0, 0, 0); - if (!det) { - return null; - } - - // Compute matrix inverse - SIMD.Float32x4.store(out, 0, SIMD.Float32x4.mul(det, minor0)); - SIMD.Float32x4.store(out, 4, SIMD.Float32x4.mul(det, minor1)); - SIMD.Float32x4.store(out, 8, SIMD.Float32x4.mul(det, minor2)); - SIMD.Float32x4.store(out, 12, SIMD.Float32x4.mul(det, minor3)); - return out; -} - -/** - * Inverts a mat4 using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.invert = glMatrix.USE_SIMD ? mat4.SIMD.invert : mat4.scalar.invert; - -/** - * Calculates the adjugate of a mat4 not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.scalar.adjoint = function(out, a) { - var 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], - a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; - - out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22)); - out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); - out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12)); - out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); - out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); - out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22)); - out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); - out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12)); - out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21)); - out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); - out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11)); - out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); - out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); - out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21)); - out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); - out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)); - return out; -}; - -/** - * Calculates the adjugate of a mat4 using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -mat4.SIMD.adjoint = function(out, a) { - var a0, a1, a2, a3; - var row0, row1, row2, row3; - var tmp1; - var minor0, minor1, minor2, minor3; - - var a0 = SIMD.Float32x4.load(a, 0); - var a1 = SIMD.Float32x4.load(a, 4); - var a2 = SIMD.Float32x4.load(a, 8); - var a3 = SIMD.Float32x4.load(a, 12); - - // Transpose the source matrix. Sort of. Not a true transpose operation - tmp1 = SIMD.Float32x4.shuffle(a0, a1, 0, 1, 4, 5); - row1 = SIMD.Float32x4.shuffle(a2, a3, 0, 1, 4, 5); - row0 = SIMD.Float32x4.shuffle(tmp1, row1, 0, 2, 4, 6); - row1 = SIMD.Float32x4.shuffle(row1, tmp1, 1, 3, 5, 7); - - tmp1 = SIMD.Float32x4.shuffle(a0, a1, 2, 3, 6, 7); - row3 = SIMD.Float32x4.shuffle(a2, a3, 2, 3, 6, 7); - row2 = SIMD.Float32x4.shuffle(tmp1, row3, 0, 2, 4, 6); - row3 = SIMD.Float32x4.shuffle(row3, tmp1, 1, 3, 5, 7); - - tmp1 = SIMD.Float32x4.mul(row2, row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor0 = SIMD.Float32x4.mul(row1, tmp1); - minor1 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row1, tmp1), minor0); - minor1 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor1); - minor1 = SIMD.Float32x4.swizzle(minor1, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(row1, row2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor0 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor0); - minor3 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(minor0, SIMD.Float32x4.mul(row3, tmp1)); - minor3 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor3); - minor3 = SIMD.Float32x4.swizzle(minor3, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(row1, 2, 3, 0, 1), row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - row2 = SIMD.Float32x4.swizzle(row2, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row2, tmp1), minor0); - minor2 = SIMD.Float32x4.mul(row0, tmp1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor0 = SIMD.Float32x4.sub(minor0, SIMD.Float32x4.mul(row2, tmp1)); - minor2 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row0, tmp1), minor2); - minor2 = SIMD.Float32x4.swizzle(minor2, 2, 3, 0, 1); - - tmp1 = SIMD.Float32x4.mul(row0, row1); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor2 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor2); - minor3 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row2, tmp1), minor3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor2 = SIMD.Float32x4.sub(SIMD.Float32x4.mul(row3, tmp1), minor2); - minor3 = SIMD.Float32x4.sub(minor3, SIMD.Float32x4.mul(row2, tmp1)); - - tmp1 = SIMD.Float32x4.mul(row0, row3); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor1 = SIMD.Float32x4.sub(minor1, SIMD.Float32x4.mul(row2, tmp1)); - minor2 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row1, tmp1), minor2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor1 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row2, tmp1), minor1); - minor2 = SIMD.Float32x4.sub(minor2, SIMD.Float32x4.mul(row1, tmp1)); - - tmp1 = SIMD.Float32x4.mul(row0, row2); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 1, 0, 3, 2); - minor1 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row3, tmp1), minor1); - minor3 = SIMD.Float32x4.sub(minor3, SIMD.Float32x4.mul(row1, tmp1)); - tmp1 = SIMD.Float32x4.swizzle(tmp1, 2, 3, 0, 1); - minor1 = SIMD.Float32x4.sub(minor1, SIMD.Float32x4.mul(row3, tmp1)); - minor3 = SIMD.Float32x4.add(SIMD.Float32x4.mul(row1, tmp1), minor3); - - SIMD.Float32x4.store(out, 0, minor0); - SIMD.Float32x4.store(out, 4, minor1); - SIMD.Float32x4.store(out, 8, minor2); - SIMD.Float32x4.store(out, 12, minor3); - return out; -}; - -/** - * Calculates the adjugate of a mat4 using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ - mat4.adjoint = glMatrix.USE_SIMD ? mat4.SIMD.adjoint : mat4.scalar.adjoint; - -/** - * Calculates the determinant of a mat4 - * - * @param {mat4} a the source matrix - * @returns {Number} determinant of a - */ -mat4.determinant = function (a) { - var 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], - a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], - - b00 = a00 * a11 - a01 * a10, - b01 = a00 * a12 - a02 * a10, - b02 = a00 * a13 - a03 * a10, - b03 = a01 * a12 - a02 * a11, - b04 = a01 * a13 - a03 * a11, - b05 = a02 * a13 - a03 * a12, - b06 = a20 * a31 - a21 * a30, - b07 = a20 * a32 - a22 * a30, - b08 = a20 * a33 - a23 * a30, - b09 = a21 * a32 - a22 * a31, - b10 = a21 * a33 - a23 * a31, - b11 = a22 * a33 - a23 * a32; - - // Calculate the determinant - return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; -}; - -/** - * Multiplies two mat4's explicitly using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand, must be a Float32Array - * @param {mat4} b the second operand, must be a Float32Array - * @returns {mat4} out - */ -mat4.SIMD.multiply = function (out, a, b) { - var a0 = SIMD.Float32x4.load(a, 0); - var a1 = SIMD.Float32x4.load(a, 4); - var a2 = SIMD.Float32x4.load(a, 8); - var a3 = SIMD.Float32x4.load(a, 12); - - var b0 = SIMD.Float32x4.load(b, 0); - var out0 = SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b0, 0, 0, 0, 0), a0), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b0, 1, 1, 1, 1), a1), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b0, 2, 2, 2, 2), a2), - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b0, 3, 3, 3, 3), a3)))); - SIMD.Float32x4.store(out, 0, out0); - - var b1 = SIMD.Float32x4.load(b, 4); - var out1 = SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b1, 0, 0, 0, 0), a0), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b1, 1, 1, 1, 1), a1), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b1, 2, 2, 2, 2), a2), - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b1, 3, 3, 3, 3), a3)))); - SIMD.Float32x4.store(out, 4, out1); - - var b2 = SIMD.Float32x4.load(b, 8); - var out2 = SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b2, 0, 0, 0, 0), a0), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b2, 1, 1, 1, 1), a1), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b2, 2, 2, 2, 2), a2), - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b2, 3, 3, 3, 3), a3)))); - SIMD.Float32x4.store(out, 8, out2); - - var b3 = SIMD.Float32x4.load(b, 12); - var out3 = SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b3, 0, 0, 0, 0), a0), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b3, 1, 1, 1, 1), a1), - SIMD.Float32x4.add( - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b3, 2, 2, 2, 2), a2), - SIMD.Float32x4.mul(SIMD.Float32x4.swizzle(b3, 3, 3, 3, 3), a3)))); - SIMD.Float32x4.store(out, 12, out3); - - return out; -}; - -/** - * Multiplies two mat4's explicitly not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @returns {mat4} out - */ -mat4.scalar.multiply = function (out, a, b) { - var 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], - a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; - - // Cache only the current line of the second matrix - 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; -}; - -/** - * Multiplies two mat4's using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @returns {mat4} out - */ -mat4.multiply = glMatrix.USE_SIMD ? mat4.SIMD.multiply : mat4.scalar.multiply; - -/** - * Alias for {@link mat4.multiply} - * @function - */ -mat4.mul = mat4.multiply; - -/** - * Translate a mat4 by the given vector not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to translate - * @param {vec3} v vector to translate by - * @returns {mat4} out - */ -mat4.scalar.translate = function (out, a, v) { - var x = v[0], y = v[1], z = v[2], - a00, a01, a02, a03, - a10, a11, a12, a13, - 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; -}; - -/** - * Translates a mat4 by the given vector using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to translate - * @param {vec3} v vector to translate by - * @returns {mat4} out - */ -mat4.SIMD.translate = function (out, a, v) { - var a0 = SIMD.Float32x4.load(a, 0), - a1 = SIMD.Float32x4.load(a, 4), - a2 = SIMD.Float32x4.load(a, 8), - a3 = SIMD.Float32x4.load(a, 12), - vec = SIMD.Float32x4(v[0], v[1], v[2] , 0); - - if (a !== out) { - 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]; - } - - a0 = SIMD.Float32x4.mul(a0, SIMD.Float32x4.swizzle(vec, 0, 0, 0, 0)); - a1 = SIMD.Float32x4.mul(a1, SIMD.Float32x4.swizzle(vec, 1, 1, 1, 1)); - a2 = SIMD.Float32x4.mul(a2, SIMD.Float32x4.swizzle(vec, 2, 2, 2, 2)); - - var t0 = SIMD.Float32x4.add(a0, SIMD.Float32x4.add(a1, SIMD.Float32x4.add(a2, a3))); - SIMD.Float32x4.store(out, 12, t0); - - return out; -}; - -/** - * Translates a mat4 by the given vector using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to translate - * @param {vec3} v vector to translate by - * @returns {mat4} out - */ -mat4.translate = glMatrix.USE_SIMD ? mat4.SIMD.translate : mat4.scalar.translate; - -/** - * Scales the mat4 by the dimensions in the given vec3 not using vectorization - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {vec3} v the vec3 to scale the matrix by - * @returns {mat4} out - **/ -mat4.scalar.scale = function(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; -}; - -/** - * Scales the mat4 by the dimensions in the given vec3 using vectorization - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {vec3} v the vec3 to scale the matrix by - * @returns {mat4} out - **/ -mat4.SIMD.scale = function(out, a, v) { - var a0, a1, a2; - var vec = SIMD.Float32x4(v[0], v[1], v[2], 0); - - a0 = SIMD.Float32x4.load(a, 0); - SIMD.Float32x4.store( - out, 0, SIMD.Float32x4.mul(a0, SIMD.Float32x4.swizzle(vec, 0, 0, 0, 0))); - - a1 = SIMD.Float32x4.load(a, 4); - SIMD.Float32x4.store( - out, 4, SIMD.Float32x4.mul(a1, SIMD.Float32x4.swizzle(vec, 1, 1, 1, 1))); - - a2 = SIMD.Float32x4.load(a, 8); - SIMD.Float32x4.store( - out, 8, SIMD.Float32x4.mul(a2, SIMD.Float32x4.swizzle(vec, 2, 2, 2, 2))); - - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - return out; -}; - -/** - * Scales the mat4 by the dimensions in the given vec3 using SIMD if available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {vec3} v the vec3 to scale the matrix by - * @returns {mat4} out - */ -mat4.scale = glMatrix.USE_SIMD ? mat4.SIMD.scale : mat4.scalar.scale; - -/** - * Rotates a mat4 by the given angle around the given axis - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around - * @returns {mat4} out - */ -mat4.rotate = function (out, a, rad, axis) { - var x = axis[0], y = axis[1], z = axis[2], - len = Math.sqrt(x * x + y * y + z * z), - s, c, t, - a00, a01, a02, a03, - a10, a11, a12, a13, - a20, a21, a22, a23, - b00, b01, b02, - b10, b11, b12, - b20, b21, b22; - - if (Math.abs(len) < glMatrix.EPSILON) { return null; } - - len = 1 / len; - x *= len; - y *= len; - z *= len; - - s = Math.sin(rad); - c = Math.cos(rad); - t = 1 - c; - - 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]; - - // Construct the elements of the rotation matrix - b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; - b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; - b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; - - // Perform rotation-specific matrix multiplication - out[0] = a00 * b00 + a10 * b01 + a20 * b02; - out[1] = a01 * b00 + a11 * b01 + a21 * b02; - out[2] = a02 * b00 + a12 * b01 + a22 * b02; - out[3] = a03 * b00 + a13 * b01 + a23 * b02; - out[4] = a00 * b10 + a10 * b11 + a20 * b12; - out[5] = a01 * b10 + a11 * b11 + a21 * b12; - out[6] = a02 * b10 + a12 * b11 + a22 * b12; - out[7] = a03 * b10 + a13 * b11 + a23 * b12; - out[8] = a00 * b20 + a10 * b21 + a20 * b22; - out[9] = a01 * b20 + a11 * b21 + a21 * b22; - out[10] = a02 * b20 + a12 * b21 + a22 * b22; - out[11] = a03 * b20 + a13 * b21 + a23 * b22; - - if (a !== out) { // If the source and destination differ, copy the unchanged last row - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } - return out; -}; - -/** - * Rotates a matrix by the given angle around the X axis not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.scalar.rotateX = function (out, a, rad) { - var s = Math.sin(rad), - c = Math.cos(rad), - a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7], - a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - - if (a !== out) { // If the source and destination differ, copy the unchanged rows - 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]; - } - - // Perform axis-specific matrix multiplication - 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; -}; - -/** - * Rotates a matrix by the given angle around the X axis using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.SIMD.rotateX = function (out, a, rad) { - var s = SIMD.Float32x4.splat(Math.sin(rad)), - c = SIMD.Float32x4.splat(Math.cos(rad)); - - if (a !== out) { // If the source and destination differ, copy the unchanged rows - 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]; - } - - // Perform axis-specific matrix multiplication - var a_1 = SIMD.Float32x4.load(a, 4); - var a_2 = SIMD.Float32x4.load(a, 8); - SIMD.Float32x4.store(out, 4, - SIMD.Float32x4.add(SIMD.Float32x4.mul(a_1, c), SIMD.Float32x4.mul(a_2, s))); - SIMD.Float32x4.store(out, 8, - SIMD.Float32x4.sub(SIMD.Float32x4.mul(a_2, c), SIMD.Float32x4.mul(a_1, s))); - return out; -}; - -/** - * Rotates a matrix by the given angle around the X axis using SIMD if availabe and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.rotateX = glMatrix.USE_SIMD ? mat4.SIMD.rotateX : mat4.scalar.rotateX; - -/** - * Rotates a matrix by the given angle around the Y axis not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.scalar.rotateY = function (out, a, rad) { - var s = Math.sin(rad), - c = Math.cos(rad), - a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3], - a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - - if (a !== out) { // If the source and destination differ, copy the unchanged rows - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } - - // Perform axis-specific matrix multiplication - out[0] = a00 * c - a20 * s; - out[1] = a01 * c - a21 * s; - out[2] = a02 * c - a22 * s; - out[3] = a03 * c - a23 * s; - out[8] = a00 * s + a20 * c; - out[9] = a01 * s + a21 * c; - out[10] = a02 * s + a22 * c; - out[11] = a03 * s + a23 * c; - return out; -}; - -/** - * Rotates a matrix by the given angle around the Y axis using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.SIMD.rotateY = function (out, a, rad) { - var s = SIMD.Float32x4.splat(Math.sin(rad)), - c = SIMD.Float32x4.splat(Math.cos(rad)); - - if (a !== out) { // If the source and destination differ, copy the unchanged rows - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } - - // Perform axis-specific matrix multiplication - var a_0 = SIMD.Float32x4.load(a, 0); - var a_2 = SIMD.Float32x4.load(a, 8); - SIMD.Float32x4.store(out, 0, - SIMD.Float32x4.sub(SIMD.Float32x4.mul(a_0, c), SIMD.Float32x4.mul(a_2, s))); - SIMD.Float32x4.store(out, 8, - SIMD.Float32x4.add(SIMD.Float32x4.mul(a_0, s), SIMD.Float32x4.mul(a_2, c))); - return out; -}; - -/** - * Rotates a matrix by the given angle around the Y axis if SIMD available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ - mat4.rotateY = glMatrix.USE_SIMD ? mat4.SIMD.rotateY : mat4.scalar.rotateY; - -/** - * Rotates a matrix by the given angle around the Z axis not using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.scalar.rotateZ = function (out, a, rad) { - var s = Math.sin(rad), - c = Math.cos(rad), - a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3], - a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - - if (a !== out) { // If the source and destination differ, copy the unchanged last row - 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]; - } - - // Perform axis-specific matrix multiplication - 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; -}; - -/** - * Rotates a matrix by the given angle around the Z axis using SIMD - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.SIMD.rotateZ = function (out, a, rad) { - var s = SIMD.Float32x4.splat(Math.sin(rad)), - c = SIMD.Float32x4.splat(Math.cos(rad)); - - if (a !== out) { // If the source and destination differ, copy the unchanged last row - 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]; - } - - // Perform axis-specific matrix multiplication - var a_0 = SIMD.Float32x4.load(a, 0); - var a_1 = SIMD.Float32x4.load(a, 4); - SIMD.Float32x4.store(out, 0, - SIMD.Float32x4.add(SIMD.Float32x4.mul(a_0, c), SIMD.Float32x4.mul(a_1, s))); - SIMD.Float32x4.store(out, 4, - SIMD.Float32x4.sub(SIMD.Float32x4.mul(a_1, c), SIMD.Float32x4.mul(a_0, s))); - return out; -}; - -/** - * Rotates a matrix by the given angle around the Z axis if SIMD available and enabled - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ - mat4.rotateZ = glMatrix.USE_SIMD ? mat4.SIMD.rotateZ : mat4.scalar.rotateZ; - -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, dest, vec); - * - * @param {mat4} out mat4 receiving operation result - * @param {vec3} v Translation vector - * @returns {mat4} out - */ -mat4.fromTranslation = function(out, v) { - 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] = v[0]; - out[13] = v[1]; - out[14] = v[2]; - out[15] = 1; - return out; -} - -/** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.scale(dest, dest, vec); - * - * @param {mat4} out mat4 receiving operation result - * @param {vec3} v Scaling vector - * @returns {mat4} out - */ -mat4.fromScaling = function(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = v[1]; - out[6] = 0; - out[7] = 0; - out[8] = 0; - out[9] = 0; - out[10] = v[2]; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} - -/** - * Creates a matrix from a given angle around a given axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotate(dest, dest, rad, axis); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around - * @returns {mat4} out - */ -mat4.fromRotation = function(out, rad, axis) { - var x = axis[0], y = axis[1], z = axis[2], - len = Math.sqrt(x * x + y * y + z * z), - s, c, t; - - if (Math.abs(len) < glMatrix.EPSILON) { return null; } - - len = 1 / len; - x *= len; - y *= len; - z *= len; - - s = Math.sin(rad); - c = Math.cos(rad); - t = 1 - c; - - // Perform rotation-specific matrix multiplication - out[0] = x * x * t + c; - out[1] = y * x * t + z * s; - out[2] = z * x * t - y * s; - out[3] = 0; - out[4] = x * y * t - z * s; - out[5] = y * y * t + c; - out[6] = z * y * t + x * s; - out[7] = 0; - out[8] = x * z * t + y * s; - out[9] = y * z * t - x * s; - out[10] = z * z * t + c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} - -/** - * Creates a matrix from the given angle around the X axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotateX(dest, dest, rad); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.fromXRotation = function(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - - // Perform axis-specific matrix multiplication - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = c; - out[6] = s; - out[7] = 0; - out[8] = 0; - out[9] = -s; - out[10] = c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} - -/** - * Creates a matrix from the given angle around the Y axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotateY(dest, dest, rad); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.fromYRotation = function(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - - // Perform axis-specific matrix multiplication - out[0] = c; - out[1] = 0; - out[2] = -s; - out[3] = 0; - out[4] = 0; - out[5] = 1; - out[6] = 0; - out[7] = 0; - out[8] = s; - out[9] = 0; - out[10] = c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} - -/** - * Creates a matrix from the given angle around the Z axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotateZ(dest, dest, rad); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -mat4.fromZRotation = function(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - - // Perform axis-specific matrix multiplication - out[0] = c; - out[1] = s; - out[2] = 0; - out[3] = 0; - out[4] = -s; - out[5] = c; - 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; -} - -/** - * Creates a matrix from a quaternion rotation and vector translation - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, vec); - * var quatMat = mat4.create(); - * quat4.toMat4(quat, quatMat); - * mat4.multiply(dest, quatMat); - * - * @param {mat4} out mat4 receiving operation result - * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @returns {mat4} out - */ -mat4.fromRotationTranslation = function (out, q, v) { - // Quaternion math - var x = q[0], y = q[1], z = q[2], w = q[3], - x2 = x + x, - y2 = y + y, - z2 = z + z, - - xx = x * x2, - xy = x * y2, - xz = x * z2, - yy = y * y2, - yz = y * z2, - zz = z * z2, - wx = w * x2, - wy = w * y2, - wz = w * z2; - - out[0] = 1 - (yy + zz); - out[1] = xy + wz; - out[2] = xz - wy; - out[3] = 0; - out[4] = xy - wz; - out[5] = 1 - (xx + zz); - out[6] = yz + wx; - out[7] = 0; - out[8] = xz + wy; - out[9] = yz - wx; - out[10] = 1 - (xx + yy); - out[11] = 0; - out[12] = v[0]; - out[13] = v[1]; - out[14] = v[2]; - out[15] = 1; - - return out; -}; - -/** - * Returns the translation vector component of a transformation - * matrix. If a matrix is built with fromRotationTranslation, - * the returned vector will be the same as the translation vector - * originally supplied. - * @param {vec3} out Vector to receive translation component - * @param {mat4} mat Matrix to be decomposed (input) - * @return {vec3} out - */ -mat4.getTranslation = function (out, mat) { - out[0] = mat[12]; - out[1] = mat[13]; - out[2] = mat[14]; - - return out; -}; - -/** - * Returns a quaternion representing the rotational component - * of a transformation matrix. If a matrix is built with - * fromRotationTranslation, the returned quaternion will be the - * same as the quaternion originally supplied. - * @param {quat} out Quaternion to receive the rotation component - * @param {mat4} mat Matrix to be decomposed (input) - * @return {quat} out - */ -mat4.getRotation = function (out, mat) { - // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - var trace = mat[0] + mat[5] + mat[10]; - var S = 0; - - if (trace > 0) { - S = Math.sqrt(trace + 1.0) * 2; - out[3] = 0.25 * S; - out[0] = (mat[6] - mat[9]) / S; - out[1] = (mat[8] - mat[2]) / S; - out[2] = (mat[1] - mat[4]) / S; - } else if ((mat[0] > mat[5])&(mat[0] > mat[10])) { - S = Math.sqrt(1.0 + mat[0] - mat[5] - mat[10]) * 2; - out[3] = (mat[6] - mat[9]) / S; - out[0] = 0.25 * S; - out[1] = (mat[1] + mat[4]) / S; - out[2] = (mat[8] + mat[2]) / S; - } else if (mat[5] > mat[10]) { - S = Math.sqrt(1.0 + mat[5] - mat[0] - mat[10]) * 2; - out[3] = (mat[8] - mat[2]) / S; - out[0] = (mat[1] + mat[4]) / S; - out[1] = 0.25 * S; - out[2] = (mat[6] + mat[9]) / S; - } else { - S = Math.sqrt(1.0 + mat[10] - mat[0] - mat[5]) * 2; - out[3] = (mat[1] - mat[4]) / S; - out[0] = (mat[8] + mat[2]) / S; - out[1] = (mat[6] + mat[9]) / S; - out[2] = 0.25 * S; - } - - return out; -}; - -/** - * Creates a matrix from a quaternion rotation, vector translation and vector scale - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, vec); - * var quatMat = mat4.create(); - * quat4.toMat4(quat, quatMat); - * mat4.multiply(dest, quatMat); - * mat4.scale(dest, scale) - * - * @param {mat4} out mat4 receiving operation result - * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @param {vec3} s Scaling vector - * @returns {mat4} out - */ -mat4.fromRotationTranslationScale = function (out, q, v, s) { - // Quaternion math - var x = q[0], y = q[1], z = q[2], w = q[3], - x2 = x + x, - y2 = y + y, - z2 = z + z, - - xx = x * x2, - xy = x * y2, - xz = x * z2, - yy = y * y2, - yz = y * z2, - zz = z * z2, - wx = w * x2, - wy = w * y2, - wz = w * z2, - sx = s[0], - sy = s[1], - sz = s[2]; - - out[0] = (1 - (yy + zz)) * sx; - out[1] = (xy + wz) * sx; - out[2] = (xz - wy) * sx; - out[3] = 0; - out[4] = (xy - wz) * sy; - out[5] = (1 - (xx + zz)) * sy; - out[6] = (yz + wx) * sy; - out[7] = 0; - out[8] = (xz + wy) * sz; - out[9] = (yz - wx) * sz; - out[10] = (1 - (xx + yy)) * sz; - out[11] = 0; - out[12] = v[0]; - out[13] = v[1]; - out[14] = v[2]; - out[15] = 1; - - return out; -}; - -/** - * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, vec); - * mat4.translate(dest, origin); - * var quatMat = mat4.create(); - * quat4.toMat4(quat, quatMat); - * mat4.multiply(dest, quatMat); - * mat4.scale(dest, scale) - * mat4.translate(dest, negativeOrigin); - * - * @param {mat4} out mat4 receiving operation result - * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @param {vec3} s Scaling vector - * @param {vec3} o The origin vector around which to scale and rotate - * @returns {mat4} out - */ -mat4.fromRotationTranslationScaleOrigin = function (out, q, v, s, o) { - // Quaternion math - var x = q[0], y = q[1], z = q[2], w = q[3], - x2 = x + x, - y2 = y + y, - z2 = z + z, - - xx = x * x2, - xy = x * y2, - xz = x * z2, - yy = y * y2, - yz = y * z2, - zz = z * z2, - wx = w * x2, - wy = w * y2, - wz = w * z2, - - sx = s[0], - sy = s[1], - sz = s[2], - - ox = o[0], - oy = o[1], - oz = o[2]; - - out[0] = (1 - (yy + zz)) * sx; - out[1] = (xy + wz) * sx; - out[2] = (xz - wy) * sx; - out[3] = 0; - out[4] = (xy - wz) * sy; - out[5] = (1 - (xx + zz)) * sy; - out[6] = (yz + wx) * sy; - out[7] = 0; - out[8] = (xz + wy) * sz; - out[9] = (yz - wx) * sz; - out[10] = (1 - (xx + yy)) * sz; - out[11] = 0; - out[12] = v[0] + ox - (out[0] * ox + out[4] * oy + out[8] * oz); - out[13] = v[1] + oy - (out[1] * ox + out[5] * oy + out[9] * oz); - out[14] = v[2] + oz - (out[2] * ox + out[6] * oy + out[10] * oz); - out[15] = 1; - - return out; -}; - -/** - * Calculates a 4x4 matrix from the given quaternion - * - * @param {mat4} out mat4 receiving operation result - * @param {quat} q Quaternion to create matrix from - * - * @returns {mat4} out - */ -mat4.fromQuat = function (out, q) { - var x = q[0], y = q[1], z = q[2], w = q[3], - x2 = x + x, - y2 = y + y, - z2 = z + z, - - xx = x * x2, - yx = y * x2, - yy = y * y2, - zx = z * x2, - zy = z * y2, - zz = z * z2, - wx = w * x2, - wy = w * y2, - wz = w * z2; - - out[0] = 1 - yy - zz; - out[1] = yx + wz; - out[2] = zx - wy; - out[3] = 0; - - out[4] = yx - wz; - out[5] = 1 - xx - zz; - out[6] = zy + wx; - out[7] = 0; - - out[8] = zx + wy; - out[9] = zy - wx; - out[10] = 1 - xx - yy; - out[11] = 0; - - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - - return out; -}; - -/** - * Generates a frustum matrix with the given bounds - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {Number} left Left bound of the frustum - * @param {Number} right Right bound of the frustum - * @param {Number} bottom Bottom bound of the frustum - * @param {Number} top Top bound of the frustum - * @param {Number} near Near bound of the frustum - * @param {Number} far Far bound of the frustum - * @returns {mat4} out - */ -mat4.frustum = function (out, left, right, bottom, top, near, far) { - var rl = 1 / (right - left), - tb = 1 / (top - bottom), - nf = 1 / (near - far); - out[0] = (near * 2) * rl; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = (near * 2) * tb; - out[6] = 0; - out[7] = 0; - out[8] = (right + left) * rl; - out[9] = (top + bottom) * tb; - out[10] = (far + near) * nf; - out[11] = -1; - out[12] = 0; - out[13] = 0; - out[14] = (far * near * 2) * nf; - out[15] = 0; - return out; -}; - -/** - * Generates a perspective projection matrix with the given bounds - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {number} fovy Vertical field of view in radians - * @param {number} aspect Aspect ratio. typically viewport width/height - * @param {number} near Near bound of the frustum - * @param {number} far Far bound of the frustum - * @returns {mat4} out - */ -mat4.perspective = function (out, fovy, aspect, near, far) { - var f = 1.0 / Math.tan(fovy / 2), - nf = 1 / (near - far); - 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[10] = (far + near) * nf; - out[11] = -1; - out[12] = 0; - out[13] = 0; - out[14] = (2 * far * near) * nf; - out[15] = 0; - return out; -}; - -/** - * Generates a perspective projection matrix with the given field of view. - * This is primarily useful for generating projection matrices to be used - * with the still experiemental WebVR API. - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees - * @param {number} near Near bound of the frustum - * @param {number} far Far bound of the frustum - * @returns {mat4} out - */ -mat4.perspectiveFromFieldOfView = function (out, fov, near, far) { - var upTan = Math.tan(fov.upDegrees * Math.PI/180.0), - downTan = Math.tan(fov.downDegrees * Math.PI/180.0), - leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0), - rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0), - xScale = 2.0 / (leftTan + rightTan), - yScale = 2.0 / (upTan + downTan); - - out[0] = xScale; - out[1] = 0.0; - out[2] = 0.0; - out[3] = 0.0; - out[4] = 0.0; - out[5] = yScale; - out[6] = 0.0; - out[7] = 0.0; - out[8] = -((leftTan - rightTan) * xScale * 0.5); - out[9] = ((upTan - downTan) * yScale * 0.5); - out[10] = far / (near - far); - out[11] = -1.0; - out[12] = 0.0; - out[13] = 0.0; - out[14] = (far * near) / (near - far); - out[15] = 0.0; - return out; -} - -/** - * Generates a orthogonal projection matrix with the given bounds - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {number} left Left bound of the frustum - * @param {number} right Right bound of the frustum - * @param {number} bottom Bottom bound of the frustum - * @param {number} top Top bound of the frustum - * @param {number} near Near bound of the frustum - * @param {number} far Far bound of the frustum - * @returns {mat4} out - */ -mat4.ortho = function (out, left, right, bottom, top, near, far) { - var lr = 1 / (left - right), - bt = 1 / (bottom - top), - 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; -}; - -/** - * Generates a look-at matrix with the given eye position, focal point, and up axis - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {vec3} eye Position of the viewer - * @param {vec3} center Point the viewer is looking at - * @param {vec3} up vec3 pointing up - * @returns {mat4} out - */ -mat4.lookAt = function (out, eye, center, up) { - var x0, x1, x2, y0, y1, y2, z0, z1, z2, len, - eyex = eye[0], - eyey = eye[1], - eyez = eye[2], - upx = up[0], - upy = up[1], - upz = up[2], - centerx = center[0], - centery = center[1], - centerz = center[2]; - - if (Math.abs(eyex - centerx) < glMatrix.EPSILON && - Math.abs(eyey - centery) < glMatrix.EPSILON && - Math.abs(eyez - centerz) < glMatrix.EPSILON) { - return mat4.identity(out); - } - - z0 = eyex - centerx; - z1 = eyey - centery; - z2 = eyez - centerz; - - len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); - z0 *= len; - z1 *= len; - z2 *= len; - - x0 = upy * z2 - upz * z1; - x1 = upz * z0 - upx * z2; - x2 = upx * z1 - upy * z0; - len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); - if (!len) { - x0 = 0; - x1 = 0; - x2 = 0; - } else { - len = 1 / len; - x0 *= len; - x1 *= len; - x2 *= len; - } - - y0 = z1 * x2 - z2 * x1; - y1 = z2 * x0 - z0 * x2; - y2 = z0 * x1 - z1 * x0; - - len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); - if (!len) { - y0 = 0; - y1 = 0; - y2 = 0; - } else { - len = 1 / len; - y0 *= len; - y1 *= len; - y2 *= len; - } - - out[0] = x0; - out[1] = y0; - out[2] = z0; - out[3] = 0; - out[4] = x1; - out[5] = y1; - out[6] = z1; - out[7] = 0; - out[8] = x2; - out[9] = y2; - out[10] = z2; - out[11] = 0; - out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); - out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); - out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); - out[15] = 1; - - return out; -}; - -/** - * Returns a string representation of a mat4 - * - * @param {mat4} mat matrix to represent as a string - * @returns {String} string representation of the matrix - */ -mat4.str = function (a) { - return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + - a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + - a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + - a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')'; -}; - -/** - * Returns Frobenius norm of a mat4 - * - * @param {mat4} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm - */ -mat4.frob = function (a) { - return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) )) -}; - -/** - * Adds two mat4's - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @returns {mat4} out - */ -mat4.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - out[6] = a[6] + b[6]; - out[7] = a[7] + b[7]; - out[8] = a[8] + b[8]; - out[9] = a[9] + b[9]; - out[10] = a[10] + b[10]; - out[11] = a[11] + b[11]; - out[12] = a[12] + b[12]; - out[13] = a[13] + b[13]; - out[14] = a[14] + b[14]; - out[15] = a[15] + b[15]; - return out; -}; - -/** - * Subtracts matrix b from matrix a - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @returns {mat4} out - */ -mat4.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - out[4] = a[4] - b[4]; - out[5] = a[5] - b[5]; - out[6] = a[6] - b[6]; - out[7] = a[7] - b[7]; - out[8] = a[8] - b[8]; - out[9] = a[9] - b[9]; - out[10] = a[10] - b[10]; - out[11] = a[11] - b[11]; - out[12] = a[12] - b[12]; - out[13] = a[13] - b[13]; - out[14] = a[14] - b[14]; - out[15] = a[15] - b[15]; - return out; -}; - -/** - * Alias for {@link mat4.subtract} - * @function - */ -mat4.sub = mat4.subtract; - -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat4} out - */ -mat4.multiplyScalar = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - out[4] = a[4] * b; - out[5] = a[5] * b; - out[6] = a[6] * b; - out[7] = a[7] * b; - out[8] = a[8] * b; - out[9] = a[9] * b; - out[10] = a[10] * b; - out[11] = a[11] * b; - out[12] = a[12] * b; - out[13] = a[13] * b; - out[14] = a[14] * b; - out[15] = a[15] * b; - return out; -}; - -/** - * Adds two mat4's after multiplying each element of the second operand by a scalar value. - * - * @param {mat4} out the receiving vector - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat4} out - */ -mat4.multiplyScalarAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - out[3] = a[3] + (b[3] * scale); - out[4] = a[4] + (b[4] * scale); - out[5] = a[5] + (b[5] * scale); - out[6] = a[6] + (b[6] * scale); - out[7] = a[7] + (b[7] * scale); - out[8] = a[8] + (b[8] * scale); - out[9] = a[9] + (b[9] * scale); - out[10] = a[10] + (b[10] * scale); - out[11] = a[11] + (b[11] * scale); - out[12] = a[12] + (b[12] * scale); - out[13] = a[13] + (b[13] * scale); - out[14] = a[14] + (b[14] * scale); - out[15] = a[15] + (b[15] * scale); - return out; -}; - -/** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat4} a The first matrix. - * @param {mat4} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat4.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && - a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && - a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && - a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; -}; - -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat4} a The first matrix. - * @param {mat4} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -mat4.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], - a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7], - a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11], - a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15]; - - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], - b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], - b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], - b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; - - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && - Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3)) && - Math.abs(a4 - b4) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a4), Math.abs(b4)) && - Math.abs(a5 - b5) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a5), Math.abs(b5)) && - Math.abs(a6 - b6) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a6), Math.abs(b6)) && - Math.abs(a7 - b7) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a7), Math.abs(b7)) && - Math.abs(a8 - b8) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a8), Math.abs(b8)) && - Math.abs(a9 - b9) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a9), Math.abs(b9)) && - Math.abs(a10 - b10) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a10), Math.abs(b10)) && - Math.abs(a11 - b11) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a11), Math.abs(b11)) && - Math.abs(a12 - b12) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a12), Math.abs(b12)) && - Math.abs(a13 - b13) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a13), Math.abs(b13)) && - Math.abs(a14 - b14) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a14), Math.abs(b14)) && - Math.abs(a15 - b15) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a15), Math.abs(b15))); -}; - - - -module.exports = mat4; - -},{"./common.js":27}],32:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); -var mat3 = require("./mat3.js"); -var vec3 = require("./vec3.js"); -var vec4 = require("./vec4.js"); - -/** - * @class Quaternion - * @name quat - */ -var quat = {}; - -/** - * Creates a new identity quat - * - * @returns {quat} a new quaternion - */ -quat.create = function() { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -}; - -/** - * Sets a quaternion to represent the shortest rotation from one - * vector to another. - * - * Both vectors are assumed to be unit length. - * - * @param {quat} out the receiving quaternion. - * @param {vec3} a the initial vector - * @param {vec3} b the destination vector - * @returns {quat} out - */ -quat.rotationTo = (function() { - var tmpvec3 = vec3.create(); - var xUnitVec3 = vec3.fromValues(1,0,0); - var yUnitVec3 = vec3.fromValues(0,1,0); - - return function(out, a, b) { - var dot = vec3.dot(a, b); - if (dot < -0.999999) { - vec3.cross(tmpvec3, xUnitVec3, a); - if (vec3.length(tmpvec3) < 0.000001) - vec3.cross(tmpvec3, yUnitVec3, a); - vec3.normalize(tmpvec3, tmpvec3); - quat.setAxisAngle(out, tmpvec3, Math.PI); - return out; - } else if (dot > 0.999999) { - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; - } else { - vec3.cross(tmpvec3, a, b); - out[0] = tmpvec3[0]; - out[1] = tmpvec3[1]; - out[2] = tmpvec3[2]; - out[3] = 1 + dot; - return quat.normalize(out, out); - } - }; -})(); - -/** - * Sets the specified quaternion with values corresponding to the given - * axes. Each axis is a vec3 and is expected to be unit length and - * perpendicular to all other specified axes. - * - * @param {vec3} view the vector representing the viewing direction - * @param {vec3} right the vector representing the local "right" direction - * @param {vec3} up the vector representing the local "up" direction - * @returns {quat} out - */ -quat.setAxes = (function() { - var matr = mat3.create(); - - return function(out, view, right, up) { - matr[0] = right[0]; - matr[3] = right[1]; - matr[6] = right[2]; - - matr[1] = up[0]; - matr[4] = up[1]; - matr[7] = up[2]; - - matr[2] = -view[0]; - matr[5] = -view[1]; - matr[8] = -view[2]; - - return quat.normalize(out, quat.fromMat3(out, matr)); - }; -})(); - -/** - * Creates a new quat initialized with values from an existing quaternion - * - * @param {quat} a quaternion to clone - * @returns {quat} a new quaternion - * @function - */ -quat.clone = vec4.clone; - -/** - * Creates a new quat initialized with the given values - * - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @param {Number} w W component - * @returns {quat} a new quaternion - * @function - */ -quat.fromValues = vec4.fromValues; - -/** - * Copy the values from one quat to another - * - * @param {quat} out the receiving quaternion - * @param {quat} a the source quaternion - * @returns {quat} out - * @function - */ -quat.copy = vec4.copy; - -/** - * Set the components of a quat to the given values - * - * @param {quat} out the receiving quaternion - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @param {Number} w W component - * @returns {quat} out - * @function - */ -quat.set = vec4.set; - -/** - * Set a quat to the identity quaternion - * - * @param {quat} out the receiving quaternion - * @returns {quat} out - */ -quat.identity = function(out) { - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -}; - -/** - * Sets a quat from the given angle and rotation axis, - * then returns it. - * - * @param {quat} out the receiving quaternion - * @param {vec3} axis the axis around which to rotate - * @param {Number} rad the angle in radians - * @returns {quat} out - **/ -quat.setAxisAngle = function(out, axis, rad) { - rad = rad * 0.5; - var s = Math.sin(rad); - out[0] = s * axis[0]; - out[1] = s * axis[1]; - out[2] = s * axis[2]; - out[3] = Math.cos(rad); - return out; -}; - -/** - * Gets the rotation axis and angle for a given - * quaternion. If a quaternion is created with - * setAxisAngle, this method will return the same - * values as providied in the original parameter list - * OR functionally equivalent values. - * Example: The quaternion formed by axis [0, 0, 1] and - * angle -90 is the same as the quaternion formed by - * [0, 0, 1] and 270. This method favors the latter. - * @param {vec3} out_axis Vector receiving the axis of rotation - * @param {quat} q Quaternion to be decomposed - * @return {Number} Angle, in radians, of the rotation - */ -quat.getAxisAngle = function(out_axis, q) { - var rad = Math.acos(q[3]) * 2.0; - var s = Math.sin(rad / 2.0); - if (s != 0.0) { - out_axis[0] = q[0] / s; - out_axis[1] = q[1] / s; - out_axis[2] = q[2] / s; - } else { - // If s is zero, return any axis (no rotation - axis does not matter) - out_axis[0] = 1; - out_axis[1] = 0; - out_axis[2] = 0; - } - return rad; -}; - -/** - * Adds two quat's - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @returns {quat} out - * @function - */ -quat.add = vec4.add; - -/** - * Multiplies two quat's - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @returns {quat} out - */ -quat.multiply = function(out, a, b) { - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - bx = b[0], by = b[1], bz = b[2], bw = b[3]; - - out[0] = ax * bw + aw * bx + ay * bz - az * by; - out[1] = ay * bw + aw * by + az * bx - ax * bz; - out[2] = az * bw + aw * bz + ax * by - ay * bx; - out[3] = aw * bw - ax * bx - ay * by - az * bz; - return out; -}; - -/** - * Alias for {@link quat.multiply} - * @function - */ -quat.mul = quat.multiply; - -/** - * Scales a quat by a scalar number - * - * @param {quat} out the receiving vector - * @param {quat} a the vector to scale - * @param {Number} b amount to scale the vector by - * @returns {quat} out - * @function - */ -quat.scale = vec4.scale; - -/** - * Rotates a quaternion by the given angle about the X axis - * - * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate - * @param {number} rad angle (in radians) to rotate - * @returns {quat} out - */ -quat.rotateX = function (out, a, rad) { - rad *= 0.5; - - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - bx = Math.sin(rad), bw = Math.cos(rad); - - out[0] = ax * bw + aw * bx; - out[1] = ay * bw + az * bx; - out[2] = az * bw - ay * bx; - out[3] = aw * bw - ax * bx; - return out; -}; - -/** - * Rotates a quaternion by the given angle about the Y axis - * - * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate - * @param {number} rad angle (in radians) to rotate - * @returns {quat} out - */ -quat.rotateY = function (out, a, rad) { - rad *= 0.5; - - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - by = Math.sin(rad), bw = Math.cos(rad); - - out[0] = ax * bw - az * by; - out[1] = ay * bw + aw * by; - out[2] = az * bw + ax * by; - out[3] = aw * bw - ay * by; - return out; -}; - -/** - * Rotates a quaternion by the given angle about the Z axis - * - * @param {quat} out quat receiving operation result - * @param {quat} a quat to rotate - * @param {number} rad angle (in radians) to rotate - * @returns {quat} out - */ -quat.rotateZ = function (out, a, rad) { - rad *= 0.5; - - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - bz = Math.sin(rad), bw = Math.cos(rad); - - out[0] = ax * bw + ay * bz; - out[1] = ay * bw - ax * bz; - out[2] = az * bw + aw * bz; - out[3] = aw * bw - az * bz; - return out; -}; - -/** - * Calculates the W component of a quat from the X, Y, and Z components. - * Assumes that quaternion is 1 unit in length. - * Any existing W component will be ignored. - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate W component of - * @returns {quat} out - */ -quat.calculateW = function (out, a) { - var x = a[0], y = a[1], z = a[2]; - - out[0] = x; - out[1] = y; - out[2] = z; - out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); - return out; -}; - -/** - * Calculates the dot product of two quat's - * - * @param {quat} a the first operand - * @param {quat} b the second operand - * @returns {Number} dot product of a and b - * @function - */ -quat.dot = vec4.dot; - -/** - * Performs a linear interpolation between two quat's - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {quat} out - * @function - */ -quat.lerp = vec4.lerp; - -/** - * Performs a spherical linear interpolation between two quat - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {quat} out - */ -quat.slerp = function (out, a, b, t) { - // benchmarks: - // http://jsperf.com/quaternion-slerp-implementations - - var ax = a[0], ay = a[1], az = a[2], aw = a[3], - bx = b[0], by = b[1], bz = b[2], bw = b[3]; - - var omega, cosom, sinom, scale0, scale1; - - // calc cosine - cosom = ax * bx + ay * by + az * bz + aw * bw; - // adjust signs (if necessary) - if ( cosom < 0.0 ) { - cosom = -cosom; - bx = - bx; - by = - by; - bz = - bz; - bw = - bw; - } - // calculate coefficients - if ( (1.0 - cosom) > 0.000001 ) { - // standard case (slerp) - omega = Math.acos(cosom); - sinom = Math.sin(omega); - scale0 = Math.sin((1.0 - t) * omega) / sinom; - scale1 = Math.sin(t * omega) / sinom; - } else { - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - scale0 = 1.0 - t; - scale1 = t; - } - // calculate final values - out[0] = scale0 * ax + scale1 * bx; - out[1] = scale0 * ay + scale1 * by; - out[2] = scale0 * az + scale1 * bz; - out[3] = scale0 * aw + scale1 * bw; - - return out; -}; - -/** - * Performs a spherical linear interpolation with two control points - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @param {quat} c the third operand - * @param {quat} d the fourth operand - * @param {Number} t interpolation amount - * @returns {quat} out - */ -quat.sqlerp = (function () { - var temp1 = quat.create(); - var temp2 = quat.create(); - - return function (out, a, b, c, d, t) { - quat.slerp(temp1, a, d, t); - quat.slerp(temp2, b, c, t); - quat.slerp(out, temp1, temp2, 2 * t * (1 - t)); - - return out; - }; -}()); - -/** - * Calculates the inverse of a quat - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate inverse of - * @returns {quat} out - */ -quat.invert = function(out, a) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], - dot = a0*a0 + a1*a1 + a2*a2 + a3*a3, - invDot = dot ? 1.0/dot : 0; - - // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 - - out[0] = -a0*invDot; - out[1] = -a1*invDot; - out[2] = -a2*invDot; - out[3] = a3*invDot; - return out; -}; - -/** - * Calculates the conjugate of a quat - * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate conjugate of - * @returns {quat} out - */ -quat.conjugate = function (out, a) { - out[0] = -a[0]; - out[1] = -a[1]; - out[2] = -a[2]; - out[3] = a[3]; - return out; -}; - -/** - * Calculates the length of a quat - * - * @param {quat} a vector to calculate length of - * @returns {Number} length of a - * @function - */ -quat.length = vec4.length; - -/** - * Alias for {@link quat.length} - * @function - */ -quat.len = quat.length; - -/** - * Calculates the squared length of a quat - * - * @param {quat} a vector to calculate squared length of - * @returns {Number} squared length of a - * @function - */ -quat.squaredLength = vec4.squaredLength; - -/** - * Alias for {@link quat.squaredLength} - * @function - */ -quat.sqrLen = quat.squaredLength; - -/** - * Normalize a quat - * - * @param {quat} out the receiving quaternion - * @param {quat} a quaternion to normalize - * @returns {quat} out - * @function - */ -quat.normalize = vec4.normalize; - -/** - * Creates a quaternion from the given 3x3 rotation matrix. - * - * NOTE: The resultant quaternion is not normalized, so you should be sure - * to renormalize the quaternion yourself where necessary. - * - * @param {quat} out the receiving quaternion - * @param {mat3} m rotation matrix - * @returns {quat} out - * @function - */ -quat.fromMat3 = function(out, m) { - // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes - // article "Quaternion Calculus and Fast Animation". - var fTrace = m[0] + m[4] + m[8]; - var fRoot; - - if ( fTrace > 0.0 ) { - // |w| > 1/2, may as well choose w > 1/2 - fRoot = Math.sqrt(fTrace + 1.0); // 2w - out[3] = 0.5 * fRoot; - fRoot = 0.5/fRoot; // 1/(4w) - out[0] = (m[5]-m[7])*fRoot; - out[1] = (m[6]-m[2])*fRoot; - out[2] = (m[1]-m[3])*fRoot; - } else { - // |w| <= 1/2 - var i = 0; - if ( m[4] > m[0] ) - i = 1; - if ( m[8] > m[i*3+i] ) - i = 2; - var j = (i+1)%3; - var k = (i+2)%3; - - fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0); - out[i] = 0.5 * fRoot; - fRoot = 0.5 / fRoot; - out[3] = (m[j*3+k] - m[k*3+j]) * fRoot; - out[j] = (m[j*3+i] + m[i*3+j]) * fRoot; - out[k] = (m[k*3+i] + m[i*3+k]) * fRoot; - } - - return out; -}; - -/** - * Returns a string representation of a quatenion - * - * @param {quat} vec vector to represent as a string - * @returns {String} string representation of the vector - */ -quat.str = function (a) { - return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; -}; - -/** - * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) - * - * @param {quat} a The first quaternion. - * @param {quat} b The second quaternion. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -quat.exactEquals = vec4.exactEquals; - -/** - * Returns whether or not the quaternions have approximately the same elements in the same position. - * - * @param {quat} a The first vector. - * @param {quat} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -quat.equals = vec4.equals; - -module.exports = quat; - -},{"./common.js":27,"./mat3.js":30,"./vec3.js":34,"./vec4.js":35}],33:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 2 Dimensional Vector - * @name vec2 - */ -var vec2 = {}; - -/** - * Creates a new, empty vec2 - * - * @returns {vec2} a new 2D vector - */ -vec2.create = function() { - var out = new glMatrix.ARRAY_TYPE(2); - out[0] = 0; - out[1] = 0; - return out; -}; - -/** - * Creates a new vec2 initialized with values from an existing vector - * - * @param {vec2} a vector to clone - * @returns {vec2} a new 2D vector - */ -vec2.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(2); - out[0] = a[0]; - out[1] = a[1]; - return out; -}; - -/** - * Creates a new vec2 initialized with the given values - * - * @param {Number} x X component - * @param {Number} y Y component - * @returns {vec2} a new 2D vector - */ -vec2.fromValues = function(x, y) { - var out = new glMatrix.ARRAY_TYPE(2); - out[0] = x; - out[1] = y; - return out; -}; - -/** - * Copy the values from one vec2 to another - * - * @param {vec2} out the receiving vector - * @param {vec2} a the source vector - * @returns {vec2} out - */ -vec2.copy = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - return out; -}; - -/** - * Set the components of a vec2 to the given values - * - * @param {vec2} out the receiving vector - * @param {Number} x X component - * @param {Number} y Y component - * @returns {vec2} out - */ -vec2.set = function(out, x, y) { - out[0] = x; - out[1] = y; - return out; -}; - -/** - * Adds two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - return out; -}; - -/** - * Subtracts vector b from vector a - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - return out; -}; - -/** - * Alias for {@link vec2.subtract} - * @function - */ -vec2.sub = vec2.subtract; - -/** - * Multiplies two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.multiply = function(out, a, b) { - out[0] = a[0] * b[0]; - out[1] = a[1] * b[1]; - return out; -}; - -/** - * Alias for {@link vec2.multiply} - * @function - */ -vec2.mul = vec2.multiply; - -/** - * Divides two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.divide = function(out, a, b) { - out[0] = a[0] / b[0]; - out[1] = a[1] / b[1]; - return out; -}; - -/** - * Alias for {@link vec2.divide} - * @function - */ -vec2.div = vec2.divide; - -/** - * Math.ceil the components of a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to ceil - * @returns {vec2} out - */ -vec2.ceil = function (out, a) { - out[0] = Math.ceil(a[0]); - out[1] = Math.ceil(a[1]); - return out; -}; - -/** - * Math.floor the components of a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to floor - * @returns {vec2} out - */ -vec2.floor = function (out, a) { - out[0] = Math.floor(a[0]); - out[1] = Math.floor(a[1]); - return out; -}; - -/** - * Returns the minimum of two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.min = function(out, a, b) { - out[0] = Math.min(a[0], b[0]); - out[1] = Math.min(a[1], b[1]); - return out; -}; - -/** - * Returns the maximum of two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec2} out - */ -vec2.max = function(out, a, b) { - out[0] = Math.max(a[0], b[0]); - out[1] = Math.max(a[1], b[1]); - return out; -}; - -/** - * Math.round the components of a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to round - * @returns {vec2} out - */ -vec2.round = function (out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - return out; -}; - -/** - * Scales a vec2 by a scalar number - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to scale - * @param {Number} b amount to scale the vector by - * @returns {vec2} out - */ -vec2.scale = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - return out; -}; - -/** - * Adds two vec2's after scaling the second operand by a scalar value - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @param {Number} scale the amount to scale b by before adding - * @returns {vec2} out - */ -vec2.scaleAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - return out; -}; - -/** - * Calculates the euclidian distance between two vec2's - * - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {Number} distance between a and b - */ -vec2.distance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1]; - return Math.sqrt(x*x + y*y); -}; - -/** - * Alias for {@link vec2.distance} - * @function - */ -vec2.dist = vec2.distance; - -/** - * Calculates the squared euclidian distance between two vec2's - * - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {Number} squared distance between a and b - */ -vec2.squaredDistance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1]; - return x*x + y*y; -}; - -/** - * Alias for {@link vec2.squaredDistance} - * @function - */ -vec2.sqrDist = vec2.squaredDistance; - -/** - * Calculates the length of a vec2 - * - * @param {vec2} a vector to calculate length of - * @returns {Number} length of a - */ -vec2.length = function (a) { - var x = a[0], - y = a[1]; - return Math.sqrt(x*x + y*y); -}; - -/** - * Alias for {@link vec2.length} - * @function - */ -vec2.len = vec2.length; - -/** - * Calculates the squared length of a vec2 - * - * @param {vec2} a vector to calculate squared length of - * @returns {Number} squared length of a - */ -vec2.squaredLength = function (a) { - var x = a[0], - y = a[1]; - return x*x + y*y; -}; - -/** - * Alias for {@link vec2.squaredLength} - * @function - */ -vec2.sqrLen = vec2.squaredLength; - -/** - * Negates the components of a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to negate - * @returns {vec2} out - */ -vec2.negate = function(out, a) { - out[0] = -a[0]; - out[1] = -a[1]; - return out; -}; - -/** - * Returns the inverse of the components of a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to invert - * @returns {vec2} out - */ -vec2.inverse = function(out, a) { - out[0] = 1.0 / a[0]; - out[1] = 1.0 / a[1]; - return out; -}; - -/** - * Normalize a vec2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a vector to normalize - * @returns {vec2} out - */ -vec2.normalize = function(out, a) { - var x = a[0], - y = a[1]; - var len = x*x + y*y; - if (len > 0) { - //TODO: evaluate use of glm_invsqrt here? - len = 1 / Math.sqrt(len); - out[0] = a[0] * len; - out[1] = a[1] * len; - } - return out; -}; - -/** - * Calculates the dot product of two vec2's - * - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {Number} dot product of a and b - */ -vec2.dot = function (a, b) { - return a[0] * b[0] + a[1] * b[1]; -}; - -/** - * Computes the cross product of two vec2's - * Note that the cross product must by definition produce a 3D vector - * - * @param {vec3} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {vec3} out - */ -vec2.cross = function(out, a, b) { - var z = a[0] * b[1] - a[1] * b[0]; - out[0] = out[1] = 0; - out[2] = z; - return out; -}; - -/** - * Performs a linear interpolation between two vec2's - * - * @param {vec2} out the receiving vector - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec2} out - */ -vec2.lerp = function (out, a, b, t) { - var ax = a[0], - ay = a[1]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - return out; -}; - -/** - * Generates a random vector with the given scale - * - * @param {vec2} out the receiving vector - * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned - * @returns {vec2} out - */ -vec2.random = function (out, scale) { - scale = scale || 1.0; - var r = glMatrix.RANDOM() * 2.0 * Math.PI; - out[0] = Math.cos(r) * scale; - out[1] = Math.sin(r) * scale; - return out; -}; - -/** - * Transforms the vec2 with a mat2 - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat2} m matrix to transform with - * @returns {vec2} out - */ -vec2.transformMat2 = function(out, a, m) { - var x = a[0], - y = a[1]; - out[0] = m[0] * x + m[2] * y; - out[1] = m[1] * x + m[3] * y; - return out; -}; - -/** - * Transforms the vec2 with a mat2d - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat2d} m matrix to transform with - * @returns {vec2} out - */ -vec2.transformMat2d = function(out, a, m) { - var x = a[0], - y = a[1]; - out[0] = m[0] * x + m[2] * y + m[4]; - out[1] = m[1] * x + m[3] * y + m[5]; - return out; -}; - -/** - * Transforms the vec2 with a mat3 - * 3rd vector component is implicitly '1' - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat3} m matrix to transform with - * @returns {vec2} out - */ -vec2.transformMat3 = function(out, a, m) { - var x = a[0], - y = a[1]; - out[0] = m[0] * x + m[3] * y + m[6]; - out[1] = m[1] * x + m[4] * y + m[7]; - return out; -}; - -/** - * Transforms the vec2 with a mat4 - * 3rd vector component is implicitly '0' - * 4th vector component is implicitly '1' - * - * @param {vec2} out the receiving vector - * @param {vec2} a the vector to transform - * @param {mat4} m matrix to transform with - * @returns {vec2} out - */ -vec2.transformMat4 = function(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]; - return out; -}; - -/** - * Perform some operation over an array of vec2s. - * - * @param {Array} a the array of vectors to iterate over - * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed - * @param {Number} offset Number of elements to skip at the beginning of the array - * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array - * @param {Function} fn Function to call for each vector in the array - * @param {Object} [arg] additional argument to pass to fn - * @returns {Array} a - * @function - */ -vec2.forEach = (function() { - var vec = vec2.create(); - - return function(a, stride, offset, count, fn, arg) { - var i, l; - if(!stride) { - stride = 2; - } - - if(!offset) { - offset = 0; - } - - if(count) { - l = Math.min((count * stride) + offset, a.length); - } else { - l = a.length; - } - - for(i = offset; i < l; i += stride) { - vec[0] = a[i]; vec[1] = a[i+1]; - fn(vec, vec, arg); - a[i] = vec[0]; a[i+1] = vec[1]; - } - - return a; - }; -})(); - -/** - * Returns a string representation of a vector - * - * @param {vec2} vec vector to represent as a string - * @returns {String} string representation of the vector - */ -vec2.str = function (a) { - return 'vec2(' + a[0] + ', ' + a[1] + ')'; -}; - -/** - * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) - * - * @param {vec2} a The first vector. - * @param {vec2} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec2.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1]; -}; - -/** - * Returns whether or not the vectors have approximately the same elements in the same position. - * - * @param {vec2} a The first vector. - * @param {vec2} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec2.equals = function (a, b) { - var a0 = a[0], a1 = a[1]; - var b0 = b[0], b1 = b[1]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1))); -}; - -module.exports = vec2; - -},{"./common.js":27}],34:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 3 Dimensional Vector - * @name vec3 - */ -var vec3 = {}; - -/** - * Creates a new, empty vec3 - * - * @returns {vec3} a new 3D vector - */ -vec3.create = function() { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = 0; - out[1] = 0; - out[2] = 0; - return out; -}; - -/** - * Creates a new vec3 initialized with values from an existing vector - * - * @param {vec3} a vector to clone - * @returns {vec3} a new 3D vector - */ -vec3.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - return out; -}; - -/** - * Creates a new vec3 initialized with the given values - * - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @returns {vec3} a new 3D vector - */ -vec3.fromValues = function(x, y, z) { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = x; - out[1] = y; - out[2] = z; - return out; -}; - -/** - * Copy the values from one vec3 to another - * - * @param {vec3} out the receiving vector - * @param {vec3} a the source vector - * @returns {vec3} out - */ -vec3.copy = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - return out; -}; - -/** - * Set the components of a vec3 to the given values - * - * @param {vec3} out the receiving vector - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @returns {vec3} out - */ -vec3.set = function(out, x, y, z) { - out[0] = x; - out[1] = y; - out[2] = z; - return out; -}; - -/** - * Adds two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - return out; -}; - -/** - * Subtracts vector b from vector a - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - return out; -}; - -/** - * Alias for {@link vec3.subtract} - * @function - */ -vec3.sub = vec3.subtract; - -/** - * Multiplies two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.multiply = function(out, a, b) { - out[0] = a[0] * b[0]; - out[1] = a[1] * b[1]; - out[2] = a[2] * b[2]; - return out; -}; - -/** - * Alias for {@link vec3.multiply} - * @function - */ -vec3.mul = vec3.multiply; - -/** - * Divides two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.divide = function(out, a, b) { - out[0] = a[0] / b[0]; - out[1] = a[1] / b[1]; - out[2] = a[2] / b[2]; - return out; -}; - -/** - * Alias for {@link vec3.divide} - * @function - */ -vec3.div = vec3.divide; - -/** - * Math.ceil the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to ceil - * @returns {vec3} out - */ -vec3.ceil = function (out, a) { - out[0] = Math.ceil(a[0]); - out[1] = Math.ceil(a[1]); - out[2] = Math.ceil(a[2]); - return out; -}; - -/** - * Math.floor the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to floor - * @returns {vec3} out - */ -vec3.floor = function (out, a) { - out[0] = Math.floor(a[0]); - out[1] = Math.floor(a[1]); - out[2] = Math.floor(a[2]); - return out; -}; - -/** - * Returns the minimum of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.min = function(out, a, b) { - out[0] = Math.min(a[0], b[0]); - out[1] = Math.min(a[1], b[1]); - out[2] = Math.min(a[2], b[2]); - return out; -}; - -/** - * Returns the maximum of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.max = function(out, a, b) { - out[0] = Math.max(a[0], b[0]); - out[1] = Math.max(a[1], b[1]); - out[2] = Math.max(a[2], b[2]); - return out; -}; - -/** - * Math.round the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to round - * @returns {vec3} out - */ -vec3.round = function (out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - out[2] = Math.round(a[2]); - return out; -}; - -/** - * Scales a vec3 by a scalar number - * - * @param {vec3} out the receiving vector - * @param {vec3} a the vector to scale - * @param {Number} b amount to scale the vector by - * @returns {vec3} out - */ -vec3.scale = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - return out; -}; - -/** - * Adds two vec3's after scaling the second operand by a scalar value - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {Number} scale the amount to scale b by before adding - * @returns {vec3} out - */ -vec3.scaleAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - return out; -}; - -/** - * Calculates the euclidian distance between two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} distance between a and b - */ -vec3.distance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1], - z = b[2] - a[2]; - return Math.sqrt(x*x + y*y + z*z); -}; - -/** - * Alias for {@link vec3.distance} - * @function - */ -vec3.dist = vec3.distance; - -/** - * Calculates the squared euclidian distance between two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} squared distance between a and b - */ -vec3.squaredDistance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1], - z = b[2] - a[2]; - return x*x + y*y + z*z; -}; - -/** - * Alias for {@link vec3.squaredDistance} - * @function - */ -vec3.sqrDist = vec3.squaredDistance; - -/** - * Calculates the length of a vec3 - * - * @param {vec3} a vector to calculate length of - * @returns {Number} length of a - */ -vec3.length = function (a) { - var x = a[0], - y = a[1], - z = a[2]; - return Math.sqrt(x*x + y*y + z*z); -}; - -/** - * Alias for {@link vec3.length} - * @function - */ -vec3.len = vec3.length; - -/** - * Calculates the squared length of a vec3 - * - * @param {vec3} a vector to calculate squared length of - * @returns {Number} squared length of a - */ -vec3.squaredLength = function (a) { - var x = a[0], - y = a[1], - z = a[2]; - return x*x + y*y + z*z; -}; - -/** - * Alias for {@link vec3.squaredLength} - * @function - */ -vec3.sqrLen = vec3.squaredLength; - -/** - * Negates the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to negate - * @returns {vec3} out - */ -vec3.negate = function(out, a) { - out[0] = -a[0]; - out[1] = -a[1]; - out[2] = -a[2]; - return out; -}; - -/** - * Returns the inverse of the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to invert - * @returns {vec3} out - */ -vec3.inverse = function(out, a) { - out[0] = 1.0 / a[0]; - out[1] = 1.0 / a[1]; - out[2] = 1.0 / a[2]; - return out; -}; - -/** - * Normalize a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to normalize - * @returns {vec3} out - */ -vec3.normalize = function(out, a) { - var x = a[0], - y = a[1], - z = a[2]; - var len = x*x + y*y + z*z; - if (len > 0) { - //TODO: evaluate use of glm_invsqrt here? - len = 1 / Math.sqrt(len); - out[0] = a[0] * len; - out[1] = a[1] * len; - out[2] = a[2] * len; - } - return out; -}; - -/** - * Calculates the dot product of two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} dot product of a and b - */ -vec3.dot = function (a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -}; - -/** - * Computes the cross product of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -vec3.cross = function(out, a, b) { - var ax = a[0], ay = a[1], az = a[2], - bx = b[0], by = b[1], bz = b[2]; - - out[0] = ay * bz - az * by; - out[1] = az * bx - ax * bz; - out[2] = ax * by - ay * bx; - return out; -}; - -/** - * Performs a linear interpolation between two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec3} out - */ -vec3.lerp = function (out, a, b, t) { - var ax = a[0], - ay = a[1], - az = a[2]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - out[2] = az + t * (b[2] - az); - return out; -}; - -/** - * Performs a hermite interpolation with two control points - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {vec3} c the third operand - * @param {vec3} d the fourth operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec3} out - */ -vec3.hermite = function (out, a, b, c, d, t) { - var factorTimes2 = t * t, - factor1 = factorTimes2 * (2 * t - 3) + 1, - factor2 = factorTimes2 * (t - 2) + t, - factor3 = factorTimes2 * (t - 1), - factor4 = factorTimes2 * (3 - 2 * t); - - out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; - out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; - out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; - - return out; -}; - -/** - * Performs a bezier interpolation with two control points - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {vec3} c the third operand - * @param {vec3} d the fourth operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec3} out - */ -vec3.bezier = function (out, a, b, c, d, t) { - var inverseFactor = 1 - t, - inverseFactorTimesTwo = inverseFactor * inverseFactor, - factorTimes2 = t * t, - factor1 = inverseFactorTimesTwo * inverseFactor, - factor2 = 3 * t * inverseFactorTimesTwo, - factor3 = 3 * factorTimes2 * inverseFactor, - factor4 = factorTimes2 * t; - - out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; - out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; - out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; - - return out; -}; - -/** - * Generates a random vector with the given scale - * - * @param {vec3} out the receiving vector - * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned - * @returns {vec3} out - */ -vec3.random = function (out, scale) { - scale = scale || 1.0; - - var r = glMatrix.RANDOM() * 2.0 * Math.PI; - var z = (glMatrix.RANDOM() * 2.0) - 1.0; - var zScale = Math.sqrt(1.0-z*z) * scale; - - out[0] = Math.cos(r) * zScale; - out[1] = Math.sin(r) * zScale; - out[2] = z * scale; - return out; -}; - -/** - * Transforms the vec3 with a mat4. - * 4th vector component is implicitly '1' - * - * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {mat4} m matrix to transform with - * @returns {vec3} out - */ -vec3.transformMat4 = function(out, a, m) { - var x = a[0], y = a[1], z = a[2], - w = m[3] * x + m[7] * y + m[11] * z + m[15]; - w = w || 1.0; - 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; - return out; -}; - -/** - * Transforms the vec3 with a mat3. - * - * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {mat4} m the 3x3 matrix to transform with - * @returns {vec3} out - */ -vec3.transformMat3 = function(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; -}; - -/** - * Transforms the vec3 with a quat - * - * @param {vec3} out the receiving vector - * @param {vec3} a the vector to transform - * @param {quat} q quaternion to transform with - * @returns {vec3} out - */ -vec3.transformQuat = function(out, a, q) { - // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations - - var x = a[0], y = a[1], z = a[2], - qx = q[0], qy = q[1], qz = q[2], qw = q[3], - - // calculate quat * vec - ix = qw * x + qy * z - qz * y, - iy = qw * y + qz * x - qx * z, - iz = qw * z + qx * y - qy * x, - iw = -qx * x - qy * y - qz * z; - - // calculate result * inverse quat - out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; - out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; - out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return out; -}; - -/** - * Rotate a 3D vector around the x-axis - * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation - * @returns {vec3} out - */ -vec3.rotateX = function(out, a, b, c){ - var p = [], r=[]; - //Translate point to the origin - p[0] = a[0] - b[0]; - p[1] = a[1] - b[1]; - p[2] = a[2] - b[2]; - - //perform rotation - r[0] = p[0]; - r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c); - r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c); - - //translate to correct position - out[0] = r[0] + b[0]; - out[1] = r[1] + b[1]; - out[2] = r[2] + b[2]; - - return out; -}; - -/** - * Rotate a 3D vector around the y-axis - * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation - * @returns {vec3} out - */ -vec3.rotateY = function(out, a, b, c){ - var p = [], r=[]; - //Translate point to the origin - p[0] = a[0] - b[0]; - p[1] = a[1] - b[1]; - p[2] = a[2] - b[2]; - - //perform rotation - r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c); - r[1] = p[1]; - r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c); - - //translate to correct position - out[0] = r[0] + b[0]; - out[1] = r[1] + b[1]; - out[2] = r[2] + b[2]; - - return out; -}; - -/** - * Rotate a 3D vector around the z-axis - * @param {vec3} out The receiving vec3 - * @param {vec3} a The vec3 point to rotate - * @param {vec3} b The origin of the rotation - * @param {Number} c The angle of rotation - * @returns {vec3} out - */ -vec3.rotateZ = function(out, a, b, c){ - var p = [], r=[]; - //Translate point to the origin - p[0] = a[0] - b[0]; - p[1] = a[1] - b[1]; - p[2] = a[2] - b[2]; - - //perform rotation - r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c); - r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c); - r[2] = p[2]; - - //translate to correct position - out[0] = r[0] + b[0]; - out[1] = r[1] + b[1]; - out[2] = r[2] + b[2]; - - return out; -}; - -/** - * Perform some operation over an array of vec3s. - * - * @param {Array} a the array of vectors to iterate over - * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed - * @param {Number} offset Number of elements to skip at the beginning of the array - * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array - * @param {Function} fn Function to call for each vector in the array - * @param {Object} [arg] additional argument to pass to fn - * @returns {Array} a - * @function - */ -vec3.forEach = (function() { - var vec = vec3.create(); - - 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; - }; -})(); - -/** - * Get the angle between two 3D vectors - * @param {vec3} a The first operand - * @param {vec3} b The second operand - * @returns {Number} The angle in radians - */ -vec3.angle = function(a, b) { - - var tempA = vec3.fromValues(a[0], a[1], a[2]); - var tempB = vec3.fromValues(b[0], b[1], b[2]); - - vec3.normalize(tempA, tempA); - vec3.normalize(tempB, tempB); - - var cosine = vec3.dot(tempA, tempB); - - if(cosine > 1.0){ - return 0; - } else { - return Math.acos(cosine); - } -}; - -/** - * Returns a string representation of a vector - * - * @param {vec3} vec vector to represent as a string - * @returns {String} string representation of the vector - */ -vec3.str = function (a) { - return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')'; -}; - -/** - * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) - * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec3.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; -}; - -/** - * Returns whether or not the vectors have approximately the same elements in the same position. - * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec3.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2]; - var b0 = b[0], b1 = b[1], b2 = b[2]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2))); -}; - -module.exports = vec3; - -},{"./common.js":27}],35:[function(require,module,exports){ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -var glMatrix = require("./common.js"); - -/** - * @class 4 Dimensional Vector - * @name vec4 - */ -var vec4 = {}; - -/** - * Creates a new, empty vec4 - * - * @returns {vec4} a new 4D vector - */ -vec4.create = function() { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 0; - return out; -}; - -/** - * Creates a new vec4 initialized with values from an existing vector - * - * @param {vec4} a vector to clone - * @returns {vec4} a new 4D vector - */ -vec4.clone = function(a) { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - return out; -}; - -/** - * Creates a new vec4 initialized with the given values - * - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @param {Number} w W component - * @returns {vec4} a new 4D vector - */ -vec4.fromValues = function(x, y, z, w) { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = x; - out[1] = y; - out[2] = z; - out[3] = w; - return out; -}; - -/** - * Copy the values from one vec4 to another - * - * @param {vec4} out the receiving vector - * @param {vec4} a the source vector - * @returns {vec4} out - */ -vec4.copy = function(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - return out; -}; - -/** - * Set the components of a vec4 to the given values - * - * @param {vec4} out the receiving vector - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @param {Number} w W component - * @returns {vec4} out - */ -vec4.set = function(out, x, y, z, w) { - out[0] = x; - out[1] = y; - out[2] = z; - out[3] = w; - return out; -}; - -/** - * Adds two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.add = function(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - return out; -}; - -/** - * Subtracts vector b from vector a - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.subtract = function(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - return out; -}; - -/** - * Alias for {@link vec4.subtract} - * @function - */ -vec4.sub = vec4.subtract; - -/** - * Multiplies two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.multiply = function(out, a, b) { - out[0] = a[0] * b[0]; - out[1] = a[1] * b[1]; - out[2] = a[2] * b[2]; - out[3] = a[3] * b[3]; - return out; -}; - -/** - * Alias for {@link vec4.multiply} - * @function - */ -vec4.mul = vec4.multiply; - -/** - * Divides two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.divide = function(out, a, b) { - out[0] = a[0] / b[0]; - out[1] = a[1] / b[1]; - out[2] = a[2] / b[2]; - out[3] = a[3] / b[3]; - return out; -}; - -/** - * Alias for {@link vec4.divide} - * @function - */ -vec4.div = vec4.divide; - -/** - * Math.ceil the components of a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to ceil - * @returns {vec4} out - */ -vec4.ceil = function (out, a) { - out[0] = Math.ceil(a[0]); - out[1] = Math.ceil(a[1]); - out[2] = Math.ceil(a[2]); - out[3] = Math.ceil(a[3]); - return out; -}; - -/** - * Math.floor the components of a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to floor - * @returns {vec4} out - */ -vec4.floor = function (out, a) { - out[0] = Math.floor(a[0]); - out[1] = Math.floor(a[1]); - out[2] = Math.floor(a[2]); - out[3] = Math.floor(a[3]); - return out; -}; - -/** - * Returns the minimum of two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.min = function(out, a, b) { - out[0] = Math.min(a[0], b[0]); - out[1] = Math.min(a[1], b[1]); - out[2] = Math.min(a[2], b[2]); - out[3] = Math.min(a[3], b[3]); - return out; -}; - -/** - * Returns the maximum of two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {vec4} out - */ -vec4.max = function(out, a, b) { - out[0] = Math.max(a[0], b[0]); - out[1] = Math.max(a[1], b[1]); - out[2] = Math.max(a[2], b[2]); - out[3] = Math.max(a[3], b[3]); - return out; -}; - -/** - * Math.round the components of a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to round - * @returns {vec4} out - */ -vec4.round = function (out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - out[2] = Math.round(a[2]); - out[3] = Math.round(a[3]); - return out; -}; - -/** - * Scales a vec4 by a scalar number - * - * @param {vec4} out the receiving vector - * @param {vec4} a the vector to scale - * @param {Number} b amount to scale the vector by - * @returns {vec4} out - */ -vec4.scale = function(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - return out; -}; - -/** - * Adds two vec4's after scaling the second operand by a scalar value - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @param {Number} scale the amount to scale b by before adding - * @returns {vec4} out - */ -vec4.scaleAndAdd = function(out, a, b, scale) { - out[0] = a[0] + (b[0] * scale); - out[1] = a[1] + (b[1] * scale); - out[2] = a[2] + (b[2] * scale); - out[3] = a[3] + (b[3] * scale); - return out; -}; - -/** - * Calculates the euclidian distance between two vec4's - * - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {Number} distance between a and b - */ -vec4.distance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1], - z = b[2] - a[2], - w = b[3] - a[3]; - return Math.sqrt(x*x + y*y + z*z + w*w); -}; - -/** - * Alias for {@link vec4.distance} - * @function - */ -vec4.dist = vec4.distance; - -/** - * Calculates the squared euclidian distance between two vec4's - * - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {Number} squared distance between a and b - */ -vec4.squaredDistance = function(a, b) { - var x = b[0] - a[0], - y = b[1] - a[1], - z = b[2] - a[2], - w = b[3] - a[3]; - return x*x + y*y + z*z + w*w; -}; - -/** - * Alias for {@link vec4.squaredDistance} - * @function - */ -vec4.sqrDist = vec4.squaredDistance; - -/** - * Calculates the length of a vec4 - * - * @param {vec4} a vector to calculate length of - * @returns {Number} length of a - */ -vec4.length = function (a) { - var x = a[0], - y = a[1], - z = a[2], - w = a[3]; - return Math.sqrt(x*x + y*y + z*z + w*w); -}; - -/** - * Alias for {@link vec4.length} - * @function - */ -vec4.len = vec4.length; - -/** - * Calculates the squared length of a vec4 - * - * @param {vec4} a vector to calculate squared length of - * @returns {Number} squared length of a - */ -vec4.squaredLength = function (a) { - var x = a[0], - y = a[1], - z = a[2], - w = a[3]; - return x*x + y*y + z*z + w*w; -}; - -/** - * Alias for {@link vec4.squaredLength} - * @function - */ -vec4.sqrLen = vec4.squaredLength; - -/** - * Negates the components of a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to negate - * @returns {vec4} out - */ -vec4.negate = function(out, a) { - out[0] = -a[0]; - out[1] = -a[1]; - out[2] = -a[2]; - out[3] = -a[3]; - return out; -}; - -/** - * Returns the inverse of the components of a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to invert - * @returns {vec4} out - */ -vec4.inverse = function(out, a) { - out[0] = 1.0 / a[0]; - out[1] = 1.0 / a[1]; - out[2] = 1.0 / a[2]; - out[3] = 1.0 / a[3]; - return out; -}; - -/** - * Normalize a vec4 - * - * @param {vec4} out the receiving vector - * @param {vec4} a vector to normalize - * @returns {vec4} out - */ -vec4.normalize = function(out, a) { - var x = a[0], - y = a[1], - z = a[2], - w = a[3]; - var len = x*x + y*y + z*z + w*w; - if (len > 0) { - len = 1 / Math.sqrt(len); - out[0] = x * len; - out[1] = y * len; - out[2] = z * len; - out[3] = w * len; - } - return out; -}; - -/** - * Calculates the dot product of two vec4's - * - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {Number} dot product of a and b - */ -vec4.dot = function (a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; -}; - -/** - * Performs a linear interpolation between two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec4} out - */ -vec4.lerp = function (out, a, b, t) { - var ax = a[0], - ay = a[1], - az = a[2], - aw = a[3]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - out[2] = az + t * (b[2] - az); - out[3] = aw + t * (b[3] - aw); - return out; -}; - -/** - * Generates a random vector with the given scale - * - * @param {vec4} out the receiving vector - * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned - * @returns {vec4} out - */ -vec4.random = function (out, scale) { - scale = scale || 1.0; - - //TODO: This is a pretty awful way of doing this. Find something better. - out[0] = glMatrix.RANDOM(); - out[1] = glMatrix.RANDOM(); - out[2] = glMatrix.RANDOM(); - out[3] = glMatrix.RANDOM(); - vec4.normalize(out, out); - vec4.scale(out, out, scale); - return out; -}; - -/** - * Transforms the vec4 with a mat4. - * - * @param {vec4} out the receiving vector - * @param {vec4} a the vector to transform - * @param {mat4} m matrix to transform with - * @returns {vec4} out - */ -vec4.transformMat4 = function(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; -}; - -/** - * Transforms the vec4 with a quat - * - * @param {vec4} out the receiving vector - * @param {vec4} a the vector to transform - * @param {quat} q quaternion to transform with - * @returns {vec4} out - */ -vec4.transformQuat = function(out, a, q) { - var x = a[0], y = a[1], z = a[2], - qx = q[0], qy = q[1], qz = q[2], qw = q[3], - - // calculate quat * vec - ix = qw * x + qy * z - qz * y, - iy = qw * y + qz * x - qx * z, - iz = qw * z + qx * y - qy * x, - iw = -qx * x - qy * y - qz * z; - - // calculate result * inverse quat - out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; - out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; - out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; - out[3] = a[3]; - return out; -}; - -/** - * Perform some operation over an array of vec4s. - * - * @param {Array} a the array of vectors to iterate over - * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed - * @param {Number} offset Number of elements to skip at the beginning of the array - * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array - * @param {Function} fn Function to call for each vector in the array - * @param {Object} [arg] additional argument to pass to fn - * @returns {Array} a - * @function - */ -vec4.forEach = (function() { - var vec = vec4.create(); - - 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; - }; -})(); - -/** - * Returns a string representation of a vector - * - * @param {vec4} vec vector to represent as a string - * @returns {String} string representation of the vector - */ -vec4.str = function (a) { - return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; -}; - -/** - * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) - * - * @param {vec4} a The first vector. - * @param {vec4} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec4.exactEquals = function (a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; -}; - -/** - * Returns whether or not the vectors have approximately the same elements in the same position. - * - * @param {vec4} a The first vector. - * @param {vec4} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -vec4.equals = function (a, b) { - var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; - var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; - return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && - Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && - Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && - Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3))); -}; - -module.exports = vec4; - -},{"./common.js":27}],36:[function(require,module,exports){ -'use strict'; - -module.exports = 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) { - var min = this.min; - var max = this.max; - if (x1 <= min && y1 <= min && max <= x2 && max <= y2) { - // We use `Array#slice` because `this.keys` may be a `Int32Array` and - // some browsers (Safari and IE) do not support `TypedArray#slice` - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice#Browser_compatibility - return Array.prototype.slice.call(this.keys); - - } else { - var result = []; - var seenUids = {}; - this._forEachCell(x1, y1, x2, y2, this._queryCell, result, seenUids); - return result; - } -}; - -GridIndex.prototype._queryCell = function(x1, y1, x2, y2, cellIndex, result, seenUids) { - 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 ((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) { - 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 (fn.call(this, x1, y1, x2, y2, cellIndex, arg1, arg2)) return; - } - } -}; - -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; -}; - -},{}],37:[function(require,module,exports){ -exports.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) -} - -exports.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 & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],38:[function(require,module,exports){ -'use strict'; - -var sort = require('./sort'); -var range = require('./range'); -var within = require('./within'); - -module.exports = kdbush; - -function kdbush(points, getX, getY, nodeSize, ArrayType) { - return new KDBush(points, getX, getY, nodeSize, ArrayType); -} - -function KDBush(points, getX, getY, nodeSize, ArrayType) { - getX = getX || defaultGetX; - getY = getY || defaultGetY; - ArrayType = ArrayType || Array; - - this.nodeSize = nodeSize || 64; - this.points = points; - - this.ids = new ArrayType(points.length); - this.coords = new ArrayType(points.length * 2); - - for (var i = 0; i < points.length; i++) { - this.ids[i] = i; - this.coords[2 * i] = getX(points[i]); - this.coords[2 * i + 1] = getY(points[i]); - } - - sort(this.ids, this.coords, this.nodeSize, 0, this.ids.length - 1, 0); -} - -KDBush.prototype = { - range: function (minX, minY, maxX, maxY) { - return range(this.ids, this.coords, minX, minY, maxX, maxY, this.nodeSize); - }, - - within: function (x, y, r) { - return within(this.ids, this.coords, x, y, r, this.nodeSize); - } -}; - -function defaultGetX(p) { return p[0]; } -function defaultGetY(p) { return p[1]; } - -},{"./range":39,"./sort":40,"./within":41}],39:[function(require,module,exports){ -'use strict'; - -module.exports = range; - -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; -} - -},{}],40:[function(require,module,exports){ -'use strict'; - -module.exports = sortKD; - -function sortKD(ids, coords, nodeSize, left, right, depth) { - if (right - left <= nodeSize) return; - - var m = Math.floor((left + right) / 2); - - 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; -} - -},{}],41:[function(require,module,exports){ -'use strict'; - -module.exports = within; - -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; -} - -},{}],42:[function(require,module,exports){ -'use strict'; - -function createFunction(parameters, defaultType) { - var fun; - - if (!isFunctionDefinition(parameters)) { - fun = function() { return parameters; }; - fun.isFeatureConstant = true; - fun.isZoomConstant = true; - - } else { - var zoomAndFeatureDependent = typeof parameters.stops[0][0] === 'object'; - var featureDependent = zoomAndFeatureDependent || parameters.property !== undefined; - var zoomDependent = zoomAndFeatureDependent || !featureDependent; - var type = parameters.type || defaultType || 'exponential'; - - var innerFun; - if (type === 'exponential') { - innerFun = evaluateExponentialFunction; - } else if (type === 'interval') { - innerFun = evaluateIntervalFunction; - } else if (type === 'categorical') { - innerFun = evaluateCategoricalFunction; - } else { - throw new Error('Unknown function type "' + type + '"'); - } - - if (zoomAndFeatureDependent) { - var featureFunctions = {}; - var featureFunctionStops = []; - for (var s = 0; s < parameters.stops.length; s++) { - var stop = parameters.stops[s]; - if (featureFunctions[stop[0].zoom] === undefined) { - featureFunctions[stop[0].zoom] = { - zoom: stop[0].zoom, - type: parameters.type, - property: parameters.property, - stops: [] - }; - } - featureFunctions[stop[0].zoom].stops.push([stop[0].value, stop[1]]); - } - - for (var z in featureFunctions) { - featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z])]); - } - fun = function(zoom, feature) { - return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature); - }; - fun.isFeatureConstant = false; - fun.isZoomConstant = false; - - } else if (zoomDependent) { - fun = function(zoom) { - return innerFun(parameters, zoom); - }; - fun.isFeatureConstant = true; - fun.isZoomConstant = false; - } else { - fun = function(zoom, feature) { - return innerFun(parameters, feature[parameters.property]); - }; - fun.isFeatureConstant = false; - fun.isZoomConstant = true; - } - } - - return fun; -} - -function evaluateCategoricalFunction(parameters, input) { - for (var i = 0; i < parameters.stops.length; i++) { - if (input === parameters.stops[i][0]) { - return parameters.stops[i][1]; - } - } - return parameters.stops[0][1]; -} - -function evaluateIntervalFunction(parameters, input) { - for (var i = 0; i < parameters.stops.length; i++) { - if (input < parameters.stops[i][0]) break; - } - return parameters.stops[Math.max(i - 1, 0)][1]; -} - -function evaluateExponentialFunction(parameters, input) { - var base = parameters.base !== undefined ? parameters.base : 1; - - var i = 0; - while (true) { - if (i >= parameters.stops.length) break; - else if (input <= parameters.stops[i][0]) break; - else i++; - } - - if (i === 0) { - return parameters.stops[i][1]; - - } else if (i === parameters.stops.length) { - return parameters.stops[i - 1][1]; - - } else { - return interpolate( - input, - base, - parameters.stops[i - 1][0], - parameters.stops[i][0], - parameters.stops[i - 1][1], - parameters.stops[i][1] - ); - } -} - - -function interpolate(input, base, inputLower, inputUpper, outputLower, outputUpper) { - if (typeof outputLower === 'function') { - return function() { - var evaluatedLower = outputLower.apply(undefined, arguments); - var evaluatedUpper = outputUpper.apply(undefined, arguments); - return interpolate(input, base, inputLower, inputUpper, evaluatedLower, evaluatedUpper); - }; - } else if (outputLower.length) { - return interpolateArray(input, base, inputLower, inputUpper, outputLower, outputUpper); - } else { - return interpolateNumber(input, base, inputLower, inputUpper, outputLower, outputUpper); - } -} - -function interpolateNumber(input, base, inputLower, inputUpper, outputLower, outputUpper) { - var difference = inputUpper - inputLower; - var progress = input - inputLower; - - var ratio; - if (base === 1) { - ratio = progress / difference; - } else { - ratio = (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1); - } - - return (outputLower * (1 - ratio)) + (outputUpper * ratio); -} - -function interpolateArray(input, base, inputLower, inputUpper, outputLower, outputUpper) { - var output = []; - for (var i = 0; i < outputLower.length; i++) { - output[i] = interpolateNumber(input, base, inputLower, inputUpper, outputLower[i], outputUpper[i]); - } - return output; -} - -function isFunctionDefinition(value) { - return typeof value === 'object' && value.stops; -} - - -module.exports.isFunctionDefinition = isFunctionDefinition; - -module.exports.interpolated = function(parameters) { - return createFunction(parameters, 'exponential'); -}; - -module.exports['piecewise-constant'] = function(parameters) { - return createFunction(parameters, 'interval'); -}; - -},{}],43:[function(require,module,exports){ - -var path = require('path'); - -// readFileSync calls must be written out long-form for brfs. -module.exports = { - debug: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform lowp vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, step(32767.0, a_pos.x), 1);\n}\n" - }, - fill: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n#pragma mapbox: define lowp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_FragColor = color * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\n#pragma mapbox: define lowp vec4 color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp vec4 color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n" - }, - circle: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n#pragma mapbox: define lowp vec4 color\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_extrude;\nvarying lowp float v_antialiasblur;\n\nvoid main() {\n #pragma mapbox: initialize lowp vec4 color\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n float t = smoothstep(1.0 - max(blur, v_antialiasblur), 1.0, length(v_extrude));\n gl_FragColor = color * (1.0 - t) * opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform mat4 u_matrix;\nuniform bool u_scale_with_map;\nuniform vec2 u_extrude_scale;\nuniform float u_devicepixelratio;\n\nattribute vec2 a_pos;\n\n#pragma mapbox: define lowp vec4 color\n#pragma mapbox: define mediump float radius\n#pragma mapbox: define lowp float blur\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_extrude;\nvarying lowp float v_antialiasblur;\n\nvoid main(void) {\n #pragma mapbox: initialize lowp vec4 color\n #pragma mapbox: initialize mediump float radius\n #pragma mapbox: initialize lowp float blur\n #pragma mapbox: initialize lowp float opacity\n\n // unencode the extrusion vector that we snuck into the a_pos vector\n v_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);\n\n vec2 extrude = v_extrude * radius * u_extrude_scale;\n // multiply a_pos by 0.5, since we had it * 2 in order to sneak\n // in extrusion data\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5), 0, 1);\n\n if (u_scale_with_map) {\n gl_Position.xy += extrude;\n } else {\n gl_Position.xy += extrude * gl_Position.w;\n }\n\n // This is a minimum blur distance that serves as a faux-antialiasing for\n // the circle. since blur is a ratio of the circle's size and the intent is\n // to keep the blur at roughly 1px, the two are inversely related.\n v_antialiasblur = 1.0 / u_devicepixelratio / radius;\n}\n" - }, - line: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform lowp vec4 u_color;\nuniform lowp float u_opacity;\nuniform float u_blur;\n\nvarying vec2 v_linewidth;\nvarying vec2 v_normal;\nvarying float v_gamma_scale;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float blur = u_blur * v_gamma_scale;\n float alpha = clamp(min(dist - (v_linewidth.t - blur), v_linewidth.s - dist) / blur, 0.0, 1.0);\n\n gl_FragColor = u_color * (alpha * u_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform mediump float u_linewidth;\nuniform mediump float u_gapwidth;\nuniform mediump float u_antialiasing;\nuniform mediump float u_extra;\nuniform mat2 u_antialiasingmatrix;\nuniform mediump float u_offset;\nuniform mediump float u_blur;\n\nvarying vec2 v_normal;\nvarying vec2 v_linewidth;\nvarying float v_gamma_scale;\n\nvoid main() {\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n float inset = u_gapwidth + (u_gapwidth > 0.0 ? u_antialiasing : 0.0);\n float outset = u_gapwidth + u_linewidth * (u_gapwidth > 0.0 ? 2.0 : 1.0) + u_antialiasing;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + (offset + dist) / u_ratio, 0.0, 1.0);\n\n // position of y on the screen\n float y = gl_Position.y / gl_Position.w;\n\n // how much features are squished in the y direction by the tilt\n float squish_scale = length(a_extrude) / length(u_antialiasingmatrix * a_extrude);\n\n // how much features are squished in all directions by the perspectiveness\n float perspective_scale = 1.0 / (1.0 - min(y * u_extra, 0.9));\n\n v_linewidth = vec2(outset, inset);\n v_gamma_scale = perspective_scale * squish_scale;\n}\n" - }, - linepattern: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform float u_blur;\n\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform float u_fade;\nuniform float u_opacity;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_normal;\nvarying vec2 v_linewidth;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float blur = u_blur * v_gamma_scale;\n float alpha = clamp(min(dist - (v_linewidth.t - blur), v_linewidth.s - dist) / blur, 0.0, 1.0);\n\n float x_a = mod(v_linesofar / u_pattern_size_a.x, 1.0);\n float x_b = mod(v_linesofar / u_pattern_size_b.x, 1.0);\n float y_a = 0.5 + (v_normal.y * v_linewidth.s / u_pattern_size_a.y);\n float y_b = 0.5 + (v_normal.y * v_linewidth.s / u_pattern_size_b.y);\n vec2 pos_a = mix(u_pattern_tl_a, u_pattern_br_a, vec2(x_a, y_a));\n vec2 pos_b = mix(u_pattern_tl_b, u_pattern_br_b, vec2(x_b, y_b));\n\n vec4 color = mix(texture2D(u_image, pos_a), texture2D(u_image, pos_b), u_fade);\n\n alpha *= u_opacity;\n\n gl_FragColor = color * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform mediump float u_linewidth;\nuniform mediump float u_gapwidth;\nuniform mediump float u_antialiasing;\nuniform mediump float u_extra;\nuniform mat2 u_antialiasingmatrix;\nuniform mediump float u_offset;\n\nvarying vec2 v_normal;\nvarying vec2 v_linewidth;\nvarying float v_linesofar;\nvarying float v_gamma_scale;\n\nvoid main() {\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n float inset = u_gapwidth + (u_gapwidth > 0.0 ? u_antialiasing : 0.0);\n float outset = u_gapwidth + u_linewidth * (u_gapwidth > 0.0 ? 2.0 : 1.0) + u_antialiasing;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + (offset + dist) / u_ratio, 0.0, 1.0);\n v_linesofar = a_linesofar;\n\n // position of y on the screen\n float y = gl_Position.y / gl_Position.w;\n\n // how much features are squished in the y direction by the tilt\n float squish_scale = length(a_extrude) / length(u_antialiasingmatrix * a_extrude);\n\n // how much features are squished in all directions by the perspectiveness\n float perspective_scale = 1.0 / (1.0 - min(y * u_extra, 0.9));\n\n v_linewidth = vec2(outset, inset);\n v_gamma_scale = perspective_scale * squish_scale;\n}\n" - }, - linesdfpattern: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform lowp vec4 u_color;\nuniform lowp float u_opacity;\n\nuniform float u_blur;\nuniform sampler2D u_image;\nuniform float u_sdfgamma;\nuniform float u_mix;\n\nvarying vec2 v_normal;\nvarying vec2 v_linewidth;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * v_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float blur = u_blur * v_gamma_scale;\n float alpha = clamp(min(dist - (v_linewidth.t - blur), v_linewidth.s - dist) / blur, 0.0, 1.0);\n\n float sdfdist_a = texture2D(u_image, v_tex_a).a;\n float sdfdist_b = texture2D(u_image, v_tex_b).a;\n float sdfdist = mix(sdfdist_a, sdfdist_b, u_mix);\n alpha *= smoothstep(0.5 - u_sdfgamma, 0.5 + u_sdfgamma, sdfdist);\n\n gl_FragColor = u_color * (alpha * u_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n// #define scale 63.0\n#define scale 0.015873016\n\n// We scale the distance before adding it to the buffers so that we can store\n// long distances for long segments. Use this value to unscale the distance.\n#define LINE_DISTANCE_SCALE 2.0\n\nattribute vec2 a_pos;\nattribute vec4 a_data;\n\nuniform mat4 u_matrix;\nuniform mediump float u_ratio;\nuniform mediump float u_linewidth;\nuniform mediump float u_gapwidth;\nuniform mediump float u_antialiasing;\nuniform vec2 u_patternscale_a;\nuniform float u_tex_y_a;\nuniform vec2 u_patternscale_b;\nuniform float u_tex_y_b;\nuniform float u_extra;\nuniform mat2 u_antialiasingmatrix;\nuniform mediump float u_offset;\n\nvarying vec2 v_normal;\nvarying vec2 v_linewidth;\nvarying vec2 v_tex_a;\nvarying vec2 v_tex_b;\nvarying float v_gamma_scale;\n\nvoid main() {\n vec2 a_extrude = a_data.xy - 128.0;\n float a_direction = mod(a_data.z, 4.0) - 1.0;\n float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;\n\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n mediump vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n float inset = u_gapwidth + (u_gapwidth > 0.0 ? u_antialiasing : 0.0);\n float outset = u_gapwidth + u_linewidth * (u_gapwidth > 0.0 ? 2.0 : 1.0) + u_antialiasing;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n mediump vec2 dist = outset * a_extrude * scale;\n\n // Calculate the offset when drawing a line that is to the side of the actual line.\n // We do this by creating a vector that points towards the extrude, but rotate\n // it when we're drawing round end points (a_direction = -1 or 1) since their\n // extrude vector points in another direction.\n mediump float u = 0.5 * a_direction;\n mediump float t = 1.0 - abs(u);\n mediump vec2 offset = u_offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix.\n gl_Position = u_matrix * vec4(floor(a_pos * 0.5) + (offset + dist) / u_ratio, 0.0, 1.0);\n\n v_tex_a = vec2(a_linesofar * u_patternscale_a.x, normal.y * u_patternscale_a.y + u_tex_y_a);\n v_tex_b = vec2(a_linesofar * u_patternscale_b.x, normal.y * u_patternscale_b.y + u_tex_y_b);\n\n // position of y on the screen\n float y = gl_Position.y / gl_Position.w;\n\n // how much features are squished in the y direction by the tilt\n float squish_scale = length(a_extrude) / length(u_antialiasingmatrix * a_extrude);\n\n // how much features are squished in all directions by the perspectiveness\n float perspective_scale = 1.0 / (1.0 - min(y * u_extra, 0.9));\n\n v_linewidth = vec2(outset, inset);\n v_gamma_scale = perspective_scale * squish_scale;\n}\n" - }, - outline: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\n#pragma mapbox: define lowp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvarying vec2 v_pos;\n\nvoid main() {\n #pragma mapbox: initialize lowp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = smoothstep(1.0, 0.0, dist);\n gl_FragColor = outline_color * (alpha * opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos;\n\n#pragma mapbox: define lowp vec4 outline_color\n#pragma mapbox: define lowp float opacity\n\nvoid main() {\n #pragma mapbox: initialize lowp vec4 outline_color\n #pragma mapbox: initialize lowp float opacity\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n" - }, - outlinepattern: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform float u_opacity;\nuniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\nvoid main() {\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b, u_pattern_br_b, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n // find distance to outline for alpha interpolation\n\n float dist = length(v_pos - gl_FragCoord.xy);\n float alpha = smoothstep(1.0, 0.0, dist);\n \n\n gl_FragColor = mix(color1, color2, u_mix) * alpha * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nuniform mat4 u_matrix;\nuniform vec2 u_world;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\nvarying vec2 v_pos;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n vec2 scaled_size_a = u_scale_a * u_pattern_size_a;\n vec2 scaled_size_b = u_scale_b * u_pattern_size_b;\n\n // the correct offset needs to be calculated.\n //\n // The offset depends on how many pixels are between the world origin and\n // the edge of the tile:\n // vec2 offset = mod(pixel_coord, size)\n //\n // At high zoom levels there are a ton of pixels between the world origin\n // and the edge of the tile. The glsl spec only guarantees 16 bits of\n // precision for highp floats. We need more than that.\n //\n // The pixel_coord is passed in as two 16 bit values:\n // pixel_coord_upper = floor(pixel_coord / 2^16)\n // pixel_coord_lower = mod(pixel_coord, 2^16)\n //\n // The offset is calculated in a series of steps that should preserve this precision:\n vec2 offset_a = mod(mod(mod(u_pixel_coord_upper, scaled_size_a) * 256.0, scaled_size_a) * 256.0 + u_pixel_coord_lower, scaled_size_a);\n vec2 offset_b = mod(mod(mod(u_pixel_coord_upper, scaled_size_b) * 256.0, scaled_size_b) * 256.0 + u_pixel_coord_lower, scaled_size_b);\n\n v_pos_a = (u_tile_units_to_pixels * a_pos + offset_a) / scaled_size_a;\n v_pos_b = (u_tile_units_to_pixels * a_pos + offset_b) / scaled_size_b;\n\n v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;\n}\n" - }, - pattern: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform float u_opacity;\nuniform vec2 u_pattern_tl_a;\nuniform vec2 u_pattern_br_a;\nuniform vec2 u_pattern_tl_b;\nuniform vec2 u_pattern_br_b;\nuniform float u_mix;\n\nuniform sampler2D u_image;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\nvoid main() {\n\n vec2 imagecoord = mod(v_pos_a, 1.0);\n vec2 pos = mix(u_pattern_tl_a, u_pattern_br_a, imagecoord);\n vec4 color1 = texture2D(u_image, pos);\n\n vec2 imagecoord_b = mod(v_pos_b, 1.0);\n vec2 pos2 = mix(u_pattern_tl_b, u_pattern_br_b, imagecoord_b);\n vec4 color2 = texture2D(u_image, pos2);\n\n gl_FragColor = mix(color1, color2, u_mix) * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform mat4 u_matrix;\nuniform vec2 u_pattern_size_a;\nuniform vec2 u_pattern_size_b;\nuniform vec2 u_pixel_coord_upper;\nuniform vec2 u_pixel_coord_lower;\nuniform float u_scale_a;\nuniform float u_scale_b;\nuniform float u_tile_units_to_pixels;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_pos_a;\nvarying vec2 v_pos_b;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n vec2 scaled_size_a = u_scale_a * u_pattern_size_a;\n vec2 scaled_size_b = u_scale_b * u_pattern_size_b;\n\n // the correct offset needs to be calculated.\n //\n // The offset depends on how many pixels are between the world origin and\n // the edge of the tile:\n // vec2 offset = mod(pixel_coord, size)\n //\n // At high zoom levels there are a ton of pixels between the world origin\n // and the edge of the tile. The glsl spec only guarantees 16 bits of\n // precision for highp floats. We need more than that.\n //\n // The pixel_coord is passed in as two 16 bit values:\n // pixel_coord_upper = floor(pixel_coord / 2^16)\n // pixel_coord_lower = mod(pixel_coord, 2^16)\n //\n // The offset is calculated in a series of steps that should preserve this precision:\n vec2 offset_a = mod(mod(mod(u_pixel_coord_upper, scaled_size_a) * 256.0, scaled_size_a) * 256.0 + u_pixel_coord_lower, scaled_size_a);\n vec2 offset_b = mod(mod(mod(u_pixel_coord_upper, scaled_size_b) * 256.0, scaled_size_b) * 256.0 + u_pixel_coord_lower, scaled_size_b);\n\n v_pos_a = (u_tile_units_to_pixels * a_pos + offset_a) / scaled_size_a;\n v_pos_b = (u_tile_units_to_pixels * a_pos + offset_b) / scaled_size_b;\n}\n" - }, - raster: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform float u_opacity0;\nuniform float u_opacity1;\nuniform sampler2D u_image0;\nuniform sampler2D u_image1;\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nuniform float u_brightness_low;\nuniform float u_brightness_high;\n\nuniform float u_saturation_factor;\nuniform float u_contrast_factor;\nuniform vec3 u_spin_weights;\n\nvoid main() {\n\n // read and cross-fade colors from the main and parent tiles\n vec4 color0 = texture2D(u_image0, v_pos0);\n vec4 color1 = texture2D(u_image1, v_pos1);\n vec4 color = color0 * u_opacity0 + color1 * u_opacity1;\n vec3 rgb = color.rgb;\n\n // spin\n rgb = vec3(\n dot(rgb, u_spin_weights.xyz),\n dot(rgb, u_spin_weights.zxy),\n dot(rgb, u_spin_weights.yzx));\n\n // saturation\n float average = (color.r + color.g + color.b) / 3.0;\n rgb += (average - rgb) * u_saturation_factor;\n\n // contrast\n rgb = (rgb - 0.5) * u_contrast_factor + 0.5;\n\n // brightness\n vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);\n vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);\n\n gl_FragColor = vec4(mix(u_high_vec, u_low_vec, rgb), color.a);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform mat4 u_matrix;\nuniform vec2 u_tl_parent;\nuniform float u_scale_parent;\nuniform float u_buffer_scale;\n\nattribute vec2 a_pos;\nattribute vec2 a_texture_pos;\n\nvarying vec2 v_pos0;\nvarying vec2 v_pos1;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n v_pos0 = (((a_texture_pos / 32767.0) - 0.5) / u_buffer_scale ) + 0.5;\n v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;\n}\n" - }, - icon: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform sampler2D u_texture;\nuniform sampler2D u_fadetexture;\nuniform lowp float u_opacity;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n lowp float alpha = texture2D(u_fadetexture, v_fade_tex).a * u_opacity;\n gl_FragColor = texture2D(u_texture, v_tex) * alpha;\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec2 a_texture_pos;\nattribute vec4 a_data;\n\n\n// matrix is for the vertex position.\nuniform mat4 u_matrix;\n\nuniform mediump float u_zoom;\nuniform bool u_rotate_with_map;\nuniform vec2 u_extrude_scale;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\n\nvoid main() {\n vec2 a_tex = a_texture_pos.xy;\n mediump float a_labelminzoom = a_data[0];\n mediump vec2 a_zoom = a_data.pq;\n mediump float a_minzoom = a_zoom[0];\n mediump float a_maxzoom = a_zoom[1];\n\n // u_zoom is the current zoom level adjusted for the change in font size\n mediump float z = 2.0 - step(a_minzoom, u_zoom) - (1.0 - step(a_maxzoom, u_zoom));\n\n vec2 extrude = u_extrude_scale * (a_offset / 64.0);\n if (u_rotate_with_map) {\n gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1);\n gl_Position.z += z * gl_Position.w;\n } else {\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n }\n\n v_tex = a_tex / u_texsize;\n v_fade_tex = vec2(a_labelminzoom / 255.0, 0.0);\n}\n" - }, - sdf: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform sampler2D u_texture;\nuniform sampler2D u_fadetexture;\nuniform lowp vec4 u_color;\nuniform lowp float u_opacity;\nuniform lowp float u_buffer;\nuniform lowp float u_gamma;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\nvarying float v_gamma_scale;\n\nvoid main() {\n lowp float dist = texture2D(u_texture, v_tex).a;\n lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a;\n lowp float gamma = u_gamma * v_gamma_scale;\n lowp float alpha = smoothstep(u_buffer - gamma, u_buffer + gamma, dist) * fade_alpha;\n\n gl_FragColor = u_color * (alpha * u_opacity);\n\n#ifdef OVERDRAW_INSPECTOR\n gl_FragColor = vec4(1.0);\n#endif\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nconst float PI = 3.141592653589793;\n\nattribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec2 a_texture_pos;\nattribute vec4 a_data;\n\n\n// matrix is for the vertex position.\nuniform mat4 u_matrix;\n\nuniform mediump float u_zoom;\nuniform bool u_rotate_with_map;\nuniform bool u_pitch_with_map;\nuniform mediump float u_pitch;\nuniform mediump float u_bearing;\nuniform mediump float u_aspect_ratio;\nuniform vec2 u_extrude_scale;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying vec2 v_fade_tex;\nvarying float v_gamma_scale;\n\nvoid main() {\n vec2 a_tex = a_texture_pos.xy;\n mediump float a_labelminzoom = a_data[0];\n mediump vec2 a_zoom = a_data.pq;\n mediump float a_minzoom = a_zoom[0];\n mediump float a_maxzoom = a_zoom[1];\n\n // u_zoom is the current zoom level adjusted for the change in font size\n mediump float z = 2.0 - step(a_minzoom, u_zoom) - (1.0 - step(a_maxzoom, u_zoom));\n\n // pitch-alignment: map\n // rotation-alignment: map | viewport\n if (u_pitch_with_map) {\n lowp float angle = u_rotate_with_map ? (a_data[1] / 256.0 * 2.0 * PI) : u_bearing;\n lowp float asin = sin(angle);\n lowp float acos = cos(angle);\n mat2 RotationMatrix = mat2(acos, asin, -1.0 * asin, acos);\n vec2 offset = RotationMatrix * a_offset;\n vec2 extrude = u_extrude_scale * (offset / 64.0);\n gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1);\n gl_Position.z += z * gl_Position.w;\n // pitch-alignment: viewport\n // rotation-alignment: map\n } else if (u_rotate_with_map) {\n // foreshortening factor to apply on pitched maps\n // as a label goes from horizontal <=> vertical in angle\n // it goes from 0% foreshortening to up to around 70% foreshortening\n lowp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75));\n\n lowp float lineangle = a_data[1] / 256.0 * 2.0 * PI;\n\n // use the lineangle to position points a,b along the line\n // project the points and calculate the label angle in projected space\n // this calculation allows labels to be rendered unskewed on pitched maps\n vec4 a = u_matrix * vec4(a_pos, 0, 1);\n vec4 b = u_matrix * vec4(a_pos + vec2(cos(lineangle),sin(lineangle)), 0, 1);\n lowp float angle = atan((b[1]/b[3] - a[1]/a[3])/u_aspect_ratio, b[0]/b[3] - a[0]/a[3]);\n lowp float asin = sin(angle);\n lowp float acos = cos(angle);\n mat2 RotationMatrix = mat2(acos, -1.0 * asin, asin, acos);\n\n vec2 offset = RotationMatrix * (vec2((1.0-pitchfactor)+(pitchfactor*cos(angle*2.0)), 1.0) * a_offset);\n vec2 extrude = u_extrude_scale * (offset / 64.0);\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n gl_Position.z += z * gl_Position.w;\n // pitch-alignment: viewport\n // rotation-alignment: viewport\n } else {\n vec2 extrude = u_extrude_scale * (a_offset / 64.0);\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);\n }\n\n v_gamma_scale = (gl_Position.w - 0.5);\n\n v_tex = a_tex / u_texsize;\n v_fade_tex = vec2(a_labelminzoom / 255.0, 0.0);\n}\n" - }, - collisionbox: { - fragmentSource: "#ifdef GL_ES\nprecision mediump float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nuniform float u_zoom;\nuniform float u_maxzoom;\n\nvarying float v_max_zoom;\nvarying float v_placement_zoom;\n\nvoid main() {\n\n float alpha = 0.5;\n\n gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0) * alpha;\n\n if (v_placement_zoom > u_zoom) {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha;\n }\n\n if (u_zoom >= v_max_zoom) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) * alpha * 0.25;\n }\n\n if (v_placement_zoom >= u_maxzoom) {\n gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0) * alpha * 0.2;\n }\n}\n", - vertexSource: "#ifdef GL_ES\nprecision highp float;\n#else\n#define lowp\n#define mediump\n#define highp\n#endif\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute vec2 a_data;\n\nuniform mat4 u_matrix;\nuniform float u_scale;\n\nvarying float v_max_zoom;\nvarying float v_placement_zoom;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos + a_extrude / u_scale, 0.0, 1.0);\n\n v_max_zoom = a_data.x;\n v_placement_zoom = a_data.y;\n}\n" - } -}; - -module.exports.util = "float evaluate_zoom_function_1(const vec4 values, const float t) {\n if (t < 1.0) {\n return mix(values[0], values[1], t);\n } else if (t < 2.0) {\n return mix(values[1], values[2], t - 1.0);\n } else {\n return mix(values[2], values[3], t - 2.0);\n }\n}\nvec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) {\n if (t < 1.0) {\n return mix(value0, value1, t);\n } else if (t < 2.0) {\n return mix(value1, value2, t - 1.0);\n } else {\n return mix(value2, value3, t - 2.0);\n }\n}\n"; - -},{"path":2}],44:[function(require,module,exports){ -'use strict'; - -var format = require('util').format; - -function ValidationError(key, value /*, message, ...*/) { - this.message = ( - (key ? key + ': ' : '') + - format.apply(format, Array.prototype.slice.call(arguments, 2)) - ); - - if (value !== null && value !== undefined && value.__line__) { - this.line = value.__line__; - } -} - -module.exports = ValidationError; - -},{"util":11}],45:[function(require,module,exports){ -'use strict'; - -module.exports = function (output) { - for (var i = 1; i < arguments.length; i++) { - var input = arguments[i]; - for (var k in input) { - output[k] = input[k]; - } - } - return output; -}; - -},{}],46:[function(require,module,exports){ -'use strict'; - -module.exports = 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; - } -}; - -},{}],47:[function(require,module,exports){ -'use strict'; - -// Turn jsonlint-lines-primitives objects into primitive objects -module.exports = function unbundle(value) { - if (value instanceof Number || value instanceof String || value instanceof Boolean) { - return value.valueOf(); - } else { - return value; - } -}; - -},{}],48:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var getType = require('../util/get_type'); -var extend = require('../util/extend'); - -// Main recursive validation function. Tracks: -// -// - key: string representing location of validation in style tree. Used only -// for more informative error reporting. -// - value: current value from style being evaluated. May be anything from a -// high level object that needs to be descended into deeper or a simple -// scalar value. -// - valueSpec: current spec being evaluated. Tracks value. - -module.exports = function validate(options) { - - var validateFunction = require('./validate_function'); - var validateObject = require('./validate_object'); - var VALIDATORS = { - '*': function() { - return []; - }, - 'array': require('./validate_array'), - 'boolean': require('./validate_boolean'), - 'number': require('./validate_number'), - 'color': require('./validate_color'), - 'constants': require('./validate_constants'), - 'enum': require('./validate_enum'), - 'filter': require('./validate_filter'), - 'function': require('./validate_function'), - 'layer': require('./validate_layer'), - 'object': require('./validate_object'), - 'source': require('./validate_source'), - 'string': require('./validate_string') - }; - - var value = options.value; - var valueSpec = options.valueSpec; - var key = options.key; - var styleSpec = options.styleSpec; - var style = options.style; - - if (getType(value) === 'string' && value[0] === '@') { - if (styleSpec.$version > 7) { - return [new ValidationError(key, value, 'constants have been deprecated as of v8')]; - } - if (!(value in style.constants)) { - return [new ValidationError(key, value, 'constant "%s" not found', value)]; - } - options = extend({}, options, { value: style.constants[value] }); - } - - if (valueSpec.function && getType(value) === 'object') { - return validateFunction(options); - - } else if (valueSpec.type && VALIDATORS[valueSpec.type]) { - return VALIDATORS[valueSpec.type](options); - - } else { - return validateObject(extend({}, options, { - valueSpec: valueSpec.type ? styleSpec[valueSpec.type] : valueSpec - })); - } -}; - -},{"../error/validation_error":44,"../util/extend":45,"../util/get_type":46,"./validate_array":49,"./validate_boolean":50,"./validate_color":51,"./validate_constants":52,"./validate_enum":53,"./validate_filter":54,"./validate_function":55,"./validate_layer":57,"./validate_number":59,"./validate_object":60,"./validate_source":62,"./validate_string":63}],49:[function(require,module,exports){ -'use strict'; - -var getType = require('../util/get_type'); -var validate = require('./validate'); -var ValidationError = require('../error/validation_error'); - -module.exports = 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, %s found', getType(array))]; - } - - if (arraySpec.length && array.length !== arraySpec.length) { - return [new ValidationError(key, array, 'array length %d expected, length %d found', arraySpec.length, array.length)]; - } - - if (arraySpec['min-length'] && array.length < arraySpec['min-length']) { - return [new ValidationError(key, array, 'array length at least %d expected, length %d found', arraySpec['min-length'], array.length)]; - } - - var arrayElementSpec = { - "type": arraySpec.value - }; - - 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; -}; - -},{"../error/validation_error":44,"../util/get_type":46,"./validate":48}],50:[function(require,module,exports){ -'use strict'; - -var getType = require('../util/get_type'); -var ValidationError = require('../error/validation_error'); - -module.exports = 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, %s found', type)]; - } - - return []; -}; - -},{"../error/validation_error":44,"../util/get_type":46}],51:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var getType = require('../util/get_type'); -var parseCSSColor = require('csscolorparser').parseCSSColor; - -module.exports = 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, %s found', type)]; - } - - if (parseCSSColor(value) === null) { - return [new ValidationError(key, value, 'color expected, "%s" found', value)]; - } - - return []; -}; - -},{"../error/validation_error":44,"../util/get_type":46,"csscolorparser":13}],52:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var getType = require('../util/get_type'); - -module.exports = function validateConstants(options) { - var key = options.key; - var constants = options.value; - var styleSpec = options.styleSpec; - - if (styleSpec.$version > 7) { - if (constants) { - return [new ValidationError(key, constants, 'constants have been deprecated as of v8')]; - } else { - return []; - } - } else { - var type = getType(constants); - if (type !== 'object') { - return [new ValidationError(key, constants, 'object expected, %s found', type)]; - } - - var errors = []; - for (var constantName in constants) { - if (constantName[0] !== '@') { - errors.push(new ValidationError(key + '.' + constantName, constants[constantName], 'constants must start with "@"')); - } - } - return errors; - } - -}; - -},{"../error/validation_error":44,"../util/get_type":46}],53:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var unbundle = require('../util/unbundle_jsonlint'); - -module.exports = function validateEnum(options) { - var key = options.key; - var value = options.value; - var valueSpec = options.valueSpec; - var errors = []; - - if (valueSpec.values.indexOf(unbundle(value)) === -1) { - errors.push(new ValidationError(key, value, 'expected one of [%s], %s found', valueSpec.values.join(', '), value)); - } - return errors; -}; - -},{"../error/validation_error":44,"../util/unbundle_jsonlint":47}],54:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var validateEnum = require('./validate_enum'); -var getType = require('../util/get_type'); -var unbundle = require('../util/unbundle_jsonlint'); - -module.exports = function validateFilter(options) { - var value = options.value; - var key = options.key; - var styleSpec = options.styleSpec; - var type; - - var errors = []; - - if (getType(value) !== 'array') { - return [new ValidationError(key, value, 'array expected, %s found', getType(value))]; - } - - 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 && value[1] == '$type') { - errors.push(new ValidationError(key, value, '"$type" cannot be use with operator "%s"', value[0])); - } - /* falls through */ - case '==': - case '!=': - if (value.length != 3) { - errors.push(new ValidationError(key, value, 'filter array for operator "%s" must have 3 elements', value[0])); - } - /* falls through */ - 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, %s found', type)); - } else if (value[1][0] === '@') { - errors.push(new ValidationError(key + '[1]', value[1], 'filter key cannot be a constant')); - } - } - for (var i = 2; i < value.length; i++) { - type = getType(value[i]); - if (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' && value[i][0] === '@') { - errors.push(new ValidationError(key + '[' + i + ']', value[i], 'filter value cannot be a constant')); - } else if (type !== 'string' && type !== 'number' && type !== 'boolean') { - errors.push(new ValidationError(key + '[' + i + ']', value[i], 'string, number, or boolean expected, %s found', type)); - } - } - break; - - case 'any': - case 'all': - case 'none': - for (i = 1; i < value.length; i++) { - errors = errors.concat(validateFilter({ - key: key + '[' + i + ']', - value: value[i], - 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 "%s" operator must have 2 elements', value[0])); - } else if (type !== 'string') { - errors.push(new ValidationError(key + '[1]', value[1], 'string expected, %s found', type)); - } else if (value[1][0] === '@') { - errors.push(new ValidationError(key + '[1]', value[1], 'filter key cannot be a constant')); - } - break; - - } - - return errors; -}; - -},{"../error/validation_error":44,"../util/get_type":46,"../util/unbundle_jsonlint":47,"./validate_enum":53}],55:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var getType = require('../util/get_type'); -var validate = require('./validate'); -var validateObject = require('./validate_object'); -var validateArray = require('./validate_array'); -var validateNumber = require('./validate_number'); - -module.exports = function validateFunction(options) { - var functionValueSpec = options.valueSpec; - var stopKeyType; - - var isPropertyFunction = options.value.property !== undefined || stopKeyType === 'object'; - var isZoomFunction = options.value.property === undefined || stopKeyType === 'object'; - - var errors = validateObject({ - key: options.key, - value: options.value, - valueSpec: options.styleSpec.function, - style: options.style, - styleSpec: options.styleSpec, - objectElementValidators: { stops: validateFunctionStops } - }); - - if (options.styleSpec.$version >= 8) { - if (isPropertyFunction && !options.valueSpec['property-function']) { - errors.push(new ValidationError(options.key, options.value, 'property functions not supported')); - } else if (isZoomFunction && !options.valueSpec['zoom-function']) { - errors.push(new ValidationError(options.key, options.value, 'zoom functions not supported')); - } - } - - return errors; - - function validateFunctionStops(options) { - 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, %s found', getType(value))]; - } - - if (value.length !== 2) { - return [new ValidationError(key, value, 'array length %d expected, length %d found', 2, value.length)]; - } - - var type = getType(value[0]); - if (!stopKeyType) stopKeyType = type; - if (type !== stopKeyType) { - return [new ValidationError(key, value, '%s stop key type must match previous stop key type %s', type, stopKeyType)]; - } - - if (type === 'object') { - 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')]; - } - errors = errors.concat(validateObject({ - key: key + '[0]', - value: value[0], - valueSpec: { zoom: {} }, - style: options.style, - styleSpec: options.styleSpec, - objectElementValidators: { zoom: validateNumber, value: validateValue } - })); - } else { - errors = errors.concat((isZoomFunction ? validateNumber : validateValue)({ - key: key + '[0]', - value: value[0], - valueSpec: {}, - style: options.style, - styleSpec: options.styleSpec - })); - } - - errors = errors.concat(validate({ - key: key + '[1]', - value: value[1], - valueSpec: functionValueSpec, - style: options.style, - styleSpec: options.styleSpec - })); - - if (getType(value[0]) === 'number') { - if (functionValueSpec.function === 'piecewise-constant' && value[0] % 1 !== 0) { - errors.push(new ValidationError(key + '[0]', value[0], 'zoom level for piecewise-constant functions must be an integer')); - } - - if (options.arrayIndex !== 0) { - if (value[0] < options.array[options.arrayIndex - 1][0]) { - errors.push(new ValidationError(key + '[0]', value[0], 'array stops must appear in ascending order')); - } - } - } - - return errors; - } - - function validateValue(options) { - var errors = []; - var type = getType(options.value); - if (type !== 'number' && type !== 'string' && type !== 'array') { - errors.push(new ValidationError(options.key, options.value, 'property value must be a number, string or array')); - } - return errors; - } - -}; - -},{"../error/validation_error":44,"../util/get_type":46,"./validate":48,"./validate_array":49,"./validate_number":59,"./validate_object":60}],56:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var validateString = require('./validate_string'); - -module.exports = function(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; -}; - -},{"../error/validation_error":44,"./validate_string":63}],57:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var unbundle = require('../util/unbundle_jsonlint'); -var validateObject = require('./validate_object'); -var validateFilter = require('./validate_filter'); -var validatePaintProperty = require('./validate_paint_property'); -var validateLayoutProperty = require('./validate_layout_property'); -var extend = require('../util/extend'); - -module.exports = 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) { - for (var i = 0; i < options.arrayIndex; i++) { - var otherLayer = style.layers[i]; - if (unbundle(otherLayer.id) === unbundle(layer.id)) { - errors.push(new ValidationError(key, layer.id, 'duplicate layer id "%s", previously used at line %d', layer.id, 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], '"%s" is prohibited for ref layers', p)); - } - }); - - var parent; - - style.layers.forEach(function(layer) { - if (layer.id == ref) parent = layer; - }); - - if (!parent) { - errors.push(new ValidationError(key, layer.ref, 'ref layer "%s" not found', ref)); - } 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]; - if (!source) { - errors.push(new ValidationError(key, layer.source, 'source "%s" not found', layer.source)); - } else if (source.type == 'vector' && type == 'raster') { - errors.push(new ValidationError(key, layer.source, 'layer "%s" requires a raster source', layer.id)); - } else if (source.type == 'raster' && type != 'raster') { - errors.push(new ValidationError(key, layer.source, 'layer "%s" requires a vector source', layer.id)); - } else if (source.type == 'vector' && !layer['source-layer']) { - errors.push(new ValidationError(key, layer, 'layer "%s" must specify a "source-layer"', layer.id)); - } - } - } - - errors = errors.concat(validateObject({ - key: key, - value: layer, - valueSpec: styleSpec.layer, - style: options.style, - styleSpec: options.styleSpec, - objectElementValidators: { - filter: validateFilter, - layout: function(options) { - return validateObject({ - layer: layer, - key: options.key, - value: options.value, - style: options.style, - styleSpec: options.styleSpec, - objectElementValidators: { - '*': function(options) { - return validateLayoutProperty(extend({layerType: type}, options)); - } - } - }); - }, - paint: function(options) { - return validateObject({ - layer: layer, - key: options.key, - value: options.value, - style: options.style, - styleSpec: options.styleSpec, - objectElementValidators: { - '*': function(options) { - return validatePaintProperty(extend({layerType: type}, options)); - } - } - }); - } - } - })); - - return errors; -}; - -},{"../error/validation_error":44,"../util/extend":45,"../util/unbundle_jsonlint":47,"./validate_filter":54,"./validate_layout_property":58,"./validate_object":60,"./validate_paint_property":61}],58:[function(require,module,exports){ -'use strict'; - -var validate = require('./validate'); -var ValidationError = require('../error/validation_error'); - -module.exports = function validateLayoutProperty(options) { - var key = options.key; - var style = options.style; - var styleSpec = options.styleSpec; - var value = options.value; - var propertyKey = options.objectKey; - var layerSpec = styleSpec['layout_' + options.layerType]; - - if (options.valueSpec || layerSpec[propertyKey]) { - var errors = []; - - if (options.layerType === 'symbol') { - if (propertyKey === 'icon-image' && style && !style.sprite) { - errors.push(new ValidationError(key, value, 'use of "icon-image" requires a style "sprite" property')); - } else if (propertyKey === 'text-field' && style && !style.glyphs) { - errors.push(new ValidationError(key, value, 'use of "text-field" requires a style "glyphs" property')); - } - } - - return errors.concat(validate({ - key: options.key, - value: value, - valueSpec: options.valueSpec || layerSpec[propertyKey], - style: style, - styleSpec: styleSpec - })); - - } else { - return [new ValidationError(key, value, 'unknown property "%s"', propertyKey)]; - } - -}; - -},{"../error/validation_error":44,"./validate":48}],59:[function(require,module,exports){ -'use strict'; - -var getType = require('../util/get_type'); -var ValidationError = require('../error/validation_error'); - -module.exports = 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, %s found', type)]; - } - - if ('minimum' in valueSpec && value < valueSpec.minimum) { - return [new ValidationError(key, value, '%s is less than the minimum value %s', value, valueSpec.minimum)]; - } - - if ('maximum' in valueSpec && value > valueSpec.maximum) { - return [new ValidationError(key, value, '%s is greater than the maximum value %s', value, valueSpec.maximum)]; - } - - return []; -}; - -},{"../error/validation_error":44,"../util/get_type":46}],60:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var getType = require('../util/get_type'); -var validate = require('./validate'); - -module.exports = function validateObject(options) { - var key = options.key; - var object = options.value; - var valueSpec = options.valueSpec; - var objectElementValidators = 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, %s found', type)]; - } - - for (var objectKey in object) { - var valueSpecKey = objectKey.split('.')[0]; // treat 'paint.*' as 'paint' - var objectElementSpec = valueSpec && (valueSpec[valueSpecKey] || valueSpec['*']); - var objectElementValidator = objectElementValidators[valueSpecKey] || objectElementValidators['*']; - - if (objectElementSpec || objectElementValidator) { - errors = errors.concat((objectElementValidator || validate)({ - key: (key ? key + '.' : key) + objectKey, - value: object[objectKey], - valueSpec: objectElementSpec, - style: style, - styleSpec: styleSpec, - object: object, - objectKey: objectKey - })); - - // tolerate root-level extra keys & arbitrary layer properties - // TODO remove this layer-specific logic - } else if (key !== '' && key.split('.').length !== 1) { - errors.push(new ValidationError(key, object[objectKey], 'unknown property "%s"', objectKey)); - } - } - - for (valueSpecKey in valueSpec) { - if (valueSpec[valueSpecKey].required && valueSpec[valueSpecKey]['default'] === undefined && object[valueSpecKey] === undefined) { - errors.push(new ValidationError(key, object, 'missing required property "%s"', valueSpecKey)); - } - } - - return errors; -}; - -},{"../error/validation_error":44,"../util/get_type":46,"./validate":48}],61:[function(require,module,exports){ -'use strict'; - -var validate = require('./validate'); -var ValidationError = require('../error/validation_error'); - -module.exports = function validatePaintProperty(options) { - var key = options.key; - var style = options.style; - var styleSpec = options.styleSpec; - var value = options.value; - var propertyKey = options.objectKey; - var layerSpec = styleSpec['paint_' + options.layerType]; - - var transitionMatch = propertyKey.match(/^(.*)-transition$/); - - if (transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) { - return validate({ - key: key, - value: value, - valueSpec: styleSpec.transition, - style: style, - styleSpec: styleSpec - }); - - } else if (options.valueSpec || layerSpec[propertyKey]) { - return validate({ - key: options.key, - value: value, - valueSpec: options.valueSpec || layerSpec[propertyKey], - style: style, - styleSpec: styleSpec - }); - - } else { - return [new ValidationError(key, value, 'unknown property "%s"', propertyKey)]; - } - -}; - -},{"../error/validation_error":44,"./validate":48}],62:[function(require,module,exports){ -'use strict'; - -var ValidationError = require('../error/validation_error'); -var unbundle = require('../util/unbundle_jsonlint'); -var validateObject = require('./validate_object'); -var validateEnum = require('./validate_enum'); - -module.exports = 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); - switch (type) { - case 'vector': - case 'raster': - var errors = []; - errors = errors.concat(validateObject({ - key: key, - value: value, - valueSpec: styleSpec.source_tile, - style: options.style, - styleSpec: styleSpec - })); - if ('url' in value) { - for (var prop in value) { - if (['type', 'url', 'tileSize'].indexOf(prop) < 0) { - errors.push(new ValidationError(key + '.' + prop, value[prop], 'a source with a "url" property may not include a "%s" property', prop)); - } - } - } - return errors; - - case 'geojson': - return validateObject({ - key: key, - value: value, - valueSpec: styleSpec.source_geojson, - style: style, - styleSpec: styleSpec - }); - - 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 - }); - - default: - return validateEnum({ - key: key + '.type', - value: value.type, - valueSpec: {values: ['vector', 'raster', 'geojson', 'video', 'image']}, - style: style, - styleSpec: styleSpec - }); - } -}; - -},{"../error/validation_error":44,"../util/unbundle_jsonlint":47,"./validate_enum":53,"./validate_object":60}],63:[function(require,module,exports){ -'use strict'; - -var getType = require('../util/get_type'); -var ValidationError = require('../error/validation_error'); - -module.exports = 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, %s found', type)]; - } - - return []; -}; - -},{"../error/validation_error":44,"../util/get_type":46}],64:[function(require,module,exports){ -'use strict'; - -var validateConstants = require('./validate/validate_constants'); -var validate = require('./validate/validate'); -var latestStyleSpec = require('../reference/latest.min'); -var validateGlyphsURL = require('./validate/validate_glyphs_url'); - -/** - * Validate a Mapbox GL style against the style specification. This entrypoint, - * `mapbox-gl-style-spec/lib/validate_style.min`, is designed to produce as - * small a browserify bundle as possible by omitting unnecessary functionality - * and legacy style specifications. - * - * @param {Object} style The style to be validated. - * @param {Object} [styleSpec] The style specification to validate against. - * If omitted, the latest style spec is used. - * @returns {Array} - * @example - * var validate = require('mapbox-gl-style-spec/lib/validate_style.min'); - * var errors = validate(style); - */ -function validateStyleMin(style, styleSpec) { - styleSpec = styleSpec || latestStyleSpec; - - var errors = []; - - errors = errors.concat(validate({ - key: '', - value: style, - valueSpec: styleSpec.$root, - styleSpec: styleSpec, - style: style, - objectElementValidators: { - glyphs: validateGlyphsURL - } - })); - - if (styleSpec.$version > 7 && style.constants) { - errors = errors.concat(validateConstants({ - key: 'constants', - value: style.constants, - style: style, - styleSpec: styleSpec - })); - } - - return sortErrors(errors); -} - -validateStyleMin.source = wrapCleanErrors(require('./validate/validate_source')); -validateStyleMin.layer = wrapCleanErrors(require('./validate/validate_layer')); -validateStyleMin.filter = wrapCleanErrors(require('./validate/validate_filter')); -validateStyleMin.paintProperty = wrapCleanErrors(require('./validate/validate_paint_property')); -validateStyleMin.layoutProperty = wrapCleanErrors(require('./validate/validate_layout_property')); - -function sortErrors(errors) { - return [].concat(errors).sort(function (a, b) { - return a.line - b.line; - }); -} - -function wrapCleanErrors(inner) { - return function() { - return sortErrors(inner.apply(this, arguments)); - }; -} - -module.exports = validateStyleMin; - -},{"../reference/latest.min":65,"./validate/validate":48,"./validate/validate_constants":52,"./validate/validate_filter":54,"./validate/validate_glyphs_url":56,"./validate/validate_layer":57,"./validate/validate_layout_property":58,"./validate/validate_paint_property":61,"./validate/validate_source":62}],65:[function(require,module,exports){ -module.exports = require('./v8.min.json'); - -},{"./v8.min.json":66}],66:[function(require,module,exports){ -module.exports={"$version":8,"$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"},"sources":{"required":true,"type":"sources"},"sprite":{"type":"string"},"glyphs":{"type":"string"},"transition":{"type":"transition"},"layers":{"required":true,"type":"array","value":"layer"}},"sources":{"*":{"type":"source"}},"source":["source_tile","source_geojson","source_video","source_image"],"source_tile":{"type":{"required":true,"type":"enum","values":["vector","raster"]},"url":{"type":"string"},"tiles":{"type":"array","value":"string"},"minzoom":{"type":"number","default":0},"maxzoom":{"type":"number","default":22},"tileSize":{"type":"number","default":512,"units":"pixels"},"*":{"type":"*"}},"source_geojson":{"type":{"required":true,"type":"enum","values":["geojson"]},"data":{"type":"*"},"maxzoom":{"type":"number","default":14},"buffer":{"type":"number","default":64},"tolerance":{"type":"number","default":3},"cluster":{"type":"boolean","default":false},"clusterRadius":{"type":"number","default":400},"clusterMaxZoom":{"type":"number"}},"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"}}},"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"}}},"layer":{"id":{"type":"string","required":true},"type":{"type":"enum","values":["fill","line","symbol","circle","raster","background"]},"metadata":{"type":"*"},"ref":{"type":"string"},"source":{"type":"string"},"source-layer":{"type":"string"},"minzoom":{"type":"number","minimum":0,"maximum":22},"maxzoom":{"type":"number","minimum":0,"maximum":22},"interactive":{"type":"boolean","default":false},"filter":{"type":"filter"},"layout":{"type":"layout"},"paint":{"type":"paint"},"paint.*":{"type":"paint"}},"layout":["layout_fill","layout_line","layout_circle","layout_symbol","layout_raster","layout_background"],"layout_background":{"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"layout_fill":{"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"layout_circle":{"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"layout_line":{"line-cap":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["butt","round","square"],"default":"butt"},"line-join":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["bevel","round","miter"],"default":"miter"},"line-miter-limit":{"type":"number","default":2,"function":"interpolated","zoom-function":true,"property-function":true,"requires":[{"line-join":"miter"}]},"line-round-limit":{"type":"number","default":1.05,"function":"interpolated","zoom-function":true,"property-function":true,"requires":[{"line-join":"round"}]},"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"layout_symbol":{"symbol-placement":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["point","line"],"default":"point"},"symbol-spacing":{"type":"number","default":250,"minimum":1,"function":"interpolated","zoom-function":true,"property-function":true,"units":"pixels","requires":[{"symbol-placement":"line"}]},"symbol-avoid-edges":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false},"icon-allow-overlap":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["icon-image"]},"icon-ignore-placement":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["icon-image"]},"icon-optional":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["icon-image","text-field"]},"icon-rotation-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"viewport","requires":["icon-image"]},"icon-size":{"type":"number","default":1,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"requires":["icon-image"]},"icon-text-fit":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":false,"values":["none","both","width","height"],"default":"none","requires":["icon-image","text-field"]},"icon-text-fit-padding":{"type":"array","value":"number","length":4,"default":[0,0,0,0],"units":"pixels","function":"interpolated","zoom-function":true,"property-function":true,"requires":["icon-image","icon-text-fit","text-field"]},"icon-image":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"tokens":true},"icon-rotate":{"type":"number","default":0,"period":360,"function":"interpolated","zoom-function":true,"property-function":true,"units":"degrees","requires":["icon-image"]},"icon-padding":{"type":"number","default":2,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"units":"pixels","requires":["icon-image"]},"icon-keep-upright":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":"line"}]},"icon-offset":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"requires":["icon-image"]},"text-pitch-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"requires":["text-field"]},"text-rotation-alignment":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"viewport","requires":["text-field"]},"text-field":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":"","tokens":true},"text-font":{"type":"array","value":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":["Open Sans Regular","Arial Unicode MS Regular"],"requires":["text-field"]},"text-size":{"type":"number","default":16,"minimum":0,"units":"pixels","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-max-width":{"type":"number","default":10,"minimum":0,"units":"em","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-line-height":{"type":"number","default":1.2,"units":"em","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-letter-spacing":{"type":"number","default":0,"units":"em","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-justify":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["left","center","right"],"default":"center","requires":["text-field"]},"text-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["center","left","right","top","bottom","top-left","top-right","bottom-left","bottom-right"],"default":"center","requires":["text-field"]},"text-max-angle":{"type":"number","default":45,"units":"degrees","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field",{"symbol-placement":"line"}]},"text-rotate":{"type":"number","default":0,"period":360,"units":"degrees","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-padding":{"type":"number","default":2,"minimum":0,"units":"pixels","function":"interpolated","zoom-function":true,"property-function":true,"requires":["text-field"]},"text-keep-upright":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":true,"requires":["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":"line"}]},"text-transform":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["none","uppercase","lowercase"],"default":"none","requires":["text-field"]},"text-offset":{"type":"array","value":"number","units":"ems","function":"interpolated","zoom-function":true,"property-function":true,"length":2,"default":[0,0],"requires":["text-field"]},"text-allow-overlap":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["text-field"]},"text-ignore-placement":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["text-field"]},"text-optional":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":false,"requires":["text-field","icon-image"]},"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"layout_raster":{"visibility":{"type":"enum","function":"piecewise-constant","zoom-function":true,"values":["visible","none"],"default":"visible"}},"filter":{"type":"array","value":"*"},"filter_operator":{"type":"enum","values":["==","!=",">",">=","<","<=","in","!in","all","any","none","has","!has"]},"geometry_type":{"type":"enum","values":["Point","LineString","Polygon"]},"color_operation":{"type":"enum","values":["lighten","saturate","spin","fade","mix"]},"function":{"stops":{"type":"array","required":true,"value":"function_stop"},"base":{"type":"number","default":1,"minimum":0},"property":{"type":"string","default":"$zoom"},"type":{"type":"enum","values":["exponential","interval","categorical"],"default":"exponential"}},"function_stop":{"type":"array","minimum":0,"maximum":22,"value":["number","color"],"length":2},"paint":["paint_fill","paint_line","paint_circle","paint_symbol","paint_raster","paint_background"],"paint_fill":{"fill-antialias":{"type":"boolean","function":"piecewise-constant","zoom-function":true,"property-function":true,"default":true},"fill-opacity":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"fill-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"fill-pattern"}]},"fill-outline-color":{"type":"color","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"fill-pattern"},{"fill-antialias":true}]},"fill-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"fill-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map","requires":["fill-translate"]},"fill-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"transition":true}},"paint_line":{"line-opacity":{"type":"number","function":"interpolated","zoom-function":true,"property-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"line-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":[{"!":"line-pattern"}]},"line-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map","requires":["line-translate"]},"line-width":{"type":"number","default":1,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-gap-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-offset":{"type":"number","default":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"line-dasharray":{"type":"array","value":"number","function":"piecewise-constant","zoom-function":true,"property-function":true,"minimum":0,"transition":true,"units":"line widths","requires":[{"!":"line-pattern"}]},"line-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"property-function":true,"transition":true}},"paint_circle":{"circle-radius":{"type":"number","default":5,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"circle-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-blur":{"type":"number","default":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true},"circle-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels"},"circle-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map","requires":["circle-translate"]},"circle-pitch-scale":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map"}},"paint_symbol":{"icon-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["icon-image"]},"icon-halo-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-halo-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["icon-image"]},"icon-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map","requires":["icon-image","icon-translate"]},"text-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-halo-color":{"type":"color","default":"rgba(0, 0, 0, 0)","function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"requires":["text-field"]},"text-halo-width":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-halo-blur":{"type":"number","default":0,"minimum":0,"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-translate":{"type":"array","value":"number","length":2,"default":[0,0],"function":"interpolated","zoom-function":true,"property-function":true,"transition":true,"units":"pixels","requires":["text-field"]},"text-translate-anchor":{"type":"enum","function":"piecewise-constant","zoom-function":true,"property-function":true,"values":["map","viewport"],"default":"map","requires":["text-field","text-translate"]}},"paint_raster":{"raster-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-hue-rotate":{"type":"number","default":0,"period":360,"function":"interpolated","zoom-function":true,"transition":true,"units":"degrees"},"raster-brightness-min":{"type":"number","function":"interpolated","zoom-function":true,"default":0,"minimum":0,"maximum":1,"transition":true},"raster-brightness-max":{"type":"number","function":"interpolated","zoom-function":true,"default":1,"minimum":0,"maximum":1,"transition":true},"raster-saturation":{"type":"number","default":0,"minimum":-1,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-contrast":{"type":"number","default":0,"minimum":-1,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true},"raster-fade-duration":{"type":"number","default":300,"minimum":0,"function":"interpolated","zoom-function":true,"transition":true,"units":"milliseconds"}},"paint_background":{"background-color":{"type":"color","default":"#000000","function":"interpolated","zoom-function":true,"transition":true,"requires":[{"!":"background-pattern"}]},"background-pattern":{"type":"string","function":"piecewise-constant","zoom-function":true,"transition":true},"background-opacity":{"type":"number","default":1,"minimum":0,"maximum":1,"function":"interpolated","zoom-function":true,"transition":true}},"transition":{"duration":{"type":"number","default":300,"minimum":0,"units":"milliseconds"},"delay":{"type":"number","default":0,"minimum":0,"units":"milliseconds"}}} -},{}],67:[function(require,module,exports){ -'use strict'; - -if (typeof module !== 'undefined' && module.exports) { - module.exports = isSupported; -} else if (window) { - window.mapboxgl = window.mapboxgl || {}; - window.mapboxgl.supported = isSupported; -} - -/** - * Test whether the current browser supports Mapbox GL JS - * @param {Object} options - * @param {boolean} [options.failIfMajorPerformanceCaveat=false] Return `false` - * if the performance of Mapbox GL JS would be dramatically worse than - * expected (i.e. a software renderer is would be used) - * @return {boolean} - */ -function isSupported(options) { - return !!( - isBrowser() && - isArraySupported() && - isFunctionSupported() && - isObjectSupported() && - isJSONSupported() && - isWorkerSupported() && - isUint8ClampedArraySupported() && - 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() { - return 'Worker' in window; -} - -// IE11 only supports `Uint8ClampedArray` as of version -// [KB2929437](https://support.microsoft.com/en-us/kb/2929437) -function isUint8ClampedArraySupported() { - return 'Uint8ClampedArray' in window; -} - -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) - ); - } -} - -},{}],68:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -module.exports = ArrayGroup; -function ArrayGroup(arrayTypes) { - var LayoutVertexArrayType = arrayTypes.layoutVertexArrayType; - this.layoutVertexArray = new LayoutVertexArrayType(); - var ElementArrayType = arrayTypes.elementArrayType; - if (ElementArrayType) - this.elementArray = new ElementArrayType(); - var ElementArrayType2 = arrayTypes.elementArrayType2; - if (ElementArrayType2) - this.elementArray2 = new ElementArrayType2(); - this.paintVertexArrays = util.mapObject(arrayTypes.paintVertexArrayTypes, function (PaintVertexArrayType) { - return new PaintVertexArrayType(); - }); -} -ArrayGroup.MAX_VERTEX_ARRAY_LENGTH = Math.pow(2, 16) - 1; -ArrayGroup.prototype.hasCapacityFor = function (numVertices) { - return this.layoutVertexArray.length + numVertices <= ArrayGroup.MAX_VERTEX_ARRAY_LENGTH; -}; -ArrayGroup.prototype.isEmpty = function () { - return this.layoutVertexArray.length === 0; -}; -ArrayGroup.prototype.trim = function () { - this.layoutVertexArray.trim(); - if (this.elementArray) { - this.elementArray.trim(); - } - if (this.elementArray2) { - this.elementArray2.trim(); - } - for (var layerName in this.paintVertexArrays) { - this.paintVertexArrays[layerName].trim(); - } -}; -ArrayGroup.prototype.serialize = function () { - return { - layoutVertexArray: this.layoutVertexArray.serialize(), - elementArray: this.elementArray && this.elementArray.serialize(), - elementArray2: this.elementArray2 && this.elementArray2.serialize(), - paintVertexArrays: util.mapObject(this.paintVertexArrays, function (array) { - return array.serialize(); - }) - }; -}; -ArrayGroup.prototype.getTransferables = function (transferables) { - transferables.push(this.layoutVertexArray.arrayBuffer); - if (this.elementArray) { - transferables.push(this.elementArray.arrayBuffer); - } - if (this.elementArray2) { - transferables.push(this.elementArray2.arrayBuffer); - } - for (var layerName in this.paintVertexArrays) { - transferables.push(this.paintVertexArrays[layerName].arrayBuffer); - } -}; -},{"../util/util":182}],69:[function(require,module,exports){ -'use strict'; -var featureFilter = require('feature-filter'); -var ArrayGroup = require('./array_group'); -var BufferGroup = require('./buffer_group'); -var util = require('../util/util'); -var StructArrayType = require('../util/struct_array'); -module.exports = Bucket; -Bucket.create = function (options) { - var Classes = { - fill: require('./bucket/fill_bucket'), - line: require('./bucket/line_bucket'), - circle: require('./bucket/circle_bucket'), - symbol: require('./bucket/symbol_bucket') - }; - return new Classes[options.layer.type](options); -}; -Bucket.EXTENT = 8192; -function Bucket(options) { - this.zoom = options.zoom; - this.overscaling = options.overscaling; - this.layer = options.layer; - this.childLayers = options.childLayers; - this.type = this.layer.type; - this.features = []; - this.id = this.layer.id; - this.index = options.index; - this.sourceLayer = this.layer.sourceLayer; - this.sourceLayerIndex = options.sourceLayerIndex; - this.minZoom = this.layer.minzoom; - this.maxZoom = this.layer.maxzoom; - this.paintAttributes = createPaintAttributes(this); - if (options.arrays) { - var programInterfaces = this.programInterfaces; - this.bufferGroups = util.mapObject(options.arrays, function (programArrayGroups, programName) { - var programInterface = programInterfaces[programName]; - var paintVertexArrayTypes = options.paintVertexArrayTypes[programName]; - return programArrayGroups.map(function (arrayGroup) { - return new BufferGroup(arrayGroup, { - layoutVertexArrayType: programInterface.layoutVertexArrayType.serialize(), - elementArrayType: programInterface.elementArrayType && programInterface.elementArrayType.serialize(), - elementArrayType2: programInterface.elementArrayType2 && programInterface.elementArrayType2.serialize(), - paintVertexArrayTypes: paintVertexArrayTypes - }); - }); - }); - } -} -Bucket.prototype.populateArrays = function () { - this.createArrays(); - this.recalculateStyleLayers(); - for (var i = 0; i < this.features.length; i++) { - this.addFeature(this.features[i]); - } - this.trimArrays(); -}; -Bucket.prototype.prepareArrayGroup = function (programName, numVertices) { - var groups = this.arrayGroups[programName]; - var currentGroup = groups.length && groups[groups.length - 1]; - if (!currentGroup || !currentGroup.hasCapacityFor(numVertices)) { - currentGroup = new ArrayGroup({ - layoutVertexArrayType: this.programInterfaces[programName].layoutVertexArrayType, - elementArrayType: this.programInterfaces[programName].elementArrayType, - elementArrayType2: this.programInterfaces[programName].elementArrayType2, - paintVertexArrayTypes: this.paintVertexArrayTypes[programName] - }); - currentGroup.index = groups.length; - groups.push(currentGroup); - } - return currentGroup; -}; -Bucket.prototype.createArrays = function () { - this.arrayGroups = {}; - this.paintVertexArrayTypes = {}; - for (var programName in this.programInterfaces) { - this.arrayGroups[programName] = []; - var paintVertexArrayTypes = this.paintVertexArrayTypes[programName] = {}; - var layerPaintAttributes = this.paintAttributes[programName]; - for (var layerName in layerPaintAttributes) { - paintVertexArrayTypes[layerName] = new Bucket.VertexArrayType(layerPaintAttributes[layerName].attributes); - } - } -}; -Bucket.prototype.destroy = function (gl) { - for (var programName in this.bufferGroups) { - var programBufferGroups = this.bufferGroups[programName]; - for (var i = 0; i < programBufferGroups.length; i++) { - programBufferGroups[i].destroy(gl); - } - } -}; -Bucket.prototype.trimArrays = function () { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - arrayGroups[i].trim(); - } - } -}; -Bucket.prototype.isEmpty = function () { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - if (!arrayGroups[i].isEmpty()) { - return false; - } - } - } - return true; -}; -Bucket.prototype.getTransferables = function (transferables) { - for (var programName in this.arrayGroups) { - var arrayGroups = this.arrayGroups[programName]; - for (var i = 0; i < arrayGroups.length; i++) { - arrayGroups[i].getTransferables(transferables); - } - } -}; -Bucket.prototype.setUniforms = function (gl, programName, program, layer, globalProperties) { - var uniforms = this.paintAttributes[programName][layer.id].uniforms; - for (var i = 0; i < uniforms.length; i++) { - var uniform = uniforms[i]; - var uniformLocation = program[uniform.name]; - gl['uniform' + uniform.components + 'fv'](uniformLocation, uniform.getValue(layer, globalProperties)); - } -}; -Bucket.prototype.serialize = function () { - return { - layerId: this.layer.id, - zoom: this.zoom, - arrays: util.mapObject(this.arrayGroups, function (programArrayGroups) { - return programArrayGroups.map(function (arrayGroup) { - return arrayGroup.serialize(); - }); - }), - paintVertexArrayTypes: util.mapObject(this.paintVertexArrayTypes, function (arrayTypes) { - return util.mapObject(arrayTypes, function (arrayType) { - return arrayType.serialize(); - }); - }), - childLayerIds: this.childLayers.map(function (layer) { - return layer.id; - }) - }; -}; -Bucket.prototype.createFilter = function () { - if (!this.filter) { - this.filter = featureFilter(this.layer.filter); - } -}; -var FAKE_ZOOM_HISTORY = { - lastIntegerZoom: Infinity, - lastIntegerZoomTime: 0, - lastZoom: 0 -}; -Bucket.prototype.recalculateStyleLayers = function () { - for (var i = 0; i < this.childLayers.length; i++) { - this.childLayers[i].recalculate(this.zoom, FAKE_ZOOM_HISTORY); - } -}; -Bucket.prototype.populatePaintArrays = function (interfaceName, globalProperties, featureProperties, startGroup, startIndex) { - for (var l = 0; l < this.childLayers.length; l++) { - var layer = this.childLayers[l]; - var groups = this.arrayGroups[interfaceName]; - for (var g = startGroup.index; g < groups.length; g++) { - var group = groups[g]; - var length = group.layoutVertexArray.length; - var paintArray = group.paintVertexArrays[layer.id]; - paintArray.resize(length); - var attributes = this.paintAttributes[interfaceName][layer.id].attributes; - for (var m = 0; m < attributes.length; m++) { - var attribute = attributes[m]; - var value = attribute.getValue(layer, globalProperties, featureProperties); - var multiplier = attribute.multiplier || 1; - var components = attribute.components || 1; - var start = g === startGroup.index ? startIndex : 0; - for (var i = start; i < length; i++) { - var vertex = paintArray.get(i); - for (var c = 0; c < components; c++) { - var memberName = components > 1 ? attribute.name + c : attribute.name; - vertex[memberName] = value[c] * multiplier; - } - } - } - } - } -}; -Bucket.VertexArrayType = function (members) { - return new StructArrayType({ - members: members, - alignment: 4 - }); -}; -Bucket.ElementArrayType = function (components) { - return new StructArrayType({ - members: [{ - type: 'Uint16', - name: 'vertices', - components: components || 3 - }] - }); -}; -function createPaintAttributes(bucket) { - var attributes = {}; - for (var interfaceName in bucket.programInterfaces) { - var layerPaintAttributes = attributes[interfaceName] = {}; - for (var c = 0; c < bucket.childLayers.length; c++) { - var childLayer = bucket.childLayers[c]; - layerPaintAttributes[childLayer.id] = { - attributes: [], - uniforms: [], - defines: [], - vertexPragmas: { - define: {}, - initialize: {} - }, - fragmentPragmas: { - define: {}, - initialize: {} - } - }; - } - var interface_ = bucket.programInterfaces[interfaceName]; - if (!interface_.paintAttributes) - continue; - var attributePrecision = '{precision}'; - var attributeType = '{type}'; - for (var i = 0; i < interface_.paintAttributes.length; i++) { - var attribute = interface_.paintAttributes[i]; - attribute.multiplier = attribute.multiplier || 1; - for (var j = 0; j < bucket.childLayers.length; j++) { - var layer = bucket.childLayers[j]; - var paintAttributes = layerPaintAttributes[layer.id]; - var attributeInputName = attribute.name; - var attributeInnerName = attribute.name.slice(2); - var attributeVaryingDefinition; - paintAttributes.fragmentPragmas.initialize[attributeInnerName] = ''; - if (layer.isPaintValueFeatureConstant(attribute.paintProperty)) { - paintAttributes.uniforms.push(attribute); - paintAttributes.fragmentPragmas.define[attributeInnerName] = paintAttributes.vertexPragmas.define[attributeInnerName] = [ - 'uniform', - attributePrecision, - attributeType, - attributeInputName - ].join(' ') + ';'; - paintAttributes.fragmentPragmas.initialize[attributeInnerName] = paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributePrecision, - attributeType, - attributeInnerName, - '=', - attributeInputName - ].join(' ') + ';\n'; - } else if (layer.isPaintValueZoomConstant(attribute.paintProperty)) { - paintAttributes.attributes.push(util.extend({}, attribute, { name: attributeInputName })); - attributeVaryingDefinition = [ - 'varying', - attributePrecision, - attributeType, - attributeInnerName - ].join(' ') + ';\n'; - var attributeAttributeDefinition = [ - paintAttributes.fragmentPragmas.define[attributeInnerName], - 'attribute', - attributePrecision, - attributeType, - attributeInputName - ].join(' ') + ';\n'; - paintAttributes.fragmentPragmas.define[attributeInnerName] = attributeVaryingDefinition; - paintAttributes.vertexPragmas.define[attributeInnerName] = attributeVaryingDefinition + attributeAttributeDefinition; - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - '=', - attributeInputName, - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - } else { - var tName = 'u_' + attributeInputName.slice(2) + '_t'; - var zoomLevels = layer.getPaintValueStopZoomLevels(attribute.paintProperty); - var numStops = 0; - while (numStops < zoomLevels.length && zoomLevels[numStops] < bucket.zoom) - numStops++; - var stopOffset = Math.max(0, Math.min(zoomLevels.length - 4, numStops - 2)); - var fourZoomLevels = []; - for (var s = 0; s < 4; s++) { - fourZoomLevels.push(zoomLevels[Math.min(stopOffset + s, zoomLevels.length - 1)]); - } - attributeVaryingDefinition = [ - 'varying', - attributePrecision, - attributeType, - attributeInnerName - ].join(' ') + ';\n'; - paintAttributes.vertexPragmas.define[attributeInnerName] = attributeVaryingDefinition + [ - 'uniform', - 'lowp', - 'float', - tName - ].join(' ') + ';\n'; - paintAttributes.fragmentPragmas.define[attributeInnerName] = attributeVaryingDefinition; - paintAttributes.uniforms.push(util.extend({}, attribute, { - name: tName, - getValue: createGetUniform(attribute, stopOffset), - components: 1 - })); - var components = attribute.components; - if (components === 1) { - paintAttributes.attributes.push(util.extend({}, attribute, { - getValue: createFunctionGetValue(attribute, fourZoomLevels), - isFunction: true, - components: components * 4 - })); - paintAttributes.vertexPragmas.define[attributeInnerName] += [ - 'attribute', - attributePrecision, - 'vec4', - attributeInputName - ].join(' ') + ';\n'; - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - '=', - 'evaluate_zoom_function_1(' + attributeInputName + ', ' + tName + ')', - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - } else { - var attributeInputNames = []; - for (var k = 0; k < 4; k++) { - attributeInputNames.push(attributeInputName + k); - paintAttributes.attributes.push(util.extend({}, attribute, { - getValue: createFunctionGetValue(attribute, [fourZoomLevels[k]]), - isFunction: true, - name: attributeInputName + k - })); - paintAttributes.vertexPragmas.define[attributeInnerName] += [ - 'attribute', - attributePrecision, - attributeType, - attributeInputName + k - ].join(' ') + ';\n'; - } - paintAttributes.vertexPragmas.initialize[attributeInnerName] = [ - attributeInnerName, - ' = ', - 'evaluate_zoom_function_4(' + attributeInputNames.join(', ') + ', ' + tName + ')', - '/', - attribute.multiplier.toFixed(1) - ].join(' ') + ';\n'; - } - } - } - } - } - return attributes; -} -function createFunctionGetValue(attribute, stopZoomLevels) { - return function (layer, globalProperties, featureProperties) { - if (stopZoomLevels.length === 1) { - return attribute.getValue(layer, util.extend({}, globalProperties, { zoom: stopZoomLevels[0] }), featureProperties); - } else { - var values = []; - for (var z = 0; z < stopZoomLevels.length; z++) { - var stopZoomLevel = stopZoomLevels[z]; - values.push(attribute.getValue(layer, util.extend({}, globalProperties, { zoom: stopZoomLevel }), featureProperties)[0]); - } - return values; - } - }; -} -function createGetUniform(attribute, stopOffset) { - return function (layer, globalProperties) { - var stopInterp = layer.getPaintInterpolationT(attribute.paintProperty, globalProperties.zoom); - return [Math.max(0, Math.min(4, stopInterp - stopOffset))]; - }; -} -},{"../util/struct_array":180,"../util/util":182,"./array_group":68,"./bucket/circle_bucket":70,"./bucket/fill_bucket":71,"./bucket/line_bucket":72,"./bucket/symbol_bucket":73,"./buffer_group":75,"feature-filter":15}],70:[function(require,module,exports){ -'use strict'; -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var EXTENT = Bucket.EXTENT; -module.exports = CircleBucket; -function CircleBucket() { - Bucket.apply(this, arguments); -} -CircleBucket.prototype = util.inherit(Bucket, {}); -CircleBucket.prototype.addCircleVertex = function (layoutVertexArray, x, y, extrudeX, extrudeY) { - return layoutVertexArray.emplaceBack(x * 2 + (extrudeX + 1) / 2, y * 2 + (extrudeY + 1) / 2); -}; -CircleBucket.prototype.programInterfaces = { - circle: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }]), - elementArrayType: new Bucket.ElementArrayType(), - paintAttributes: [ - { - name: 'a_color', - components: 4, - type: 'Uint8', - getValue: function (layer, globalProperties, featureProperties) { - return layer.getPaintValue('circle-color', globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'circle-color' - }, - { - name: 'a_radius', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function (layer, globalProperties, featureProperties) { - return [layer.getPaintValue('circle-radius', globalProperties, featureProperties)]; - }, - multiplier: 10, - paintProperty: 'circle-radius' - }, - { - name: 'a_blur', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function (layer, globalProperties, featureProperties) { - return [layer.getPaintValue('circle-blur', globalProperties, featureProperties)]; - }, - multiplier: 10, - paintProperty: 'circle-blur' - }, - { - name: 'a_opacity', - components: 1, - type: 'Uint16', - isLayerConstant: false, - getValue: function (layer, globalProperties, featureProperties) { - return [layer.getPaintValue('circle-opacity', globalProperties, featureProperties)]; - }, - multiplier: 255, - paintProperty: 'circle-opacity' - } - ] - } -}; -CircleBucket.prototype.addFeature = function (feature) { - var globalProperties = { zoom: this.zoom }; - var geometries = loadGeometry(feature); - var startGroup = this.prepareArrayGroup('circle', 0); - var startIndex = startGroup.layoutVertexArray.length; - for (var j = 0; j < geometries.length; j++) { - for (var k = 0; k < geometries[j].length; k++) { - var x = geometries[j][k].x; - var y = geometries[j][k].y; - if (x < 0 || x >= EXTENT || y < 0 || y >= EXTENT) - continue; - var group = this.prepareArrayGroup('circle', 4); - var layoutVertexArray = group.layoutVertexArray; - var index = this.addCircleVertex(layoutVertexArray, x, y, -1, -1); - this.addCircleVertex(layoutVertexArray, x, y, 1, -1); - this.addCircleVertex(layoutVertexArray, x, y, 1, 1); - this.addCircleVertex(layoutVertexArray, x, y, -1, 1); - group.elementArray.emplaceBack(index, index + 1, index + 2); - group.elementArray.emplaceBack(index, index + 3, index + 2); - } - } - this.populatePaintArrays('circle', globalProperties, feature.properties, startGroup, startIndex); -}; -},{"../../util/util":182,"../bucket":69,"../load_geometry":77}],71:[function(require,module,exports){ -'use strict'; -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var earcut = require('earcut'); -var classifyRings = require('../../util/classify_rings'); -var EARCUT_MAX_RINGS = 500; -module.exports = FillBucket; -function FillBucket() { - Bucket.apply(this, arguments); -} -FillBucket.prototype = util.inherit(Bucket, {}); -FillBucket.prototype.programInterfaces = { - fill: { - layoutVertexArrayType: new Bucket.VertexArrayType([{ - name: 'a_pos', - components: 2, - type: 'Int16' - }]), - elementArrayType: new Bucket.ElementArrayType(1), - elementArrayType2: new Bucket.ElementArrayType(2), - paintAttributes: [ - { - name: 'a_color', - components: 4, - type: 'Uint8', - getValue: function (layer, globalProperties, featureProperties) { - return layer.getPaintValue('fill-color', globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'fill-color' - }, - { - name: 'a_outline_color', - components: 4, - type: 'Uint8', - getValue: function (layer, globalProperties, featureProperties) { - return layer.getPaintValue('fill-outline-color', globalProperties, featureProperties); - }, - multiplier: 255, - paintProperty: 'fill-outline-color' - }, - { - name: 'a_opacity', - components: 1, - type: 'Uint8', - getValue: function (layer, globalProperties, featureProperties) { - return [layer.getPaintValue('fill-opacity', globalProperties, featureProperties)]; - }, - multiplier: 255, - paintProperty: 'fill-opacity' - } - ] - } -}; -FillBucket.prototype.addFeature = function (feature) { - var lines = loadGeometry(feature); - var polygons = classifyRings(lines, EARCUT_MAX_RINGS); - var startGroup = this.prepareArrayGroup('fill', 0); - var startIndex = startGroup.layoutVertexArray.length; - for (var i = 0; i < polygons.length; i++) { - this.addPolygon(polygons[i]); - } - this.populatePaintArrays('fill', { zoom: this.zoom }, feature.properties, startGroup, startIndex); -}; -FillBucket.prototype.addPolygon = function (polygon) { - var numVertices = 0; - for (var k = 0; k < polygon.length; k++) { - numVertices += polygon[k].length; - } - var group = this.prepareArrayGroup('fill', numVertices); - var flattened = []; - var holeIndices = []; - var startIndex = group.layoutVertexArray.length; - for (var r = 0; r < polygon.length; r++) { - var ring = polygon[r]; - if (r > 0) - holeIndices.push(flattened.length / 2); - for (var v = 0; v < ring.length; v++) { - var vertex = ring[v]; - var index = group.layoutVertexArray.emplaceBack(vertex.x, vertex.y); - if (v >= 1) { - group.elementArray2.emplaceBack(index - 1, index); - } - flattened.push(vertex.x); - flattened.push(vertex.y); - } - } - var triangleIndices = earcut(flattened, holeIndices); - for (var i = 0; i < triangleIndices.length; i++) { - group.elementArray.emplaceBack(triangleIndices[i] + startIndex); - } -}; -},{"../../util/classify_rings":170,"../../util/util":182,"../bucket":69,"../load_geometry":77,"earcut":14}],72:[function(require,module,exports){ -'use strict'; -var Bucket = require('../bucket'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var EXTENT = Bucket.EXTENT; -var EXTRUDE_SCALE = 63; -var COS_HALF_SHARP_CORNER = Math.cos(75 / 2 * (Math.PI / 180)); -var SHARP_CORNER_OFFSET = 15; -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; -module.exports = LineBucket; -function LineBucket() { - Bucket.apply(this, arguments); -} -LineBucket.prototype = util.inherit(Bucket, {}); -LineBucket.prototype.addLineVertex = function (layoutVertexBuffer, point, extrude, tx, ty, dir, linesofar) { - return layoutVertexBuffer.emplaceBack(point.x << 1 | tx, point.y << 1 | ty, Math.round(EXTRUDE_SCALE * extrude.x) + 128, Math.round(EXTRUDE_SCALE * extrude.y) + 128, (dir === 0 ? 0 : dir < 0 ? -1 : 1) + 1 | (linesofar * LINE_DISTANCE_SCALE & 63) << 2, linesofar * LINE_DISTANCE_SCALE >> 6); -}; -LineBucket.prototype.programInterfaces = { - line: { - layoutVertexArrayType: new Bucket.VertexArrayType([ - { - name: 'a_pos', - components: 2, - type: 'Int16' - }, - { - name: 'a_data', - components: 4, - type: 'Uint8' - } - ]), - elementArrayType: new Bucket.ElementArrayType() - } -}; -LineBucket.prototype.addFeature = function (feature) { - var lines = loadGeometry(feature, LINE_DISTANCE_BUFFER_BITS); - for (var i = 0; i < lines.length; i++) { - this.addLine(lines[i], this.layer.layout['line-join'], this.layer.layout['line-cap'], this.layer.layout['line-miter-limit'], this.layer.layout['line-round-limit']); - } -}; -LineBucket.prototype.addLine = function (vertices, join, cap, miterLimit, roundLimit) { - var len = vertices.length; - while (len > 2 && vertices[len - 1].equals(vertices[len - 2])) { - len--; - } - if (vertices.length < 2) - return; - if (join === 'bevel') - miterLimit = 1.05; - var sharpCornerOffset = SHARP_CORNER_OFFSET * (EXTENT / (512 * this.overscaling)); - var firstVertex = vertices[0], lastVertex = vertices[len - 1], closed = firstVertex.equals(lastVertex); - this.prepareArrayGroup('line', len * 10); - if (len === 2 && closed) - return; - this.distance = 0; - var beginCap = cap, endCap = closed ? 'butt' : cap, startOfLine = true, currentVertex, prevVertex, nextVertex, prevNormal, nextNormal, offsetA, offsetB; - this.e1 = this.e2 = this.e3 = -1; - if (closed) { - currentVertex = vertices[len - 2]; - nextNormal = firstVertex.sub(currentVertex)._unit()._perp(); - } - for (var i = 0; i < len; i++) { - nextVertex = closed && i === len - 1 ? vertices[1] : vertices[i + 1]; - if (nextVertex && vertices[i].equals(nextVertex)) - continue; - if (nextNormal) - prevNormal = nextNormal; - if (currentVertex) - prevVertex = currentVertex; - currentVertex = vertices[i]; - nextNormal = nextVertex ? nextVertex.sub(currentVertex)._unit()._perp() : prevNormal; - prevNormal = prevNormal || nextNormal; - var joinNormal = prevNormal.add(nextNormal)._unit(); - var cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y; - var miterLength = 1 / cosHalfAngle; - var isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex; - if (isSharpCorner && i > 0) { - var prevSegmentLength = currentVertex.dist(prevVertex); - if (prevSegmentLength > 2 * sharpCornerOffset) { - var newPrevVertex = currentVertex.sub(currentVertex.sub(prevVertex)._mult(sharpCornerOffset / prevSegmentLength)._round()); - this.distance += newPrevVertex.dist(prevVertex); - this.addCurrentVertex(newPrevVertex, this.distance, prevNormal.mult(1), 0, 0, false); - prevVertex = newPrevVertex; - } - } - var middleVertex = prevVertex && nextVertex; - var currentJoin = middleVertex ? join : nextVertex ? beginCap : endCap; - 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.distance += currentVertex.dist(prevVertex); - if (currentJoin === 'miter') { - joinNormal._mult(miterLength); - this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false); - } else if (currentJoin === 'flipbevel') { - if (miterLength > 100) { - joinNormal = nextNormal.clone(); - } else { - var direction = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0 ? -1 : 1; - var bevelLength = miterLength * prevNormal.add(nextNormal).mag() / prevNormal.sub(nextNormal).mag(); - joinNormal._perp()._mult(bevelLength * direction); - } - this.addCurrentVertex(currentVertex, this.distance, joinNormal, 0, 0, false); - this.addCurrentVertex(currentVertex, this.distance, joinNormal.mult(-1), 0, 0, false); - } else if (currentJoin === 'bevel' || currentJoin === 'fakeround') { - var lineTurnsLeft = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x > 0; - var offset = -Math.sqrt(miterLength * miterLength - 1); - if (lineTurnsLeft) { - offsetB = 0; - offsetA = offset; - } else { - offsetA = 0; - offsetB = offset; - } - if (!startOfLine) { - this.addCurrentVertex(currentVertex, this.distance, prevNormal, offsetA, offsetB, false); - } - if (currentJoin === 'fakeround') { - var n = Math.floor((0.5 - (cosHalfAngle - 0.5)) * 8); - var approxFractionalJoinNormal; - for (var m = 0; m < n; m++) { - approxFractionalJoinNormal = nextNormal.mult((m + 1) / (n + 1))._add(prevNormal)._unit(); - this.addPieSliceVertex(currentVertex, this.distance, approxFractionalJoinNormal, lineTurnsLeft); - } - this.addPieSliceVertex(currentVertex, this.distance, joinNormal, lineTurnsLeft); - for (var k = n - 1; k >= 0; k--) { - approxFractionalJoinNormal = prevNormal.mult((k + 1) / (n + 1))._add(nextNormal)._unit(); - this.addPieSliceVertex(currentVertex, this.distance, approxFractionalJoinNormal, lineTurnsLeft); - } - } - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -offsetA, -offsetB, false); - } - } else if (currentJoin === 'butt') { - if (!startOfLine) { - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false); - } - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false); - } - } else if (currentJoin === 'square') { - if (!startOfLine) { - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, false); - this.e1 = this.e2 = -1; - } - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, false); - } - } else if (currentJoin === 'round') { - if (!startOfLine) { - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 0, 0, false); - this.addCurrentVertex(currentVertex, this.distance, prevNormal, 1, 1, true); - this.e1 = this.e2 = -1; - } - if (nextVertex) { - this.addCurrentVertex(currentVertex, this.distance, nextNormal, -1, -1, true); - this.addCurrentVertex(currentVertex, this.distance, nextNormal, 0, 0, false); - } - } - if (isSharpCorner && i < len - 1) { - var nextSegmentLength = currentVertex.dist(nextVertex); - if (nextSegmentLength > 2 * sharpCornerOffset) { - var newCurrentVertex = currentVertex.add(nextVertex.sub(currentVertex)._mult(sharpCornerOffset / nextSegmentLength)._round()); - this.distance += newCurrentVertex.dist(currentVertex); - this.addCurrentVertex(newCurrentVertex, this.distance, nextNormal.mult(1), 0, 0, false); - currentVertex = newCurrentVertex; - } - } - startOfLine = false; - } -}; -LineBucket.prototype.addCurrentVertex = function (currentVertex, distance, normal, endLeft, endRight, round) { - var tx = round ? 1 : 0; - var extrude; - var arrayGroup = this.arrayGroups.line[this.arrayGroups.line.length - 1]; - var layoutVertexArray = arrayGroup.layoutVertexArray; - var elementArray = arrayGroup.elementArray; - extrude = normal.clone(); - if (endLeft) - extrude._sub(normal.perp()._mult(endLeft)); - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 0, endLeft, distance); - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - this.e1 = this.e2; - this.e2 = this.e3; - extrude = normal.mult(-1); - if (endRight) - extrude._sub(normal.perp()._mult(endRight)); - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 1, -endRight, distance); - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - this.e1 = this.e2; - this.e2 = this.e3; - if (distance > MAX_LINE_DISTANCE / 2) { - this.distance = 0; - this.addCurrentVertex(currentVertex, this.distance, normal, endLeft, endRight, round); - } -}; -LineBucket.prototype.addPieSliceVertex = function (currentVertex, distance, extrude, lineTurnsLeft) { - var ty = lineTurnsLeft ? 1 : 0; - extrude = extrude.mult(lineTurnsLeft ? -1 : 1); - var arrayGroup = this.arrayGroups.line[this.arrayGroups.line.length - 1]; - var layoutVertexArray = arrayGroup.layoutVertexArray; - var elementArray = arrayGroup.elementArray; - this.e3 = this.addLineVertex(layoutVertexArray, currentVertex, extrude, 0, ty, 0, distance); - if (this.e1 >= 0 && this.e2 >= 0) { - elementArray.emplaceBack(this.e1, this.e2, this.e3); - } - if (lineTurnsLeft) { - this.e2 = this.e3; - } else { - this.e1 = this.e3; - } -}; -},{"../../util/util":182,"../bucket":69,"../load_geometry":77}],73:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -var Bucket = require('../bucket'); -var Anchor = require('../../symbol/anchor'); -var getAnchors = require('../../symbol/get_anchors'); -var resolveTokens = require('../../util/token'); -var Quads = require('../../symbol/quads'); -var Shaping = require('../../symbol/shaping'); -var resolveText = require('../../symbol/resolve_text'); -var mergeLines = require('../../symbol/mergelines'); -var clipLine = require('../../symbol/clip_line'); -var util = require('../../util/util'); -var loadGeometry = require('../load_geometry'); -var CollisionFeature = require('../../symbol/collision_feature'); -var shapeText = Shaping.shapeText; -var shapeIcon = Shaping.shapeIcon; -var getGlyphQuads = Quads.getGlyphQuads; -var getIconQuads = Quads.getIconQuads; -var EXTENT = Bucket.EXTENT; -module.exports = SymbolBucket; -function SymbolBucket(options) { - Bucket.apply(this, arguments); - this.showCollisionBoxes = options.showCollisionBoxes; - this.overscaling = options.overscaling; - this.collisionBoxArray = options.collisionBoxArray; - this.symbolQuadsArray = options.symbolQuadsArray; - this.symbolInstancesArray = options.symbolInstancesArray; - this.sdfIcons = options.sdfIcons; - this.iconsNeedLinear = options.iconsNeedLinear; - this.adjustedTextSize = options.adjustedTextSize; - this.adjustedIconSize = options.adjustedIconSize; - this.fontstack = options.fontstack; -} -SymbolBucket.prototype = util.inherit(Bucket, {}); -SymbolBucket.prototype.serialize = function () { - var serialized = Bucket.prototype.serialize.apply(this); - serialized.sdfIcons = this.sdfIcons; - serialized.iconsNeedLinear = this.iconsNeedLinear; - serialized.adjustedTextSize = this.adjustedTextSize; - serialized.adjustedIconSize = this.adjustedIconSize; - serialized.fontstack = this.fontstack; - return serialized; -}; -var layoutVertexArrayType = new Bucket.VertexArrayType([ - { - name: 'a_pos', - components: 2, - type: 'Int16' - }, - { - name: 'a_offset', - components: 2, - type: 'Int16' - }, - { - name: 'a_texture_pos', - components: 2, - type: 'Uint16' - }, - { - name: 'a_data', - components: 4, - type: 'Uint8' - } -]); -var elementArrayType = new Bucket.ElementArrayType(); -function addVertex(array, x, y, ox, oy, tx, ty, minzoom, maxzoom, labelminzoom, labelangle) { - return array.emplaceBack(x, y, Math.round(ox * 64), Math.round(oy * 64), tx / 4, ty / 4, (labelminzoom || 0) * 10, labelangle, (minzoom || 0) * 10, Math.min(maxzoom || 25, 25) * 10); -} -SymbolBucket.prototype.addCollisionBoxVertex = function (layoutVertexArray, point, extrude, maxZoom, placementZoom) { - return layoutVertexArray.emplaceBack(point.x, point.y, Math.round(extrude.x), Math.round(extrude.y), maxZoom * 10, placementZoom * 10); -}; -SymbolBucket.prototype.programInterfaces = { - glyph: { - layoutVertexArrayType: layoutVertexArrayType, - elementArrayType: elementArrayType - }, - icon: { - layoutVertexArrayType: layoutVertexArrayType, - elementArrayType: elementArrayType - }, - collisionBox: { - layoutVertexArrayType: new Bucket.VertexArrayType([ - { - name: 'a_pos', - components: 2, - type: 'Int16' - }, - { - name: 'a_extrude', - components: 2, - type: 'Int16' - }, - { - name: 'a_data', - components: 2, - type: 'Uint8' - } - ]) - } -}; -SymbolBucket.prototype.populateArrays = function (collisionTile, stacks, icons) { - var zoomHistory = { - lastIntegerZoom: Infinity, - lastIntegerZoomTime: 0, - lastZoom: 0 - }; - this.adjustedTextMaxSize = this.layer.getLayoutValue('text-size', { - zoom: 18, - zoomHistory: zoomHistory - }); - this.adjustedTextSize = this.layer.getLayoutValue('text-size', { - zoom: this.zoom + 1, - zoomHistory: zoomHistory - }); - this.adjustedIconMaxSize = this.layer.getLayoutValue('icon-size', { - zoom: 18, - zoomHistory: zoomHistory - }); - this.adjustedIconSize = this.layer.getLayoutValue('icon-size', { - zoom: this.zoom + 1, - zoomHistory: zoomHistory - }); - var tileSize = 512 * this.overscaling; - this.tilePixelRatio = EXTENT / tileSize; - this.compareText = {}; - this.iconsNeedLinear = false; - this.symbolInstancesStartIndex = this.symbolInstancesArray.length; - var layout = this.layer.layout; - var features = this.features; - var textFeatures = this.textFeatures; - var horizontalAlign = 0.5, verticalAlign = 0.5; - switch (layout['text-anchor']) { - case 'right': - case 'top-right': - case 'bottom-right': - horizontalAlign = 1; - break; - case 'left': - case 'top-left': - case 'bottom-left': - horizontalAlign = 0; - break; - } - switch (layout['text-anchor']) { - case 'bottom': - case 'bottom-right': - case 'bottom-left': - verticalAlign = 1; - break; - case 'top': - case 'top-right': - case 'top-left': - verticalAlign = 0; - break; - } - var justify = layout['text-justify'] === 'right' ? 1 : layout['text-justify'] === 'left' ? 0 : 0.5; - var oneEm = 24; - var lineHeight = layout['text-line-height'] * oneEm; - var maxWidth = layout['symbol-placement'] !== 'line' ? layout['text-max-width'] * oneEm : 0; - var spacing = layout['text-letter-spacing'] * oneEm; - var textOffset = [ - layout['text-offset'][0] * oneEm, - layout['text-offset'][1] * oneEm - ]; - var fontstack = this.fontstack = layout['text-font'].join(','); - var geometries = []; - for (var g = 0; g < features.length; g++) { - geometries.push(loadGeometry(features[g])); - } - if (layout['symbol-placement'] === 'line') { - var merged = mergeLines(features, textFeatures, geometries); - geometries = merged.geometries; - features = merged.features; - textFeatures = merged.textFeatures; - } - var shapedText, shapedIcon; - for (var k = 0; k < features.length; k++) { - if (!geometries[k]) - continue; - if (textFeatures[k]) { - shapedText = shapeText(textFeatures[k], stacks[fontstack], maxWidth, lineHeight, horizontalAlign, verticalAlign, justify, spacing, textOffset); - } else { - shapedText = null; - } - if (layout['icon-image']) { - var iconName = resolveTokens(features[k].properties, layout['icon-image']); - var image = icons[iconName]; - shapedIcon = shapeIcon(image, layout); - if (image) { - if (this.sdfIcons === undefined) { - this.sdfIcons = image.sdf; - } else if (this.sdfIcons !== image.sdf) { - util.warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer'); - } - if (image.pixelRatio !== 1) { - this.iconsNeedLinear = true; - } else if (layout['icon-rotate'] !== 0 || !this.layer.isLayoutValueFeatureConstant('icon-rotate')) { - this.iconsNeedLinear = true; - } - } - } else { - shapedIcon = null; - } - if (shapedText || shapedIcon) { - this.addFeature(geometries[k], shapedText, shapedIcon, features[k]); - } - } - this.symbolInstancesEndIndex = this.symbolInstancesArray.length; - this.placeFeatures(collisionTile, this.showCollisionBoxes); - this.trimArrays(); -}; -SymbolBucket.prototype.addFeature = function (lines, shapedText, shapedIcon, feature) { - var layout = this.layer.layout; - var glyphSize = 24; - var fontScale = this.adjustedTextSize / glyphSize, textMaxSize = this.adjustedTextMaxSize !== undefined ? this.adjustedTextMaxSize : this.adjustedTextSize, textBoxScale = this.tilePixelRatio * fontScale, textMaxBoxScale = this.tilePixelRatio * textMaxSize / glyphSize, iconBoxScale = this.tilePixelRatio * this.adjustedIconSize, symbolMinDistance = this.tilePixelRatio * layout['symbol-spacing'], avoidEdges = layout['symbol-avoid-edges'], textPadding = layout['text-padding'] * this.tilePixelRatio, iconPadding = layout['icon-padding'] * this.tilePixelRatio, textMaxAngle = layout['text-max-angle'] / 180 * Math.PI, textAlongLine = layout['text-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line', iconAlongLine = layout['icon-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line', mayOverlap = layout['text-allow-overlap'] || layout['icon-allow-overlap'] || layout['text-ignore-placement'] || layout['icon-ignore-placement'], isLine = layout['symbol-placement'] === 'line', textRepeatDistance = symbolMinDistance / 2; - if (isLine) { - lines = clipLine(lines, 0, 0, EXTENT, EXTENT); - } - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - var anchors; - if (isLine) { - anchors = getAnchors(line, symbolMinDistance, textMaxAngle, shapedText, shapedIcon, glyphSize, textMaxBoxScale, this.overscaling, EXTENT); - } else { - anchors = [new Anchor(line[0].x, line[0].y, 0)]; - } - for (var j = 0, len = anchors.length; j < len; j++) { - var anchor = anchors[j]; - if (shapedText && isLine) { - if (this.anchorIsTooClose(shapedText.text, textRepeatDistance, anchor)) { - continue; - } - } - var inside = !(anchor.x < 0 || anchor.x > EXTENT || anchor.y < 0 || anchor.y > EXTENT); - if (avoidEdges && !inside) - continue; - var addToBuffers = inside || mayOverlap; - this.addSymbolInstance(anchor, line, shapedText, shapedIcon, this.layer, addToBuffers, this.symbolInstancesArray.length, this.collisionBoxArray, feature.index, this.sourceLayerIndex, this.index, textBoxScale, textPadding, textAlongLine, iconBoxScale, iconPadding, iconAlongLine, { zoom: this.zoom }, feature.properties); - } - } -}; -SymbolBucket.prototype.anchorIsTooClose = function (text, repeatDistance, anchor) { - var compareText = this.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; -}; -SymbolBucket.prototype.placeFeatures = function (collisionTile, showCollisionBoxes) { - this.recalculateStyleLayers(); - this.createArrays(); - var layout = this.layer.layout; - var maxScale = collisionTile.maxScale; - var textAlongLine = layout['text-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line'; - var iconAlongLine = layout['icon-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line'; - var mayOverlap = layout['text-allow-overlap'] || layout['icon-allow-overlap'] || layout['text-ignore-placement'] || layout['icon-ignore-placement']; - if (mayOverlap) { - var symbolInstancesStructTypeArray = this.symbolInstancesArray.toArray(this.symbolInstancesStartIndex, this.symbolInstancesEndIndex); - var angle = collisionTile.angle; - var sin = Math.sin(angle), cos = Math.cos(angle); - this.sortedSymbolInstances = symbolInstancesStructTypeArray.sort(function (a, b) { - var aRotated = sin * a.anchorPointX + cos * a.anchorPointY | 0; - var bRotated = sin * b.anchorPointX + cos * b.anchorPointY | 0; - return aRotated - bRotated || b.index - a.index; - }); - } - for (var p = this.symbolInstancesStartIndex; p < this.symbolInstancesEndIndex; p++) { - var symbolInstance = this.sortedSymbolInstances ? this.sortedSymbolInstances[p - this.symbolInstancesStartIndex] : this.symbolInstancesArray.get(p); - var textCollisionFeature = { - boxStartIndex: symbolInstance.textBoxStartIndex, - boxEndIndex: symbolInstance.textBoxEndIndex - }; - var iconCollisionFeature = { - boxStartIndex: symbolInstance.iconBoxStartIndex, - boxEndIndex: symbolInstance.iconBoxEndIndex - }; - var hasText = !(symbolInstance.textBoxStartIndex === symbolInstance.textBoxEndIndex); - var hasIcon = !(symbolInstance.iconBoxStartIndex === symbolInstance.iconBoxEndIndex); - var iconWithoutText = layout['text-optional'] || !hasText, textWithoutIcon = layout['icon-optional'] || !hasIcon; - var glyphScale = hasText ? collisionTile.placeCollisionFeature(textCollisionFeature, layout['text-allow-overlap'], layout['symbol-avoid-edges']) : collisionTile.minScale; - var iconScale = hasIcon ? collisionTile.placeCollisionFeature(iconCollisionFeature, layout['icon-allow-overlap'], layout['symbol-avoid-edges']) : collisionTile.minScale; - if (!iconWithoutText && !textWithoutIcon) { - iconScale = glyphScale = Math.max(iconScale, glyphScale); - } else if (!textWithoutIcon && glyphScale) { - glyphScale = Math.max(iconScale, glyphScale); - } else if (!iconWithoutText && iconScale) { - iconScale = Math.max(iconScale, glyphScale); - } - if (hasText) { - collisionTile.insertCollisionFeature(textCollisionFeature, glyphScale, layout['text-ignore-placement']); - if (glyphScale <= maxScale) { - this.addSymbols('glyph', symbolInstance.glyphQuadStartIndex, symbolInstance.glyphQuadEndIndex, glyphScale, layout['text-keep-upright'], textAlongLine, collisionTile.angle); - } - } - if (hasIcon) { - collisionTile.insertCollisionFeature(iconCollisionFeature, iconScale, layout['icon-ignore-placement']); - if (iconScale <= maxScale) { - this.addSymbols('icon', symbolInstance.iconQuadStartIndex, symbolInstance.iconQuadEndIndex, iconScale, layout['icon-keep-upright'], iconAlongLine, collisionTile.angle); - } - } - } - if (showCollisionBoxes) - this.addToDebugBuffers(collisionTile); -}; -SymbolBucket.prototype.addSymbols = function (programName, quadsStart, quadsEnd, scale, keepUpright, alongLine, placementAngle) { - var group = this.prepareArrayGroup(programName, 4 * (quadsEnd - quadsStart)); - var elementArray = group.elementArray; - var layoutVertexArray = group.layoutVertexArray; - var zoom = this.zoom; - var placementZoom = Math.max(Math.log(scale) / Math.LN2 + zoom, 0); - for (var k = quadsStart; k < quadsEnd; k++) { - var symbol = this.symbolQuadsArray.get(k).SymbolQuad; - var a = (symbol.anchorAngle + placementAngle + Math.PI) % (Math.PI * 2); - if (keepUpright && alongLine && (a <= Math.PI / 2 || a > Math.PI * 3 / 2)) - continue; - var tl = symbol.tl, tr = symbol.tr, bl = symbol.bl, br = symbol.br, tex = symbol.tex, anchorPoint = symbol.anchorPoint, minZoom = Math.max(zoom + Math.log(symbol.minScale) / Math.LN2, placementZoom), maxZoom = Math.min(zoom + Math.log(symbol.maxScale) / Math.LN2, 25); - if (maxZoom <= minZoom) - continue; - if (minZoom === placementZoom) - minZoom = 0; - var glyphAngle = Math.round(symbol.glyphAngle / (Math.PI * 2) * 256); - var index = addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle); - addVertex(layoutVertexArray, anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle); - elementArray.emplaceBack(index, index + 1, index + 2); - elementArray.emplaceBack(index + 1, index + 2, index + 3); - } -}; -SymbolBucket.prototype.updateIcons = function (icons) { - this.recalculateStyleLayers(); - var iconValue = this.layer.layout['icon-image']; - if (!iconValue) - return; - for (var i = 0; i < this.features.length; i++) { - var iconName = resolveTokens(this.features[i].properties, iconValue); - if (iconName) - icons[iconName] = true; - } -}; -SymbolBucket.prototype.updateFont = function (stacks) { - this.recalculateStyleLayers(); - var fontName = this.layer.layout['text-font'], stack = stacks[fontName] = stacks[fontName] || {}; - this.textFeatures = resolveText(this.features, this.layer.layout, stack); -}; -SymbolBucket.prototype.addToDebugBuffers = function (collisionTile) { - var group = this.prepareArrayGroup('collisionBox', 0); - var layoutVertexArray = group.layoutVertexArray; - var angle = -collisionTile.angle; - var yStretch = collisionTile.yStretch; - for (var j = this.symbolInstancesStartIndex; j < this.symbolInstancesEndIndex; j++) { - var symbolInstance = this.symbolInstancesArray.get(j); - symbolInstance.textCollisionFeature = { - boxStartIndex: symbolInstance.textBoxStartIndex, - boxEndIndex: symbolInstance.textBoxEndIndex - }; - symbolInstance.iconCollisionFeature = { - boxStartIndex: symbolInstance.iconBoxStartIndex, - boxEndIndex: symbolInstance.iconBoxEndIndex - }; - for (var i = 0; i < 2; i++) { - var feature = symbolInstance[i === 0 ? 'textCollisionFeature' : 'iconCollisionFeature']; - if (!feature) - continue; - for (var b = feature.boxStartIndex; b < feature.boxEndIndex; b++) { - var box = this.collisionBoxArray.get(b); - var anchorPoint = box.anchorPoint; - var tl = new Point(box.x1, box.y1 * yStretch)._rotate(angle); - var tr = new Point(box.x2, box.y1 * yStretch)._rotate(angle); - var bl = new Point(box.x1, box.y2 * yStretch)._rotate(angle); - var br = new Point(box.x2, box.y2 * yStretch)._rotate(angle); - var maxZoom = Math.max(0, Math.min(25, this.zoom + Math.log(box.maxScale) / Math.LN2)); - var placementZoom = Math.max(0, Math.min(25, this.zoom + Math.log(box.placementScale) / Math.LN2)); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tr, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tr, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, br, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, br, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, bl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, bl, maxZoom, placementZoom); - this.addCollisionBoxVertex(layoutVertexArray, anchorPoint, tl, maxZoom, placementZoom); - } - } - } -}; -SymbolBucket.prototype.addSymbolInstance = function (anchor, line, shapedText, shapedIcon, layer, addToBuffers, index, collisionBoxArray, featureIndex, sourceLayerIndex, bucketIndex, textBoxScale, textPadding, textAlongLine, iconBoxScale, iconPadding, iconAlongLine, globalProperties, featureProperties) { - var glyphQuadStartIndex, glyphQuadEndIndex, iconQuadStartIndex, iconQuadEndIndex, textCollisionFeature, iconCollisionFeature, glyphQuads, iconQuads; - if (shapedText) { - glyphQuads = addToBuffers ? getGlyphQuads(anchor, shapedText, textBoxScale, line, layer, textAlongLine) : []; - textCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedText, textBoxScale, textPadding, textAlongLine, false); - } - glyphQuadStartIndex = this.symbolQuadsArray.length; - if (glyphQuads && glyphQuads.length) { - for (var i = 0; i < glyphQuads.length; i++) { - this.addSymbolQuad(glyphQuads[i]); - } - } - glyphQuadEndIndex = this.symbolQuadsArray.length; - var textBoxStartIndex = textCollisionFeature ? textCollisionFeature.boxStartIndex : this.collisionBoxArray.length; - var textBoxEndIndex = textCollisionFeature ? textCollisionFeature.boxEndIndex : this.collisionBoxArray.length; - if (shapedIcon) { - iconQuads = addToBuffers ? getIconQuads(anchor, shapedIcon, iconBoxScale, line, layer, iconAlongLine, shapedText, globalProperties, featureProperties) : []; - iconCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, iconAlongLine, true); - } - iconQuadStartIndex = this.symbolQuadsArray.length; - if (iconQuads && iconQuads.length === 1) { - this.addSymbolQuad(iconQuads[0]); - } - iconQuadEndIndex = this.symbolQuadsArray.length; - var iconBoxStartIndex = iconCollisionFeature ? iconCollisionFeature.boxStartIndex : this.collisionBoxArray.length; - var iconBoxEndIndex = iconCollisionFeature ? iconCollisionFeature.boxEndIndex : this.collisionBoxArray.length; - return this.symbolInstancesArray.emplaceBack(textBoxStartIndex, textBoxEndIndex, iconBoxStartIndex, iconBoxEndIndex, glyphQuadStartIndex, glyphQuadEndIndex, iconQuadStartIndex, iconQuadEndIndex, anchor.x, anchor.y, index); -}; -SymbolBucket.prototype.addSymbolQuad = function (symbolQuad) { - return this.symbolQuadsArray.emplaceBack(symbolQuad.anchorPoint.x, symbolQuad.anchorPoint.y, symbolQuad.tl.x, symbolQuad.tl.y, symbolQuad.tr.x, symbolQuad.tr.y, symbolQuad.bl.x, symbolQuad.bl.y, symbolQuad.br.x, symbolQuad.br.y, symbolQuad.tex.h, symbolQuad.tex.w, symbolQuad.tex.x, symbolQuad.tex.y, symbolQuad.anchorAngle, symbolQuad.glyphAngle, symbolQuad.maxScale, symbolQuad.minScale); -}; -},{"../../symbol/anchor":131,"../../symbol/clip_line":133,"../../symbol/collision_feature":135,"../../symbol/get_anchors":137,"../../symbol/mergelines":140,"../../symbol/quads":141,"../../symbol/resolve_text":142,"../../symbol/shaping":143,"../../util/token":181,"../../util/util":182,"../bucket":69,"../load_geometry":77,"point-geometry":187}],74:[function(require,module,exports){ -'use strict'; -module.exports = Buffer; -function Buffer(array, arrayType, type) { - this.arrayBuffer = array.arrayBuffer; - this.length = array.length; - this.attributes = arrayType.members; - this.itemSize = arrayType.bytesPerElement; - this.type = type; - this.arrayType = arrayType; -} -Buffer.prototype.bind = function (gl) { - var type = gl[this.type]; - if (!this.buffer) { - this.buffer = gl.createBuffer(); - gl.bindBuffer(type, this.buffer); - gl.bufferData(type, this.arrayBuffer, gl.STATIC_DRAW); - this.arrayBuffer = null; - } else { - gl.bindBuffer(type, this.buffer); - } -}; -var AttributeType = { - Int8: 'BYTE', - Uint8: 'UNSIGNED_BYTE', - Int16: 'SHORT', - Uint16: 'UNSIGNED_SHORT' -}; -Buffer.prototype.setVertexAttribPointers = function (gl, program) { - for (var j = 0; j < this.attributes.length; j++) { - var member = this.attributes[j]; - var attribIndex = program[member.name]; - if (attribIndex !== undefined) { - gl.vertexAttribPointer(attribIndex, member.components, gl[AttributeType[member.type]], false, this.arrayType.bytesPerElement, member.offset); - } - } -}; -Buffer.prototype.destroy = function (gl) { - if (this.buffer) { - gl.deleteBuffer(this.buffer); - } -}; -Buffer.BufferType = { - VERTEX: 'ARRAY_BUFFER', - ELEMENT: 'ELEMENT_ARRAY_BUFFER' -}; -},{}],75:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var Buffer = require('./buffer'); -var VertexArrayObject = require('../render/vertex_array_object'); -module.exports = BufferGroup; -function BufferGroup(arrayGroup, arrayTypes) { - this.layoutVertexBuffer = new Buffer(arrayGroup.layoutVertexArray, arrayTypes.layoutVertexArrayType, Buffer.BufferType.VERTEX); - if (arrayGroup.elementArray) { - this.elementBuffer = new Buffer(arrayGroup.elementArray, arrayTypes.elementArrayType, Buffer.BufferType.ELEMENT); - } - var vaos = this.vaos = {}; - var secondVaos; - if (arrayGroup.elementArray2) { - this.elementBuffer2 = new Buffer(arrayGroup.elementArray2, arrayTypes.elementArrayType2, Buffer.BufferType.ELEMENT); - secondVaos = this.secondVaos = {}; - } - this.paintVertexBuffers = util.mapObject(arrayGroup.paintVertexArrays, function (array, name) { - vaos[name] = new VertexArrayObject(); - if (arrayGroup.elementArray2) { - secondVaos[name] = new VertexArrayObject(); - } - return new Buffer(array, arrayTypes.paintVertexArrayTypes[name], Buffer.BufferType.VERTEX); - }); -} -BufferGroup.prototype.destroy = function (gl) { - this.layoutVertexBuffer.destroy(gl); - if (this.elementBuffer) { - this.elementBuffer.destroy(gl); - } - if (this.elementBuffer2) { - this.elementBuffer2.destroy(gl); - } - for (var n in this.paintVertexBuffers) { - this.paintVertexBuffers[n].destroy(gl); - } - for (var j in this.vaos) { - this.vaos[j].destroy(gl); - } - for (var k in this.secondVaos) { - this.secondVaos[k].destroy(gl); - } -}; -},{"../render/vertex_array_object":97,"../util/util":182,"./buffer":74}],76:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -var loadGeometry = require('./load_geometry'); -var EXTENT = require('./bucket').EXTENT; -var featureFilter = require('feature-filter'); -var StructArrayType = require('../util/struct_array'); -var Grid = require('grid-index'); -var DictionaryCoder = require('../util/dictionary_coder'); -var vt = require('vector-tile'); -var Protobuf = require('pbf'); -var GeoJSONFeature = require('../util/vectortile_to_geojson'); -var arraysIntersect = require('../util/util').arraysIntersect; -var intersection = require('../util/intersection_tests'); -var multiPolygonIntersectsBufferedMultiPoint = intersection.multiPolygonIntersectsBufferedMultiPoint; -var multiPolygonIntersectsMultiPolygon = intersection.multiPolygonIntersectsMultiPolygon; -var multiPolygonIntersectsBufferedMultiLine = intersection.multiPolygonIntersectsBufferedMultiLine; -var FeatureIndexArray = new StructArrayType({ - members: [ - { - type: 'Uint32', - name: 'featureIndex' - }, - { - type: 'Uint16', - name: 'sourceLayerIndex' - }, - { - type: 'Uint16', - name: 'bucketIndex' - } - ] -}); -module.exports = FeatureIndex; -function FeatureIndex(coord, overscaling, collisionTile) { - if (coord.grid) { - var serialized = coord; - var rawTileData = overscaling; - coord = serialized.coord; - overscaling = serialized.overscaling; - this.grid = new Grid(serialized.grid); - this.featureIndexArray = new FeatureIndexArray(serialized.featureIndexArray); - this.rawTileData = rawTileData; - this.bucketLayerIDs = serialized.bucketLayerIDs; - } else { - this.grid = new Grid(EXTENT, 16, 0); - this.featureIndexArray = new FeatureIndexArray(); - } - this.coord = coord; - this.overscaling = overscaling; - this.x = coord.x; - this.y = coord.y; - this.z = coord.z - Math.log(overscaling) / Math.LN2; - this.setCollisionTile(collisionTile); -} -FeatureIndex.prototype.insert = function (feature, featureIndex, sourceLayerIndex, bucketIndex) { - var key = this.featureIndexArray.length; - this.featureIndexArray.emplaceBack(featureIndex, sourceLayerIndex, bucketIndex); - var geometry = loadGeometry(feature); - 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); - } - this.grid.insert(key, bbox[0], bbox[1], bbox[2], bbox[3]); - } -}; -FeatureIndex.prototype.setCollisionTile = function (collisionTile) { - this.collisionTile = collisionTile; -}; -FeatureIndex.prototype.serialize = function () { - var data = { - coord: this.coord, - overscaling: this.overscaling, - grid: this.grid.toArrayBuffer(), - featureIndexArray: this.featureIndexArray.serialize(), - bucketLayerIDs: this.bucketLayerIDs - }; - return { - data: data, - transferables: [ - data.grid, - data.featureIndexArray.arrayBuffer - ] - }; -}; -function translateDistance(translate) { - return Math.sqrt(translate[0] * translate[0] + translate[1] * translate[1]); -} -FeatureIndex.prototype.query = function (args, styleLayers) { - if (!this.vtLayers) { - this.vtLayers = new vt.VectorTile(new Protobuf(new Uint8Array(this.rawTileData))).layers; - this.sourceLayerCoder = new DictionaryCoder(this.vtLayers ? Object.keys(this.vtLayers).sort() : ['_geojsonTileLayer']); - } - var result = {}; - var params = args.params || {}, pixelsToTileUnits = EXTENT / args.tileSize / args.scale, filter = featureFilter(params.filter); - var additionalRadius = 0; - for (var id in styleLayers) { - var styleLayer = styleLayers[id]; - var paint = styleLayer.paint; - var styleLayerDistance = 0; - if (styleLayer.type === 'line') { - styleLayerDistance = getLineWidth(paint) / 2 + Math.abs(paint['line-offset']) + translateDistance(paint['line-translate']); - } else if (styleLayer.type === 'fill') { - styleLayerDistance = translateDistance(paint['fill-translate']); - } else if (styleLayer.type === 'circle') { - styleLayerDistance = paint['circle-radius'] + translateDistance(paint['circle-translate']); - } - additionalRadius = Math.max(additionalRadius, styleLayerDistance * pixelsToTileUnits); - } - var queryGeometry = args.queryGeometry.map(function (q) { - return q.map(function (p) { - return new Point(p.x, p.y); - }); - }); - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - for (var i = 0; i < queryGeometry.length; i++) { - var ring = queryGeometry[i]; - for (var k = 0; k < ring.length; k++) { - var p = ring[k]; - 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 matching = this.grid.query(minX - additionalRadius, minY - additionalRadius, maxX + additionalRadius, maxY + additionalRadius); - matching.sort(topDownFeatureComparator); - this.filterMatching(result, matching, this.featureIndexArray, queryGeometry, filter, params.layers, styleLayers, args.bearing, pixelsToTileUnits); - var matchingSymbols = this.collisionTile.queryRenderedSymbols(minX, minY, maxX, maxY, args.scale); - matchingSymbols.sort(); - this.filterMatching(result, matchingSymbols, this.collisionTile.collisionBoxArray, queryGeometry, filter, params.layers, styleLayers, args.bearing, pixelsToTileUnits); - return result; -}; -function topDownFeatureComparator(a, b) { - return b - a; -} -function getLineWidth(paint) { - if (paint['line-gap-width'] > 0) { - return paint['line-gap-width'] + 2 * paint['line-width']; - } else { - return paint['line-width']; - } -} -FeatureIndex.prototype.filterMatching = function (result, matching, array, queryGeometry, filter, filterLayerIDs, styleLayers, bearing, pixelsToTileUnits) { - var previousIndex; - for (var k = 0; k < matching.length; k++) { - var index = matching[k]; - if (index === previousIndex) - continue; - previousIndex = index; - var match = array.get(index); - var layerIDs = this.bucketLayerIDs[match.bucketIndex]; - if (filterLayerIDs && !arraysIntersect(filterLayerIDs, layerIDs)) - continue; - var sourceLayerName = this.sourceLayerCoder.decode(match.sourceLayerIndex); - var sourceLayer = this.vtLayers[sourceLayerName]; - var feature = sourceLayer.feature(match.featureIndex); - if (!filter(feature)) - continue; - var geometry = null; - 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 translatedPolygon; - if (styleLayer.type !== 'symbol') { - if (!geometry) - geometry = loadGeometry(feature); - var paint = styleLayer.paint; - if (styleLayer.type === 'line') { - translatedPolygon = translate(queryGeometry, paint['line-translate'], paint['line-translate-anchor'], bearing, pixelsToTileUnits); - var halfWidth = getLineWidth(paint) / 2 * pixelsToTileUnits; - if (paint['line-offset']) { - geometry = offsetLine(geometry, paint['line-offset'] * pixelsToTileUnits); - } - if (!multiPolygonIntersectsBufferedMultiLine(translatedPolygon, geometry, halfWidth)) - continue; - } else if (styleLayer.type === 'fill') { - translatedPolygon = translate(queryGeometry, paint['fill-translate'], paint['fill-translate-anchor'], bearing, pixelsToTileUnits); - if (!multiPolygonIntersectsMultiPolygon(translatedPolygon, geometry)) - continue; - } else if (styleLayer.type === 'circle') { - translatedPolygon = translate(queryGeometry, paint['circle-translate'], paint['circle-translate-anchor'], bearing, pixelsToTileUnits); - var circleRadius = paint['circle-radius'] * pixelsToTileUnits; - if (!multiPolygonIntersectsBufferedMultiPoint(translatedPolygon, geometry, circleRadius)) - continue; - } - } - var geojsonFeature = new GeoJSONFeature(feature, this.z, this.x, this.y); - geojsonFeature.layer = styleLayer.serialize({ includeRefProperties: true }); - var layerResult = result[layerID]; - if (layerResult === undefined) { - layerResult = result[layerID] = []; - } - layerResult.push(geojsonFeature); - } - } -}; -function translate(queryGeometry, translate, translateAnchor, bearing, pixelsToTileUnits) { - if (!translate[0] && !translate[1]) { - return queryGeometry; - } - translate = Point.convert(translate); - if (translateAnchor === 'viewport') { - translate._rotate(-bearing); - } - var translated = []; - for (var i = 0; i < queryGeometry.length; i++) { - var ring = queryGeometry[i]; - var translatedRing = []; - for (var k = 0; k < ring.length; k++) { - translatedRing.push(ring[k].sub(translate._mult(pixelsToTileUnits))); - } - translated.push(translatedRing); - } - return translated; -} -function offsetLine(rings, offset) { - var newRings = []; - var zero = new Point(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; -} -},{"../util/dictionary_coder":172,"../util/intersection_tests":177,"../util/struct_array":180,"../util/util":182,"../util/vectortile_to_geojson":183,"./bucket":69,"./load_geometry":77,"feature-filter":15,"grid-index":36,"pbf":186,"point-geometry":187,"vector-tile":193}],77:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var EXTENT = require('./bucket').EXTENT; -function createBounds(bits) { - return { - min: -1 * Math.pow(2, bits - 1), - max: Math.pow(2, bits - 1) - 1 - }; -} -var boundsLookup = { - 15: createBounds(15), - 16: createBounds(16) -}; -module.exports = function loadGeometry(feature, bits) { - var bounds = boundsLookup[bits || 16]; - 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) { - util.warnOnce('Geometry exceeds allowed extent, reduce your vector tile buffer size'); - } - } - } - return geometry; -}; -},{"../util/util":182,"./bucket":69}],78:[function(require,module,exports){ -'use strict'; -module.exports = Coordinate; -function Coordinate(column, row, zoom) { - this.column = column; - this.row = row; - this.zoom = zoom; -} -Coordinate.prototype = { - clone: function () { - return new Coordinate(this.column, this.row, this.zoom); - }, - zoomTo: function (zoom) { - return this.clone()._zoomTo(zoom); - }, - sub: function (c) { - return this.clone()._sub(c); - }, - _zoomTo: function (zoom) { - var scale = Math.pow(2, zoom - this.zoom); - this.column *= scale; - this.row *= scale; - this.zoom = zoom; - return this; - }, - _sub: function (c) { - c = c.zoomTo(this.zoom); - this.column -= c.column; - this.row -= c.row; - return this; - } -}; -},{}],79:[function(require,module,exports){ -'use strict'; -module.exports = LngLat; -var wrap = require('../util/util').wrap; -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 () { - return new LngLat(wrap(this.lng, -180, 180), this.lat); -}; -LngLat.prototype.toArray = function () { - return [ - this.lng, - this.lat - ]; -}; -LngLat.prototype.toString = function () { - return 'LngLat(' + this.lng + ', ' + this.lat + ')'; -}; -LngLat.convert = function (input) { - if (input instanceof LngLat) { - return input; - } - if (Array.isArray(input)) { - return new LngLat(input[0], input[1]); - } - return input; -}; -},{"../util/util":182}],80:[function(require,module,exports){ -'use strict'; -module.exports = LngLatBounds; -var LngLat = require('./lng_lat'); -function LngLatBounds(sw, ne) { - if (!sw) { - return; - } else if (ne) { - this.extend(sw).extend(ne); - } else if (sw.length === 4) { - this.extend([ - sw[0], - sw[1] - ]).extend([ - sw[2], - sw[3] - ]); - } else { - this.extend(sw[0]).extend(sw[1]); - } -} -LngLatBounds.prototype = { - extend: function (obj) { - var sw = this._sw, ne = this._ne, 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 { - return obj ? this.extend(LngLat.convert(obj) || LngLatBounds.convert(obj)) : 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; - }, - getCenter: function () { - return new LngLat((this._sw.lng + this._ne.lng) / 2, (this._sw.lat + this._ne.lat) / 2); - }, - getSouthWest: function () { - return this._sw; - }, - getNorthEast: function () { - return this._ne; - }, - getNorthWest: function () { - return new LngLat(this.getWest(), this.getNorth()); - }, - getSouthEast: function () { - return new LngLat(this.getEast(), this.getSouth()); - }, - getWest: function () { - return this._sw.lng; - }, - getSouth: function () { - return this._sw.lat; - }, - getEast: function () { - return this._ne.lng; - }, - getNorth: function () { - return this._ne.lat; - }, - toArray: function () { - return [ - this._sw.toArray(), - this._ne.toArray() - ]; - }, - toString: function () { - return 'LngLatBounds(' + this._sw.toString() + ', ' + this._ne.toString() + ')'; - } -}; -LngLatBounds.convert = function (input) { - if (!input || input instanceof LngLatBounds) - return input; - return new LngLatBounds(input); -}; -},{"./lng_lat":79}],81:[function(require,module,exports){ -'use strict'; -var LngLat = require('./lng_lat'), Point = require('point-geometry'), Coordinate = require('./coordinate'), wrap = require('../util/util').wrap, interp = require('../util/interpolate'), TileCoord = require('../source/tile_coord'), EXTENT = require('../data/bucket').EXTENT, glmatrix = require('gl-matrix'); -var vec4 = glmatrix.vec4, mat4 = glmatrix.mat4, mat2 = glmatrix.mat2; -module.exports = Transform; -function Transform(minZoom, maxZoom) { - this.tileSize = 512; - this._minZoom = minZoom || 0; - this._maxZoom = maxZoom || 22; - this.latRange = [ - -85.05113, - 85.05113 - ]; - this.width = 0; - this.height = 0; - this._center = new LngLat(0, 0); - this.zoom = 0; - this.angle = 0; - this._altitude = 1.5; - this._pitch = 0; - this._unmodified = true; -} -Transform.prototype = { - get minZoom() { - return this._minZoom; - }, - set minZoom(zoom) { - if (this._minZoom === zoom) - return; - this._minZoom = zoom; - this.zoom = Math.max(this.zoom, zoom); - }, - get maxZoom() { - return this._maxZoom; - }, - set maxZoom(zoom) { - if (this._maxZoom === zoom) - return; - this._maxZoom = zoom; - this.zoom = Math.min(this.zoom, zoom); - }, - get worldSize() { - return this.tileSize * this.scale; - }, - get centerPoint() { - return this.size._div(2); - }, - get size() { - return new Point(this.width, this.height); - }, - get bearing() { - return -this.angle / Math.PI * 180; - }, - set bearing(bearing) { - var b = -wrap(bearing, -180, 180) * Math.PI / 180; - if (this.angle === b) - return; - this._unmodified = false; - this.angle = b; - this._calcMatrices(); - this.rotationMatrix = mat2.create(); - mat2.rotate(this.rotationMatrix, this.rotationMatrix, this.angle); - }, - get pitch() { - return this._pitch / Math.PI * 180; - }, - set pitch(pitch) { - var p = Math.min(60, pitch) / 180 * Math.PI; - if (this._pitch === p) - return; - this._unmodified = false; - this._pitch = p; - this._calcMatrices(); - }, - get altitude() { - return this._altitude; - }, - set altitude(altitude) { - var a = Math.max(0.75, altitude); - if (this._altitude === a) - return; - this._unmodified = false; - this._altitude = a; - this._calcMatrices(); - }, - get zoom() { - return this._zoom; - }, - set zoom(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._calcMatrices(); - this._constrain(); - }, - get center() { - return this._center; - }, - set center(center) { - if (center.lat === this._center.lat && center.lng === this._center.lng) - return; - this._unmodified = false; - this._center = center; - this._calcMatrices(); - this._constrain(); - }, - coveringZoomLevel: function (options) { - return (options.roundZoom ? Math.round : Math.floor)(this.zoom + this.scaleZoom(this.tileSize / options.tileSize)); - }, - coveringTiles: function (options) { - var z = this.coveringZoomLevel(options); - var actualZ = z; - if (z < options.minzoom) - return []; - if (z > options.maxzoom) - z = options.maxzoom; - var tr = this, tileCenter = tr.locationCoordinate(tr.center)._zoomTo(z), centerPoint = new Point(tileCenter.column - 0.5, tileCenter.row - 0.5); - return TileCoord.cover(z, [ - tr.pointCoordinate(new Point(0, 0))._zoomTo(z), - tr.pointCoordinate(new Point(tr.width, 0))._zoomTo(z), - tr.pointCoordinate(new Point(tr.width, tr.height))._zoomTo(z), - tr.pointCoordinate(new Point(0, tr.height))._zoomTo(z) - ], options.reparseOverscaled ? actualZ : z).sort(function (a, b) { - return centerPoint.dist(a) - centerPoint.dist(b); - }); - }, - resize: function (width, height) { - this.width = width; - this.height = height; - this.pixelsToGLUnits = [ - 2 / width, - -2 / height - ]; - this._calcMatrices(); - this._constrain(); - }, - get unmodified() { - return this._unmodified; - }, - zoomScale: function (zoom) { - return Math.pow(2, zoom); - }, - scaleZoom: function (scale) { - return Math.log(scale) / Math.LN2; - }, - project: function (lnglat, worldSize) { - return new Point(this.lngX(lnglat.lng, worldSize), this.latY(lnglat.lat, worldSize)); - }, - unproject: function (point, worldSize) { - return new LngLat(this.xLng(point.x, worldSize), this.yLat(point.y, worldSize)); - }, - get x() { - return this.lngX(this.center.lng); - }, - get y() { - return this.latY(this.center.lat); - }, - get point() { - return new Point(this.x, this.y); - }, - lngX: function (lng, worldSize) { - return (180 + lng) * (worldSize || this.worldSize) / 360; - }, - latY: function (lat, worldSize) { - var y = 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)); - return (180 - y) * (worldSize || this.worldSize) / 360; - }, - xLng: function (x, worldSize) { - return x * 360 / (worldSize || this.worldSize) - 180; - }, - yLat: function (y, worldSize) { - var y2 = 180 - y * 360 / (worldSize || this.worldSize); - return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90; - }, - panBy: function (offset) { - var point = this.centerPoint._add(offset); - this.center = this.pointLocation(point); - }, - setLocationAtPoint: function (lnglat, point) { - var c = this.locationCoordinate(lnglat); - var coordAtPoint = this.pointCoordinate(point); - var coordCenter = this.pointCoordinate(this.centerPoint); - var translate = coordAtPoint._sub(c); - this._unmodified = false; - this.center = this.coordinateLocation(coordCenter._sub(translate)); - }, - locationPoint: function (lnglat) { - return this.coordinatePoint(this.locationCoordinate(lnglat)); - }, - pointLocation: function (p) { - return this.coordinateLocation(this.pointCoordinate(p)); - }, - locationCoordinate: function (lnglat) { - var k = this.zoomScale(this.tileZoom) / this.worldSize, ll = LngLat.convert(lnglat); - return new Coordinate(this.lngX(ll.lng) * k, this.latY(ll.lat) * k, this.tileZoom); - }, - coordinateLocation: function (coord) { - var worldSize = this.zoomScale(coord.zoom); - return new LngLat(this.xLng(coord.column, worldSize), this.yLat(coord.row, worldSize)); - }, - pointCoordinate: function (p) { - var targetZ = 0; - var coord0 = [ - p.x, - p.y, - 0, - 1 - ]; - var coord1 = [ - p.x, - p.y, - 1, - 1 - ]; - vec4.transformMat4(coord0, coord0, this.pixelMatrixInverse); - vec4.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); - var scale = this.worldSize / this.zoomScale(this.tileZoom); - return new Coordinate(interp(x0, x1, t) / scale, interp(y0, y1, t) / scale, this.tileZoom); - }, - coordinatePoint: function (coord) { - var scale = this.worldSize / this.zoomScale(coord.zoom); - var p = [ - coord.column * scale, - coord.row * scale, - 0, - 1 - ]; - vec4.transformMat4(p, p, this.pixelMatrix); - return new Point(p[0] / p[3], p[1] / p[3]); - }, - calculatePosMatrix: function (coord, maxZoom) { - if (maxZoom === undefined) - maxZoom = Infinity; - if (coord instanceof TileCoord) - coord = coord.toCoordinate(maxZoom); - var z = Math.min(coord.zoom, maxZoom); - var scale = this.worldSize / Math.pow(2, z); - var posMatrix = new Float64Array(16); - mat4.identity(posMatrix); - mat4.translate(posMatrix, posMatrix, [ - coord.column * scale, - coord.row * scale, - 0 - ]); - mat4.scale(posMatrix, posMatrix, [ - scale / EXTENT, - scale / EXTENT, - 1 - ]); - mat4.multiply(posMatrix, this.projMatrix, posMatrix); - return new Float32Array(posMatrix); - }, - _constrain: function () { - if (!this.center || !this.width || !this.height || this._constraining) - return; - this._constraining = true; - var minY, maxY, minX, maxX, sy, sx, x2, y2, size = this.size, unmodified = this._unmodified; - if (this.latRange) { - minY = this.latY(this.latRange[1]); - maxY = this.latY(this.latRange[0]); - sy = maxY - minY < size.y ? size.y / (maxY - minY) : 0; - } - if (this.lngRange) { - minX = this.lngX(this.lngRange[0]); - maxX = this.lngX(this.lngRange[1]); - sx = maxX - minX < size.x ? size.x / (maxX - minX) : 0; - } - var s = Math.max(sx || 0, sy || 0); - if (s) { - this.center = this.unproject(new Point(sx ? (maxX + minX) / 2 : this.x, sy ? (maxY + minY) / 2 : this.y)); - this.zoom += this.scaleZoom(s); - this._unmodified = unmodified; - this._constraining = false; - return; - } - if (this.latRange) { - var y = this.y, h2 = size.y / 2; - if (y - h2 < minY) - y2 = minY + h2; - if (y + h2 > maxY) - y2 = maxY - h2; - } - if (this.lngRange) { - var x = this.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 Point(x2 !== undefined ? x2 : this.x, y2 !== undefined ? y2 : this.y)); - } - this._unmodified = unmodified; - this._constraining = false; - }, - _calcMatrices: function () { - if (!this.height) - return; - var halfFov = Math.atan(0.5 / this.altitude); - var topHalfSurfaceDistance = Math.sin(halfFov) * this.altitude / Math.sin(Math.PI / 2 - this._pitch - halfFov); - var farZ = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.altitude; - var m = new Float64Array(16); - mat4.perspective(m, 2 * Math.atan(this.height / 2 / this.altitude), this.width / this.height, 0.1, farZ); - mat4.translate(m, m, [ - 0, - 0, - -this.altitude - ]); - mat4.scale(m, m, [ - 1, - -1, - 1 / this.height - ]); - mat4.rotateX(m, m, this._pitch); - mat4.rotateZ(m, m, this.angle); - mat4.translate(m, m, [ - -this.x, - -this.y, - 0 - ]); - this.projMatrix = m; - m = mat4.create(); - mat4.scale(m, m, [ - this.width / 2, - -this.height / 2, - 1 - ]); - mat4.translate(m, m, [ - 1, - -1, - 0 - ]); - this.pixelMatrix = mat4.multiply(new Float64Array(16), m, this.projMatrix); - m = mat4.invert(new Float64Array(16), this.pixelMatrix); - if (!m) - throw new Error('failed to invert matrix'); - this.pixelMatrixInverse = m; - } -}; -},{"../data/bucket":69,"../source/tile_coord":109,"../util/interpolate":176,"../util/util":182,"./coordinate":78,"./lng_lat":79,"gl-matrix":26,"point-geometry":187}],82:[function(require,module,exports){ -'use strict'; -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 - ] - ] -}; -module.exports = function textVertices(text, left, baseline, scale) { - scale = scale || 1; - var strokes = [], 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; -}; -},{}],83:[function(require,module,exports){ -'use strict'; -var mapboxgl = module.exports = {}; -mapboxgl.version = require('../package.json').version; -mapboxgl.Map = require('./ui/map'); -mapboxgl.Control = require('./ui/control/control'); -mapboxgl.Navigation = require('./ui/control/navigation'); -mapboxgl.Geolocate = require('./ui/control/geolocate'); -mapboxgl.Attribution = require('./ui/control/attribution'); -mapboxgl.Popup = require('./ui/popup'); -mapboxgl.Marker = require('./ui/marker'); -mapboxgl.Style = require('./style/style'); -mapboxgl.Source = require('./source/source'); -mapboxgl.LngLat = require('./geo/lng_lat'); -mapboxgl.LngLatBounds = require('./geo/lng_lat_bounds'); -mapboxgl.Point = require('point-geometry'); -mapboxgl.Evented = require('./util/evented'); -mapboxgl.util = require('./util/util'); -mapboxgl.supported = require('./util/browser').supported; -var ajax = require('./util/ajax'); -mapboxgl.util.getJSON = ajax.getJSON; -mapboxgl.util.getArrayBuffer = ajax.getArrayBuffer; -var config = require('./util/config'); -mapboxgl.config = config; -Object.defineProperty(mapboxgl, 'accessToken', { - get: function () { - return config.ACCESS_TOKEN; - }, - set: function (token) { - config.ACCESS_TOKEN = token; - } -}); -},{"../package.json":184,"./geo/lng_lat":79,"./geo/lng_lat_bounds":80,"./source/source":106,"./style/style":118,"./ui/control/attribution":149,"./ui/control/control":150,"./ui/control/geolocate":151,"./ui/control/navigation":152,"./ui/map":161,"./ui/marker":162,"./ui/popup":163,"./util/ajax":165,"./util/browser":166,"./util/config":171,"./util/evented":174,"./util/util":182,"point-geometry":187}],84:[function(require,module,exports){ -'use strict'; -module.exports = function (uniforms) { - var pragmas = { - define: {}, - initialize: {} - }; - for (var i = 0; i < uniforms.length; i++) { - var uniform = uniforms[i]; - var type = '{precision} ' + (uniform.components === 1 ? 'float' : 'vec' + uniform.components); - pragmas.define[uniform.name.slice(2)] = 'uniform ' + type + ' ' + uniform.name + ';\n'; - pragmas.initialize[uniform.name.slice(2)] = type + ' ' + uniform.name.slice(2) + ' = ' + uniform.name + ';\n'; - } - return pragmas; -}; -},{}],85:[function(require,module,exports){ -'use strict'; -var pixelsToTileUnits = require('../source/pixels_to_tile_units'); -var createUniformPragmas = require('./create_uniform_pragmas'); -var tileSize = 512; -module.exports = drawBackground; -function drawBackground(painter, source, layer) { - var gl = painter.gl; - var transform = painter.transform; - var color = layer.paint['background-color']; - var image = layer.paint['background-pattern']; - var opacity = layer.paint['background-opacity']; - var program; - var imagePosA = image ? painter.spriteAtlas.getPosition(image.from, true) : null; - var imagePosB = image ? painter.spriteAtlas.getPosition(image.to, true) : null; - painter.setDepthSublayer(0); - if (imagePosA && imagePosB) { - if (painter.isOpaquePass) - return; - program = painter.useProgram('pattern'); - gl.uniform1i(program.u_image, 0); - gl.uniform2fv(program.u_pattern_tl_a, imagePosA.tl); - gl.uniform2fv(program.u_pattern_br_a, imagePosA.br); - gl.uniform2fv(program.u_pattern_tl_b, imagePosB.tl); - gl.uniform2fv(program.u_pattern_br_b, imagePosB.br); - gl.uniform1f(program.u_opacity, opacity); - gl.uniform1f(program.u_mix, image.t); - gl.uniform2fv(program.u_pattern_size_a, imagePosA.size); - gl.uniform2fv(program.u_pattern_size_b, imagePosB.size); - gl.uniform1f(program.u_scale_a, image.fromScale); - gl.uniform1f(program.u_scale_b, image.toScale); - gl.activeTexture(gl.TEXTURE0); - painter.spriteAtlas.bind(gl, true); - painter.tileExtentPatternVAO.bind(gl, program, painter.tileExtentBuffer); - } else { - if (painter.isOpaquePass !== (color[3] === 1)) - return; - var pragmas = createUniformPragmas([ - { - name: 'u_color', - components: 4 - }, - { - name: 'u_opacity', - components: 1 - } - ]); - program = painter.useProgram('fill', [], pragmas, pragmas); - gl.uniform4fv(program.u_color, color); - gl.uniform1f(program.u_opacity, opacity); - painter.tileExtentVAO.bind(gl, program, painter.tileExtentBuffer); - } - gl.disable(gl.STENCIL_TEST); - var coords = transform.coveringTiles({ tileSize: tileSize }); - for (var c = 0; c < coords.length; c++) { - var coord = coords[c]; - if (imagePosA && imagePosB) { - var tile = { - coord: coord, - tileSize: tileSize - }; - gl.uniform1f(program.u_tile_units_to_pixels, 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom)); - var tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom - tile.coord.z); - var pixelX = tileSizeAtNearestZoom * (tile.coord.x + coord.w * Math.pow(2, tile.coord.z)); - var pixelY = tileSizeAtNearestZoom * tile.coord.y; - gl.uniform2f(program.u_pixel_coord_upper, pixelX >> 16, pixelY >> 16); - gl.uniform2f(program.u_pixel_coord_lower, pixelX & 65535, pixelY & 65535); - } - gl.uniformMatrix4fv(program.u_matrix, false, painter.transform.calculatePosMatrix(coord)); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, painter.tileExtentBuffer.length); - } - gl.stencilMask(0); - gl.stencilFunc(gl.EQUAL, 128, 128); -} -},{"../source/pixels_to_tile_units":103,"./create_uniform_pragmas":84}],86:[function(require,module,exports){ -'use strict'; -var browser = require('../util/browser'); -module.exports = drawCircles; -function drawCircles(painter, source, layer, coords) { - if (painter.isOpaquePass) - return; - var gl = painter.gl; - painter.setDepthSublayer(0); - painter.depthMask(false); - gl.disable(gl.STENCIL_TEST); - for (var i = 0; i < coords.length; i++) { - var coord = coords[i]; - var tile = source.getTile(coord); - var bucket = tile.getBucket(layer); - if (!bucket) - continue; - var bufferGroups = bucket.bufferGroups.circle; - if (!bufferGroups) - continue; - var programOptions = bucket.paintAttributes.circle[layer.id]; - var program = painter.useProgram('circle', programOptions.defines, programOptions.vertexPragmas, programOptions.fragmentPragmas); - if (layer.paint['circle-pitch-scale'] === 'map') { - gl.uniform1i(program.u_scale_with_map, true); - gl.uniform2f(program.u_extrude_scale, painter.transform.pixelsToGLUnits[0] * painter.transform.altitude, painter.transform.pixelsToGLUnits[1] * painter.transform.altitude); - } else { - gl.uniform1i(program.u_scale_with_map, false); - gl.uniform2fv(program.u_extrude_scale, painter.transform.pixelsToGLUnits); - } - gl.uniform1f(program.u_devicepixelratio, browser.devicePixelRatio); - gl.uniformMatrix4fv(program.u_matrix, false, painter.translatePosMatrix(coord.posMatrix, tile, layer.paint['circle-translate'], layer.paint['circle-translate-anchor'])); - bucket.setUniforms(gl, 'circle', program, layer, { zoom: painter.transform.zoom }); - for (var k = 0; k < bufferGroups.length; k++) { - var group = bufferGroups[k]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer, group.paintVertexBuffers[layer.id]); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length * 3, gl.UNSIGNED_SHORT, 0); - } - } -} -},{"../util/browser":166}],87:[function(require,module,exports){ -'use strict'; -module.exports = drawCollisionDebug; -function drawCollisionDebug(painter, source, layer, coords) { - var gl = painter.gl; - gl.enable(gl.STENCIL_TEST); - var program = painter.useProgram('collisionbox'); - for (var i = 0; i < coords.length; i++) { - var coord = coords[i]; - var tile = source.getTile(coord); - var bucket = tile.getBucket(layer); - if (!bucket) - continue; - var bufferGroups = bucket.bufferGroups.collisionBox; - if (!bufferGroups || !bufferGroups.length) - continue; - var group = bufferGroups[0]; - if (group.layoutVertexBuffer.length === 0) - continue; - gl.uniformMatrix4fv(program.u_matrix, false, coord.posMatrix); - painter.enableTileClippingMask(coord); - painter.lineWidth(1); - gl.uniform1f(program.u_scale, Math.pow(2, painter.transform.zoom - tile.coord.z)); - gl.uniform1f(program.u_zoom, painter.transform.zoom * 10); - gl.uniform1f(program.u_maxzoom, (tile.coord.z + 1) * 10); - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer); - gl.drawArrays(gl.LINES, 0, group.layoutVertexBuffer.length); - } -} -},{}],88:[function(require,module,exports){ -'use strict'; -var textVertices = require('../lib/debugtext'); -var browser = require('../util/browser'); -var mat4 = require('gl-matrix').mat4; -var EXTENT = require('../data/bucket').EXTENT; -var Buffer = require('../data/buffer'); -var VertexArrayObject = require('./vertex_array_object'); -module.exports = drawDebug; -function drawDebug(painter, source, coords) { - if (painter.isOpaquePass) - return; - if (!painter.options.debug) - return; - for (var i = 0; i < coords.length; i++) { - drawDebugTile(painter, source, coords[i]); - } -} -function drawDebugTile(painter, source, coord) { - var gl = painter.gl; - gl.disable(gl.STENCIL_TEST); - painter.lineWidth(1 * browser.devicePixelRatio); - var posMatrix = coord.posMatrix; - var program = painter.useProgram('debug'); - gl.uniformMatrix4fv(program.u_matrix, false, posMatrix); - gl.uniform4f(program.u_color, 1, 0, 0, 1); - painter.debugVAO.bind(gl, program, painter.debugBuffer); - gl.drawArrays(gl.LINE_STRIP, 0, painter.debugBuffer.length); - var vertices = textVertices(coord.toString(), 50, 200, 5); - var debugTextArray = new painter.PosArray(); - for (var v = 0; v < vertices.length; v += 2) { - debugTextArray.emplaceBack(vertices[v], vertices[v + 1]); - } - var debugTextBuffer = new Buffer(debugTextArray.serialize(), painter.PosArray.serialize(), Buffer.BufferType.VERTEX); - var debugTextVAO = new VertexArrayObject(); - debugTextVAO.bind(gl, program, debugTextBuffer); - gl.uniform4f(program.u_color, 1, 1, 1, 1); - var tileSize = source.getTile(coord).tileSize; - var onePixel = EXTENT / (Math.pow(2, painter.transform.zoom - coord.z) * tileSize); - var translations = [ - [ - -1, - -1 - ], - [ - -1, - 1 - ], - [ - 1, - -1 - ], - [ - 1, - 1 - ] - ]; - for (var i = 0; i < translations.length; i++) { - var translation = translations[i]; - gl.uniformMatrix4fv(program.u_matrix, false, mat4.translate([], posMatrix, [ - onePixel * translation[0], - onePixel * translation[1], - 0 - ])); - gl.drawArrays(gl.LINES, 0, debugTextBuffer.length); - } - gl.uniform4f(program.u_color, 0, 0, 0, 1); - gl.uniformMatrix4fv(program.u_matrix, false, posMatrix); - gl.drawArrays(gl.LINES, 0, debugTextBuffer.length); -} -},{"../data/bucket":69,"../data/buffer":74,"../lib/debugtext":82,"../util/browser":166,"./vertex_array_object":97,"gl-matrix":26}],89:[function(require,module,exports){ -'use strict'; -var pixelsToTileUnits = require('../source/pixels_to_tile_units'); -module.exports = draw; -function draw(painter, source, layer, coords) { - var gl = painter.gl; - gl.enable(gl.STENCIL_TEST); - var isOpaque; - if (layer.paint['fill-pattern']) { - isOpaque = false; - } else { - isOpaque = layer.isPaintValueFeatureConstant('fill-color') && layer.isPaintValueFeatureConstant('fill-opacity') && layer.paint['fill-color'][3] === 1 && layer.paint['fill-opacity'] === 1; - } - if (painter.isOpaquePass === isOpaque) { - painter.setDepthSublayer(1); - for (var i = 0; i < coords.length; i++) { - drawFill(painter, source, layer, coords[i]); - } - } - if (!painter.isOpaquePass && layer.paint['fill-antialias']) { - painter.lineWidth(2); - painter.depthMask(false); - var isOutlineColorDefined = layer.getPaintProperty('fill-outline-color'); - if (isOutlineColorDefined || !layer.paint['fill-pattern']) { - if (isOutlineColorDefined) { - painter.setDepthSublayer(2); - } else { - painter.setDepthSublayer(0); - } - } else { - painter.setDepthSublayer(0); - } - for (var j = 0; j < coords.length; j++) { - drawStroke(painter, source, layer, coords[j]); - } - } -} -function drawFill(painter, source, layer, coord) { - var tile = source.getTile(coord); - var bucket = tile.getBucket(layer); - if (!bucket) - return; - var bufferGroups = bucket.bufferGroups.fill; - if (!bufferGroups) - return; - var gl = painter.gl; - var image = layer.paint['fill-pattern']; - var program; - if (!image) { - var programOptions = bucket.paintAttributes.fill[layer.id]; - program = painter.useProgram('fill', programOptions.defines, programOptions.vertexPragmas, programOptions.fragmentPragmas); - bucket.setUniforms(gl, 'fill', program, layer, { zoom: painter.transform.zoom }); - } else { - program = painter.useProgram('pattern'); - setPattern(image, layer.paint['fill-opacity'], tile, coord, painter, program); - gl.activeTexture(gl.TEXTURE0); - painter.spriteAtlas.bind(gl, true); - } - gl.uniformMatrix4fv(program.u_matrix, false, painter.translatePosMatrix(coord.posMatrix, tile, layer.paint['fill-translate'], layer.paint['fill-translate-anchor'])); - painter.enableTileClippingMask(coord); - for (var i = 0; i < bufferGroups.length; i++) { - var group = bufferGroups[i]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer, group.paintVertexBuffers[layer.id]); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length, gl.UNSIGNED_SHORT, 0); - } -} -function drawStroke(painter, source, layer, coord) { - var tile = source.getTile(coord); - var bucket = tile.getBucket(layer); - if (!bucket) - return; - var gl = painter.gl; - var bufferGroups = bucket.bufferGroups.fill; - var image = layer.paint['fill-pattern']; - var opacity = layer.paint['fill-opacity']; - var isOutlineColorDefined = layer.getPaintProperty('fill-outline-color'); - var program; - if (image && !isOutlineColorDefined) { - program = painter.useProgram('outlinepattern'); - gl.uniform2f(program.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - } else { - var programOptions = bucket.paintAttributes.fill[layer.id]; - program = painter.useProgram('outline', programOptions.defines, programOptions.vertexPragmas, programOptions.fragmentPragmas); - gl.uniform2f(program.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - gl.uniform1f(program.u_opacity, opacity); - bucket.setUniforms(gl, 'fill', program, layer, { zoom: painter.transform.zoom }); - } - gl.uniformMatrix4fv(program.u_matrix, false, painter.translatePosMatrix(coord.posMatrix, tile, layer.paint['fill-translate'], layer.paint['fill-translate-anchor'])); - if (image) { - setPattern(image, opacity, tile, coord, painter, program); - } - painter.enableTileClippingMask(coord); - for (var k = 0; k < bufferGroups.length; k++) { - var group = bufferGroups[k]; - group.secondVaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer2, group.paintVertexBuffers[layer.id]); - gl.drawElements(gl.LINES, group.elementBuffer2.length * 2, gl.UNSIGNED_SHORT, 0); - } -} -function setPattern(image, opacity, tile, coord, painter, program) { - var gl = painter.gl; - var imagePosA = painter.spriteAtlas.getPosition(image.from, true); - var imagePosB = painter.spriteAtlas.getPosition(image.to, true); - if (!imagePosA || !imagePosB) - return; - gl.uniform1i(program.u_image, 0); - gl.uniform2fv(program.u_pattern_tl_a, imagePosA.tl); - gl.uniform2fv(program.u_pattern_br_a, imagePosA.br); - gl.uniform2fv(program.u_pattern_tl_b, imagePosB.tl); - gl.uniform2fv(program.u_pattern_br_b, imagePosB.br); - gl.uniform1f(program.u_opacity, opacity); - gl.uniform1f(program.u_mix, image.t); - gl.uniform1f(program.u_tile_units_to_pixels, 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom)); - gl.uniform2fv(program.u_pattern_size_a, imagePosA.size); - gl.uniform2fv(program.u_pattern_size_b, imagePosB.size); - gl.uniform1f(program.u_scale_a, image.fromScale); - gl.uniform1f(program.u_scale_b, image.toScale); - var tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom - tile.coord.z); - var pixelX = tileSizeAtNearestZoom * (tile.coord.x + coord.w * Math.pow(2, tile.coord.z)); - var pixelY = tileSizeAtNearestZoom * tile.coord.y; - gl.uniform2f(program.u_pixel_coord_upper, pixelX >> 16, pixelY >> 16); - gl.uniform2f(program.u_pixel_coord_lower, pixelX & 65535, pixelY & 65535); - gl.activeTexture(gl.TEXTURE0); - painter.spriteAtlas.bind(gl, true); -} -},{"../source/pixels_to_tile_units":103}],90:[function(require,module,exports){ -'use strict'; -var browser = require('../util/browser'); -var mat2 = require('gl-matrix').mat2; -var pixelsToTileUnits = require('../source/pixels_to_tile_units'); -module.exports = function drawLine(painter, source, layer, coords) { - if (painter.isOpaquePass) - return; - painter.setDepthSublayer(0); - painter.depthMask(false); - var gl = painter.gl; - gl.enable(gl.STENCIL_TEST); - if (layer.paint['line-width'] <= 0) - return; - var antialiasing = 1 / browser.devicePixelRatio; - var blur = layer.paint['line-blur'] + antialiasing; - var color = layer.paint['line-color']; - var tr = painter.transform; - var antialiasingMatrix = mat2.create(); - mat2.scale(antialiasingMatrix, antialiasingMatrix, [ - 1, - Math.cos(tr._pitch) - ]); - mat2.rotate(antialiasingMatrix, antialiasingMatrix, painter.transform.angle); - var topedgelength = Math.sqrt(tr.height * tr.height / 4 * (1 + tr.altitude * tr.altitude)); - var x = tr.height / 2 * Math.tan(tr._pitch); - var extra = (topedgelength + x) / topedgelength - 1; - var dasharray = layer.paint['line-dasharray']; - var image = layer.paint['line-pattern']; - var program, posA, posB, imagePosA, imagePosB; - if (dasharray) { - program = painter.useProgram('linesdfpattern'); - gl.uniform1f(program.u_linewidth, layer.paint['line-width'] / 2); - gl.uniform1f(program.u_gapwidth, layer.paint['line-gap-width'] / 2); - gl.uniform1f(program.u_antialiasing, antialiasing / 2); - gl.uniform1f(program.u_blur, blur); - gl.uniform4fv(program.u_color, color); - gl.uniform1f(program.u_opacity, layer.paint['line-opacity']); - posA = painter.lineAtlas.getDash(dasharray.from, layer.layout['line-cap'] === 'round'); - posB = painter.lineAtlas.getDash(dasharray.to, layer.layout['line-cap'] === 'round'); - gl.uniform1i(program.u_image, 0); - gl.activeTexture(gl.TEXTURE0); - painter.lineAtlas.bind(gl); - gl.uniform1f(program.u_tex_y_a, posA.y); - gl.uniform1f(program.u_tex_y_b, posB.y); - gl.uniform1f(program.u_mix, dasharray.t); - gl.uniform1f(program.u_extra, extra); - gl.uniform1f(program.u_offset, -layer.paint['line-offset']); - gl.uniformMatrix2fv(program.u_antialiasingmatrix, false, antialiasingMatrix); - } else if (image) { - imagePosA = painter.spriteAtlas.getPosition(image.from, true); - imagePosB = painter.spriteAtlas.getPosition(image.to, true); - if (!imagePosA || !imagePosB) - return; - program = painter.useProgram('linepattern'); - gl.uniform1i(program.u_image, 0); - gl.activeTexture(gl.TEXTURE0); - painter.spriteAtlas.bind(gl, true); - gl.uniform1f(program.u_linewidth, layer.paint['line-width'] / 2); - gl.uniform1f(program.u_gapwidth, layer.paint['line-gap-width'] / 2); - gl.uniform1f(program.u_antialiasing, antialiasing / 2); - gl.uniform1f(program.u_blur, blur); - gl.uniform2fv(program.u_pattern_tl_a, imagePosA.tl); - gl.uniform2fv(program.u_pattern_br_a, imagePosA.br); - gl.uniform2fv(program.u_pattern_tl_b, imagePosB.tl); - gl.uniform2fv(program.u_pattern_br_b, imagePosB.br); - gl.uniform1f(program.u_fade, image.t); - gl.uniform1f(program.u_opacity, layer.paint['line-opacity']); - gl.uniform1f(program.u_extra, extra); - gl.uniform1f(program.u_offset, -layer.paint['line-offset']); - gl.uniformMatrix2fv(program.u_antialiasingmatrix, false, antialiasingMatrix); - } else { - program = painter.useProgram('line'); - gl.uniform1f(program.u_linewidth, layer.paint['line-width'] / 2); - gl.uniform1f(program.u_gapwidth, layer.paint['line-gap-width'] / 2); - gl.uniform1f(program.u_antialiasing, antialiasing / 2); - gl.uniform1f(program.u_blur, blur); - gl.uniform1f(program.u_extra, extra); - gl.uniform1f(program.u_offset, -layer.paint['line-offset']); - gl.uniformMatrix2fv(program.u_antialiasingmatrix, false, antialiasingMatrix); - gl.uniform4fv(program.u_color, color); - gl.uniform1f(program.u_opacity, layer.paint['line-opacity']); - } - for (var k = 0; k < coords.length; k++) { - var coord = coords[k]; - var tile = source.getTile(coord); - var bucket = tile.getBucket(layer); - if (!bucket) - continue; - var bufferGroups = bucket.bufferGroups.line; - if (!bufferGroups) - continue; - painter.enableTileClippingMask(coord); - var posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, layer.paint['line-translate'], layer.paint['line-translate-anchor']); - gl.uniformMatrix4fv(program.u_matrix, false, posMatrix); - var ratio = 1 / pixelsToTileUnits(tile, 1, painter.transform.zoom); - if (dasharray) { - var widthA = posA.width * dasharray.fromScale; - var widthB = posB.width * dasharray.toScale; - var scaleA = [ - 1 / pixelsToTileUnits(tile, widthA, painter.transform.tileZoom), - -posA.height / 2 - ]; - var scaleB = [ - 1 / pixelsToTileUnits(tile, widthB, painter.transform.tileZoom), - -posB.height / 2 - ]; - var gamma = painter.lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2; - gl.uniform1f(program.u_ratio, ratio); - gl.uniform2fv(program.u_patternscale_a, scaleA); - gl.uniform2fv(program.u_patternscale_b, scaleB); - gl.uniform1f(program.u_sdfgamma, gamma); - } else if (image) { - gl.uniform1f(program.u_ratio, ratio); - gl.uniform2fv(program.u_pattern_size_a, [ - pixelsToTileUnits(tile, imagePosA.size[0] * image.fromScale, painter.transform.tileZoom), - imagePosB.size[1] - ]); - gl.uniform2fv(program.u_pattern_size_b, [ - pixelsToTileUnits(tile, imagePosB.size[0] * image.toScale, painter.transform.tileZoom), - imagePosB.size[1] - ]); - } else { - gl.uniform1f(program.u_ratio, ratio); - } - for (var i = 0; i < bufferGroups.length; i++) { - var group = bufferGroups[i]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length * 3, gl.UNSIGNED_SHORT, 0); - } - } -}; -},{"../source/pixels_to_tile_units":103,"../util/browser":166,"gl-matrix":26}],91:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var StructArrayType = require('../util/struct_array'); -module.exports = drawRaster; -function drawRaster(painter, source, layer, coords) { - if (painter.isOpaquePass) - return; - var gl = painter.gl; - gl.enable(gl.DEPTH_TEST); - painter.depthMask(true); - gl.depthFunc(gl.LESS); - var minTileZ = coords.length && coords[0].z; - for (var i = 0; i < coords.length; i++) { - var coord = coords[i]; - painter.setDepthSublayer(coord.z - minTileZ); - drawRasterTile(painter, source, layer, coord); - } - gl.depthFunc(gl.LEQUAL); -} -drawRaster.RasterBoundsArray = new StructArrayType({ - members: [ - { - name: 'a_pos', - type: 'Int16', - components: 2 - }, - { - name: 'a_texture_pos', - type: 'Int16', - components: 2 - } - ] -}); -function drawRasterTile(painter, source, layer, coord) { - var gl = painter.gl; - gl.disable(gl.STENCIL_TEST); - var tile = source.getTile(coord); - var posMatrix = painter.transform.calculatePosMatrix(coord, source.maxzoom); - var program = painter.useProgram('raster'); - gl.uniformMatrix4fv(program.u_matrix, false, posMatrix); - gl.uniform1f(program.u_brightness_low, layer.paint['raster-brightness-min']); - gl.uniform1f(program.u_brightness_high, layer.paint['raster-brightness-max']); - gl.uniform1f(program.u_saturation_factor, saturationFactor(layer.paint['raster-saturation'])); - gl.uniform1f(program.u_contrast_factor, contrastFactor(layer.paint['raster-contrast'])); - gl.uniform3fv(program.u_spin_weights, spinWeights(layer.paint['raster-hue-rotate'])); - var parentTile = tile.source && tile.source.findLoadedParent(coord, 0, {}), opacities = getOpacities(tile, parentTile, layer, painter.transform); - var parentScaleBy, parentTL; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, tile.texture); - gl.activeTexture(gl.TEXTURE1); - if (parentTile) { - gl.bindTexture(gl.TEXTURE_2D, parentTile.texture); - parentScaleBy = Math.pow(2, parentTile.coord.z - tile.coord.z); - parentTL = [ - tile.coord.x * parentScaleBy % 1, - tile.coord.y * parentScaleBy % 1 - ]; - } else { - gl.bindTexture(gl.TEXTURE_2D, tile.texture); - opacities[1] = 0; - } - gl.uniform2fv(program.u_tl_parent, parentTL || [ - 0, - 0 - ]); - gl.uniform1f(program.u_scale_parent, parentScaleBy || 1); - gl.uniform1f(program.u_buffer_scale, 1); - gl.uniform1f(program.u_opacity0, opacities[0]); - gl.uniform1f(program.u_opacity1, opacities[1]); - gl.uniform1i(program.u_image0, 0); - gl.uniform1i(program.u_image1, 1); - var buffer = tile.boundsBuffer || painter.rasterBoundsBuffer; - var vao = tile.boundsVAO || painter.rasterBoundsVAO; - vao.bind(gl, program, buffer); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); -} -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; -} -function getOpacities(tile, parentTile, layer, transform) { - var opacity = [ - 1, - 0 - ]; - var fadeDuration = layer.paint['raster-fade-duration']; - if (tile.source && fadeDuration > 0) { - var now = new Date().getTime(); - var sinceTile = (now - tile.timeAdded) / fadeDuration; - var sinceParent = parentTile ? (now - parentTile.timeAdded) / fadeDuration : -1; - var idealZ = transform.coveringZoomLevel(tile.source); - var parentFurther = parentTile ? Math.abs(parentTile.coord.z - idealZ) > Math.abs(tile.coord.z - idealZ) : false; - if (!parentTile || parentFurther) { - opacity[0] = util.clamp(sinceTile, 0, 1); - opacity[1] = 1 - opacity[0]; - } else { - opacity[0] = util.clamp(1 - sinceParent, 0, 1); - opacity[1] = 1 - opacity[0]; - } - } - var op = layer.paint['raster-opacity']; - opacity[0] *= op; - opacity[1] *= op; - return opacity; -} -},{"../util/struct_array":180,"../util/util":182}],92:[function(require,module,exports){ -'use strict'; -var browser = require('../util/browser'); -var drawCollisionDebug = require('./draw_collision_debug'); -var pixelsToTileUnits = require('../source/pixels_to_tile_units'); -module.exports = drawSymbols; -function drawSymbols(painter, source, layer, coords) { - if (painter.isOpaquePass) - return; - var drawAcrossEdges = !(layer.layout['text-allow-overlap'] || layer.layout['icon-allow-overlap'] || layer.layout['text-ignore-placement'] || layer.layout['icon-ignore-placement']); - var gl = painter.gl; - if (drawAcrossEdges) { - gl.disable(gl.STENCIL_TEST); - } else { - gl.enable(gl.STENCIL_TEST); - } - painter.setDepthSublayer(0); - painter.depthMask(false); - gl.disable(gl.DEPTH_TEST); - drawLayerSymbols(painter, source, layer, coords, false, layer.paint['icon-translate'], layer.paint['icon-translate-anchor'], layer.layout['icon-rotation-alignment'], layer.layout['icon-rotation-alignment'], layer.layout['icon-size'], layer.paint['icon-halo-width'], layer.paint['icon-halo-color'], layer.paint['icon-halo-blur'], layer.paint['icon-opacity'], layer.paint['icon-color']); - drawLayerSymbols(painter, source, layer, coords, true, layer.paint['text-translate'], layer.paint['text-translate-anchor'], layer.layout['text-rotation-alignment'], layer.layout['text-pitch-alignment'], layer.layout['text-size'], layer.paint['text-halo-width'], layer.paint['text-halo-color'], layer.paint['text-halo-blur'], layer.paint['text-opacity'], layer.paint['text-color']); - gl.enable(gl.DEPTH_TEST); - if (source.map.showCollisionBoxes) { - drawCollisionDebug(painter, source, layer, coords); - } -} -function drawLayerSymbols(painter, source, layer, coords, isText, translate, translateAnchor, rotationAlignment, pitchAlignment, size, haloWidth, haloColor, haloBlur, opacity, color) { - for (var j = 0; j < coords.length; j++) { - var tile = source.getTile(coords[j]); - var bucket = tile.getBucket(layer); - if (!bucket) - continue; - var bothBufferGroups = bucket.bufferGroups; - var bufferGroups = isText ? bothBufferGroups.glyph : bothBufferGroups.icon; - if (!bufferGroups.length) - continue; - painter.enableTileClippingMask(coords[j]); - drawSymbol(painter, layer, coords[j].posMatrix, tile, bucket, bufferGroups, isText, isText || bucket.sdfIcons, !isText && bucket.iconsNeedLinear, isText ? bucket.adjustedTextSize : bucket.adjustedIconSize, bucket.fontstack, translate, translateAnchor, rotationAlignment, pitchAlignment, size, haloWidth, haloColor, haloBlur, opacity, color); - } -} -function drawSymbol(painter, layer, posMatrix, tile, bucket, bufferGroups, isText, sdf, iconsNeedLinear, adjustedSize, fontstack, translate, translateAnchor, rotationAlignment, pitchAlignment, size, haloWidth, haloColor, haloBlur, opacity, color) { - var gl = painter.gl; - var tr = painter.transform; - var rotateWithMap = rotationAlignment === 'map'; - var pitchWithMap = pitchAlignment === 'map'; - var defaultSize = isText ? 24 : 1; - var fontScale = size / defaultSize; - var extrudeScale, s, gammaScale; - if (pitchWithMap) { - s = pixelsToTileUnits(tile, 1, painter.transform.zoom) * fontScale; - gammaScale = 1 / Math.cos(tr._pitch); - extrudeScale = [ - s, - s - ]; - } else { - s = painter.transform.altitude * fontScale; - gammaScale = 1; - extrudeScale = [ - tr.pixelsToGLUnits[0] * s, - tr.pixelsToGLUnits[1] * s - ]; - } - if (!isText && !painter.style.sprite.loaded()) - return; - var program = painter.useProgram(sdf ? 'sdf' : 'icon'); - gl.uniformMatrix4fv(program.u_matrix, false, painter.translatePosMatrix(posMatrix, tile, translate, translateAnchor)); - gl.uniform1i(program.u_rotate_with_map, rotateWithMap); - gl.uniform1i(program.u_pitch_with_map, pitchWithMap); - gl.uniform2fv(program.u_extrude_scale, extrudeScale); - gl.activeTexture(gl.TEXTURE0); - gl.uniform1i(program.u_texture, 0); - if (isText) { - var glyphAtlas = fontstack && painter.glyphSource.getGlyphAtlas(fontstack); - if (!glyphAtlas) - return; - glyphAtlas.updateTexture(gl); - gl.uniform2f(program.u_texsize, glyphAtlas.width / 4, glyphAtlas.height / 4); - } else { - var mapMoving = painter.options.rotating || painter.options.zooming; - var iconScaled = fontScale !== 1 || browser.devicePixelRatio !== painter.spriteAtlas.pixelRatio || iconsNeedLinear; - var iconTransformed = pitchWithMap || painter.transform.pitch; - painter.spriteAtlas.bind(gl, sdf || mapMoving || iconScaled || iconTransformed); - gl.uniform2f(program.u_texsize, painter.spriteAtlas.width / 4, painter.spriteAtlas.height / 4); - } - var zoomAdjust = Math.log(size / adjustedSize) / Math.LN2 || 0; - gl.uniform1f(program.u_zoom, (painter.transform.zoom - zoomAdjust) * 10); - gl.activeTexture(gl.TEXTURE1); - painter.frameHistory.bind(gl); - gl.uniform1i(program.u_fadetexture, 1); - var group; - if (sdf) { - var sdfPx = 8; - var blurOffset = 1.19; - var haloOffset = 6; - var gamma = 0.105 * defaultSize / size / browser.devicePixelRatio; - if (haloWidth) { - gl.uniform1f(program.u_gamma, (haloBlur * blurOffset / fontScale / sdfPx + gamma) * gammaScale); - gl.uniform4fv(program.u_color, haloColor); - gl.uniform1f(program.u_opacity, opacity); - gl.uniform1f(program.u_buffer, (haloOffset - haloWidth / fontScale) / sdfPx); - for (var j = 0; j < bufferGroups.length; j++) { - group = bufferGroups[j]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length * 3, gl.UNSIGNED_SHORT, 0); - } - } - gl.uniform1f(program.u_gamma, gamma * gammaScale); - gl.uniform4fv(program.u_color, color); - gl.uniform1f(program.u_opacity, opacity); - gl.uniform1f(program.u_buffer, (256 - 64) / 256); - gl.uniform1f(program.u_pitch, tr.pitch / 360 * 2 * Math.PI); - gl.uniform1f(program.u_bearing, tr.bearing / 360 * 2 * Math.PI); - gl.uniform1f(program.u_aspect_ratio, tr.width / tr.height); - for (var i = 0; i < bufferGroups.length; i++) { - group = bufferGroups[i]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length * 3, gl.UNSIGNED_SHORT, 0); - } - } else { - gl.uniform1f(program.u_opacity, opacity); - for (var k = 0; k < bufferGroups.length; k++) { - group = bufferGroups[k]; - group.vaos[layer.id].bind(gl, program, group.layoutVertexBuffer, group.elementBuffer); - gl.drawElements(gl.TRIANGLES, group.elementBuffer.length * 3, gl.UNSIGNED_SHORT, 0); - } - } -} -},{"../source/pixels_to_tile_units":103,"../util/browser":166,"./draw_collision_debug":87}],93:[function(require,module,exports){ -'use strict'; -module.exports = FrameHistory; -function FrameHistory() { - this.changeTimes = new Float64Array(256); - this.changeOpacities = new Uint8Array(256); - this.opacities = new Uint8ClampedArray(256); - this.array = new Uint8Array(this.opacities.buffer); - this.fadeDuration = 300; - this.previousZoom = 0; - this.firstFrame = true; -} -FrameHistory.prototype.record = function (zoom) { - var now = Date.now(); - if (this.firstFrame) { - now = 0; - this.firstFrame = false; - } - zoom = Math.floor(zoom * 10); - var z; - if (zoom < this.previousZoom) { - for (z = zoom + 1; z <= this.previousZoom; z++) { - this.changeTimes[z] = now; - this.changeOpacities[z] = this.opacities[z]; - } - } else { - for (z = zoom; z > this.previousZoom; z--) { - this.changeTimes[z] = now; - this.changeOpacities[z] = this.opacities[z]; - } - } - for (z = 0; z < 256; z++) { - var timeSince = now - this.changeTimes[z]; - var opacityChange = timeSince / this.fadeDuration * 255; - if (z <= zoom) { - this.opacities[z] = this.changeOpacities[z] + opacityChange; - } else { - this.opacities[z] = this.changeOpacities[z] - opacityChange; - } - } - this.changed = true; - this.previousZoom = zoom; -}; -FrameHistory.prototype.bind = function (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.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.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, 256, 1, 0, gl.ALPHA, gl.UNSIGNED_BYTE, this.array); - } else { - gl.bindTexture(gl.TEXTURE_2D, this.texture); - if (this.changed) { - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 256, 1, gl.ALPHA, gl.UNSIGNED_BYTE, this.array); - this.changed = false; - } - } -}; -},{}],94:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -module.exports = 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.setSprite = function (sprite) { - this.sprite = sprite; -}; -LineAtlas.prototype.getDash = function (dasharray, round) { - var key = dasharray.join(',') + round; - if (!this.positions[key]) { - this.positions[key] = this.addDash(dasharray, round); - } - return this.positions[key]; -}; -LineAtlas.prototype.addDash = function (dasharray, round) { - var n = round ? 7 : 0; - var height = 2 * n + 1; - var offset = 128; - if (this.nextRow + height > this.height) { - util.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; - 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 (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); - } - } -}; -},{"../util/util":182}],95:[function(require,module,exports){ -'use strict'; -var browser = require('../util/browser'); -var mat4 = require('gl-matrix').mat4; -var FrameHistory = require('./frame_history'); -var SourceCache = require('../source/source_cache'); -var EXTENT = require('../data/bucket').EXTENT; -var pixelsToTileUnits = require('../source/pixels_to_tile_units'); -var util = require('../util/util'); -var StructArrayType = require('../util/struct_array'); -var Buffer = require('../data/buffer'); -var VertexArrayObject = require('./vertex_array_object'); -var RasterBoundsArray = require('./draw_raster').RasterBoundsArray; -var createUniformPragmas = require('./create_uniform_pragmas'); -module.exports = Painter; -function Painter(gl, transform) { - this.gl = gl; - this.transform = transform; - this.reusableTextures = {}; - this.preFbos = {}; - this.frameHistory = new FrameHistory(); - this.setup(); - this.numSublayers = SourceCache.maxUnderzooming + SourceCache.maxOverzooming + 1; - this.depthEpsilon = 1 / Math.pow(2, 16); - this.lineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE); -} -util.extend(Painter.prototype, require('./painter/use_program')); -Painter.prototype.resize = function (width, height) { - var gl = this.gl; - this.width = width * browser.devicePixelRatio; - this.height = height * browser.devicePixelRatio; - gl.viewport(0, 0, this.width, this.height); -}; -Painter.prototype.setup = function () { - var gl = this.gl; - gl.verbose = true; - gl.enable(gl.BLEND); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - gl.enable(gl.STENCIL_TEST); - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - this._depthMask = false; - gl.depthMask(false); - var PosArray = this.PosArray = new StructArrayType({ - members: [{ - name: 'a_pos', - type: 'Int16', - components: 2 - }] - }); - var tileExtentArray = new PosArray(); - tileExtentArray.emplaceBack(0, 0); - tileExtentArray.emplaceBack(EXTENT, 0); - tileExtentArray.emplaceBack(0, EXTENT); - tileExtentArray.emplaceBack(EXTENT, EXTENT); - this.tileExtentBuffer = new Buffer(tileExtentArray.serialize(), PosArray.serialize(), Buffer.BufferType.VERTEX); - this.tileExtentVAO = new VertexArrayObject(); - this.tileExtentPatternVAO = new VertexArrayObject(); - var debugArray = new PosArray(); - debugArray.emplaceBack(0, 0); - debugArray.emplaceBack(EXTENT, 0); - debugArray.emplaceBack(EXTENT, EXTENT); - debugArray.emplaceBack(0, EXTENT); - debugArray.emplaceBack(0, 0); - this.debugBuffer = new Buffer(debugArray.serialize(), PosArray.serialize(), Buffer.BufferType.VERTEX); - this.debugVAO = new VertexArrayObject(); - var rasterBoundsArray = new RasterBoundsArray(); - rasterBoundsArray.emplaceBack(0, 0, 0, 0); - rasterBoundsArray.emplaceBack(EXTENT, 0, 32767, 0); - rasterBoundsArray.emplaceBack(0, EXTENT, 0, 32767); - rasterBoundsArray.emplaceBack(EXTENT, EXTENT, 32767, 32767); - this.rasterBoundsBuffer = new Buffer(rasterBoundsArray.serialize(), RasterBoundsArray.serialize(), Buffer.BufferType.VERTEX); - this.rasterBoundsVAO = new VertexArrayObject(); -}; -Painter.prototype.clearColor = function () { - var gl = this.gl; - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); -}; -Painter.prototype.clearStencil = function () { - var gl = this.gl; - gl.clearStencil(0); - gl.stencilMask(255); - gl.clear(gl.STENCIL_BUFFER_BIT); -}; -Painter.prototype.clearDepth = function () { - var gl = this.gl; - gl.clearDepth(1); - this.depthMask(true); - gl.clear(gl.DEPTH_BUFFER_BIT); -}; -Painter.prototype._renderTileClippingMasks = function (coords) { - var gl = this.gl; - gl.colorMask(false, false, false, false); - this.depthMask(false); - gl.disable(gl.DEPTH_TEST); - gl.enable(gl.STENCIL_TEST); - gl.stencilMask(248); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); - var idNext = 1; - this._tileClippingMaskIDs = {}; - for (var i = 0; i < coords.length; i++) { - var coord = coords[i]; - var id = this._tileClippingMaskIDs[coord.id] = idNext++ << 3; - gl.stencilFunc(gl.ALWAYS, id, 248); - var pragmas = createUniformPragmas([ - { - name: 'u_color', - components: 4 - }, - { - name: 'u_opacity', - components: 1 - } - ]); - var program = this.useProgram('fill', [], pragmas, pragmas); - gl.uniformMatrix4fv(program.u_matrix, false, coord.posMatrix); - this.tileExtentVAO.bind(gl, program, this.tileExtentBuffer); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.tileExtentBuffer.length); - } - gl.stencilMask(0); - gl.colorMask(true, true, true, true); - this.depthMask(true); - gl.enable(gl.DEPTH_TEST); -}; -Painter.prototype.enableTileClippingMask = function (coord) { - var gl = this.gl; - gl.stencilFunc(gl.EQUAL, this._tileClippingMaskIDs[coord.id], 248); -}; -Painter.prototype.prepareBuffers = function () { -}; -Painter.prototype.bindDefaultFramebuffer = function () { - var gl = this.gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); -}; -var draw = { - symbol: require('./draw_symbol'), - circle: require('./draw_circle'), - line: require('./draw_line'), - fill: require('./draw_fill'), - raster: require('./draw_raster'), - background: require('./draw_background'), - debug: require('./draw_debug') -}; -Painter.prototype.render = function (style, options) { - this.style = style; - this.options = options; - this.lineAtlas = style.lineAtlas; - this.spriteAtlas = style.spriteAtlas; - this.spriteAtlas.setSprite(style.sprite); - this.glyphSource = style.glyphSource; - this.frameHistory.record(this.transform.zoom); - this.prepareBuffers(); - this.clearColor(); - this.clearDepth(); - this.showOverdrawInspector(options.showOverdrawInspector); - this.depthRange = (style._order.length + 2) * this.numSublayers * this.depthEpsilon; - this.renderPass({ isOpaquePass: true }); - this.renderPass({ isOpaquePass: false }); -}; -Painter.prototype.renderPass = function (options) { - var groups = this.style._groups; - var isOpaquePass = options.isOpaquePass; - this.currentLayer = isOpaquePass ? this.style._order.length : -1; - for (var i = 0; i < groups.length; i++) { - var group = groups[isOpaquePass ? groups.length - 1 - i : i]; - var source = this.style.sources[group.source]; - var j; - var coords = []; - if (source) { - coords = source.getVisibleCoordinates(); - for (j = 0; j < coords.length; j++) { - coords[j].posMatrix = this.transform.calculatePosMatrix(coords[j], source.maxzoom); - } - this.clearStencil(); - if (source.prepare) - source.prepare(); - if (source.isTileClipped) { - this._renderTileClippingMasks(coords); - } - } - if (isOpaquePass) { - if (!this._showOverdrawInspector) { - this.gl.disable(this.gl.BLEND); - } - this.isOpaquePass = true; - } else { - this.gl.enable(this.gl.BLEND); - this.isOpaquePass = false; - coords.reverse(); - } - for (j = 0; j < group.length; j++) { - var layer = group[isOpaquePass ? group.length - 1 - j : j]; - this.currentLayer += isOpaquePass ? -1 : 1; - this.renderLayer(this, source, layer, coords); - } - if (source) { - draw.debug(this, source, coords); - } - } -}; -Painter.prototype.depthMask = function (mask) { - if (mask !== this._depthMask) { - this._depthMask = mask; - this.gl.depthMask(mask); - } -}; -Painter.prototype.renderLayer = function (painter, source, layer, coords) { - if (layer.isHidden(this.transform.zoom)) - return; - if (layer.type !== 'background' && !coords.length) - return; - this.id = layer.id; - draw[layer.type](painter, source, layer, coords); -}; -Painter.prototype.setDepthSublayer = function (n) { - var farDepth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon; - var nearDepth = farDepth - 1 + this.depthRange; - this.gl.depthRange(nearDepth, farDepth); -}; -Painter.prototype.translatePosMatrix = function (matrix, tile, translate, anchor) { - if (!translate[0] && !translate[1]) - return matrix; - if (anchor === 'viewport') { - var sinA = Math.sin(-this.transform.angle); - var cosA = Math.cos(-this.transform.angle); - translate = [ - translate[0] * cosA - translate[1] * sinA, - translate[0] * sinA + translate[1] * cosA - ]; - } - var translation = [ - pixelsToTileUnits(tile, translate[0], this.transform.zoom), - pixelsToTileUnits(tile, translate[1], this.transform.zoom), - 0 - ]; - var translatedMatrix = new Float32Array(16); - mat4.translate(translatedMatrix, matrix, translation); - return translatedMatrix; -}; -Painter.prototype.saveTexture = function (texture) { - var textures = this.reusableTextures[texture.size]; - if (!textures) { - this.reusableTextures[texture.size] = [texture]; - } else { - textures.push(texture); - } -}; -Painter.prototype.getTexture = function (size) { - var textures = this.reusableTextures[size]; - return textures && textures.length > 0 ? textures.pop() : null; -}; -Painter.prototype.lineWidth = function (width) { - this.gl.lineWidth(util.clamp(width, this.lineWidthRange[0], this.lineWidthRange[1])); -}; -Painter.prototype.showOverdrawInspector = function (enabled) { - if (!enabled && !this._showOverdrawInspector) - return; - this._showOverdrawInspector = enabled; - var gl = this.gl; - if (enabled) { - gl.blendFunc(gl.CONSTANT_COLOR, gl.ONE); - var numOverdrawSteps = 8; - var a = 1 / numOverdrawSteps; - gl.blendColor(a, a, a, 0); - gl.clearColor(0, 0, 0, 1); - gl.clear(gl.COLOR_BUFFER_BIT); - } else { - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - } -}; -},{"../data/bucket":69,"../data/buffer":74,"../source/pixels_to_tile_units":103,"../source/source_cache":107,"../util/browser":166,"../util/struct_array":180,"../util/util":182,"./create_uniform_pragmas":84,"./draw_background":85,"./draw_circle":86,"./draw_debug":88,"./draw_fill":89,"./draw_line":90,"./draw_raster":91,"./draw_symbol":92,"./frame_history":93,"./painter/use_program":96,"./vertex_array_object":97,"gl-matrix":26}],96:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var shaders = require('mapbox-gl-shaders'); -var utilSource = shaders.util; -module.exports._createProgram = function (name, defines, vertexPragmas, fragmentPragmas) { - var gl = this.gl; - var program = gl.createProgram(); - var definition = shaders[name]; - var definesSource = '#define MAPBOX_GL_JS;\n'; - for (var j = 0; j < defines.length; j++) { - definesSource += '#define ' + defines[j] + ';\n'; - } - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, applyPragmas(definesSource + definition.fragmentSource, fragmentPragmas)); - gl.compileShader(fragmentShader); - gl.attachShader(program, fragmentShader); - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, applyPragmas(definesSource + utilSource + definition.vertexSource, vertexPragmas)); - gl.compileShader(vertexShader); - gl.attachShader(program, vertexShader); - gl.linkProgram(program); - var attributes = {}; - var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); - for (var i = 0; i < numAttributes; i++) { - var attribute = gl.getActiveAttrib(program, i); - attributes[attribute.name] = gl.getAttribLocation(program, attribute.name); - } - var uniforms = {}; - var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - for (var ui = 0; ui < numUniforms; ui++) { - var uniform = gl.getActiveUniform(program, ui); - uniforms[uniform.name] = gl.getUniformLocation(program, uniform.name); - } - return util.extend({ - program: program, - definition: definition, - attributes: attributes, - numAttributes: numAttributes - }, attributes, uniforms); -}; -module.exports._createProgramCached = function (name, defines, vertexPragmas, fragmentPragmas) { - this.cache = this.cache || {}; - var key = JSON.stringify({ - name: name, - defines: defines, - vertexPragmas: vertexPragmas, - fragmentPragmas: fragmentPragmas - }); - if (!this.cache[key]) { - this.cache[key] = this._createProgram(name, defines, vertexPragmas, fragmentPragmas); - } - return this.cache[key]; -}; -module.exports.useProgram = function (nextProgramName, defines, vertexPragmas, fragmentPragmas) { - var gl = this.gl; - defines = defines || []; - if (this._showOverdrawInspector) { - defines = defines.concat('OVERDRAW_INSPECTOR'); - } - var nextProgram = this._createProgramCached(nextProgramName, defines, vertexPragmas, fragmentPragmas); - var previousProgram = this.currentProgram; - if (previousProgram !== nextProgram) { - gl.useProgram(nextProgram.program); - this.currentProgram = nextProgram; - } - return nextProgram; -}; -function applyPragmas(source, pragmas) { - return source.replace(/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g, function (match, operation, precision, type, name) { - return pragmas[operation][name].replace(/{type}/g, type).replace(/{precision}/g, precision); - }); -} -},{"../../util/util":182,"mapbox-gl-shaders":43}],97:[function(require,module,exports){ -'use strict'; -module.exports = VertexArrayObject; -function VertexArrayObject() { - this.boundProgram = null; - this.boundVertexBuffer = null; - this.boundVertexBuffer2 = null; - this.boundElementBuffer = null; - this.vao = null; -} -VertexArrayObject.prototype.bind = function (gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2) { - if (gl.extVertexArrayObject === undefined) { - gl.extVertexArrayObject = gl.getExtension('OES_vertex_array_object'); - } - var isFreshBindRequired = !this.vao || this.boundProgram !== program || this.boundVertexBuffer !== layoutVertexBuffer || this.boundVertexBuffer2 !== vertexBuffer2 || this.boundElementBuffer !== elementBuffer; - if (!gl.extVertexArrayObject || isFreshBindRequired) { - this.freshBind(gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2); - } else { - gl.extVertexArrayObject.bindVertexArrayOES(this.vao); - } -}; -VertexArrayObject.prototype.freshBind = function (gl, program, layoutVertexBuffer, elementBuffer, vertexBuffer2) { - var numPrevAttributes; - var numNextAttributes = program.numAttributes; - if (gl.extVertexArrayObject) { - if (this.vao) - this.destroy(gl); - this.vao = gl.extVertexArrayObject.createVertexArrayOES(); - gl.extVertexArrayObject.bindVertexArrayOES(this.vao); - numPrevAttributes = 0; - this.boundProgram = program; - this.boundVertexBuffer = layoutVertexBuffer; - this.boundVertexBuffer2 = vertexBuffer2; - this.boundElementBuffer = elementBuffer; - } else { - numPrevAttributes = gl.currentNumAttributes || 0; - for (var i = numNextAttributes; i < numPrevAttributes; i++) { - gl.disableVertexAttribArray(i); - } - } - for (var j = numPrevAttributes; j < numNextAttributes; j++) { - gl.enableVertexAttribArray(j); - } - layoutVertexBuffer.bind(gl); - layoutVertexBuffer.setVertexAttribPointers(gl, program); - if (vertexBuffer2) { - vertexBuffer2.bind(gl); - vertexBuffer2.setVertexAttribPointers(gl, program); - } - if (elementBuffer) { - elementBuffer.bind(gl); - } - gl.currentNumAttributes = numNextAttributes; -}; -VertexArrayObject.prototype.unbind = function (gl) { - var ext = gl.extVertexArrayObject; - if (ext) { - ext.bindVertexArrayOES(null); - } -}; -VertexArrayObject.prototype.destroy = function (gl) { - var ext = gl.extVertexArrayObject; - if (ext && this.vao) { - ext.deleteVertexArrayOES(this.vao); - this.vao = null; - } -}; -},{}],98:[function(require,module,exports){ -'use strict'; -var Evented = require('../util/evented'); -var util = require('../util/util'); -var urlResolve = require('resolve-url'); -var EXTENT = require('../data/bucket').EXTENT; -module.exports = GeoJSONSource; -function GeoJSONSource(id, options, dispatcher) { - options = options || {}; - this.id = id; - this.dispatcher = dispatcher; - this._data = options.data; - if (options.maxzoom !== undefined) - this.maxzoom = options.maxzoom; - if (options.type) - this.type = options.type; - var scale = EXTENT / this.tileSize; - this.workerOptions = util.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: EXTENT, - maxZoom: this.maxzoom - }, - superclusterOptions: { - maxZoom: Math.min(options.clusterMaxZoom, this.maxzoom - 1) || this.maxzoom - 1, - extent: EXTENT, - radius: (options.clusterRadius || 50) * scale, - log: false - } - }, options.workerOptions); - this._updateWorkerData(function done(err) { - if (err) { - this.fire('error', { error: err }); - return; - } - this.fire('load'); - }.bind(this)); -} -GeoJSONSource.prototype = util.inherit(Evented, { - type: 'geojson', - minzoom: 0, - maxzoom: 18, - tileSize: 512, - isTileClipped: true, - reparseOverscaled: true, - onAdd: function (map) { - this.map = map; - }, - setData: function (data) { - this._data = data; - this._updateWorkerData(function (err) { - if (err) { - return this.fire('error', { error: err }); - } - this.fire('change'); - }.bind(this)); - return this; - }, - _updateWorkerData: function (callback) { - var options = util.extend({}, this.workerOptions); - var data = this._data; - if (typeof data === 'string') { - options.url = typeof window != 'undefined' ? urlResolve(window.location.href, data) : data; - } else { - options.data = JSON.stringify(data); - } - this.workerID = this.dispatcher.send(this.type + '.loadData', options, function (err) { - this._loaded = true; - callback(err); - }.bind(this)); - }, - loadTile: function (tile, callback) { - var overscaling = tile.coord.z > this.maxzoom ? Math.pow(2, tile.coord.z - this.maxzoom) : 1; - var params = { - type: this.type, - uid: tile.uid, - coord: tile.coord, - zoom: tile.coord.z, - maxZoom: this.maxzoom, - tileSize: this.tileSize, - source: this.id, - overscaling: overscaling, - angle: this.map.transform.angle, - pitch: this.map.transform.pitch, - showCollisionBoxes: this.map.showCollisionBoxes - }; - tile.workerID = this.dispatcher.send('load tile', params, function (err, data) { - tile.unloadVectorData(this.map.painter); - if (tile.aborted) - return; - if (err) { - return callback(err); - } - tile.loadVectorData(data, this.map.style); - if (tile.redoWhenDone) { - tile.redoWhenDone = false; - tile.redoPlacement(this); - } - return callback(null); - }.bind(this), this.workerID); - }, - abortTile: function (tile) { - tile.aborted = true; - }, - unloadTile: function (tile) { - tile.unloadVectorData(this.map.painter); - this.dispatcher.send('remove tile', { - uid: tile.uid, - source: this.id - }, function () { - }, tile.workerID); - }, - serialize: function () { - return { - type: this.type, - data: this._data - }; - } -}); -},{"../data/bucket":69,"../util/evented":174,"../util/util":182,"resolve-url":189}],99:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var ajax = require('../util/ajax'); -var rewind = require('geojson-rewind'); -var GeoJSONWrapper = require('./geojson_wrapper'); -var vtpbf = require('vt-pbf'); -var supercluster = require('supercluster'); -var geojsonvt = require('geojson-vt'); -var VectorTileWorkerSource = require('./vector_tile_worker_source'); -module.exports = GeoJSONWorkerSource; -function GeoJSONWorkerSource(actor, styleLayers, loadGeoJSON) { - if (loadGeoJSON) { - this.loadGeoJSON = loadGeoJSON; - } - VectorTileWorkerSource.call(this, actor, styleLayers); -} -GeoJSONWorkerSource.prototype = util.inherit(VectorTileWorkerSource, { - _geoJSONIndexes: {}, - loadVectorData: function (params, callback) { - var source = params.source, coord = params.coord; - if (!this._geoJSONIndexes[source]) - return callback(null, null); - var geoJSONTile = this._geoJSONIndexes[source].getTile(Math.min(coord.z, params.maxZoom), coord.x, coord.y); - if (geoJSONTile) { - var geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features); - geojsonWrapper.name = '_geojsonTileLayer'; - var pbf = vtpbf({ layers: { '_geojsonTileLayer': geojsonWrapper } }); - if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) { - pbf = new Uint8Array(pbf); - } - callback(null, { - tile: geojsonWrapper, - rawTileData: pbf.buffer - }); - } else { - return callback(null, null); - } - }, - loadData: function (params, callback) { - var handleData = function (err, data) { - if (err) - return callback(err); - if (typeof data != 'object') { - return callback(new Error('Input data is not a valid GeoJSON object.')); - } - rewind(data, true); - this._indexData(data, params, function (err, indexed) { - if (err) { - return callback(err); - } - this._geoJSONIndexes[params.source] = indexed; - callback(null); - }.bind(this)); - }.bind(this); - this.loadGeoJSON(params, handleData); - }, - loadGeoJSON: function (params, callback) { - if (params.url) { - ajax.getJSON(params.url, callback); - } else if (typeof params.data === 'string') { - try { - return callback(null, JSON.parse(params.data)); - } catch (e) { - return callback(new Error('Input data is not a valid GeoJSON object.')); - } - } else { - return callback(new Error('Input data is not a valid GeoJSON object.')); - } - }, - _indexData: function (data, params, callback) { - try { - if (params.cluster) { - callback(null, supercluster(params.superclusterOptions).load(data.features)); - } else { - callback(null, geojsonvt(data, params.geojsonVtOptions)); - } - } catch (err) { - return callback(err); - } - } -}); -},{"../util/ajax":165,"../util/util":182,"./geojson_wrapper":100,"./vector_tile_worker_source":111,"geojson-rewind":17,"geojson-vt":21,"supercluster":191,"vt-pbf":197}],100:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -var VectorTileFeature = require('vector-tile').VectorTileFeature; -var EXTENT = require('../data/bucket').EXTENT; -module.exports = GeoJSONWrapper; -function GeoJSONWrapper(features) { - this.features = features; - this.length = features.length; - this.extent = EXTENT; -} -GeoJSONWrapper.prototype.feature = function (i) { - return new FeatureWrapper(this.features[i]); -}; -function FeatureWrapper(feature) { - this.type = feature.type; - if (feature.type === 1) { - this.rawGeometry = []; - for (var i = 0; i < feature.geometry.length; i++) { - this.rawGeometry.push([feature.geometry[i]]); - } - } else { - this.rawGeometry = feature.geometry; - } - this.properties = feature.tags; - this.extent = EXTENT; -} -FeatureWrapper.prototype.loadGeometry = function () { - var rings = this.rawGeometry; - this.geometry = []; - for (var i = 0; i < rings.length; i++) { - var ring = rings[i], newRing = []; - for (var j = 0; j < ring.length; j++) { - newRing.push(new Point(ring[j][0], ring[j][1])); - } - this.geometry.push(newRing); - } - return this.geometry; -}; -FeatureWrapper.prototype.bbox = function () { - if (!this.geometry) - this.loadGeometry(); - var rings = this.geometry, x1 = Infinity, x2 = -Infinity, y1 = Infinity, 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.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON; -},{"../data/bucket":69,"point-geometry":187,"vector-tile":193}],101:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var TileCoord = require('./tile_coord'); -var LngLat = require('../geo/lng_lat'); -var Point = require('point-geometry'); -var Evented = require('../util/evented'); -var ajax = require('../util/ajax'); -var EXTENT = require('../data/bucket').EXTENT; -var RasterBoundsArray = require('../render/draw_raster').RasterBoundsArray; -var Buffer = require('../data/buffer'); -var VertexArrayObject = require('../render/vertex_array_object'); -module.exports = ImageSource; -function ImageSource(id, options, dispatcher) { - this.id = id; - this.dispatcher = dispatcher; - this.url = options.url; - this.coordinates = options.coordinates; - ajax.getImage(options.url, function (err, image) { - if (err) - return this.fire('error', { error: err }); - this.image = image; - this.image.addEventListener('load', function () { - this.map._rerender(); - }.bind(this)); - this._loaded = true; - this.fire('load'); - if (this.map) { - this.setCoordinates(options.coordinates); - } - }.bind(this)); -} -ImageSource.prototype = util.inherit(Evented, { - minzoom: 0, - maxzoom: 22, - tileSize: 512, - onAdd: function (map) { - this.map = map; - if (this.image) { - this.setCoordinates(this.coordinates); - } - }, - setCoordinates: function (coordinates) { - this.coordinates = coordinates; - var map = this.map; - var cornerZ0Coords = coordinates.map(function (coord) { - return map.transform.locationCoordinate(LngLat.convert(coord)).zoomTo(0); - }); - var centerCoord = this.centerCoord = util.getCoordinatesCenter(cornerZ0Coords); - centerCoord.column = Math.round(centerCoord.column); - centerCoord.row = Math.round(centerCoord.row); - this.minzoom = this.maxzoom = centerCoord.zoom; - this._coord = new TileCoord(centerCoord.zoom, centerCoord.column, centerCoord.row); - this._tileCoords = cornerZ0Coords.map(function (coord) { - var zoomedCoord = coord.zoomTo(centerCoord.zoom); - return new Point(Math.round((zoomedCoord.column - centerCoord.column) * EXTENT), Math.round((zoomedCoord.row - centerCoord.row) * EXTENT)); - }); - this.fire('change'); - return this; - }, - _setTile: function (tile) { - this._prepared = false; - this.tile = tile; - var maxInt16 = 32767; - var array = new RasterBoundsArray(); - array.emplaceBack(this._tileCoords[0].x, this._tileCoords[0].y, 0, 0); - array.emplaceBack(this._tileCoords[1].x, this._tileCoords[1].y, maxInt16, 0); - array.emplaceBack(this._tileCoords[3].x, this._tileCoords[3].y, 0, maxInt16); - array.emplaceBack(this._tileCoords[2].x, this._tileCoords[2].y, maxInt16, maxInt16); - this.tile.buckets = {}; - this.tile.boundsBuffer = new Buffer(array.serialize(), RasterBoundsArray.serialize(), Buffer.BufferType.VERTEX); - this.tile.boundsVAO = new VertexArrayObject(); - this.tile.state = 'loaded'; - }, - prepare: function () { - if (!this._loaded || !this.image || !this.image.complete) - return; - if (!this.tile) - return; - var painter = this.map.painter; - var gl = painter.gl; - if (!this._prepared) { - this.tile.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.tile.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); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.image); - } else { - gl.bindTexture(gl.TEXTURE_2D, this.tile.texture); - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.image); - } - }, - loadTile: function (tile, callback) { - if (this._coord && this._coord.toString() === tile.coord.toString()) { - this._setTile(tile); - callback(null); - } else { - tile.state = 'errored'; - callback(null); - } - }, - serialize: function () { - return { - type: 'image', - urls: this.url, - coordinates: this.coordinates - }; - } -}); -},{"../data/bucket":69,"../data/buffer":74,"../geo/lng_lat":79,"../render/draw_raster":91,"../render/vertex_array_object":97,"../util/ajax":165,"../util/evented":174,"../util/util":182,"./tile_coord":109,"point-geometry":187}],102:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var ajax = require('../util/ajax'); -var browser = require('../util/browser'); -var normalizeURL = require('../util/mapbox').normalizeSourceURL; -module.exports = function (options, callback) { - var loaded = function (err, tileJSON) { - if (err) { - return callback(err); - } - var result = util.pick(tileJSON, [ - 'tiles', - 'minzoom', - 'maxzoom', - 'attribution' - ]); - if (tileJSON.vector_layers) { - result.vectorLayers = tileJSON.vector_layers; - result.vectorLayerIds = result.vectorLayers.map(function (layer) { - return layer.id; - }); - } - callback(null, result); - }; - if (options.url) { - ajax.getJSON(normalizeURL(options.url), loaded); - } else { - browser.frame(loaded.bind(null, null, options)); - } -}; -},{"../util/ajax":165,"../util/browser":166,"../util/mapbox":179,"../util/util":182}],103:[function(require,module,exports){ -'use strict'; -var Bucket = require('../data/bucket'); -module.exports = function (tile, pixelValue, z) { - return pixelValue * (Bucket.EXTENT / (tile.tileSize * Math.pow(2, z - tile.coord.z))); -}; -},{"../data/bucket":69}],104:[function(require,module,exports){ -'use strict'; -var TileCoord = require('./tile_coord'); -exports.rendered = function (sourceCache, styleLayers, queryGeometry, params, zoom, bearing) { - var tilesIn = sourceCache.tilesIn(queryGeometry); - tilesIn.sort(sortTilesIn); - var renderedFeatureLayers = []; - for (var r = 0; r < tilesIn.length; r++) { - var tileIn = tilesIn[r]; - if (!tileIn.tile.featureIndex) - continue; - renderedFeatureLayers.push(tileIn.tile.featureIndex.query({ - queryGeometry: tileIn.queryGeometry, - scale: tileIn.scale, - tileSize: tileIn.tile.tileSize, - bearing: bearing, - params: params - }, styleLayers)); - } - return mergeRenderedFeatureLayers(renderedFeatureLayers); -}; -exports.source = function (sourceCache, params) { - var tiles = sourceCache.renderedIDs().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 = new TileCoord(Math.min(tile.sourceMaxZoom, tile.coord.z), tile.coord.x, tile.coord.y, 0).id; - if (!dataTiles[dataID]) { - dataTiles[dataID] = true; - tile.querySourceFeatures(result, params); - } - } - return result; -}; -function sortTilesIn(a, b) { - var coordA = a.coord; - var coordB = b.coord; - return coordA.z - coordB.z || coordA.y - coordB.y || coordA.w - coordB.w || coordA.x - coordB.x; -} -function mergeRenderedFeatureLayers(tiles) { - var result = tiles[0] || {}; - for (var i = 1; i < tiles.length; i++) { - var tile = tiles[i]; - for (var layerID in tile) { - var tileFeatures = tile[layerID]; - var resultFeatures = result[layerID]; - if (resultFeatures === undefined) { - resultFeatures = result[layerID] = tileFeatures; - } else { - for (var f = 0; f < tileFeatures.length; f++) { - resultFeatures.push(tileFeatures[f]); - } - } - } - } - return result; -} -},{"./tile_coord":109}],105:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var ajax = require('../util/ajax'); -var Evented = require('../util/evented'); -var loadTileJSON = require('./load_tilejson'); -var normalizeURL = require('../util/mapbox').normalizeTileURL; -module.exports = RasterTileSource; -function RasterTileSource(id, options, dispatcher) { - this.id = id; - this.dispatcher = dispatcher; - util.extend(this, util.pick(options, [ - 'url', - 'scheme', - 'tileSize' - ])); - loadTileJSON(options, function (err, tileJSON) { - if (err) { - return this.fire('error', err); - } - util.extend(this, tileJSON); - this.fire('load'); - }.bind(this)); -} -RasterTileSource.prototype = util.inherit(Evented, { - minzoom: 0, - maxzoom: 22, - roundZoom: true, - scheme: 'xyz', - tileSize: 512, - _loaded: false, - onAdd: function (map) { - this.map = map; - }, - serialize: function () { - return { - type: 'raster', - url: this.url, - tileSize: this.tileSize - }; - }, - loadTile: function (tile, callback) { - var url = normalizeURL(tile.coord.url(this.tiles, null, this.scheme), this.url, this.tileSize); - tile.request = ajax.getImage(url, done.bind(this)); - function done(err, img) { - delete tile.request; - if (tile.aborted) - return; - if (err) { - return callback(err); - } - var gl = this.map.painter.gl; - tile.texture = this.map.painter.getTexture(img.width); - if (tile.texture) { - gl.bindTexture(gl.TEXTURE_2D, tile.texture); - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img); - } else { - tile.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, tile.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - 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.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); - tile.texture.size = img.width; - } - gl.generateMipmap(gl.TEXTURE_2D); - this.map.animationLoop.set(this.map.style.rasterFadeDuration); - tile.state = 'loaded'; - callback(null); - } - }, - abortTile: function (tile) { - if (tile.request) { - tile.request.abort(); - delete tile.request; - } - }, - unloadTile: function (tile) { - if (tile.texture) - this.map.painter.saveTexture(tile.texture); - } -}); -},{"../util/ajax":165,"../util/evented":174,"../util/mapbox":179,"../util/util":182,"./load_tilejson":102}],106:[function(require,module,exports){ -'use strict'; -var Evented = require('../util/evented'); -var util = require('../util/util'); -var sourceTypes = { - 'vector': require('../source/vector_tile_source'), - 'raster': require('../source/raster_tile_source'), - 'geojson': require('../source/geojson_source'), - 'video': require('../source/video_source'), - 'image': require('../source/image_source') -}; -var coreTypes = [ - 'vector', - 'raster', - 'geojson', - 'video', - 'image' -]; -var Source = module.exports = util.extend({}, Evented); -Source.create = function (id, source, dispatcher) { - source = new sourceTypes[source.type](id, source, dispatcher); - if (source.id !== id) { - throw new Error('Expected Source id to be ' + id + ' instead of ' + source.id); - } - util.bindAll([ - 'load', - 'abort', - 'unload', - 'serialize', - 'prepare' - ], source); - return source; -}; -Source.getType = function (name) { - return sourceTypes[name]; -}; -Source.setType = function (name, type) { - sourceTypes[name] = type; -}; -Source.getCustomTypeNames = function () { - return Object.keys(sourceTypes).filter(function (type) { - return coreTypes.indexOf(type) < 0; - }); -}; -Source.addType = function (name, SourceType) { - if (Source.getType(name)) { - throw new Error('A source type named ' + name + ' already exists.'); - } - Source.setType(name, SourceType); - Source.fire('_add', { name: name }); -}; -},{"../source/geojson_source":98,"../source/image_source":101,"../source/raster_tile_source":105,"../source/vector_tile_source":110,"../source/video_source":112,"../util/evented":174,"../util/util":182}],107:[function(require,module,exports){ -'use strict'; -var Source = require('./source'); -var Tile = require('./tile'); -var Evented = require('../util/evented'); -var TileCoord = require('./tile_coord'); -var Cache = require('../util/lru_cache'); -var Coordinate = require('../geo/coordinate'); -var util = require('../util/util'); -var EXTENT = require('../data/bucket').EXTENT; -module.exports = SourceCache; -function SourceCache(id, options, dispatcher) { - this.id = id; - this.dispatcher = dispatcher; - var source = this._source = Source.create(id, options, dispatcher).on('load', function () { - if (this.map && this._source.onAdd) { - this._source.onAdd(this.map); - } - this._sourceLoaded = true; - this.tileSize = source.tileSize; - this.minzoom = source.minzoom; - this.maxzoom = source.maxzoom; - this.roundZoom = source.roundZoom; - this.reparseOverscaled = source.reparseOverscaled; - this.isTileClipped = source.isTileClipped; - this.attribution = source.attribution; - this.vectorLayerIds = source.vectorLayerIds; - this.fire('load'); - }.bind(this)).on('error', function (e) { - this._sourceErrored = true; - this.fire('error', e); - }.bind(this)).on('change', function () { - this.reload(); - if (this.transform) { - this.update(this.transform, this.map && this.map.style.rasterFadeDuration); - } - this.fire('change'); - }.bind(this)); - this._tiles = {}; - this._cache = new Cache(0, this.unloadTile.bind(this)); - this._isIdRenderable = this._isIdRenderable.bind(this); -} -SourceCache.maxOverzooming = 10; -SourceCache.maxUnderzooming = 3; -SourceCache.prototype = util.inherit(Evented, { - onAdd: function (map) { - this.map = map; - if (this._source && this._source.onAdd) { - this._source.onAdd(map); - } - }, - loaded: function () { - if (this._sourceErrored) { - return true; - } - if (!this._sourceLoaded) { - return false; - } - for (var t in this._tiles) { - var tile = this._tiles[t]; - if (tile.state !== 'loaded' && tile.state !== 'errored') - return false; - } - return true; - }, - getSource: function () { - return this._source; - }, - loadTile: function (tile, callback) { - return this._source.loadTile(tile, callback); - }, - unloadTile: function (tile) { - if (this._source.unloadTile) - return this._source.unloadTile(tile); - }, - abortTile: function (tile) { - if (this._source.abortTile) - return this._source.abortTile(tile); - }, - serialize: function () { - return this._source.serialize(); - }, - prepare: function () { - if (this._sourceLoaded && this._source.prepare) - return this._source.prepare(); - }, - getIds: function () { - return Object.keys(this._tiles).map(Number).sort(compareKeyZoom); - }, - getRenderableIds: function () { - return this.getIds().filter(this._isIdRenderable); - }, - _isIdRenderable: function (id) { - return this._tiles[id].isRenderable() && !this._coveredTiles[id]; - }, - reload: function () { - this._cache.reset(); - for (var i in this._tiles) { - var tile = this._tiles[i]; - if (tile.state !== 'loading') { - tile.state = 'reloading'; - } - this.loadTile(this._tiles[i], this._tileLoaded.bind(this, this._tiles[i])); - } - }, - _tileLoaded: function (tile, err) { - if (err) { - tile.state = 'errored'; - this.fire('tile.error', { - tile: tile, - error: err - }); - this._source.fire('tile.error', { - tile: tile, - error: err - }); - return; - } - tile.source = this; - tile.timeAdded = new Date().getTime(); - this.fire('tile.load', { tile: tile }); - this._source.fire('tile.load', { tile: tile }); - }, - getTile: function (coord) { - return this.getTileByID(coord.id); - }, - getTileByID: function (id) { - return this._tiles[id]; - }, - getZoom: function (transform) { - return transform.zoom + transform.scaleZoom(transform.tileSize / this.tileSize); - }, - findLoadedChildren: function (coord, maxCoveringZoom, retain) { - var found = false; - for (var id in this._tiles) { - var tile = this._tiles[id]; - if (retain[id] || !tile.isRenderable() || tile.coord.z <= coord.z || tile.coord.z > maxCoveringZoom) - continue; - var z2 = Math.pow(2, Math.min(tile.coord.z, this.maxzoom) - Math.min(coord.z, this.maxzoom)); - if (Math.floor(tile.coord.x / z2) !== coord.x || Math.floor(tile.coord.y / z2) !== coord.y) - continue; - retain[id] = true; - found = true; - while (tile && tile.coord.z - 1 > coord.z) { - var parentId = tile.coord.parent(this.maxzoom).id; - tile = this._tiles[parentId]; - if (tile && tile.isRenderable()) { - delete retain[id]; - retain[parentId] = true; - } - } - } - return found; - }, - findLoadedParent: function (coord, minCoveringZoom, retain) { - for (var z = coord.z - 1; z >= minCoveringZoom; z--) { - coord = coord.parent(this.maxzoom); - var tile = this._tiles[coord.id]; - if (tile && tile.isRenderable()) { - retain[coord.id] = true; - return tile; - } - if (this._cache.has(coord.id)) { - this.addTile(coord); - retain[coord.id] = true; - return this._tiles[coord.id]; - } - } - }, - updateCacheSize: function (transform) { - var widthInTiles = Math.ceil(transform.width / transform.tileSize) + 1; - var heightInTiles = Math.ceil(transform.height / transform.tileSize) + 1; - var approxTilesInView = widthInTiles * heightInTiles; - var commonZoomRange = 5; - this._cache.setMaxSize(Math.floor(approxTilesInView * commonZoomRange)); - }, - update: function (transform, fadeDuration) { - if (!this._sourceLoaded) { - return; - } - var i; - var coord; - var tile; - this.updateCacheSize(transform); - var zoom = (this.roundZoom ? Math.round : Math.floor)(this.getZoom(transform)); - var minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this.minzoom); - var maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this.minzoom); - var retain = {}; - var now = new Date().getTime(); - this._coveredTiles = {}; - var required = this.used ? transform.coveringTiles(this._source) : []; - for (i = 0; i < required.length; i++) { - coord = required[i]; - tile = this.addTile(coord); - retain[coord.id] = true; - if (tile.isRenderable()) - continue; - if (!this.findLoadedChildren(coord, maxCoveringZoom, retain)) { - this.findLoadedParent(coord, minCoveringZoom, retain); - } - } - var parentsForFading = {}; - var ids = Object.keys(retain); - for (var k = 0; k < ids.length; k++) { - var id = ids[k]; - coord = TileCoord.fromID(id); - tile = this._tiles[id]; - if (tile && tile.timeAdded > now - (fadeDuration || 0)) { - if (this.findLoadedChildren(coord, maxCoveringZoom, retain)) { - retain[id] = true; - } - this.findLoadedParent(coord, minCoveringZoom, parentsForFading); - } - } - var fadedParent; - for (fadedParent in parentsForFading) { - if (!retain[fadedParent]) { - this._coveredTiles[fadedParent] = true; - } - } - for (fadedParent in parentsForFading) { - retain[fadedParent] = true; - } - var remove = util.keysDifference(this._tiles, retain); - for (i = 0; i < remove.length; i++) { - this.removeTile(+remove[i]); - } - this.transform = transform; - }, - addTile: function (coord) { - var tile = this._tiles[coord.id]; - if (tile) - return tile; - var wrapped = coord.wrapped(); - tile = this._tiles[wrapped.id]; - if (!tile) { - tile = this._cache.get(wrapped.id); - if (tile && this._redoPlacement) { - this._redoPlacement(tile); - } - } - if (!tile) { - var zoom = coord.z; - var overscaling = zoom > this.maxzoom ? Math.pow(2, zoom - this.maxzoom) : 1; - tile = new Tile(wrapped, this.tileSize * overscaling, this.maxzoom); - this.loadTile(tile, this._tileLoaded.bind(this, tile)); - } - tile.uses++; - this._tiles[coord.id] = tile; - this.fire('tile.add', { tile: tile }); - this._source.fire('tile.add', { tile: tile }); - return tile; - }, - removeTile: function (id) { - var tile = this._tiles[id]; - if (!tile) - return; - tile.uses--; - delete this._tiles[id]; - this.fire('tile.remove', { tile: tile }); - this._source.fire('tile.remove', { tile: tile }); - if (tile.uses > 0) - return; - if (tile.isRenderable()) { - this._cache.add(tile.coord.wrapped().id, tile); - } else { - tile.aborted = true; - this.abortTile(tile); - this.unloadTile(tile); - } - }, - clearTiles: function () { - for (var id in this._tiles) - this.removeTile(id); - this._cache.reset(); - }, - tilesIn: function (queryGeometry) { - var tileResults = {}; - var ids = this.getIds(); - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - var z = queryGeometry[0].zoom; - for (var k = 0; k < queryGeometry.length; k++) { - var p = queryGeometry[k]; - minX = Math.min(minX, p.column); - minY = Math.min(minY, p.row); - maxX = Math.max(maxX, p.column); - maxY = Math.max(maxY, p.row); - } - for (var i = 0; i < ids.length; i++) { - var tile = this._tiles[ids[i]]; - var coord = TileCoord.fromID(ids[i]); - var tileSpaceBounds = [ - coordinateToTilePoint(coord, tile.sourceMaxZoom, new Coordinate(minX, minY, z)), - coordinateToTilePoint(coord, tile.sourceMaxZoom, new Coordinate(maxX, maxY, z)) - ]; - if (tileSpaceBounds[0].x < EXTENT && tileSpaceBounds[0].y < EXTENT && tileSpaceBounds[1].x >= 0 && tileSpaceBounds[1].y >= 0) { - var tileSpaceQueryGeometry = []; - for (var j = 0; j < queryGeometry.length; j++) { - tileSpaceQueryGeometry.push(coordinateToTilePoint(coord, tile.sourceMaxZoom, queryGeometry[j])); - } - var tileResult = tileResults[tile.coord.id]; - if (tileResult === undefined) { - tileResult = tileResults[tile.coord.id] = { - tile: tile, - coord: coord, - queryGeometry: [], - scale: Math.pow(2, this.transform.zoom - tile.coord.z) - }; - } - tileResult.queryGeometry.push(tileSpaceQueryGeometry); - } - } - var results = []; - for (var t in tileResults) { - results.push(tileResults[t]); - } - return results; - }, - redoPlacement: function () { - var ids = this.getIds(); - for (var i = 0; i < ids.length; i++) { - var tile = this.getTileByID(ids[i]); - tile.redoPlacement(this); - } - }, - getVisibleCoordinates: function () { - return this.getRenderableIds().map(TileCoord.fromID); - } -}); -function coordinateToTilePoint(tileCoord, sourceMaxZoom, coord) { - var zoomedCoord = coord.zoomTo(Math.min(tileCoord.z, sourceMaxZoom)); - return { - x: (zoomedCoord.column - (tileCoord.x + tileCoord.w * Math.pow(2, tileCoord.z))) * EXTENT, - y: (zoomedCoord.row - tileCoord.y) * EXTENT - }; -} -function compareKeyZoom(a, b) { - return a % 32 - b % 32; -} -},{"../data/bucket":69,"../geo/coordinate":78,"../util/evented":174,"../util/lru_cache":178,"../util/util":182,"./source":106,"./tile":108,"./tile_coord":109}],108:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var Bucket = require('../data/bucket'); -var FeatureIndex = require('../data/feature_index'); -var vt = require('vector-tile'); -var Protobuf = require('pbf'); -var GeoJSONFeature = require('../util/vectortile_to_geojson'); -var featureFilter = require('feature-filter'); -var CollisionTile = require('../symbol/collision_tile'); -var CollisionBoxArray = require('../symbol/collision_box'); -var SymbolInstancesArray = require('../symbol/symbol_instances'); -var SymbolQuadsArray = require('../symbol/symbol_quads'); -module.exports = Tile; -function Tile(coord, size, sourceMaxZoom) { - this.coord = coord; - this.uid = util.uniqueId(); - this.uses = 0; - this.tileSize = size; - this.sourceMaxZoom = sourceMaxZoom; - this.buckets = {}; - this.state = 'loading'; -} -Tile.prototype = { - loadVectorData: function (data, style) { - this.state = 'loaded'; - if (!data) - return; - this.collisionBoxArray = new CollisionBoxArray(data.collisionBoxArray); - this.collisionTile = new CollisionTile(data.collisionTile, this.collisionBoxArray); - this.symbolInstancesArray = new SymbolInstancesArray(data.symbolInstancesArray); - this.symbolQuadsArray = new SymbolQuadsArray(data.symbolQuadsArray); - this.featureIndex = new FeatureIndex(data.featureIndex, data.rawTileData, this.collisionTile); - this.rawTileData = data.rawTileData; - this.buckets = unserializeBuckets(data.buckets, style); - }, - reloadSymbolData: function (data, painter, style) { - if (this.state === 'unloaded') - return; - this.collisionTile = new CollisionTile(data.collisionTile, this.collisionBoxArray); - this.featureIndex.setCollisionTile(this.collisionTile); - for (var id in this.buckets) { - var bucket = this.buckets[id]; - if (bucket.type === 'symbol') { - bucket.destroy(painter.gl); - delete this.buckets[id]; - } - } - util.extend(this.buckets, unserializeBuckets(data.buckets, style)); - }, - unloadVectorData: function (painter) { - for (var id in this.buckets) { - var bucket = this.buckets[id]; - bucket.destroy(painter.gl); - } - this.collisionBoxArray = null; - this.symbolQuadsArray = null; - this.symbolInstancesArray = null; - this.collisionTile = null; - this.featureIndex = null; - this.rawTileData = null; - this.buckets = null; - this.state = 'unloaded'; - }, - redoPlacement: function (source) { - if (this.state !== 'loaded' || this.state === 'reloading') { - this.redoWhenDone = true; - return; - } - this.state = 'reloading'; - source.dispatcher.send('redo placement', { - uid: this.uid, - source: source.id, - angle: source.map.transform.angle, - pitch: source.map.transform.pitch, - showCollisionBoxes: source.map.showCollisionBoxes - }, done.bind(this), this.workerID); - function done(_, data) { - this.reloadSymbolData(data, source.map.painter, source.map.style); - source.fire('tile.load', { tile: this }); - this.state = 'loaded'; - if (this.redoWhenDone) { - this.redoPlacement(source); - this.redoWhenDone = false; - } - } - }, - getBucket: function (layer) { - return this.buckets && this.buckets[layer.ref || layer.id]; - }, - querySourceFeatures: function (result, params) { - if (!this.rawTileData) - return; - if (!this.vtLayers) { - this.vtLayers = new vt.VectorTile(new Protobuf(new Uint8Array(this.rawTileData))).layers; - } - var layer = this.vtLayers._geojsonTileLayer || this.vtLayers[params.sourceLayer]; - if (!layer) - return; - var filter = featureFilter(params.filter); - var coord = { - z: this.coord.z, - x: this.coord.x, - y: this.coord.y - }; - for (var i = 0; i < layer.length; i++) { - var feature = layer.feature(i); - if (filter(feature)) { - var geojsonFeature = new GeoJSONFeature(feature, this.coord.z, this.coord.x, this.coord.y); - geojsonFeature.tile = coord; - result.push(geojsonFeature); - } - } - }, - isRenderable: function () { - return this.state === 'loaded' || this.state === 'reloading'; - } -}; -function unserializeBuckets(input, style) { - if (!style) - return; - var output = {}; - for (var i = 0; i < input.length; i++) { - var layer = style.getLayer(input[i].layerId); - if (!layer) - continue; - var bucket = Bucket.create(util.extend({ - layer: layer, - childLayers: input[i].childLayerIds.map(style.getLayer.bind(style)).filter(function (layer) { - return layer; - }) - }, input[i])); - output[bucket.id] = bucket; - } - return output; -} -},{"../data/bucket":69,"../data/feature_index":76,"../symbol/collision_box":134,"../symbol/collision_tile":136,"../symbol/symbol_instances":145,"../symbol/symbol_quads":146,"../util/util":182,"../util/vectortile_to_geojson":183,"feature-filter":15,"pbf":186,"vector-tile":193}],109:[function(require,module,exports){ -'use strict'; -var WhooTS = require('whoots-js'); -var Coordinate = require('../geo/coordinate'); -module.exports = TileCoord; -function TileCoord(z, x, y, w) { - if (isNaN(w)) - w = 0; - this.z = +z; - this.x = +x; - this.y = +y; - this.w = +w; - w *= 2; - if (w < 0) - w = w * -1 - 1; - var dim = 1 << this.z; - this.id = (dim * dim * w + dim * this.y + this.x) * 32 + this.z; - this.posMatrix = null; -} -TileCoord.prototype.toString = function () { - return this.z + '/' + this.x + '/' + this.y; -}; -TileCoord.prototype.toCoordinate = function (sourceMaxZoom) { - var zoom = Math.min(this.z, sourceMaxZoom); - var tileScale = Math.pow(2, zoom); - var row = this.y; - var column = this.x + tileScale * this.w; - return new Coordinate(column, row, zoom); -}; -TileCoord.fromID = function (id) { - var z = id % 32, dim = 1 << z; - var xy = (id - z) / 32; - var x = xy % dim, y = (xy - x) / dim % dim; - var w = Math.floor(xy / (dim * dim)); - if (w % 2 !== 0) - w = w * -1 - 1; - w /= 2; - return new TileCoord(z, x, y, w); -}; -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; -} -TileCoord.prototype.url = function (urls, sourceMaxZoom, scheme) { - var bbox = WhooTS.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}', Math.min(this.z, sourceMaxZoom || this.z)).replace('{x}', this.x).replace('{y}', scheme === 'tms' ? Math.pow(2, this.z) - this.y - 1 : this.y).replace('{quadkey}', quadkey).replace('{bbox-epsg-3857}', bbox); -}; -TileCoord.prototype.parent = function (sourceMaxZoom) { - if (this.z === 0) - return null; - if (this.z > sourceMaxZoom) { - return new TileCoord(this.z - 1, this.x, this.y, this.w); - } - return new TileCoord(this.z - 1, Math.floor(this.x / 2), Math.floor(this.y / 2), this.w); -}; -TileCoord.prototype.wrapped = function () { - return new TileCoord(this.z, this.x, this.y, 0); -}; -TileCoord.prototype.children = function (sourceMaxZoom) { - if (this.z >= sourceMaxZoom) { - return [new TileCoord(this.z + 1, this.x, this.y, this.w)]; - } - var z = this.z + 1; - var x = this.x * 2; - var y = this.y * 2; - return [ - new TileCoord(z, x, y, this.w), - new TileCoord(z, x + 1, y, this.w), - new TileCoord(z, x, y + 1, this.w), - new TileCoord(z, x + 1, y + 1, this.w) - ]; -}; -function edge(a, b) { - if (a.row > b.row) { - var t = a; - a = b; - b = t; - } - return { - x0: a.column, - y0: a.row, - x1: b.column, - y1: b.row, - dx: b.column - a.column, - dy: b.row - a.row - }; -} -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); -} -TileCoord.cover = function (z, bounds, actualZ) { - var tiles = 1 << z; - var t = {}; - function scanLine(x0, x1, y) { - var x, wx, coord; - if (y >= 0 && y <= tiles) { - for (x = x0; x < x1; x++) { - wx = (x % tiles + tiles) % tiles; - coord = new TileCoord(actualZ, wx, y, Math.floor(x / tiles)); - t[coord.id] = coord; - } - } - } - scanTriangle(bounds[0], bounds[1], bounds[2], 0, tiles, scanLine); - scanTriangle(bounds[2], bounds[3], bounds[0], 0, tiles, scanLine); - return Object.keys(t).map(function (id) { - return t[id]; - }); -}; -},{"../geo/coordinate":78,"whoots-js":202}],110:[function(require,module,exports){ -'use strict'; -var Evented = require('../util/evented'); -var util = require('../util/util'); -var loadTileJSON = require('./load_tilejson'); -var normalizeURL = require('../util/mapbox').normalizeTileURL; -module.exports = VectorTileSource; -function VectorTileSource(id, options, dispatcher) { - this.id = id; - this.dispatcher = dispatcher; - util.extend(this, util.pick(options, [ - 'url', - 'scheme', - 'tileSize' - ])); - this._options = util.extend({ type: 'vector' }, options); - if (this.tileSize !== 512) { - throw new Error('vector tile sources must have a tileSize of 512'); - } - loadTileJSON(options, function (err, tileJSON) { - if (err) { - this.fire('error', err); - return; - } - util.extend(this, tileJSON); - this.fire('load'); - }.bind(this)); -} -VectorTileSource.prototype = util.inherit(Evented, { - minzoom: 0, - maxzoom: 22, - scheme: 'xyz', - tileSize: 512, - reparseOverscaled: true, - isTileClipped: true, - onAdd: function (map) { - this.map = map; - }, - serialize: function () { - return util.extend({}, this._options); - }, - loadTile: function (tile, callback) { - var overscaling = tile.coord.z > this.maxzoom ? Math.pow(2, tile.coord.z - this.maxzoom) : 1; - var params = { - url: normalizeURL(tile.coord.url(this.tiles, this.maxzoom, this.scheme), this.url), - uid: tile.uid, - coord: tile.coord, - zoom: tile.coord.z, - tileSize: this.tileSize * overscaling, - source: this.id, - overscaling: overscaling, - angle: this.map.transform.angle, - pitch: this.map.transform.pitch, - showCollisionBoxes: this.map.showCollisionBoxes - }; - if (tile.workerID) { - if (tile.state === 'loading') { - tile.reloadCallback = callback; - } else { - params.rawTileData = tile.rawTileData; - this.dispatcher.send('reload tile', params, done.bind(this), tile.workerID); - } - } else { - tile.workerID = this.dispatcher.send('load tile', params, done.bind(this)); - } - function done(err, data) { - if (tile.aborted) - return; - if (err) { - return callback(err); - } - tile.loadVectorData(data, this.map.style); - if (tile.redoWhenDone) { - tile.redoWhenDone = false; - tile.redoPlacement(this); - } - callback(null); - if (tile.reloadCallback) { - this.loadTile(tile, tile.reloadCallback); - tile.reloadCallback = null; - } - } - }, - abortTile: function (tile) { - this.dispatcher.send('abort tile', { - uid: tile.uid, - source: this.id - }, null, tile.workerID); - }, - unloadTile: function (tile) { - tile.unloadVectorData(this.map.painter); - this.dispatcher.send('remove tile', { - uid: tile.uid, - source: this.id - }, null, tile.workerID); - } -}); -},{"../util/evented":174,"../util/mapbox":179,"../util/util":182,"./load_tilejson":102}],111:[function(require,module,exports){ -'use strict'; -var ajax = require('../util/ajax'); -var vt = require('vector-tile'); -var Protobuf = require('pbf'); -var WorkerTile = require('./worker_tile'); -module.exports = VectorTileWorkerSource; -function VectorTileWorkerSource(actor, styleLayers, loadVectorData) { - this.actor = actor; - this.styleLayers = styleLayers; - if (loadVectorData) { - this.loadVectorData = loadVectorData; - } - this.loading = {}; - this.loaded = {}; -} -VectorTileWorkerSource.prototype = { - loadTile: function (params, callback) { - var source = params.source, uid = params.uid; - if (!this.loading[source]) - this.loading[source] = {}; - var tile = this.loading[source][uid] = new WorkerTile(params); - tile.abort = this.loadVectorData(params, done.bind(this)); - function done(err, data) { - delete this.loading[source][uid]; - if (err) - return callback(err); - if (!data) - return callback(null, null); - tile.data = data.tile; - tile.parse(tile.data, this.styleLayers.getLayerFamilies(), this.actor, data.rawTileData, callback); - this.loaded[source] = this.loaded[source] || {}; - this.loaded[source][uid] = tile; - } - }, - reloadTile: function (params, callback) { - var loaded = this.loaded[params.source], uid = params.uid; - if (loaded && loaded[uid]) { - var tile = loaded[uid]; - tile.parse(tile.data, this.styleLayers.getLayerFamilies(), this.actor, params.rawTileData, callback); - } - }, - abortTile: function (params) { - var loading = this.loading[params.source], uid = params.uid; - if (loading && loading[uid] && loading[uid].abort) { - loading[uid].abort(); - delete loading[uid]; - } - }, - removeTile: function (params) { - var loaded = this.loaded[params.source], uid = params.uid; - if (loaded && loaded[uid]) { - delete loaded[uid]; - } - }, - loadVectorData: function (params, callback) { - var xhr = ajax.getArrayBuffer(params.url, done.bind(this)); - return function abort() { - xhr.abort(); - }; - function done(err, data) { - if (err) { - return callback(err); - } - var tile = new vt.VectorTile(new Protobuf(new Uint8Array(data))); - callback(err, { - tile: tile, - rawTileData: data - }); - } - }, - redoPlacement: function (params, callback) { - var loaded = this.loaded[params.source], loading = this.loading[params.source], uid = params.uid; - if (loaded && loaded[uid]) { - var tile = loaded[uid]; - var result = tile.redoPlacement(params.angle, params.pitch, params.showCollisionBoxes); - if (result.result) { - callback(null, result.result, result.transferables); - } - } else if (loading && loading[uid]) { - loading[uid].angle = params.angle; - } - } -}; -},{"../util/ajax":165,"./worker_tile":114,"pbf":186,"vector-tile":193}],112:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var TileCoord = require('./tile_coord'); -var LngLat = require('../geo/lng_lat'); -var Point = require('point-geometry'); -var Evented = require('../util/evented'); -var ajax = require('../util/ajax'); -var EXTENT = require('../data/bucket').EXTENT; -var RasterBoundsArray = require('../render/draw_raster').RasterBoundsArray; -var Buffer = require('../data/buffer'); -var VertexArrayObject = require('../render/vertex_array_object'); -module.exports = VideoSource; -function VideoSource(id, options) { - this.id = id; - this.urls = options.urls; - this.coordinates = options.coordinates; - ajax.getVideo(options.urls, function (err, video) { - if (err) - return this.fire('error', { error: err }); - this.video = video; - this.video.loop = true; - var loopID; - this.video.addEventListener('playing', function () { - loopID = this.map.style.animationLoop.set(Infinity); - this.map._rerender(); - }.bind(this)); - this.video.addEventListener('pause', function () { - this.map.style.animationLoop.cancel(loopID); - }.bind(this)); - if (this.map) { - this.video.play(); - this.setCoordinates(options.coordinates); - } - this.fire('load'); - }.bind(this)); -} -VideoSource.prototype = util.inherit(Evented, { - minzoom: 0, - maxzoom: 22, - tileSize: 512, - roundZoom: true, - getVideo: function () { - return this.video; - }, - onAdd: function (map) { - if (this.map) - return; - this.map = map; - if (this.video) { - this.video.play(); - this.setCoordinates(this.coordinates); - } - }, - setCoordinates: function (coordinates) { - this.coordinates = coordinates; - var map = this.map; - var cornerZ0Coords = coordinates.map(function (coord) { - return map.transform.locationCoordinate(LngLat.convert(coord)).zoomTo(0); - }); - var centerCoord = this.centerCoord = util.getCoordinatesCenter(cornerZ0Coords); - centerCoord.column = Math.round(centerCoord.column); - centerCoord.row = Math.round(centerCoord.row); - this.minzoom = this.maxzoom = centerCoord.zoom; - this._coord = new TileCoord(centerCoord.zoom, centerCoord.column, centerCoord.row); - this._tileCoords = cornerZ0Coords.map(function (coord) { - var zoomedCoord = coord.zoomTo(centerCoord.zoom); - return new Point(Math.round((zoomedCoord.column - centerCoord.column) * EXTENT), Math.round((zoomedCoord.row - centerCoord.row) * EXTENT)); - }); - this.fire('change'); - return this; - }, - _setTile: function (tile) { - this._prepared = false; - this.tile = tile; - var maxInt16 = 32767; - var array = new RasterBoundsArray(); - array.emplaceBack(this._tileCoords[0].x, this._tileCoords[0].y, 0, 0); - array.emplaceBack(this._tileCoords[1].x, this._tileCoords[1].y, maxInt16, 0); - array.emplaceBack(this._tileCoords[3].x, this._tileCoords[3].y, 0, maxInt16); - array.emplaceBack(this._tileCoords[2].x, this._tileCoords[2].y, maxInt16, maxInt16); - this.tile.buckets = {}; - this.tile.boundsBuffer = new Buffer(array.serialize(), RasterBoundsArray.serialize(), Buffer.BufferType.VERTEX); - this.tile.boundsVAO = new VertexArrayObject(); - this.tile.state = 'loaded'; - }, - prepare: function () { - if (this.video.readyState < 2) - return; - if (!this.tile) - return; - var gl = this.map.painter.gl; - if (!this._prepared) { - this._prepared = true; - this.tile.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.tile.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); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.video); - } else { - gl.bindTexture(gl.TEXTURE_2D, this.tile.texture); - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.video); - } - this._currentTime = this.video.currentTime; - }, - loadTile: function (tile, callback) { - if (this._coord && this._coord.toString() === tile.coord.toString()) { - this._setTile(tile); - callback(null); - } else { - tile.state = 'errored'; - callback(null); - } - }, - serialize: function () { - return { - type: 'video', - urls: this.urls, - coordinates: this.coordinates - }; - } -}); -},{"../data/bucket":69,"../data/buffer":74,"../geo/lng_lat":79,"../render/draw_raster":91,"../render/vertex_array_object":97,"../util/ajax":165,"../util/evented":174,"../util/util":182,"./tile_coord":109,"point-geometry":187}],113:[function(require,module,exports){ -'use strict'; -var Actor = require('../util/actor'); -var StyleLayer = require('../style/style_layer'); -var util = require('../util/util'); -var VectorTileWorkerSource = require('./vector_tile_worker_source'); -var GeoJSONWorkerSource = require('./geojson_worker_source'); -module.exports = function createWorker(self) { - return new Worker(self); -}; -function Worker(self) { - this.self = self; - this.actor = new Actor(self, this); - var styleLayers = { - getLayers: function () { - return this.layers; - }.bind(this), - getLayerFamilies: function () { - return this.layerFamilies; - }.bind(this) - }; - this.workerSources = { - vector: new VectorTileWorkerSource(this.actor, styleLayers), - geojson: new GeoJSONWorkerSource(this.actor, styleLayers) - }; - this.self.registerWorkerSource = function (name, WorkerSource) { - if (this.workerSources[name]) { - util.warnOnce('Worker source named "' + name + '" already registered.'); - } - this.workerSources[name] = new WorkerSource(this.actor, styleLayers); - }.bind(this); -} -util.extend(Worker.prototype, { - 'set layers': function (layers) { - this.layers = {}; - var that = this; - var childLayerIndicies = []; - for (var i = 0; i < layers.length; i++) { - var layer = layers[i]; - if (layer.type === 'fill' || layer.type === 'line' || layer.type === 'circle' || layer.type === 'symbol') { - if (layer.ref) { - childLayerIndicies.push(i); - } else { - setLayer(layer); - } - } - } - for (var j = 0; j < childLayerIndicies.length; j++) { - setLayer(layers[childLayerIndicies[j]]); - } - function setLayer(serializedLayer) { - var styleLayer = StyleLayer.create(serializedLayer, serializedLayer.ref && that.layers[serializedLayer.ref]); - styleLayer.updatePaintTransitions({}, { transition: false }); - that.layers[styleLayer.id] = styleLayer; - } - this.layerFamilies = createLayerFamilies(this.layers); - }, - 'update layers': function (layers) { - var that = this; - var id; - var layer; - for (id in layers) { - layer = layers[id]; - if (layer.ref) - updateLayer(layer); - } - for (id in layers) { - layer = layers[id]; - if (!layer.ref) - updateLayer(layer); - } - function updateLayer(layer) { - var refLayer = that.layers[layer.ref]; - if (that.layers[layer.id]) { - that.layers[layer.id].set(layer, refLayer); - } else { - that.layers[layer.id] = StyleLayer.create(layer, refLayer); - } - that.layers[layer.id].updatePaintTransitions({}, { transition: false }); - } - this.layerFamilies = createLayerFamilies(this.layers); - }, - 'load tile': function (params, callback) { - var type = params.type || 'vector'; - this.workerSources[type].loadTile(params, callback); - }, - 'reload tile': function (params, callback) { - var type = params.type || 'vector'; - this.workerSources[type].reloadTile(params, callback); - }, - 'abort tile': function (params) { - var type = params.type || 'vector'; - this.workerSources[type].abortTile(params); - }, - 'remove tile': function (params) { - var type = params.type || 'vector'; - this.workerSources[type].removeTile(params); - }, - 'redo placement': function (params, callback) { - var type = params.type || 'vector'; - this.workerSources[type].redoPlacement(params, callback); - }, - 'load worker source': function (params, callback) { - try { - this.self.importScripts(params.url); - callback(); - } catch (e) { - callback(e); - } - } -}); -function createLayerFamilies(layers) { - var families = {}; - for (var layerId in layers) { - var layer = layers[layerId]; - var parentLayerId = layer.ref || layer.id; - var parentLayer = layers[parentLayerId]; - if (parentLayer.layout && parentLayer.layout.visibility === 'none') - continue; - families[parentLayerId] = families[parentLayerId] || []; - if (layerId === parentLayerId) { - families[parentLayerId].unshift(layer); - } else { - families[parentLayerId].push(layer); - } - } - return families; -} -},{"../style/style_layer":121,"../util/actor":164,"../util/util":182,"./geojson_worker_source":99,"./vector_tile_worker_source":111}],114:[function(require,module,exports){ -'use strict'; -var FeatureIndex = require('../data/feature_index'); -var CollisionTile = require('../symbol/collision_tile'); -var Bucket = require('../data/bucket'); -var CollisionBoxArray = require('../symbol/collision_box'); -var DictionaryCoder = require('../util/dictionary_coder'); -var util = require('../util/util'); -var SymbolInstancesArray = require('../symbol/symbol_instances'); -var SymbolQuadsArray = require('../symbol/symbol_quads'); -module.exports = WorkerTile; -function WorkerTile(params) { - this.coord = params.coord; - this.uid = params.uid; - this.zoom = params.zoom; - this.tileSize = params.tileSize; - this.source = params.source; - this.overscaling = params.overscaling; - this.angle = params.angle; - this.pitch = params.pitch; - this.showCollisionBoxes = params.showCollisionBoxes; -} -WorkerTile.prototype.parse = function (data, layerFamilies, actor, rawTileData, callback) { - this.status = 'parsing'; - this.data = data; - this.collisionBoxArray = new CollisionBoxArray(); - this.symbolInstancesArray = new SymbolInstancesArray(); - this.symbolQuadsArray = new SymbolQuadsArray(); - var collisionTile = new CollisionTile(this.angle, this.pitch, this.collisionBoxArray); - var featureIndex = new FeatureIndex(this.coord, this.overscaling, collisionTile, data.layers); - var sourceLayerCoder = new DictionaryCoder(data.layers ? Object.keys(data.layers).sort() : ['_geojsonTileLayer']); - var tile = this; - var bucketsById = {}; - var bucketsBySourceLayer = {}; - var i; - var layer; - var sourceLayerId; - var bucket; - var bucketIndex = 0; - for (var layerId in layerFamilies) { - layer = layerFamilies[layerId][0]; - if (layer.source !== this.source) - continue; - if (layer.ref) - continue; - if (layer.minzoom && this.zoom < layer.minzoom) - continue; - if (layer.maxzoom && this.zoom >= layer.maxzoom) - continue; - if (layer.layout && layer.layout.visibility === 'none') - continue; - if (data.layers && !data.layers[layer.sourceLayer]) - continue; - bucket = Bucket.create({ - layer: layer, - index: bucketIndex++, - childLayers: layerFamilies[layerId], - zoom: this.zoom, - overscaling: this.overscaling, - showCollisionBoxes: this.showCollisionBoxes, - collisionBoxArray: this.collisionBoxArray, - symbolQuadsArray: this.symbolQuadsArray, - symbolInstancesArray: this.symbolInstancesArray, - sourceLayerIndex: sourceLayerCoder.encode(layer.sourceLayer || '_geojsonTileLayer') - }); - bucket.createFilter(); - bucketsById[layer.id] = bucket; - if (data.layers) { - sourceLayerId = layer.sourceLayer; - bucketsBySourceLayer[sourceLayerId] = bucketsBySourceLayer[sourceLayerId] || {}; - bucketsBySourceLayer[sourceLayerId][layer.id] = bucket; - } - } - if (data.layers) { - for (sourceLayerId in bucketsBySourceLayer) { - if (layer.version === 1) { - util.warnOnce('Vector tile source "' + this.source + '" layer "' + sourceLayerId + '" does not use vector tile spec v2 ' + 'and therefore may have some rendering errors.'); - } - layer = data.layers[sourceLayerId]; - if (layer) { - sortLayerIntoBuckets(layer, bucketsBySourceLayer[sourceLayerId]); - } - } - } else { - sortLayerIntoBuckets(data, bucketsById); - } - function sortLayerIntoBuckets(layer, buckets) { - for (var i = 0; i < layer.length; i++) { - var feature = layer.feature(i); - feature.index = i; - for (var id in buckets) { - if (buckets[id].filter(feature)) - buckets[id].features.push(feature); - } - } - } - var buckets = [], symbolBuckets = this.symbolBuckets = [], otherBuckets = []; - featureIndex.bucketLayerIDs = {}; - for (var id in bucketsById) { - bucket = bucketsById[id]; - if (bucket.features.length === 0) - continue; - featureIndex.bucketLayerIDs[bucket.index] = bucket.childLayers.map(getLayerId); - buckets.push(bucket); - if (bucket.type === 'symbol') - symbolBuckets.push(bucket); - else - otherBuckets.push(bucket); - } - var icons = {}; - var stacks = {}; - var deps = 0; - if (symbolBuckets.length > 0) { - for (i = symbolBuckets.length - 1; i >= 0; i--) { - symbolBuckets[i].updateIcons(icons); - symbolBuckets[i].updateFont(stacks); - } - for (var fontName in stacks) { - stacks[fontName] = Object.keys(stacks[fontName]).map(Number); - } - icons = Object.keys(icons); - actor.send('get glyphs', { - uid: this.uid, - stacks: stacks - }, function (err, newStacks) { - stacks = newStacks; - gotDependency(err); - }); - if (icons.length) { - actor.send('get icons', { icons: icons }, function (err, newIcons) { - icons = newIcons; - gotDependency(err); - }); - } else { - gotDependency(); - } - } - for (i = otherBuckets.length - 1; i >= 0; i--) { - parseBucket(this, otherBuckets[i]); - } - if (symbolBuckets.length === 0) - return done(); - function gotDependency(err) { - if (err) - return callback(err); - deps++; - if (deps === 2) { - for (var i = symbolBuckets.length - 1; i >= 0; i--) { - parseBucket(tile, symbolBuckets[i]); - } - done(); - } - } - function parseBucket(tile, bucket) { - bucket.populateArrays(collisionTile, stacks, icons); - if (bucket.type !== 'symbol') { - for (var i = 0; i < bucket.features.length; i++) { - var feature = bucket.features[i]; - featureIndex.insert(feature, feature.index, bucket.sourceLayerIndex, bucket.index); - } - } - bucket.features = null; - } - function done() { - tile.status = 'done'; - if (tile.redoPlacementAfterDone) { - tile.redoPlacement(tile.angle, tile.pitch, null); - tile.redoPlacementAfterDone = false; - } - var featureIndex_ = featureIndex.serialize(); - var collisionTile_ = collisionTile.serialize(); - var collisionBoxArray = tile.collisionBoxArray.serialize(); - var symbolInstancesArray = tile.symbolInstancesArray.serialize(); - var symbolQuadsArray = tile.symbolQuadsArray.serialize(); - var transferables = [rawTileData].concat(featureIndex_.transferables).concat(collisionTile_.transferables); - var nonEmptyBuckets = buckets.filter(isBucketNonEmpty); - callback(null, { - buckets: nonEmptyBuckets.map(serializeBucket), - featureIndex: featureIndex_.data, - collisionTile: collisionTile_.data, - collisionBoxArray: collisionBoxArray, - symbolInstancesArray: symbolInstancesArray, - symbolQuadsArray: symbolQuadsArray, - rawTileData: rawTileData - }, getTransferables(nonEmptyBuckets).concat(transferables)); - } -}; -WorkerTile.prototype.redoPlacement = function (angle, pitch, showCollisionBoxes) { - if (this.status !== 'done') { - this.redoPlacementAfterDone = true; - this.angle = angle; - return {}; - } - var collisionTile = new CollisionTile(angle, pitch, this.collisionBoxArray); - var buckets = this.symbolBuckets; - for (var i = buckets.length - 1; i >= 0; i--) { - buckets[i].placeFeatures(collisionTile, showCollisionBoxes); - } - var collisionTile_ = collisionTile.serialize(); - var nonEmptyBuckets = buckets.filter(isBucketNonEmpty); - return { - result: { - buckets: nonEmptyBuckets.map(serializeBucket), - collisionTile: collisionTile_.data - }, - transferables: getTransferables(nonEmptyBuckets).concat(collisionTile_.transferables) - }; -}; -function isBucketNonEmpty(bucket) { - return !bucket.isEmpty(); -} -function serializeBucket(bucket) { - return bucket.serialize(); -} -function getTransferables(buckets) { - var transferables = []; - for (var i in buckets) { - buckets[i].getTransferables(transferables); - } - return transferables; -} -function getLayerId(layer) { - return layer.id; -} -},{"../data/bucket":69,"../data/feature_index":76,"../symbol/collision_box":134,"../symbol/collision_tile":136,"../symbol/symbol_instances":145,"../symbol/symbol_quads":146,"../util/dictionary_coder":172,"../util/util":182}],115:[function(require,module,exports){ -'use strict'; -module.exports = AnimationLoop; -function AnimationLoop() { - this.n = 0; - this.times = []; -} -AnimationLoop.prototype.stopped = function () { - this.times = this.times.filter(function (t) { - return t.time >= new Date().getTime(); - }); - return !this.times.length; -}; -AnimationLoop.prototype.set = function (t) { - this.times.push({ - id: this.n, - time: t + new Date().getTime() - }); - return this.n++; -}; -AnimationLoop.prototype.cancel = function (n) { - this.times = this.times.filter(function (t) { - return t.id !== n; - }); -}; -},{}],116:[function(require,module,exports){ -'use strict'; -var Evented = require('../util/evented'); -var ajax = require('../util/ajax'); -var browser = require('../util/browser'); -var normalizeURL = require('../util/mapbox').normalizeSpriteURL; -module.exports = ImageSprite; -function ImageSprite(base) { - this.base = base; - this.retina = browser.devicePixelRatio > 1; - var format = this.retina ? '@2x' : ''; - ajax.getJSON(normalizeURL(base, format, '.json'), function (err, data) { - if (err) { - this.fire('error', { error: err }); - return; - } - this.data = data; - if (this.img) - this.fire('load'); - }.bind(this)); - ajax.getImage(normalizeURL(base, format, '.png'), function (err, img) { - if (err) { - this.fire('error', { error: err }); - return; - } - var data = img.getData(); - var newdata = img.data = new Uint8Array(data.length); - for (var i = 0; i < data.length; i += 4) { - var alpha = data[i + 3] / 255; - newdata[i + 0] = data[i + 0] * alpha; - newdata[i + 1] = data[i + 1] * alpha; - newdata[i + 2] = data[i + 2] * alpha; - newdata[i + 3] = data[i + 3]; - } - this.img = img; - if (this.data) - this.fire('load'); - }.bind(this)); -} -ImageSprite.prototype = Object.create(Evented); -ImageSprite.prototype.toJSON = function () { - return this.base; -}; -ImageSprite.prototype.loaded = function () { - return !!(this.data && this.img); -}; -ImageSprite.prototype.resize = function () { - if (browser.devicePixelRatio > 1 !== this.retina) { - var newSprite = new ImageSprite(this.base); - newSprite.on('load', function () { - this.img = newSprite.img; - this.data = newSprite.data; - this.retina = newSprite.retina; - }.bind(this)); - } -}; -function SpritePosition() { -} -SpritePosition.prototype = { - x: 0, - y: 0, - width: 0, - height: 0, - pixelRatio: 1, - sdf: false -}; -ImageSprite.prototype.getSpritePosition = function (name) { - if (!this.loaded()) - return new SpritePosition(); - var pos = this.data && this.data[name]; - if (pos && this.img) - return pos; - return new SpritePosition(); -}; -},{"../util/ajax":165,"../util/browser":166,"../util/evented":174,"../util/mapbox":179}],117:[function(require,module,exports){ -'use strict'; -var parseColorString = require('csscolorparser').parseCSSColor; -var util = require('../util/util'); -var StyleFunction = require('./style_function'); -var cache = {}; -module.exports = function parseColor(input) { - if (StyleFunction.isFunctionDefinition(input)) { - return util.extend({}, input, { - stops: input.stops.map(function (stop) { - return [ - stop[0], - parseColor(stop[1]) - ]; - }) - }); - } else if (typeof input === 'string') { - if (!cache[input]) { - var rgba = parseColorString(input); - if (!rgba) { - throw new Error('Invalid color ' + input); - } - cache[input] = [ - rgba[0] / 255 * rgba[3], - rgba[1] / 255 * rgba[3], - rgba[2] / 255 * rgba[3], - rgba[3] - ]; - } - return cache[input]; - } else { - throw new Error('Invalid color ' + input); - } -}; -},{"../util/util":182,"./style_function":120,"csscolorparser":13}],118:[function(require,module,exports){ -'use strict'; -var Evented = require('../util/evented'); -var StyleLayer = require('./style_layer'); -var ImageSprite = require('./image_sprite'); -var GlyphSource = require('../symbol/glyph_source'); -var SpriteAtlas = require('../symbol/sprite_atlas'); -var LineAtlas = require('../render/line_atlas'); -var util = require('../util/util'); -var ajax = require('../util/ajax'); -var normalizeURL = require('../util/mapbox').normalizeStyleURL; -var browser = require('../util/browser'); -var Dispatcher = require('../util/dispatcher'); -var AnimationLoop = require('./animation_loop'); -var validateStyle = require('./validate_style'); -var Source = require('../source/source'); -var QueryFeatures = require('../source/query_features'); -var SourceCache = require('../source/source_cache'); -var styleSpec = require('./style_spec'); -var StyleFunction = require('./style_function'); -module.exports = Style; -function Style(stylesheet, animationLoop, workerCount) { - this.animationLoop = animationLoop || new AnimationLoop(); - this.dispatcher = new Dispatcher(workerCount || 1, this); - this.spriteAtlas = new SpriteAtlas(1024, 1024); - this.lineAtlas = new LineAtlas(256, 512); - this._layers = {}; - this._order = []; - this._groups = []; - this.sources = {}; - this.zoomHistory = {}; - util.bindAll([ - '_forwardSourceEvent', - '_forwardTileEvent', - '_forwardLayerEvent', - '_redoPlacement', - '_handleAddSourceType', - '_registerCustomSource' - ], this); - this._resetUpdates(); - Source.on('_add', this._handleAddSourceType); - var stylesheetLoaded = function (err, stylesheet) { - if (err) { - this.fire('error', { error: err }); - return; - } - if (validateStyle.emitErrors(this, validateStyle(stylesheet))) - return; - this._loaded = true; - this.stylesheet = stylesheet; - this.updateClasses(); - var sources = stylesheet.sources; - for (var id in sources) { - this.addSource(id, sources[id]); - } - if (stylesheet.sprite) { - this.sprite = new ImageSprite(stylesheet.sprite); - this.sprite.on('load', this.fire.bind(this, 'change')); - } - this.glyphSource = new GlyphSource(stylesheet.glyphs); - this._resolve(); - this.fire('load'); - }.bind(this); - util.asyncAll(Source.getCustomTypeNames(), this._registerCustomSource, function (err) { - if (err) { - this.fire('error', { error: err }); - return; - } - if (typeof stylesheet === 'string') { - ajax.getJSON(normalizeURL(stylesheet), stylesheetLoaded); - } else { - browser.frame(stylesheetLoaded.bind(this, null, stylesheet)); - } - }.bind(this)); - this.on('source.load', function (event) { - var source = event.source; - if (source && source.vectorLayerIds) { - for (var layerId in this._layers) { - var layer = this._layers[layerId]; - if (layer.source === source.id) { - this._validateLayer(layer); - } - } - } - }); -} -Style.prototype = util.inherit(Evented, { - _loaded: false, - _validateLayer: function (layer) { - var source = this.sources[layer.source]; - if (!layer.sourceLayer) - return; - if (!source) - return; - if (!source.vectorLayerIds) - return; - if (source.vectorLayerIds.indexOf(layer.sourceLayer) === -1) { - this.fire('error', { error: new Error('Source layer "' + layer.sourceLayer + '" ' + 'does not exist on source "' + source.id + '" ' + 'as specified by style layer "' + layer.id + '"') }); - } - }, - loaded: function () { - if (!this._loaded) - return false; - if (Object.keys(this._updates.sources).length) - return false; - for (var id in this.sources) - if (!this.sources[id].loaded()) - return false; - if (this.sprite && !this.sprite.loaded()) - return false; - return true; - }, - _resolve: function () { - var layer, layerJSON; - this._layers = {}; - this._order = this.stylesheet.layers.map(function (layer) { - return layer.id; - }); - for (var i = 0; i < this.stylesheet.layers.length; i++) { - layerJSON = this.stylesheet.layers[i]; - if (layerJSON.ref) - continue; - layer = StyleLayer.create(layerJSON); - this._layers[layer.id] = layer; - layer.on('error', this._forwardLayerEvent); - } - for (var j = 0; j < this.stylesheet.layers.length; j++) { - layerJSON = this.stylesheet.layers[j]; - if (!layerJSON.ref) - continue; - var refLayer = this.getLayer(layerJSON.ref); - layer = StyleLayer.create(layerJSON, refLayer); - this._layers[layer.id] = layer; - layer.on('error', this._forwardLayerEvent); - } - this._groupLayers(); - this._updateWorkerLayers(); - }, - _groupLayers: function () { - var group; - this._groups = []; - for (var i = 0; i < this._order.length; ++i) { - var layer = this._layers[this._order[i]]; - if (!group || layer.source !== group.source) { - group = []; - group.source = layer.source; - this._groups.push(group); - } - group.push(layer); - } - }, - _updateWorkerLayers: function (ids) { - this.dispatcher.broadcast(ids ? 'update layers' : 'set layers', this._serializeLayers(ids)); - }, - _serializeLayers: function (ids) { - ids = ids || this._order; - var serialized = []; - var options = { includeRefProperties: true }; - for (var i = 0; i < ids.length; i++) { - serialized.push(this._layers[ids[i]].serialize(options)); - } - return serialized; - }, - _applyClasses: function (classes, options) { - if (!this._loaded) - return; - classes = classes || []; - options = options || { transition: true }; - var transition = this.stylesheet.transition || {}; - var layers = this._updates.allPaintProps ? this._layers : this._updates.paintProps; - for (var id in layers) { - var layer = this._layers[id]; - var props = this._updates.paintProps[id]; - if (this._updates.allPaintProps || props.all) { - layer.updatePaintTransitions(classes, options, transition, this.animationLoop); - } else { - for (var paintName in props) { - this._layers[id].updatePaintTransition(paintName, classes, options, transition, this.animationLoop); - } - } - } - }, - _recalculate: function (z) { - for (var sourceId in this.sources) - this.sources[sourceId].used = false; - this._updateZoomHistory(z); - this.rasterFadeDuration = 300; - for (var layerId in this._layers) { - var layer = this._layers[layerId]; - layer.recalculate(z, this.zoomHistory); - if (!layer.isHidden(z) && layer.source) { - this.sources[layer.source].used = true; - } - } - var maxZoomTransitionDuration = 300; - if (Math.floor(this.z) !== Math.floor(z)) { - this.animationLoop.set(maxZoomTransitionDuration); - } - this.z = z; - this.fire('zoom'); - }, - _updateZoomHistory: function (z) { - var zh = this.zoomHistory; - if (zh.lastIntegerZoom === undefined) { - zh.lastIntegerZoom = Math.floor(z); - zh.lastIntegerZoomTime = 0; - zh.lastZoom = z; - } - if (Math.floor(zh.lastZoom) < Math.floor(z)) { - zh.lastIntegerZoom = Math.floor(z); - zh.lastIntegerZoomTime = Date.now(); - } else if (Math.floor(zh.lastZoom) > Math.floor(z)) { - zh.lastIntegerZoom = Math.floor(z + 1); - zh.lastIntegerZoomTime = Date.now(); - } - zh.lastZoom = z; - }, - _checkLoaded: function () { - if (!this._loaded) { - throw new Error('Style is not done loading'); - } - }, - update: function (classes, options) { - if (!this._updates.changed) - return this; - if (this._updates.allLayers) { - this._groupLayers(); - this._updateWorkerLayers(); - } else { - var updatedIds = Object.keys(this._updates.layers); - if (updatedIds.length) { - this._updateWorkerLayers(updatedIds); - } - } - var updatedSourceIds = Object.keys(this._updates.sources); - var i; - for (i = 0; i < updatedSourceIds.length; i++) { - this._reloadSource(updatedSourceIds[i]); - } - for (i = 0; i < this._updates.events.length; i++) { - var args = this._updates.events[i]; - this.fire(args[0], args[1]); - } - this._applyClasses(classes, options); - if (this._updates.changed) { - this.fire('change'); - } - this._resetUpdates(); - return this; - }, - _resetUpdates: function () { - this._updates = { - events: [], - layers: {}, - sources: {}, - paintProps: {} - }; - }, - addSource: function (id, source) { - this._checkLoaded(); - if (this.sources[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) + '.'); - } - var builtIns = [ - 'vector', - 'raster', - 'geojson', - 'video', - 'image' - ]; - var shouldValidate = builtIns.indexOf(source.type) >= 0; - if (shouldValidate && this._handleErrors(validateStyle.source, 'sources.' + id, source)) - return this; - source = new SourceCache(id, source, this.dispatcher); - this.sources[id] = source; - source.style = this; - source.on('load', this._forwardSourceEvent).on('error', this._forwardSourceEvent).on('change', this._forwardSourceEvent).on('tile.add', this._forwardTileEvent).on('tile.load', this._forwardTileEvent).on('tile.error', this._forwardTileEvent).on('tile.remove', this._forwardTileEvent).on('tile.stats', this._forwardTileEvent); - this._updates.events.push([ - 'source.add', - { source: source } - ]); - this._updates.changed = true; - return this; - }, - removeSource: function (id) { - this._checkLoaded(); - if (this.sources[id] === undefined) { - throw new Error('There is no source with this ID'); - } - var source = this.sources[id]; - delete this.sources[id]; - delete this._updates.sources[id]; - source.off('load', this._forwardSourceEvent).off('error', this._forwardSourceEvent).off('change', this._forwardSourceEvent).off('tile.add', this._forwardTileEvent).off('tile.load', this._forwardTileEvent).off('tile.error', this._forwardTileEvent).off('tile.remove', this._forwardTileEvent).off('tile.stats', this._forwardTileEvent); - this._updates.events.push([ - 'source.remove', - { source: source } - ]); - this._updates.changed = true; - return this; - }, - getSource: function (id) { - return this.sources[id] && this.sources[id].getSource(); - }, - addLayer: function (layer, before) { - this._checkLoaded(); - if (!(layer instanceof StyleLayer)) { - if (this._handleErrors(validateStyle.layer, 'layers.' + layer.id, layer, false, { arrayIndex: -1 })) - return this; - var refLayer = layer.ref && this.getLayer(layer.ref); - layer = StyleLayer.create(layer, refLayer); - } - this._validateLayer(layer); - layer.on('error', this._forwardLayerEvent); - this._layers[layer.id] = layer; - this._order.splice(before ? this._order.indexOf(before) : Infinity, 0, layer.id); - this._updates.allLayers = true; - if (layer.source) { - this._updates.sources[layer.source] = true; - } - this._updates.events.push([ - 'layer.add', - { layer: layer } - ]); - return this.updateClasses(layer.id); - }, - removeLayer: function (id) { - this._checkLoaded(); - var layer = this._layers[id]; - if (layer === undefined) { - throw new Error('There is no layer with this ID'); - } - for (var i in this._layers) { - if (this._layers[i].ref === id) { - this.removeLayer(i); - } - } - layer.off('error', this._forwardLayerEvent); - delete this._layers[id]; - delete this._updates.layers[id]; - delete this._updates.paintProps[id]; - this._order.splice(this._order.indexOf(id), 1); - this._updates.allLayers = true; - this._updates.events.push([ - 'layer.remove', - { layer: layer } - ]); - this._updates.changed = true; - return this; - }, - getLayer: function (id) { - return this._layers[id]; - }, - getReferentLayer: function (id) { - var layer = this.getLayer(id); - if (layer.ref) { - layer = this.getLayer(layer.ref); - } - return layer; - }, - setLayerZoomRange: function (layerId, minzoom, maxzoom) { - this._checkLoaded(); - var layer = this.getReferentLayer(layerId); - if (layer.minzoom === minzoom && layer.maxzoom === maxzoom) - return this; - if (minzoom != null) { - layer.minzoom = minzoom; - } - if (maxzoom != null) { - layer.maxzoom = maxzoom; - } - return this._updateLayer(layer); - }, - setFilter: function (layerId, filter) { - this._checkLoaded(); - var layer = this.getReferentLayer(layerId); - if (filter !== null && this._handleErrors(validateStyle.filter, 'layers.' + layer.id + '.filter', filter)) - return this; - if (util.deepEqual(layer.filter, filter)) - return this; - layer.filter = util.clone(filter); - return this._updateLayer(layer); - }, - getFilter: function (layer) { - return this.getReferentLayer(layer).filter; - }, - setLayoutProperty: function (layerId, name, value) { - this._checkLoaded(); - var layer = this.getReferentLayer(layerId); - if (util.deepEqual(layer.getLayoutProperty(name), value)) - return this; - layer.setLayoutProperty(name, value); - return this._updateLayer(layer); - }, - getLayoutProperty: function (layer, name) { - return this.getReferentLayer(layer).getLayoutProperty(name); - }, - setPaintProperty: function (layerId, name, value, klass) { - this._checkLoaded(); - var layer = this.getLayer(layerId); - if (util.deepEqual(layer.getPaintProperty(name, klass), value)) - return this; - var wasFeatureConstant = layer.isPaintValueFeatureConstant(name); - layer.setPaintProperty(name, value, klass); - var isFeatureConstant = !(value && StyleFunction.isFunctionDefinition(value) && value.property !== '$zoom' && value.property !== undefined); - if (!isFeatureConstant || !wasFeatureConstant) { - this._updates.layers[layerId] = true; - if (layer.source) { - this._updates.sources[layer.source] = true; - } - } - return this.updateClasses(layerId, name); - }, - getPaintProperty: function (layer, name, klass) { - return this.getLayer(layer).getPaintProperty(name, klass); - }, - updateClasses: function (layerId, paintName) { - this._updates.changed = true; - if (!layerId) { - this._updates.allPaintProps = true; - } else { - var props = this._updates.paintProps; - if (!props[layerId]) - props[layerId] = {}; - props[layerId][paintName || 'all'] = true; - } - return this; - }, - serialize: function () { - return util.filterObject({ - version: this.stylesheet.version, - name: this.stylesheet.name, - metadata: this.stylesheet.metadata, - 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: util.mapObject(this.sources, function (source) { - return source.serialize(); - }), - layers: this._order.map(function (id) { - return this._layers[id].serialize(); - }, this) - }, function (value) { - return value !== undefined; - }); - }, - _updateLayer: function (layer) { - this._updates.layers[layer.id] = true; - if (layer.source) { - this._updates.sources[layer.source] = true; - } - this._updates.changed = true; - return this; - }, - _flattenRenderedFeatures: function (sourceResults) { - var features = []; - for (var l = this._order.length - 1; l >= 0; l--) { - var layerID = this._order[l]; - for (var s = 0; s < sourceResults.length; s++) { - var layerFeatures = sourceResults[s][layerID]; - if (layerFeatures) { - for (var f = 0; f < layerFeatures.length; f++) { - features.push(layerFeatures[f]); - } - } - } - } - return features; - }, - queryRenderedFeatures: function (queryGeometry, params, zoom, bearing) { - if (params && params.filter) { - this._handleErrors(validateStyle.filter, 'queryRenderedFeatures.filter', params.filter, true); - } - var includedSources = {}; - if (params && params.layers) { - for (var i = 0; i < params.layers.length; i++) { - var layerId = params.layers[i]; - includedSources[this._layers[layerId].source] = true; - } - } - var sourceResults = []; - for (var id in this.sources) { - if (params.layers && !includedSources[id]) - continue; - var source = this.sources[id]; - var results = QueryFeatures.rendered(source, this._layers, queryGeometry, params, zoom, bearing); - sourceResults.push(results); - } - return this._flattenRenderedFeatures(sourceResults); - }, - querySourceFeatures: function (sourceID, params) { - if (params && params.filter) { - this._handleErrors(validateStyle.filter, 'querySourceFeatures.filter', params.filter, true); - } - var source = this.sources[sourceID]; - return source ? QueryFeatures.source(source, params) : []; - }, - _handleErrors: function (validate, key, value, throws, props) { - var action = throws ? validateStyle.throwErrors : validateStyle.emitErrors; - var result = validate.call(validateStyle, util.extend({ - key: key, - style: this.serialize(), - value: value, - styleSpec: styleSpec - }, props)); - return action.call(validateStyle, this, result); - }, - _handleAddSourceType: function (event) { - this._registerCustomSource(event.name, function (err) { - if (err) { - this.fire('error', { error: err }); - return; - } - this.fire('source-type.add', event); - }.bind(this)); - }, - _registerCustomSource: function (name, callback) { - var SourceType = Source.getType(name); - if (SourceType.workerSourceURL) { - this.dispatcher.broadcast('load worker source', { - name: name, - url: SourceType.workerSourceURL - }, callback); - } else { - callback(); - } - }, - _remove: function () { - this.dispatcher.remove(); - Source.off('_add', this._handleAddSourceType); - }, - _reloadSource: function (id) { - this.sources[id].reload(); - }, - _updateSources: function (transform) { - for (var id in this.sources) { - this.sources[id].update(transform); - } - }, - _redoPlacement: function () { - for (var id in this.sources) { - if (this.sources[id].redoPlacement) - this.sources[id].redoPlacement(); - } - }, - _forwardSourceEvent: function (e) { - this.fire('source.' + e.type, util.extend({ source: e.target.getSource() }, e)); - }, - _forwardTileEvent: function (e) { - this.fire(e.type, util.extend({ source: e.target }, e)); - }, - _forwardLayerEvent: function (e) { - this.fire('layer.' + e.type, util.extend({ layer: { id: e.target.id } }, e)); - }, - 'get sprite json': function (params, callback) { - var sprite = this.sprite; - if (sprite.loaded()) { - callback(null, { - sprite: sprite.data, - retina: sprite.retina - }); - } else { - sprite.on('load', function () { - callback(null, { - sprite: sprite.data, - retina: sprite.retina - }); - }); - } - }, - 'get icons': function (params, callback) { - var sprite = this.sprite; - var spriteAtlas = this.spriteAtlas; - if (sprite.loaded()) { - spriteAtlas.setSprite(sprite); - spriteAtlas.addIcons(params.icons, callback); - } else { - sprite.on('load', function () { - spriteAtlas.setSprite(sprite); - spriteAtlas.addIcons(params.icons, callback); - }); - } - }, - 'get glyphs': function (params, callback) { - var stacks = params.stacks, remaining = Object.keys(stacks).length, allGlyphs = {}; - for (var fontName in stacks) { - this.glyphSource.getSimpleGlyphs(fontName, stacks[fontName], params.uid, done); - } - function done(err, glyphs, fontName) { - if (err) - console.error(err); - allGlyphs[fontName] = glyphs; - remaining--; - if (remaining === 0) - callback(null, allGlyphs); - } - } -}); -},{"../render/line_atlas":94,"../source/query_features":104,"../source/source":106,"../source/source_cache":107,"../symbol/glyph_source":139,"../symbol/sprite_atlas":144,"../util/ajax":165,"../util/browser":166,"../util/dispatcher":173,"../util/evented":174,"../util/mapbox":179,"../util/util":182,"./animation_loop":115,"./image_sprite":116,"./style_function":120,"./style_layer":121,"./style_spec":128,"./validate_style":130}],119:[function(require,module,exports){ -'use strict'; -var MapboxGLFunction = require('./style_function'); -var parseColor = require('./parse_color'); -var util = require('../util/util'); -module.exports = StyleDeclaration; -function StyleDeclaration(reference, value) { - this.value = util.clone(value); - this.isFunction = MapboxGLFunction.isFunctionDefinition(value); - this.json = JSON.stringify(this.value); - var parsedValue = reference.type === 'color' && this.value ? parseColor(this.value) : value; - this.calculate = MapboxGLFunction[reference.function || 'piecewise-constant'](parsedValue); - this.isFeatureConstant = this.calculate.isFeatureConstant; - this.isZoomConstant = this.calculate.isZoomConstant; - if (reference.function === 'piecewise-constant' && reference.transition) { - this.calculate = transitioned(this.calculate); - } - if (!this.isFeatureConstant && !this.isZoomConstant) { - this.stopZoomLevels = []; - var interpolationAmountStops = []; - var stops = this.value.stops; - for (var i = 0; i < this.value.stops.length; i++) { - var zoom = stops[i][0].zoom; - if (this.stopZoomLevels.indexOf(zoom) < 0) { - this.stopZoomLevels.push(zoom); - interpolationAmountStops.push([ - zoom, - interpolationAmountStops.length - ]); - } - } - this.calculateInterpolationT = MapboxGLFunction.interpolated({ - stops: interpolationAmountStops, - base: value.base - }); - } -} -function transitioned(calculate) { - return function (globalProperties, featureProperties) { - var z = globalProperties.zoom; - var zh = globalProperties.zoomHistory; - var duration = globalProperties.duration; - var fraction = z % 1; - var t = Math.min((Date.now() - zh.lastIntegerZoomTime) / duration, 1); - var fromScale = 1; - var toScale = 1; - var mix, from, to; - if (z > zh.lastIntegerZoom) { - mix = fraction + (1 - fraction) * t; - fromScale *= 2; - from = calculate({ zoom: z - 1 }, featureProperties); - to = calculate({ zoom: z }, featureProperties); - } else { - mix = 1 - (1 - t) * fraction; - to = calculate({ zoom: z }, featureProperties); - from = calculate({ zoom: z + 1 }, featureProperties); - fromScale /= 2; - } - if (from === undefined || to === undefined) { - return undefined; - } else { - return { - from: from, - fromScale: fromScale, - to: to, - toScale: toScale, - t: mix - }; - } - }; -} -},{"../util/util":182,"./parse_color":117,"./style_function":120}],120:[function(require,module,exports){ -'use strict'; -var MapboxGLFunction = require('mapbox-gl-function'); -exports.interpolated = function (parameters) { - var inner = MapboxGLFunction.interpolated(parameters); - var outer = function (globalProperties, featureProperties) { - return inner(globalProperties && globalProperties.zoom, featureProperties || {}); - }; - outer.isFeatureConstant = inner.isFeatureConstant; - outer.isZoomConstant = inner.isZoomConstant; - return outer; -}; -exports['piecewise-constant'] = function (parameters) { - var inner = MapboxGLFunction['piecewise-constant'](parameters); - var outer = function (globalProperties, featureProperties) { - return inner(globalProperties && globalProperties.zoom, featureProperties || {}); - }; - outer.isFeatureConstant = inner.isFeatureConstant; - outer.isZoomConstant = inner.isZoomConstant; - return outer; -}; -exports.isFunctionDefinition = MapboxGLFunction.isFunctionDefinition; -},{"mapbox-gl-function":42}],121:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var StyleTransition = require('./style_transition'); -var StyleDeclaration = require('./style_declaration'); -var styleSpec = require('./style_spec'); -var validateStyle = require('./validate_style'); -var parseColor = require('./parse_color'); -var Evented = require('../util/evented'); -module.exports = StyleLayer; -var TRANSITION_SUFFIX = '-transition'; -StyleLayer.create = function (layer, refLayer) { - var Classes = { - background: require('./style_layer/background_style_layer'), - circle: require('./style_layer/circle_style_layer'), - fill: require('./style_layer/fill_style_layer'), - line: require('./style_layer/line_style_layer'), - raster: require('./style_layer/raster_style_layer'), - symbol: require('./style_layer/symbol_style_layer') - }; - return new Classes[(refLayer || layer).type](layer, refLayer); -}; -function StyleLayer(layer, refLayer) { - this.set(layer, refLayer); -} -StyleLayer.prototype = util.inherit(Evented, { - set: function (layer, refLayer) { - this.id = layer.id; - this.ref = layer.ref; - this.metadata = layer.metadata; - this.type = (refLayer || layer).type; - this.source = (refLayer || layer).source; - this.sourceLayer = (refLayer || layer)['source-layer']; - this.minzoom = (refLayer || layer).minzoom; - this.maxzoom = (refLayer || layer).maxzoom; - this.filter = (refLayer || layer).filter; - this.paint = {}; - this.layout = {}; - this._paintSpecifications = styleSpec['paint_' + this.type]; - this._layoutSpecifications = styleSpec['layout_' + this.type]; - this._paintTransitions = {}; - this._paintTransitionOptions = {}; - this._paintDeclarations = {}; - this._layoutDeclarations = {}; - this._layoutFunctions = {}; - var paintName, layoutName; - for (var key in layer) { - var match = key.match(/^paint(?:\.(.*))?$/); - if (match) { - var klass = match[1] || ''; - for (paintName in layer[key]) { - this.setPaintProperty(paintName, layer[key][paintName], klass); - } - } - } - if (this.ref) { - this._layoutDeclarations = refLayer._layoutDeclarations; - } else { - for (layoutName in layer.layout) { - this.setLayoutProperty(layoutName, layer.layout[layoutName]); - } - } - for (paintName in this._paintSpecifications) { - this.paint[paintName] = this.getPaintValue(paintName); - } - for (layoutName in this._layoutSpecifications) { - this._updateLayoutValue(layoutName); - } - }, - setLayoutProperty: function (name, value) { - if (value == null) { - delete this._layoutDeclarations[name]; - } else { - var key = 'layers.' + this.id + '.layout.' + name; - if (this._handleErrors(validateStyle.layoutProperty, key, name, value)) - return; - this._layoutDeclarations[name] = new StyleDeclaration(this._layoutSpecifications[name], value); - } - this._updateLayoutValue(name); - }, - getLayoutProperty: function (name) { - return this._layoutDeclarations[name] && this._layoutDeclarations[name].value; - }, - getLayoutValue: function (name, globalProperties, featureProperties) { - var specification = this._layoutSpecifications[name]; - var declaration = this._layoutDeclarations[name]; - if (declaration) { - return declaration.calculate(globalProperties, featureProperties); - } else { - return specification.default; - } - }, - setPaintProperty: function (name, value, klass) { - var validateStyleKey = 'layers.' + this.id + (klass ? '["paint.' + klass + '"].' : '.paint.') + name; - if (util.endsWith(name, TRANSITION_SUFFIX)) { - if (!this._paintTransitionOptions[klass || '']) { - this._paintTransitionOptions[klass || ''] = {}; - } - if (value === null || value === undefined) { - delete this._paintTransitionOptions[klass || ''][name]; - } else { - if (this._handleErrors(validateStyle.paintProperty, validateStyleKey, name, value)) - return; - this._paintTransitionOptions[klass || ''][name] = value; - } - } else { - if (!this._paintDeclarations[klass || '']) { - this._paintDeclarations[klass || ''] = {}; - } - if (value === null || value === undefined) { - delete this._paintDeclarations[klass || ''][name]; - } else { - if (this._handleErrors(validateStyle.paintProperty, validateStyleKey, name, value)) - return; - this._paintDeclarations[klass || ''][name] = new StyleDeclaration(this._paintSpecifications[name], value); - } - } - }, - getPaintProperty: function (name, klass) { - klass = klass || ''; - if (util.endsWith(name, TRANSITION_SUFFIX)) { - return this._paintTransitionOptions[klass] && this._paintTransitionOptions[klass][name]; - } else { - return this._paintDeclarations[klass] && this._paintDeclarations[klass][name] && this._paintDeclarations[klass][name].value; - } - }, - getPaintValue: function (name, globalProperties, featureProperties) { - var specification = this._paintSpecifications[name]; - var transition = this._paintTransitions[name]; - if (transition) { - return transition.calculate(globalProperties, featureProperties); - } else if (specification.type === 'color' && specification.default) { - return parseColor(specification.default); - } else { - return specification.default; - } - }, - getPaintValueStopZoomLevels: function (name) { - var transition = this._paintTransitions[name]; - if (transition) { - return transition.declaration.stopZoomLevels; - } else { - return []; - } - }, - getPaintInterpolationT: function (name, zoom) { - var transition = this._paintTransitions[name]; - return transition.declaration.calculateInterpolationT({ zoom: zoom }); - }, - isPaintValueFeatureConstant: function (name) { - var transition = this._paintTransitions[name]; - if (transition) { - return transition.declaration.isFeatureConstant; - } else { - return true; - } - }, - isLayoutValueFeatureConstant: function (name) { - var declaration = this._layoutDeclarations[name]; - if (declaration) { - return declaration.isFeatureConstant; - } else { - return true; - } - }, - isPaintValueZoomConstant: function (name) { - var transition = this._paintTransitions[name]; - if (transition) { - return transition.declaration.isZoomConstant; - } else { - return true; - } - }, - isHidden: function (zoom) { - if (this.minzoom && zoom < this.minzoom) - return true; - if (this.maxzoom && zoom >= this.maxzoom) - return true; - if (this.layout['visibility'] === 'none') - return true; - if (this.paint[this.type + '-opacity'] === 0) - return true; - return false; - }, - updatePaintTransitions: function (classes, options, globalOptions, animationLoop) { - var declarations = util.extend({}, this._paintDeclarations['']); - for (var i = 0; i < classes.length; i++) { - util.extend(declarations, this._paintDeclarations[classes[i]]); - } - var name; - for (name in declarations) { - this._applyPaintDeclaration(name, declarations[name], options, globalOptions, animationLoop); - } - for (name in this._paintTransitions) { - if (!(name in declarations)) - this._applyPaintDeclaration(name, null, options, globalOptions, animationLoop); - } - }, - updatePaintTransition: function (name, classes, options, globalOptions, animationLoop) { - var declaration = this._paintDeclarations[''][name]; - for (var i = 0; i < classes.length; i++) { - var classPaintDeclarations = this._paintDeclarations[classes[i]]; - if (classPaintDeclarations && classPaintDeclarations[name]) { - declaration = classPaintDeclarations[name]; - } - } - this._applyPaintDeclaration(name, declaration, options, globalOptions, animationLoop); - }, - recalculate: function (zoom, zoomHistory) { - for (var paintName in this._paintTransitions) { - this.paint[paintName] = this.getPaintValue(paintName, { - zoom: zoom, - zoomHistory: zoomHistory - }); - } - for (var layoutName in this._layoutFunctions) { - this.layout[layoutName] = this.getLayoutValue(layoutName, { - zoom: zoom, - zoomHistory: zoomHistory - }); - } - }, - serialize: function (options) { - var output = { - 'id': this.id, - 'ref': this.ref, - 'metadata': this.metadata, - 'minzoom': this.minzoom, - 'maxzoom': this.maxzoom - }; - for (var klass in this._paintDeclarations) { - var key = klass === '' ? 'paint' : 'paint.' + klass; - output[key] = util.mapObject(this._paintDeclarations[klass], getDeclarationValue); - } - if (!this.ref || options && options.includeRefProperties) { - util.extend(output, { - 'type': this.type, - 'source': this.source, - 'source-layer': this.sourceLayer, - 'filter': this.filter, - 'layout': util.mapObject(this._layoutDeclarations, getDeclarationValue) - }); - } - return util.filterObject(output, function (value, key) { - return value !== undefined && !(key === 'layout' && !Object.keys(value).length); - }); - }, - _applyPaintDeclaration: function (name, declaration, options, globalOptions, animationLoop) { - var oldTransition = options.transition ? this._paintTransitions[name] : undefined; - var spec = this._paintSpecifications[name]; - if (declaration === null || declaration === undefined) { - declaration = new StyleDeclaration(spec, spec.default); - } - if (oldTransition && oldTransition.declaration.json === declaration.json) - return; - var transitionOptions = util.extend({ - duration: 300, - delay: 0 - }, globalOptions, this.getPaintProperty(name + TRANSITION_SUFFIX)); - var newTransition = this._paintTransitions[name] = new StyleTransition(spec, declaration, oldTransition, transitionOptions); - if (!newTransition.instant()) { - newTransition.loopID = animationLoop.set(newTransition.endTime - Date.now()); - } - if (oldTransition) { - animationLoop.cancel(oldTransition.loopID); - } - }, - _updateLayoutValue: function (name) { - var declaration = this._layoutDeclarations[name]; - if (declaration && declaration.isFunction) { - this._layoutFunctions[name] = true; - } else { - delete this._layoutFunctions[name]; - this.layout[name] = this.getLayoutValue(name); - } - }, - _handleErrors: function (validate, key, name, value) { - return validateStyle.emitErrors(this, validate.call(validateStyle, { - key: key, - layerType: this.type, - objectKey: name, - value: value, - styleSpec: styleSpec, - style: { - glyphs: true, - sprite: true - } - })); - } -}); -function getDeclarationValue(declaration) { - return declaration.value; -} -},{"../util/evented":174,"../util/util":182,"./parse_color":117,"./style_declaration":119,"./style_layer/background_style_layer":122,"./style_layer/circle_style_layer":123,"./style_layer/fill_style_layer":124,"./style_layer/line_style_layer":125,"./style_layer/raster_style_layer":126,"./style_layer/symbol_style_layer":127,"./style_spec":128,"./style_transition":129,"./validate_style":130}],122:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function BackgroundStyleLayer() { - StyleLayer.apply(this, arguments); -} -module.exports = BackgroundStyleLayer; -BackgroundStyleLayer.prototype = util.inherit(StyleLayer, {}); -},{"../../util/util":182,"../style_layer":121}],123:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function CircleStyleLayer() { - StyleLayer.apply(this, arguments); -} -module.exports = CircleStyleLayer; -CircleStyleLayer.prototype = util.inherit(StyleLayer, {}); -},{"../../util/util":182,"../style_layer":121}],124:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function FillStyleLayer() { - StyleLayer.apply(this, arguments); -} -FillStyleLayer.prototype = util.inherit(StyleLayer, { - getPaintValue: function (name, globalProperties, featureProperties) { - if (name === 'fill-outline-color' && this.getPaintProperty('fill-outline-color') === undefined) { - return StyleLayer.prototype.getPaintValue.call(this, 'fill-color', globalProperties, featureProperties); - } else { - return StyleLayer.prototype.getPaintValue.call(this, name, globalProperties, featureProperties); - } - }, - getPaintValueStopZoomLevels: function (name) { - if (name === 'fill-outline-color' && this.getPaintProperty('fill-outline-color') === undefined) { - return StyleLayer.prototype.getPaintValueStopZoomLevels.call(this, 'fill-color'); - } else { - return StyleLayer.prototype.getPaintValueStopZoomLevels.call(this, arguments); - } - }, - getPaintInterpolationT: function (name, zoom) { - if (name === 'fill-outline-color' && this.getPaintProperty('fill-outline-color') === undefined) { - return StyleLayer.prototype.getPaintInterpolationT.call(this, 'fill-color', zoom); - } else { - return StyleLayer.prototype.getPaintInterpolationT.call(this, name, zoom); - } - }, - isPaintValueFeatureConstant: function (name) { - if (name === 'fill-outline-color' && this.getPaintProperty('fill-outline-color') === undefined) { - return StyleLayer.prototype.isPaintValueFeatureConstant.call(this, 'fill-color'); - } else { - return StyleLayer.prototype.isPaintValueFeatureConstant.call(this, name); - } - }, - isPaintValueZoomConstant: function (name) { - if (name === 'fill-outline-color' && this.getPaintProperty('fill-outline-color') === undefined) { - return StyleLayer.prototype.isPaintValueZoomConstant.call(this, 'fill-color'); - } else { - return StyleLayer.prototype.isPaintValueZoomConstant.call(this, name); - } - } -}); -module.exports = FillStyleLayer; -},{"../../util/util":182,"../style_layer":121}],125:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function LineStyleLayer() { - StyleLayer.apply(this, arguments); -} -module.exports = LineStyleLayer; -LineStyleLayer.prototype = util.inherit(StyleLayer, { - getPaintValue: function (name, globalProperties, featureProperties) { - var value = StyleLayer.prototype.getPaintValue.apply(this, arguments); - if (value && name === 'line-dasharray') { - var flooredZoom = Math.floor(globalProperties.zoom); - if (this._flooredZoom !== flooredZoom) { - this._flooredZoom = flooredZoom; - this._flooredLineWidth = this.getPaintValue('line-width', globalProperties, featureProperties); - } - value.fromScale *= this._flooredLineWidth; - value.toScale *= this._flooredLineWidth; - } - return value; - } -}); -},{"../../util/util":182,"../style_layer":121}],126:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function RasterStyleLayer() { - StyleLayer.apply(this, arguments); -} -module.exports = RasterStyleLayer; -RasterStyleLayer.prototype = util.inherit(StyleLayer, {}); -},{"../../util/util":182,"../style_layer":121}],127:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var StyleLayer = require('../style_layer'); -function SymbolStyleLayer() { - StyleLayer.apply(this, arguments); -} -module.exports = SymbolStyleLayer; -SymbolStyleLayer.prototype = util.inherit(StyleLayer, { - isHidden: function () { - if (StyleLayer.prototype.isHidden.apply(this, arguments)) - return true; - var isTextHidden = this.paint['text-opacity'] === 0 || !this.layout['text-field']; - var isIconHidden = this.paint['icon-opacity'] === 0 || !this.layout['icon-image']; - if (isTextHidden && isIconHidden) - return true; - return false; - }, - getLayoutValue: function (name, globalProperties, featureProperties) { - if (name === 'text-rotation-alignment' && this.getLayoutValue('symbol-placement', globalProperties, featureProperties) === 'line' && !this.getLayoutProperty('text-rotation-alignment')) { - return 'map'; - } else if (name === 'icon-rotation-alignment' && this.getLayoutValue('symbol-placement', globalProperties, featureProperties) === 'line' && !this.getLayoutProperty('icon-rotation-alignment')) { - return 'map'; - } else if (name === 'text-pitch-alignment' && !this.getLayoutProperty('text-pitch-alignment')) { - return this.getLayoutValue('text-rotation-alignment'); - } else { - return StyleLayer.prototype.getLayoutValue.apply(this, arguments); - } - } -}); -},{"../../util/util":182,"../style_layer":121}],128:[function(require,module,exports){ -'use strict'; -module.exports = require('mapbox-gl-style-spec/reference/latest.min'); -},{"mapbox-gl-style-spec/reference/latest.min":65}],129:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var interpolate = require('../util/interpolate'); -module.exports = StyleTransition; -function StyleTransition(reference, declaration, oldTransition, value) { - this.declaration = declaration; - this.startTime = this.endTime = new Date().getTime(); - if (reference.function === 'piecewise-constant' && reference.transition) { - this.interp = interpZoomTransitioned; - } else { - this.interp = interpolate[reference.type]; - } - this.oldTransition = oldTransition; - this.duration = value.duration || 0; - this.delay = value.delay || 0; - if (!this.instant()) { - this.endTime = this.startTime + this.duration + this.delay; - this.ease = util.easeCubicInOut; - } - if (oldTransition && oldTransition.endTime <= this.startTime) { - delete oldTransition.oldTransition; - } -} -StyleTransition.prototype.instant = function () { - return !this.oldTransition || !this.interp || this.duration === 0 && this.delay === 0; -}; -StyleTransition.prototype.calculate = function (globalProperties, featureProperties) { - var value = this.declaration.calculate(util.extend({}, globalProperties, { duration: this.duration }), featureProperties); - if (this.instant()) - return value; - var t = globalProperties.time || Date.now(); - if (t < this.endTime) { - var oldValue = this.oldTransition.calculate(util.extend({}, globalProperties, { time: this.startTime }), featureProperties); - var eased = this.ease((t - this.startTime - this.delay) / this.duration); - value = this.interp(oldValue, value, eased); - } - return value; -}; -function interpZoomTransitioned(from, to, t) { - if ((from && from.to) === undefined || (to && to.to) === undefined) { - return undefined; - } else { - return { - from: from.to, - fromScale: from.toScale, - to: to.to, - toScale: to.toScale, - t: t - }; - } -} -},{"../util/interpolate":176,"../util/util":182}],130:[function(require,module,exports){ -'use strict'; -module.exports = require('mapbox-gl-style-spec/lib/validate_style.min'); -module.exports.emitErrors = function throwErrors(emitter, errors) { - if (errors && errors.length) { - for (var i = 0; i < errors.length; i++) { - emitter.fire('error', { error: new Error(errors[i].message) }); - } - return true; - } else { - return false; - } -}; -module.exports.throwErrors = function throwErrors(emitter, errors) { - if (errors) { - for (var i = 0; i < errors.length; i++) { - throw new Error(errors[i].message); - } - } -}; -},{"mapbox-gl-style-spec/lib/validate_style.min":64}],131:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -module.exports = Anchor; -function Anchor(x, y, angle, segment) { - this.x = x; - this.y = y; - this.angle = angle; - if (segment !== undefined) { - this.segment = segment; - } -} -Anchor.prototype = Object.create(Point.prototype); -Anchor.prototype.clone = function () { - return new Anchor(this.x, this.y, this.angle, this.segment); -}; -},{"point-geometry":187}],132:[function(require,module,exports){ -'use strict'; -module.exports = checkMaxAngle; -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; -} -},{}],133:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -module.exports = clipLine; -function clipLine(lines, x1, y1, x2, y2) { - var clippedLines = []; - for (var l = 0; l < lines.length; l++) { - var line = lines[l]; - var clippedLine; - 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 Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round(); - } else if (p1.x < x1) { - p1 = new Point(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 Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round(); - } else if (p1.y < y1) { - p1 = new Point(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 Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round(); - } else if (p1.x >= x2) { - p1 = new Point(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 Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round(); - } else if (p1.y >= y2) { - p1 = new Point(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; -} -},{"point-geometry":187}],134:[function(require,module,exports){ -'use strict'; -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); -var CollisionBoxArray = module.exports = new StructArrayType({ - members: [ - { - 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: 'Float32', - name: 'maxScale' - }, - { - type: 'Uint32', - name: 'featureIndex' - }, - { - type: 'Uint16', - name: 'sourceLayerIndex' - }, - { - type: 'Uint16', - name: 'bucketIndex' - }, - { - type: 'Int16', - name: 'bbox0' - }, - { - type: 'Int16', - name: 'bbox1' - }, - { - type: 'Int16', - name: 'bbox2' - }, - { - type: 'Int16', - name: 'bbox3' - }, - { - type: 'Float32', - name: 'placementScale' - } - ] -}); -util.extendAll(CollisionBoxArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - } -}); -},{"../util/struct_array":180,"../util/util":182,"point-geometry":187}],135:[function(require,module,exports){ -'use strict'; -module.exports = CollisionFeature; -function CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shaped, boxScale, padding, alignLine, straight) { - 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); - if (straight) { - var vector = line[anchor.segment + 1].sub(line[anchor.segment])._unit()._mult(length); - var straightLine = [ - anchor.sub(vector), - anchor.add(vector) - ]; - this._addLineCollisionBoxes(collisionBoxArray, straightLine, anchor, 0, length, height, featureIndex, sourceLayerIndex, bucketIndex); - } else { - this._addLineCollisionBoxes(collisionBoxArray, line, anchor, anchor.segment, length, height, featureIndex, sourceLayerIndex, bucketIndex); - } - } - } else { - collisionBoxArray.emplaceBack(anchor.x, anchor.y, x1, y1, x2, y2, Infinity, featureIndex, sourceLayerIndex, bucketIndex, 0, 0, 0, 0, 0); - } - this.boxEndIndex = collisionBoxArray.length; -} -CollisionFeature.prototype._addLineCollisionBoxes = function (collisionBoxArray, line, anchor, segment, labelLength, boxSize, featureIndex, sourceLayerIndex, bucketIndex) { - var step = boxSize / 2; - var nBoxes = Math.floor(labelLength / step); - var firstBoxOffset = -boxSize / 2; - var bboxes = this.boxes; - var p = anchor; - var index = segment + 1; - var anchorDistance = firstBoxOffset; - do { - index--; - if (index < 0) - return bboxes; - anchorDistance -= line[index].dist(p); - p = line[index]; - } while (anchorDistance > -labelLength / 2); - var segmentLength = line[index].dist(line[index + 1]); - for (var i = 0; i < nBoxes; i++) { - var boxDistanceToAnchor = -labelLength / 2 + i * step; - while (anchorDistance + segmentLength < boxDistanceToAnchor) { - anchorDistance += segmentLength; - index++; - if (index + 1 >= line.length) - return bboxes; - 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 distanceToInnerEdge = Math.max(Math.abs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0); - var maxScale = labelLength / 2 / distanceToInnerEdge; - collisionBoxArray.emplaceBack(boxAnchorPoint.x, boxAnchorPoint.y, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale, featureIndex, sourceLayerIndex, bucketIndex, 0, 0, 0, 0, 0); - } - return bboxes; -}; -},{}],136:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -var EXTENT = require('../data/bucket').EXTENT; -var Grid = require('grid-index'); -module.exports = CollisionTile; -function CollisionTile(angle, pitch, collisionBoxArray) { - if (typeof angle === 'object') { - var serialized = angle; - collisionBoxArray = pitch; - angle = serialized.angle; - pitch = serialized.pitch; - this.grid = new Grid(serialized.grid); - this.ignoredGrid = new Grid(serialized.ignoredGrid); - } else { - this.grid = new Grid(EXTENT, 12, 6); - this.ignoredGrid = new Grid(EXTENT, 12, 0); - } - this.angle = angle; - this.pitch = pitch; - var sin = Math.sin(angle), cos = Math.cos(angle); - this.rotationMatrix = [ - cos, - -sin, - sin, - cos - ]; - this.reverseRotationMatrix = [ - cos, - sin, - -sin, - cos - ]; - this.yStretch = 1 / Math.cos(pitch / 180 * Math.PI); - this.yStretch = Math.pow(this.yStretch, 1.3); - this.collisionBoxArray = collisionBoxArray; - if (collisionBoxArray.length === 0) { - collisionBoxArray.emplaceBack(); - var maxInt16 = 32767; - collisionBoxArray.emplaceBack(0, 0, 0, -maxInt16, 0, maxInt16, maxInt16, 0, 0, 0, 0, 0, 0, 0, 0, 0); - collisionBoxArray.emplaceBack(EXTENT, 0, 0, -maxInt16, 0, maxInt16, maxInt16, 0, 0, 0, 0, 0, 0, 0, 0, 0); - collisionBoxArray.emplaceBack(0, 0, -maxInt16, 0, maxInt16, 0, maxInt16, 0, 0, 0, 0, 0, 0, 0, 0, 0); - collisionBoxArray.emplaceBack(0, EXTENT, -maxInt16, 0, maxInt16, 0, maxInt16, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } - this.tempCollisionBox = collisionBoxArray.get(0); - this.edges = [ - collisionBoxArray.get(1), - collisionBoxArray.get(2), - collisionBoxArray.get(3), - collisionBoxArray.get(4) - ]; -} -CollisionTile.prototype.serialize = function () { - var data = { - angle: this.angle, - pitch: this.pitch, - grid: this.grid.toArrayBuffer(), - ignoredGrid: this.ignoredGrid.toArrayBuffer() - }; - return { - data: data, - transferables: [ - data.grid, - data.ignoredGrid - ] - }; -}; -CollisionTile.prototype.minScale = 0.25; -CollisionTile.prototype.maxScale = 2; -CollisionTile.prototype.placeCollisionFeature = function (collisionFeature, allowOverlap, avoidEdges) { - var collisionBoxArray = this.collisionBoxArray; - var minPlacementScale = this.minScale; - var rotationMatrix = this.rotationMatrix; - var yStretch = this.yStretch; - for (var b = collisionFeature.boxStartIndex; b < collisionFeature.boxEndIndex; b++) { - var box = collisionBoxArray.get(b); - var anchorPoint = box.anchorPoint._matMult(rotationMatrix); - var x = anchorPoint.x; - var y = anchorPoint.y; - var x1 = x + box.x1; - var y1 = y + box.y1 * yStretch; - var x2 = x + box.x2; - var y2 = y + box.y2 * yStretch; - box.bbox0 = x1; - box.bbox1 = y1; - box.bbox2 = x2; - box.bbox3 = y2; - if (!allowOverlap) { - var blockingBoxes = this.grid.query(x1, y1, x2, y2); - for (var i = 0; i < blockingBoxes.length; i++) { - var blocking = collisionBoxArray.get(blockingBoxes[i]); - var blockingAnchorPoint = blocking.anchorPoint._matMult(rotationMatrix); - minPlacementScale = this.getPlacementScale(minPlacementScale, anchorPoint, box, blockingAnchorPoint, blocking); - if (minPlacementScale >= this.maxScale) { - return minPlacementScale; - } - } - } - if (avoidEdges) { - var rotatedCollisionBox; - if (this.angle) { - var reverseRotationMatrix = this.reverseRotationMatrix; - var tl = new Point(box.x1, box.y1).matMult(reverseRotationMatrix); - var tr = new Point(box.x2, box.y1).matMult(reverseRotationMatrix); - var bl = new Point(box.x1, box.y2).matMult(reverseRotationMatrix); - var br = new Point(box.x2, box.y2).matMult(reverseRotationMatrix); - rotatedCollisionBox = this.tempCollisionBox; - rotatedCollisionBox.anchorPointX = box.anchorPoint.x; - rotatedCollisionBox.anchorPointY = box.anchorPoint.y; - rotatedCollisionBox.x1 = Math.min(tl.x, tr.x, bl.x, br.x); - rotatedCollisionBox.y1 = Math.min(tl.y, tr.x, bl.x, br.x); - rotatedCollisionBox.x2 = Math.max(tl.x, tr.x, bl.x, br.x); - rotatedCollisionBox.y2 = Math.max(tl.y, tr.x, bl.x, br.x); - rotatedCollisionBox.maxScale = box.maxScale; - } else { - rotatedCollisionBox = box; - } - for (var k = 0; k < this.edges.length; k++) { - var edgeBox = this.edges[k]; - minPlacementScale = this.getPlacementScale(minPlacementScale, box.anchorPoint, rotatedCollisionBox, edgeBox.anchorPoint, edgeBox); - if (minPlacementScale >= this.maxScale) { - return minPlacementScale; - } - } - } - } - return minPlacementScale; -}; -CollisionTile.prototype.queryRenderedSymbols = function (minX, minY, maxX, maxY, scale) { - var sourceLayerFeatures = {}; - var result = []; - var collisionBoxArray = this.collisionBoxArray; - var rotationMatrix = this.rotationMatrix; - var anchorPoint = new Point(minX, minY)._matMult(rotationMatrix); - var queryBox = this.tempCollisionBox; - queryBox.anchorX = anchorPoint.x; - queryBox.anchorY = anchorPoint.y; - queryBox.x1 = 0; - queryBox.y1 = 0; - queryBox.x2 = maxX - minX; - queryBox.y2 = maxY - minY; - queryBox.maxScale = scale; - scale = queryBox.maxScale; - var searchBox = [ - anchorPoint.x + queryBox.x1 / scale, - anchorPoint.y + queryBox.y1 / scale * this.yStretch, - anchorPoint.x + queryBox.x2 / scale, - anchorPoint.y + queryBox.y2 / scale * this.yStretch - ]; - var blockingBoxKeys = this.grid.query(searchBox[0], searchBox[1], searchBox[2], searchBox[3]); - var blockingBoxKeys2 = this.ignoredGrid.query(searchBox[0], searchBox[1], searchBox[2], searchBox[3]); - for (var k = 0; k < blockingBoxKeys2.length; k++) { - blockingBoxKeys.push(blockingBoxKeys2[k]); - } - for (var i = 0; i < blockingBoxKeys.length; i++) { - var blocking = collisionBoxArray.get(blockingBoxKeys[i]); - var sourceLayer = blocking.sourceLayerIndex; - var featureIndex = blocking.featureIndex; - if (sourceLayerFeatures[sourceLayer] === undefined) { - sourceLayerFeatures[sourceLayer] = {}; - } - if (!sourceLayerFeatures[sourceLayer][featureIndex]) { - var blockingAnchorPoint = blocking.anchorPoint.matMult(rotationMatrix); - var minPlacementScale = this.getPlacementScale(this.minScale, anchorPoint, queryBox, blockingAnchorPoint, blocking); - if (minPlacementScale >= scale) { - sourceLayerFeatures[sourceLayer][featureIndex] = true; - result.push(blockingBoxKeys[i]); - } - } - } - return result; -}; -CollisionTile.prototype.getPlacementScale = function (minPlacementScale, anchorPoint, box, blockingAnchorPoint, blocking) { - var anchorDiffX = anchorPoint.x - blockingAnchorPoint.x; - var anchorDiffY = anchorPoint.y - blockingAnchorPoint.y; - var s1 = (blocking.x1 - box.x2) / anchorDiffX; - var s2 = (blocking.x2 - box.x1) / anchorDiffX; - var s3 = (blocking.y1 - box.y2) * this.yStretch / anchorDiffY; - var s4 = (blocking.y2 - box.y1) * this.yStretch / anchorDiffY; - if (isNaN(s1) || isNaN(s2)) - s1 = s2 = 1; - if (isNaN(s3) || isNaN(s4)) - s3 = s4 = 1; - var collisionFreeScale = Math.min(Math.max(s1, s2), Math.max(s3, s4)); - var blockingMaxScale = blocking.maxScale; - var boxMaxScale = box.maxScale; - if (collisionFreeScale > blockingMaxScale) { - collisionFreeScale = blockingMaxScale; - } - if (collisionFreeScale > boxMaxScale) { - collisionFreeScale = boxMaxScale; - } - if (collisionFreeScale > minPlacementScale && collisionFreeScale >= blocking.placementScale) { - minPlacementScale = collisionFreeScale; - } - return minPlacementScale; -}; -CollisionTile.prototype.insertCollisionFeature = function (collisionFeature, minPlacementScale, ignorePlacement) { - var grid = ignorePlacement ? this.ignoredGrid : this.grid; - var collisionBoxArray = this.collisionBoxArray; - for (var k = collisionFeature.boxStartIndex; k < collisionFeature.boxEndIndex; k++) { - var box = collisionBoxArray.get(k); - box.placementScale = minPlacementScale; - if (minPlacementScale < this.maxScale) { - grid.insert(k, box.bbox0, box.bbox1, box.bbox2, box.bbox3); - } - } -}; -},{"../data/bucket":69,"grid-index":36,"point-geometry":187}],137:[function(require,module,exports){ -'use strict'; -var interpolate = require('../util/interpolate'); -var Anchor = require('../symbol/anchor'); -var checkMaxAngle = require('./check_max_angle'); -module.exports = getAnchors; -function getAnchors(line, spacing, maxAngle, shapedText, shapedIcon, glyphSize, boxScale, overscaling, tileExtent) { - var angleWindowSize = shapedText ? 3 / 5 * glyphSize * boxScale : 0; - var labelLength = Math.max(shapedText ? shapedText.right - shapedText.left : 0, shapedIcon ? shapedIcon.right - shapedIcon.left : 0); - var isLineContinued = line[0].x === 0 || line[0].x === tileExtent || line[0].y === 0 || line[0].y === tileExtent; - if (spacing - labelLength * boxScale < spacing / 4) { - spacing = labelLength * boxScale + spacing / 4; - } - var fixedExtraOffset = glyphSize * 2; - var offset = !isLineContinued ? (labelLength / 2 + fixedExtraOffset) * boxScale * overscaling % spacing : spacing / 2 * overscaling % spacing; - return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength * boxScale, isLineContinued, false, tileExtent); -} -function resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, placeAtMiddle, tileExtent) { - var halfLabelLength = labelLength / 2; - var lineLength = 0; - for (var k = 0; k < line.length - 1; k++) { - lineLength += line[k].dist(line[k + 1]); - } - 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 = interpolate(a.x, b.x, t), y = interpolate(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)._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; -} -},{"../symbol/anchor":131,"../util/interpolate":176,"./check_max_angle":132}],138:[function(require,module,exports){ -'use strict'; -var ShelfPack = require('shelf-pack'); -var util = require('../util/util'); -var SIZE_GROWTH_RATE = 4; -var DEFAULT_SIZE = 128; -var MAX_SIZE = 2048; -module.exports = GlyphAtlas; -function GlyphAtlas() { - this.width = DEFAULT_SIZE; - this.height = DEFAULT_SIZE; - this.bin = new ShelfPack(this.width, this.height); - this.index = {}; - this.ids = {}; - this.data = new Uint8Array(this.width * this.height); -} -GlyphAtlas.prototype.getGlyphs = function () { - var glyphs = {}, split, name, id; - for (var key in this.ids) { - split = key.split('#'); - name = split[0]; - id = split[1]; - if (!glyphs[name]) - glyphs[name] = []; - glyphs[name].push(id); - } - return glyphs; -}; -GlyphAtlas.prototype.getRects = function () { - var rects = {}, split, name, id; - for (var key in this.ids) { - split = key.split('#'); - name = split[0]; - id = split[1]; - if (!rects[name]) - rects[name] = {}; - rects[name][id] = this.index[key]; - } - return rects; -}; -GlyphAtlas.prototype.addGlyph = function (id, name, glyph, buffer) { - if (!glyph) - return null; - var key = name + '#' + glyph.id; - if (this.index[key]) { - if (this.ids[key].indexOf(id) < 0) { - this.ids[key].push(id); - } - return this.index[key]; - } - if (!glyph.bitmap) { - return null; - } - var bufferedWidth = glyph.width + buffer * 2; - var bufferedHeight = glyph.height + buffer * 2; - var padding = 1; - var packWidth = bufferedWidth + 2 * padding; - var packHeight = bufferedHeight + 2 * padding; - packWidth += 4 - packWidth % 4; - packHeight += 4 - packHeight % 4; - var rect = this.bin.packOne(packWidth, packHeight); - if (!rect) { - this.resize(); - rect = this.bin.packOne(packWidth, packHeight); - } - if (!rect) { - util.warnOnce('glyph bitmap overflow'); - return null; - } - this.index[key] = rect; - this.ids[key] = [id]; - var target = this.data; - var source = glyph.bitmap; - for (var y = 0; y < bufferedHeight; y++) { - var y1 = this.width * (rect.y + y + padding) + rect.x + padding; - var y2 = bufferedWidth * y; - for (var x = 0; x < bufferedWidth; x++) { - target[y1 + x] = source[y2 + x]; - } - } - this.dirty = true; - return rect; -}; -GlyphAtlas.prototype.resize = function () { - var prevWidth = this.width; - var prevHeight = this.height; - if (prevWidth >= MAX_SIZE || prevHeight >= MAX_SIZE) - return; - if (this.texture) { - if (this.gl) { - this.gl.deleteTexture(this.texture); - } - this.texture = null; - } - this.width *= SIZE_GROWTH_RATE; - this.height *= SIZE_GROWTH_RATE; - this.bin.resize(this.width, this.height); - var buf = new ArrayBuffer(this.width * this.height); - for (var i = 0; i < prevHeight; i++) { - var src = new Uint8Array(this.data.buffer, prevHeight * i, prevWidth); - var dst = new Uint8Array(buf, prevHeight * i * SIZE_GROWTH_RATE, prevWidth); - dst.set(src); - } - this.data = new Uint8Array(buf); -}; -GlyphAtlas.prototype.bind = function (gl) { - this.gl = gl; - if (!this.texture) { - this.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - 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.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, this.width, this.height, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null); - } else { - gl.bindTexture(gl.TEXTURE_2D, this.texture); - } -}; -GlyphAtlas.prototype.updateTexture = function (gl) { - this.bind(gl); - if (this.dirty) { - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.width, this.height, gl.ALPHA, gl.UNSIGNED_BYTE, this.data); - this.dirty = false; - } -}; -},{"../util/util":182,"shelf-pack":190}],139:[function(require,module,exports){ -'use strict'; -var normalizeURL = require('../util/mapbox').normalizeGlyphsURL; -var getArrayBuffer = require('../util/ajax').getArrayBuffer; -var Glyphs = require('../util/glyphs'); -var GlyphAtlas = require('../symbol/glyph_atlas'); -var Protobuf = require('pbf'); -module.exports = GlyphSource; -function GlyphSource(url) { - this.url = url && normalizeURL(url); - this.atlases = {}; - this.stacks = {}; - this.loading = {}; -} -GlyphSource.prototype.getSimpleGlyphs = function (fontstack, glyphIDs, uid, callback) { - if (this.stacks[fontstack] === undefined) { - this.stacks[fontstack] = {}; - } - if (this.atlases[fontstack] === undefined) { - this.atlases[fontstack] = new GlyphAtlas(); - } - var glyphs = {}; - var stack = this.stacks[fontstack]; - var atlas = this.atlases[fontstack]; - var buffer = 3; - var missing = {}; - var remaining = 0; - var range; - for (var i = 0; i < glyphIDs.length; i++) { - var glyphID = glyphIDs[i]; - range = Math.floor(glyphID / 256); - if (stack[range]) { - var glyph = stack[range].glyphs[glyphID]; - var rect = atlas.addGlyph(uid, fontstack, glyph, buffer); - if (glyph) - glyphs[glyphID] = new SimpleGlyph(glyph, rect, buffer); - } else { - if (missing[range] === undefined) { - missing[range] = []; - remaining++; - } - missing[range].push(glyphID); - } - } - if (!remaining) - callback(undefined, glyphs, fontstack); - var onRangeLoaded = function (err, range, data) { - if (!err) { - var stack = this.stacks[fontstack][range] = data.stacks[0]; - for (var i = 0; i < missing[range].length; i++) { - var glyphID = missing[range][i]; - var glyph = stack.glyphs[glyphID]; - var rect = atlas.addGlyph(uid, fontstack, glyph, buffer); - if (glyph) - glyphs[glyphID] = new SimpleGlyph(glyph, rect, buffer); - } - } - remaining--; - if (!remaining) - callback(undefined, glyphs, fontstack); - }.bind(this); - for (var r in missing) { - this.loadRange(fontstack, r, onRangeLoaded); - } -}; -function SimpleGlyph(glyph, rect, buffer) { - var padding = 1; - this.advance = glyph.advance; - this.left = glyph.left - buffer - padding; - this.top = glyph.top + buffer + padding; - this.rect = rect; -} -GlyphSource.prototype.loadRange = function (fontstack, range, callback) { - if (range * 256 > 65535) - return callback('glyphs > 65535 not supported'); - if (this.loading[fontstack] === undefined) { - this.loading[fontstack] = {}; - } - var loading = this.loading[fontstack]; - if (loading[range]) { - loading[range].push(callback); - } else { - loading[range] = [callback]; - var rangeName = range * 256 + '-' + (range * 256 + 255); - var url = glyphUrl(fontstack, rangeName, this.url); - getArrayBuffer(url, function (err, data) { - var glyphs = !err && new Glyphs(new Protobuf(new Uint8Array(data))); - for (var i = 0; i < loading[range].length; i++) { - loading[range][i](err, range, glyphs); - } - delete loading[range]; - }); - } -}; -GlyphSource.prototype.getGlyphAtlas = function (fontstack) { - return this.atlases[fontstack]; -}; -function glyphUrl(fontstack, range, url, subdomains) { - subdomains = subdomains || 'abc'; - return url.replace('{s}', subdomains[fontstack.length % subdomains.length]).replace('{fontstack}', fontstack).replace('{range}', range); -} -},{"../symbol/glyph_atlas":138,"../util/ajax":165,"../util/glyphs":175,"../util/mapbox":179,"pbf":186}],140:[function(require,module,exports){ -'use strict'; -module.exports = function (features, textFeatures, geometries) { - var leftIndex = {}, rightIndex = {}, mergedFeatures = [], mergedGeom = [], mergedTexts = [], mergedIndex = 0, k; - function add(k) { - mergedFeatures.push(features[k]); - mergedGeom.push(geometries[k]); - mergedTexts.push(textFeatures[k]); - mergedIndex++; - } - function mergeFromRight(leftKey, rightKey, geom) { - var i = rightIndex[leftKey]; - delete rightIndex[leftKey]; - rightIndex[rightKey] = i; - mergedGeom[i][0].pop(); - mergedGeom[i][0] = mergedGeom[i][0].concat(geom[0]); - return i; - } - function mergeFromLeft(leftKey, rightKey, geom) { - var i = leftIndex[rightKey]; - delete leftIndex[rightKey]; - leftIndex[leftKey] = i; - mergedGeom[i][0].shift(); - mergedGeom[i][0] = geom[0].concat(mergedGeom[i][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 (k = 0; k < features.length; k++) { - var geom = geometries[k], text = textFeatures[k]; - 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, mergedGeom[j]); - delete leftIndex[leftKey]; - delete rightIndex[rightKey]; - rightIndex[getKey(text, mergedGeom[i], true)] = i; - mergedGeom[j] = 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 { - features: mergedFeatures, - textFeatures: mergedTexts, - geometries: mergedGeom - }; -}; -},{}],141:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -module.exports = { - getIconQuads: getIconQuads, - getGlyphQuads: getGlyphQuads, - SymbolQuad: SymbolQuad -}; -var minScale = 0.5; -function SymbolQuad(anchorPoint, tl, tr, bl, br, tex, anchorAngle, glyphAngle, minScale, maxScale) { - this.anchorPoint = anchorPoint; - this.tl = tl; - this.tr = tr; - this.bl = bl; - this.br = br; - this.tex = tex; - this.anchorAngle = anchorAngle; - this.glyphAngle = glyphAngle; - this.minScale = minScale; - this.maxScale = maxScale; -} -function getIconQuads(anchor, shapedIcon, boxScale, line, layer, alongLine, shapedText, globalProperties, featureProperties) { - var rect = shapedIcon.image.rect; - var layout = layer.layout; - var border = 1; - var left = shapedIcon.left - border; - var right = left + rect.w / shapedIcon.image.pixelRatio; - var top = shapedIcon.top - border; - var bottom = top + rect.h / shapedIcon.image.pixelRatio; - var tl, tr, br, bl; - if (layout['icon-text-fit'] !== 'none' && shapedText) { - var iconWidth = right - left, iconHeight = bottom - top, size = layout['text-size'] / 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['icon-text-fit-padding'][0], padR = layout['icon-text-fit-padding'][1], padB = layout['icon-text-fit-padding'][2], padL = layout['icon-text-fit-padding'][3], offsetY = layout['icon-text-fit'] === 'width' ? (textHeight - iconHeight) * 0.5 : 0, offsetX = layout['icon-text-fit'] === 'height' ? (textWidth - iconWidth) * 0.5 : 0, width = layout['icon-text-fit'] === 'width' || layout['icon-text-fit'] === 'both' ? textWidth : iconWidth, height = layout['icon-text-fit'] === 'height' || layout['icon-text-fit'] === 'both' ? textHeight : iconHeight; - tl = new Point(textLeft + offsetX - padL, textTop + offsetY - padT); - tr = new Point(textLeft + offsetX + padR + width, textTop + offsetY - padT); - br = new Point(textLeft + offsetX + padR + width, textTop + offsetY + padB + height); - bl = new Point(textLeft + offsetX - padL, textTop + offsetY + padB + height); - } else { - tl = new Point(left, top); - tr = new Point(right, top); - br = new Point(right, bottom); - bl = new Point(left, bottom); - } - var angle = layer.getLayoutValue('icon-rotate', globalProperties, featureProperties) * Math.PI / 180; - if (alongLine) { - var prev = line[anchor.segment]; - if (anchor.y === prev.y && anchor.x === prev.x && anchor.segment + 1 < line.length) { - var next = line[anchor.segment + 1]; - angle += Math.atan2(anchor.y - next.y, anchor.x - next.x) + Math.PI; - } else { - angle += Math.atan2(anchor.y - prev.y, anchor.x - prev.x); - } - } - if (angle) { - var sin = Math.sin(angle), cos = Math.cos(angle), matrix = [ - cos, - -sin, - sin, - cos - ]; - tl = tl.matMult(matrix); - tr = tr.matMult(matrix); - bl = bl.matMult(matrix); - br = br.matMult(matrix); - } - return [new SymbolQuad(new Point(anchor.x, anchor.y), tl, tr, bl, br, shapedIcon.image.rect, 0, 0, minScale, Infinity)]; -} -function getGlyphQuads(anchor, shaping, boxScale, line, layer, alongLine) { - var textRotate = layer.layout['text-rotate'] * Math.PI / 180; - var keepUpright = layer.layout['text-keep-upright']; - var positionedGlyphs = shaping.positionedGlyphs; - var quads = []; - for (var k = 0; k < positionedGlyphs.length; k++) { - var positionedGlyph = positionedGlyphs[k]; - var glyph = positionedGlyph.glyph; - var rect = glyph.rect; - if (!rect) - continue; - var centerX = (positionedGlyph.x + glyph.advance / 2) * boxScale; - var glyphInstances; - var labelMinScale = minScale; - if (alongLine) { - glyphInstances = []; - labelMinScale = getSegmentGlyphs(glyphInstances, anchor, centerX, line, anchor.segment, true); - if (keepUpright) { - labelMinScale = Math.min(labelMinScale, getSegmentGlyphs(glyphInstances, anchor, centerX, line, anchor.segment, false)); - } - } else { - glyphInstances = [{ - anchorPoint: new Point(anchor.x, anchor.y), - offset: 0, - angle: 0, - maxScale: Infinity, - minScale: minScale - }]; - } - var x1 = positionedGlyph.x + glyph.left, y1 = positionedGlyph.y - glyph.top, x2 = x1 + rect.w, y2 = y1 + rect.h, otl = new Point(x1, y1), otr = new Point(x2, y1), obl = new Point(x1, y2), obr = new Point(x2, y2); - for (var i = 0; i < glyphInstances.length; i++) { - var instance = glyphInstances[i], tl = otl, tr = otr, bl = obl, br = obr; - if (textRotate) { - var sin = Math.sin(textRotate), cos = Math.cos(textRotate), matrix = [ - cos, - -sin, - sin, - cos - ]; - tl = tl.matMult(matrix); - tr = tr.matMult(matrix); - bl = bl.matMult(matrix); - br = br.matMult(matrix); - } - var glyphMinScale = Math.max(instance.minScale, labelMinScale); - var anchorAngle = (anchor.angle + instance.offset + 2 * Math.PI) % (2 * Math.PI); - var glyphAngle = (instance.angle + instance.offset + 2 * Math.PI) % (2 * Math.PI); - quads.push(new SymbolQuad(instance.anchorPoint, tl, tr, bl, br, rect, anchorAngle, glyphAngle, glyphMinScale, instance.maxScale)); - } - } - return quads; -} -function getSegmentGlyphs(glyphs, anchor, offset, line, segment, forward) { - var upsideDown = !forward; - if (offset < 0) - forward = !forward; - if (forward) - segment++; - var newAnchorPoint = new Point(anchor.x, anchor.y); - var end = line[segment]; - var prevScale = Infinity; - offset = Math.abs(offset); - var placementScale = minScale; - while (true) { - var distance = newAnchorPoint.dist(end); - var scale = offset / distance; - var angle = Math.atan2(end.y - newAnchorPoint.y, end.x - newAnchorPoint.x); - if (!forward) - angle += Math.PI; - glyphs.push({ - anchorPoint: newAnchorPoint, - offset: upsideDown ? Math.PI : 0, - minScale: scale, - maxScale: prevScale, - angle: (angle + 2 * Math.PI) % (2 * Math.PI) - }); - if (scale <= placementScale) - break; - newAnchorPoint = end; - while (newAnchorPoint.equals(end)) { - segment += forward ? 1 : -1; - end = line[segment]; - if (!end) { - return scale; - } - } - var unit = end.sub(newAnchorPoint)._unit(); - newAnchorPoint = newAnchorPoint.sub(unit._mult(distance)); - prevScale = scale; - } - return placementScale; -} -},{"point-geometry":187}],142:[function(require,module,exports){ -'use strict'; -var resolveTokens = require('../util/token'); -module.exports = resolveText; -function resolveText(features, layoutProperties, codepoints) { - var textFeatures = []; - for (var i = 0, fl = features.length; i < fl; i++) { - var text = resolveTokens(features[i].properties, layoutProperties['text-field']); - if (!text) { - textFeatures[i] = null; - continue; - } - text = text.toString(); - var transform = layoutProperties['text-transform']; - if (transform === 'uppercase') { - text = text.toLocaleUpperCase(); - } else if (transform === 'lowercase') { - text = text.toLocaleLowerCase(); - } - for (var j = 0; j < text.length; j++) { - codepoints[text.charCodeAt(j)] = true; - } - textFeatures[i] = text; - } - return textFeatures; -} -},{"../util/token":181}],143:[function(require,module,exports){ -'use strict'; -module.exports = { - shapeText: shapeText, - shapeIcon: shapeIcon -}; -function PositionedGlyph(codePoint, x, y, glyph) { - this.codePoint = codePoint; - this.x = x; - this.y = y; - this.glyph = glyph; -} -function Shaping(positionedGlyphs, text, top, bottom, left, right) { - this.positionedGlyphs = positionedGlyphs; - this.text = text; - this.top = top; - this.bottom = bottom; - this.left = left; - this.right = right; -} -function shapeText(text, glyphs, maxWidth, lineHeight, horizontalAlign, verticalAlign, justify, spacing, translate) { - var positionedGlyphs = []; - var shaping = new Shaping(positionedGlyphs, text, translate[1], translate[1], translate[0], translate[0]); - var yOffset = -17; - var x = 0; - var y = yOffset; - for (var i = 0; i < text.length; i++) { - var codePoint = text.charCodeAt(i); - var glyph = glyphs[codePoint]; - if (!glyph) - continue; - positionedGlyphs.push(new PositionedGlyph(codePoint, x, y, glyph)); - x += glyph.advance + spacing; - } - if (!positionedGlyphs.length) - return false; - linewrap(shaping, glyphs, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate); - return shaping; -} -var invisible = { - 32: true, - 8203: true -}; -var breakable = { - 32: true, - 38: true, - 43: true, - 45: true, - 47: true, - 173: true, - 183: true, - 8203: true, - 8208: true, - 8211: true -}; -function linewrap(shaping, glyphs, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate) { - var lastSafeBreak = null; - var lengthBeforeCurrentLine = 0; - var lineStartIndex = 0; - var line = 0; - var maxLineLength = 0; - var positionedGlyphs = shaping.positionedGlyphs; - if (maxWidth) { - for (var i = 0; i < positionedGlyphs.length; i++) { - var positionedGlyph = positionedGlyphs[i]; - positionedGlyph.x -= lengthBeforeCurrentLine; - positionedGlyph.y += lineHeight * line; - if (positionedGlyph.x > maxWidth && lastSafeBreak !== null) { - var lineLength = positionedGlyphs[lastSafeBreak + 1].x; - maxLineLength = Math.max(lineLength, maxLineLength); - for (var k = lastSafeBreak + 1; k <= i; k++) { - positionedGlyphs[k].y += lineHeight; - positionedGlyphs[k].x -= lineLength; - } - if (justify) { - var lineEnd = lastSafeBreak; - if (invisible[positionedGlyphs[lastSafeBreak].codePoint]) { - lineEnd--; - } - justifyLine(positionedGlyphs, glyphs, lineStartIndex, lineEnd, justify); - } - lineStartIndex = lastSafeBreak + 1; - lastSafeBreak = null; - lengthBeforeCurrentLine += lineLength; - line++; - } - if (breakable[positionedGlyph.codePoint]) { - lastSafeBreak = i; - } - } - } - var lastPositionedGlyph = positionedGlyphs[positionedGlyphs.length - 1]; - var lastLineLength = lastPositionedGlyph.x + glyphs[lastPositionedGlyph.codePoint].advance; - maxLineLength = Math.max(maxLineLength, lastLineLength); - var height = (line + 1) * lineHeight; - justifyLine(positionedGlyphs, glyphs, lineStartIndex, positionedGlyphs.length - 1, justify); - align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate); - shaping.top += -verticalAlign * height; - shaping.bottom = shaping.top + height; - shaping.left += -horizontalAlign * maxLineLength; - shaping.right = shaping.left + maxLineLength; -} -function justifyLine(positionedGlyphs, glyphs, start, end, justify) { - var lastAdvance = glyphs[positionedGlyphs[end].codePoint].advance; - var lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify; - for (var j = start; j <= end; j++) { - positionedGlyphs[j].x -= lineIndent; - } -} -function align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate) { - var shiftX = (justify - horizontalAlign) * maxLineLength + translate[0]; - var shiftY = (-verticalAlign * (line + 1) + 0.5) * lineHeight + translate[1]; - for (var j = 0; j < positionedGlyphs.length; j++) { - positionedGlyphs[j].x += shiftX; - positionedGlyphs[j].y += shiftY; - } -} -function shapeIcon(image, layout) { - if (!image || !image.rect) - return null; - var dx = layout['icon-offset'][0]; - var dy = layout['icon-offset'][1]; - var x1 = dx - image.width / 2; - var x2 = x1 + image.width; - var y1 = dy - image.height / 2; - var y2 = y1 + image.height; - return new PositionedIcon(image, y1, y2, x1, x2); -} -function PositionedIcon(image, top, bottom, left, right) { - this.image = image; - this.top = top; - this.bottom = bottom; - this.left = left; - this.right = right; -} -},{}],144:[function(require,module,exports){ -'use strict'; -var ShelfPack = require('shelf-pack'); -var browser = require('../util/browser'); -var util = require('../util/util'); -module.exports = SpriteAtlas; -function SpriteAtlas(width, height) { - this.width = width; - this.height = height; - this.bin = new ShelfPack(width, height); - this.images = {}; - this.data = false; - this.texture = 0; - this.filter = 0; - this.pixelRatio = 1; - this.dirty = true; -} -function copyBitmap(src, srcStride, srcX, srcY, dst, dstStride, dstX, dstY, width, height, wrap) { - var srcI = srcY * srcStride + srcX; - var dstI = dstY * dstStride + dstX; - var x, y; - if (wrap) { - dstI -= dstStride; - for (y = -1; y <= height; y++, srcI = ((y + height) % height + srcY) * srcStride + srcX, dstI += dstStride) { - for (x = -1; x <= width; x++) { - dst[dstI + x] = src[srcI + (x + width) % width]; - } - } - } else { - for (y = 0; y < height; y++, srcI += srcStride, dstI += dstStride) { - for (x = 0; x < width; x++) { - dst[dstI + x] = src[srcI + x]; - } - } - } -} -SpriteAtlas.prototype.allocateImage = function (pixelWidth, pixelHeight) { - pixelWidth = pixelWidth / this.pixelRatio; - pixelHeight = pixelHeight / this.pixelRatio; - var padding = 2; - var packWidth = pixelWidth + padding + (4 - (pixelWidth + padding) % 4); - var packHeight = pixelHeight + padding + (4 - (pixelHeight + padding) % 4); - var rect = this.bin.packOne(packWidth, packHeight); - if (!rect) { - util.warnOnce('SpriteAtlas out of space.'); - return null; - } - return rect; -}; -SpriteAtlas.prototype.getImage = function (name, wrap) { - if (this.images[name]) { - return this.images[name]; - } - if (!this.sprite) { - return null; - } - var pos = this.sprite.getSpritePosition(name); - if (!pos.width || !pos.height) { - return null; - } - var rect = this.allocateImage(pos.width, pos.height); - if (!rect) { - return null; - } - var image = new AtlasImage(rect, pos.width / pos.pixelRatio, pos.height / pos.pixelRatio, pos.sdf, pos.pixelRatio / this.pixelRatio); - this.images[name] = image; - this.copy(rect, pos, wrap); - return image; -}; -SpriteAtlas.prototype.getPosition = function (name, repeating) { - var image = this.getImage(name, repeating); - var rect = image && image.rect; - if (!rect) { - return null; - } - var width = image.width * image.pixelRatio; - var height = image.height * image.pixelRatio; - var padding = 1; - return { - size: [ - image.width, - image.height - ], - tl: [ - (rect.x + padding) / this.width, - (rect.y + padding) / this.height - ], - br: [ - (rect.x + padding + width) / this.width, - (rect.y + padding + height) / this.height - ] - }; -}; -SpriteAtlas.prototype.allocate = function () { - if (!this.data) { - var w = Math.floor(this.width * this.pixelRatio); - var h = Math.floor(this.height * this.pixelRatio); - this.data = new Uint32Array(w * h); - for (var i = 0; i < this.data.length; i++) { - this.data[i] = 0; - } - } -}; -SpriteAtlas.prototype.copy = function (dst, src, wrap) { - if (!this.sprite.img.data) - return; - var srcImg = new Uint32Array(this.sprite.img.data.buffer); - this.allocate(); - var dstImg = this.data; - var padding = 1; - copyBitmap(srcImg, this.sprite.img.width, src.x, src.y, dstImg, this.width * this.pixelRatio, (dst.x + padding) * this.pixelRatio, (dst.y + padding) * this.pixelRatio, src.width, src.height, wrap); - this.dirty = true; -}; -SpriteAtlas.prototype.setSprite = function (sprite) { - if (sprite) { - this.pixelRatio = browser.devicePixelRatio > 1 ? 2 : 1; - if (this.canvas) { - this.canvas.width = this.width * this.pixelRatio; - this.canvas.height = this.height * this.pixelRatio; - } - } - this.sprite = sprite; -}; -SpriteAtlas.prototype.addIcons = function (icons, callback) { - for (var i = 0; i < icons.length; i++) { - this.getImage(icons[i]); - } - callback(null, this.images); -}; -SpriteAtlas.prototype.bind = function (gl, linear) { - var first = false; - if (!this.texture) { - this.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.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); - first = true; - } else { - gl.bindTexture(gl.TEXTURE_2D, this.texture); - } - var filterVal = linear ? gl.LINEAR : gl.NEAREST; - if (filterVal !== this.filter) { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterVal); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterVal); - this.filter = filterVal; - } - if (this.dirty) { - this.allocate(); - if (first) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width * this.pixelRatio, this.height * this.pixelRatio, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(this.data.buffer)); - } else { - gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.width * this.pixelRatio, this.height * this.pixelRatio, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(this.data.buffer)); - } - this.dirty = false; - } -}; -function AtlasImage(rect, width, height, sdf, pixelRatio) { - this.rect = rect; - this.width = width; - this.height = height; - this.sdf = sdf; - this.pixelRatio = pixelRatio; -} -},{"../util/browser":166,"../util/util":182,"shelf-pack":190}],145:[function(require,module,exports){ -'use strict'; -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); -var SymbolInstancesArray = module.exports = new StructArrayType({ - members: [ - { - type: 'Uint16', - name: 'textBoxStartIndex' - }, - { - type: 'Uint16', - name: 'textBoxEndIndex' - }, - { - type: 'Uint16', - name: 'iconBoxStartIndex' - }, - { - type: 'Uint16', - name: 'iconBoxEndIndex' - }, - { - type: 'Uint16', - name: 'glyphQuadStartIndex' - }, - { - type: 'Uint16', - name: 'glyphQuadEndIndex' - }, - { - type: 'Uint16', - name: 'iconQuadStartIndex' - }, - { - type: 'Uint16', - name: 'iconQuadEndIndex' - }, - { - type: 'Int16', - name: 'anchorPointX' - }, - { - type: 'Int16', - name: 'anchorPointY' - }, - { - type: 'Int8', - name: 'index' - } - ] -}); -util.extendAll(SymbolInstancesArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - } -}); -},{"../util/struct_array":180,"../util/util":182,"point-geometry":187}],146:[function(require,module,exports){ -'use strict'; -var StructArrayType = require('../util/struct_array'); -var util = require('../util/util'); -var Point = require('point-geometry'); -var SymbolQuad = require('./quads').SymbolQuad; -var SymbolQuadsArray = module.exports = new StructArrayType({ - members: [ - { - type: 'Int16', - name: 'anchorPointX' - }, - { - type: 'Int16', - name: 'anchorPointY' - }, - { - type: 'Float32', - name: 'tlX' - }, - { - type: 'Float32', - name: 'tlY' - }, - { - type: 'Float32', - name: 'trX' - }, - { - type: 'Float32', - name: 'trY' - }, - { - type: 'Float32', - name: 'blX' - }, - { - type: 'Float32', - name: 'blY' - }, - { - type: 'Float32', - name: 'brX' - }, - { - type: 'Float32', - name: 'brY' - }, - { - type: 'Int16', - name: 'texH' - }, - { - type: 'Int16', - name: 'texW' - }, - { - type: 'Int16', - name: 'texX' - }, - { - type: 'Int16', - name: 'texY' - }, - { - type: 'Float32', - name: 'anchorAngle' - }, - { - type: 'Float32', - name: 'glyphAngle' - }, - { - type: 'Float32', - name: 'maxScale' - }, - { - type: 'Float32', - name: 'minScale' - } - ] -}); -util.extendAll(SymbolQuadsArray.prototype.StructType.prototype, { - get anchorPoint() { - return new Point(this.anchorPointX, this.anchorPointY); - }, - get SymbolQuad() { - return new SymbolQuad(this.anchorPoint, new Point(this.tlX, this.tlY), new Point(this.trX, this.trY), new Point(this.blX, this.blY), new Point(this.brX, this.brY), { - x: this.texX, - y: this.texY, - h: this.texH, - w: this.texW, - height: this.texH, - width: this.texW - }, this.anchorAngle, this.glyphAngle, this.minScale, this.maxScale); - } -}); -},{"../util/struct_array":180,"../util/util":182,"./quads":141,"point-geometry":187}],147:[function(require,module,exports){ -'use strict'; -var DOM = require('../util/dom'); -var Point = require('point-geometry'); -var handlers = { - scrollZoom: require('./handler/scroll_zoom'), - boxZoom: require('./handler/box_zoom'), - dragRotate: require('./handler/drag_rotate'), - dragPan: require('./handler/drag_pan'), - keyboard: require('./handler/keyboard'), - doubleClickZoom: require('./handler/dblclick_zoom'), - touchZoomRotate: require('./handler/touch_zoom_rotate') -}; -module.exports = function bindHandlers(map, options) { - var el = map.getCanvasContainer(); - var contextMenuEvent = null; - var startPos = null; - var tapped = null; - for (var name in handlers) { - map[name] = new handlers[name](map, options); - if (options.interactive && options[name]) { - map[name].enable(); - } - } - el.addEventListener('mouseout', onMouseOut, false); - el.addEventListener('mousedown', onMouseDown, false); - el.addEventListener('mouseup', onMouseUp, false); - el.addEventListener('mousemove', onMouseMove, false); - el.addEventListener('touchstart', onTouchStart, false); - el.addEventListener('touchend', onTouchEnd, false); - el.addEventListener('touchmove', onTouchMove, false); - el.addEventListener('touchcancel', onTouchCancel, false); - el.addEventListener('click', onClick, false); - el.addEventListener('dblclick', onDblClick, false); - el.addEventListener('contextmenu', onContextMenu, false); - function onMouseOut(e) { - fireMouseEvent('mouseout', e); - } - function onMouseDown(e) { - map.stop(); - startPos = DOM.mousePos(el, e); - fireMouseEvent('mousedown', e); - } - function onMouseUp(e) { - var rotating = map.dragRotate && map.dragRotate.isActive(); - if (contextMenuEvent && !rotating) { - fireMouseEvent('contextmenu', contextMenuEvent); - } - contextMenuEvent = null; - fireMouseEvent('mouseup', e); - } - function onMouseMove(e) { - if (map.dragPan && map.dragPan.isActive()) - return; - if (map.dragRotate && map.dragRotate.isActive()) - return; - var target = e.toElement || e.target; - while (target && target !== el) - target = target.parentNode; - if (target !== el) - return; - fireMouseEvent('mousemove', e); - } - function onTouchStart(e) { - map.stop(); - fireTouchEvent('touchstart', e); - if (!e.touches || e.touches.length > 1) - return; - if (!tapped) { - tapped = setTimeout(onTouchTimeout, 300); - } else { - clearTimeout(tapped); - tapped = null; - fireMouseEvent('dblclick', e); - } - } - function onTouchMove(e) { - fireTouchEvent('touchmove', e); - } - function onTouchEnd(e) { - fireTouchEvent('touchend', e); - } - function onTouchCancel(e) { - fireTouchEvent('touchcancel', e); - } - function onTouchTimeout() { - tapped = null; - } - function onClick(e) { - var pos = DOM.mousePos(el, e); - if (pos.equals(startPos)) { - fireMouseEvent('click', e); - } - } - function onDblClick(e) { - fireMouseEvent('dblclick', e); - e.preventDefault(); - } - function onContextMenu(e) { - contextMenuEvent = e; - e.preventDefault(); - } - function fireMouseEvent(type, e) { - var pos = DOM.mousePos(el, e); - return map.fire(type, { - lngLat: map.unproject(pos), - point: pos, - originalEvent: e - }); - } - function fireTouchEvent(type, e) { - var touches = DOM.touchPos(el, e); - var singular = touches.reduce(function (prev, curr, i, arr) { - return prev.add(curr.div(arr.length)); - }, new Point(0, 0)); - return map.fire(type, { - lngLat: map.unproject(singular), - point: singular, - lngLats: touches.map(function (t) { - return map.unproject(t); - }, this), - points: touches, - originalEvent: e - }); - } -}; -},{"../util/dom":168,"./handler/box_zoom":153,"./handler/dblclick_zoom":154,"./handler/drag_pan":155,"./handler/drag_rotate":156,"./handler/keyboard":157,"./handler/scroll_zoom":158,"./handler/touch_zoom_rotate":159,"point-geometry":187}],148:[function(require,module,exports){ -'use strict'; -var util = require('../util/util'); -var interpolate = require('../util/interpolate'); -var browser = require('../util/browser'); -var LngLat = require('../geo/lng_lat'); -var LngLatBounds = require('../geo/lng_lat_bounds'); -var Point = require('point-geometry'); -var Camera = module.exports = function () { -}; -util.extend(Camera.prototype, { - getCenter: function () { - return this.transform.center; - }, - setCenter: function (center, eventData) { - this.jumpTo({ center: center }, eventData); - return this; - }, - panBy: function (offset, options, eventData) { - this.panTo(this.transform.center, util.extend({ offset: Point.convert(offset).mult(-1) }, options), eventData); - return this; - }, - panTo: function (lnglat, options, eventData) { - return this.easeTo(util.extend({ center: lnglat }, options), eventData); - }, - getZoom: function () { - return this.transform.zoom; - }, - setZoom: function (zoom, eventData) { - this.jumpTo({ zoom: zoom }, eventData); - return this; - }, - zoomTo: function (zoom, options, eventData) { - return this.easeTo(util.extend({ zoom: zoom }, options), eventData); - }, - zoomIn: function (options, eventData) { - this.zoomTo(this.getZoom() + 1, options, eventData); - return this; - }, - zoomOut: function (options, eventData) { - this.zoomTo(this.getZoom() - 1, options, eventData); - return this; - }, - getBearing: function () { - return this.transform.bearing; - }, - setBearing: function (bearing, eventData) { - this.jumpTo({ bearing: bearing }, eventData); - return this; - }, - rotateTo: function (bearing, options, eventData) { - return this.easeTo(util.extend({ bearing: bearing }, options), eventData); - }, - resetNorth: function (options, eventData) { - this.rotateTo(0, util.extend({ duration: 1000 }, options), eventData); - return this; - }, - snapToNorth: function (options, eventData) { - if (Math.abs(this.getBearing()) < this._bearingSnap) { - return this.resetNorth(options, eventData); - } - return this; - }, - getPitch: function () { - return this.transform.pitch; - }, - setPitch: function (pitch, eventData) { - this.jumpTo({ pitch: pitch }, eventData); - return this; - }, - fitBounds: function (bounds, options, eventData) { - options = util.extend({ - padding: 0, - offset: [ - 0, - 0 - ], - maxZoom: Infinity - }, options); - bounds = LngLatBounds.convert(bounds); - var offset = Point.convert(options.offset), tr = this.transform, nw = tr.project(bounds.getNorthWest()), se = tr.project(bounds.getSouthEast()), size = se.sub(nw), scaleX = (tr.width - options.padding * 2 - Math.abs(offset.x) * 2) / size.x, scaleY = (tr.height - options.padding * 2 - Math.abs(offset.y) * 2) / size.y; - options.center = tr.unproject(nw.add(se).div(2)); - options.zoom = Math.min(tr.scaleZoom(tr.scale * Math.min(scaleX, scaleY)), options.maxZoom); - options.bearing = 0; - return options.linear ? this.easeTo(options, eventData) : this.flyTo(options, eventData); - }, - jumpTo: function (options, eventData) { - this.stop(); - var tr = this.transform, zoomChanged = false, bearingChanged = false, pitchChanged = false; - if ('zoom' in options && tr.zoom !== +options.zoom) { - zoomChanged = true; - tr.zoom = +options.zoom; - } - if ('center' in options) { - tr.center = 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('movestart', eventData).fire('move', eventData); - if (zoomChanged) { - this.fire('zoomstart', eventData).fire('zoom', eventData).fire('zoomend', eventData); - } - if (bearingChanged) { - this.fire('rotate', eventData); - } - if (pitchChanged) { - this.fire('pitch', eventData); - } - return this.fire('moveend', eventData); - }, - easeTo: function (options, eventData) { - this.stop(); - options = util.extend({ - offset: [ - 0, - 0 - ], - duration: 500, - easing: util.ease - }, options); - var tr = this.transform, offset = Point.convert(options.offset), 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, toLngLat, toPoint; - if ('center' in options) { - toLngLat = LngLat.convert(options.center); - toPoint = tr.centerPoint.add(offset); - } else if ('around' in options) { - toLngLat = LngLat.convert(options.around); - toPoint = tr.locationPoint(toLngLat); - } else { - toPoint = tr.centerPoint.add(offset); - toLngLat = tr.pointLocation(toPoint); - } - var fromPoint = tr.locationPoint(toLngLat); - if (options.animate === false) - options.duration = 0; - this.zooming = zoom !== startZoom; - this.rotating = startBearing !== bearing; - this.pitching = pitch !== startPitch; - if (!options.noMoveStart) { - this.fire('movestart', eventData); - } - if (this.zooming) { - this.fire('zoomstart', eventData); - } - clearTimeout(this._onEaseEnd); - this._ease(function (k) { - if (this.zooming) { - tr.zoom = interpolate(startZoom, zoom, k); - } - if (this.rotating) { - tr.bearing = interpolate(startBearing, bearing, k); - } - if (this.pitching) { - tr.pitch = interpolate(startPitch, pitch, k); - } - tr.setLocationAtPoint(toLngLat, fromPoint.add(toPoint.sub(fromPoint)._mult(k))); - this.fire('move', eventData); - if (this.zooming) { - this.fire('zoom', eventData); - } - if (this.rotating) { - this.fire('rotate', eventData); - } - if (this.pitching) { - this.fire('pitch', eventData); - } - }, function () { - if (options.delayEndEvents) { - this._onEaseEnd = setTimeout(this._easeToEnd.bind(this, eventData), options.delayEndEvents); - } else { - this._easeToEnd(eventData); - } - }.bind(this), options); - return this; - }, - _easeToEnd: function (eventData) { - var wasZooming = this.zooming; - this.zooming = false; - this.rotating = false; - this.pitching = false; - if (wasZooming) { - this.fire('zoomend', eventData); - } - this.fire('moveend', eventData); - }, - flyTo: function (options, eventData) { - this.stop(); - options = util.extend({ - offset: [ - 0, - 0 - ], - speed: 1.2, - curve: 1.42, - easing: util.ease - }, options); - var tr = this.transform, offset = Point.convert(options.offset), startZoom = this.getZoom(), startBearing = this.getBearing(), startPitch = this.getPitch(); - var center = 'center' in options ? LngLat.convert(options.center) : this.getCenter(); - var zoom = 'zoom' in options ? +options.zoom : startZoom; - var bearing = 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing; - var pitch = 'pitch' in options ? +options.pitch : startPitch; - if (Math.abs(tr.center.lng) + Math.abs(center.lng) > 180) { - if (tr.center.lng > 0 && center.lng < 0) { - center.lng += 360; - } else if (tr.center.lng < 0 && center.lng > 0) { - center.lng -= 360; - } - } - var scale = tr.zoomScale(zoom - startZoom), from = tr.point, to = 'center' in options ? tr.project(center).sub(offset.div(scale)) : from; - var startWorldSize = tr.worldSize, rho = options.curve, w0 = Math.max(tr.width, tr.height), w1 = w0 / scale, u1 = to.sub(from).mag(); - if ('minZoom' in options) { - var minZoom = util.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), w = function (s) { - return cosh(r0) / cosh(r0 + rho * s); - }, u = function (s) { - return w0 * ((cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2) / u1; - }, S = (r(1) - r0) / rho; - if (Math.abs(u1) < 0.000001) { - if (Math.abs(w0 - w1) < 0.000001) - return this.easeTo(options); - 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; - } - this.zooming = true; - if (startBearing !== bearing) - this.rotating = true; - if (startPitch !== pitch) - this.pitching = true; - this.fire('movestart', eventData); - this.fire('zoomstart', eventData); - this._ease(function (k) { - var s = k * S, us = u(s); - tr.zoom = startZoom + tr.scaleZoom(1 / w(s)); - tr.center = tr.unproject(from.add(to.sub(from).mult(us)), startWorldSize); - if (this.rotating) { - tr.bearing = interpolate(startBearing, bearing, k); - } - if (this.pitching) { - tr.pitch = interpolate(startPitch, pitch, k); - } - this.fire('move', eventData); - this.fire('zoom', eventData); - if (this.rotating) { - this.fire('rotate', eventData); - } - if (this.pitching) { - this.fire('pitch', eventData); - } - }, function () { - this.zooming = false; - this.rotating = false; - this.pitching = false; - this.fire('zoomend', eventData); - this.fire('moveend', eventData); - }, options); - return this; - }, - isEasing: function () { - return !!this._abortFn; - }, - stop: function () { - if (this._abortFn) { - this._abortFn(); - this._finishEase(); - } - return this; - }, - _ease: function (frame, finish, options) { - this._finishFn = finish; - this._abortFn = browser.timed(function (t) { - frame.call(this, options.easing(t)); - if (t === 1) { - this._finishEase(); - } - }, options.animate === false ? 0 : options.duration, this); - }, - _finishEase: function () { - delete this._abortFn; - var finish = this._finishFn; - delete this._finishFn; - finish.call(this); - }, - _normalizeBearing: function (bearing, currentBearing) { - bearing = util.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; - }, - _updateEasing: function (duration, zoom, bezier) { - var easing; - if (this.ease) { - var ease = this.ease, t = (Date.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 = util.bezier(x, y, 0.25, 1); - } else { - easing = bezier ? util.bezier.apply(util, bezier) : util.ease; - } - this.ease = { - start: new Date().getTime(), - to: Math.pow(2, zoom), - duration: duration, - easing: easing - }; - return easing; - } -}); -},{"../geo/lng_lat":79,"../geo/lng_lat_bounds":80,"../util/browser":166,"../util/interpolate":176,"../util/util":182,"point-geometry":187}],149:[function(require,module,exports){ -'use strict'; -var Control = require('./control'); -var DOM = require('../../util/dom'); -var util = require('../../util/util'); -module.exports = Attribution; -function Attribution(options) { - util.setOptions(this, options); -} -Attribution.createAttributionString = function (sources) { - var attributions = []; - for (var id in sources) { - var source = sources[id]; - 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; - }); - return attributions.join(' | '); -}; -Attribution.prototype = util.inherit(Control, { - options: { position: 'bottom-right' }, - onAdd: function (map) { - var className = 'mapboxgl-ctrl-attrib', container = this._container = DOM.create('div', className, map.getContainer()); - this._update(); - map.on('source.load', this._update.bind(this)); - map.on('source.change', this._update.bind(this)); - map.on('source.remove', this._update.bind(this)); - map.on('moveend', this._updateEditLink.bind(this)); - return container; - }, - _update: function () { - if (this._map.style) { - this._container.innerHTML = Attribution.createAttributionString(this._map.style.sources); - } - this._editLink = this._container.getElementsByClassName('mapbox-improve-map')[0]; - this._updateEditLink(); - }, - _updateEditLink: function () { - if (this._editLink) { - var center = this._map.getCenter(); - this._editLink.href = 'https://www.mapbox.com/map-feedback/#/' + center.lng + '/' + center.lat + '/' + Math.round(this._map.getZoom() + 1); - } - } -}); -},{"../../util/dom":168,"../../util/util":182,"./control":150}],150:[function(require,module,exports){ -'use strict'; -var util = require('../../util/util'); -var Evented = require('../../util/evented'); -module.exports = Control; -function Control() { -} -Control.prototype = { - addTo: function (map) { - this._map = map; - var container = this._container = this.onAdd(map); - if (this.options && this.options.position) { - var pos = this.options.position; - var corner = map._controlCorners[pos]; - container.className += ' mapboxgl-ctrl'; - if (pos.indexOf('bottom') !== -1) { - corner.insertBefore(container, corner.firstChild); - } else { - corner.appendChild(container); - } - } - return this; - }, - remove: function () { - this._container.parentNode.removeChild(this._container); - if (this.onRemove) - this.onRemove(this._map); - this._map = null; - return this; - } -}; -util.extend(Control.prototype, Evented); -},{"../../util/evented":174,"../../util/util":182}],151:[function(require,module,exports){ -'use strict'; -var Control = require('./control'); -var browser = require('../../util/browser'); -var DOM = require('../../util/dom'); -var util = require('../../util/util'); -module.exports = Geolocate; -var geoOptions = { - enableHighAccuracy: false, - timeout: 6000 -}; -function Geolocate(options) { - util.setOptions(this, options); -} -Geolocate.prototype = util.inherit(Control, { - options: { position: 'top-right' }, - onAdd: function (map) { - var className = 'mapboxgl-ctrl'; - var container = this._container = DOM.create('div', className + '-group', map.getContainer()); - if (!browser.supportsGeolocation) - return container; - this._container.addEventListener('contextmenu', this._onContextMenu.bind(this)); - this._geolocateButton = DOM.create('button', className + '-icon ' + className + '-geolocate', this._container); - this._geolocateButton.type = 'button'; - this._geolocateButton.addEventListener('click', this._onClickGeolocate.bind(this)); - return container; - }, - _onContextMenu: function (e) { - e.preventDefault(); - }, - _onClickGeolocate: function () { - navigator.geolocation.getCurrentPosition(this._success.bind(this), this._error.bind(this), geoOptions); - this._timeoutId = setTimeout(this._finish.bind(this), 10000); - }, - _success: function (position) { - this._map.jumpTo({ - center: [ - position.coords.longitude, - position.coords.latitude - ], - zoom: 17, - bearing: 0, - pitch: 0 - }); - this.fire('geolocate', position); - this._finish(); - }, - _error: function (error) { - this.fire('error', error); - this._finish(); - }, - _finish: function () { - if (this._timeoutId) { - clearTimeout(this._timeoutId); - } - this._timeoutId = undefined; - } -}); -},{"../../util/browser":166,"../../util/dom":168,"../../util/util":182,"./control":150}],152:[function(require,module,exports){ -'use strict'; -var Control = require('./control'); -var DOM = require('../../util/dom'); -var util = require('../../util/util'); -module.exports = Navigation; -function Navigation(options) { - util.setOptions(this, options); -} -Navigation.prototype = util.inherit(Control, { - options: { position: 'top-right' }, - onAdd: function (map) { - var className = 'mapboxgl-ctrl'; - var container = this._container = DOM.create('div', className + '-group', map.getContainer()); - this._container.addEventListener('contextmenu', this._onContextMenu.bind(this)); - this._zoomInButton = this._createButton(className + '-icon ' + className + '-zoom-in', map.zoomIn.bind(map)); - this._zoomOutButton = this._createButton(className + '-icon ' + className + '-zoom-out', map.zoomOut.bind(map)); - this._compass = this._createButton(className + '-icon ' + className + '-compass', map.resetNorth.bind(map)); - this._compassArrow = DOM.create('div', 'arrow', this._compass); - this._compass.addEventListener('mousedown', this._onCompassDown.bind(this)); - this._onCompassMove = this._onCompassMove.bind(this); - this._onCompassUp = this._onCompassUp.bind(this); - map.on('rotate', this._rotateCompassArrow.bind(this)); - this._rotateCompassArrow(); - this._el = map.getCanvasContainer(); - return container; - }, - _onContextMenu: function (e) { - e.preventDefault(); - }, - _onCompassDown: function (e) { - if (e.button !== 0) - return; - DOM.disableDrag(); - document.addEventListener('mousemove', this._onCompassMove); - document.addEventListener('mouseup', this._onCompassUp); - this._el.dispatchEvent(copyMouseEvent(e)); - e.stopPropagation(); - }, - _onCompassMove: function (e) { - if (e.button !== 0) - return; - this._el.dispatchEvent(copyMouseEvent(e)); - e.stopPropagation(); - }, - _onCompassUp: function (e) { - if (e.button !== 0) - return; - document.removeEventListener('mousemove', this._onCompassMove); - document.removeEventListener('mouseup', this._onCompassUp); - DOM.enableDrag(); - this._el.dispatchEvent(copyMouseEvent(e)); - e.stopPropagation(); - }, - _createButton: function (className, fn) { - var a = DOM.create('button', className, this._container); - a.type = 'button'; - a.addEventListener('click', function () { - fn(); - }); - return a; - }, - _rotateCompassArrow: function () { - var rotate = 'rotate(' + this._map.transform.angle * (180 / Math.PI) + 'deg)'; - this._compassArrow.style.transform = rotate; - } -}); -function copyMouseEvent(e) { - return new MouseEvent(e.type, { - button: 2, - buttons: 2, - bubbles: true, - cancelable: true, - detail: e.detail, - view: e.view, - screenX: e.screenX, - screenY: e.screenY, - clientX: e.clientX, - clientY: e.clientY, - movementX: e.movementX, - movementY: e.movementY, - ctrlKey: e.ctrlKey, - shiftKey: e.shiftKey, - altKey: e.altKey, - metaKey: e.metaKey - }); -} -},{"../../util/dom":168,"../../util/util":182,"./control":150}],153:[function(require,module,exports){ -'use strict'; -var DOM = require('../../util/dom'), LngLatBounds = require('../../geo/lng_lat_bounds'), util = require('../../util/util'); -module.exports = BoxZoomHandler; -function BoxZoomHandler(map) { - this._map = map; - this._el = map.getCanvasContainer(); - this._container = map.getContainer(); - util.bindHandlers(this); -} -BoxZoomHandler.prototype = { - _enabled: false, - _active: false, - isEnabled: function () { - return this._enabled; - }, - isActive: function () { - return this._active; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('mousedown', this._onMouseDown, false); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('mousedown', this._onMouseDown); - this._enabled = false; - }, - _onMouseDown: function (e) { - if (!(e.shiftKey && e.button === 0)) - return; - document.addEventListener('mousemove', this._onMouseMove, false); - document.addEventListener('keydown', this._onKeyDown, false); - document.addEventListener('mouseup', this._onMouseUp, false); - DOM.disableDrag(); - this._startPos = DOM.mousePos(this._el, e); - this._active = true; - }, - _onMouseMove: function (e) { - var p0 = this._startPos, p1 = DOM.mousePos(this._el, e); - 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, p1.x), maxX = Math.max(p0.x, p1.x), minY = Math.min(p0.y, p1.y), maxY = Math.max(p0.y, p1.y); - DOM.setTransform(this._box, 'translate(' + minX + 'px,' + minY + 'px)'); - this._box.style.width = maxX - minX + 'px'; - this._box.style.height = maxY - minY + 'px'; - }, - _onMouseUp: function (e) { - if (e.button !== 0) - return; - var p0 = this._startPos, p1 = DOM.mousePos(this._el, e), bounds = new LngLatBounds(this._map.unproject(p0), this._map.unproject(p1)); - this._finish(); - if (p0.x === p1.x && p0.y === p1.y) { - this._fireEvent('boxzoomcancel', e); - } else { - this._map.fitBounds(bounds, { linear: true }).fire('boxzoomend', { - originalEvent: e, - boxZoomBounds: bounds - }); - } - }, - _onKeyDown: function (e) { - if (e.keyCode === 27) { - this._finish(); - this._fireEvent('boxzoomcancel', e); - } - }, - _finish: function () { - this._active = false; - document.removeEventListener('mousemove', this._onMouseMove, false); - document.removeEventListener('keydown', this._onKeyDown, false); - document.removeEventListener('mouseup', this._onMouseUp, false); - this._container.classList.remove('mapboxgl-crosshair'); - if (this._box) { - this._box.parentNode.removeChild(this._box); - this._box = null; - } - DOM.enableDrag(); - }, - _fireEvent: function (type, e) { - return this._map.fire(type, { originalEvent: e }); - } -}; -},{"../../geo/lng_lat_bounds":80,"../../util/dom":168,"../../util/util":182}],154:[function(require,module,exports){ -'use strict'; -module.exports = DoubleClickZoomHandler; -function DoubleClickZoomHandler(map) { - this._map = map; - this._onDblClick = this._onDblClick.bind(this); -} -DoubleClickZoomHandler.prototype = { - _enabled: false, - isEnabled: function () { - return this._enabled; - }, - enable: function () { - if (this.isEnabled()) - return; - this._map.on('dblclick', this._onDblClick); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._map.off('dblclick', this._onDblClick); - this._enabled = false; - }, - _onDblClick: function (e) { - this._map.zoomTo(this._map.getZoom() + (e.originalEvent.shiftKey ? -1 : 1), { around: e.lngLat }, e); - } -}; -},{}],155:[function(require,module,exports){ -'use strict'; -var DOM = require('../../util/dom'), util = require('../../util/util'); -module.exports = DragPanHandler; -var inertiaLinearity = 0.3, inertiaEasing = util.bezier(0, 0, inertiaLinearity, 1), inertiaMaxSpeed = 1400, inertiaDeceleration = 2500; -function DragPanHandler(map) { - this._map = map; - this._el = map.getCanvasContainer(); - util.bindHandlers(this); -} -DragPanHandler.prototype = { - _enabled: false, - _active: false, - isEnabled: function () { - return this._enabled; - }, - isActive: function () { - return this._active; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('mousedown', this._onDown); - this._el.addEventListener('touchstart', this._onDown); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('mousedown', this._onDown); - this._el.removeEventListener('touchstart', this._onDown); - this._enabled = false; - }, - _onDown: function (e) { - if (this._ignoreEvent(e)) - return; - if (this.isActive()) - return; - if (e.touches) { - document.addEventListener('touchmove', this._onMove); - document.addEventListener('touchend', this._onTouchEnd); - } else { - document.addEventListener('mousemove', this._onMove); - document.addEventListener('mouseup', this._onMouseUp); - } - this._active = false; - this._startPos = this._pos = DOM.mousePos(this._el, e); - this._inertia = [[ - Date.now(), - this._pos - ]]; - }, - _onMove: function (e) { - if (this._ignoreEvent(e)) - return; - if (!this.isActive()) { - this._active = true; - this._fireEvent('dragstart', e); - this._fireEvent('movestart', e); - } - var pos = DOM.mousePos(this._el, e), map = this._map; - map.stop(); - this._drainInertiaBuffer(); - this._inertia.push([ - Date.now(), - pos - ]); - map.transform.setLocationAtPoint(map.transform.pointLocation(this._pos), pos); - this._fireEvent('drag', e); - this._fireEvent('move', e); - this._pos = pos; - e.preventDefault(); - }, - _onUp: function (e) { - if (!this.isActive()) - return; - this._active = false; - this._fireEvent('dragend', e); - this._drainInertiaBuffer(); - var finish = function () { - this._fireEvent('moveend', e); - }.bind(this); - var inertia = this._inertia; - if (inertia.length < 2) { - finish(); - 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])) { - finish(); - return; - } - var velocity = flingOffset.mult(inertiaLinearity / flingDuration), speed = velocity.mag(); - if (speed > inertiaMaxSpeed) { - speed = inertiaMaxSpeed; - velocity._unit()._mult(speed); - } - var duration = speed / (inertiaDeceleration * inertiaLinearity), offset = velocity.mult(-duration / 2); - this._map.panBy(offset, { - duration: duration * 1000, - easing: inertiaEasing, - noMoveStart: true - }, { originalEvent: e }); - }, - _onMouseUp: function (e) { - if (this._ignoreEvent(e)) - return; - this._onUp(e); - document.removeEventListener('mousemove', this._onMove); - document.removeEventListener('mouseup', this._onMouseUp); - }, - _onTouchEnd: function (e) { - if (this._ignoreEvent(e)) - return; - this._onUp(e); - document.removeEventListener('touchmove', this._onMove); - document.removeEventListener('touchend', this._onTouchEnd); - }, - _fireEvent: function (type, e) { - return this._map.fire(type, { originalEvent: e }); - }, - _ignoreEvent: function (e) { - var map = this._map; - if (map.boxZoom && map.boxZoom.isActive()) - return true; - if (map.dragRotate && map.dragRotate.isActive()) - return true; - if (e.touches) { - return e.touches.length > 1; - } else { - if (e.ctrlKey) - return true; - var buttons = 1, button = 0; - return e.type === 'mousemove' ? e.buttons & buttons === 0 : e.button !== button; - } - }, - _drainInertiaBuffer: function () { - var inertia = this._inertia, now = Date.now(), cutoff = 160; - while (inertia.length > 0 && now - inertia[0][0] > cutoff) - inertia.shift(); - } -}; -},{"../../util/dom":168,"../../util/util":182}],156:[function(require,module,exports){ -'use strict'; -var DOM = require('../../util/dom'), Point = require('point-geometry'), util = require('../../util/util'); -module.exports = DragRotateHandler; -var inertiaLinearity = 0.25, inertiaEasing = util.bezier(0, 0, inertiaLinearity, 1), inertiaMaxSpeed = 180, inertiaDeceleration = 720; -function DragRotateHandler(map, options) { - this._map = map; - this._el = map.getCanvasContainer(); - this._bearingSnap = options.bearingSnap; - util.bindHandlers(this); -} -DragRotateHandler.prototype = { - _enabled: false, - _active: false, - isEnabled: function () { - return this._enabled; - }, - isActive: function () { - return this._active; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('mousedown', this._onDown); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('mousedown', this._onDown); - this._enabled = false; - }, - _onDown: function (e) { - if (this._ignoreEvent(e)) - return; - if (this.isActive()) - return; - document.addEventListener('mousemove', this._onMove); - document.addEventListener('mouseup', this._onUp); - this._active = false; - this._inertia = [[ - Date.now(), - this._map.getBearing() - ]]; - this._startPos = this._pos = DOM.mousePos(this._el, e); - this._center = this._map.transform.centerPoint; - var startToCenter = this._startPos.sub(this._center), startToCenterDist = startToCenter.mag(); - if (startToCenterDist < 200) { - this._center = this._startPos.add(new Point(-200, 0)._rotate(startToCenter.angle())); - } - e.preventDefault(); - }, - _onMove: function (e) { - if (this._ignoreEvent(e)) - return; - if (!this.isActive()) { - this._active = true; - this._fireEvent('rotatestart', e); - this._fireEvent('movestart', e); - } - var map = this._map; - map.stop(); - var p1 = this._pos, p2 = DOM.mousePos(this._el, e), center = this._center, bearingDiff = p1.sub(center).angleWith(p2.sub(center)) / Math.PI * 180, bearing = map.getBearing() - bearingDiff, inertia = this._inertia, last = inertia[inertia.length - 1]; - this._drainInertiaBuffer(); - inertia.push([ - Date.now(), - map._normalizeBearing(bearing, last[1]) - ]); - map.transform.bearing = bearing; - this._fireEvent('rotate', e); - this._fireEvent('move', e); - this._pos = p2; - }, - _onUp: function (e) { - if (this._ignoreEvent(e)) - return; - document.removeEventListener('mousemove', this._onMove); - document.removeEventListener('mouseup', this._onUp); - if (!this.isActive()) - return; - this._active = false; - this._fireEvent('rotateend', e); - this._drainInertiaBuffer(); - var map = this._map, mapBearing = map.getBearing(), inertia = this._inertia; - var finish = function () { - if (Math.abs(mapBearing) < this._bearingSnap) { - map.resetNorth({ noMoveStart: true }, { originalEvent: e }); - } else { - this._fireEvent('moveend', e); - } - }.bind(this); - if (inertia.length < 2) { - finish(); - return; - } - var first = inertia[0], last = inertia[inertia.length - 1], previous = inertia[inertia.length - 2], bearing = map._normalizeBearing(mapBearing, previous[1]), 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 }); - }, - _fireEvent: function (type, e) { - return this._map.fire(type, { originalEvent: e }); - }, - _ignoreEvent: function (e) { - var map = this._map; - if (map.boxZoom && map.boxZoom.isActive()) - return true; - if (map.dragPan && map.dragPan.isActive()) - return true; - if (e.touches) { - return e.touches.length > 1; - } else { - var buttons = e.ctrlKey ? 1 : 2, button = e.ctrlKey ? 0 : 2; - return e.type === 'mousemove' ? e.buttons & buttons === 0 : e.button !== button; - } - }, - _drainInertiaBuffer: function () { - var inertia = this._inertia, now = Date.now(), cutoff = 160; - while (inertia.length > 0 && now - inertia[0][0] > cutoff) - inertia.shift(); - } -}; -},{"../../util/dom":168,"../../util/util":182,"point-geometry":187}],157:[function(require,module,exports){ -'use strict'; -module.exports = KeyboardHandler; -var panDelta = 80, rotateDelta = 2, pitchDelta = 5; -function KeyboardHandler(map) { - this._map = map; - this._el = map.getCanvasContainer(); - this._onKeyDown = this._onKeyDown.bind(this); -} -KeyboardHandler.prototype = { - _enabled: false, - isEnabled: function () { - return this._enabled; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('keydown', this._onKeyDown, false); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('keydown', this._onKeyDown); - this._enabled = false; - }, - _onKeyDown: function (e) { - if (e.altKey || e.ctrlKey || e.metaKey) - return; - var map = this._map, eventData = { originalEvent: e }; - if (map.isEasing()) - return; - switch (e.keyCode) { - case 61: - case 107: - case 171: - case 187: - map.zoomTo(Math.round(map.getZoom()) + (e.shiftKey ? 2 : 1), eventData); - break; - case 189: - case 109: - case 173: - map.zoomTo(Math.round(map.getZoom()) - (e.shiftKey ? 2 : 1), eventData); - break; - case 37: - if (e.shiftKey) { - map.easeTo({ bearing: map.getBearing() - rotateDelta }, eventData); - } else { - e.preventDefault(); - map.panBy([ - -panDelta, - 0 - ], eventData); - } - break; - case 39: - if (e.shiftKey) { - map.easeTo({ bearing: map.getBearing() + rotateDelta }, eventData); - } else { - e.preventDefault(); - map.panBy([ - panDelta, - 0 - ], eventData); - } - break; - case 38: - if (e.shiftKey) { - map.easeTo({ pitch: map.getPitch() + pitchDelta }, eventData); - } else { - e.preventDefault(); - map.panBy([ - 0, - -panDelta - ], eventData); - } - break; - case 40: - if (e.shiftKey) { - map.easeTo({ pitch: Math.max(map.getPitch() - pitchDelta, 0) }, eventData); - } else { - e.preventDefault(); - map.panBy([ - 0, - panDelta - ], eventData); - } - break; - } - } -}; -},{}],158:[function(require,module,exports){ -'use strict'; -var DOM = require('../../util/dom'), browser = require('../../util/browser'), util = require('../../util/util'); -module.exports = ScrollZoomHandler; -var ua = typeof navigator !== 'undefined' ? navigator.userAgent.toLowerCase() : '', firefox = ua.indexOf('firefox') !== -1, safari = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') === -1; -function ScrollZoomHandler(map) { - this._map = map; - this._el = map.getCanvasContainer(); - util.bindHandlers(this); -} -ScrollZoomHandler.prototype = { - _enabled: false, - isEnabled: function () { - return this._enabled; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('wheel', this._onWheel, false); - this._el.addEventListener('mousewheel', this._onWheel, false); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('wheel', this._onWheel); - this._el.removeEventListener('mousewheel', this._onWheel); - this._enabled = false; - }, - _onWheel: function (e) { - var value; - if (e.type === 'wheel') { - value = e.deltaY; - if (firefox && e.deltaMode === window.WheelEvent.DOM_DELTA_PIXEL) - value /= browser.devicePixelRatio; - if (e.deltaMode === window.WheelEvent.DOM_DELTA_LINE) - value *= 40; - } else if (e.type === 'mousewheel') { - value = -e.wheelDeltaY; - if (safari) - value = value / 3; - } - var now = browser.now(), timeDelta = now - (this._time || 0); - this._pos = DOM.mousePos(this._el, e); - this._time = now; - if (value !== 0 && value % 4.000244140625 === 0) { - this._type = 'wheel'; - value = Math.floor(value / 4); - } 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); - } 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._zoom(-value, e); - e.preventDefault(); - }, - _onTimeout: function () { - this._type = 'wheel'; - this._zoom(-this._lastValue); - }, - _zoom: function (delta, e) { - if (delta === 0) - return; - var map = this._map; - var scale = 2 / (1 + Math.exp(-Math.abs(delta / 100))); - if (delta < 0 && scale !== 0) - scale = 1 / scale; - var fromScale = map.ease ? map.ease.to : map.transform.scale, targetZoom = map.transform.scaleZoom(fromScale * scale); - map.zoomTo(targetZoom, { - duration: 0, - around: map.unproject(this._pos), - delayEndEvents: 200 - }, { originalEvent: e }); - } -}; -},{"../../util/browser":166,"../../util/dom":168,"../../util/util":182}],159:[function(require,module,exports){ -'use strict'; -var DOM = require('../../util/dom'), util = require('../../util/util'); -module.exports = TouchZoomRotateHandler; -var inertiaLinearity = 0.15, inertiaEasing = util.bezier(0, 0, inertiaLinearity, 1), inertiaDeceleration = 12, inertiaMaxSpeed = 2.5, significantScaleThreshold = 0.15, significantRotateThreshold = 4; -function TouchZoomRotateHandler(map) { - this._map = map; - this._el = map.getCanvasContainer(); - util.bindHandlers(this); -} -TouchZoomRotateHandler.prototype = { - _enabled: false, - isEnabled: function () { - return this._enabled; - }, - enable: function () { - if (this.isEnabled()) - return; - this._el.addEventListener('touchstart', this._onStart, false); - this._enabled = true; - }, - disable: function () { - if (!this.isEnabled()) - return; - this._el.removeEventListener('touchstart', this._onStart); - this._enabled = false; - }, - disableRotation: function () { - this._rotationDisabled = true; - }, - enableRotation: function () { - this._rotationDisabled = false; - }, - _onStart: function (e) { - if (e.touches.length !== 2) - return; - var p0 = DOM.mousePos(this._el, e.touches[0]), p1 = DOM.mousePos(this._el, e.touches[1]); - this._startVec = p0.sub(p1); - this._startScale = this._map.transform.scale; - this._startBearing = this._map.transform.bearing; - this._gestureIntent = undefined; - this._inertia = []; - document.addEventListener('touchmove', this._onMove, false); - document.addEventListener('touchend', this._onEnd, false); - }, - _onMove: function (e) { - if (e.touches.length !== 2) - return; - var p0 = DOM.mousePos(this._el, e.touches[0]), p1 = DOM.mousePos(this._el, e.touches[1]), p = p0.add(p1).div(2), vec = p0.sub(p1), scale = vec.mag() / this._startVec.mag(), bearing = this._rotationDisabled ? 0 : vec.angleWith(this._startVec) * 180 / Math.PI, map = this._map; - if (!this._gestureIntent) { - var scalingSignificantly = 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._startVec = vec; - this._startScale = map.transform.scale; - this._startBearing = map.transform.bearing; - } - } else { - var param = { - duration: 0, - around: map.unproject(p) - }; - if (this._gestureIntent === 'rotate') { - param.bearing = this._startBearing + bearing; - } - if (this._gestureIntent === 'zoom' || this._gestureIntent === 'rotate') { - param.zoom = map.transform.scaleZoom(this._startScale * scale); - } - map.stop(); - this._drainInertiaBuffer(); - this._inertia.push([ - Date.now(), - scale, - p - ]); - map.easeTo(param, { originalEvent: e }); - } - e.preventDefault(); - }, - _onEnd: function (e) { - document.removeEventListener('touchmove', this._onMove); - document.removeEventListener('touchend', this._onEnd); - 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(this._startScale * last[1]), firstScale = map.transform.scaleZoom(this._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 / scaleDuration; - if (Math.abs(speed) > inertiaMaxSpeed) { - if (speed > 0) { - speed = inertiaMaxSpeed; - } else { - speed = -inertiaMaxSpeed; - } - } - var duration = Math.abs(speed / (inertiaDeceleration * inertiaLinearity)) * 1000, targetScale = lastScale + speed * duration / 2000; - if (targetScale < 0) { - targetScale = 0; - } - map.easeTo({ - zoom: targetScale, - duration: duration, - easing: inertiaEasing, - around: map.unproject(p) - }, { originalEvent: e }); - }, - _drainInertiaBuffer: function () { - var inertia = this._inertia, now = Date.now(), cutoff = 160; - while (inertia.length > 2 && now - inertia[0][0] > cutoff) - inertia.shift(); - } -}; -},{"../../util/dom":168,"../../util/util":182}],160:[function(require,module,exports){ -'use strict'; -module.exports = Hash; -var util = require('../util/util'); -function Hash() { - util.bindAll([ - '_onHashChange', - '_updateHash' - ], this); -} -Hash.prototype = { - addTo: function (map) { - this._map = map; - window.addEventListener('hashchange', this._onHashChange, false); - this._map.on('moveend', this._updateHash); - return this; - }, - remove: function () { - window.removeEventListener('hashchange', this._onHashChange, false); - this._map.off('moveend', this._updateHash); - delete this._map; - return this; - }, - _onHashChange: function () { - var loc = location.hash.replace('#', '').split('/'); - if (loc.length >= 3) { - this._map.jumpTo({ - center: [ - +loc[2], - +loc[1] - ], - zoom: +loc[0], - bearing: +(loc[3] || 0) - }); - return true; - } - return false; - }, - _updateHash: function () { - var center = this._map.getCenter(), zoom = this._map.getZoom(), bearing = this._map.getBearing(), precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)), hash = '#' + Math.round(zoom * 100) / 100 + '/' + center.lat.toFixed(precision) + '/' + center.lng.toFixed(precision) + (bearing ? '/' + Math.round(bearing * 10) / 10 : ''); - window.history.replaceState('', '', hash); - } -}; -},{"../util/util":182}],161:[function(require,module,exports){ -'use strict'; -var Canvas = require('../util/canvas'); -var util = require('../util/util'); -var browser = require('../util/browser'); -var window = require('../util/browser').window; -var Evented = require('../util/evented'); -var DOM = require('../util/dom'); -var Source = require('../source/source'); -var Style = require('../style/style'); -var AnimationLoop = require('../style/animation_loop'); -var Painter = require('../render/painter'); -var Transform = require('../geo/transform'); -var Hash = require('./hash'); -var bindHandlers = require('./bind_handlers'); -var Camera = require('./camera'); -var LngLat = require('../geo/lng_lat'); -var LngLatBounds = require('../geo/lng_lat_bounds'); -var Point = require('point-geometry'); -var Attribution = require('./control/attribution'); -var defaultMinZoom = 0; -var defaultMaxZoom = 20; -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, - hash: false, - attributionControl: true, - failIfMajorPerformanceCaveat: false, - preserveDrawingBuffer: false, - trackResize: true, - workerCount: Math.max(browser.hardwareConcurrency - 1, 1) -}; -var Map = module.exports = function (options) { - options = util.extend({}, defaultOptions, options); - if (options.workerCount < 1) { - throw new Error('workerCount must an integer greater than or equal to 1.'); - } - this._interactive = options.interactive; - this._failIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat; - this._preserveDrawingBuffer = options.preserveDrawingBuffer; - this._trackResize = options.trackResize; - this._workerCount = options.workerCount; - this._bearingSnap = options.bearingSnap; - if (typeof options.container === 'string') { - this._container = document.getElementById(options.container); - } else { - this._container = options.container; - } - this.animationLoop = new AnimationLoop(); - this.transform = new Transform(options.minZoom, options.maxZoom); - if (options.maxBounds) { - this.setMaxBounds(options.maxBounds); - } - util.bindAll([ - '_forwardStyleEvent', - '_forwardSourceEvent', - '_forwardLayerEvent', - '_forwardTileEvent', - '_onStyleLoad', - '_onStyleChange', - '_onSourceAdd', - '_onSourceRemove', - '_onSourceUpdate', - '_onWindowOnline', - '_onWindowResize', - '_update', - '_render' - ], this); - this._setupContainer(); - this._setupPainter(); - this.on('move', this._update.bind(this, false)); - this.on('zoom', this._update.bind(this, true)); - this.on('moveend', function () { - this.animationLoop.set(300); - this._rerender(); - }.bind(this)); - if (typeof window !== 'undefined') { - window.addEventListener('online', this._onWindowOnline, false); - 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 - }); - } - this.stacks = {}; - this._classes = []; - this.resize(); - if (options.classes) - this.setClasses(options.classes); - if (options.customSourceTypes) { - for (var sourceTypeName in options.customSourceTypes) { - Source.addType(sourceTypeName, options.customSourceTypes[sourceTypeName]); - } - } - if (options.style) - this.setStyle(options.style); - if (options.attributionControl) - this.addControl(new Attribution(options.attributionControl)); - var fireError = this.fire.bind(this, 'error'); - this.on('style.error', fireError); - this.on('source.error', fireError); - this.on('tile.error', fireError); - this.on('layer.error', fireError); -}; -util.extend(Map.prototype, Evented); -util.extend(Map.prototype, Camera.prototype); -util.extend(Map.prototype, { - addControl: function (control) { - control.addTo(this); - return this; - }, - addClass: function (klass, options) { - if (this._classes.indexOf(klass) >= 0 || klass === '') - return this; - this._classes.push(klass); - this._classOptions = options; - if (this.style) - this.style.updateClasses(); - return this._update(true); - }, - removeClass: function (klass, options) { - var i = this._classes.indexOf(klass); - if (i < 0 || klass === '') - return this; - this._classes.splice(i, 1); - this._classOptions = options; - if (this.style) - this.style.updateClasses(); - return this._update(true); - }, - setClasses: function (klasses, options) { - var uniqueClasses = {}; - for (var i = 0; i < klasses.length; i++) { - if (klasses[i] !== '') - uniqueClasses[klasses[i]] = true; - } - this._classes = Object.keys(uniqueClasses); - this._classOptions = options; - if (this.style) - this.style.updateClasses(); - return this._update(true); - }, - hasClass: function (klass) { - return this._classes.indexOf(klass) >= 0; - }, - getClasses: function () { - return this._classes; - }, - resize: function () { - var width = 0, height = 0; - if (this._container) { - width = this._container.offsetWidth || 400; - height = this._container.offsetHeight || 300; - } - this._canvas.resize(width, height); - this.transform.resize(width, height); - this.painter.resize(width, height); - return this.fire('movestart').fire('move').fire('resize').fire('moveend'); - }, - getBounds: function () { - var bounds = new LngLatBounds(this.transform.pointLocation(new Point(0, 0)), this.transform.pointLocation(this.transform.size)); - if (this.transform.angle || this.transform.pitch) { - bounds.extend(this.transform.pointLocation(new Point(this.transform.size.x, 0))); - bounds.extend(this.transform.pointLocation(new Point(0, this.transform.size.y))); - } - return bounds; - }, - setMaxBounds: function (lnglatbounds) { - if (lnglatbounds) { - var b = LngLatBounds.convert(lnglatbounds); - this.transform.lngRange = [ - b.getWest(), - b.getEast() - ]; - this.transform.latRange = [ - b.getSouth(), - b.getNorth() - ]; - this.transform._constrain(); - this._update(); - } else if (lnglatbounds === null || lnglatbounds === undefined) { - this.transform.lngRange = []; - this.transform.latRange = []; - this._update(); - } - return this; - }, - setMinZoom: function (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'); - }, - setMaxZoom: function (maxZoom) { - maxZoom = maxZoom === null || maxZoom === undefined ? defaultMaxZoom : maxZoom; - if (maxZoom >= this.transform.minZoom && maxZoom <= defaultMaxZoom) { - this.transform.maxZoom = maxZoom; - this._update(); - if (this.getZoom() > maxZoom) - this.setZoom(maxZoom); - return this; - } else - throw new Error('maxZoom must be between the current minZoom and ' + defaultMaxZoom + ', inclusive'); - }, - project: function (lnglat) { - return this.transform.locationPoint(LngLat.convert(lnglat)); - }, - unproject: function (point) { - return this.transform.pointLocation(Point.convert(point)); - }, - queryRenderedFeatures: function () { - var params = {}; - var geometry; - if (arguments.length === 2) { - geometry = arguments[0]; - params = arguments[1]; - } else if (arguments.length === 1 && isPointLike(arguments[0])) { - geometry = arguments[0]; - } else if (arguments.length === 1) { - params = arguments[0]; - } - return this.style.queryRenderedFeatures(this._makeQueryGeometry(geometry), params, this.transform.zoom, this.transform.angle); - function isPointLike(input) { - return input instanceof Point || Array.isArray(input); - } - }, - _makeQueryGeometry: function (pointOrBox) { - if (pointOrBox === undefined) { - pointOrBox = [ - Point.convert([ - 0, - 0 - ]), - Point.convert([ - this.transform.width, - this.transform.height - ]) - ]; - } - var queryGeometry; - var isPoint = pointOrBox instanceof Point || typeof pointOrBox[0] === 'number'; - if (isPoint) { - var point = Point.convert(pointOrBox); - queryGeometry = [point]; - } else { - var box = [ - Point.convert(pointOrBox[0]), - Point.convert(pointOrBox[1]) - ]; - queryGeometry = [ - box[0], - new Point(box[1].x, box[0].y), - box[1], - new Point(box[0].x, box[1].y), - box[0] - ]; - } - queryGeometry = queryGeometry.map(function (p) { - return this.transform.pointCoordinate(p); - }.bind(this)); - return queryGeometry; - }, - querySourceFeatures: function (sourceID, params) { - return this.style.querySourceFeatures(sourceID, params); - }, - setStyle: function (style) { - if (this.style) { - this.style.off('load', this._onStyleLoad).off('error', this._forwardStyleEvent).off('change', this._onStyleChange).off('source.add', this._onSourceAdd).off('source.remove', this._onSourceRemove).off('source.load', this._onSourceUpdate).off('source.error', this._forwardSourceEvent).off('source.change', this._onSourceUpdate).off('layer.add', this._forwardLayerEvent).off('layer.remove', this._forwardLayerEvent).off('layer.error', this._forwardLayerEvent).off('tile.add', this._forwardTileEvent).off('tile.remove', this._forwardTileEvent).off('tile.load', this._update).off('tile.error', this._forwardTileEvent).off('tile.stats', this._forwardTileEvent)._remove(); - this.off('rotate', this.style._redoPlacement); - this.off('pitch', this.style._redoPlacement); - } - if (!style) { - this.style = null; - return this; - } else if (style instanceof Style) { - this.style = style; - } else { - this.style = new Style(style, this.animationLoop, this._workerCount); - } - this.style.on('load', this._onStyleLoad).on('error', this._forwardStyleEvent).on('change', this._onStyleChange).on('source.add', this._onSourceAdd).on('source.remove', this._onSourceRemove).on('source.load', this._onSourceUpdate).on('source.error', this._forwardSourceEvent).on('source.change', this._onSourceUpdate).on('layer.add', this._forwardLayerEvent).on('layer.remove', this._forwardLayerEvent).on('layer.error', this._forwardLayerEvent).on('tile.add', this._forwardTileEvent).on('tile.remove', this._forwardTileEvent).on('tile.load', this._update).on('tile.error', this._forwardTileEvent).on('tile.stats', this._forwardTileEvent); - this.on('rotate', this.style._redoPlacement); - this.on('pitch', this.style._redoPlacement); - return this; - }, - getStyle: function () { - if (this.style) { - return this.style.serialize(); - } - }, - addSource: function (id, source) { - this.style.addSource(id, source); - this._update(true); - return this; - }, - removeSource: function (id) { - this.style.removeSource(id); - this._update(true); - return this; - }, - getSource: function (id) { - return this.style.getSource(id); - }, - addLayer: function (layer, before) { - this.style.addLayer(layer, before); - this._update(true); - return this; - }, - removeLayer: function (id) { - this.style.removeLayer(id); - this._update(true); - return this; - }, - getLayer: function (id) { - return this.style.getLayer(id); - }, - setFilter: function (layer, filter) { - this.style.setFilter(layer, filter); - this._update(true); - return this; - }, - setLayerZoomRange: function (layerId, minzoom, maxzoom) { - this.style.setLayerZoomRange(layerId, minzoom, maxzoom); - this._update(true); - return this; - }, - getFilter: function (layer) { - return this.style.getFilter(layer); - }, - setPaintProperty: function (layer, name, value, klass) { - this.style.setPaintProperty(layer, name, value, klass); - this._update(true); - return this; - }, - getPaintProperty: function (layer, name, klass) { - return this.style.getPaintProperty(layer, name, klass); - }, - setLayoutProperty: function (layer, name, value) { - this.style.setLayoutProperty(layer, name, value); - this._update(true); - return this; - }, - getLayoutProperty: function (layer, name) { - return this.style.getLayoutProperty(layer, name); - }, - getContainer: function () { - return this._container; - }, - getCanvasContainer: function () { - return this._canvasContainer; - }, - getCanvas: function () { - return this._canvas.getElement(); - }, - _setupContainer: function () { - var container = this._container; - container.classList.add('mapboxgl-map'); - var canvasContainer = this._canvasContainer = DOM.create('div', 'mapboxgl-canvas-container', container); - if (this._interactive) { - canvasContainer.classList.add('mapboxgl-interactive'); - } - this._canvas = new Canvas(this, canvasContainer); - var controlContainer = this._controlContainer = DOM.create('div', 'mapboxgl-control-container', container); - var corners = this._controlCorners = {}; - [ - 'top-left', - 'top-right', - 'bottom-left', - 'bottom-right' - ].forEach(function (pos) { - corners[pos] = DOM.create('div', 'mapboxgl-ctrl-' + pos, controlContainer); - }); - }, - _setupPainter: function () { - var gl = this._canvas.getWebGLContext({ - failIfMajorPerformanceCaveat: this._failIfMajorPerformanceCaveat, - preserveDrawingBuffer: this._preserveDrawingBuffer - }); - if (!gl) { - this.fire('error', { error: new Error('Failed to initialize WebGL') }); - return; - } - this.painter = new Painter(gl, this.transform); - }, - _contextLost: function (event) { - event.preventDefault(); - if (this._frameId) { - browser.cancelFrame(this._frameId); - } - this.fire('webglcontextlost', { originalEvent: event }); - }, - _contextRestored: function (event) { - this._setupPainter(); - this.resize(); - this._update(); - this.fire('webglcontextrestored', { originalEvent: event }); - }, - loaded: function () { - if (this._styleDirty || this._sourcesDirty) - return false; - if (!this.style || !this.style.loaded()) - return false; - return true; - }, - _update: function (updateStyle) { - if (!this.style) - return this; - this._styleDirty = this._styleDirty || updateStyle; - this._sourcesDirty = true; - this._rerender(); - return this; - }, - _render: function () { - try { - if (this.style && this._styleDirty) { - this._styleDirty = false; - this.style.update(this._classes, this._classOptions); - this._classOptions = null; - this.style._recalculate(this.transform.zoom); - } - if (this.style && this._sourcesDirty) { - this._sourcesDirty = false; - this.style._updateSources(this.transform); - } - this.painter.render(this.style, { - debug: this.showTileBoundaries, - showOverdrawInspector: this._showOverdrawInspector, - vertices: this.vertices, - rotating: this.rotating, - zooming: this.zooming - }); - this.fire('render'); - if (this.loaded() && !this._loaded) { - this._loaded = true; - this.fire('load'); - } - this._frameId = null; - if (!this.animationLoop.stopped()) { - this._styleDirty = true; - } - if (this._sourcesDirty || this._repaint || !this.animationLoop.stopped()) { - this._rerender(); - } - } catch (error) { - this.fire('error', { error: error }); - } - return this; - }, - remove: function () { - if (this._hash) - this._hash.remove(); - browser.cancelFrame(this._frameId); - this.setStyle(null); - if (typeof window !== 'undefined') { - window.removeEventListener('resize', this._onWindowResize, false); - } - var extension = this.painter.gl.getExtension('WEBGL_lose_context'); - if (extension) - extension.loseContext(); - removeNode(this._canvasContainer); - removeNode(this._controlContainer); - this._container.classList.remove('mapboxgl-map'); - }, - _rerender: function () { - if (this.style && !this._frameId) { - this._frameId = browser.frame(this._render); - } - }, - _forwardStyleEvent: function (e) { - this.fire('style.' + e.type, util.extend({ style: e.target }, e)); - }, - _forwardSourceEvent: function (e) { - this.fire(e.type, util.extend({ style: e.target }, e)); - }, - _forwardLayerEvent: function (e) { - this.fire(e.type, util.extend({ style: e.target }, e)); - }, - _forwardTileEvent: function (e) { - this.fire(e.type, util.extend({ style: e.target }, e)); - }, - _onStyleLoad: function (e) { - if (this.transform.unmodified) { - this.jumpTo(this.style.stylesheet); - } - this.style.update(this._classes, { transition: false }); - this._forwardStyleEvent(e); - }, - _onStyleChange: function (e) { - this._update(true); - this._forwardStyleEvent(e); - }, - _onSourceAdd: function (e) { - var source = e.source; - if (source.onAdd) - source.onAdd(this); - this._forwardSourceEvent(e); - }, - _onSourceRemove: function (e) { - var source = e.source; - if (source.onRemove) - source.onRemove(this); - this._forwardSourceEvent(e); - }, - _onSourceUpdate: function (e) { - this._update(); - this._forwardSourceEvent(e); - }, - _onWindowOnline: function () { - this._update(); - }, - _onWindowResize: function () { - if (this._trackResize) { - this.stop().resize()._update(); - } - } -}); -util.extendAll(Map.prototype, { - _showTileBoundaries: false, - get showTileBoundaries() { - return this._showTileBoundaries; - }, - set showTileBoundaries(value) { - if (this._showTileBoundaries === value) - return; - this._showTileBoundaries = value; - this._update(); - }, - _showCollisionBoxes: false, - get showCollisionBoxes() { - return this._showCollisionBoxes; - }, - set showCollisionBoxes(value) { - if (this._showCollisionBoxes === value) - return; - this._showCollisionBoxes = value; - this.style._redoPlacement(); - }, - _showOverdrawInspector: false, - get showOverdrawInspector() { - return this._showOverdrawInspector; - }, - set showOverdrawInspector(value) { - if (this._showOverdrawInspector === value) - return; - this._showOverdrawInspector = value; - this._update(); - }, - _repaint: false, - get repaint() { - return this._repaint; - }, - set repaint(value) { - this._repaint = value; - this._update(); - }, - _vertices: false, - get vertices() { - return this._vertices; - }, - set vertices(value) { - this._vertices = value; - this._update(); - } -}); -function removeNode(node) { - if (node.parentNode) { - node.parentNode.removeChild(node); - } -} -},{"../geo/lng_lat":79,"../geo/lng_lat_bounds":80,"../geo/transform":81,"../render/painter":95,"../source/source":106,"../style/animation_loop":115,"../style/style":118,"../util/browser":166,"../util/canvas":167,"../util/dom":168,"../util/evented":174,"../util/util":182,"./bind_handlers":147,"./camera":148,"./control/attribution":149,"./hash":160,"point-geometry":187}],162:[function(require,module,exports){ -'use strict'; -module.exports = Marker; -var DOM = require('../util/dom'); -var LngLat = require('../geo/lng_lat'); -var Point = require('point-geometry'); -function Marker(element, options) { - if (!element) { - element = DOM.create('div'); - } - element.classList.add('mapboxgl-marker'); - this._el = element; - this._offset = Point.convert(options && options.offset || [ - 0, - 0 - ]); - this._update = this._update.bind(this); -} -Marker.prototype = { - addTo: function (map) { - this.remove(); - this._map = map; - map.getCanvasContainer().appendChild(this._el); - map.on('move', this._update); - this._update(); - return this; - }, - remove: function () { - if (this._map) { - this._map.off('move', this._update); - this._map = null; - } - var parent = this._el.parentNode; - if (parent) - parent.removeChild(this._el); - return this; - }, - getLngLat: function () { - return this._lngLat; - }, - setLngLat: function (lnglat) { - this._lngLat = LngLat.convert(lnglat); - this._update(); - return this; - }, - getElement: function () { - return this._el; - }, - _update: function () { - if (!this._map) - return; - var pos = this._map.project(this._lngLat)._add(this._offset); - DOM.setTransform(this._el, 'translate(' + pos.x + 'px,' + pos.y + 'px)'); - } -}; -},{"../geo/lng_lat":79,"../util/dom":168,"point-geometry":187}],163:[function(require,module,exports){ -'use strict'; -module.exports = Popup; -var util = require('../util/util'); -var Evented = require('../util/evented'); -var DOM = require('../util/dom'); -var LngLat = require('../geo/lng_lat'); -function Popup(options) { - util.setOptions(this, options); - util.bindAll([ - '_update', - '_onClickClose' - ], this); -} -Popup.prototype = util.inherit(Evented, { - options: { - closeButton: true, - closeOnClick: true - }, - addTo: function (map) { - this._map = map; - this._map.on('move', this._update); - if (this.options.closeOnClick) { - this._map.on('click', this._onClickClose); - } - this._update(); - return this; - }, - remove: function () { - if (this._content && this._content.parentNode) { - this._content.parentNode.removeChild(this._content); - } - if (this._container) { - this._container.parentNode.removeChild(this._container); - delete this._container; - } - if (this._map) { - this._map.off('move', this._update); - this._map.off('click', this._onClickClose); - delete this._map; - } - this.fire('close'); - return this; - }, - getLngLat: function () { - return this._lngLat; - }, - setLngLat: function (lnglat) { - this._lngLat = LngLat.convert(lnglat); - this._update(); - return this; - }, - setText: function (text) { - return this.setDOMContent(document.createTextNode(text)); - }, - setHTML: function (html) { - var frag = document.createDocumentFragment(); - var temp = document.createElement('body'), child; - temp.innerHTML = html; - while (true) { - child = temp.firstChild; - if (!child) - break; - frag.appendChild(child); - } - return this.setDOMContent(frag); - }, - setDOMContent: function (htmlNode) { - this._createContent(); - this._content.appendChild(htmlNode); - this._update(); - return this; - }, - _createContent: function () { - if (this._content && this._content.parentNode) { - this._content.parentNode.removeChild(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.innerHTML = '×'; - this._closeButton.addEventListener('click', this._onClickClose); - } - }, - _update: function () { - if (!this._map || !this._lngLat || !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); - } - var pos = this._map.project(this._lngLat).round(), anchor = this.options.anchor; - if (!anchor) { - var width = this._container.offsetWidth, height = this._container.offsetHeight; - if (pos.y < height) { - anchor = ['top']; - } else if (pos.y > this._map.transform.height - height) { - anchor = ['bottom']; - } else { - anchor = []; - } - if (pos.x < width / 2) { - anchor.push('left'); - } else if (pos.x > this._map.transform.width - width / 2) { - anchor.push('right'); - } - if (anchor.length === 0) { - anchor = 'bottom'; - } else { - anchor = anchor.join('-'); - } - } - var anchorTranslate = { - '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%)' - }; - var classList = this._container.classList; - for (var key in anchorTranslate) { - classList.remove('mapboxgl-popup-anchor-' + key); - } - classList.add('mapboxgl-popup-anchor-' + anchor); - DOM.setTransform(this._container, anchorTranslate[anchor] + ' translate(' + pos.x + 'px,' + pos.y + 'px)'); - }, - _onClickClose: function () { - this.remove(); - } -}); -},{"../geo/lng_lat":79,"../util/dom":168,"../util/evented":174,"../util/util":182}],164:[function(require,module,exports){ -'use strict'; -module.exports = Actor; -function Actor(target, parent) { - this.target = target; - this.parent = parent; - this.callbacks = {}; - this.callbackID = 0; - this.receive = this.receive.bind(this); - this.target.addEventListener('message', this.receive, false); -} -Actor.prototype.receive = function (message) { - var data = message.data, id = data.id, callback; - if (data.type === '') { - callback = this.callbacks[data.id]; - delete this.callbacks[data.id]; - if (callback) - callback(data.error || null, data.data); - } else if (typeof data.id !== 'undefined' && this.parent[data.type]) { - this.parent[data.type](data.data, done.bind(this)); - } else if (typeof data.id !== 'undefined' && this.parent.workerSources) { - var keys = data.type.split('.'); - this.parent.workerSources[keys[0]][keys[1]](data.data, done.bind(this)); - } else { - this.parent[data.type](data.data); - } - function done(err, data, buffers) { - this.postMessage({ - type: '', - id: String(id), - error: err ? String(err) : null, - data: data - }, buffers); - } -}; -Actor.prototype.send = function (type, data, callback, buffers) { - var id = null; - if (callback) - this.callbacks[id = this.callbackID++] = callback; - this.postMessage({ - type: type, - id: String(id), - data: data - }, buffers); -}; -Actor.prototype.postMessage = function (message, transferList) { - this.target.postMessage(message, transferList); -}; -},{}],165:[function(require,module,exports){ -'use strict'; -exports.getJSON = function (url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.setRequestHeader('Accept', 'application/json'); - xhr.onerror = function (e) { - callback(e); - }; - xhr.onload = function () { - if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { - var data; - try { - data = JSON.parse(xhr.response); - } catch (err) { - return callback(err); - } - callback(null, data); - } else { - callback(new Error(xhr.statusText)); - } - }; - xhr.send(); - return xhr; -}; -exports.getArrayBuffer = function (url, callback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onerror = function (e) { - callback(e); - }; - xhr.onload = function () { - if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { - callback(null, xhr.response); - } else { - callback(new Error(xhr.statusText)); - } - }; - xhr.send(); - return xhr; -}; -function sameOrigin(url) { - var a = document.createElement('a'); - a.href = url; - return a.protocol === document.location.protocol && a.host === document.location.host; -} -exports.getImage = function (url, callback) { - return exports.getArrayBuffer(url, function (err, imgData) { - if (err) - return callback(err); - var img = new Image(); - img.onload = function () { - callback(null, img); - (window.URL || window.webkitURL).revokeObjectURL(img.src); - }; - var blob = new Blob([new Uint8Array(imgData)], { type: 'image/png' }); - img.src = (window.URL || window.webkitURL).createObjectURL(blob); - img.getData = function () { - var canvas = document.createElement('canvas'); - var context = canvas.getContext('2d'); - canvas.width = img.width; - canvas.height = img.height; - context.drawImage(img, 0, 0); - return context.getImageData(0, 0, img.width, img.height).data; - }; - return img; - }); -}; -exports.getVideo = function (urls, callback) { - var video = document.createElement('video'); - video.onloadstart = function () { - callback(null, video); - }; - for (var i = 0; i < urls.length; i++) { - var s = document.createElement('source'); - if (!sameOrigin(urls[i])) { - video.crossOrigin = 'Anonymous'; - } - s.src = urls[i]; - video.appendChild(s); - } - video.getData = function () { - return video; - }; - return video; -}; -},{}],166:[function(require,module,exports){ -'use strict'; -exports.window = window; -module.exports.now = function () { - if (window.performance && window.performance.now) { - return window.performance.now.bind(window.performance); - } else { - return Date.now.bind(Date); - } -}(); -var frame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; -exports.frame = function (fn) { - return frame(fn); -}; -var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame; -exports.cancelFrame = function (id) { - cancel(id); -}; -exports.timed = function (fn, dur, ctx) { - if (!dur) { - fn.call(ctx, 1); - return null; - } - var abort = false, start = module.exports.now(); - function tick(now) { - if (abort) - return; - now = module.exports.now(); - if (now >= start + dur) { - fn.call(ctx, 1); - } else { - fn.call(ctx, (now - start) / dur); - exports.frame(tick); - } - } - exports.frame(tick); - return function () { - abort = true; - }; -}; -exports.supported = require('mapbox-gl-supported'); -exports.hardwareConcurrency = navigator.hardwareConcurrency || 4; -Object.defineProperty(exports, 'devicePixelRatio', { - get: function () { - return window.devicePixelRatio; - } -}); -exports.supportsWebp = false; -var webpImgTest = document.createElement('img'); -webpImgTest.onload = function () { - exports.supportsWebp = true; -}; -webpImgTest.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA='; -exports.supportsGeolocation = !!navigator.geolocation; -},{"mapbox-gl-supported":67}],167:[function(require,module,exports){ -'use strict'; -var util = require('../util'); -var isSupported = require('mapbox-gl-supported'); -module.exports = Canvas; -function Canvas(parent, container) { - this.canvas = document.createElement('canvas'); - if (parent && container) { - this.canvas.style.position = 'absolute'; - this.canvas.classList.add('mapboxgl-canvas'); - this.canvas.addEventListener('webglcontextlost', parent._contextLost.bind(parent), false); - this.canvas.addEventListener('webglcontextrestored', parent._contextRestored.bind(parent), false); - this.canvas.setAttribute('tabindex', 0); - container.appendChild(this.canvas); - } -} -Canvas.prototype.resize = function (width, height) { - var pixelRatio = 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'; -}; -Canvas.prototype.getWebGLContext = function (attributes) { - attributes = util.extend({}, attributes, isSupported.webGLContextAttributes); - return this.canvas.getContext('webgl', attributes) || this.canvas.getContext('experimental-webgl', attributes); -}; -Canvas.prototype.getElement = function () { - return this.canvas; -}; -},{"../util":182,"mapbox-gl-supported":67}],168:[function(require,module,exports){ -'use strict'; -var Point = require('point-geometry'); -exports.create = function (tagName, className, container) { - var el = document.createElement(tagName); - if (className) - el.className = className; - if (container) - container.appendChild(el); - return el; -}; -var docStyle = document.documentElement.style; -function testProp(props) { - for (var i = 0; i < props.length; i++) { - if (props[i] in docStyle) { - return props[i]; - } - } -} -var selectProp = testProp([ - 'userSelect', - 'MozUserSelect', - 'WebkitUserSelect', - 'msUserSelect' - ]), userSelect; -exports.disableDrag = function () { - if (selectProp) { - userSelect = docStyle[selectProp]; - docStyle[selectProp] = 'none'; - } -}; -exports.enableDrag = function () { - if (selectProp) { - docStyle[selectProp] = userSelect; - } -}; -var transformProp = testProp([ - 'transform', - 'WebkitTransform' -]); -exports.setTransform = function (el, value) { - el.style[transformProp] = value; -}; -function suppressClick(e) { - e.preventDefault(); - e.stopPropagation(); - window.removeEventListener('click', suppressClick, true); -} -exports.suppressClick = function () { - window.addEventListener('click', suppressClick, true); - window.setTimeout(function () { - window.removeEventListener('click', suppressClick, true); - }, 0); -}; -exports.mousePos = function (el, e) { - var rect = el.getBoundingClientRect(); - e = e.touches ? e.touches[0] : e; - return new Point(e.clientX - rect.left - el.clientLeft, e.clientY - rect.top - el.clientTop); -}; -exports.touchPos = function (el, e) { - var rect = el.getBoundingClientRect(), points = []; - for (var i = 0; i < e.touches.length; i++) { - points.push(new Point(e.touches[i].clientX - rect.left - el.clientLeft, e.touches[i].clientY - rect.top - el.clientTop)); - } - return points; -}; -},{"point-geometry":187}],169:[function(require,module,exports){ -'use strict'; -var WebWorkify = require('webworkify'); -module.exports = function () { - return new WebWorkify(require('../../source/worker')); -}; -},{"../../source/worker":113,"webworkify":200}],170:[function(require,module,exports){ -'use strict'; -var quickselect = require('quickselect'); -module.exports = function classifyRings(rings, maxRings) { - var len = rings.length; - if (len <= 1) - return [rings]; - var polygons = [], 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 calculateSignedArea(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; -} -},{"quickselect":188}],171:[function(require,module,exports){ -'use strict'; -module.exports = { - API_URL: 'https://api.mapbox.com', - REQUIRE_ACCESS_TOKEN: true -}; -},{}],172:[function(require,module,exports){ -'use strict'; -module.exports = 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 (string) { - return this._stringToNumber[string]; -}; -DictionaryCoder.prototype.decode = function (n) { - return this._numberToString[n]; -}; -},{}],173:[function(require,module,exports){ -'use strict'; -var util = require('./util'); -var Actor = require('./actor'); -var WebWorker = require('./web_worker'); -module.exports = Dispatcher; -function Dispatcher(length, parent) { - this.actors = []; - this.currentActor = 0; - for (var i = 0; i < length; i++) { - var worker = new WebWorker(); - var actor = new Actor(worker, parent); - actor.name = 'Worker ' + i; - this.actors.push(actor); - } -} -Dispatcher.prototype = { - broadcast: function (type, data, cb) { - cb = cb || function () { - }; - util.asyncAll(this.actors, function (actor, done) { - actor.send(type, data, done); - }, cb); - }, - send: function (type, data, callback, targetID, buffers) { - if (typeof targetID !== 'number' || isNaN(targetID)) { - targetID = this.currentActor = (this.currentActor + 1) % this.actors.length; - } - this.actors[targetID].send(type, data, callback, buffers); - return targetID; - }, - remove: function () { - for (var i = 0; i < this.actors.length; i++) { - this.actors[i].target.terminate(); - } - this.actors = []; - } -}; -},{"./actor":164,"./util":182,"./web_worker":169}],174:[function(require,module,exports){ -'use strict'; -var util = require('./util'); -var Evented = { - on: function (type, listener) { - this._events = this._events || {}; - this._events[type] = this._events[type] || []; - this._events[type].push(listener); - return this; - }, - off: function (type, listener) { - if (!type) { - delete this._events; - return this; - } - if (!this.listens(type)) - return this; - if (listener) { - var idx = this._events[type].indexOf(listener); - if (idx >= 0) { - this._events[type].splice(idx, 1); - } - if (!this._events[type].length) { - delete this._events[type]; - } - } else { - delete this._events[type]; - } - return this; - }, - once: function (type, listener) { - var wrapper = function (data) { - this.off(type, wrapper); - listener.call(this, data); - }.bind(this); - this.on(type, wrapper); - return this; - }, - fire: function (type, data) { - if (!this.listens(type)) { - if (util.endsWith(type, 'error')) { - console.error(data && data.error || data || 'Empty error event'); - } - return this; - } - data = util.extend({}, data); - util.extend(data, { - type: type, - target: this - }); - var listeners = this._events[type].slice(); - for (var i = 0; i < listeners.length; i++) { - listeners[i].call(this, data); - } - return this; - }, - listens: function (type) { - return !!(this._events && this._events[type]); - } -}; -module.exports = Evented; -},{"./util":182}],175:[function(require,module,exports){ -'use strict'; -module.exports = Glyphs; -function Glyphs(pbf, end) { - this.stacks = pbf.readFields(readFontstacks, [], end); -} -function readFontstacks(tag, stacks, pbf) { - if (tag === 1) { - var fontstack = pbf.readMessage(readFontstack, { glyphs: {} }); - stacks.push(fontstack); - } -} -function readFontstack(tag, fontstack, pbf) { - if (tag === 1) - fontstack.name = pbf.readString(); - else if (tag === 2) - fontstack.range = pbf.readString(); - else if (tag === 3) { - var glyph = pbf.readMessage(readGlyph, {}); - fontstack.glyphs[glyph.id] = glyph; - } -} -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(); -} -},{}],176:[function(require,module,exports){ -'use strict'; -module.exports = interpolate; -function interpolate(a, b, t) { - return a * (1 - t) + b * t; -} -interpolate.number = interpolate; -interpolate.vec2 = function (from, to, t) { - return [ - interpolate(from[0], to[0], t), - interpolate(from[1], to[1], t) - ]; -}; -interpolate.color = function (from, to, t) { - return [ - interpolate(from[0], to[0], t), - interpolate(from[1], to[1], t), - interpolate(from[2], to[2], t), - interpolate(from[3], to[3], t) - ]; -}; -interpolate.array = function (from, to, t) { - return from.map(function (d, i) { - return interpolate(d, to[i], t); - }); -}; -},{}],177:[function(require,module,exports){ -'use strict'; -module.exports = { - multiPolygonIntersectsBufferedMultiPoint: multiPolygonIntersectsBufferedMultiPoint, - multiPolygonIntersectsMultiPolygon: multiPolygonIntersectsMultiPolygon, - multiPolygonIntersectsBufferedMultiLine: multiPolygonIntersectsBufferedMultiLine -}; -function multiPolygonIntersectsBufferedMultiPoint(multiPolygon, rings, radius) { - for (var j = 0; j < multiPolygon.length; j++) { - var polygon = multiPolygon[j]; - for (var i = 0; i < rings.length; i++) { - var ring = rings[i]; - for (var k = 0; k < ring.length; k++) { - var point = ring[k]; - if (polygonContainsPoint(polygon, point)) - return true; - if (pointIntersectsBufferedLine(point, polygon, radius)) - return true; - } - } - } - return false; -} -function multiPolygonIntersectsMultiPolygon(multiPolygonA, multiPolygonB) { - if (multiPolygonA.length === 1 && multiPolygonA[0].length === 1) { - return multiPolygonContainsPoint(multiPolygonB, multiPolygonA[0][0]); - } - for (var m = 0; m < multiPolygonB.length; m++) { - var ring = multiPolygonB[m]; - for (var n = 0; n < ring.length; n++) { - if (multiPolygonContainsPoint(multiPolygonA, ring[n])) - return true; - } - } - for (var j = 0; j < multiPolygonA.length; j++) { - var polygon = multiPolygonA[j]; - for (var i = 0; i < polygon.length; i++) { - if (multiPolygonContainsPoint(multiPolygonB, polygon[i])) - return true; - } - for (var k = 0; k < multiPolygonB.length; k++) { - if (lineIntersectsLine(polygon, multiPolygonB[k])) - return true; - } - } - return false; -} -function multiPolygonIntersectsBufferedMultiLine(multiPolygon, multiLine, radius) { - for (var i = 0; i < multiLine.length; i++) { - var line = multiLine[i]; - for (var j = 0; j < multiPolygon.length; j++) { - var polygon = multiPolygon[j]; - 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) { - 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 isCounterClockwise(a, b, c) { - return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x); -} -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; -} -},{}],178:[function(require,module,exports){ -'use strict'; -module.exports = LRUCache; -function LRUCache(max, onRemove) { - this.max = max; - this.onRemove = onRemove; - this.reset(); -} -LRUCache.prototype.reset = function () { - for (var key in this.data) { - this.onRemove(this.data[key]); - } - this.data = {}; - this.order = []; - return this; -}; -LRUCache.prototype.add = function (key, data) { - if (this.has(key)) { - this.order.splice(this.order.indexOf(key), 1); - this.data[key] = data; - this.order.push(key); - } else { - this.data[key] = data; - this.order.push(key); - if (this.order.length > this.max) { - var removedData = this.get(this.order[0]); - if (removedData) - this.onRemove(removedData); - } - } - return this; -}; -LRUCache.prototype.has = function (key) { - return key in this.data; -}; -LRUCache.prototype.keys = function () { - return this.order; -}; -LRUCache.prototype.get = function (key) { - if (!this.has(key)) { - return null; - } - var data = this.data[key]; - delete this.data[key]; - this.order.splice(this.order.indexOf(key), 1); - return data; -}; -LRUCache.prototype.setMaxSize = function (max) { - this.max = max; - while (this.order.length > this.max) { - var removedData = this.get(this.order[0]); - if (removedData) - this.onRemove(removedData); - } - return this; -}; -},{}],179:[function(require,module,exports){ -'use strict'; -var config = require('./config'); -var browser = require('./browser'); -var URL = require('url'); -var util = require('./util'); -function normalizeURL(url, pathPrefix, accessToken) { - accessToken = accessToken || config.ACCESS_TOKEN; - if (!accessToken && config.REQUIRE_ACCESS_TOKEN) { - throw new Error('An API access token is required to use Mapbox GL. ' + 'See https://www.mapbox.com/developers/api/#access-tokens'); - } - url = url.replace(/^mapbox:\/\//, config.API_URL + pathPrefix); - url += url.indexOf('?') !== -1 ? '&access_token=' : '?access_token='; - if (config.REQUIRE_ACCESS_TOKEN) { - if (accessToken[0] === 's') { - throw new Error('Use a public access token (pk.*) with Mapbox GL JS, not a secret access token (sk.*). ' + 'See https://www.mapbox.com/developers/api/#access-tokens'); - } - url += accessToken; - } - return url; -} -module.exports.normalizeStyleURL = function (url, accessToken) { - var urlObject = URL.parse(url); - if (urlObject.protocol !== 'mapbox:') { - return url; - } else { - return normalizeURL('mapbox:/' + urlObject.pathname + formatQuery(urlObject.query), '/styles/v1/', accessToken); - } -}; -module.exports.normalizeSourceURL = function (url, accessToken) { - var urlObject = URL.parse(url); - if (urlObject.protocol !== 'mapbox:') { - return url; - } else { - return normalizeURL(url + '.json', '/v4/', accessToken) + '&secure'; - } -}; -module.exports.normalizeGlyphsURL = function (url, accessToken) { - var urlObject = URL.parse(url); - if (urlObject.protocol !== 'mapbox:') { - return url; - } else { - var user = urlObject.pathname.split('/')[1]; - return normalizeURL('mapbox://' + user + '/{fontstack}/{range}.pbf' + formatQuery(urlObject.query), '/fonts/v1/', accessToken); - } -}; -module.exports.normalizeSpriteURL = function (url, format, extension, accessToken) { - var urlObject = URL.parse(url); - if (urlObject.protocol !== 'mapbox:') { - urlObject.pathname += format + extension; - return URL.format(urlObject); - } else { - return normalizeURL('mapbox:/' + urlObject.pathname + '/sprite' + format + extension + formatQuery(urlObject.query), '/styles/v1/', accessToken); - } -}; -module.exports.normalizeTileURL = function (tileURL, sourceURL, tileSize) { - var tileURLObject = URL.parse(tileURL, true); - if (!sourceURL) - return tileURL; - var sourceURLObject = URL.parse(sourceURL); - if (sourceURLObject.protocol !== 'mapbox:') - return tileURL; - var extension = browser.supportsWebp ? '.webp' : '$1'; - var resolution = browser.devicePixelRatio >= 2 || tileSize === 512 ? '@2x' : ''; - return URL.format({ - protocol: tileURLObject.protocol, - hostname: tileURLObject.hostname, - pathname: tileURLObject.pathname.replace(/(\.(?:png|jpg)\d*)/, resolution + extension), - query: replaceTempAccessToken(tileURLObject.query) - }); -}; -function formatQuery(query) { - return query ? '?' + query : ''; -} -function replaceTempAccessToken(query) { - if (query.access_token && query.access_token.slice(0, 3) === 'tk.') { - return util.extend({}, query, { 'access_token': config.ACCESS_TOKEN }); - } else { - return query; - } -} -},{"./browser":166,"./config":171,"./util":182,"url":8}],180:[function(require,module,exports){ -'use strict'; -module.exports = StructArrayType; -var viewTypes = { - 'Int8': Int8Array, - 'Uint8': Uint8Array, - 'Uint8Clamped': Uint8ClampedArray, - 'Int16': Int16Array, - 'Uint16': Uint16Array, - 'Int32': Int32Array, - 'Uint32': Uint32Array, - 'Float32': Float32Array, - 'Float64': Float64Array -}; -var structArrayTypeCache = {}; -function StructArrayType(options) { - var key = JSON.stringify(options); - if (structArrayTypeCache[key]) { - return structArrayTypeCache[key]; - } - if (options.alignment === undefined) - options.alignment = 1; - function StructType() { - Struct.apply(this, arguments); - } - StructType.prototype = Object.create(Struct.prototype); - var offset = 0; - var maxSize = 0; - var usedTypes = ['Uint8']; - StructType.prototype.members = options.members.map(function (member) { - member = { - name: member.name, - type: member.type, - components: member.components || 1 - }; - if (usedTypes.indexOf(member.type) < 0) - usedTypes.push(member.type); - var typeSize = sizeOf(member.type); - maxSize = Math.max(maxSize, typeSize); - member.offset = offset = align(offset, Math.max(options.alignment, typeSize)); - for (var c = 0; c < member.components; c++) { - Object.defineProperty(StructType.prototype, member.name + (member.components === 1 ? '' : c), { - get: createGetter(member, c), - set: createSetter(member, c) - }); - } - offset += typeSize * member.components; - return member; - }); - StructType.prototype.alignment = options.alignment; - StructType.prototype.size = align(offset, Math.max(maxSize, options.alignment)); - function StructArrayType() { - StructArray.apply(this, arguments); - this.members = StructType.prototype.members; - } - StructArrayType.serialize = serializeStructArrayType; - StructArrayType.prototype = Object.create(StructArray.prototype); - StructArrayType.prototype.StructType = StructType; - StructArrayType.prototype.bytesPerElement = StructType.prototype.size; - StructArrayType.prototype.emplaceBack = createEmplaceBack(StructType.prototype.members, StructType.prototype.size); - StructArrayType.prototype._usedTypes = usedTypes; - structArrayTypeCache[key] = StructArrayType; - return StructArrayType; -} -function serializeStructArrayType() { - return { - members: this.prototype.StructType.prototype.members, - alignment: this.prototype.StructType.prototype.alignment, - bytesPerElement: this.prototype.bytesPerElement - }; -} -function align(offset, size) { - return Math.ceil(offset / size) * size; -} -function sizeOf(type) { - return viewTypes[type].BYTES_PER_ELEMENT; -} -function getArrayViewName(type) { - return type.toLowerCase(); -} -function createEmplaceBack(members, bytesPerElement) { - var usedTypeSizes = []; - var argNames = []; - var body = '' + 'var i = this.length;\n' + 'this.resize(this.length + 1);\n'; - for (var m = 0; m < members.length; m++) { - var member = members[m]; - var size = sizeOf(member.type); - if (usedTypeSizes.indexOf(size) < 0) { - usedTypeSizes.push(size); - body += 'var o' + size.toFixed(0) + ' = i * ' + (bytesPerElement / size).toFixed(0) + ';\n'; - } - for (var c = 0; c < member.components; c++) { - var argName = 'v' + argNames.length; - var index = 'o' + size.toFixed(0) + ' + ' + (member.offset / size + c).toFixed(0); - body += 'this.' + getArrayViewName(member.type) + '[' + index + '] = ' + argName + ';\n'; - argNames.push(argName); - } - } - body += 'return i;'; - return new Function(argNames, body); -} -function createMemberComponentString(member, component) { - var elementOffset = 'this._pos' + sizeOf(member.type).toFixed(0); - var componentOffset = (member.offset / sizeOf(member.type) + component).toFixed(0); - var index = elementOffset + ' + ' + componentOffset; - return 'this._structArray.' + getArrayViewName(member.type) + '[' + index + ']'; -} -function createGetter(member, c) { - return new Function([], 'return ' + createMemberComponentString(member, c) + ';'); -} -function createSetter(member, c) { - return new Function(['x'], createMemberComponentString(member, c) + ' = x;'); -} -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; -} -function StructArray(serialized) { - if (serialized !== undefined) { - this.arrayBuffer = serialized.arrayBuffer; - this.length = serialized.length; - this.capacity = this.arrayBuffer.byteLength / this.bytesPerElement; - this._refreshViews(); - } else { - this.capacity = -1; - this.resize(0); - } -} -StructArray.prototype.DEFAULT_CAPACITY = 128; -StructArray.prototype.RESIZE_MULTIPLIER = 5; -StructArray.prototype.serialize = function () { - this.trim(); - return { - length: this.length, - arrayBuffer: this.arrayBuffer - }; -}; -StructArray.prototype.get = function (index) { - return new this.StructType(this, index); -}; -StructArray.prototype.trim = function () { - if (this.length !== this.capacity) { - this.capacity = this.length; - this.arrayBuffer = this.arrayBuffer.slice(0, this.length * this.bytesPerElement); - this._refreshViews(); - } -}; -StructArray.prototype.resize = function (n) { - this.length = n; - if (n > this.capacity) { - this.capacity = Math.max(n, Math.floor(this.capacity * this.RESIZE_MULTIPLIER), this.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 () { - for (var t = 0; t < this._usedTypes.length; t++) { - var type = this._usedTypes[t]; - this[getArrayViewName(type)] = new viewTypes[type](this.arrayBuffer); - } -}; -StructArray.prototype.toArray = function (startIndex, endIndex) { - var array = []; - for (var i = startIndex; i < endIndex; i++) { - var struct = this.get(i); - array.push(struct); - } - return array; -}; -},{}],181:[function(require,module,exports){ -'use strict'; -module.exports = resolveTokens; -function resolveTokens(properties, text) { - return text.replace(/{([^{}]+)}/g, function (match, key) { - return key in properties ? properties[key] : ''; - }); -} -},{}],182:[function(require,module,exports){ -'use strict'; -var UnitBezier = require('unitbezier'); -var Coordinate = require('../geo/coordinate'); -exports.easeCubicInOut = function (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); -}; -exports.bezier = function (p1x, p1y, p2x, p2y) { - var bezier = new UnitBezier(p1x, p1y, p2x, p2y); - return function (t) { - return bezier.solve(t); - }; -}; -exports.ease = exports.bezier(0.25, 0.1, 0.25, 1); -exports.clamp = function (n, min, max) { - return Math.min(max, Math.max(min, n)); -}; -exports.wrap = function (n, min, max) { - var d = max - min; - var w = ((n - min) % d + d) % d + min; - return w === min ? max : w; -}; -exports.coalesce = function () { - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - if (arg !== null && arg !== undefined) - return arg; - } -}; -exports.asyncAll = function (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); - }); - }); -}; -exports.keysDifference = function (obj, other) { - var difference = []; - for (var i in obj) { - if (!(i in other)) { - difference.push(i); - } - } - return difference; -}; -exports.extend = function (dest) { - for (var i = 1; i < arguments.length; i++) { - var src = arguments[i]; - for (var k in src) { - dest[k] = src[k]; - } - } - return dest; -}; -exports.extendAll = function (dest, src) { - for (var i in src) { - Object.defineProperty(dest, i, Object.getOwnPropertyDescriptor(src, i)); - } - return dest; -}; -exports.inherit = function (parent, props) { - var parentProto = typeof parent === 'function' ? parent.prototype : parent, proto = Object.create(parentProto); - exports.extendAll(proto, props); - return proto; -}; -exports.pick = function (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; -exports.uniqueId = function () { - return id++; -}; -exports.debounce = function (fn, time) { - var timer, args; - return function () { - args = arguments; - clearTimeout(timer); - timer = setTimeout(function () { - fn.apply(null, args); - }, time); - }; -}; -exports.bindAll = function (fns, context) { - fns.forEach(function (fn) { - if (!context[fn]) { - return; - } - context[fn] = context[fn].bind(context); - }); -}; -exports.bindHandlers = function (context) { - for (var i in context) { - if (typeof context[i] === 'function' && i.indexOf('_on') === 0) { - context[i] = context[i].bind(context); - } - } -}; -exports.setOptions = function (obj, options) { - if (!obj.hasOwnProperty('options')) { - obj.options = obj.options ? Object.create(obj.options) : {}; - } - for (var i in options) { - obj.options[i] = options[i]; - } - return obj.options; -}; -exports.getCoordinatesCenter = function (coords) { - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - for (var i = 0; i < coords.length; i++) { - minX = Math.min(minX, coords[i].column); - minY = Math.min(minY, coords[i].row); - maxX = Math.max(maxX, coords[i].column); - maxY = Math.max(maxY, coords[i].row); - } - var dx = maxX - minX; - var dy = maxY - minY; - var dMax = Math.max(dx, dy); - return new Coordinate((minX + maxX) / 2, (minY + maxY) / 2, 0).zoomTo(Math.floor(-Math.log(dMax) / Math.LN2)); -}; -exports.endsWith = function (string, suffix) { - return string.indexOf(suffix, string.length - suffix.length) !== -1; -}; -exports.startsWith = function (string, prefix) { - return string.indexOf(prefix) === 0; -}; -exports.mapObject = function (input, iterator, context) { - var output = {}; - for (var key in input) { - output[key] = iterator.call(context || this, input[key], key, input); - } - return output; -}; -exports.filterObject = function (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; -}; -exports.deepEqual = 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; -}; -exports.clone = function deepEqual(input) { - if (Array.isArray(input)) { - return input.map(exports.clone); - } else if (typeof input === 'object') { - return exports.mapObject(input, exports.clone); - } else { - return input; - } -}; -exports.arraysIntersect = function (a, b) { - for (var l = 0; l < a.length; l++) { - if (b.indexOf(a[l]) >= 0) - return true; - } - return false; -}; -var warnOnceHistory = {}; -exports.warnOnce = function (message) { - if (!warnOnceHistory[message]) { - if (typeof console !== 'undefined') - console.warn(message); - warnOnceHistory[message] = true; - } -}; -},{"../geo/coordinate":78,"unitbezier":192}],183:[function(require,module,exports){ -'use strict'; -module.exports = Feature; -function Feature(vectorTileFeature, z, x, y) { - this._vectorTileFeature = vectorTileFeature; - vectorTileFeature._z = z; - vectorTileFeature._x = x; - vectorTileFeature._y = y; - this.properties = vectorTileFeature.properties; - if (vectorTileFeature.id != null) { - this.id = vectorTileFeature.id; - } -} -Feature.prototype = { - type: 'Feature', - get geometry() { - if (this._geometry === undefined) { - this._geometry = this._vectorTileFeature.toGeoJSON(this._vectorTileFeature._x, this._vectorTileFeature._y, this._vectorTileFeature._z).geometry; - } - return this._geometry; - }, - set geometry(g) { - this._geometry = g; - }, - toJSON: function () { - var json = {}; - for (var i in this) { - if (i === '_geometry' || i === '_vectorTileFeature' || i === 'toJSON') - continue; - json[i] = this[i]; - } - return json; - } -}; -},{}],184:[function(require,module,exports){ -module.exports={ - "_args": [ - [ - { - "hosted": { - "directUrl": "https://raw.githubusercontent.com/mapbox/mapbox-gl-js/fix-add-source-type/package.json", - "gitUrl": "git://github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "httpsUrl": "git+https://github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "shortcut": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "ssh": "git@github.com:mapbox/mapbox-gl-js.git#fix-add-source-type", - "sshUrl": "git+ssh://git@github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "type": "github" - }, - "name": "mapbox-gl", - "raw": "mapbox-gl@github:mapbox/mapbox-gl-js#fix-add-source-type", - "rawSpec": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "scope": null, - "spec": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "type": "hosted" - }, - "/Users/anand/c/developmentseed/mapbox-gl-topojson" - ] - ], - "_from": "mapbox/mapbox-gl-js#fix-add-source-type", - "_id": "mapbox-gl@0.22.0", - "_inCache": true, - "_installable": true, - "_location": "/mapbox-gl", - "_phantomChildren": {}, - "_requested": { - "hosted": { - "directUrl": "https://raw.githubusercontent.com/mapbox/mapbox-gl-js/fix-add-source-type/package.json", - "gitUrl": "git://github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "httpsUrl": "git+https://github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "shortcut": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "ssh": "git@github.com:mapbox/mapbox-gl-js.git#fix-add-source-type", - "sshUrl": "git+ssh://git@github.com/mapbox/mapbox-gl-js.git#fix-add-source-type", - "type": "github" - }, - "name": "mapbox-gl", - "raw": "mapbox-gl@github:mapbox/mapbox-gl-js#fix-add-source-type", - "rawSpec": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "scope": null, - "spec": "github:mapbox/mapbox-gl-js#fix-add-source-type", - "type": "hosted" - }, - "_requiredBy": [ - "#DEV:/" - ], - "_resolved": "git://github.com/mapbox/mapbox-gl-js.git#5dae4c7390d5752958e132d1189f339443dde465", - "_shasum": "11315d2a52d0c77f454d6d5020b31bdf1f13dd38", - "_shrinkwrap": null, - "_spec": "mapbox-gl@github:mapbox/mapbox-gl-js#fix-add-source-type", - "_where": "/Users/anand/c/developmentseed/mapbox-gl-topojson", - "browser": { - "./js/util/ajax.js": "./js/util/browser/ajax.js", - "./js/util/browser.js": "./js/util/browser/browser.js", - "./js/util/canvas.js": "./js/util/browser/canvas.js", - "./js/util/dom.js": "./js/util/browser/dom.js", - "./js/util/web_worker.js": "./js/util/browser/web_worker.js" - }, - "browserify": { - "transform": [ - "unassertify" - ] - }, - "bugs": { - "url": "https://github.com/mapbox/mapbox-gl-js/issues" - }, - "dependencies": { - "csscolorparser": "^1.0.2", - "earcut": "^2.0.3", - "feature-filter": "^2.2.0", - "geojson-rewind": "^0.1.0", - "geojson-vt": "^2.4.0", - "gl-matrix": "^2.3.1", - "grid-index": "^1.0.0", - "mapbox-gl-function": "^1.2.1", - "mapbox-gl-shaders": "github:mapbox/mapbox-gl-shaders#de2ab007455aa2587c552694c68583f94c9f2747", - "mapbox-gl-style-spec": "github:mapbox/mapbox-gl-style-spec#83b1a3e5837d785af582efd5ed1a212f2df6a4ae", - "mapbox-gl-supported": "^1.2.0", - "pbf": "^1.3.2", - "pngjs": "^2.2.0", - "point-geometry": "^0.0.0", - "quickselect": "^1.0.0", - "request": "^2.39.0", - "resolve-url": "^0.2.1", - "shelf-pack": "^1.0.0", - "supercluster": "^2.0.1", - "unassertify": "^2.0.0", - "unitbezier": "^0.0.0", - "vector-tile": "^1.3.0", - "vt-pbf": "^2.0.2", - "webworkify": "^1.3.0", - "whoots-js": "^2.0.0" - }, - "description": "A WebGL interactive maps library", - "devDependencies": { - "async": "^2.0.1", - "babel-preset-react": "^6.11.1", - "babelify": "^7.3.0", - "benchmark": "~2.1.0", - "browserify": "^13.0.0", - "browserify-middleware": "^7.0.0", - "clipboard": "^1.5.12", - "concat-stream": "1.5.1", - "coveralls": "^2.11.8", - "doctrine": "^1.2.1", - "documentation": "https://github.com/documentationjs/documentation/archive/bb41619c734e59ef3fbc3648610032efcfdaaace.tar.gz", - "documentation-theme-utils": "3.0.0", - "envify": "^3.4.0", - "eslint": "^2.5.3", - "eslint-config-mourner": "^2.0.0", - "eslint-plugin-html": "^1.5.1", - "express": "^4.13.4", - "gl": "^4.0.1", - "handlebars": "4.0.5", - "highlight.js": "9.3.0", - "istanbul": "^0.4.2", - "json-loader": "^0.5.4", - "lodash": "^4.13.1", - "mapbox-gl-test-suite": "github:mapbox/mapbox-gl-test-suite#1619d84e76ff3434becd51237720d370c7405ee5", - "memory-fs": "^0.3.0", - "minifyify": "^7.0.1", - "nyc": "6.4.0", - "proxyquire": "^1.7.9", - "react": "^15.3.0", - "react-dom": "^15.3.0", - "remark": "4.2.2", - "remark-html": "3.0.0", - "sinon": "^1.15.4", - "st": "^1.0.0", - "tap": "^5.7.0", - "through": "^2.3.7", - "transform-loader": "^0.2.3", - "unist-util-visit": "1.1.0", - "vinyl": "1.1.1", - "vinyl-fs": "2.4.3", - "watchify": "^3.2.2", - "webpack": "^1.13.1", - "webworkify-webpack": "^1.1.3" - }, - "engines": { - "node": ">=4.0.0" - }, - "gitHead": "5dae4c7390d5752958e132d1189f339443dde465", - "homepage": "https://github.com/mapbox/mapbox-gl-js#readme", - "license": "BSD-3-Clause", - "main": "js/mapbox-gl.js", - "name": "mapbox-gl", - "optionalDependencies": {}, - "readme": "[![Build Status](https://circleci.com/gh/mapbox/mapbox-gl-js.svg?style=svg)](https://circleci.com/gh/mapbox/mapbox-gl-js) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-js/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-js?branch=master)\n\n# Mapbox GL JS\n\nMapbox GL JS is a Javascript & WebGL library that renders interactive maps from [vector tiles](https://www.mapbox.com/blog/vector-tiles/) and [Mapbox styles](https://www.mapbox.com/mapbox-gl-style-spec).\n\nIt is part of the [Mapbox GL ecosystem](https://github.com/mapbox/mapbox-gl) which includes [Mapbox GL Native](https://github.com/mapbox/mapbox-gl-native), a suite of compatible SDKs for native desktop and mobile applications.\n\n- [API Documentation](https://www.mapbox.com/mapbox-gl-js/api)\n- [API Examples](https://www.mapbox.com/mapbox-gl-js/examples/)\n- [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec)\n- [Gallery](https://www.mapbox.com/gallery/)\n\n[\"Mapbox](https://www.mapbox.com/gallery/)\n\n## Using Mapbox GL JS with a `\n \n\n\n\n
\n\n \n\n\n```\n\n## Using Mapbox GL JS with [Browserify](http://browserify.org/)\n\nTo use the [vector tiles](https://www.mapbox.com/maps/) and styles hosted on http://mapbox.com, you must [create an account](https://www.mapbox.com/studio/signup/) and then [obtain an access token](https://www.mapbox.com/studio/account/tokens/). You may learn more about access tokens [here](https://www.mapbox.com/help/define-access-token/).\n\nInstall the [`mapbox-gl` npm package](https://www.npmjs.com/package/mapbox-gl)\n\n```bash\nnpm install --save mapbox-gl\n```\n\nInstantiate `mapboxgl.Map`\n\n```js\nvar mapboxgl = require('mapbox-gl');\nmapboxgl.accessToken = '';\nvar map = new mapboxgl.Map({\n container: '',\n style: 'mapbox://styles/mapbox/streets-v9'\n});\n```\n\n## Using Mapbox GL JS with [Webpack](https://webpack.github.io/)\n\nTo use the [vector tiles](https://www.mapbox.com/maps/) and styles hosted on http://mapbox.com, you must [create an account](https://www.mapbox.com/studio/signup/) and then [obtain an access token](https://www.mapbox.com/studio/account/tokens/). You may learn more about access tokens [here](https://www.mapbox.com/help/define-access-token/).\n\nInstall the [`mapbox-gl` npm package](https://www.npmjs.com/package/mapbox-gl)\nand the required loaders.\n\n```bash\nnpm install --save mapbox-gl\nnpm install --save transform-loader\nnpm install --save json-loader\nnpm install --save webworkify-webpack\n```\n\nAdd the [required additional options from webpack.config.example.js](webpack.config.example.js)\nto your webpack configuration.\n\nInstantiate `mapboxgl.Map`\n\n```js\nvar mapboxgl = require('mapbox-gl');\nmapboxgl.accessToken = '';\nvar map = new mapboxgl.Map({\n container: '',\n style: 'mapbox://styles/mapbox/streets-v9'\n});\n```\n\n### Using import\n\nIf you're using the ES6 module system, you can import `mapboxgl` like so:\n\n```js\nimport mapboxgl from 'mapbox-gl';\n```\n\n## Third Party Projects\n\nThese projects are written and maintained by the GL JS community. Feel free to open a PR add your own projects to this list. We :heart: third party projects!\n\n - [Typescript Interface Definition](https://github.com/Smartrak/mapbox-gl-js-typescript)\n - [Webtoolkit Integration](https://github.com/yvanvds/wtMapbox)\n\n## Using Mapbox GL JS with [CSP](https://developer.mozilla.org/en-US/docs/Web/Security/CSP)\n\nYou may use a Content Security Policy to restrict the resources your page has\naccess to, as a way of guarding against Cross-Site Scripting and other types of\nattacks. If you do, Mapbox GL JS requires the following directives:\n\n```\nchild-src blob: ;\nimg-src data: blob: ;\nscript-src 'unsafe-eval' ;\n```\n\nRequesting styles from Mapbox or other services will require additional\ndirectives. For Mapbox, you can use this `connect-src` setting:\n\n```\nconnect-src https://*.tiles.mapbox.com https://api.mapbox.com\n```\n\n## Contributing to Mapbox GL JS\n\nSee [CONTRIBUTING.md](https://github.com/mapbox/mapbox-gl-js/blob/master/CONTRIBUTING.md).\n", - "readmeFilename": "README.md", - "repository": { - "type": "git", - "url": "git://github.com/mapbox/mapbox-gl-js.git" - }, - "scripts": { - "//": "The 'build' script is invoked by publisher when publishing docs on the mb-pages branch", - "build": "npm run build-docs", - "build-dev": "browserify js/mapbox-gl.js --debug --ignore-transform unassertify --standalone mapboxgl > dist/mapbox-gl-dev.js && tap --no-coverage test/build/dev.test.js", - "build-docs": "documentation build --github --format html -c documentation.yml --theme ./docs/_theme --output docs/api/", - "build-min": "browserify js/mapbox-gl.js --debug --plugin [minifyify --map mapbox-gl.js.map --output dist/mapbox-gl.js.map] --standalone mapboxgl > dist/mapbox-gl.js && tap --no-coverage test/build/min.test.js", - "lint": "eslint js test bench server.js docs/_posts/examples/*.html", - "open-changed-examples": "git diff --name-only mb-pages HEAD -- docs/_posts/examples/*.html | awk '{print \"http://127.0.0.1:4000/mapbox-gl-js/example/\" substr($0,33,length($0)-37)}' | xargs open", - "start": "node server.js", - "start-docs": "npm run build-min && npm run build-docs && jekyll serve -w", - "test": "npm run lint && tap --reporter dot test/js/*/*.js test/build/webpack.test.js", - "test-suite": "node test/render.test.js && node test/query.test.js" - }, - "version": "0.22.0" -} - -},{}],185:[function(require,module,exports){ -'use strict'; - -// lightweight Buffer shim for pbf browser build -// based on code from github.com/feross/buffer (MIT-licensed) - -module.exports = Buffer; - -var ieee754 = require('ieee754'); - -var BufferMethods; - -function Buffer(length) { - var arr; - if (length && length.length) { - arr = length; - length = arr.length; - } - var buf = new Uint8Array(length || 0); - if (arr) buf.set(arr); - - buf.readUInt32LE = BufferMethods.readUInt32LE; - buf.writeUInt32LE = BufferMethods.writeUInt32LE; - buf.readInt32LE = BufferMethods.readInt32LE; - buf.writeInt32LE = BufferMethods.writeInt32LE; - buf.readFloatLE = BufferMethods.readFloatLE; - buf.writeFloatLE = BufferMethods.writeFloatLE; - buf.readDoubleLE = BufferMethods.readDoubleLE; - buf.writeDoubleLE = BufferMethods.writeDoubleLE; - buf.toString = BufferMethods.toString; - buf.write = BufferMethods.write; - buf.slice = BufferMethods.slice; - buf.copy = BufferMethods.copy; - - buf._isBuffer = true; - return buf; -} - -var lastStr, lastStrEncoded; - -BufferMethods = { - readUInt32LE: function(pos) { - return ((this[pos]) | - (this[pos + 1] << 8) | - (this[pos + 2] << 16)) + - (this[pos + 3] * 0x1000000); - }, - - writeUInt32LE: function(val, pos) { - this[pos] = val; - this[pos + 1] = (val >>> 8); - this[pos + 2] = (val >>> 16); - this[pos + 3] = (val >>> 24); - }, - - readInt32LE: function(pos) { - return ((this[pos]) | - (this[pos + 1] << 8) | - (this[pos + 2] << 16)) + - (this[pos + 3] << 24); - }, - - readFloatLE: function(pos) { return ieee754.read(this, pos, true, 23, 4); }, - readDoubleLE: function(pos) { return ieee754.read(this, pos, true, 52, 8); }, - - writeFloatLE: function(val, pos) { return ieee754.write(this, val, pos, true, 23, 4); }, - writeDoubleLE: function(val, pos) { return ieee754.write(this, val, pos, true, 52, 8); }, - - toString: function(encoding, start, end) { - var str = '', - tmp = ''; - - start = start || 0; - end = Math.min(this.length, end || this.length); - - for (var i = start; i < end; i++) { - var ch = this[i]; - if (ch <= 0x7F) { - str += decodeURIComponent(tmp) + String.fromCharCode(ch); - tmp = ''; - } else { - tmp += '%' + ch.toString(16); - } - } - - str += decodeURIComponent(tmp); - - return str; - }, - - write: function(str, pos) { - var bytes = str === lastStr ? lastStrEncoded : encodeString(str); - for (var i = 0; i < bytes.length; i++) { - this[pos + i] = bytes[i]; - } - }, - - slice: function(start, end) { - return this.subarray(start, end); - }, - - copy: function(buf, pos) { - pos = pos || 0; - for (var i = 0; i < this.length; i++) { - buf[pos + i] = this[i]; - } - } -}; - -BufferMethods.writeInt32LE = BufferMethods.writeUInt32LE; - -Buffer.byteLength = function(str) { - lastStr = str; - lastStrEncoded = encodeString(str); - return lastStrEncoded.length; -}; - -Buffer.isBuffer = function(buf) { - return !!(buf && buf._isBuffer); -}; - -function encodeString(str) { - var length = str.length, - bytes = []; - - for (var i = 0, c, lead; i < length; i++) { - c = str.charCodeAt(i); // code point - - if (c > 0xD7FF && c < 0xE000) { - - if (lead) { - if (c < 0xDC00) { - bytes.push(0xEF, 0xBF, 0xBD); - lead = c; - continue; - - } else { - c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000; - lead = null; - } - - } else { - if (c > 0xDBFF || (i + 1 === length)) bytes.push(0xEF, 0xBF, 0xBD); - else lead = c; - - continue; - } - - } else if (lead) { - bytes.push(0xEF, 0xBF, 0xBD); - lead = null; - } - - if (c < 0x80) bytes.push(c); - else if (c < 0x800) bytes.push(c >> 0x6 | 0xC0, c & 0x3F | 0x80); - else if (c < 0x10000) bytes.push(c >> 0xC | 0xE0, c >> 0x6 & 0x3F | 0x80, c & 0x3F | 0x80); - else bytes.push(c >> 0x12 | 0xF0, c >> 0xC & 0x3F | 0x80, c >> 0x6 & 0x3F | 0x80, c & 0x3F | 0x80); - } - return bytes; -} - -},{"ieee754":37}],186:[function(require,module,exports){ -(function (global){ -'use strict'; - -module.exports = Pbf; - -var Buffer = global.Buffer || require('./buffer'); - -function Pbf(buf) { - this.buf = !Buffer.isBuffer(buf) ? new Buffer(buf || 0) : buf; - this.pos = 0; - this.length = this.buf.length; -} - -Pbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum -Pbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64 -Pbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields -Pbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32 - -var SHIFT_LEFT_32 = (1 << 16) * (1 << 16), - SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32, - POW_2_63 = Math.pow(2, 63); - -Pbf.prototype = { - - destroy: function() { - this.buf = null; - }, - - // === READING ================================================================= - - readFields: function(readField, result, end) { - end = end || this.length; - - while (this.pos < end) { - var val = this.readVarint(), - tag = val >> 3, - startPos = this.pos; - - 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 = this.buf.readUInt32LE(this.pos); - this.pos += 4; - return val; - }, - - readSFixed32: function() { - var val = this.buf.readInt32LE(this.pos); - this.pos += 4; - return val; - }, - - // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed) - - readFixed64: function() { - var val = this.buf.readUInt32LE(this.pos) + this.buf.readUInt32LE(this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - - readSFixed64: function() { - var val = this.buf.readUInt32LE(this.pos) + this.buf.readInt32LE(this.pos + 4) * SHIFT_LEFT_32; - this.pos += 8; - return val; - }, - - readFloat: function() { - var val = this.buf.readFloatLE(this.pos); - this.pos += 4; - return val; - }, - - readDouble: function() { - var val = this.buf.readDoubleLE(this.pos); - this.pos += 8; - return val; - }, - - readVarint: function() { - var buf = this.buf, - val, b; - - b = buf[this.pos++]; val = b & 0x7f; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 7; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val; - b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val; - - return readVarintRemainder(val, this); - }, - - readVarint64: function() { - var startPos = this.pos, - val = this.readVarint(); - - if (val < POW_2_63) return val; - - var pos = this.pos - 2; - while (this.buf[pos] === 0xff) pos--; - if (pos < startPos) pos = startPos; - - val = 0; - for (var i = 0; i < pos - startPos + 1; i++) { - var b = ~this.buf[startPos + i] & 0x7f; - val += i < 4 ? b << i * 7 : b * Math.pow(2, i * 7); - } - - return -val - 1; - }, - - readSVarint: function() { - var num = this.readVarint(); - return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding - }, - - readBoolean: function() { - return Boolean(this.readVarint()); - }, - - readString: function() { - var end = this.readVarint() + this.pos, - str = this.buf.toString('utf8', this.pos, end); - this.pos = end; - return str; - }, - - readBytes: function() { - var end = this.readVarint() + this.pos, - buffer = this.buf.slice(this.pos, end); - this.pos = end; - return buffer; - }, - - // verbose for performance reasons; doesn't affect gzipped size - - readPackedVarint: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readVarint()); - return arr; - }, - readPackedSVarint: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSVarint()); - return arr; - }, - readPackedBoolean: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readBoolean()); - return arr; - }, - readPackedFloat: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFloat()); - return arr; - }, - readPackedDouble: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readDouble()); - return arr; - }, - readPackedFixed32: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFixed32()); - return arr; - }, - readPackedSFixed32: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSFixed32()); - return arr; - }, - readPackedFixed64: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readFixed64()); - return arr; - }, - readPackedSFixed64: function() { - var end = this.readVarint() + this.pos, arr = []; - while (this.pos < end) arr.push(this.readSFixed64()); - return arr; - }, - - skip: function(val) { - var type = val & 0x7; - if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {} - 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); - }, - - // === WRITING ================================================================= - - 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 Buffer(length); - this.buf.copy(buf); - this.buf = buf; - this.length = length; - } - }, - - finish: function() { - this.length = this.pos; - this.pos = 0; - return this.buf.slice(0, this.length); - }, - - writeFixed32: function(val) { - this.realloc(4); - this.buf.writeUInt32LE(val, this.pos); - this.pos += 4; - }, - - writeSFixed32: function(val) { - this.realloc(4); - this.buf.writeInt32LE(val, this.pos); - this.pos += 4; - }, - - writeFixed64: function(val) { - this.realloc(8); - this.buf.writeInt32LE(val & -1, this.pos); - this.buf.writeUInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - - writeSFixed64: function(val) { - this.realloc(8); - this.buf.writeInt32LE(val & -1, this.pos); - this.buf.writeInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4); - this.pos += 8; - }, - - writeVarint: function(val) { - val = +val; - - if (val > 0xfffffff) { - writeBigVarint(val, this); - return; - } - - this.realloc(4); - - this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return; - this.buf[this.pos++] = (val >>> 7) & 0x7f; - }, - - 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); - var bytes = Buffer.byteLength(str); - this.writeVarint(bytes); - this.realloc(bytes); - this.buf.write(str, this.pos); - this.pos += bytes; - }, - - writeFloat: function(val) { - this.realloc(4); - this.buf.writeFloatLE(val, this.pos); - this.pos += 4; - }, - - writeDouble: function(val) { - this.realloc(8); - this.buf.writeDoubleLE(val, this.pos); - 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++; // reserve 1 byte for short message length - - // write the message directly to the buffer and see how much was written - var startPos = this.pos; - fn(obj, this); - var len = this.pos - startPos; - - if (len >= 0x80) reallocForRawMessage(startPos, len, this); - - // finally, write the message length in the reserved place and restore the position - 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) { this.writeMessage(tag, writePackedVarint, arr); }, - writePackedSVarint: function(tag, arr) { this.writeMessage(tag, writePackedSVarint, arr); }, - writePackedBoolean: function(tag, arr) { this.writeMessage(tag, writePackedBoolean, arr); }, - writePackedFloat: function(tag, arr) { this.writeMessage(tag, writePackedFloat, arr); }, - writePackedDouble: function(tag, arr) { this.writeMessage(tag, writePackedDouble, arr); }, - writePackedFixed32: function(tag, arr) { this.writeMessage(tag, writePackedFixed32, arr); }, - writePackedSFixed32: function(tag, arr) { this.writeMessage(tag, writePackedSFixed32, arr); }, - writePackedFixed64: function(tag, arr) { this.writeMessage(tag, writePackedFixed64, arr); }, - writePackedSFixed64: function(tag, arr) { 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(val, pbf) { - var buf = pbf.buf, b; - - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x10000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x800000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x40000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x2000000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x100000000000000; if (b < 0x80) return val; - b = buf[pbf.pos++]; val += (b & 0x7f) * 0x8000000000000000; if (b < 0x80) return val; - - throw new Error('Expected varint not more than 10 bytes'); -} - -function writeBigVarint(val, pbf) { - pbf.realloc(10); - - var maxPos = pbf.pos + 10; - - while (val >= 1) { - if (pbf.pos >= maxPos) throw new Error('Given varint doesn\'t fit into 10 bytes'); - var b = val & 0xff; - pbf.buf[pbf.pos++] = b | (val >= 0x80 ? 0x80 : 0); - val /= 0x80; - } -} - -function reallocForRawMessage(startPos, len, pbf) { - var extraLen = - len <= 0x3fff ? 1 : - len <= 0x1fffff ? 2 : - len <= 0xfffffff ? 3 : Math.ceil(Math.log(len) / (Math.LN2 * 7)); - - // if 1 byte isn't enough for encoding message length, shift the data to the right - 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]); } - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./buffer":185}],187:[function(require,module,exports){ -'use strict'; - -module.exports = 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); }, - mult: function(k) { return this.clone()._mult(k); }, - div: function(k) { return this.clone()._div(k); }, - rotate: function(a) { return this.clone()._rotate(a); }, - 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(p) { - return this.x === p.x && - this.y === p.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); - }, - - // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. - 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; - }, - - _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; - }, - - _round: function() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } -}; - -// constructs Point from an array if necessary -Point.convert = function (a) { - if (a instanceof Point) { - return a; - } - if (Array.isArray(a)) { - return new Point(a[0], a[1]); - } - return a; -}; - -},{}],188:[function(require,module,exports){ -'use strict'; - -module.exports = partialSort; - -// Floyd-Rivest selection algorithm: -// Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right]; -// The k-th element will have the (k - left + 1)th smallest value in [left, right] - -function partialSort(arr, k, left, right, compare) { - left = left || 0; - right = right || (arr.length - 1); - compare = compare || defaultCompare; - - 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)); - partialSort(arr, k, newLeft, newRight, compare); - } - - var t = arr[k]; - var i = left; - var j = right; - - swap(arr, left, k); - if (compare(arr[right], t) > 0) swap(arr, left, right); - - while (i < j) { - swap(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(arr, left, j); - else { - j++; - swap(arr, j, right); - } - - if (j <= k) left = j + 1; - if (k <= j) right = j - 1; - } -} - -function swap(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; -} - -},{}],189:[function(require,module,exports){ -// Copyright 2014 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) - -void (function(root, factory) { - if (typeof define === "function" && define.amd) { - define(factory) - } else if (typeof exports === "object") { - module.exports = factory() - } else { - root.resolveUrl = factory() - } -}(this, function() { - - function resolveUrl(/* ...urls */) { - var numUrls = arguments.length - - if (numUrls === 0) { - throw new Error("resolveUrl requires at least one argument; got none.") - } - - var base = document.createElement("base") - base.href = arguments[0] - - if (numUrls === 1) { - return base.href - } - - var head = document.getElementsByTagName("head")[0] - head.insertBefore(base, head.firstChild) - - var a = document.createElement("a") - var resolved - - for (var index = 1; index < numUrls; index++) { - a.href = arguments[index] - resolved = a.href - base.href = resolved - } - - head.removeChild(base) - - return resolved - } - - return resolveUrl - -})); - -},{}],190:[function(require,module,exports){ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.ShelfPack = factory()); -}(this, function () { - -/** - * Create a new ShelfPack bin allocator. - * - * Uses the Shelf Best Height Fit algorithm from - * http://clb.demon.fi/files/RectangleBinPack.pdf - * - * @class ShelfPack - * @param {number} [w=64] Initial width of the sprite - * @param {number} [h=64] Initial width of the sprite - * @param {Object} [options] - * @param {boolean} [options.autoResize=false] If `true`, the sprite will automatically grow - * @example - * var sprite = new ShelfPack(64, 64, { autoResize: false }); - */ -function ShelfPack(w, h, options) { - options = options || {}; - this.w = w || 64; - this.h = h || 64; - this.autoResize = !!options.autoResize; - this.shelves = []; - this.stats = {}; - this.count = function(h) { - this.stats[h] = (this.stats[h] | 0) + 1; - }; -} - -/** - * Batch pack multiple bins into the sprite. - * - * @param {Array} bins Array of requested bins - each object should have `width`, `height` (or `w`, `h`) properties - * @param {Object} [options] - * @param {boolean} [options.inPlace=false] If `true`, the supplied bin objects will be updated inplace with `x` and `y` properties - * @returns {Array} Array of allocated bins - each bin is an object with `x`, `y`, `w`, `h` properties - * @example - * var bins = [ - * { id: 'a', width: 12, height: 12 }, - * { id: 'b', width: 12, height: 16 }, - * { id: 'c', width: 12, height: 24 } - * ]; - * var results = sprite.pack(bins, { inPlace: false }); - */ -ShelfPack.prototype.pack = function(bins, options) { - bins = [].concat(bins); - options = options || {}; - - var results = [], - w, h, allocation; - - for (var i = 0; i < bins.length; i++) { - w = bins[i].w || bins[i].width; - h = bins[i].h || bins[i].height; - if (w && h) { - allocation = this.packOne(w, h); - if (!allocation) { - continue; - } - if (options.inPlace) { - bins[i].x = allocation.x; - bins[i].y = allocation.y; - } - results.push(allocation); - } - } - - // Shrink the width/height of the sprite to the bare minimum. - // Since shelf-pack doubles first width, then height when running out of shelf space - // this can result in fairly large unused space both in width and height if that happens - // towards the end of bin packing. - if (this.shelves.length > 0) { - var w2 = 0; - var h2 = 0; - - for (var j = 0; j < this.shelves.length; j++) { - var shelf = this.shelves[j]; - h2 += shelf.h; - w2 = Math.max(shelf.w - shelf.free, w2); - } - - this.resize(w2, h2); - } - - return results; -}; - -/** - * Pack a single bin into the sprite. - * - * @param {number} w Width of the bin to allocate - * @param {number} h Height of the bin to allocate - * @returns {Object} Allocated bin object with `x`, `y`, `w`, `h` properties, or `null` if allocation failed - * @example - * var results = sprite.packOne(12, 16); - */ -ShelfPack.prototype.packOne = function(w, h) { - var y = 0, - best = { shelf: -1, waste: Infinity }, - shelf, waste; - - // find the best shelf - for (var i = 0; i < this.shelves.length; i++) { - shelf = this.shelves[i]; - y += shelf.h; - - // exactly the right height with width to spare, pack it.. - if (h === shelf.h && w <= shelf.free) { - this.count(h); - return shelf.alloc(w, h); - } - // not enough height or width, skip it.. - if (h > shelf.h || w > shelf.free) { - continue; - } - // maybe enough height or width, minimize waste.. - if (h < shelf.h && w <= shelf.free) { - waste = shelf.h - h; - if (waste < best.waste) { - best.waste = waste; - best.shelf = i; - } - } - } - - if (best.shelf !== -1) { - shelf = this.shelves[best.shelf]; - this.count(h); - return shelf.alloc(w, h); - } - - // add shelf.. - if (h <= (this.h - y) && w <= this.w) { - shelf = new Shelf(y, this.w, h); - this.shelves.push(shelf); - this.count(h); - return shelf.alloc(w, h); - } - - // no more space.. - // If `autoResize` option is set, grow the sprite as follows: - // * double whichever sprite dimension is smaller (`w1` or `h1`) - // * if sprite dimensions are equal, grow width before height - // * accomodate very large bin requests (big `w` or `h`) - if (this.autoResize) { - var h1, h2, w1, w2; - - h1 = h2 = this.h; - w1 = w2 = this.w; - - if (w1 <= h1 || w > w1) { // grow width.. - w2 = Math.max(w, w1) * 2; - } - if (h1 < w1 || h > h1) { // grow height.. - h2 = Math.max(h, h1) * 2; - } - - this.resize(w2, h2); - return this.packOne(w, h); // retry - } - - return null; -}; - -/** - * Clear the sprite. - * - * @example - * sprite.clear(); - */ -ShelfPack.prototype.clear = function() { - this.shelves = []; - this.stats = {}; -}; - -/** - * Resize the sprite. - * - * @param {number} w Requested new sprite width - * @param {number} h Requested new sprite height - * @returns {boolean} `true` if resize succeeded, `false` if failed - * @example - * sprite.resize(256, 256); - */ -ShelfPack.prototype.resize = function(w, h) { - this.w = w; - this.h = h; - for (var i = 0; i < this.shelves.length; i++) { - this.shelves[i].resize(w); - } - return true; -}; - - - -/** - * Create a new Shelf. - * - * @private - * @class Shelf - * @param {number} y Top coordinate of the new shelf - * @param {number} w Width of the new shelf - * @param {number} h Height of the new shelf - * @example - * var shelf = new Shelf(64, 512, 24); - */ -function Shelf(y, w, h) { - this.x = 0; - this.y = y; - this.w = this.free = w; - this.h = h; -} - -/** - * Allocate a single bin into the shelf. - * - * @private - * @param {number} w Width of the bin to allocate - * @param {number} h Height of the bin to allocate - * @returns {Object} Allocated bin object with `x`, `y`, `w`, `h` properties, or `null` if allocation failed - * @example - * shelf.alloc(12, 16); - */ -Shelf.prototype.alloc = function(w, h) { - if (w > this.free || h > this.h) { - return null; - } - var x = this.x; - this.x += w; - this.free -= w; - return { x: x, y: this.y, w: w, h: h, width: w, height: h }; -}; - -/** - * Resize the shelf. - * - * @private - * @param {number} w Requested new width of the shelf - * @returns {boolean} true if resize succeeded, false if failed - * @example - * shelf.resize(512); - */ -Shelf.prototype.resize = function(w) { - this.free += (w - this.w); - this.w = w; - return true; -}; - -return ShelfPack; - -})); -},{}],191:[function(require,module,exports){ -'use strict'; - -var kdbush = require('kdbush'); - -module.exports = supercluster; - -function supercluster(options) { - return new SuperCluster(options); -} - -function SuperCluster(options) { - this.options = extend(Object.create(this.options), options); - this.trees = new Array(this.options.maxZoom + 1); -} - -SuperCluster.prototype = { - options: { - minZoom: 0, // min zoom to generate clusters on - maxZoom: 16, // max zoom level to cluster the points on - radius: 40, // cluster radius in pixels - extent: 512, // tile extent (radius is calculated relative to it) - nodeSize: 64, // size of the KD-tree leaf node, affects performance - log: false // whether to log timing info - }, - - load: function (points) { - var log = this.options.log; - - if (log) console.time('total time'); - - var timerId = 'prepare ' + points.length + ' points'; - if (log) console.time(timerId); - - this.points = points; - - // generate a cluster object for each point - var clusters = points.map(createPointCluster); - if (log) console.timeEnd(timerId); - - // cluster points on max zoom, then cluster the results on previous zoom, etc.; - // results in a cluster hierarchy across zoom levels - for (var z = this.options.maxZoom; z >= this.options.minZoom; z--) { - var now = +Date.now(); - - // index input points into a KD-tree - this.trees[z + 1] = kdbush(clusters, getX, getY, this.options.nodeSize, Float32Array); - - clusters = this._cluster(clusters, z); // create a new set of clusters for the zoom - - if (log) console.log('z%d: %d clusters in %dms', z, clusters.length, +Date.now() - now); - } - - // index top-level clusters - this.trees[this.options.minZoom] = kdbush(clusters, getX, getY, this.options.nodeSize, Float32Array); - - if (log) console.timeEnd('total time'); - - return this; - }, - - getClusters: function (bbox, zoom) { - var tree = this.trees[this._limitZoom(zoom)]; - var ids = tree.range(lngX(bbox[0]), latY(bbox[3]), lngX(bbox[2]), latY(bbox[1])); - var clusters = []; - for (var i = 0; i < ids.length; i++) { - var c = tree.points[ids[i]]; - clusters.push(c.id !== -1 ? this.points[c.id] : getClusterJSON(c)); - } - return clusters; - }, - - getTile: function (z, x, y) { - var z2 = Math.pow(2, z); - var extent = this.options.extent; - var p = this.options.radius / extent; - var tree = this.trees[this._limitZoom(z)]; - var ids = tree.range( - (x - p) / z2, - (y - p) / z2, - (x + 1 + p) / z2, - (y + 1 + p) / z2); - - if (!ids.length) return null; - - var tile = { - features: [] - }; - for (var i = 0; i < ids.length; i++) { - var c = tree.points[ids[i]]; - var feature = { - type: 1, - geometry: [[ - Math.round(extent * (c.x * z2 - x)), - Math.round(extent * (c.y * z2 - y)) - ]], - tags: c.id !== -1 ? this.points[c.id].properties : getClusterProperties(c) - }; - tile.features.push(feature); - } - return tile; - }, - - _limitZoom: function (z) { - return Math.max(this.options.minZoom, Math.min(z, this.options.maxZoom + 1)); - }, - - _cluster: function (points, zoom) { - var clusters = []; - var r = this.options.radius / (this.options.extent * Math.pow(2, zoom)); - - // loop through each point - for (var i = 0; i < points.length; i++) { - var p = points[i]; - // if we've already visited the point at this zoom level, skip it - if (p.zoom <= zoom) continue; - p.zoom = zoom; - - // find all nearby points - var tree = this.trees[zoom + 1]; - var neighborIds = tree.within(p.x, p.y, r); - - var foundNeighbors = false; - var numPoints = p.numPoints; - var wx = p.x * numPoints; - var wy = p.y * numPoints; - - for (var j = 0; j < neighborIds.length; j++) { - var b = tree.points[neighborIds[j]]; - // filter out neighbors that are too far or already processed - if (zoom < b.zoom) { - foundNeighbors = true; - b.zoom = zoom; // save the zoom (so it doesn't get processed twice) - wx += b.x * b.numPoints; // accumulate coordinates for calculating weighted center - wy += b.y * b.numPoints; - numPoints += b.numPoints; - } - } - - clusters.push(foundNeighbors ? createCluster(wx / numPoints, wy / numPoints, numPoints, -1) : p); - } - - return clusters; - } -}; - -function createCluster(x, y, numPoints, id) { - return { - x: x, // weighted cluster center - y: y, - zoom: Infinity, // the last zoom the cluster was processed at - id: id, // index of the source feature in the original input array - numPoints: numPoints - }; -} - -function createPointCluster(p, i) { - var coords = p.geometry.coordinates; - return createCluster(lngX(coords[0]), latY(coords[1]), 1, i); -} - -function getClusterJSON(cluster) { - return { - type: 'Feature', - 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 { - cluster: true, - point_count: count, - point_count_abbreviated: abbrev - }; -} - -// longitude/latitude to spherical mercator in [0..1] range -function lngX(lng) { - return lng / 360 + 0.5; -} -function latY(lat) { - var sin = Math.sin(lat * Math.PI / 180), - y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI); - return y < 0 ? 0 : - y > 1 ? 1 : y; -} - -// spherical mercator to longitude/latitude -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; -} - -},{"kdbush":38}],192:[function(require,module,exports){ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Ported from Webkit - * http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h - */ - -module.exports = UnitBezier; - -function UnitBezier(p1x, p1y, p2x, p2y) { - // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). - this.cx = 3.0 * p1x; - this.bx = 3.0 * (p2x - p1x) - this.cx; - this.ax = 1.0 - this.cx - this.bx; - - this.cy = 3.0 * p1y; - this.by = 3.0 * (p2y - p1y) - this.cy; - this.ay = 1.0 - this.cy - this.by; - - this.p1x = p1x; - this.p1y = p2y; - this.p2x = p2x; - this.p2y = p2y; -} - -UnitBezier.prototype.sampleCurveX = function(t) { - // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. - 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.0 * this.ax * t + 2.0 * this.bx) * t + this.cx; -}; - -UnitBezier.prototype.solveCurveX = function(x, epsilon) { - if (typeof epsilon === 'undefined') epsilon = 1e-6; - - var t0, t1, t2, x2, i; - - // First try a few iterations of Newton's method -- normally very fast. - 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) < 1e-6) break; - - t2 = t2 - x2 / d2; - } - - // Fall back to the bisection method for reliability. - t0 = 0.0; - t1 = 1.0; - 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; - } - - // Failure. - return t2; -}; - -UnitBezier.prototype.solve = function(x, epsilon) { - return this.sampleCurveY(this.solveCurveX(x, epsilon)); -}; - -},{}],193:[function(require,module,exports){ -module.exports.VectorTile = require('./lib/vectortile.js'); -module.exports.VectorTileFeature = require('./lib/vectortilefeature.js'); -module.exports.VectorTileLayer = require('./lib/vectortilelayer.js'); - -},{"./lib/vectortile.js":194,"./lib/vectortilefeature.js":195,"./lib/vectortilelayer.js":196}],194:[function(require,module,exports){ -'use strict'; - -var VectorTileLayer = require('./vectortilelayer'); - -module.exports = 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; - } -} - - -},{"./vectortilelayer":196}],195:[function(require,module,exports){ -'use strict'; - -var Point = require('point-geometry'); - -module.exports = VectorTileFeature; - -function VectorTileFeature(pbf, end, extent, keys, values) { - // Public - this.properties = {}; - this.extent = extent; - this.type = 0; - - // Private - 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) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - length = cmdLen >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += pbf.readSVarint(); - y += pbf.readSVarint(); - - if (cmd === 1) { // moveTo - if (line) lines.push(line); - line = []; - } - - line.push(new Point(x, y)); - - } else if (cmd === 7) { - - // Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90 - if (line) { - line.push(line[0].clone()); // closePolygon - } - - } 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) { - var cmdLen = pbf.readVarint(); - cmd = cmdLen & 0x7; - 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(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; -}; - -// classifies an array of rings into polygons with outer rings and holes - -function classifyRings(rings) { - var len = rings.length; - - if (len <= 1) return [rings]; - - var polygons = [], - polygon, - ccw; - - for (var i = 0; i < len; i++) { - var area = signedArea(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(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; -} - -},{"point-geometry":187}],196:[function(require,module,exports){ -'use strict'; - -var VectorTileFeature = require('./vectortilefeature.js'); - -module.exports = VectorTileLayer; - -function VectorTileLayer(pbf, end) { - // Public - this.version = 1; - this.name = null; - this.extent = 4096; - this.length = 0; - - // Private - 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; -} - -// return feature `i` from this layer as a `VectorTileFeature` -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); -}; - -},{"./vectortilefeature.js":195}],197:[function(require,module,exports){ -var Pbf = require('pbf') -var vtpb = require('./vector-tile-pb') -var GeoJSONWrapper = require('./lib/geojson_wrapper') - -module.exports = fromVectorTileJs -module.exports.fromVectorTileJs = fromVectorTileJs -module.exports.fromGeojsonVt = fromGeojsonVt -module.exports.GeoJSONWrapper = GeoJSONWrapper - -/** - * Serialize a vector-tile-js-created tile to pbf - * - * @param {Object} tile - * @return {Buffer} uncompressed, pbf-serialized tile data - */ -function fromVectorTileJs (tile) { - var layers = [] - for (var l in tile.layers) { - layers.push(prepareLayer(tile.layers[l])) - } - - var out = new Pbf() - vtpb.tile.write({ layers: layers }, out) - return out.finish() -} - -/** - * Serialized a geojson-vt-created tile to pbf. - * - * @param {Object} layers - An object mapping layer names to geojson-vt-created vector tile objects - * @return {Buffer} uncompressed, pbf-serialized tile data - */ -function fromGeojsonVt (layers) { - var l = {} - for (var k in layers) { - l[k] = new GeoJSONWrapper(layers[k].features) - l[k].name = k - } - return fromVectorTileJs({layers: l}) -} - -/** - * Prepare the given layer to be serialized by the auto-generated pbf - * serializer by encoding the feature geometry and properties. - */ -function prepareLayer (layer) { - var preparedLayer = { - name: layer.name || '', - version: layer.version || 1, - extent: layer.extent || 4096, - keys: [], - values: [], - features: [] - } - - var keycache = {} - var valuecache = {} - - for (var i = 0; i < layer.length; i++) { - var feature = layer.feature(i) - feature.geometry = encodeGeometry(feature.loadGeometry()) - - var tags = [] - for (var key in feature.properties) { - var keyIndex = keycache[key] - if (typeof keyIndex === 'undefined') { - preparedLayer.keys.push(key) - keyIndex = preparedLayer.keys.length - 1 - keycache[key] = keyIndex - } - var value = wrapValue(feature.properties[key]) - var valueIndex = valuecache[value.key] - if (typeof valueIndex === 'undefined') { - preparedLayer.values.push(value) - valueIndex = preparedLayer.values.length - 1 - valuecache[value.key] = valueIndex - } - tags.push(keyIndex) - tags.push(valueIndex) - } - - feature.tags = tags - preparedLayer.features.push(feature) - } - - return preparedLayer -} - -function command (cmd, length) { - return (length << 3) + (cmd & 0x7) -} - -function zigzag (num) { - return (num << 1) ^ (num >> 31) -} - -/** - * Encode a polygon's geometry into an array ready to be serialized - * to mapbox vector tile specified geometry data. - * - * @param {Array} Rings, each being an array of [x, y] tile-space coordinates - * @return {Array} encoded geometry - */ -function encodeGeometry (geometry) { - var encoded = [] - var x = 0 - var y = 0 - var rings = geometry.length - for (var r = 0; r < rings; r++) { - var ring = geometry[r] - encoded.push(command(1, 1)) // moveto - for (var i = 0; i < ring.length; i++) { - if (i === 1) { - encoded.push(command(2, ring.length - 1)) // lineto - } - var dx = ring[i].x - x - var dy = ring[i].y - y - encoded.push(zigzag(dx), zigzag(dy)) - x += dx - y += dy - } - } - - return encoded -} - -/** - * Wrap a property value according to its type. The returned object - * is of the form { xxxx_value: primitiveValue }, which is what the generated - * protobuf serializer expects. - */ -function wrapValue (value) { - var result - var type = typeof value - if (type === 'string') { - result = { string_value: value } - } else if (type === 'boolean') { - result = { bool_value: value } - } else if (type === 'number') { - if (value % 1 !== 0) { - result = { double_value: value } - } else if (value < 0) { - result = { sint_value: value } - } else { - result = { uint_value: value } - } - } else { - value = JSON.stringify(value) - result = { string_value: value } - } - - result.key = type + ':' + value - return result -} - -},{"./lib/geojson_wrapper":198,"./vector-tile-pb":199,"pbf":186}],198:[function(require,module,exports){ -'use strict' - -var Point = require('point-geometry') -var VectorTileFeature = require('vector-tile').VectorTileFeature - -module.exports = GeoJSONWrapper - -// conform to vectortile api -function GeoJSONWrapper (features) { - this.features = features - this.length = features.length -} - -GeoJSONWrapper.prototype.feature = function (i) { - return new FeatureWrapper(this.features[i]) -} - -function FeatureWrapper (feature) { - 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 = 4096 -} - -FeatureWrapper.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 Point(ring[j][0], ring[j][1])) - } - this.geometry.push(newRing) - } - return this.geometry -} - -FeatureWrapper.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.prototype.toGeoJSON = VectorTileFeature.prototype.toGeoJSON - -},{"point-geometry":187,"vector-tile":193}],199:[function(require,module,exports){ -'use strict'; - -// tile ======================================== - -var tile = exports.tile = {read: readTile, write: writeTile}; - -tile.GeomType = { - "Unknown": 0, - "Point": 1, - "LineString": 2, - "Polygon": 3 -}; - -function readTile(pbf, end) { - return pbf.readFields(readTileField, {"layers": []}, end); -} - -function readTileField(tag, tile, pbf) { - if (tag === 3) tile.layers.push(readLayer(pbf, pbf.readVarint() + pbf.pos)); -} - -function writeTile(tile, pbf) { - var i; - if (tile.layers !== undefined) for (i = 0; i < tile.layers.length; i++) pbf.writeMessage(3, writeLayer, tile.layers[i]); -} - -// value ======================================== - -tile.value = {read: readValue, write: writeValue}; - -function readValue(pbf, end) { - return pbf.readFields(readValueField, {}, end); -} - -function readValueField(tag, value, pbf) { - if (tag === 1) value.string_value = pbf.readString(); - else if (tag === 2) value.float_value = pbf.readFloat(); - else if (tag === 3) value.double_value = pbf.readDouble(); - else if (tag === 4) value.int_value = pbf.readVarint(); - else if (tag === 5) value.uint_value = pbf.readVarint(); - else if (tag === 6) value.sint_value = pbf.readSVarint(); - else if (tag === 7) value.bool_value = pbf.readBoolean(); -} - -function writeValue(value, pbf) { - if (value.string_value !== undefined) pbf.writeStringField(1, value.string_value); - if (value.float_value !== undefined) pbf.writeFloatField(2, value.float_value); - if (value.double_value !== undefined) pbf.writeDoubleField(3, value.double_value); - if (value.int_value !== undefined) pbf.writeVarintField(4, value.int_value); - if (value.uint_value !== undefined) pbf.writeVarintField(5, value.uint_value); - if (value.sint_value !== undefined) pbf.writeSVarintField(6, value.sint_value); - if (value.bool_value !== undefined) pbf.writeBooleanField(7, value.bool_value); -} - -// feature ======================================== - -tile.feature = {read: readFeature, write: writeFeature}; - -function readFeature(pbf, end) { - var feature = pbf.readFields(readFeatureField, {}, end); - if (feature.type === undefined) feature.type = "Unknown"; - return feature; -} - -function readFeatureField(tag, feature, pbf) { - if (tag === 1) feature.id = pbf.readVarint(); - else if (tag === 2) feature.tags = pbf.readPackedVarint(); - else if (tag === 3) feature.type = pbf.readVarint(); - else if (tag === 4) feature.geometry = pbf.readPackedVarint(); -} - -function writeFeature(feature, pbf) { - if (feature.id !== undefined) pbf.writeVarintField(1, feature.id); - if (feature.tags !== undefined) pbf.writePackedVarint(2, feature.tags); - if (feature.type !== undefined) pbf.writeVarintField(3, feature.type); - if (feature.geometry !== undefined) pbf.writePackedVarint(4, feature.geometry); -} - -// layer ======================================== - -tile.layer = {read: readLayer, write: writeLayer}; - -function readLayer(pbf, end) { - return pbf.readFields(readLayerField, {"features": [], "keys": [], "values": []}, end); -} - -function readLayerField(tag, layer, pbf) { - if (tag === 15) layer.version = pbf.readVarint(); - else if (tag === 1) layer.name = pbf.readString(); - else if (tag === 2) layer.features.push(readFeature(pbf, pbf.readVarint() + pbf.pos)); - else if (tag === 3) layer.keys.push(pbf.readString()); - else if (tag === 4) layer.values.push(readValue(pbf, pbf.readVarint() + pbf.pos)); - else if (tag === 5) layer.extent = pbf.readVarint(); -} - -function writeLayer(layer, pbf) { - if (layer.version !== undefined) pbf.writeVarintField(15, layer.version); - if (layer.name !== undefined) pbf.writeStringField(1, layer.name); - var i; - if (layer.features !== undefined) for (i = 0; i < layer.features.length; i++) pbf.writeMessage(2, writeFeature, layer.features[i]); - if (layer.keys !== undefined) for (i = 0; i < layer.keys.length; i++) pbf.writeStringField(3, layer.keys[i]); - if (layer.values !== undefined) for (i = 0; i < layer.values.length; i++) pbf.writeMessage(4, writeValue, layer.values[i]); - if (layer.extent !== undefined) pbf.writeVarintField(5, layer.extent); -} - -},{}],200:[function(require,module,exports){ -var bundleFn = arguments[3]; -var sources = arguments[4]; -var cache = arguments[5]; - -var stringify = JSON.stringify; - -module.exports = function (fn, options) { - var wkey; - var cacheKeys = Object.keys(cache); - - for (var i = 0, l = cacheKeys.length; i < l; i++) { - var key = cacheKeys[i]; - var exp = cache[key].exports; - // Using babel as a transpiler to use esmodule, the export will always - // be an object with the default export as a property of it. To ensure - // the existing api and babel esmodule exports are both supported we - // check for both - if (exp === fn || exp && exp.default === fn) { - wkey = key; - break; - } - } - - if (!wkey) { - wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16); - var wcache = {}; - for (var i = 0, l = cacheKeys.length; i < l; i++) { - var key = cacheKeys[i]; - wcache[key] = key; - } - sources[wkey] = [ - Function(['require','module','exports'], '(' + fn + ')(self)'), - wcache - ]; - } - var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16); - - var scache = {}; scache[wkey] = wkey; - sources[skey] = [ - Function(['require'], ( - // try to call default if defined to also support babel esmodule - // exports - 'var f = require(' + stringify(wkey) + ');' + - '(f.default ? f.default : f)(self);' - )), - scache - ]; - - var src = '(' + bundleFn + ')({' - + Object.keys(sources).map(function (key) { - return stringify(key) + ':[' - + sources[key][0] - + ',' + stringify(sources[key][1]) + ']' - ; - }).join(',') - + '},{},[' + stringify(skey) + '])' - ; - - var URL = window.URL || window.webkitURL || window.mozURL || window.msURL; - - var blob = new Blob([src], { type: 'text/javascript' }); - if (options && options.bare) { return blob; } - var workerUrl = URL.createObjectURL(blob); - var worker = new Worker(workerUrl); - worker.objectURL = workerUrl; - return worker; -}; - -},{}],201:[function(require,module,exports){ -module.exports.RADIUS = 6378137; -module.exports.FLATTENING = 1/298.257223563; -module.exports.POLAR_RADIUS = 6356752.3142; - -},{}],202:[function(require,module,exports){ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.WhooTS = global.WhooTS || {}))); -}(this, function (exports) { - -/** - * getURL - * - * @param {String} baseUrl Base url of the WMS server - * @param {String} layer Layer name - * @param {Number} x Tile coordinate x - * @param {Number} y Tile coordinate y - * @param {Number} z Tile zoom - * @param {Object} [options] - * @param {String} [options.format='image/png'] - * @param {String} [options.service='WMS'] - * @param {String} [options.version='1.1.1'] - * @param {String} [options.request='GetMap'] - * @param {String} [options.srs='EPSG:3857'] - * @param {Number} [options.width='256'] - * @param {Number} [options.height='256'] - * @returns {String} url - * @example - * var baseUrl = 'http://geodata.state.nj.us/imagerywms/Natural2015'; - * var layer = 'Natural2015'; - * var url = whoots.getURL(baseUrl, layer, 154308, 197167, 19); - */ -function getURL(baseUrl, layer, x, y, z, options) { - options = options || {}; - - var url = baseUrl + '?' + [ - 'bbox=' + getTileBBox(x, y, z), - 'format=' + (options.format || 'image/png'), - 'service=' + (options.service || 'WMS'), - 'version=' + (options.version || '1.1.1'), - 'request=' + (options.request || 'GetMap'), - 'srs=' + (options.srs || 'EPSG:3857'), - 'width=' + (options.width || 256), - 'height=' + (options.height || 256), - 'layers=' + layer - ].join('&'); - - return url; -} - - -/** - * 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]; -} - -exports.getURL = getURL; -exports.getTileBBox = getTileBBox; -exports.getMercCoords = getMercCoords; - -Object.defineProperty(exports, '__esModule', { value: true }); - -})); -},{}]},{},[12])(12) -}); \ No newline at end of file diff --git a/index.html b/index.html index fd9515e..f9495f9 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - +