diff --git a/src/Parser/LASLoader.js b/src/Parser/LASLoader.js index 39a1c66325..cfec8080ac 100644 --- a/src/Parser/LASLoader.js +++ b/src/Parser/LASLoader.js @@ -1,5 +1,6 @@ import { LazPerf } from 'laz-perf'; import { Las } from 'copc'; +import Coordinates from 'Core/Geographic/Coordinates'; /** * @typedef {Object} Header - Partial LAS header. @@ -56,6 +57,9 @@ class LASLoader { const getScanAngle = view.getter('ScanAngle'); const positions = new Float32Array(view.pointCount * 3); + const positionsProj = new Float32Array(view.pointCount * 3); + const elevations = new Float32Array(view.pointCount); + const intensities = new Uint16Array(view.pointCount); const returnNumbers = new Uint8Array(view.pointCount); const numberOfReturns = new Uint8Array(view.pointCount); @@ -71,6 +75,9 @@ class LASLoader { */ const scanAngles = new Float32Array(view.pointCount); + const coord = new Coordinates(options.crsIn, 0, 0, 0); + const coordProj = new Coordinates(options.crsOut, 0, 0, 0); + for (let i = 0; i < view.pointCount; i++) { // `getPosition` apply scale and offset transform to the X, Y, Z // values. See https://github.com/connormanning/copc.js/blob/master/src/las/extractor.ts. @@ -79,6 +86,20 @@ class LASLoader { positions[i * 3 + 1] = y; positions[i * 3 + 2] = z; + // Calculate positions on view.crs + coord.setFromValues( + positions[i * 3], + positions[i * 3 + 1], + positions[i * 3 + 2], + ); + coord.as(options.crsOut, coordProj); + positionsProj[i * 3] = coordProj.x; + positionsProj[i * 3 + 1] = coordProj.y; + positionsProj[i * 3 + 2] = coordProj.z; + elevations[i] = coordProj.z; + // geocentric height to elevation + if (options.crsOut === 'EPSG:4978') { elevations[i] = positions[i * 3 + 2]; } + intensities[i] = getIntensity(i); returnNumbers[i] = getReturnNumber(i); numberOfReturns[i] = getNumberOfReturns(i); @@ -108,6 +129,8 @@ class LASLoader { return { position: positions, + elevation: elevations, + positionProj: positionsProj, intensity: intensities, returnNumber: returnNumbers, numberOfReturns, @@ -151,11 +174,10 @@ class LASLoader { const eb = ebVlr && Las.ExtraBytes.parse(await Las.Vlr.fetch(getter, ebVlr)); const view = Las.View.create(pointData, header, eb); - const attributes = this._parseView(view, { colorDepth }); + const attributes = this._parseView(view, { colorDepth, crsIn: options.crsIn, crsOut: options.crsOut }); return { header, attributes, - pointCount: view.pointCount, }; } } diff --git a/src/Parser/LASParser.js b/src/Parser/LASParser.js index c38199d72a..3ea7d20782 100644 --- a/src/Parser/LASParser.js +++ b/src/Parser/LASParser.js @@ -1,6 +1,5 @@ import * as THREE from 'three'; import LASLoader from 'Parser/LASLoader'; -import Coordinates from 'Core/Geographic/Coordinates'; const lasLoader = new LASLoader(); @@ -43,33 +42,16 @@ export default { } return lasLoader.parseFile(data, { colorDepth: options.in?.colorDepth, + crsIn: options.in.crs, + crsOut: options.out.crs, }).then((parsedData) => { const geometry = new THREE.BufferGeometry(); const attributes = parsedData.attributes; geometry.userData = parsedData.header; - const coord = new Coordinates(options.in.crs, 0, 0, 0); - const coordOut = new Coordinates(options.out.crs, 0, 0, 0); - const positionsProj = new Float32Array(parsedData.pointCount * 3); - const elevations = new Float32Array(parsedData.pointCount); - - for (let i = 0; i < parsedData.pointCount; i++) { - coord.setFromValues( - attributes.position[i * 3], - attributes.position[i * 3 + 1], - attributes.position[i * 3 + 2], - ); - coord.as(options.out.crs, coordOut); - positionsProj[i * 3] = coordOut.x; - positionsProj[i * 3 + 1] = coordOut.y; - positionsProj[i * 3 + 2] = coordOut.z; - elevations[i] = coordOut.z; - if (options.out.crs === 'EPSG:4978') { elevations[i] = attributes.position[i * 3 + 2]; } - } - - const positionBuffer = new THREE.BufferAttribute(positionsProj, 3); + const positionBuffer = new THREE.BufferAttribute(attributes.positionProj, 3); geometry.setAttribute('position', positionBuffer); - const elevationBuffer = new THREE.BufferAttribute(elevations, 1); + const elevationBuffer = new THREE.BufferAttribute(attributes.elevation, 1); geometry.setAttribute('elevation', elevationBuffer); const intensityBuffer = new THREE.BufferAttribute(attributes.intensity, 1);