@deck.gl/geo-layers
Version:
deck.gl layers supporting geospatial use cases and GIS formats
250 lines (206 loc) • 8.81 kB
JavaScript
"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