UNPKG

@deck.gl/geo-layers

Version:

deck.gl layers supporting geospatial use cases and GIS formats

250 lines (206 loc) 8.81 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getOSMTileIndices = getOSMTileIndices; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _culling = require("@math.gl/culling"); var _webMercator = require("@math.gl/web-mercator"); var _utils = require("./utils"); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var TILE_SIZE = 512; var MAX_MAPS = 3; var REF_POINTS_5 = [[0.5, 0.5], [0, 0], [0, 1], [1, 0], [1, 1]]; var REF_POINTS_9 = REF_POINTS_5.concat([[0, 0.5], [0.5, 0], [1, 0.5], [0.5, 1]]); var REF_POINTS_11 = REF_POINTS_9.concat([[0.25, 0.5], [0.75, 0.5]]); var OSMNode = function () { function OSMNode(x, y, z) { (0, _classCallCheck2.default)(this, OSMNode); this.x = x; this.y = y; this.z = z; } (0, _createClass2.default)(OSMNode, [{ key: "children", get: function get() { if (!this._children) { var x = this.x * 2; var y = this.y * 2; var z = this.z + 1; this._children = [new OSMNode(x, y, z), new OSMNode(x, y + 1, z), new OSMNode(x + 1, y, z), new OSMNode(x + 1, y + 1, z)]; } return this._children; } }, { key: "update", value: function update(params) { var viewport = params.viewport, cullingVolume = params.cullingVolume, elevationBounds = params.elevationBounds, minZ = params.minZ, maxZ = params.maxZ, bounds = params.bounds, offset = params.offset, project = params.project; var boundingVolume = this.getBoundingVolume(elevationBounds, offset, project); if (bounds && !this.insideBounds(bounds)) { return false; } var isInside = cullingVolume.computeVisibility(boundingVolume); if (isInside < 0) { return false; } if (!this.childVisible) { var z = this.z; if (z < maxZ && z >= minZ) { var distance = boundingVolume.distanceTo(viewport.cameraPosition) * viewport.scale / viewport.height; z += Math.floor(Math.log2(distance)); } if (z >= maxZ) { this.selected = true; return true; } } this.selected = false; this.childVisible = true; var _iterator = _createForOfIteratorHelper(this.children), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var child = _step.value; child.update(params); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return true; } }, { key: "getSelected", value: function getSelected() { var result = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; if (this.selected) { result.push(this); } if (this._children) { var _iterator2 = _createForOfIteratorHelper(this._children), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var node = _step2.value; node.getSelected(result); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } return result; } }, { key: "insideBounds", value: function insideBounds(_ref) { var _ref2 = (0, _slicedToArray2.default)(_ref, 4), minX = _ref2[0], minY = _ref2[1], maxX = _ref2[2], maxY = _ref2[3]; var scale = Math.pow(2, this.z); var extent = TILE_SIZE / scale; return this.x * extent < maxX && this.y * extent < maxY && (this.x + 1) * extent > minX && (this.y + 1) * extent > minY; } }, { key: "getBoundingVolume", value: function getBoundingVolume(zRange, worldOffset, project) { if (project) { var refPoints = this.z < 1 ? REF_POINTS_11 : this.z < 2 ? REF_POINTS_9 : REF_POINTS_5; var refPointPositions = []; var _iterator3 = _createForOfIteratorHelper(refPoints), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var p = _step3.value; var lngLat = (0, _utils.osmTile2lngLat)(this.x + p[0], this.y + p[1], this.z); lngLat[2] = zRange[0]; refPointPositions.push(project(lngLat)); if (zRange[0] !== zRange[1]) { lngLat[2] = zRange[1]; refPointPositions.push(project(lngLat)); } } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } return (0, _culling.makeOrientedBoundingBoxFromPoints)(refPointPositions); } var scale = Math.pow(2, this.z); var extent = TILE_SIZE / scale; var originX = this.x * extent + worldOffset * TILE_SIZE; var originY = TILE_SIZE - (this.y + 1) * extent; return new _culling.AxisAlignedBoundingBox([originX, originY, zRange[0]], [originX + extent, originY + extent, zRange[1]]); } }]); return OSMNode; }(); function getOSMTileIndices(viewport, maxZ, zRange, bounds) { var project = viewport.resolution ? viewport.projectPosition : null; var planes = Object.values(viewport.getFrustumPlanes()).map(function (_ref3) { var normal = _ref3.normal, distance = _ref3.distance; return new _culling.Plane(normal.clone().negate(), distance); }); var cullingVolume = new _culling.CullingVolume(planes); var unitsPerMeter = viewport.distanceScales.unitsPerMeter[2]; var elevationMin = zRange && zRange[0] * unitsPerMeter || 0; var elevationMax = zRange && zRange[1] * unitsPerMeter || 0; var minZ = viewport.pitch <= 60 ? maxZ : 0; if (bounds) { var _bounds = bounds, _bounds2 = (0, _slicedToArray2.default)(_bounds, 4), minLng = _bounds2[0], minLat = _bounds2[1], maxLng = _bounds2[2], maxLat = _bounds2[3]; var topLeft = (0, _webMercator.lngLatToWorld)([minLng, maxLat]); var bottomRight = (0, _webMercator.lngLatToWorld)([maxLng, minLat]); bounds = [topLeft[0], TILE_SIZE - topLeft[1], bottomRight[0], TILE_SIZE - bottomRight[1]]; } var root = new OSMNode(0, 0, 0); var traversalParams = { viewport: viewport, project: project, cullingVolume: cullingVolume, elevationBounds: [elevationMin, elevationMax], minZ: minZ, maxZ: maxZ, bounds: bounds, offset: 0 }; root.update(traversalParams); if (viewport.subViewports && viewport.subViewports.length > 1) { traversalParams.offset = -1; while (root.update(traversalParams)) { if (--traversalParams.offset < -MAX_MAPS) { break; } } traversalParams.offset = 1; while (root.update(traversalParams)) { if (++traversalParams.offset > MAX_MAPS) { break; } } } return root.getSelected(); } //# sourceMappingURL=tile-2d-traversal.js.map