UNPKG

@webviz/subsurface-viewer

Version:

3D visualization component for subsurface reservoir data

189 lines 8.35 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import _ from "lodash"; import { distance } from "mathjs"; function hasPropertiesArray( // eslint-disable-next-line @typescript-eslint/no-explicit-any obj) { return obj && Array.isArray(obj.properties); } // eslint-disable-next-line @typescript-eslint/no-explicit-any function hasSingleProperty(obj) { return (obj && "propertyValue" in obj && typeof obj.propertyValue === "number"); } function getUniqueInfoPickId(pick) { var _a; return `${pick.index}::${(_a = pick.layer) === null || _a === void 0 ? void 0 : _a.id}`; } export class MultiViewPickingInfoAssembler { constructor(deckGL, options = { multiPicking: false, pickDepth: 1, }) { this._deckGl = null; this._subscribers = new Set(); this._deckGl = deckGL; this._options = options; } setDeckGL(deckGL) { this._deckGl = deckGL; } subscribe(callback) { this._subscribers.add(callback); return () => { this._subscribers.delete(callback); }; } publish(info, activeViewportId) { for (const subscriber of this._subscribers) { subscriber(info, activeViewportId); } } getMultiViewPickingInfo(hoverEvent) { var _a, _b, _c; if (!((_a = this._deckGl) === null || _a === void 0 ? void 0 : _a.deck)) { return; } const viewports = (_b = this._deckGl.deck) === null || _b === void 0 ? void 0 : _b.getViewports(); if (!viewports) { return; } if (hoverEvent.infos.length === 0) { return; } const activeViewportId = (_c = hoverEvent.infos[0].viewport) === null || _c === void 0 ? void 0 : _c.id; if (!activeViewportId) { return; } const eventScreenCoordinate = [ hoverEvent.infos[0].x, hoverEvent.infos[0].y, ]; this.assembleMultiViewPickingInfo(eventScreenCoordinate, activeViewportId, viewports).then((info) => { this.publish(info, activeViewportId); }); } pickAtCoordinate(x, y) { var _a; const deck = (_a = this._deckGl) === null || _a === void 0 ? void 0 : _a.deck; if (!deck) return []; if (this._options.multiPicking) { // ! For some reason, multi-pick pads the array up to pick-depth length, repeating the last element const multPickResult = deck.pickMultipleObjects({ depth: this._options.pickDepth, unproject3D: true, x, y, }); // Ensure the top-most element is processed first by sorting based on distance to camera return _.sortBy(multPickResult, (pick) => { var _a; if (!((_a = pick.viewport) === null || _a === void 0 ? void 0 : _a.cameraPosition)) return -1; if (!pick.coordinate) return -1; return distance(pick.coordinate, pick.viewport.cameraPosition); }); } else { const obj = deck.pickObject({ unproject3D: true, x, y, }); return obj ? [obj] : []; } } assembleMultiViewPickingInfo(eventScreenCoordinate, activeViewportId, viewports) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { var _a; if (!((_a = this._deckGl) === null || _a === void 0 ? void 0 : _a.deck)) { reject("DeckGL not initialized"); return; } const activeViewport = viewports.find((el) => el.id === activeViewportId); if (!activeViewport) { reject("Active viewport not found"); return; } const activeViewportRelativeScreenCoordinates = [ eventScreenCoordinate[0] - activeViewport.x, eventScreenCoordinate[1] - activeViewport.y, ]; const worldCoordinate = activeViewport.unproject(activeViewportRelativeScreenCoordinates); const collectedPickingInfo = {}; for (const viewport of viewports) { const [relativeScreenX, relativeScreenY] = viewport.project(worldCoordinate); const pickingInfo = this.pickAtCoordinate(relativeScreenX + viewport.x, relativeScreenY + viewport.y); if (pickingInfo) { const layerInfoDict = {}; const processedPickIds = []; for (const info of pickingInfo) { const uniquePickId = getUniqueInfoPickId(info); const hasMultipleProperties = hasPropertiesArray(info); const hasOneProperty = hasSingleProperty(info); // General guard clauses if (!info.layer) continue; if (processedPickIds.includes(uniquePickId)) continue; if (!hasMultipleProperties && !hasOneProperty) continue; processedPickIds.push(uniquePickId); const layerId = info.layer.id; const layerProps = info.layer .props; const layerName = layerProps.name; if (!layerInfoDict[layerId]) { layerInfoDict[layerId] = { layerId, layerName, properties: [], }; } const layerPickingInfo = layerInfoDict[layerId]; if (hasOneProperty) { layerPickingInfo.properties.push({ name: "Value", value: info.propertyValue, color: undefined, }); } else if (hasMultipleProperties) { const properties = info.properties; for (const property of properties) { layerPickingInfo.properties.push({ name: property.name, value: property.value, color: property.color, }); } } } collectedPickingInfo[viewport.id] = { coordinates: worldCoordinate, layerPickingInfo: Object.values(layerInfoDict), }; } else { collectedPickingInfo[viewport.id] = { coordinates: worldCoordinate, layerPickingInfo: [], }; } } resolve(collectedPickingInfo); }); }); } } //# sourceMappingURL=MultiViewPickingInfoAssembler.js.map