UNPKG

qwc2

Version:
243 lines (238 loc) 12.4 kB
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /** * Copyright 2025 Sourcepole AG * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ import { Parser as ExprParser } from 'expr-eval'; import isEmpty from "lodash.isempty"; import parseCssColor from 'parse-css-color'; import { Float32BufferAttribute, Group, Vector3 } from "three"; import MiscUtils from '../../../utils/MiscUtils'; import { createLabelObject, TileMeshHelper } from "./MiscUtils3D"; var styleExpressionParser = new ExprParser(); styleExpressionParser.functions.color = function (name) { var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var color = parseCssColor(name); return [].concat(_toConsumableArray(color.values.map(function (c) { return c / 255; })), [alpha]); }; styleExpressionParser.functions.rgb = function (r, g, b) { return [r / 255, g / 255, g / 255, 1]; }; styleExpressionParser.functions.rgba = function (r, g, b, a) { return [r / 255, g / 255, g / 255, a]; }; styleExpressionParser.functions.hsl = function (h, s, l) { return [].concat(_toConsumableArray(MiscUtils.hslToRgb(h, s, l)), [1]); }; styleExpressionParser.functions.hsla = function (h, s, l, a) { return [].concat(_toConsumableArray(MiscUtils.hslToRgb(h, s, l)), [a]); }; function featureColor(objectId, featureProperties, context) { var _context$featureStyle, _context$featureStyle2; if (((_context$featureStyle = (_context$featureStyle2 = context.featureStyles) === null || _context$featureStyle2 === void 0 || (_context$featureStyle2 = _context$featureStyle2[objectId]) === null || _context$featureStyle2 === void 0 ? void 0 : _context$featureStyle2.color) !== null && _context$featureStyle !== void 0 ? _context$featureStyle : null) !== null) { var color = parseCssColor(context.featureStyles[objectId].color); return [].concat(_toConsumableArray(color.values.map(function (c) { return c / 255; })), [color.alpha]); } else if (context.colorExpressions.length) { try { for (var i = 0; i < context.colorExpressions.length; ++i) { var condition = context.colorExpressions[i][0].evaluate(featureProperties); if (condition) { return context.colorExpressions[i][1].evaluate(featureProperties); } } } catch (e) { /* eslint-disable-next-line */ console.warn("Failed to parse color expression: " + String(e)); } return null; } else if (featureProperties[context.colorAttr]) { var _featureProperties$co; var _color = featureProperties[context.colorAttr]; var alpha = context.alphaAttr ? (_featureProperties$co = featureProperties[context.alphaAttr]) !== null && _featureProperties$co !== void 0 ? _featureProperties$co : 255 : 255; var r = (_color >> 16 & 0xff) / 255; var g = (_color >> 8 & 0xff) / 255; var b = (_color & 0xff) / 255; return [r, g, b, alpha / 255]; } else { return null; } } function featureLabel(objectId, featureProperties, context) { var _context$featureStyle3, _context$featureStyle4; if (((_context$featureStyle3 = (_context$featureStyle4 = context.featureStyles) === null || _context$featureStyle4 === void 0 || (_context$featureStyle4 = _context$featureStyle4[objectId]) === null || _context$featureStyle4 === void 0 ? void 0 : _context$featureStyle4.label) !== null && _context$featureStyle3 !== void 0 ? _context$featureStyle3 : null) !== null) { var _context$featureStyle5; return { text: context.featureStyles[objectId].label, offset: (_context$featureStyle5 = context.featureStyles[objectId].labelOffset) !== null && _context$featureStyle5 !== void 0 ? _context$featureStyle5 : 80 }; } else if (context.labelAttr) { return featureProperties[context.labelAttr]; } else { return null; } } var Tiles3DStyle = { applyTileStyle: function applyTileStyle(group, config, sceneContext) { var _config$idAttr, _config$tilesetStyle, _config$tilesetStyle2; var featureColorCache = {}; var featureLabelCache = {}; var labels = {}; var idAttr = (_config$idAttr = config.idAttr) !== null && _config$idAttr !== void 0 ? _config$idAttr : "id"; var context = { colorExpressions: [], featureStyles: (_config$tilesetStyle = config.tilesetStyle) === null || _config$tilesetStyle === void 0 ? void 0 : _config$tilesetStyle.featureStyles, colorAttr: config.colorAttr, alphaAttr: config.alphaAttr, labelAttr: config.labelAttr }; var baseColor = [1, 1, 1, 1]; var customBaseColor = false; if (config.baseColor) { var color = parseCssColor(config.baseColor); baseColor = [].concat(_toConsumableArray(color.values.map(function (x) { return x / 255; })), [color.alpha]); customBaseColor = true; } var colorRules = (_config$tilesetStyle2 = config.tilesetStyle) === null || _config$tilesetStyle2 === void 0 ? void 0 : _config$tilesetStyle2.color; var parseExpr = function parseExpr(expr) { var cleanExpr = expr.replace(/\$\{(\w+)\}/g, '$1').replaceAll('===', '==').replaceAll('!==', '==').replaceAll('||', 'or').replaceAll('&&', 'and'); return styleExpressionParser.parse(cleanExpr); }; if (colorRules !== null && colorRules !== void 0 && colorRules.conditions) { colorRules === null || colorRules === void 0 || colorRules.conditions.forEach(function (cond) { context.colorExpressions.push([parseExpr(cond[0]), parseExpr(cond[1])]); }); } else if (typeof colorRules === "string") { context.colorExpressions.push([parseExpr("true"), parseExpr(colorRules)]); } group.traverse(function (c) { if (c.geometry) { var helper = new TileMeshHelper(c); var featureIdAttr = helper.getFeatureIdAttr(); if (!featureIdAttr) { return; } var posAttr = c.geometry.getAttribute('position'); var rgbaColors = []; var rgbColors = []; var haveColor = customBaseColor; var haveAlpha = baseColor[3] < 1; for (var idx = 0; idx < featureIdAttr.count; ++idx) { var featureId = featureIdAttr.getX(idx); var featureProperties = helper.getFeatureProperties(featureId); var objectId = String(featureProperties[idAttr]); // Handle color var _color2 = featureColorCache[featureId]; if (_color2 === undefined) { _color2 = featureColorCache[featureId] = featureColor(objectId, featureProperties, context); } if (_color2) { haveColor = true; haveAlpha |= _color2[3] < 1; rgbaColors.push.apply(rgbaColors, _toConsumableArray(_color2)); rgbColors.push.apply(rgbColors, _toConsumableArray(_color2.slice(0, 3))); } else { rgbaColors.push.apply(rgbaColors, _toConsumableArray(baseColor)); rgbColors.push.apply(rgbColors, _toConsumableArray(baseColor.slice(0, 3))); } // Handle label var label = featureLabelCache[featureId]; if (label === undefined) { label = featureLabelCache[featureId] = featureLabel(objectId, featureProperties, context); } if (label) { var pos = posAttr.array.slice(3 * idx, 3 * idx + 3); var entry = labels[featureId]; if (!entry) { entry = labels[featureId] = { label: label.text, labelOffset: label.offset, pos: pos, ymax: pos[1], count: 1, matrix: c.matrixWorld }; } else { entry.pos[0] += pos[0]; entry.pos[1] += pos[1]; entry.pos[2] += pos[2]; entry.ymax = Math.max(entry.ymax, pos[1]); ++entry.count; } } } // NOTE: Also update color buffers if they were previously colored if (haveColor || group.userData.haveColor) { if (haveAlpha) { c.geometry.setAttribute('color', new Float32BufferAttribute(rgbaColors, 4)); } else { // Discard alpha var count = rgbaColors.length / 4; var bufAttr = new Float32BufferAttribute(count * 3, 3); for (var i = 0, j = 0; i < count; ++i) { bufAttr.array[j++] = rgbaColors[4 * i]; bufAttr.array[j++] = rgbaColors[4 * i + 1]; bufAttr.array[j++] = rgbaColors[4 * i + 2]; } c.geometry.setAttribute('color', bufAttr); } c.material.vertexColors = true; c.material.transparent = haveAlpha; group.userData.haveColor = haveColor; } } }); // Clear previous labels if (group.userData.labelGroup) { group.remove(group.children.find(function (child) { return child.uuid === group.userData.labelGroup; })); // Explicitly remove label DOM elements Object.values(group.userData.tileLabels).forEach(function (entry) { entry.labelObject.element.parentNode.removeChild(entry.labelObject.element); }); delete group.userData.tileLabels; delete group.userData.labelGroup; } // Add new labels if (!isEmpty(labels)) { var tileLabels = {}; var labelObjects = new Group(); Object.entries(labels).forEach(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), featureId = _ref2[0], entry = _ref2[1]; var pos = new Vector3(entry.pos[0] / entry.count, entry.pos[1] / entry.count, entry.pos[2] / entry.count).applyMatrix4(entry.matrix); var maxpos = new Vector3(entry.pos[0] / entry.count, entry.ymax, entry.pos[2] / entry.count).applyMatrix4(entry.matrix); tileLabels[featureId] = { pos: pos, label: entry.label, labelOffset: entry.labelOffset }; tileLabels[featureId].labelObject = createLabelObject(entry.label, pos, sceneContext, 0, entry.labelOffset + (maxpos.y - pos.y)); labelObjects.add(tileLabels[featureId].labelObject); }); group.userData.tileLabels = tileLabels; group.userData.labelGroup = labelObjects.uuid; group.add(labelObjects); } } }; export default Tiles3DStyle;