123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- function parseEpt(event) {
- let buffer = event.data.buffer;
- let view = new DataView(buffer);
- let schema = event.data.schema;
- let scale = event.data.scale;
- let offset = event.data.offset;
- let mins = event.data.mins;
- let dimensions = schema.reduce((p, c) => {
- p[c.name] = c;
- return p;
- }, { });
- let dimOffset = (name) => {
- let offset = 0;
- for (var i = 0; i < schema.length; ++i) {
- if (schema[i].name == name) return offset;
- offset += schema[i].size;
- }
- return undefined;
- };
- let getExtractor = (name) => {
- let offset = dimOffset(name);
- let type = dimensions[name].type;
- let size = dimensions[name].size;
- if (type == 'signed') switch (size) {
- case 1: return (p) => view.getInt8(p + offset);
- case 2: return (p) => view.getInt16(p + offset, true);
- case 4: return (p) => view.getInt32(p + offset, true);
- case 8: return (p) => view.getInt64(p + offset, true);
- }
- if (type == 'unsigned') switch (size) {
- case 1: return (p) => view.getUint8(p + offset);
- case 2: return (p) => view.getUint16(p + offset, true);
- case 4: return (p) => view.getUint32(p + offset, true);
- case 8: return (p) => view.getUint64(p + offset, true);
- }
- if (type == 'float') switch (size) {
- case 4: return (p) => view.getFloat32(p + offset, true);
- case 8: return (p) => view.getFloat64(p + offset, true);
- }
- let str = JSON.stringify(dimensions[name]);
- throw new Error(`Invalid dimension specification for ${name}: ${str}`);
- };
- let pointSize = schema.reduce((p, c) => p + c.size, 0);
- let numPoints = buffer.byteLength / pointSize;
- let xyzBuffer, rgbBuffer, intensityBuffer, classificationBuffer,
- returnNumberBuffer, numberOfReturnsBuffer, pointSourceIdBuffer;
- let xyz, rgb, intensity, classification, returnNumber, numberOfReturns,
- pointSourceId;
- let xyzExtractor, rgbExtractor, intensityExtractor, classificationExtractor,
- returnNumberExtractor, numberOfReturnsExtractor, pointSourceIdExtractor;
- let twoByteColor = false;
- if (dimensions['X'] && dimensions['Y'] && dimensions['Z']) {
- xyzBuffer = new ArrayBuffer(numPoints * 4 * 3);
- xyz = new Float32Array(xyzBuffer);
- xyzExtractor = [
- getExtractor('X'),
- getExtractor('Y'),
- getExtractor('Z')
- ];
- }
- if (dimensions['Red'] && dimensions['Green'] && dimensions['Blue']) {
- rgbBuffer = new ArrayBuffer(numPoints * 4);
- rgb = new Uint8Array(rgbBuffer);
- rgbExtractor = [
- getExtractor('Red'),
- getExtractor('Green'),
- getExtractor('Blue')
- ];
- let r, g, b, pos;
- for (let i = 0; i < numPoints && !twoByteColor; ++i) {
- pos = i * pointSize;
- r = rgbExtractor[0](pos);
- g = rgbExtractor[1](pos);
- b = rgbExtractor[2](pos);
- if (r > 255 || g > 255 || b > 255) twoByteColor = true;
- }
- }
- if (dimensions['Intensity']) {
- intensityBuffer = new ArrayBuffer(numPoints * 4);
- intensity = new Float32Array(intensityBuffer);
- intensityExtractor = getExtractor('Intensity');
- }
- if (dimensions['Classification']) {
- classificationBuffer = new ArrayBuffer(numPoints);
- classification = new Uint8Array(classificationBuffer);
- classificationExtractor = getExtractor('Classification');
- }
- if (dimensions['ReturnNumber']) {
- returnNumberBuffer = new ArrayBuffer(numPoints);
- returnNumber = new Uint8Array(returnNumberBuffer);
- returnNumberExtractor = getExtractor('ReturnNumber');
- }
- if (dimensions['NumberOfReturns']) {
- numberOfReturnsBuffer = new ArrayBuffer(numPoints);
- numberOfReturns = new Uint8Array(numberOfReturnsBuffer);
- numberOfReturnsExtractor = getExtractor('NumberOfReturns');
- }
- if (dimensions['PointSourceId']) {
- pointSourceIdBuffer = new ArrayBuffer(numPoints * 2);
- pointSourceId = new Uint16Array(pointSourceIdBuffer);
- pointSourceIdExtractor = getExtractor('PointSourceId');
- }
- let mean = [0, 0, 0];
- let bounds = {
- min: [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE],
- max: [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE],
- };
- let x, y, z, r, g, b;
- for (let i = 0; i < numPoints; ++i) {
- let pos = i * pointSize;
- if (xyz) {
- x = xyzExtractor[0](pos) * scale.x + offset.x - mins[0];
- y = xyzExtractor[1](pos) * scale.y + offset.y - mins[1];
- z = xyzExtractor[2](pos) * scale.z + offset.z - mins[2];
- mean[0] += x / numPoints;
- mean[1] += y / numPoints;
- mean[2] += z / numPoints;
- bounds.min[0] = Math.min(bounds.min[0], x);
- bounds.min[1] = Math.min(bounds.min[1], y);
- bounds.min[2] = Math.min(bounds.min[2], z);
- bounds.max[0] = Math.max(bounds.max[0], x);
- bounds.max[1] = Math.max(bounds.max[1], y);
- bounds.max[2] = Math.max(bounds.max[2], z);
- xyz[3 * i + 0] = x;
- xyz[3 * i + 1] = y;
- xyz[3 * i + 2] = z;
- }
- if (rgb) {
- r = rgbExtractor[0](pos);
- g = rgbExtractor[1](pos);
- b = rgbExtractor[2](pos);
- if (twoByteColor) {
- r /= 256;
- g /= 256;
- b /= 256;
- }
- rgb[4 * i + 0] = r;
- rgb[4 * i + 1] = g;
- rgb[4 * i + 2] = b;
- }
- if (intensity) intensity[i] = intensityExtractor(pos);
- if (classification) classification[i] = classificationExtractor(pos);
- if (returnNumber) returnNumber[i] = returnNumberExtractor(pos);
- if (numberOfReturns) numberOfReturns[i] = numberOfReturnsExtractor(pos);
- if (pointSourceId) pointSourceId[i] = pointSourceIdExtractor(pos);
- }
- let indicesBuffer = new ArrayBuffer(numPoints * 4);
- let indices = new Uint32Array(indicesBuffer);
- for (let i = 0; i < numPoints; ++i) {
- indices[i] = i;
- }
- let message = {
- numPoints: numPoints,
- tightBoundingBox: bounds,
- mean: mean,
- position: xyzBuffer,
- color: rgbBuffer,
- intensity: intensityBuffer,
- classification: classificationBuffer,
- returnNumber: returnNumberBuffer,
- numberOfReturns: numberOfReturnsBuffer,
- pointSourceId: pointSourceIdBuffer,
- indices: indicesBuffer
- };
- let transferables = [
- message.position,
- message.color,
- message.intensity,
- message.classification,
- message.returnNumber,
- message.numberOfReturns,
- message.pointSourceId,
- message.indices
- ].filter((v) => v);
- postMessage(message, transferables);
- }
- // importScripts('/libs/ept/ParseBuffer.js');
- onmessage = function(event) {
- parseEpt(event);
- }
|