diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ec08d..1f07fcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ [Official Releases](https://github.com/NASA-AMMOS/LithoSphere/releases) +## v1.4.0 + +_Mar 29, 2022_ + +#### Added + +- Navigation control +- Easting and northing `boundingBoxEN` option for tile layers + +--- + ## v1.3.0 _Feb 23, 2022_ @@ -15,6 +26,8 @@ _Feb 23, 2022_ - Removed extraneous addition of "ratio of surface areas" to `reszoomlevel` +--- + ## v1.2.0 _Jan 27, 2022_ diff --git a/dist/src/controls/index.d.ts b/dist/src/controls/index.d.ts index 37d3725..746ff40 100644 --- a/dist/src/controls/index.d.ts +++ b/dist/src/controls/index.d.ts @@ -10,6 +10,7 @@ export default class Controls { }; activeControls: any; compass: any; + navigation: any; coordinates: any; home: any; layers: any; diff --git a/dist/src/controls/navigation.d.ts b/dist/src/controls/navigation.d.ts new file mode 100644 index 0000000..22470ea --- /dev/null +++ b/dist/src/controls/navigation.d.ts @@ -0,0 +1,14 @@ +import { Corners } from '../generalTypes.d.ts'; +import './navigation.css'; +interface Private { +} +export default class Navigation { + _: Private; + p: any; + name: string; + corner: Corners; + constructor(parent: any, name: string); + getControl: () => string; + attachEvents: () => void; +} +export {}; diff --git a/dist/src/utils/index.d.ts b/dist/src/utils/index.d.ts index 8a123d9..a348252 100644 --- a/dist/src/utils/index.d.ts +++ b/dist/src/utils/index.d.ts @@ -5,6 +5,7 @@ declare const Utils: { findHighestMaxZoom: (tileLayers: any) => number; findLowestMinZoom: (tileLayers: any) => number; isInExtent: (xyz: XYZ, bb: any, projection: any) => boolean; + isInExtentEN: (xyz: XYZ, bb: any, proj: any, margin?: number) => boolean; clone: (obj: any) => any; capitalizeFirstLetter: (string: string) => string; getExtension: (string: string) => string; diff --git a/docs/pages/Controls/controls.markdown b/docs/pages/Controls/controls.markdown index 2b35218..f6fe07d 100644 --- a/docs/pages/Controls/controls.markdown +++ b/docs/pages/Controls/controls.markdown @@ -62,6 +62,14 @@ A menu that lists out the current layers within LithoSphere and provides the abi Litho.addControl('myLayers', Litho.controls.layers) ``` +### Navigation + +Adds on-screen spin, tilt, pan and zoom options to navigate and reorientate the scene through clicking. + +```javascript +Litho.addControl('myNavigation', Litho.controls.navigation) +``` + ### Observe Allows users to set camera parameters and stand at a location in it. diff --git a/docs/pages/Layers/Tile/tile.markdown b/docs/pages/Layers/Tile/tile.markdown index 16925f1..a9260c0 100644 --- a/docs/pages/Layers/Tile/tile.markdown +++ b/docs/pages/Layers/Tile/tile.markdown @@ -11,21 +11,22 @@ A tiled raster layer with height support. ## Options -| Parameter | Type | Default | Description | -| :------------------: | :-----------: | :--------: | :------------------------------------------------------------------------------------------------------: | -| **name** | _string_ | _Required_ | Layer's name and unique identifier | -| **order** | _number_ | _Required_ | Layer draw order state | -| **on** | _boolean_ | _Required_ | Initial visibility | -| **path** | _string_ | _Required_ | A URL to the raster tileset curtain | -| **demPath** | _string_ | null | A URL to the DEM (Digital Elevation Model) tileset | -| **format** | _string-enum_ | 'tms' | Raster tileset format ('tms', 'wmts', 'wms ) | -| **demFormat** | _string_ | 'tms' | DEM tileset format ('tms', 'wmts', 'wms ) | -| **demFormatOptions** | _object_ | null | See example below | -| **opacity** | _number_ | _Required_ | Initial opaqueness [0(transparent), 1(opaque)] | -| **minZoom** | _integer_ | _Required_ | The minimum (smallest number) zoom level of the raster tileset | -| **maxZoom** | _integer_ | _Required_ | The maximum (biggest number) zoom level of the raster tileset | -| **filters** | _object_ | null | Filter and blend mode effect for the layer | -| **boundingBox** | _number[4]_ | null | The bounds of the tileset. Only queries for tiles that intersect this box. [lng, lat, lng, lat] (SW, NE) | +| Parameter | Type | Default | Description | +| :------------------: | :-----------: | :--------: | :--------------------------------------------------------------------------------------------------------: | +| **name** | _string_ | _Required_ | Layer's name and unique identifier | +| **order** | _number_ | _Required_ | Layer draw order state | +| **on** | _boolean_ | _Required_ | Initial visibility | +| **path** | _string_ | _Required_ | A URL to the raster tileset curtain | +| **demPath** | _string_ | null | A URL to the DEM (Digital Elevation Model) tileset | +| **format** | _string-enum_ | 'tms' | Raster tileset format ('tms', 'wmts', 'wms ) | +| **demFormat** | _string_ | 'tms' | DEM tileset format ('tms', 'wmts', 'wms ) | +| **demFormatOptions** | _object_ | null | See example below | +| **opacity** | _number_ | _Required_ | Initial opaqueness [0(transparent), 1(opaque)] | +| **minZoom** | _integer_ | _Required_ | The minimum (smallest number) zoom level of the raster tileset | +| **maxZoom** | _integer_ | _Required_ | The maximum (biggest number) zoom level of the raster tileset | +| **filters** | _object_ | null | Filter and blend mode effect for the layer | +| **boundingBox** | _number[4]_ | null | The bounds of the tileset. Only queries for tiles that intersect this box. `[lng, lat, lng, lat] (SW, NE)` | +| **boundingBoxEN** | _number[4]_ | null | Alternative bounding box in the projected space. `[easting, northing, easting, northing] (min, max)` | ### Example diff --git a/docs/pages/Overview/overview.markdown b/docs/pages/Overview/overview.markdown index e8a0125..f27155a 100644 --- a/docs/pages/Overview/overview.markdown +++ b/docs/pages/Overview/overview.markdown @@ -40,7 +40,7 @@ Head over to [Getting Started]({{ site.baseurl }}/getting-started) for more, che - Home - Exaggerate - Crop - - Controls + - Navigation - Coordinates - Link - A stub to create parsers for your own tiled data formats diff --git a/package.json b/package.json index 904b8ef..916a565 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lithosphere", - "version": "1.3.0", + "version": "1.4.0", "description": "LithoSphere is a GIS JavaScript library for building 3D tile-based globes in the web browser.", "author": "Tariq Soliman", "license": "Apache-2.0", diff --git a/public/dist/lithosphere.js b/public/dist/lithosphere.js index b6beab2..c6831d9 100644 --- a/public/dist/lithosphere.js +++ b/public/dist/lithosphere.js @@ -504,6 +504,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ }), +/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js?!./src/controls/navigation.css": +/*!*******************************************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ref--5-2!./src/controls/navigation.css ***! + \*******************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.i, \"#_lithosphere_control_navigation_root {\\r\\n display: flex;\\r\\n}\\r\\n#_lithosphere_control_navigation_root svg {\\r\\n width: 24px;\\r\\n height: 24px;\\r\\n}\\r\\n#_lithosphere_control_navigation_root > div {\\r\\n width: 80px;\\r\\n margin-right: 6px;\\r\\n display: flex;\\r\\n flex-flow: column;\\r\\n}\\r\\n#_lithosphere_control_navigation_root > div > div:first-child {\\r\\n background: black;\\r\\n color: white;\\r\\n height: 26px;\\r\\n line-height: 26px;\\r\\n text-transform: uppercase;\\r\\n font-size: 12px;\\r\\n}\\r\\n#_lithosphere_control_navigation_root > div > div:first-child svg {\\r\\n width: 18px;\\r\\n height: 18px;\\r\\n padding: 4px 0px;\\r\\n}\\r\\n\\r\\n._lithosphere_control_navigation_panel {\\r\\n width: 80px;\\r\\n max-height: 0px;\\r\\n overflow: hidden;\\r\\n line-height: 42px;\\r\\n background: black;\\r\\n color: white;\\r\\n display: flex;\\r\\n border-top: 1px solid #444;\\r\\n opacity: 0;\\r\\n pointer-events: none;\\r\\n transition: all 0.2s ease-out;\\r\\n}\\r\\n\\r\\n#_lithosphere_control_navigation_root\\r\\n > div:hover\\r\\n > ._lithosphere_control_navigation_panel,\\r\\n#_lithosphere_control_navigation_root\\r\\n ._lithosphere_control_navigation_panel.active {\\r\\n opacity: 1;\\r\\n max-height: 100px;\\r\\n pointer-events: inherit;\\r\\n}\\r\\n._lithosphere_control_navigation_panel div {\\r\\n cursor: pointer;\\r\\n transition: background 0.2s ease-out;\\r\\n}\\r\\n._lithosphere_control_navigation_panel div:hover {\\r\\n background: rgba(255, 255, 255, 0.15);\\r\\n}\\r\\n\\r\\n#_lithosphere_control_navigation_spin_root\\r\\n ._lithosphere_control_navigation_panel {\\r\\n height: 30px;\\r\\n}\\r\\n#_lithosphere_control_navigation_dolly_root\\r\\n ._lithosphere_control_navigation_panel {\\r\\n height: 30px;\\r\\n}\\r\\n#_lithosphere_control_navigation_pan_root\\r\\n ._lithosphere_control_navigation_panel {\\r\\n line-height: 30px;\\r\\n height: 90px;\\r\\n flex-flow: column;\\r\\n}\\r\\n#_lithosphere_control_navigation_zoom_root\\r\\n ._lithosphere_control_navigation_panel {\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\n#_lithosphere_control_navigation_spin_left,\\r\\n#_lithosphere_control_navigation_spin_right,\\r\\n#_lithosphere_control_navigation_dolly_up,\\r\\n#_lithosphere_control_navigation_dolly_down,\\r\\n#_lithosphere_control_navigation_zoom_in,\\r\\n#_lithosphere_control_navigation_zoom_out {\\r\\n width: 50%;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\n#_lithosphere_control_navigation_pan_up {\\r\\n height: 30px;\\r\\n line-height: 49px;\\r\\n text-align: center;\\r\\n}\\r\\n#_lithosphere_control_navigation_pan_left,\\r\\n#_lithosphere_control_navigation_pan_right {\\r\\n height: 30px;\\r\\n line-height: 44px;\\r\\n width: 50%;\\r\\n text-align: center;\\r\\n}\\r\\n#_lithosphere_control_navigation_pan_down {\\r\\n height: 30px;\\r\\n line-height: 38px;\\r\\n text-align: center;\\r\\n}\\r\\n\", \"\"]);\n// Exports\n/* harmony default export */ __webpack_exports__[\"default\"] = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://LithoSphere/./src/controls/navigation.css?./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ref--5-2"); + +/***/ }), + /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js?!./src/secondary/loadingScreen.css": /*!***********************************************************************************************************************************!*\ !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ref--5-2!./src/secondary/loadingScreen.css ***! @@ -1864,7 +1876,7 @@ eval("__webpack_require__.r(__webpack_exports__);\nvar Home = function () {\n f /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _compass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./compass */ \"./src/controls/compass.ts\");\n/* harmony import */ var _coordinates__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./coordinates */ \"./src/controls/coordinates.ts\");\n/* harmony import */ var _home__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./home */ \"./src/controls/home.ts\");\n/* harmony import */ var _layers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./layers */ \"./src/controls/layers.ts\");\n/* harmony import */ var _exaggerate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./exaggerate */ \"./src/controls/exaggerate.ts\");\n/* harmony import */ var _observe__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./observe */ \"./src/controls/observe.ts\");\n/* harmony import */ var _walk__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./walk */ \"./src/controls/walk.ts\");\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./link */ \"./src/controls/link.ts\");\n\n\n\n\n\n\n\n\n\nvar Controls = function () {\n function Controls(parent) {\n var _this = this;\n\n this.addControl = function (name, control, params, corner) {\n if (_this.activeControls[name] != null) {\n console.warn(\"UI Control control with identifying name '\" + name + \"' already exists. Remove the existing one or pick a different name to add this control.\");\n return;\n }\n\n try {\n _this.activeControls[name] = new control(_this.p, name, params);\n } catch (err) {\n if (_this.activeControls[name] != null) delete _this.activeControls[name];\n console.warn(\"Error adding UI Element with name '\" + name + \"' -\", err);\n return;\n }\n\n corner = corner || _this.activeControls[name].corner || \"TopLeft\";\n var newControl = document.createElement('div');\n newControl.setAttribute('id', \"_lithosphere_control_\" + name);\n newControl.innerHTML = _this.activeControls[name].getControl();\n newControl.style.marginRight = '5px';\n if (corner === \"TopLeft\" || corner === \"TopRight\") newControl.style.marginBottom = '5px';\n\n _this.corners[corner].appendChild(newControl);\n\n _this.activeControls[name].attachEvents();\n\n if (_this.activeControls[name].getReturn) {\n return _this.activeControls[name].getReturn();\n }\n };\n\n this.removeControl = function (name) {\n delete _this.activeControls[name];\n document.getElementById(\"_lithosphere_control_\" + name).remove();\n };\n\n this._onUpdateEvent = function () {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onUpdate === 'function') control.onUpdate();\n });\n };\n\n this._onMove = function (lng, lat, height) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMove === 'function') control.onMove(lng, lat, height);\n });\n };\n\n this._onMouseMove = function (lng, lat, height) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMouseMove === 'function') control.onMouseMove(lng, lat, height);\n });\n };\n\n this._onMouseOut = function (e) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMouseOut === 'function') control.onMouseOut(e);\n });\n };\n\n this._onFirstPersonUpdate = function () {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onFirstPersonUpdate === 'function') control.onFirstPersonUpdate();\n });\n };\n\n this._onOrbitalUpdate = function (e) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onOrbitalUpdate === 'function') control.onOrbitalUpdate(e);\n });\n };\n\n this.p = parent;\n this.activeControls = {};\n this.controlContainer = document.createElement('div');\n this.controlContainer.setAttribute('id', '_lithosphere_controls');\n this.controlContainer.style.position = 'absolute';\n this.controlContainer.style.top = '0';\n this.controlContainer.style.left = '0';\n this.controlContainer.style.width = '100%';\n this.controlContainer.style.height = '100%';\n this.controlContainer.style.pointerEvents = 'none';\n this.controlContainer.style.color = 'white';\n this.controlContainer.style.fontFamily = 'sans-serif';\n this.controlContainer.style.zIndex = '1000';\n\n this.p._.container.appendChild(this.controlContainer);\n\n this.corners = {\n TopLeft: null,\n TopRight: null,\n BottomLeft: null,\n BottomRight: null\n };\n var margin = '10px';\n this.corners.TopLeft = document.createElement('div');\n this.corners.TopLeft.setAttribute('id', '_lithosphere_controls_topleft');\n this.corners.TopLeft.style.position = 'absolute';\n this.corners.TopLeft.style.top = margin;\n this.corners.TopLeft.style.left = margin;\n this.corners.TopLeft.style.pointerEvents = 'all';\n this.corners.TopLeft.style.display = 'flex';\n this.corners.TopLeft.style.flexFlow = 'column';\n this.controlContainer.appendChild(this.corners.TopLeft);\n this.corners.TopRight = document.createElement('div');\n this.corners.TopRight.setAttribute('id', '_lithosphere_controls_topright');\n this.corners.TopRight.style.position = 'absolute';\n this.corners.TopRight.style.top = margin;\n this.corners.TopRight.style.right = margin;\n this.corners.TopRight.style.pointerEvents = 'all';\n this.corners.TopRight.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.TopRight);\n this.corners.BottomLeft = document.createElement('div');\n this.corners.BottomLeft.setAttribute('id', '_lithosphere_controls_bottomleft');\n this.corners.BottomLeft.style.position = 'absolute';\n this.corners.BottomLeft.style.bottom = margin;\n this.corners.BottomLeft.style.left = margin;\n this.corners.BottomLeft.style.pointerEvents = 'all';\n this.corners.BottomLeft.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.BottomLeft);\n this.corners.BottomRight = document.createElement('div');\n this.corners.BottomRight.setAttribute('id', '_lithosphere_controls_bottomright');\n this.corners.BottomRight.style.position = 'absolute';\n this.corners.BottomRight.style.bottom = margin;\n this.corners.BottomRight.style.right = margin;\n this.corners.BottomRight.style.pointerEvents = 'all';\n this.corners.BottomRight.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.BottomRight);\n this.compass = _compass__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n this.coordinates = _coordinates__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n this.home = _home__WEBPACK_IMPORTED_MODULE_2__[\"default\"];\n this.layers = _layers__WEBPACK_IMPORTED_MODULE_3__[\"default\"];\n this.exaggerate = _exaggerate__WEBPACK_IMPORTED_MODULE_4__[\"default\"];\n this.observe = _observe__WEBPACK_IMPORTED_MODULE_5__[\"default\"];\n this.walk = _walk__WEBPACK_IMPORTED_MODULE_6__[\"default\"];\n this.link = _link__WEBPACK_IMPORTED_MODULE_7__[\"default\"];\n }\n\n return Controls;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Controls);\n\n//# sourceURL=webpack://LithoSphere/./src/controls/index.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _compass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./compass */ \"./src/controls/compass.ts\");\n/* harmony import */ var _navigation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./navigation */ \"./src/controls/navigation.ts\");\n/* harmony import */ var _coordinates__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./coordinates */ \"./src/controls/coordinates.ts\");\n/* harmony import */ var _home__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./home */ \"./src/controls/home.ts\");\n/* harmony import */ var _layers__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./layers */ \"./src/controls/layers.ts\");\n/* harmony import */ var _exaggerate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./exaggerate */ \"./src/controls/exaggerate.ts\");\n/* harmony import */ var _observe__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./observe */ \"./src/controls/observe.ts\");\n/* harmony import */ var _walk__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./walk */ \"./src/controls/walk.ts\");\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./link */ \"./src/controls/link.ts\");\n\n\n\n\n\n\n\n\n\n\nvar Controls = function () {\n function Controls(parent) {\n var _this = this;\n\n this.addControl = function (name, control, params, corner) {\n if (_this.activeControls[name] != null) {\n console.warn(\"UI Control control with identifying name '\" + name + \"' already exists. Remove the existing one or pick a different name to add this control.\");\n return;\n }\n\n try {\n _this.activeControls[name] = new control(_this.p, name, params);\n } catch (err) {\n if (_this.activeControls[name] != null) delete _this.activeControls[name];\n console.warn(\"Error adding UI Element with name '\" + name + \"' -\", err);\n return;\n }\n\n corner = corner || _this.activeControls[name].corner || \"TopLeft\";\n var newControl = document.createElement('div');\n newControl.setAttribute('id', \"_lithosphere_control_\" + name);\n newControl.innerHTML = _this.activeControls[name].getControl();\n newControl.style.marginRight = '5px';\n if (corner === \"TopLeft\" || corner === \"TopRight\") newControl.style.marginBottom = '5px';\n\n _this.corners[corner].appendChild(newControl);\n\n _this.activeControls[name].attachEvents();\n\n if (_this.activeControls[name].getReturn) {\n return _this.activeControls[name].getReturn();\n }\n };\n\n this.removeControl = function (name) {\n delete _this.activeControls[name];\n document.getElementById(\"_lithosphere_control_\" + name).remove();\n };\n\n this._onUpdateEvent = function () {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onUpdate === 'function') control.onUpdate();\n });\n };\n\n this._onMove = function (lng, lat, height) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMove === 'function') control.onMove(lng, lat, height);\n });\n };\n\n this._onMouseMove = function (lng, lat, height) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMouseMove === 'function') control.onMouseMove(lng, lat, height);\n });\n };\n\n this._onMouseOut = function (e) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onMouseOut === 'function') control.onMouseOut(e);\n });\n };\n\n this._onFirstPersonUpdate = function () {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onFirstPersonUpdate === 'function') control.onFirstPersonUpdate();\n });\n };\n\n this._onOrbitalUpdate = function (e) {\n Object.values(_this.activeControls).forEach(function (control) {\n if (typeof control.onOrbitalUpdate === 'function') control.onOrbitalUpdate(e);\n });\n };\n\n this.p = parent;\n this.activeControls = {};\n this.controlContainer = document.createElement('div');\n this.controlContainer.setAttribute('id', '_lithosphere_controls');\n this.controlContainer.style.position = 'absolute';\n this.controlContainer.style.top = '0';\n this.controlContainer.style.left = '0';\n this.controlContainer.style.width = '100%';\n this.controlContainer.style.height = '100%';\n this.controlContainer.style.pointerEvents = 'none';\n this.controlContainer.style.color = 'white';\n this.controlContainer.style.fontFamily = 'sans-serif';\n this.controlContainer.style.zIndex = '1000';\n\n this.p._.container.appendChild(this.controlContainer);\n\n this.corners = {\n TopLeft: null,\n TopRight: null,\n BottomLeft: null,\n BottomRight: null\n };\n var margin = '10px';\n this.corners.TopLeft = document.createElement('div');\n this.corners.TopLeft.setAttribute('id', '_lithosphere_controls_topleft');\n this.corners.TopLeft.style.position = 'absolute';\n this.corners.TopLeft.style.top = margin;\n this.corners.TopLeft.style.left = margin;\n this.corners.TopLeft.style.pointerEvents = 'all';\n this.corners.TopLeft.style.display = 'flex';\n this.corners.TopLeft.style.flexFlow = 'column';\n this.controlContainer.appendChild(this.corners.TopLeft);\n this.corners.TopRight = document.createElement('div');\n this.corners.TopRight.setAttribute('id', '_lithosphere_controls_topright');\n this.corners.TopRight.style.position = 'absolute';\n this.corners.TopRight.style.top = margin;\n this.corners.TopRight.style.right = margin;\n this.corners.TopRight.style.pointerEvents = 'all';\n this.corners.TopRight.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.TopRight);\n this.corners.BottomLeft = document.createElement('div');\n this.corners.BottomLeft.setAttribute('id', '_lithosphere_controls_bottomleft');\n this.corners.BottomLeft.style.position = 'absolute';\n this.corners.BottomLeft.style.bottom = margin;\n this.corners.BottomLeft.style.left = margin;\n this.corners.BottomLeft.style.pointerEvents = 'all';\n this.corners.BottomLeft.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.BottomLeft);\n this.corners.BottomRight = document.createElement('div');\n this.corners.BottomRight.setAttribute('id', '_lithosphere_controls_bottomright');\n this.corners.BottomRight.style.position = 'absolute';\n this.corners.BottomRight.style.bottom = margin;\n this.corners.BottomRight.style.right = margin;\n this.corners.BottomRight.style.pointerEvents = 'all';\n this.corners.BottomRight.style.display = 'flex';\n this.controlContainer.appendChild(this.corners.BottomRight);\n this.compass = _compass__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n this.coordinates = _coordinates__WEBPACK_IMPORTED_MODULE_2__[\"default\"];\n this.navigation = _navigation__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n this.home = _home__WEBPACK_IMPORTED_MODULE_3__[\"default\"];\n this.layers = _layers__WEBPACK_IMPORTED_MODULE_4__[\"default\"];\n this.exaggerate = _exaggerate__WEBPACK_IMPORTED_MODULE_5__[\"default\"];\n this.observe = _observe__WEBPACK_IMPORTED_MODULE_6__[\"default\"];\n this.walk = _walk__WEBPACK_IMPORTED_MODULE_7__[\"default\"];\n this.link = _link__WEBPACK_IMPORTED_MODULE_8__[\"default\"];\n }\n\n return Controls;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Controls);\n\n//# sourceURL=webpack://LithoSphere/./src/controls/index.ts?"); /***/ }), @@ -1892,6 +1904,29 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var thre /***/ }), +/***/ "./src/controls/navigation.css": +/*!*************************************!*\ + !*** ./src/controls/navigation.css ***! + \*************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n var content = __webpack_require__(/*! !../../node_modules/css-loader/dist/cjs.js!../../node_modules/postcss-loader/dist/cjs.js??ref--5-2!./navigation.css */ \"./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js?!./src/controls/navigation.css\");\n\n content = content.__esModule ? content.default : content;\n\n if (typeof content === 'string') {\n content = [[module.i, content, '']];\n }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\n\nmodule.exports = content.locals || {};\n\n//# sourceURL=webpack://LithoSphere/./src/controls/navigation.css?"); + +/***/ }), + +/***/ "./src/controls/navigation.ts": +/*!************************************!*\ + !*** ./src/controls/navigation.ts ***! + \************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _navigation_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./navigation.css */ \"./src/controls/navigation.css\");\n/* harmony import */ var _navigation_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_navigation_css__WEBPACK_IMPORTED_MODULE_0__);\n\n\nvar Navigation = function () {\n function Navigation(parent, name) {\n var _this = this;\n\n this.getControl = function () {\n return [\"
\"].join('\\n');\n };\n\n this.attachEvents = function () {\n document.getElementById('_lithosphere_control_navigation_spin').addEventListener('click', function (e) {\n document.querySelector('#_lithosphere_control_navigation_spin_root ._lithosphere_control_navigation_panel').classList.toggle('active');\n });\n document.getElementById('_lithosphere_control_navigation_spin_left').addEventListener('click', function () {\n _this.p._.cameras.controls.rotateLeft(3 * (Math.PI / 180));\n });\n document.getElementById('_lithosphere_control_navigation_spin_right').addEventListener('click', function () {\n _this.p._.cameras.controls.rotateLeft(-3 * (Math.PI / 180));\n });\n document.getElementById('_lithosphere_control_navigation_dolly').addEventListener('click', function (e) {\n document.querySelector('#_lithosphere_control_navigation_dolly_root ._lithosphere_control_navigation_panel').classList.toggle('active');\n });\n document.getElementById('_lithosphere_control_navigation_dolly_up').addEventListener('click', function () {\n _this.p._.cameras.controls.rotateUp(1.3 * (Math.PI / 180));\n });\n document.getElementById('_lithosphere_control_navigation_dolly_down').addEventListener('click', function () {\n _this.p._.cameras.controls.rotateUp(-1.3 * (Math.PI / 180));\n });\n document.getElementById('_lithosphere_control_navigation_pan').addEventListener('click', function (e) {\n document.querySelector('#_lithosphere_control_navigation_pan_root ._lithosphere_control_navigation_panel').classList.toggle('active');\n });\n document.getElementById('_lithosphere_control_navigation_pan_up').addEventListener('click', function () {\n _this.p._.events._rotateGlobe({\n pageX: 0,\n pageY: 0\n }, {\n x: 0,\n y: -200\n });\n });\n document.getElementById('_lithosphere_control_navigation_pan_left').addEventListener('click', function () {\n _this.p._.events._rotateGlobe({\n pageX: 0,\n pageY: 0\n }, {\n x: -200,\n y: 0\n });\n });\n document.getElementById('_lithosphere_control_navigation_pan_right').addEventListener('click', function () {\n _this.p._.events._rotateGlobe({\n pageX: 0,\n pageY: 0\n }, {\n x: 200,\n y: 0\n });\n });\n document.getElementById('_lithosphere_control_navigation_pan_down').addEventListener('click', function () {\n _this.p._.events._rotateGlobe({\n pageX: 0,\n pageY: 0\n }, {\n x: 0,\n y: 200\n });\n });\n document.getElementById('_lithosphere_control_navigation_zoom').addEventListener('click', function (e) {\n document.querySelector('#_lithosphere_control_navigation_zoom_root ._lithosphere_control_navigation_panel').classList.toggle('active');\n });\n document.getElementById('_lithosphere_control_navigation_zoom_in').addEventListener('click', function () {\n _this.p._.cameras.controls.handleMouseWheel({\n deltaY: -200\n });\n\n _this.p._.events._onZoom();\n });\n document.getElementById('_lithosphere_control_navigation_zoom_out').addEventListener('click', function () {\n _this.p._.cameras.controls.handleMouseWheel({\n deltaY: 200\n });\n\n _this.p._.events._onZoom();\n });\n };\n\n this.p = parent;\n this.name = name;\n this._ = {};\n this.corner = \"TopRight\";\n }\n\n return Navigation;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Navigation);\n\n//# sourceURL=webpack://LithoSphere/./src/controls/navigation.ts?"); + +/***/ }), + /***/ "./src/controls/observe.ts": /*!*********************************!*\ !*** ./src/controls/observe.ts ***! @@ -2008,7 +2043,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var thre /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ */ \"./src/core/index.ts\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _parsers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../parsers */ \"./src/parsers/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"./src/utils/index.ts\");\n/* harmony import */ var _utils_paths__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/paths */ \"./src/utils/paths.ts\");\nvar __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P ? value : new P(function (resolve) {\n resolve(value);\n });\n }\n\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n\n function step(result) {\n result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n }\n\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\nvar __generator = undefined && undefined.__generator || function (thisArg, body) {\n var _ = {\n label: 0,\n sent: function () {\n if (t[0] & 1) throw t[1];\n return t[1];\n },\n trys: [],\n ops: []\n },\n f,\n y,\n t,\n g;\n return g = {\n next: verb(0),\n \"throw\": verb(1),\n \"return\": verb(2)\n }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function () {\n return this;\n }), g;\n\n function verb(n) {\n return function (v) {\n return step([n, v]);\n };\n }\n\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n\n while (_) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n\n switch (op[0]) {\n case 0:\n case 1:\n t = op;\n break;\n\n case 4:\n _.label++;\n return {\n value: op[1],\n done: false\n };\n\n case 5:\n _.label++;\n y = op[1];\n op = [0];\n continue;\n\n case 7:\n op = _.ops.pop();\n\n _.trys.pop();\n\n continue;\n\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n _ = 0;\n continue;\n }\n\n if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n _.label = op[1];\n break;\n }\n\n if (op[0] === 6 && _.label < t[1]) {\n _.label = t[1];\n t = op;\n break;\n }\n\n if (t && _.label < t[2]) {\n _.label = t[2];\n\n _.ops.push(op);\n\n break;\n }\n\n if (t[2]) _.ops.pop();\n\n _.trys.pop();\n\n continue;\n }\n\n op = body.call(thisArg, _);\n } catch (e) {\n op = [6, e];\n y = 0;\n } finally {\n f = t = 0;\n }\n\n if (op[0] & 5) throw op[1];\n return {\n value: op[0] ? op[1] : void 0,\n done: true\n };\n }\n};\n\n\n\n\n\n\n\nvar TiledWorld = function () {\n function TiledWorld(parent) {\n this.p = parent;\n\n this._reset();\n }\n\n TiledWorld.prototype._reset = function () {\n this._ = {\n loader: new three__WEBPACK_IMPORTED_MODULE_1__[\"TextureLoader\"](),\n tileDimension: 6\n };\n this.tilesDrawn = [];\n this.tilesWanted = [];\n this.tilesToBeDrawn = [];\n this.tilesBeingDrawn = [];\n };\n\n TiledWorld.prototype.refreshTiles = function () {\n var _this = this;\n\n this.updateDesiredTiles();\n this.tilesToBeDrawn = [];\n\n for (var i = 0; i < this.tilesWanted.length; i++) {\n var matched = false;\n\n for (var j = 0; j < this.tilesDrawn.length; j++) {\n if (this.tilesWanted[i].x == this.tilesDrawn[j].x && this.tilesWanted[i].y == this.tilesDrawn[j].y && this.tilesWanted[i].z == this.tilesDrawn[j].z && this.tilesWanted[i].isLODTile == this.tilesDrawn[j].isLODTile && this.tilesWanted[i].LODLevel == this.tilesDrawn[j].LODLevel && this.tilesDrawn[j].outdated != true) {\n matched = true;\n break;\n }\n }\n\n for (var j = 0; j < this.tilesToBeDrawn.length; j++) {\n if (this.tilesWanted[i].x == this.tilesToBeDrawn[j].x && this.tilesWanted[i].y == this.tilesToBeDrawn[j].y && this.tilesWanted[i].z == this.tilesToBeDrawn[j].z && this.tilesWanted[i].isLODTile == this.tilesToBeDrawn[j].isLODTile && this.tilesWanted[i].LODLevel == this.tilesToBeDrawn[j].LODLevel) {\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n this.tilesToBeDrawn.push(this.tilesWanted[i]);\n }\n }\n\n if (this.tilesToBeDrawn.length > 0) {\n var failCallback_1 = function () {\n if (_this.tilesToBeDrawn.length > 0) {\n _this.addTile(_this.tilesToBeDrawn.pop(), failCallback_1).catch(function () {\n failCallback_1();\n });\n }\n };\n\n this.addTile(this.tilesToBeDrawn.pop(), failCallback_1).catch(function () {\n failCallback_1();\n });\n }\n\n if (this.tilesToBeDrawn.length == 0 && this.tilesBeingDrawn.length == 0 || false && false) {\n for (var i = 0; i < this.tilesDrawn.length; i++) {\n var matched = false;\n\n for (var j = 0; j < this.tilesWanted.length; j++) {\n if (this.tilesDrawn[i].x == this.tilesWanted[j].x && this.tilesDrawn[i].y == this.tilesWanted[j].y && this.tilesDrawn[i].z == this.tilesWanted[j].z && this.tilesDrawn[i].isLODTile == this.tilesWanted[j].isLODTile && this.tilesDrawn[i].LODLevel == this.tilesWanted[j].LODLevel) {\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n this.removeTile(i, true);\n }\n }\n\n this.removeAllOutdatedTiles();\n }\n\n if (this.tilesToBeDrawn.length == 0) {\n if (!this.p._.firstLoad) {\n this.p._onFirstLoad();\n }\n }\n\n var spinner = document.getElementById(this.p.options.loadingSpinnerId);\n var percent = document.getElementById(this.p.options.loadingPercentId);\n\n if (this.tilesToBeDrawn.length == 0) {\n if (spinner) spinner.style.opacity = '0';\n } else if (spinner && spinner.style.opacity == '0') {\n spinner.style.opacity = '1';\n }\n\n if (percent) percent.innerHTML = this.tilesToBeDrawn.length;\n this.filterEffects();\n this.fadeInTiles();\n this.fadeOutTiles();\n };\n\n TiledWorld.prototype.updateDesiredTiles = function () {\n this.tilesWanted = [];\n var center = this.p.getCenter();\n var projectedXYZ = this.p.projection.latLngZ2TileXYZ(center.lat, center.lng, this.p.zoom);\n var xCenter = projectedXYZ.x;\n var yCenter = projectedXYZ.y;\n var r = this.p.options.radiusOfTiles;\n var d;\n\n for (var x = xCenter - r + 1; x < xCenter + r; x++) {\n for (var y = yCenter - r + 1; y < yCenter + r; y++) {\n d = Math.pow(x - xCenter, 2) + Math.pow(y - yCenter, 2);\n\n if (d <= r * r) {\n this.tilesWanted.push({\n x: this.p.projection.tileMapResource.proj ? parseInt(x) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(x, Math.pow(2, this.p.zoom)),\n y: this.p.projection.tileMapResource.proj ? parseInt(y) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(y, Math.pow(2, this.p.zoom)),\n z: this.p.zoom,\n d: d,\n make: true,\n isLODTile: false\n });\n }\n }\n }\n\n var lastZ = null;\n\n if (this.p.options.useLOD) {\n for (var i = 0; i < this.p.options.LOD.length; i++) {\n var lr = this.p.options.LOD[i].radiusOfTiles;\n var z = Math.max(this.p._.minNativeZoom, this.p.zoom - this.p.options.LOD[i].zoomsUp);\n if (z == lastZ) break;\n lastZ = z;\n if (Math.abs(z - this.p.zoom) <= 1) continue;\n projectedXYZ = this.p.projection.latLngZ2TileXYZ(center.lat, center.lng, z);\n xCenter = projectedXYZ.x;\n yCenter = projectedXYZ.y;\n\n for (var x = xCenter - lr + 1; x < xCenter + lr; x++) {\n for (var y = yCenter - lr + 1; y < yCenter + lr; y++) {\n d = Math.pow(x - xCenter, 2) + Math.pow(y - yCenter, 2);\n\n if (d <= lr * lr) {\n this.tilesWanted.push({\n x: this.p.projection.tileMapResource.proj ? parseInt(x) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(x, Math.pow(2, z)),\n y: this.p.projection.tileMapResource.proj ? parseInt(y) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(y, Math.pow(2, z)),\n z: z,\n d: d,\n make: true,\n isLODTile: true,\n LODLevel: i\n });\n }\n }\n }\n }\n }\n\n this.tilesWanted.sort(function (a, b) {\n return b.d - a.d;\n });\n this.tilesWanted.sort(function (a, b) {\n var aLODLevel = a.isLODTile ? a.LODLevel : -1;\n var bLODLevel = b.isLODTile ? b.LODLevel : -1;\n return bLODLevel - aLODLevel;\n });\n };\n\n TiledWorld.prototype.addTile = function (xyz, failCallback) {\n return __awaiter(this, void 0, void 0, function () {\n var tileLoaded, t, onceTileLoaded, tileGeometry, loadDemTile, layerI, i, heightArr, builtDemPath, errored_1, builtDemPathFallback, builtDemPathFallback;\n\n var _this = this;\n\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (xyz === undefined) return [2];\n tileLoaded = {\n raster: false,\n data: false\n };\n t = new three__WEBPACK_IMPORTED_MODULE_1__[\"Mesh\"](new three__WEBPACK_IMPORTED_MODULE_1__[\"PlaneBufferGeometry\"](this._.tileDimension, this._.tileDimension, this.p.options.tileResolution - 1, this.p.options.tileResolution - 1), new three__WEBPACK_IMPORTED_MODULE_1__[\"MeshBasicMaterial\"]({\n visible: false\n }));\n this.tilesBeingDrawn.push({\n x: xyz.x,\n y: xyz.y,\n z: xyz.z,\n isLODTile: xyz.isLODTile,\n LODLevel: xyz.LODLevel,\n make: xyz.make\n });\n this.tilesDrawn.push({\n x: xyz.x,\n y: xyz.y,\n z: xyz.z,\n isLODTile: xyz.isLODTile,\n LODLevel: xyz.LODLevel,\n t: t,\n contents: [],\n from: {\n dems: [],\n rasters: [],\n data: []\n }\n });\n\n onceTileLoaded = function (destroy) {\n if (destroy) {\n t.geometry.dispose();\n t.material.dispose();\n if (typeof failCallback === 'function') failCallback();\n }\n\n if (tileLoaded.data) {\n var differentZoomTilesToRemove = [];\n\n if (_this.p._.events._.lastZoomDelta <= 2) {\n for (var i = _this.tilesDrawn.length - 1; i >= 0; i--) {\n if (xyz.isLODTile == _this.tilesDrawn[i].isLODTile && xyz.LODLevel == _this.tilesDrawn[i].LODLevel) {\n var drawnXYZ = [_this.tilesDrawn[i].x, _this.tilesDrawn[i].y, _this.tilesDrawn[i].z];\n var thisXYZ = [xyz.x, xyz.y, xyz.z];\n\n if (xyz.z < _this.tilesDrawn[i].z) {\n if (_utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileIsContained(thisXYZ, drawnXYZ, true)) {\n differentZoomTilesToRemove.push(i);\n }\n } else if (xyz.z > _this.tilesDrawn[i].z) {\n if (_utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileIsContained(drawnXYZ, thisXYZ)) {\n _this.tilesDrawn[i].contents.push(thisXYZ);\n\n if (_this.tilesDrawn[i].contents.length >= _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileContains(drawnXYZ, xyz.z).length) {\n differentZoomTilesToRemove.push(i);\n }\n }\n }\n }\n }\n }\n\n for (var i = _this.tilesBeingDrawn.length - 1; i >= 0; i--) {\n if (_this.tilesBeingDrawn[i].x == xyz.x && _this.tilesBeingDrawn[i].y == xyz.y && _this.tilesBeingDrawn[i].z == xyz.z && _this.tilesBeingDrawn[i].isLODTile == xyz.isLODTile && _this.tilesBeingDrawn[i].LODLevel == xyz.LODLevel) {\n if (_this.tilesBeingDrawn[i].make) {\n if (xyz.isLODTile) {\n _this.p.planetsLOD[xyz.LODLevel].add(t);\n } else {\n _this.p.planet.add(t);\n }\n\n _this.updateRastersForTile(xyz);\n\n differentZoomTilesToRemove.forEach(function (tileI) {\n _this.removeTile(tileI, true);\n });\n } else {\n t.geometry.dispose();\n t.material.dispose();\n\n for (var j = _this.tilesDrawn.length - 1; j >= 0; j--) {\n if (_this.tilesDrawn[j].x == xyz.x && _this.tilesDrawn[j].y == xyz.y && _this.tilesDrawn[j].z == xyz.z && _this.tilesDrawn[i].isLODTile == xyz.isLODTile && _this.tilesDrawn[i].LODLevel == xyz.LODLevel) {\n _this.tilesDrawn.splice(j, 1);\n }\n }\n }\n\n _this.tilesBeingDrawn.splice(i, 1);\n\n return;\n }\n }\n }\n };\n\n tileGeometry = function (heightArr) {\n var cnt = 0;\n var verts = Math.pow(_this.p.options.tileResolution, 2);\n var colors = new Float32Array(verts * 3);\n\n if (heightArr == null) {\n heightArr = new Array(verts).fill(0);\n }\n\n var centerHeight = 0;\n var centerCnt = Math.floor(heightArr.length / 2);\n var counter = 0;\n\n while ((centerHeight == null || centerHeight > _this.p.projection.radiusOfPlanetMajor || centerHeight < -_this.p.projection.radiusOfPlanetMajor) && counter < heightArr.length) {\n centerHeight = heightArr[centerCnt];\n counter++;\n }\n\n var centerP = Math.floor(t.geometry.attributes.position.array.length / 6) * 3;\n var tx = xyz.x + centerP / 3 % _this.p.options.tileResolution / (_this.p.options.tileResolution - 1);\n var ty = xyz.y + Math.floor(centerP / 3 / _this.p.options.tileResolution) / (_this.p.options.tileResolution - 1);\n\n var projectedLL = _this.p.projection.tileXYZ2LatLng(tx, ty, xyz.z);\n\n var tlat = projectedLL.lat;\n var tlon = projectedLL.lng;\n var centerLat = tlat;\n\n var centerPos = _this.p.projection.lonLatToVector3(tlon, tlat, centerHeight * _this.p.options.exaggeration);\n\n t.position.set(centerPos.x, centerPos.y, centerPos.z);\n\n if (t.geometry.attributes.position.array.length / 3 == verts) {\n var height = 0;\n var xyzPos = void 0;\n\n for (var p = 0; p < t.geometry.attributes.position.array.length; p += 3) {\n height = heightArr[cnt] || 0;\n colors[p] = 0;\n colors[p + 1] = 0;\n colors[p + 2] = 0;\n height = Math.min(height, 100000);\n height = Math.max(height, -100000);\n var tx_1 = xyz.x + p / 3 % _this.p.options.tileResolution / (_this.p.options.tileResolution - 1);\n var ty_1 = xyz.y + Math.floor(p / 3 / _this.p.options.tileResolution) / (_this.p.options.tileResolution - 1);\n\n var projectedLL_1 = _this.p.projection.tileXYZ2LatLng(tx_1, ty_1, xyz.z, xyz);\n\n var tlat_1 = projectedLL_1.lat;\n var tlon_1 = projectedLL_1.lng;\n\n if (_this.p.zoom <= _this.p._.zCutOff) {\n if (centerLat > 75 && tlat_1 < -88) {\n tlat_1 = 90;\n } else if (centerLat < -75 && tlat_1 > 88) {\n tlat_1 = -90;\n }\n }\n\n xyzPos = _this.p.projection.lonLatToVector3(tlon_1, tlat_1, height * _this.p.options.exaggeration);\n t.geometry.attributes.position.array[p] = xyzPos.x - centerPos.x;\n t.geometry.attributes.position.array[p + 1] = xyzPos.y - centerPos.y;\n t.geometry.attributes.position.array[p + 2] = xyzPos.z - centerPos.z;\n cnt += 1;\n }\n\n t.geometry.attributes.position.needsUpdate = true;\n t.geometry.computeVertexNormals();\n t.geometry.computeBoundingSphere();\n t.geometry.setAttribute('customColor', new three__WEBPACK_IMPORTED_MODULE_1__[\"BufferAttribute\"](colors, 3));\n tileLoaded.data = true;\n onceTileLoaded();\n }\n };\n\n loadDemTile = false;\n layerI = null;\n\n for (i = this.p.layers.tile.length - 1; i >= 0; i--) {\n if (this.p.layers.tile[i].on && (xyz.z >= this.p.layers.tile[i].minZoom && xyz.z <= this.p.layers.tile[i].maxZoom && _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent(xyz, this.p.layers.tile[i].boundingBox, this.p.projection) || this.p.layers.tile[i].path == '_vectorsastile_')) {\n layerI = i;\n\n if (this.p.layers.tile[i].demPath != undefined) {\n loadDemTile = true;\n break;\n }\n }\n }\n\n heightArr = null;\n if (!(loadDemTile && layerI != null)) return [3, 4];\n builtDemPath = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.layers.tile[layerI].format, this.p.layers.tile[layerI].demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPath) return [3, 3];\n errored_1 = false;\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPath.path, this.p.layers.tile[layerI], builtDemPath.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2)).catch(function () {\n errored_1 = true;\n })];\n\n case 1:\n heightArr = _a.sent();\n if (!(errored_1 && this.p.options.demFallback != null)) return [3, 3];\n builtDemPathFallback = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.options.demFallback.format, this.p.options.demFallback.demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPathFallback) return [3, 3];\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPathFallback.path, this.p.layers.tile[layerI], builtDemPathFallback.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2), this.p.options.demFallback.parserType).catch(function () {})];\n\n case 2:\n heightArr = _a.sent();\n _a.label = 3;\n\n case 3:\n tileGeometry(heightArr || null);\n return [3, 7];\n\n case 4:\n if (!(this.p.options.demFallback != null)) return [3, 6];\n builtDemPathFallback = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.options.demFallback.format, this.p.options.demFallback.demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPathFallback) return [3, 6];\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPathFallback.path, this.p.layers.tile[layerI], builtDemPathFallback.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2), this.p.options.demFallback.parserType).catch(function () {})];\n\n case 5:\n heightArr = _a.sent();\n _a.label = 6;\n\n case 6:\n tileGeometry();\n _a.label = 7;\n\n case 7:\n return [2];\n }\n });\n });\n };\n\n TiledWorld.prototype.findTileDrawnBasedOnUUID = function (uuid) {\n var foundTile = null;\n this.tilesDrawn.forEach(function (tile) {\n if (tile.t.uuid === uuid) {\n foundTile = tile;\n return;\n }\n });\n return foundTile;\n };\n\n TiledWorld.prototype.findTileDrawnBasedOnXYZLOD = function (xyz) {\n var foundTile = null;\n this.tilesDrawn.forEach(function (tile) {\n if (tile.x === xyz.x && tile.y === xyz.y && tile.z === xyz.z && tile.isLODTile === xyz.isLODTile && tile.LODLevel == xyz.LODLevel) {\n foundTile = tile;\n return;\n }\n });\n return foundTile;\n };\n\n TiledWorld.prototype.updateRastersForTile = function (xyz) {\n var _this = this;\n\n var tD = this.findTileDrawnBasedOnXYZLOD(xyz);\n if (tD == null) return;\n var textures = [];\n var tileLayersComplete = new Array(this.p.layers.tile.length).fill(false);\n var clampedLayersComplete = new Array(this.p.layers.clamped.length).fill(false);\n\n var onceTexturesLoaded = function () {\n if (tileLayersComplete.every(Boolean) && (xyz.isLODTile || clampedLayersComplete.every(Boolean))) {\n if (textures.length == 0) {\n tD.t.visible = false;\n return;\n }\n\n textures.sort(function (a, b) {\n return a.i - b.i;\n });\n tD.from.rasters = [];\n var orderingI = 0;\n\n for (var i = 0; i < textures.length; i++) {\n if (textures[i].type == 'tile') {\n tD.from.rasters.push({\n name: textures[i].name,\n type: textures[i].type,\n texture: textures[i].texture,\n opacity: textures[i].opacity,\n isVAT: 0,\n filters: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n blendCode: 0,\n blend: 0\n },\n i: orderingI\n });\n orderingI++;\n }\n }\n\n for (var i = 0; i < textures.length; i++) {\n if (textures[i].type == 'clamped') {\n tD.from.rasters.push({\n name: textures[i].name,\n type: textures[i].type,\n texture: textures[i].texture,\n opacity: textures[i].opacity,\n isVAT: 1,\n filters: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n blendCode: 0,\n blend: 0\n },\n i: orderingI\n });\n orderingI++;\n }\n }\n\n tD.t.material = ___WEBPACK_IMPORTED_MODULE_0__[\"Shaders\"].multiTexture(tD.from.rasters);\n\n if (_this.p.options.wireframeMode) {\n tD.t.material = new three__WEBPACK_IMPORTED_MODULE_1__[\"MeshBasicMaterial\"]({\n color: 0xffffff,\n wireframe: true\n });\n }\n\n tD.t.material.needsUpdate = true;\n }\n };\n\n var _loop_1 = function (i) {\n if (this_1.p.layers.tile[i].on && tD.z >= this_1.p.layers.tile[i].minZoom && tD.z <= this_1.p.layers.tile[i].maxZoom && _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, this_1.p.layers.tile[i].boundingBox, this_1.p.projection)) {\n var builtPath_1 = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this_1.p.layers.tile[i].format, this_1.p.layers.tile[i].path, tD, this_1.p.projection, this_1.p.options.trueTileResolution, this_1.p.options.trueTileResolution, this_1.p.layers.tile[i].formatOptions);\n\n if (builtPath_1) {\n ;\n\n (function (i) {\n _this._.loader.load(builtPath_1, function (texture) {\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n if (_this.p.layers.tile[i]) textures.push({\n name: _this.p.layers.tile[i].name,\n type: 'tile',\n texture: texture,\n opacity: _this.p.layers.tile[i].opacity,\n i: i\n });\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }, function () {\n console.log('');\n }, function () {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n });\n })(i);\n } else {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n } else {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n };\n\n var this_1 = this;\n\n for (var i = 0; i < this.p.layers.tile.length; i++) {\n _loop_1(i);\n }\n\n if (!xyz.isLODTile) {\n for (var i = 0; i < this.p.layers.clamped.length; i++) {\n if (this.p.layers.clamped[i].on && (this.p.layers.clamped[i].minZoom == null || tD.z >= this.p.layers.clamped[i].minZoom) && (this.p.layers.clamped[i].maxZoom == null || tD.z <= this.p.layers.clamped[i].maxZoom) && (this.p.layers.clamped[i].boundingBox == null || _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, this.p.layers.clamped[i].boundingBox, this.p.projection))) {\n var clampedTexture = this.p.layers._.layerers.clamped.getClampedTexture(i, {\n x: tD.x,\n y: tD.y,\n z: tD.z\n });\n\n tD.contains = tD.contains || {};\n tD.contains[this.p.layers.clamped[i].name] = clampedTexture.features;\n var texture = new three__WEBPACK_IMPORTED_MODULE_1__[\"CanvasTexture\"](clampedTexture.canvas);\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n if (this.p.layers.clamped[i]) textures.push({\n name: this.p.layers.clamped[i].name,\n type: 'clamped',\n texture: texture,\n opacity: this.p.layers.clamped[i].opacity,\n i: i\n });\n clampedLayersComplete[i] = true;\n onceTexturesLoaded();\n } else {\n clampedLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n }\n }\n };\n\n TiledWorld.prototype.updateClampedRasterForTile = function (tD, layerName) {\n if (this.p.options.wireframeMode || tD.isLODTile) return;\n var clampedLayerI = null;\n\n for (var i = 0; i < this.p.layers.clamped.length; i++) {\n if (this.p.layers.clamped[i].name === layerName) {\n clampedLayerI = i;\n break;\n }\n }\n\n var clampedLayer = clampedLayerI != null ? this.p.layers.clamped[clampedLayerI] : null;\n\n if (clampedLayer && clampedLayer.on && (clampedLayer.minZoom == null || tD.z >= clampedLayer.minZoom) && (clampedLayer.maxZoom == null || tD.z <= clampedLayer.maxZoom) && (clampedLayer.boundingBox == null || _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, clampedLayer.boundingBox, this.p.projection))) {\n var clampedTexture = this.p.layers._.layerers.clamped.getClampedTexture(clampedLayerI, {\n x: tD.x,\n y: tD.y,\n z: tD.z\n });\n\n tD.contains = tD.contains || {};\n tD.contains[this.p.layers.clamped[clampedLayerI].name] = clampedTexture.features;\n var texture = new three__WEBPACK_IMPORTED_MODULE_1__[\"CanvasTexture\"](clampedTexture.canvas);\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n\n for (var i = 0; i < tD.from.rasters.length; i++) {\n if (tD.from.rasters[i].name === layerName) {\n tD.from.rasters[i].texture = texture;\n break;\n }\n }\n\n tD.t.material = ___WEBPACK_IMPORTED_MODULE_0__[\"Shaders\"].multiTexture(tD.from.rasters);\n tD.t.material.needsUpdate = true;\n }\n };\n\n TiledWorld.prototype.updateAllRasters = function () {\n this.killDrawingTiles();\n var startingLength = this.tilesDrawn.length;\n\n for (var j = 0; j < startingLength; j++) {\n var tD = this.tilesDrawn[j];\n this.updateRastersForTile({\n x: tD.x,\n y: tD.y,\n z: tD.z,\n isLODTile: tD.isLODTile,\n LODLevel: tD.LODLevel\n });\n }\n };\n\n TiledWorld.prototype.removeTile = function (i, shouldFadeOut) {\n shouldFadeOut = false;\n\n if (this.tilesDrawn[i]) {\n if (shouldFadeOut) {\n this.tilesDrawn[i].fadeOutAndRemove = true;\n } else {\n this.tilesDrawn[i].t.geometry.dispose();\n this.tilesDrawn[i].t.material.dispose();\n if (this.tilesDrawn[i].isLODTile) this.p.planetsLOD[this.tilesDrawn[i].LODLevel].remove(this.tilesDrawn[i].t);else this.p.planet.remove(this.tilesDrawn[i].t);\n this.tilesDrawn.splice(i, 1);\n }\n }\n };\n\n TiledWorld.prototype.removeAllTiles = function () {\n this.killDrawingTiles();\n\n for (var j = 0; j < this.tilesDrawn.length; j++) {\n this.removeTile(0);\n }\n };\n\n TiledWorld.prototype.outdateAllTiles = function () {\n this.killDrawingTiles();\n this.tilesDrawn.forEach(function (tile) {\n tile.outdated = true;\n });\n };\n\n TiledWorld.prototype.removeAllOutdatedTiles = function () {\n var _this = this;\n\n var outdatedTileIndices = [];\n this.tilesDrawn.forEach(function (t, i) {\n if (t.outdated) outdatedTileIndices.push(i);\n });\n outdatedTileIndices = outdatedTileIndices.sort().reverse();\n outdatedTileIndices.forEach(function (i) {\n _this.removeTile(i);\n });\n };\n\n TiledWorld.prototype.removeTileXYZ = function (xyz) {\n for (var t in this.tilesDrawn) {\n if (this.tilesDrawn[t].x == xyz.x && this.tilesDrawn[t].y == xyz.y && this.tilesDrawn[t].z == xyz.z) {\n this.tilesDrawn[t].t.geometry.dispose();\n this.tilesDrawn[t].t.material.dispose();\n if (this.tilesDrawn[t].isLODTile) this.p.planetsLOD[this.tilesDrawn[t].LODLevel].remove(this.tilesDrawn[t].t);else this.p.planet.remove(this.tilesDrawn[t].t);\n this.tilesDrawn.splice(t, 1);\n }\n }\n };\n\n TiledWorld.prototype.killDrawingTiles = function () {\n for (var t in this.tilesToBeDrawn) {\n this.tilesToBeDrawn[t].make = false;\n }\n\n for (var t in this.tilesBeingDrawn) {\n this.tilesBeingDrawn[t].make = false;\n }\n };\n\n TiledWorld.prototype.filterEffects = function () {\n var _this = this;\n\n var transitionFilters = ['brightness', 'contrast', 'saturation', 'blendCode'];\n\n var _loop_2 = function (m) {\n var _loop_3 = function (n) {\n if (this_2.tilesDrawn[m] && this_2.tilesDrawn[m].t && this_2.tilesDrawn[m].t.material.hasOwnProperty('uniforms')) {\n var layer_1 = this_2.p.layers.getLayerByName(this_2.tilesDrawn[m].from.rasters[n].name);\n\n if (layer_1 && layer_1.filters) {\n transitionFilters.forEach(function (f) {\n var desiredFilter = layer_1.filters[f];\n if (desiredFilter == null) return;\n var currentFilter = _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value;\n\n if (f == 'blendCode') {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = desiredFilter;\n } else if (desiredFilter > currentFilter) {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = Math.min(_this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value + 0.1, desiredFilter);\n } else {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = Math.max(_this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value - 0.1, desiredFilter);\n }\n });\n }\n }\n };\n\n for (var n in this_2.tilesDrawn[m].from.rasters) {\n _loop_3(n);\n }\n };\n\n var this_2 = this;\n\n for (var m in this.tilesDrawn) {\n _loop_2(m);\n }\n };\n\n TiledWorld.prototype.fadeInTiles = function () {\n for (var m in this.tilesDrawn) {\n if (!this.tilesDrawn[m].fadeOutAndRemove) for (var n in this.tilesDrawn[m].from.rasters) {\n if (this.tilesDrawn[m] && this.tilesDrawn[m].t && this.tilesDrawn[m].t.material.hasOwnProperty('uniforms')) {\n var layer = this.p.layers.getLayerByName(this.tilesDrawn[m].from.rasters[n].name);\n\n if (layer) {\n var desiredOpacity = layer.opacity;\n var currentOpacity = this.tilesDrawn[m].t.material.uniforms['tA' + n].value;\n\n if (desiredOpacity > currentOpacity) {\n this.tilesDrawn[m].t.material.uniforms['tA' + n].value = Math.min(this.tilesDrawn[m].t.material.uniforms['tA' + n].value + 0.1, desiredOpacity);\n } else {\n this.tilesDrawn[m].t.material.uniforms['tA' + n].value = Math.max(this.tilesDrawn[m].t.material.uniforms['tA' + n].value - 0.1, desiredOpacity);\n }\n }\n }\n }\n }\n };\n\n TiledWorld.prototype.fadeOutTiles = function () {\n for (var i = this.tilesDrawn.length - 1; i >= 0; i--) {\n if (this.tilesDrawn[i].fadeOutAndRemove) {\n for (var n = 0; this.tilesDrawn[i] && n < this.tilesDrawn[i].from.rasters.length; n++) {\n if (this.tilesDrawn[i] && this.tilesDrawn[i].t && this.tilesDrawn[i].t.material.hasOwnProperty('uniforms') && this.tilesDrawn[i].t.material.uniforms['tA' + n] != null) {\n var nextOpacity = Math.max(this.tilesDrawn[i].t.material.uniforms['tA' + n].value - 0.1, 0);\n if (nextOpacity <= 0) this.removeTile(i);else {\n this.tilesDrawn[i].t.material.uniforms['tA' + n].value = nextOpacity;\n }\n } else {\n this.removeTile(i);\n }\n }\n }\n }\n };\n\n return TiledWorld;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (TiledWorld);\n\n//# sourceURL=webpack://LithoSphere/./src/core/tiledWorld.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ */ \"./src/core/index.ts\");\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _parsers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../parsers */ \"./src/parsers/index.ts\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ \"./src/utils/index.ts\");\n/* harmony import */ var _utils_paths__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/paths */ \"./src/utils/paths.ts\");\nvar __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P ? value : new P(function (resolve) {\n resolve(value);\n });\n }\n\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n\n function step(result) {\n result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n }\n\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n\nvar __generator = undefined && undefined.__generator || function (thisArg, body) {\n var _ = {\n label: 0,\n sent: function () {\n if (t[0] & 1) throw t[1];\n return t[1];\n },\n trys: [],\n ops: []\n },\n f,\n y,\n t,\n g;\n return g = {\n next: verb(0),\n \"throw\": verb(1),\n \"return\": verb(2)\n }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function () {\n return this;\n }), g;\n\n function verb(n) {\n return function (v) {\n return step([n, v]);\n };\n }\n\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n\n while (_) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n\n switch (op[0]) {\n case 0:\n case 1:\n t = op;\n break;\n\n case 4:\n _.label++;\n return {\n value: op[1],\n done: false\n };\n\n case 5:\n _.label++;\n y = op[1];\n op = [0];\n continue;\n\n case 7:\n op = _.ops.pop();\n\n _.trys.pop();\n\n continue;\n\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n _ = 0;\n continue;\n }\n\n if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n _.label = op[1];\n break;\n }\n\n if (op[0] === 6 && _.label < t[1]) {\n _.label = t[1];\n t = op;\n break;\n }\n\n if (t && _.label < t[2]) {\n _.label = t[2];\n\n _.ops.push(op);\n\n break;\n }\n\n if (t[2]) _.ops.pop();\n\n _.trys.pop();\n\n continue;\n }\n\n op = body.call(thisArg, _);\n } catch (e) {\n op = [6, e];\n y = 0;\n } finally {\n f = t = 0;\n }\n\n if (op[0] & 5) throw op[1];\n return {\n value: op[0] ? op[1] : void 0,\n done: true\n };\n }\n};\n\n\n\n\n\n\n\nvar TiledWorld = function () {\n function TiledWorld(parent) {\n this.p = parent;\n\n this._reset();\n }\n\n TiledWorld.prototype._reset = function () {\n this._ = {\n loader: new three__WEBPACK_IMPORTED_MODULE_1__[\"TextureLoader\"](),\n tileDimension: 6\n };\n this.tilesDrawn = [];\n this.tilesWanted = [];\n this.tilesToBeDrawn = [];\n this.tilesBeingDrawn = [];\n };\n\n TiledWorld.prototype.refreshTiles = function () {\n var _this = this;\n\n this.updateDesiredTiles();\n this.tilesToBeDrawn = [];\n\n for (var i = 0; i < this.tilesWanted.length; i++) {\n var matched = false;\n\n for (var j = 0; j < this.tilesDrawn.length; j++) {\n if (this.tilesWanted[i].x == this.tilesDrawn[j].x && this.tilesWanted[i].y == this.tilesDrawn[j].y && this.tilesWanted[i].z == this.tilesDrawn[j].z && this.tilesWanted[i].isLODTile == this.tilesDrawn[j].isLODTile && this.tilesWanted[i].LODLevel == this.tilesDrawn[j].LODLevel && this.tilesDrawn[j].outdated != true) {\n matched = true;\n break;\n }\n }\n\n for (var j = 0; j < this.tilesToBeDrawn.length; j++) {\n if (this.tilesWanted[i].x == this.tilesToBeDrawn[j].x && this.tilesWanted[i].y == this.tilesToBeDrawn[j].y && this.tilesWanted[i].z == this.tilesToBeDrawn[j].z && this.tilesWanted[i].isLODTile == this.tilesToBeDrawn[j].isLODTile && this.tilesWanted[i].LODLevel == this.tilesToBeDrawn[j].LODLevel) {\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n this.tilesToBeDrawn.push(this.tilesWanted[i]);\n }\n }\n\n if (this.tilesToBeDrawn.length > 0) {\n var failCallback_1 = function () {\n if (_this.tilesToBeDrawn.length > 0) {\n _this.addTile(_this.tilesToBeDrawn.pop(), failCallback_1).catch(function () {\n failCallback_1();\n });\n }\n };\n\n this.addTile(this.tilesToBeDrawn.pop(), failCallback_1).catch(function () {\n failCallback_1();\n });\n }\n\n if (this.tilesToBeDrawn.length == 0 && this.tilesBeingDrawn.length == 0 || false && false) {\n for (var i = 0; i < this.tilesDrawn.length; i++) {\n var matched = false;\n\n for (var j = 0; j < this.tilesWanted.length; j++) {\n if (this.tilesDrawn[i].x == this.tilesWanted[j].x && this.tilesDrawn[i].y == this.tilesWanted[j].y && this.tilesDrawn[i].z == this.tilesWanted[j].z && this.tilesDrawn[i].isLODTile == this.tilesWanted[j].isLODTile && this.tilesDrawn[i].LODLevel == this.tilesWanted[j].LODLevel) {\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n this.removeTile(i, true);\n }\n }\n\n this.removeAllOutdatedTiles();\n }\n\n if (this.tilesToBeDrawn.length == 0) {\n if (!this.p._.firstLoad) {\n this.p._onFirstLoad();\n }\n }\n\n var spinner = document.getElementById(this.p.options.loadingSpinnerId);\n var percent = document.getElementById(this.p.options.loadingPercentId);\n\n if (this.tilesToBeDrawn.length == 0) {\n if (spinner) spinner.style.opacity = '0';\n } else if (spinner && spinner.style.opacity == '0') {\n spinner.style.opacity = '1';\n }\n\n if (percent) percent.innerHTML = this.tilesToBeDrawn.length;\n this.filterEffects();\n this.fadeInTiles();\n this.fadeOutTiles();\n };\n\n TiledWorld.prototype.updateDesiredTiles = function () {\n this.tilesWanted = [];\n var center = this.p.getCenter();\n var projectedXYZ = this.p.projection.latLngZ2TileXYZ(center.lat, center.lng, this.p.zoom);\n var xCenter = projectedXYZ.x;\n var yCenter = projectedXYZ.y;\n var r = this.p.options.radiusOfTiles;\n var d;\n\n for (var x = xCenter - r + 1; x < xCenter + r; x++) {\n for (var y = yCenter - r + 1; y < yCenter + r; y++) {\n d = Math.pow(x - xCenter, 2) + Math.pow(y - yCenter, 2);\n\n if (d <= r * r) {\n this.tilesWanted.push({\n x: this.p.projection.tileMapResource.proj ? parseInt(x) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(x, Math.pow(2, this.p.zoom)),\n y: this.p.projection.tileMapResource.proj ? parseInt(y) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(y, Math.pow(2, this.p.zoom)),\n z: this.p.zoom,\n d: d,\n make: true,\n isLODTile: false\n });\n }\n }\n }\n\n var lastZ = null;\n\n if (this.p.options.useLOD) {\n for (var i = 0; i < this.p.options.LOD.length; i++) {\n var lr = this.p.options.LOD[i].radiusOfTiles;\n var z = Math.max(this.p._.minNativeZoom, this.p.zoom - this.p.options.LOD[i].zoomsUp);\n if (z == lastZ) break;\n lastZ = z;\n if (Math.abs(z - this.p.zoom) <= 1) continue;\n projectedXYZ = this.p.projection.latLngZ2TileXYZ(center.lat, center.lng, z);\n xCenter = projectedXYZ.x;\n yCenter = projectedXYZ.y;\n\n for (var x = xCenter - lr + 1; x < xCenter + lr; x++) {\n for (var y = yCenter - lr + 1; y < yCenter + lr; y++) {\n d = Math.pow(x - xCenter, 2) + Math.pow(y - yCenter, 2);\n\n if (d <= lr * lr) {\n this.tilesWanted.push({\n x: this.p.projection.tileMapResource.proj ? parseInt(x) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(x, Math.pow(2, z)),\n y: this.p.projection.tileMapResource.proj ? parseInt(y) : _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].mod(y, Math.pow(2, z)),\n z: z,\n d: d,\n make: true,\n isLODTile: true,\n LODLevel: i\n });\n }\n }\n }\n }\n }\n\n this.tilesWanted.sort(function (a, b) {\n return b.d - a.d;\n });\n this.tilesWanted.sort(function (a, b) {\n var aLODLevel = a.isLODTile ? a.LODLevel : -1;\n var bLODLevel = b.isLODTile ? b.LODLevel : -1;\n return bLODLevel - aLODLevel;\n });\n };\n\n TiledWorld.prototype.addTile = function (xyz, failCallback) {\n return __awaiter(this, void 0, void 0, function () {\n var tileLoaded, t, onceTileLoaded, tileGeometry, loadDemTile, layerI, i, heightArr, builtDemPath, errored_1, builtDemPathFallback, builtDemPathFallback;\n\n var _this = this;\n\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (xyz === undefined) return [2];\n tileLoaded = {\n raster: false,\n data: false\n };\n t = new three__WEBPACK_IMPORTED_MODULE_1__[\"Mesh\"](new three__WEBPACK_IMPORTED_MODULE_1__[\"PlaneBufferGeometry\"](this._.tileDimension, this._.tileDimension, this.p.options.tileResolution - 1, this.p.options.tileResolution - 1), new three__WEBPACK_IMPORTED_MODULE_1__[\"MeshBasicMaterial\"]({\n visible: false\n }));\n this.tilesBeingDrawn.push({\n x: xyz.x,\n y: xyz.y,\n z: xyz.z,\n isLODTile: xyz.isLODTile,\n LODLevel: xyz.LODLevel,\n make: xyz.make\n });\n this.tilesDrawn.push({\n x: xyz.x,\n y: xyz.y,\n z: xyz.z,\n isLODTile: xyz.isLODTile,\n LODLevel: xyz.LODLevel,\n t: t,\n contents: [],\n from: {\n dems: [],\n rasters: [],\n data: []\n }\n });\n\n onceTileLoaded = function (destroy) {\n if (destroy) {\n t.geometry.dispose();\n t.material.dispose();\n if (typeof failCallback === 'function') failCallback();\n }\n\n if (tileLoaded.data) {\n var differentZoomTilesToRemove = [];\n\n if (_this.p._.events._.lastZoomDelta <= 2) {\n for (var i = _this.tilesDrawn.length - 1; i >= 0; i--) {\n if (xyz.isLODTile == _this.tilesDrawn[i].isLODTile && xyz.LODLevel == _this.tilesDrawn[i].LODLevel) {\n var drawnXYZ = [_this.tilesDrawn[i].x, _this.tilesDrawn[i].y, _this.tilesDrawn[i].z];\n var thisXYZ = [xyz.x, xyz.y, xyz.z];\n\n if (xyz.z < _this.tilesDrawn[i].z) {\n if (_utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileIsContained(thisXYZ, drawnXYZ, true)) {\n differentZoomTilesToRemove.push(i);\n }\n } else if (xyz.z > _this.tilesDrawn[i].z) {\n if (_utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileIsContained(drawnXYZ, thisXYZ)) {\n _this.tilesDrawn[i].contents.push(thisXYZ);\n\n if (_this.tilesDrawn[i].contents.length >= _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].tileContains(drawnXYZ, xyz.z).length) {\n differentZoomTilesToRemove.push(i);\n }\n }\n }\n }\n }\n }\n\n for (var i = _this.tilesBeingDrawn.length - 1; i >= 0; i--) {\n if (_this.tilesBeingDrawn[i].x == xyz.x && _this.tilesBeingDrawn[i].y == xyz.y && _this.tilesBeingDrawn[i].z == xyz.z && _this.tilesBeingDrawn[i].isLODTile == xyz.isLODTile && _this.tilesBeingDrawn[i].LODLevel == xyz.LODLevel) {\n if (_this.tilesBeingDrawn[i].make) {\n if (xyz.isLODTile) {\n _this.p.planetsLOD[xyz.LODLevel].add(t);\n } else {\n _this.p.planet.add(t);\n }\n\n _this.updateRastersForTile(xyz);\n\n differentZoomTilesToRemove.forEach(function (tileI) {\n _this.removeTile(tileI, true);\n });\n } else {\n t.geometry.dispose();\n t.material.dispose();\n\n for (var j = _this.tilesDrawn.length - 1; j >= 0; j--) {\n if (_this.tilesDrawn[j].x == xyz.x && _this.tilesDrawn[j].y == xyz.y && _this.tilesDrawn[j].z == xyz.z && _this.tilesDrawn[i].isLODTile == xyz.isLODTile && _this.tilesDrawn[i].LODLevel == xyz.LODLevel) {\n _this.tilesDrawn.splice(j, 1);\n }\n }\n }\n\n _this.tilesBeingDrawn.splice(i, 1);\n\n return;\n }\n }\n }\n };\n\n tileGeometry = function (heightArr) {\n var cnt = 0;\n var verts = Math.pow(_this.p.options.tileResolution, 2);\n var colors = new Float32Array(verts * 3);\n\n if (heightArr == null) {\n heightArr = new Array(verts).fill(0);\n }\n\n var centerHeight = 0;\n var centerCnt = Math.floor(heightArr.length / 2);\n var counter = 0;\n\n while ((centerHeight == null || centerHeight > _this.p.projection.radiusOfPlanetMajor || centerHeight < -_this.p.projection.radiusOfPlanetMajor) && counter < heightArr.length) {\n centerHeight = heightArr[centerCnt];\n counter++;\n }\n\n var centerP = Math.floor(t.geometry.attributes.position.array.length / 6) * 3;\n var tx = xyz.x + centerP / 3 % _this.p.options.tileResolution / (_this.p.options.tileResolution - 1);\n var ty = xyz.y + Math.floor(centerP / 3 / _this.p.options.tileResolution) / (_this.p.options.tileResolution - 1);\n\n var projectedLL = _this.p.projection.tileXYZ2LatLng(tx, ty, xyz.z);\n\n var tlat = projectedLL.lat;\n var tlon = projectedLL.lng;\n var centerLat = tlat;\n\n var centerPos = _this.p.projection.lonLatToVector3(tlon, tlat, centerHeight * _this.p.options.exaggeration);\n\n t.position.set(centerPos.x, centerPos.y, centerPos.z);\n\n if (t.geometry.attributes.position.array.length / 3 == verts) {\n var height = 0;\n var xyzPos = void 0;\n\n for (var p = 0; p < t.geometry.attributes.position.array.length; p += 3) {\n height = heightArr[cnt] || 0;\n colors[p] = 0;\n colors[p + 1] = 0;\n colors[p + 2] = 0;\n height = Math.min(height, 100000);\n height = Math.max(height, -100000);\n var tx_1 = xyz.x + p / 3 % _this.p.options.tileResolution / (_this.p.options.tileResolution - 1);\n var ty_1 = xyz.y + Math.floor(p / 3 / _this.p.options.tileResolution) / (_this.p.options.tileResolution - 1);\n\n var projectedLL_1 = _this.p.projection.tileXYZ2LatLng(tx_1, ty_1, xyz.z, xyz);\n\n var tlat_1 = projectedLL_1.lat;\n var tlon_1 = projectedLL_1.lng;\n\n if (_this.p.zoom <= _this.p._.zCutOff) {\n if (centerLat > 75 && tlat_1 < -88) {\n tlat_1 = 90;\n } else if (centerLat < -75 && tlat_1 > 88) {\n tlat_1 = -90;\n }\n }\n\n xyzPos = _this.p.projection.lonLatToVector3(tlon_1, tlat_1, height * _this.p.options.exaggeration);\n t.geometry.attributes.position.array[p] = xyzPos.x - centerPos.x;\n t.geometry.attributes.position.array[p + 1] = xyzPos.y - centerPos.y;\n t.geometry.attributes.position.array[p + 2] = xyzPos.z - centerPos.z;\n cnt += 1;\n }\n\n t.geometry.attributes.position.needsUpdate = true;\n t.geometry.computeVertexNormals();\n t.geometry.computeBoundingSphere();\n t.geometry.setAttribute('customColor', new three__WEBPACK_IMPORTED_MODULE_1__[\"BufferAttribute\"](colors, 3));\n tileLoaded.data = true;\n onceTileLoaded();\n }\n };\n\n loadDemTile = false;\n layerI = null;\n\n for (i = this.p.layers.tile.length - 1; i >= 0; i--) {\n if (this.p.layers.tile[i].on && (xyz.z >= this.p.layers.tile[i].minZoom && xyz.z <= this.p.layers.tile[i].maxZoom && _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent(xyz, this.p.layers.tile[i].boundingBox, this.p.projection) && _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtentEN(xyz, this.p.layers.tile[i].boundingBoxEN, this.p.projection) || this.p.layers.tile[i].path == '_vectorsastile_')) {\n layerI = i;\n\n if (this.p.layers.tile[i].demPath != undefined) {\n loadDemTile = true;\n break;\n }\n }\n }\n\n heightArr = null;\n if (!(loadDemTile && layerI != null)) return [3, 4];\n builtDemPath = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.layers.tile[layerI].format, this.p.layers.tile[layerI].demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPath) return [3, 3];\n errored_1 = false;\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPath.path, this.p.layers.tile[layerI], builtDemPath.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2)).catch(function () {\n errored_1 = true;\n })];\n\n case 1:\n heightArr = _a.sent();\n if (!(errored_1 && this.p.options.demFallback != null)) return [3, 3];\n builtDemPathFallback = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.options.demFallback.format, this.p.options.demFallback.demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPathFallback) return [3, 3];\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPathFallback.path, this.p.layers.tile[layerI], builtDemPathFallback.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2), this.p.options.demFallback.parserType).catch(function () {})];\n\n case 2:\n heightArr = _a.sent();\n _a.label = 3;\n\n case 3:\n tileGeometry(heightArr || null);\n return [3, 7];\n\n case 4:\n if (!(this.p.options.demFallback != null)) return [3, 6];\n builtDemPathFallback = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this.p.options.demFallback.format, this.p.options.demFallback.demPath, xyz, this.p.projection, this.p.options.tileResolution, this.p.options.trueTileResolution, this.p.layers.tile[layerI].demFormatOptions, true);\n if (!builtDemPathFallback) return [3, 6];\n return [4, Object(_parsers__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(this.p.options.customParsers, builtDemPathFallback.path, this.p.layers.tile[layerI], builtDemPathFallback.xyz, this.p.options.tileResolution, Math.pow(this.p.options.tileResolution, 2), this.p.options.demFallback.parserType).catch(function () {})];\n\n case 5:\n heightArr = _a.sent();\n _a.label = 6;\n\n case 6:\n tileGeometry();\n _a.label = 7;\n\n case 7:\n return [2];\n }\n });\n });\n };\n\n TiledWorld.prototype.findTileDrawnBasedOnUUID = function (uuid) {\n var foundTile = null;\n this.tilesDrawn.forEach(function (tile) {\n if (tile.t.uuid === uuid) {\n foundTile = tile;\n return;\n }\n });\n return foundTile;\n };\n\n TiledWorld.prototype.findTileDrawnBasedOnXYZLOD = function (xyz) {\n var foundTile = null;\n this.tilesDrawn.forEach(function (tile) {\n if (tile.x === xyz.x && tile.y === xyz.y && tile.z === xyz.z && tile.isLODTile === xyz.isLODTile && tile.LODLevel == xyz.LODLevel) {\n foundTile = tile;\n return;\n }\n });\n return foundTile;\n };\n\n TiledWorld.prototype.updateRastersForTile = function (xyz) {\n var _this = this;\n\n var tD = this.findTileDrawnBasedOnXYZLOD(xyz);\n if (tD == null) return;\n var textures = [];\n var tileLayersComplete = new Array(this.p.layers.tile.length).fill(false);\n var clampedLayersComplete = new Array(this.p.layers.clamped.length).fill(false);\n\n var onceTexturesLoaded = function () {\n if (tileLayersComplete.every(Boolean) && (xyz.isLODTile || clampedLayersComplete.every(Boolean))) {\n if (textures.length == 0) {\n tD.t.visible = false;\n return;\n }\n\n textures.sort(function (a, b) {\n return a.i - b.i;\n });\n tD.from.rasters = [];\n var orderingI = 0;\n\n for (var i = 0; i < textures.length; i++) {\n if (textures[i].type == 'tile') {\n tD.from.rasters.push({\n name: textures[i].name,\n type: textures[i].type,\n texture: textures[i].texture,\n opacity: textures[i].opacity,\n isVAT: 0,\n filters: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n blendCode: 0,\n blend: 0\n },\n i: orderingI\n });\n orderingI++;\n }\n }\n\n for (var i = 0; i < textures.length; i++) {\n if (textures[i].type == 'clamped') {\n tD.from.rasters.push({\n name: textures[i].name,\n type: textures[i].type,\n texture: textures[i].texture,\n opacity: textures[i].opacity,\n isVAT: 1,\n filters: {\n brightness: 1,\n contrast: 1,\n saturation: 1,\n blendCode: 0,\n blend: 0\n },\n i: orderingI\n });\n orderingI++;\n }\n }\n\n tD.t.material = ___WEBPACK_IMPORTED_MODULE_0__[\"Shaders\"].multiTexture(tD.from.rasters);\n\n if (_this.p.options.wireframeMode) {\n tD.t.material = new three__WEBPACK_IMPORTED_MODULE_1__[\"MeshBasicMaterial\"]({\n color: 0xffffff,\n wireframe: true\n });\n }\n\n tD.t.material.needsUpdate = true;\n }\n };\n\n var _loop_1 = function (i) {\n if (this_1.p.layers.tile[i].on && tD.z >= this_1.p.layers.tile[i].minZoom && tD.z <= this_1.p.layers.tile[i].maxZoom && _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, this_1.p.layers.tile[i].boundingBox, this_1.p.projection)) {\n var builtPath_1 = _utils_paths__WEBPACK_IMPORTED_MODULE_4__[\"default\"].buildPath(this_1.p.layers.tile[i].format, this_1.p.layers.tile[i].path, tD, this_1.p.projection, this_1.p.options.trueTileResolution, this_1.p.options.trueTileResolution, this_1.p.layers.tile[i].formatOptions);\n\n if (builtPath_1) {\n ;\n\n (function (i) {\n _this._.loader.load(builtPath_1, function (texture) {\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n if (_this.p.layers.tile[i]) textures.push({\n name: _this.p.layers.tile[i].name,\n type: 'tile',\n texture: texture,\n opacity: _this.p.layers.tile[i].opacity,\n i: i\n });\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }, function () {\n console.log('');\n }, function () {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n });\n })(i);\n } else {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n } else {\n tileLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n };\n\n var this_1 = this;\n\n for (var i = 0; i < this.p.layers.tile.length; i++) {\n _loop_1(i);\n }\n\n if (!xyz.isLODTile) {\n for (var i = 0; i < this.p.layers.clamped.length; i++) {\n if (this.p.layers.clamped[i].on && (this.p.layers.clamped[i].minZoom == null || tD.z >= this.p.layers.clamped[i].minZoom) && (this.p.layers.clamped[i].maxZoom == null || tD.z <= this.p.layers.clamped[i].maxZoom) && (this.p.layers.clamped[i].boundingBox == null || _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, this.p.layers.clamped[i].boundingBox, this.p.projection))) {\n var clampedTexture = this.p.layers._.layerers.clamped.getClampedTexture(i, {\n x: tD.x,\n y: tD.y,\n z: tD.z\n });\n\n tD.contains = tD.contains || {};\n tD.contains[this.p.layers.clamped[i].name] = clampedTexture.features;\n var texture = new three__WEBPACK_IMPORTED_MODULE_1__[\"CanvasTexture\"](clampedTexture.canvas);\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n if (this.p.layers.clamped[i]) textures.push({\n name: this.p.layers.clamped[i].name,\n type: 'clamped',\n texture: texture,\n opacity: this.p.layers.clamped[i].opacity,\n i: i\n });\n clampedLayersComplete[i] = true;\n onceTexturesLoaded();\n } else {\n clampedLayersComplete[i] = true;\n onceTexturesLoaded();\n }\n }\n }\n };\n\n TiledWorld.prototype.updateClampedRasterForTile = function (tD, layerName) {\n if (this.p.options.wireframeMode || tD.isLODTile) return;\n var clampedLayerI = null;\n\n for (var i = 0; i < this.p.layers.clamped.length; i++) {\n if (this.p.layers.clamped[i].name === layerName) {\n clampedLayerI = i;\n break;\n }\n }\n\n var clampedLayer = clampedLayerI != null ? this.p.layers.clamped[clampedLayerI] : null;\n\n if (clampedLayer && clampedLayer.on && (clampedLayer.minZoom == null || tD.z >= clampedLayer.minZoom) && (clampedLayer.maxZoom == null || tD.z <= clampedLayer.maxZoom) && (clampedLayer.boundingBox == null || _utils__WEBPACK_IMPORTED_MODULE_3__[\"default\"].isInExtent({\n x: tD.x,\n y: tD.y,\n z: tD.z\n }, clampedLayer.boundingBox, this.p.projection))) {\n var clampedTexture = this.p.layers._.layerers.clamped.getClampedTexture(clampedLayerI, {\n x: tD.x,\n y: tD.y,\n z: tD.z\n });\n\n tD.contains = tD.contains || {};\n tD.contains[this.p.layers.clamped[clampedLayerI].name] = clampedTexture.features;\n var texture = new three__WEBPACK_IMPORTED_MODULE_1__[\"CanvasTexture\"](clampedTexture.canvas);\n texture.magFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n texture.minFilter = three__WEBPACK_IMPORTED_MODULE_1__[\"NearestFilter\"];\n\n for (var i = 0; i < tD.from.rasters.length; i++) {\n if (tD.from.rasters[i].name === layerName) {\n tD.from.rasters[i].texture = texture;\n break;\n }\n }\n\n tD.t.material = ___WEBPACK_IMPORTED_MODULE_0__[\"Shaders\"].multiTexture(tD.from.rasters);\n tD.t.material.needsUpdate = true;\n }\n };\n\n TiledWorld.prototype.updateAllRasters = function () {\n this.killDrawingTiles();\n var startingLength = this.tilesDrawn.length;\n\n for (var j = 0; j < startingLength; j++) {\n var tD = this.tilesDrawn[j];\n this.updateRastersForTile({\n x: tD.x,\n y: tD.y,\n z: tD.z,\n isLODTile: tD.isLODTile,\n LODLevel: tD.LODLevel\n });\n }\n };\n\n TiledWorld.prototype.removeTile = function (i, shouldFadeOut) {\n shouldFadeOut = false;\n\n if (this.tilesDrawn[i]) {\n if (shouldFadeOut) {\n this.tilesDrawn[i].fadeOutAndRemove = true;\n } else {\n this.tilesDrawn[i].t.geometry.dispose();\n this.tilesDrawn[i].t.material.dispose();\n if (this.tilesDrawn[i].isLODTile) this.p.planetsLOD[this.tilesDrawn[i].LODLevel].remove(this.tilesDrawn[i].t);else this.p.planet.remove(this.tilesDrawn[i].t);\n this.tilesDrawn.splice(i, 1);\n }\n }\n };\n\n TiledWorld.prototype.removeAllTiles = function () {\n this.killDrawingTiles();\n\n for (var j = 0; j < this.tilesDrawn.length; j++) {\n this.removeTile(0);\n }\n };\n\n TiledWorld.prototype.outdateAllTiles = function () {\n this.killDrawingTiles();\n this.tilesDrawn.forEach(function (tile) {\n tile.outdated = true;\n });\n };\n\n TiledWorld.prototype.removeAllOutdatedTiles = function () {\n var _this = this;\n\n var outdatedTileIndices = [];\n this.tilesDrawn.forEach(function (t, i) {\n if (t.outdated) outdatedTileIndices.push(i);\n });\n outdatedTileIndices = outdatedTileIndices.sort().reverse();\n outdatedTileIndices.forEach(function (i) {\n _this.removeTile(i);\n });\n };\n\n TiledWorld.prototype.removeTileXYZ = function (xyz) {\n for (var t in this.tilesDrawn) {\n if (this.tilesDrawn[t].x == xyz.x && this.tilesDrawn[t].y == xyz.y && this.tilesDrawn[t].z == xyz.z) {\n this.tilesDrawn[t].t.geometry.dispose();\n this.tilesDrawn[t].t.material.dispose();\n if (this.tilesDrawn[t].isLODTile) this.p.planetsLOD[this.tilesDrawn[t].LODLevel].remove(this.tilesDrawn[t].t);else this.p.planet.remove(this.tilesDrawn[t].t);\n this.tilesDrawn.splice(t, 1);\n }\n }\n };\n\n TiledWorld.prototype.killDrawingTiles = function () {\n for (var t in this.tilesToBeDrawn) {\n this.tilesToBeDrawn[t].make = false;\n }\n\n for (var t in this.tilesBeingDrawn) {\n this.tilesBeingDrawn[t].make = false;\n }\n };\n\n TiledWorld.prototype.filterEffects = function () {\n var _this = this;\n\n var transitionFilters = ['brightness', 'contrast', 'saturation', 'blendCode'];\n\n var _loop_2 = function (m) {\n var _loop_3 = function (n) {\n if (this_2.tilesDrawn[m] && this_2.tilesDrawn[m].t && this_2.tilesDrawn[m].t.material.hasOwnProperty('uniforms')) {\n var layer_1 = this_2.p.layers.getLayerByName(this_2.tilesDrawn[m].from.rasters[n].name);\n\n if (layer_1 && layer_1.filters) {\n transitionFilters.forEach(function (f) {\n var desiredFilter = layer_1.filters[f];\n if (desiredFilter == null) return;\n var currentFilter = _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value;\n\n if (f == 'blendCode') {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = desiredFilter;\n } else if (desiredFilter > currentFilter) {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = Math.min(_this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value + 0.1, desiredFilter);\n } else {\n _this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value = Math.max(_this.tilesDrawn[m].t.material.uniforms[\"f\" + f + n].value - 0.1, desiredFilter);\n }\n });\n }\n }\n };\n\n for (var n in this_2.tilesDrawn[m].from.rasters) {\n _loop_3(n);\n }\n };\n\n var this_2 = this;\n\n for (var m in this.tilesDrawn) {\n _loop_2(m);\n }\n };\n\n TiledWorld.prototype.fadeInTiles = function () {\n for (var m in this.tilesDrawn) {\n if (!this.tilesDrawn[m].fadeOutAndRemove) for (var n in this.tilesDrawn[m].from.rasters) {\n if (this.tilesDrawn[m] && this.tilesDrawn[m].t && this.tilesDrawn[m].t.material.hasOwnProperty('uniforms')) {\n var layer = this.p.layers.getLayerByName(this.tilesDrawn[m].from.rasters[n].name);\n\n if (layer) {\n var desiredOpacity = layer.opacity;\n var currentOpacity = this.tilesDrawn[m].t.material.uniforms['tA' + n].value;\n\n if (desiredOpacity > currentOpacity) {\n this.tilesDrawn[m].t.material.uniforms['tA' + n].value = Math.min(this.tilesDrawn[m].t.material.uniforms['tA' + n].value + 0.1, desiredOpacity);\n } else {\n this.tilesDrawn[m].t.material.uniforms['tA' + n].value = Math.max(this.tilesDrawn[m].t.material.uniforms['tA' + n].value - 0.1, desiredOpacity);\n }\n }\n }\n }\n }\n };\n\n TiledWorld.prototype.fadeOutTiles = function () {\n for (var i = this.tilesDrawn.length - 1; i >= 0; i--) {\n if (this.tilesDrawn[i].fadeOutAndRemove) {\n for (var n = 0; this.tilesDrawn[i] && n < this.tilesDrawn[i].from.rasters.length; n++) {\n if (this.tilesDrawn[i] && this.tilesDrawn[i].t && this.tilesDrawn[i].t.material.hasOwnProperty('uniforms') && this.tilesDrawn[i].t.material.uniforms['tA' + n] != null) {\n var nextOpacity = Math.max(this.tilesDrawn[i].t.material.uniforms['tA' + n].value - 0.1, 0);\n if (nextOpacity <= 0) this.removeTile(i);else {\n this.tilesDrawn[i].t.material.uniforms['tA' + n].value = nextOpacity;\n }\n } else {\n this.removeTile(i);\n }\n }\n }\n }\n };\n\n return TiledWorld;\n}();\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (TiledWorld);\n\n//# sourceURL=webpack://LithoSphere/./src/core/tiledWorld.ts?"); /***/ }), @@ -2257,7 +2292,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var thre /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n\nvar Utils = {\n getIn: function (obj, keyArray, notSetValue) {\n if (obj == null) return notSetValue != null ? notSetValue : null;\n if (typeof keyArray === 'string') keyArray = keyArray.split('.');\n if (keyArray == null) return notSetValue != null ? notSetValue : null;\n var object = Object.assign({}, obj);\n\n for (var i = 0; i < keyArray.length; i++) {\n if (object.hasOwnProperty(keyArray[i])) object = object[keyArray[i]];else return notSetValue != null ? notSetValue : null;\n }\n\n return object;\n },\n mod: function (n, m) {\n var remain = n % m;\n return Math.floor(remain >= 0 ? remain : remain + m);\n },\n findHighestMaxZoom: function (tileLayers) {\n var highest = 0;\n\n for (var l in tileLayers) {\n if (tileLayers[l].name != 'Vectors As Tiles') if (tileLayers[l].maxZoom > highest) {\n highest = tileLayers[l].maxZoom;\n }\n }\n\n return highest;\n },\n findLowestMinZoom: function (tileLayers) {\n var lowest = Infinity;\n\n for (var l in tileLayers) {\n if (tileLayers[l].path !== '_vectorsastile_') {\n if (tileLayers[l].minZoom < lowest) {\n lowest = tileLayers[l].minZoom;\n }\n }\n }\n\n return lowest;\n },\n isInExtent: function (xyz, bb, projection) {\n var inExtent = true;\n\n if (bb) {\n var tx_ext = xyz.x + 0;\n var ty_ext = xyz.y + 0;\n var projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n var tlat_ext = projectedLL.lat;\n var tlon_ext = projectedLL.lng;\n inExtent = tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 1;\n ty_ext = xyz.y + 0;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 1;\n ty_ext = xyz.y + 1;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 0;\n ty_ext = xyz.y + 1;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n }\n\n return inExtent;\n },\n clone: function (obj) {\n var copy;\n if (null == obj || 'object' != typeof obj) return obj;\n\n if (obj instanceof Date) {\n copy = new Date();\n copy.setTime(obj.getTime());\n return copy;\n }\n\n if (obj instanceof Array) {\n copy = [];\n\n for (var i = 0, len = obj.length; i < len; i++) {\n copy[i] = Utils.clone(obj[i]);\n }\n\n return copy;\n }\n\n if (obj instanceof Object) {\n copy = {};\n\n for (var attr in obj) {\n if (obj.hasOwnProperty(attr)) copy[attr] = Utils.clone(obj[attr]);\n }\n\n return copy;\n }\n\n throw new Error(\"Unable to copy obj! Its type isn't supported.\");\n },\n capitalizeFirstLetter: function (string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n },\n getExtension: function (string) {\n return /(?:\\.([^.]+))?$/.exec(string)[1] || '';\n },\n getRadiansPerPixel: function (zoom) {\n return 360 / Math.pow(2, zoom) * (Math.PI / 180) / 256;\n },\n lastTileContains: [],\n tileContains: function (xyz, z, useLast) {\n if (useLast) {\n for (var i = 0; i < Utils.lastTileContains.length; i++) {\n var lastxyz = Utils.lastTileContains[i].call.xyz;\n\n if (lastxyz[0] == xyz[0] && lastxyz[1] == xyz[1] && lastxyz[2] == xyz[2] && Utils.lastTileContains[i].call.z == z) {\n return Utils.lastTileContains[i].result;\n }\n }\n }\n\n var contained = [];\n var zoomRatio = Math.pow(2, z) / Math.pow(2, xyz[2]);\n var max = [(xyz[0] + 1) * zoomRatio - 1, (xyz[1] + 1) * zoomRatio - 1];\n var min = [max[0] - zoomRatio + 1, max[1] - zoomRatio + 1];\n\n for (var x = min[0]; x <= max[0]; x++) {\n for (var y = min[1]; y <= max[1]; y++) {\n contained.push([x, y, z]);\n }\n }\n\n Utils.lastTileContains.unshift({\n call: {\n xyz: xyz,\n z: z\n },\n result: contained\n });\n if (Utils.lastTileContains.length > 3) Utils.lastTileContains.pop();\n return contained;\n },\n tileIsContained: function (xyzContainer, xyzContained, useLast) {\n var contains = this.tileContains(xyzContainer, xyzContained[2], useLast);\n\n for (var i = 0; i < contains.length; i++) {\n if (contains[i][0] == xyzContained[0] && contains[i][1] == xyzContained[1]) return true;\n }\n\n return false;\n },\n arrayAverage: function (array, key) {\n var total = 0;\n\n for (var i = 0; i < array.length; i++) {\n if (key != null) total += array[i][key];else total += array[i];\n }\n\n return total / array.length;\n },\n hexToRGB: function (hex) {\n var shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n hex = hex.replace(shorthandRegex, function (m, r, g, b) {\n return r + r + g + g + b + b;\n });\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n },\n rotatePoint: function (pt, center, angle) {\n var cosAngle = Math.cos(angle);\n var sinAngle = Math.sin(angle);\n var dx = pt.x - center[0];\n var dy = pt.y - center[1];\n return {\n x: center[0] + dx * cosAngle - dy * sinAngle,\n y: center[1] + dx * sinAngle + dy * cosAngle\n };\n },\n rotateAroundArbAxis: function (object, axis, radians, noPremultiply) {\n object.updateWorldMatrix(true);\n var invWorldRot = object.getWorldQuaternion(new three__WEBPACK_IMPORTED_MODULE_0__[\"Quaternion\"]()).invert();\n axis.applyQuaternion(invWorldRot);\n var deltaLocalRot = new three__WEBPACK_IMPORTED_MODULE_0__[\"Quaternion\"]();\n deltaLocalRot.setFromAxisAngle(axis, radians);\n object.quaternion.multiply(deltaLocalRot);\n },\n getParamString: function (params, baseUrl, isUppercase) {\n var str = [];\n var urlParams = new URLSearchParams(baseUrl.toUpperCase());\n\n for (var o in params) {\n if (!urlParams.has(o.toUpperCase())) str.push(encodeURIComponent(isUppercase ? o.toUpperCase() : o) + '=' + encodeURIComponent(params[o]));\n }\n\n return (baseUrl && baseUrl.indexOf('?') !== -1 ? '&' : '?') + str.join('&');\n },\n isArray: function (object) {\n return Object.prototype.toString.call(object) === '[object Array]';\n },\n setChildrenMaterialOpacity: function (model, opacity, recurse) {\n model.children.forEach(function (mesh) {\n if (mesh.material) {\n mesh.material.transparent = true;\n mesh.material.opacity = opacity;\n }\n\n if (typeof recurse === 'function' && mesh.children && mesh.children.length > 0) {\n recurse(mesh);\n }\n });\n },\n setAllMaterialOpacity: function (model, opacity) {\n if (model.material) {\n model.material.transparent = true;\n model.material.opacity = opacity;\n }\n\n Utils.setChildrenMaterialOpacity(model, opacity, function (mesh) {\n Utils.setAllMaterialOpacity(mesh, opacity);\n });\n }\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (Utils);\n\n//# sourceURL=webpack://LithoSphere/./src/utils/index.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n\nvar Utils = {\n getIn: function (obj, keyArray, notSetValue) {\n if (obj == null) return notSetValue != null ? notSetValue : null;\n if (typeof keyArray === 'string') keyArray = keyArray.split('.');\n if (keyArray == null) return notSetValue != null ? notSetValue : null;\n var object = Object.assign({}, obj);\n\n for (var i = 0; i < keyArray.length; i++) {\n if (object.hasOwnProperty(keyArray[i])) object = object[keyArray[i]];else return notSetValue != null ? notSetValue : null;\n }\n\n return object;\n },\n mod: function (n, m) {\n var remain = n % m;\n return Math.floor(remain >= 0 ? remain : remain + m);\n },\n findHighestMaxZoom: function (tileLayers) {\n var highest = 0;\n\n for (var l in tileLayers) {\n if (tileLayers[l].name != 'Vectors As Tiles') if (tileLayers[l].maxZoom > highest) {\n highest = tileLayers[l].maxZoom;\n }\n }\n\n return highest;\n },\n findLowestMinZoom: function (tileLayers) {\n var lowest = Infinity;\n\n for (var l in tileLayers) {\n if (tileLayers[l].path !== '_vectorsastile_') {\n if (tileLayers[l].minZoom < lowest) {\n lowest = tileLayers[l].minZoom;\n }\n }\n }\n\n return lowest;\n },\n isInExtent: function (xyz, bb, projection) {\n var inExtent = true;\n\n if (bb) {\n var tx_ext = xyz.x + 0;\n var ty_ext = xyz.y + 0;\n var projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n var tlat_ext = projectedLL.lat;\n var tlon_ext = projectedLL.lng;\n inExtent = tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 1;\n ty_ext = xyz.y + 0;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 1;\n ty_ext = xyz.y + 1;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n tx_ext = xyz.x + 0;\n ty_ext = xyz.y + 1;\n projectedLL = projection.tileXYZ2LatLng(tx_ext, ty_ext, xyz.z);\n tlat_ext = projectedLL.lat;\n tlon_ext = projectedLL.lng;\n inExtent = inExtent || tlat_ext < bb[3] && tlat_ext > bb[1] && tlon_ext < bb[2] && tlon_ext > bb[0];\n }\n\n return inExtent;\n },\n isInExtentEN: function (xyz, bb, proj, margin) {\n if (margin === void 0) {\n margin = 0.0000001;\n }\n\n if (!bb) return true;\n var minE = bb[0],\n minN = bb[1],\n maxE = bb[2],\n maxN = bb[3];\n\n var _a = proj.tileXYZ2NwSe(xyz, proj.trueTileResolution, true),\n min = _a.min,\n max = _a.max;\n\n return max.x > minE + margin && min.x < maxE - margin && max.y > minN + margin && min.y < maxN - margin;\n },\n clone: function (obj) {\n var copy;\n if (null == obj || 'object' != typeof obj) return obj;\n\n if (obj instanceof Date) {\n copy = new Date();\n copy.setTime(obj.getTime());\n return copy;\n }\n\n if (obj instanceof Array) {\n copy = [];\n\n for (var i = 0, len = obj.length; i < len; i++) {\n copy[i] = Utils.clone(obj[i]);\n }\n\n return copy;\n }\n\n if (obj instanceof Object) {\n copy = {};\n\n for (var attr in obj) {\n if (obj.hasOwnProperty(attr)) copy[attr] = Utils.clone(obj[attr]);\n }\n\n return copy;\n }\n\n throw new Error(\"Unable to copy obj! Its type isn't supported.\");\n },\n capitalizeFirstLetter: function (string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n },\n getExtension: function (string) {\n return /(?:\\.([^.]+))?$/.exec(string)[1] || '';\n },\n getRadiansPerPixel: function (zoom) {\n return 360 / Math.pow(2, zoom) * (Math.PI / 180) / 256;\n },\n lastTileContains: [],\n tileContains: function (xyz, z, useLast) {\n if (useLast) {\n for (var i = 0; i < Utils.lastTileContains.length; i++) {\n var lastxyz = Utils.lastTileContains[i].call.xyz;\n\n if (lastxyz[0] == xyz[0] && lastxyz[1] == xyz[1] && lastxyz[2] == xyz[2] && Utils.lastTileContains[i].call.z == z) {\n return Utils.lastTileContains[i].result;\n }\n }\n }\n\n var contained = [];\n var zoomRatio = Math.pow(2, z) / Math.pow(2, xyz[2]);\n var max = [(xyz[0] + 1) * zoomRatio - 1, (xyz[1] + 1) * zoomRatio - 1];\n var min = [max[0] - zoomRatio + 1, max[1] - zoomRatio + 1];\n\n for (var x = min[0]; x <= max[0]; x++) {\n for (var y = min[1]; y <= max[1]; y++) {\n contained.push([x, y, z]);\n }\n }\n\n Utils.lastTileContains.unshift({\n call: {\n xyz: xyz,\n z: z\n },\n result: contained\n });\n if (Utils.lastTileContains.length > 3) Utils.lastTileContains.pop();\n return contained;\n },\n tileIsContained: function (xyzContainer, xyzContained, useLast) {\n var contains = this.tileContains(xyzContainer, xyzContained[2], useLast);\n\n for (var i = 0; i < contains.length; i++) {\n if (contains[i][0] == xyzContained[0] && contains[i][1] == xyzContained[1]) return true;\n }\n\n return false;\n },\n arrayAverage: function (array, key) {\n var total = 0;\n\n for (var i = 0; i < array.length; i++) {\n if (key != null) total += array[i][key];else total += array[i];\n }\n\n return total / array.length;\n },\n hexToRGB: function (hex) {\n var shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n hex = hex.replace(shorthandRegex, function (m, r, g, b) {\n return r + r + g + g + b + b;\n });\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n },\n rotatePoint: function (pt, center, angle) {\n var cosAngle = Math.cos(angle);\n var sinAngle = Math.sin(angle);\n var dx = pt.x - center[0];\n var dy = pt.y - center[1];\n return {\n x: center[0] + dx * cosAngle - dy * sinAngle,\n y: center[1] + dx * sinAngle + dy * cosAngle\n };\n },\n rotateAroundArbAxis: function (object, axis, radians, noPremultiply) {\n object.updateWorldMatrix(true);\n var invWorldRot = object.getWorldQuaternion(new three__WEBPACK_IMPORTED_MODULE_0__[\"Quaternion\"]()).invert();\n axis.applyQuaternion(invWorldRot);\n var deltaLocalRot = new three__WEBPACK_IMPORTED_MODULE_0__[\"Quaternion\"]();\n deltaLocalRot.setFromAxisAngle(axis, radians);\n object.quaternion.multiply(deltaLocalRot);\n },\n getParamString: function (params, baseUrl, isUppercase) {\n var str = [];\n var urlParams = new URLSearchParams(baseUrl.toUpperCase());\n\n for (var o in params) {\n if (!urlParams.has(o.toUpperCase())) str.push(encodeURIComponent(isUppercase ? o.toUpperCase() : o) + '=' + encodeURIComponent(params[o]));\n }\n\n return (baseUrl && baseUrl.indexOf('?') !== -1 ? '&' : '?') + str.join('&');\n },\n isArray: function (object) {\n return Object.prototype.toString.call(object) === '[object Array]';\n },\n setChildrenMaterialOpacity: function (model, opacity, recurse) {\n model.children.forEach(function (mesh) {\n if (mesh.material) {\n mesh.material.transparent = true;\n mesh.material.opacity = opacity;\n }\n\n if (typeof recurse === 'function' && mesh.children && mesh.children.length > 0) {\n recurse(mesh);\n }\n });\n },\n setAllMaterialOpacity: function (model, opacity) {\n if (model.material) {\n model.material.transparent = true;\n model.material.opacity = opacity;\n }\n\n Utils.setChildrenMaterialOpacity(model, opacity, function (mesh) {\n Utils.setAllMaterialOpacity(mesh, opacity);\n });\n }\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (Utils);\n\n//# sourceURL=webpack://LithoSphere/./src/utils/index.ts?"); /***/ }), diff --git a/public/examples/example.html b/public/examples/example.html index 3faf3ca..6598ba0 100644 --- a/public/examples/example.html +++ b/public/examples/example.html @@ -699,12 +699,13 @@ Litho.addControl('myHome', Litho.controls.home) Litho.addControl('myExaggerate', Litho.controls.exaggerate) + Litho.addControl('myNavigation', Litho.controls.navigation) Litho.addControl('myLayers', Litho.controls.layers) Litho.addControl('myObserve', Litho.controls.observe) Litho.addControl('myWalk', Litho.controls.walk) Litho.addControl('myCompass', Litho.controls.compass) Litho.addControl('myCoords', Litho.controls.coordinates, { - //existingDivId: 'myCustomCoordDiv', + existingDivId: 'myCustomCoordDiv', }) const myLink = Litho.addControl('myLink', Litho.controls.link, { initiallyLinked: true, diff --git a/src/controls/controls.ts b/src/controls/controls.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/controls/index.ts b/src/controls/index.ts index afa5ba7..713fb97 100644 --- a/src/controls/index.ts +++ b/src/controls/index.ts @@ -1,6 +1,7 @@ import { Corners, ControlType } from '../generalTypes' import Compass from './compass' +import Navigation from './navigation' import Coordinates from './coordinates' import Home from './home' import Layers from './layers' @@ -9,10 +10,6 @@ import Observe from './observe' import Walk from './walk' import Link from './link' -/* -import Controls from './controls' -*/ - export default class Controls { // parent p: any @@ -25,6 +22,7 @@ export default class Controls { } activeControls: any compass: any + navigation: any coordinates: any home: any layers: any @@ -33,10 +31,6 @@ export default class Controls { walk: any link: any - /* - controls: Controls - */ - constructor(parent: any) { this.p = parent this.activeControls = {} @@ -115,15 +109,13 @@ export default class Controls { // Premade controls this.compass = Compass this.coordinates = Coordinates + this.navigation = Navigation this.home = Home this.layers = Layers this.exaggerate = Exaggerate this.observe = Observe this.walk = Walk this.link = Link - /* - this.controls = Controls - */ } addControl = ( diff --git a/src/controls/navigation.css b/src/controls/navigation.css new file mode 100644 index 0000000..8204be5 --- /dev/null +++ b/src/controls/navigation.css @@ -0,0 +1,104 @@ +#_lithosphere_control_navigation_root { + display: flex; +} +#_lithosphere_control_navigation_root svg { + width: 24px; + height: 24px; +} +#_lithosphere_control_navigation_root > div { + width: 80px; + margin-right: 6px; + display: flex; + flex-flow: column; +} +#_lithosphere_control_navigation_root > div > div:first-child { + background: black; + color: white; + height: 26px; + line-height: 26px; + text-transform: uppercase; + font-size: 12px; +} +#_lithosphere_control_navigation_root > div > div:first-child svg { + width: 18px; + height: 18px; + padding: 4px 0px; +} + +._lithosphere_control_navigation_panel { + width: 80px; + max-height: 0px; + overflow: hidden; + line-height: 42px; + background: black; + color: white; + display: flex; + border-top: 1px solid #444; + opacity: 0; + pointer-events: none; + transition: all 0.2s ease-out; +} + +#_lithosphere_control_navigation_root + > div:hover + > ._lithosphere_control_navigation_panel, +#_lithosphere_control_navigation_root + ._lithosphere_control_navigation_panel.active { + opacity: 1; + max-height: 100px; + pointer-events: inherit; +} +._lithosphere_control_navigation_panel div { + cursor: pointer; + transition: background 0.2s ease-out; +} +._lithosphere_control_navigation_panel div:hover { + background: rgba(255, 255, 255, 0.15); +} + +#_lithosphere_control_navigation_spin_root + ._lithosphere_control_navigation_panel { + height: 30px; +} +#_lithosphere_control_navigation_dolly_root + ._lithosphere_control_navigation_panel { + height: 30px; +} +#_lithosphere_control_navigation_pan_root + ._lithosphere_control_navigation_panel { + line-height: 30px; + height: 90px; + flex-flow: column; +} +#_lithosphere_control_navigation_zoom_root + ._lithosphere_control_navigation_panel { + height: 30px; +} + +#_lithosphere_control_navigation_spin_left, +#_lithosphere_control_navigation_spin_right, +#_lithosphere_control_navigation_dolly_up, +#_lithosphere_control_navigation_dolly_down, +#_lithosphere_control_navigation_zoom_in, +#_lithosphere_control_navigation_zoom_out { + width: 50%; + text-align: center; +} + +#_lithosphere_control_navigation_pan_up { + height: 30px; + line-height: 49px; + text-align: center; +} +#_lithosphere_control_navigation_pan_left, +#_lithosphere_control_navigation_pan_right { + height: 30px; + line-height: 44px; + width: 50%; + text-align: center; +} +#_lithosphere_control_navigation_pan_down { + height: 30px; + line-height: 38px; + text-align: center; +} diff --git a/src/controls/navigation.ts b/src/controls/navigation.ts new file mode 100644 index 0000000..31b0d83 --- /dev/null +++ b/src/controls/navigation.ts @@ -0,0 +1,229 @@ +import { Corners } from '../generalTypes.d.ts' + +import './navigation.css' + +interface Private {} + +export default class Navigation { + _: Private + // parent + p: any + name: string + corner: Corners + + constructor(parent: any, name: string) { + this.p = parent + this.name = name + this._ = {} + this.corner = Corners.TopRight + } + + getControl = (): string => { + // prettier-ignore + return [ + ` ` ].join('\n'); + } + + attachEvents = (): void => { + // Spin + document + .getElementById('_lithosphere_control_navigation_spin') + .addEventListener('click', (e) => { + document + .querySelector( + '#_lithosphere_control_navigation_spin_root ._lithosphere_control_navigation_panel' + ) + .classList.toggle('active') + }) + document + .getElementById('_lithosphere_control_navigation_spin_left') + .addEventListener('click', () => { + this.p._.cameras.controls.rotateLeft(3 * (Math.PI / 180)) + }) + document + .getElementById('_lithosphere_control_navigation_spin_right') + .addEventListener('click', () => { + this.p._.cameras.controls.rotateLeft(-3 * (Math.PI / 180)) + }) + + // Dolly + document + .getElementById('_lithosphere_control_navigation_dolly') + .addEventListener('click', (e) => { + document + .querySelector( + '#_lithosphere_control_navigation_dolly_root ._lithosphere_control_navigation_panel' + ) + .classList.toggle('active') + }) + document + .getElementById('_lithosphere_control_navigation_dolly_up') + .addEventListener('click', () => { + this.p._.cameras.controls.rotateUp(1.3 * (Math.PI / 180)) + }) + document + .getElementById('_lithosphere_control_navigation_dolly_down') + .addEventListener('click', () => { + this.p._.cameras.controls.rotateUp(-1.3 * (Math.PI / 180)) + }) + + // Pan + document + .getElementById('_lithosphere_control_navigation_pan') + .addEventListener('click', (e) => { + document + .querySelector( + '#_lithosphere_control_navigation_pan_root ._lithosphere_control_navigation_panel' + ) + .classList.toggle('active') + }) + document + .getElementById('_lithosphere_control_navigation_pan_up') + .addEventListener('click', () => { + this.p._.events._rotateGlobe( + { pageX: 0, pageY: 0 }, + { x: 0, y: -200 } + ) + }) + document + .getElementById('_lithosphere_control_navigation_pan_left') + .addEventListener('click', () => { + this.p._.events._rotateGlobe( + { pageX: 0, pageY: 0 }, + { x: -200, y: 0 } + ) + }) + document + .getElementById('_lithosphere_control_navigation_pan_right') + .addEventListener('click', () => { + this.p._.events._rotateGlobe( + { pageX: 0, pageY: 0 }, + { x: 200, y: 0 } + ) + }) + document + .getElementById('_lithosphere_control_navigation_pan_down') + .addEventListener('click', () => { + this.p._.events._rotateGlobe( + { pageX: 0, pageY: 0 }, + { x: 0, y: 200 } + ) + }) + + // Zoom + document + .getElementById('_lithosphere_control_navigation_zoom') + .addEventListener('click', (e) => { + document + .querySelector( + '#_lithosphere_control_navigation_zoom_root ._lithosphere_control_navigation_panel' + ) + .classList.toggle('active') + }) + document + .getElementById('_lithosphere_control_navigation_zoom_in') + .addEventListener('click', () => { + this.p._.cameras.controls.handleMouseWheel({ deltaY: -200 }) + this.p._.events._onZoom() + }) + document + .getElementById('_lithosphere_control_navigation_zoom_out') + .addEventListener('click', () => { + this.p._.cameras.controls.handleMouseWheel({ deltaY: 200 }) + this.p._.events._onZoom() + }) + } +} diff --git a/src/core/tiledWorld.ts b/src/core/tiledWorld.ts index 0f16079..df93d63 100644 --- a/src/core/tiledWorld.ts +++ b/src/core/tiledWorld.ts @@ -579,6 +579,11 @@ export default class TiledWorld { xyz, this.p.layers.tile[i].boundingBox, this.p.projection + ) && + Utils.isInExtentEN( + xyz, + this.p.layers.tile[i].boundingBoxEN, + this.p.projection )) || this.p.layers.tile[i].path == '_vectorsastile_') //TODO: Check this vec as tile ) { diff --git a/src/utils/index.ts b/src/utils/index.ts index d7b8138..f56e167 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -103,6 +103,16 @@ const Utils = { } return inExtent }, + // Returns true if the tile at xyz in the bounding box bb where bb is + // specified as [minEasting, minNorthing, maxEasting, maxNorthing] + // Checks to see if any corners of it fit inside + isInExtentEN: function (xyz: XYZ, bb, proj, margin = 0.0000001): boolean { + if (!bb) return true + const [minE, minN, maxE, maxN] = bb + const { min, max } = proj.tileXYZ2NwSe(xyz, proj.trueTileResolution, true) + return max.x > minE + margin && min.x < maxE - margin + && max.y > minN + margin && min.y < maxN - margin + }, //Return a clone of the object to avoid pass by reference issues clone: function (obj: any): any { let copy