UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

288 lines (237 loc) 9.36 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var THREE = _interopRequireWildcard(require("three")); var _LayerUpdateState = _interopRequireDefault(require("../Layer/LayerUpdateState")); var _ObjectRemovalHelper = _interopRequireDefault(require("./ObjectRemovalHelper")); var _handlerNodeError = _interopRequireDefault(require("./handlerNodeError")); var _Coordinates = _interopRequireDefault(require("../Core/Geographic/Coordinates")); var _Extent = _interopRequireDefault(require("../Core/Geographic/Extent")); var _extent = new _Extent["default"]('EPSG:4326', 0, 0, 0, 0); var coord = new _Coordinates["default"]('EPSG:4326', 0, 0, 0); var vector = new THREE.Vector3(); var tmp = new THREE.Vector3(); function applyOffset(obj, offset, quaternion) { var offsetAltitude = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; if (obj.geometry) { if (obj.geometry.isBufferGeometry) { var count = obj.geometry.attributes.position.count * 3; for (var i = 0; i < count; i += 3) { vector.fromArray(obj.geometry.attributes.position.array, i); vector.add(offset).applyQuaternion(quaternion); vector.z -= offsetAltitude; vector.toArray(obj.geometry.attributes.position.array, i); } obj.geometry.attributes.position.needsUpdate = true; } else { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = obj.geometry.vertices[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var v = _step.value; v.add(offset).applyQuaternion(quaternion); v.z -= offsetAltitude; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } obj.geometry.verticesNeedUpdate = true; } } obj.children.forEach(function (c) { return applyOffset(c, offset, quaternion, offsetAltitude); }); } function assignLayer(object, layer) { if (object) { object.layer = layer; if (object.material) { object.material.transparent = layer.opacity < 1.0; object.material.opacity = layer.opacity; object.material.wireframe = layer.wireframe; if (layer.size) { object.material.size = layer.size; } if (layer.linewidth) { object.material.linewidth = layer.linewidth; } } object.layers.set(layer.threejsLayer); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = object.children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var c = _step2.value; assignLayer(c, layer); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) { _iterator2["return"](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return object; } } function extentInsideSource(extent, source) { return !source.extentInsideLimit(extent) || source.parsedData && !source.parsedData.extent.isPointInside(extent.center(coord)); } var quaternion = new THREE.Quaternion(); var _default = { update: function update(context, layer, node) { if (!node.parent && node.children.length) { // if node has been removed dispose three.js resource _ObjectRemovalHelper["default"].removeChildrenAndCleanupRecursively(layer, node); return; } if (!node.visible) { return; } if (node.layerUpdateState[layer.id] === undefined) { node.layerUpdateState[layer.id] = new _LayerUpdateState["default"](); } if (!node.layerUpdateState[layer.id].canTryUpdate()) { return; } var features = node.children.filter(function (n) { return n.layer == layer; }); if (features.length > 0) { return features; } var extentsDestination = node.getExtentsByProjection(layer.source.projection) || [node.extent]; extentsDestination.forEach(function (e) { e.zoom = node.level; }); var extentsSource = []; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = extentsDestination[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var extentDest = _step3.value; var ext = layer.source.projection == extentDest.crs ? extentDest : extentDest.as(layer.source.projection); ext.zoom = extentDest.zoom; if (extentInsideSource(ext, layer.source)) { node.layerUpdateState[layer.id].noMoreUpdatePossible(); return; } extentsSource.push(extentDest); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3["return"] != null) { _iterator3["return"](); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } node.layerUpdateState[layer.id].newTry(); var command = { layer: layer, extentsSource: extentsSource, view: context.view, threejsLayer: layer.threejsLayer, requester: node }; return context.scheduler.execute(command).then(function (result) { // if request return empty json, WFSProvider.getFeatures return undefined result = result[0]; if (result) { // special case for FileSource, as it is not tiled and we need // to attach it to the correct node if (layer.source && layer.source.isFileSource) { var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = extentsSource[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var extentSrc = _step4.value; var ext = extentSrc.crs == layer.source.projection ? extentSrc : extentSrc.as(layer.source.projection, _extent); ext.zoom = extentSrc.zoom; if (extentInsideSource(ext, layer.source)) { node.layerUpdateState[layer.id].noMoreUpdatePossible(); return; } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4["return"] != null) { _iterator4["return"](); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } var isApplied = !result.layer; result.minAltitude = isNaN(result.minAltitude) ? 0 : result.minAltitude; assignLayer(result, layer); // call onMeshCreated callback if needed if (layer.onMeshCreated) { layer.onMeshCreated(result); } node.layerUpdateState[layer.id].success(); if (!node.parent) { _ObjectRemovalHelper["default"].removeChildrenAndCleanupRecursively(layer, result); return; } // We don't use node.matrixWorld here, because feature coordinates are // expressed in crs coordinates (which may be different than world coordinates, // if node's layer is attached to an Object with a non-identity transformation) if (isApplied) { // NOTE: now data source provider use cache on Mesh // TODO move transform in feature2Mesh node.extent.center(coord).as(context.view.referenceCrs, coord).toVector3(tmp).negate(); quaternion.setFromRotationMatrix(node.matrixWorld).inverse(); // const quaternion = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 0, 1), node.extent.center().geodesicNormal).inverse(); applyOffset(result, tmp, quaternion, result.minAltitude); } if (result.minAltitude) { result.position.z = result.minAltitude; } result.layer = layer; node.add(result); node.updateMatrixWorld(); } else { node.layerUpdateState[layer.id].failure(1, true); } }, function (err) { return (0, _handlerNodeError["default"])(err, node, layer, node.level, context.view); }); } }; exports["default"] = _default;