UNPKG

@itwin/core-frontend

Version:
91 lines 5.57 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { Cartographic, EcefLocation } from "@itwin/core-common"; import { Range3d } from "@itwin/core-geometry"; import { CRSManager, Downloader, DownloaderXhr, OnlineEngine, OPCReader, OrbitGtBounds, PageCachedFile, UrlFS } from "@itwin/core-orbitgt"; import { FrontendLoggerCategory } from "../../common/FrontendLoggerCategory"; import { BentleyError, expectDefined, Logger, RealityDataStatus } from "@itwin/core-bentley"; import { RealityDataError } from "../../RealityDataSource"; const loggerCategory = FrontendLoggerCategory.RealityData; /** * This class provide methods used to interpret Orbit Point Cloud (OPC) format */ export class OPCFormatInterpreter { /** Gets an OPC file reader from a blobFileUrl * @param blobFileURL the name of the file. * @returns return a file reader open to read provided blob file */ static async getFileReaderFromBlobFileURL(blobFileURL) { if (Downloader.INSTANCE == null) Downloader.INSTANCE = new DownloaderXhr(); if (CRSManager.ENGINE == null) CRSManager.ENGINE = await OnlineEngine.create(); // let blobFileURL: string = rdUrl; // if (accountName.length > 0) blobFileURL = UrlFS.getAzureBlobSasUrl(opcConfig.accountName, opcConfig.containerName, opcConfig.blobFileName, opcConfig.sasToken); const urlFS = new UrlFS(); // wrap a caching layer (16 MB) around the blob file const blobFileSize = await urlFS.getFileLength(blobFileURL); Logger.logTrace(loggerCategory, `OPC File Size is ${blobFileSize.toString()}`); const blobFile = new PageCachedFile(urlFS, blobFileURL, blobFileSize, 128 * 1024 /* pageSize */, 128 /* maxPageCount */); const fileReader = await OPCReader.openFile(blobFile, blobFileURL, true /* lazyLoading */); return fileReader; } /** Gets reality data spatial location and extents * @param fileReader a file reader instance obtains from call to getFileReaderFromBlobFileURL * @returns spatial location and volume of interest, in meters, centered around `spatial location` * @throws [[RealityDataError]] if source is invalid or cannot be read */ static async getSpatialLocationAndExtents(fileReader) { let worldRange = new Range3d(); let location; let isGeolocated = true; const bounds = fileReader.getFileBounds(); worldRange = Range3d.createXYZXYZ(bounds.getMinX(), bounds.getMinY(), bounds.getMinZ(), bounds.getMaxX(), bounds.getMaxY(), bounds.getMaxZ()); isGeolocated = false; const fileCrs = fileReader.getFileCRS(); // the CRS 9300 is not defined in the CRS registry database, so we cannot use CRSManager // Check to isGeographicCRS and isProjectedCRS are both going to return false in that case and we will fallback to // use un-georeferenced code path. await CRSManager.ENGINE.prepareForArea(fileCrs, bounds); const isGeographicCRS = CRSManager.ENGINE.isGeographicCRS(fileCrs); const isProjectedCRS = CRSManager.ENGINE.isProjectedCRS(fileCrs); if (fileCrs && (isProjectedCRS || isGeographicCRS)) { try { const wgs84ECEFCrs = "4978"; await CRSManager.ENGINE.prepareForArea(wgs84ECEFCrs, new OrbitGtBounds()); const ecefBounds = CRSManager.transformBounds(bounds, fileCrs, wgs84ECEFCrs); const ecefRange = Range3d.createXYZXYZ(ecefBounds.getMinX(), ecefBounds.getMinY(), ecefBounds.getMinZ(), ecefBounds.getMaxX(), ecefBounds.getMaxY(), ecefBounds.getMaxZ()); const ecefCenter = expectDefined(ecefRange.localXYZToWorld(.5, .5, .5)); const cartoCenter = expectDefined(Cartographic.fromEcef(ecefCenter)); cartoCenter.height = 0; const ecefLocation = EcefLocation.createFromCartographicOrigin(cartoCenter); location = ecefLocation; // this.iModelDb.setEcefLocation(ecefLocation); const ecefToWorld = expectDefined(ecefLocation.getTransform().inverse()); worldRange = ecefToWorld.multiplyRange(ecefRange); isGeolocated = true; } catch (e) { Logger.logWarning(loggerCategory, `Error getSpatialLocationAndExtents - cannot interpret point cloud`); const errorProps = BentleyError.getErrorProps(e); const getMetaData = () => { return { errorProps }; }; const error = new RealityDataError(RealityDataStatus.InvalidData, "Invalid or unknown data", getMetaData); throw error; } } else { // NoGCS case isGeolocated = false; const centerOfEarth = new EcefLocation({ origin: { x: 0.0, y: 0.0, z: 0.0 }, orientation: { yaw: 0.0, pitch: 0.0, roll: 0.0 } }); location = centerOfEarth; Logger.logTrace(loggerCategory, "OPC RealityData NOT Geolocated", () => ({ ...location })); } const spatialLocation = { location, worldRange, isGeolocated }; return spatialLocation; } } //# sourceMappingURL=OPCFormatInterpreter.js.map