From 4edfff3946bcad85017574bfdcc2aba3768f123d Mon Sep 17 00:00:00 2001 From: Robin Hawkes Date: Sat, 2 Feb 2019 17:51:06 +0000 Subject: [PATCH] Fix interaction events --- dist/vizicities-worker.js | 5884 +++++++++++++++++---- dist/vizicities-worker.min.js | 13 +- dist/vizicities-worker.min.js.map | 2 +- dist/vizicities.js | 7556 ++++++++++++++++++++------- dist/vizicities.min.js | 21 +- dist/vizicities.min.js.map | 2 +- src/layer/geometry/PointLayer.js | 9 +- src/layer/geometry/PolygonLayer.js | 9 +- src/layer/geometry/PolylineLayer.js | 9 +- 9 files changed, 10438 insertions(+), 3067 deletions(-) diff --git a/dist/vizicities-worker.js b/dist/vizicities-worker.js index 6569d96..92a0e97 100755 --- a/dist/vizicities-worker.js +++ b/dist/vizicities-worker.js @@ -7,7 +7,7 @@ exports["VIZI"] = factory(require("THREE")); else root["VIZI"] = factory(root["THREE"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_18__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_21__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -52,7 +52,7 @@ return /******/ (function(modules) { // webpackBootstrap /************************************************************************/ /******/ ([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { value: true @@ -68,11 +68,11 @@ return /******/ (function(modules) { // webpackBootstrap var _layerLayer2 = _interopRequireDefault(_layerLayer); - var _layerGeoJSONWorkerLayer = __webpack_require__(22); + var _layerGeoJSONWorkerLayer = __webpack_require__(25); var _layerGeoJSONWorkerLayer2 = _interopRequireDefault(_layerGeoJSONWorkerLayer); - var _layerGeometryPolygonLayer = __webpack_require__(36); + var _layerGeometryPolygonLayer = __webpack_require__(42); var _layerGeometryPolygonLayer2 = _interopRequireDefault(_layerGeometryPolygonLayer); @@ -84,7 +84,7 @@ return /******/ (function(modules) { // webpackBootstrap var _geoLatLon2 = _interopRequireDefault(_geoLatLon); - var _utilIndex = __webpack_require__(41); + var _utilIndex = __webpack_require__(47); var _utilIndex2 = _interopRequireDefault(_utilIndex); @@ -108,9 +108,9 @@ return /******/ (function(modules) { // webpackBootstrap exports['default'] = VIZI; module.exports = exports['default']; -/***/ }, +/***/ }), /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { value: true @@ -130,6 +130,20 @@ return /******/ (function(modules) { // webpackBootstrap Geo.ECC = 0.081819191; Geo.ECC2 = 0.081819191 * 0.081819191; + // Multiplier is used to expand or compress the WebGL coordinate space relative + // to the EPSG:3857 / Pseudo-Mercator coordinate space (metres). + // + // This is useful for keeping coordinate calculations to smaller numbers and + // helps increase accuracy of things like the z-buffer, object intersection, + // and camera near and far clipping. + // + // A multiplier of 1 would mean a 1:1 mapping between WebGL and EPSG:3857 + // coordinates (1 EPSG:3857 metre === 1 WebGL unit) + // + // A multiplier of 0.1 would mean a 1:0.1 mapping between WebGL and EPSG:3857 + // coordinates (1 EPSG:3857 metre === 0.1 WebGL units) + Geo.multiplier = 0.1; + Geo.project = function (latlon) { var d = Math.PI / 180; var max = Geo.MAX_LATITUDE; @@ -149,6 +163,9 @@ return /******/ (function(modules) { // webpackBootstrap var projected = Geo.project(latlon); projected.y *= -1; + projected.x *= Geo.multiplier; + projected.y *= Geo.multiplier; + return projected; }; @@ -156,6 +173,10 @@ return /******/ (function(modules) { // webpackBootstrap // This just reverses the Y axis to match WebGL Geo.pointToLatLon = function (point) { var _point = (0, _Point.point)(point.x, point.y * -1); + + _point.x /= Geo.multiplier; + _point.y /= Geo.multiplier; + return Geo.unproject(_point); }; @@ -225,36 +246,21 @@ return /******/ (function(modules) { // webpackBootstrap // // Latitude scale is chosen because it fluctuates more than longitude var projectedMetres = Geo.metresToProjected(metres, pointScale); - - var scale = Geo.scale(); - - // Scale projected metres - var scaledMetres = scale * projectedMetres; - - return scaledMetres; + return projectedMetres * Geo.multiplier; }; // Convert world (WebGL) units to a value in real metres Geo.worldToMetres = function (worldUnits, pointScale) { - var scale = Geo.scale(); - - var projectedUnits = worldUnits / scale; + var projectedUnits = worldUnits; var realMetres = Geo.projectedToMetres(projectedUnits, pointScale); - return realMetres; + return realMetres / Geo.multiplier; }; - // If zoom is provided, returns the map width in pixels for a given zoom - // Else, provides fixed scale value + // Returns the world width in pixels for a given zoom, assuming tile dimensions + // of 256x256 pixels Geo.scale = function (zoom) { - // If zoom is provided then return scale based on map tile zoom - if (zoom >= 0) { - return 256 * Math.pow(2, zoom); - // Else, return fixed scale value to expand projected coordinates from - // their 0 to 1 range into something more practical - } else { - return 1; - } + return 256 * Math.pow(2, zoom); }; // Returns zoom level for a given scale value @@ -304,16 +310,16 @@ return /******/ (function(modules) { // webpackBootstrap }; Geo.bounds = (function () { - var d = Geo.R * Math.PI; + var d = Geo.R * Math.PI * Geo.multiplier; return [[-d, -d], [d, d]]; })(); exports['default'] = Geo; module.exports = exports['default']; -/***/ }, +/***/ }), /* 2 */ -/***/ function(module, exports) { +/***/ (function(module, exports) { Object.defineProperty(exports, '__esModule', { value: true @@ -388,9 +394,9 @@ return /******/ (function(modules) { // webpackBootstrap // Initialise without requiring new keyword exports.latLon = noNew; -/***/ }, +/***/ }), /* 3 */ -/***/ function(module, exports) { +/***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true @@ -476,11 +482,11 @@ return /******/ (function(modules) { // webpackBootstrap // Initialise without requiring new keyword exports.point = _point; -/***/ }, +/***/ }), /* 4 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { - Object.defineProperty(exports, '__esModule', { + /* WEBPACK VAR INJECTION */(function(Promise) {Object.defineProperty(exports, '__esModule', { value: true }); @@ -494,29 +500,29 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _eventemitter3 = __webpack_require__(5); + var _eventemitter3 = __webpack_require__(9); var _eventemitter32 = _interopRequireDefault(_eventemitter3); - var _lodashAssign = __webpack_require__(6); + var _lodashAssign = __webpack_require__(10); var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - var _shortid = __webpack_require__(9); + var _shortid = __webpack_require__(11); var _shortid2 = _interopRequireDefault(_shortid); - var _three = __webpack_require__(18); + var _three = __webpack_require__(21); var _three2 = _interopRequireDefault(_three); - var _engineScene = __webpack_require__(19); + var _engineScene = __webpack_require__(22); var _engineScene2 = _interopRequireDefault(_engineScene); - var _vendorCSS3DRenderer = __webpack_require__(20); + var _vendorCSS3DRenderer = __webpack_require__(23); - var _vendorCSS2DRenderer = __webpack_require__(21); + var _vendorCSS2DRenderer = __webpack_require__(24); // TODO: Make sure nothing is left behind in the heap after calling destroy() @@ -764,10 +770,704 @@ return /******/ (function(modules) { // webpackBootstrap }; exports.layer = noNew; + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) -/***/ }, +/***/ }), /* 5 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(setImmediate) {(function (root) { + + // Store setTimeout reference so promise-polyfill will be unaffected by + // other code modifying setTimeout (like sinon.useFakeTimers()) + var setTimeoutFunc = setTimeout; + + function noop() {} + + // Polyfill for Function.prototype.bind + function bind(fn, thisArg) { + return function () { + fn.apply(thisArg, arguments); + }; + } + + function Promise(fn) { + if (!(this instanceof Promise)) throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + this._state = 0; + this._handled = false; + this._value = undefined; + this._deferreds = []; + + doResolve(fn, this); + } + + function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + if (self._state === 0) { + self._deferreds.push(deferred); + return; + } + self._handled = true; + Promise._immediateFn(function () { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + (self._state === 1 ? resolve : reject)(deferred.promise, self._value); + return; + } + var ret; + try { + ret = cb(self._value); + } catch (e) { + reject(deferred.promise, e); + return; + } + resolve(deferred.promise, ret); + }); + } + + function resolve(self, newValue) { + try { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.'); + if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { + var then = newValue.then; + if (newValue instanceof Promise) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(bind(then, newValue), self); + return; + } + } + self._state = 1; + self._value = newValue; + finale(self); + } catch (e) { + reject(self, e); + } + } + + function reject(self, newValue) { + self._state = 2; + self._value = newValue; + finale(self); + } + + function finale(self) { + if (self._state === 2 && self._deferreds.length === 0) { + Promise._immediateFn(function() { + if (!self._handled) { + Promise._unhandledRejectionFn(self._value); + } + }); + } + + for (var i = 0, len = self._deferreds.length; i < len; i++) { + handle(self, self._deferreds[i]); + } + self._deferreds = null; + } + + function Handler(onFulfilled, onRejected, promise) { + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; + } + + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + function doResolve(fn, self) { + var done = false; + try { + fn(function (value) { + if (done) return; + done = true; + resolve(self, value); + }, function (reason) { + if (done) return; + done = true; + reject(self, reason); + }); + } catch (ex) { + if (done) return; + done = true; + reject(self, ex); + } + } + + Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); + }; + + Promise.prototype.then = function (onFulfilled, onRejected) { + var prom = new (this.constructor)(noop); + + handle(this, new Handler(onFulfilled, onRejected, prom)); + return prom; + }; + + Promise.all = function (arr) { + return new Promise(function (resolve, reject) { + if (!arr || typeof arr.length === 'undefined') throw new TypeError('Promise.all accepts an array'); + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call(val, function (val) { + res(i, val); + }, reject); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; + + Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function (resolve) { + resolve(value); + }); + }; + + Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); + }; + + Promise.race = function (values) { + return new Promise(function (resolve, reject) { + for (var i = 0, len = values.length; i < len; i++) { + values[i].then(resolve, reject); + } + }); + }; + + // Use polyfill for setImmediate for performance gains + Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) || + function (fn) { + setTimeoutFunc(fn, 0); + }; + + Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) { + if (typeof console !== 'undefined' && console) { + console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console + } + }; + + /** + * Set the immediate function to execute callbacks + * @param fn {function} Function to execute + * @deprecated + */ + Promise._setImmediateFn = function _setImmediateFn(fn) { + Promise._immediateFn = fn; + }; + + /** + * Change the function to execute on unhandled rejection + * @param {function} fn Function to execute on unhandled rejection + * @deprecated + */ + Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) { + Promise._unhandledRejectionFn = fn; + }; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = Promise; + } else if (!root.Promise) { + root.Promise = Promise; + } + + })(this); + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6).setImmediate)) + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) || + (typeof self !== "undefined" && self) || + window; + var apply = Function.prototype.apply; + + // DOM APIs, for completeness + + exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout); + }; + exports.setInterval = function() { + return new Timeout(apply.call(setInterval, scope, arguments), clearInterval); + }; + exports.clearTimeout = + exports.clearInterval = function(timeout) { + if (timeout) { + timeout.close(); + } + }; + + function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; + } + Timeout.prototype.unref = Timeout.prototype.ref = function() {}; + Timeout.prototype.close = function() { + this._clearFn.call(scope, this._id); + }; + + // Does not start the time, just sets up the members needed. + exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; + }; + + exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; + }; + + exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } + }; + + // setimmediate attaches itself to the global object + __webpack_require__(7); + // On some exotic environments, it's not clear which object `setimmediate` was + // able to install onto. Search each possibility in the same order as the + // `setimmediate` library. + exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) || + (typeof global !== "undefined" && global.setImmediate) || + (this && this.setImmediate); + exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) || + (typeof global !== "undefined" && global.clearImmediate) || + (this && this.clearImmediate); + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { + "use strict"; + + if (global.setImmediate) { + return; + } + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + var doc = global.document; + var registerImmediate; + + function setImmediate(callback) { + // Callback can either be a function or a string + if (typeof callback !== "function") { + callback = new Function("" + callback); + } + // Copy function arguments + var args = new Array(arguments.length - 1); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i + 1]; + } + // Store and register the task + var task = { callback: callback, args: args }; + tasksByHandle[nextHandle] = task; + registerImmediate(nextHandle); + return nextHandle++; + } + + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function run(task) { + var callback = task.callback; + var args = task.args; + switch (args.length) { + case 0: + callback(); + break; + case 1: + callback(args[0]); + break; + case 2: + callback(args[0], args[1]); + break; + case 3: + callback(args[0], args[1], args[2]); + break; + default: + callback.apply(undefined, args); + break; + } + } + + function runIfPresent(handle) { + // From the spec: "Wait until any invocations of this algorithm started before this one have completed." + // So if we're currently running a task, we'll need to delay this invocation. + if (currentlyRunningATask) { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // "too much recursion" error. + setTimeout(runIfPresent, 0, handle); + } else { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + run(task); + } finally { + clearImmediate(handle); + currentlyRunningATask = false; + } + } + } + } + + function installNextTickImplementation() { + registerImmediate = function(handle) { + process.nextTick(function () { runIfPresent(handle); }); + }; + } + + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + var oldOnMessage = global.onmessage; + global.onmessage = function() { + postMessageIsAsynchronous = false; + }; + global.postMessage("", "*"); + global.onmessage = oldOnMessage; + return postMessageIsAsynchronous; + } + } + + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages + + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + runIfPresent(+event.data.slice(messagePrefix.length)); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); + } + + registerImmediate = function(handle) { + global.postMessage(messagePrefix + handle, "*"); + }; + } + + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + var handle = event.data; + runIfPresent(handle); + }; + + registerImmediate = function(handle) { + channel.port2.postMessage(handle); + }; + } + + function installReadyStateChangeImplementation() { + var html = doc.documentElement; + registerImmediate = function(handle) { + // Create a