This commit is contained in:
Andreas Wilms
2025-09-08 16:25:55 +02:00
commit cdcd870b6f
614 changed files with 343437 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Uday Verma, uday.karan@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,398 @@
// laslaz.js
// LAS/LAZ loading
//
//var common = require("./common"),
// Promise = require("bluebird");
(function(scope) {
"use strict";
var pointFormatReaders = {
0: function(dv) {
return {
"position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
"intensity": dv.getUint16(12, true),
"classification": dv.getUint8(16, true)
};
},
1: function(dv) {
return {
"position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
"intensity": dv.getUint16(12, true),
"classification": dv.getUint8(16, true)
};
},
2: function(dv) {
return {
"position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
"intensity": dv.getUint16(12, true),
"classification": dv.getUint8(16, true),
"color": [dv.getUint16(20, true), dv.getUint16(22, true), dv.getUint16(24, true)]
};
},
3: function(dv) {
return {
"position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],
"intensity": dv.getUint16(12, true),
"classification": dv.getUint8(16, true),
"color": [dv.getUint16(28, true), dv.getUint16(30, true), dv.getUint16(32, true)]
};
}
};
function readAs(buf, Type, offset, count) {
count = (count === undefined || count === 0 ? 1 : count);
var sub = buf.slice(offset, offset + Type.BYTES_PER_ELEMENT * count);
var r = new Type(sub);
if (count === undefined || count === 1)
return r[0];
var ret = [];
for (var i = 0 ; i < count ; i ++) {
ret.push(r[i]);
}
return ret;
}
function parseLASHeader(arraybuffer) {
var o = {};
o.pointsOffset = readAs(arraybuffer, Uint32Array, 32*3);
o.pointsFormatId = readAs(arraybuffer, Uint8Array, 32*3+8);
o.pointsStructSize = readAs(arraybuffer, Uint16Array, 32*3+8+1);
o.pointsCount = readAs(arraybuffer, Uint32Array, 32*3 + 11);
var start = 32*3 + 35;
o.scale = readAs(arraybuffer, Float64Array, start, 3); start += 24; // 8*3
o.offset = readAs(arraybuffer, Float64Array, start, 3); start += 24;
var bounds = readAs(arraybuffer, Float64Array, start, 6); start += 48; // 8*6;
o.maxs = [bounds[0], bounds[2], bounds[4]];
o.mins = [bounds[1], bounds[3], bounds[5]];
return o;
}
var msgIndex = 0;
var waitHandlers = {};
// This method is scope-wide since the nacl module uses this fuction to notify
// us of events
scope.handleMessage = function(message_event) {
var msg = message_event.data;
var resolver = waitHandlers[msg.id];
delete waitHandlers[msg.id];
// call the callback in a separate context, make sure we've cleaned our
// state out before the callback is invoked since it may queue more doExchanges
setTimeout(function() {
if (msg.error)
return resolver.reject(new Error(msg.message || "Unknown Error"));
if (msg.hasOwnProperty('count') && msg.hasOwnProperty('hasMoreData')) {
return resolver.resolve({
buffer: msg.result,
count: msg.count,
hasMoreData: msg.hasMoreData});
}
resolver.resolve(msg.result);
}, 0);
};
var doDataExchange = function(cmd, callback) {
cmd.id = msgIndex.toString();
msgIndex ++;
var resolver = Promise.defer();
waitHandlers[cmd.id] = resolver;
nacl_module.postMessage(cmd);
return resolver.promise.cancellable();
};
// LAS Loader
// Loads uncompressed files
//
var LASLoader = function(arraybuffer) {
this.arraybuffer = arraybuffer;
};
LASLoader.prototype.open = function() {
// nothing needs to be done to open this file
//
this.readOffset = 0;
return new Promise(function(res, rej) {
setTimeout(res, 0);
});
};
LASLoader.prototype.getHeader = function() {
var o = this;
return new Promise(function(res, rej) {
setTimeout(function() {
o.header = parseLASHeader(o.arraybuffer);
res(o.header);
}, 0);
});
};
LASLoader.prototype.readData = function(count, offset, skip) {
var o = this;
return new Promise(function(res, rej) {
setTimeout(function() {
if (!o.header)
return rej(new Error("Cannot start reading data till a header request is issued"));
var start;
if (skip <= 1) {
count = Math.min(count, o.header.pointsCount - o.readOffset);
start = o.header.pointsOffset + o.readOffset * o.header.pointsStructSize;
var end = start + count * o.header.pointsStructSize;
res({
buffer: o.arraybuffer.slice(start, end),
count: count,
hasMoreData: o.readOffset + count < o.header.pointsCount});
o.readOffset += count;
}
else {
var pointsToRead = Math.min(count * skip, o.header.pointsCount - o.readOffset);
var bufferSize = Math.ceil(pointsToRead / skip);
var pointsRead = 0;
var buf = new Uint8Array(bufferSize * o.header.pointsStructSize);
for (var i = 0 ; i < pointsToRead ; i ++) {
if (i % skip === 0) {
start = o.header.pointsOffset + o.readOffset * o.header.pointsStructSize;
var src = new Uint8Array(o.arraybuffer, start, o.header.pointsStructSize);
buf.set(src, pointsRead * o.header.pointsStructSize);
pointsRead ++;
}
o.readOffset ++;
}
res({
buffer: buf.buffer,
count: pointsRead,
hasMoreData: o.readOffset < o.header.pointsCount
});
}
}, 0);
});
};
LASLoader.prototype.close = function() {
var o = this;
return new Promise(function(res, rej) {
o.arraybuffer = null;
setTimeout(res, 0);
});
};
// LAZ Loader
// Uses NaCL module to load LAZ files
//
var LAZLoader = function(arraybuffer) {
this.arraybuffer = arraybuffer;
let workerPath = Potree.scriptPath + "/workers/LASLAZWorker.js";
this.ww = Potree.workerPool.getWorker(workerPath);
this.nextCB = null;
var o = this;
this.ww.onmessage = function(e) {
if (o.nextCB !== null) {
o.nextCB(e.data);
o.nextCB = null;
}
};
this.dorr = function(req, cb) {
o.nextCB = cb;
o.ww.postMessage(req);
};
};
LAZLoader.prototype.open = function() {
// nothing needs to be done to open this file
//
var o = this;
return new Promise(function(res, rej) {
o.dorr({type:"open", arraybuffer: o.arraybuffer}, function(r) {
if (r.status !== 1)
return rej(new Error("Failed to open file"));
res(true);
});
});
};
LAZLoader.prototype.getHeader = function() {
var o = this;
return new Promise(function(res, rej) {
o.dorr({type:'header'}, function(r) {
if (r.status !== 1)
return rej(new Error("Failed to get header"));
res(r.header);
});
});
};
LAZLoader.prototype.readData = function(count, offset, skip) {
var o = this;
return new Promise(function(res, rej) {
o.dorr({type:'read', count: count, offset: offset, skip: skip}, function(r) {
if (r.status !== 1)
return rej(new Error("Failed to read data"));
res({
buffer: r.buffer,
count: r.count,
hasMoreData: r.hasMoreData
});
});
});
};
LAZLoader.prototype.close = function() {
var o = this;
return new Promise(function(res, rej) {
o.dorr({type:'close'}, function(r) {
let workerPath = Potree.scriptPath + "/workers/LASLAZWorker.js";
Potree.workerPool.returnWorker(workerPath, o.ww);
if (r.status !== 1)
return rej(new Error("Failed to close file"));
res(true);
});
});
};
// A single consistent interface for loading LAS/LAZ files
var LASFile = function(arraybuffer) {
this.arraybuffer = arraybuffer;
this.determineVersion();
if (this.version > 12)
throw new Error("Only file versions <= 1.2 are supported at this time");
this.determineFormat();
if (pointFormatReaders[this.formatId] === undefined)
throw new Error("The point format ID is not supported");
this.loader = this.isCompressed ?
new LAZLoader(this.arraybuffer) :
new LASLoader(this.arraybuffer);
};
LASFile.prototype.determineFormat = function() {
var formatId = readAs(this.arraybuffer, Uint8Array, 32*3+8);
var bit_7 = (formatId & 0x80) >> 7;
var bit_6 = (formatId & 0x40) >> 6;
if (bit_7 === 1 && bit_6 === 1)
throw new Error("Old style compression not supported");
this.formatId = formatId & 0x3f;
this.isCompressed = (bit_7 === 1 || bit_6 === 1);
};
LASFile.prototype.determineVersion = function() {
var ver = new Int8Array(this.arraybuffer, 24, 2);
this.version = ver[0] * 10 + ver[1];
this.versionAsString = ver[0] + "." + ver[1];
};
LASFile.prototype.open = function() {
return this.loader.open();
};
LASFile.prototype.getHeader = function() {
return this.loader.getHeader();
};
LASFile.prototype.readData = function(count, start, skip) {
return this.loader.readData(count, start, skip);
};
LASFile.prototype.close = function() {
return this.loader.close();
};
// Decodes LAS records into points
//
var LASDecoder = function(buffer, pointFormatID, pointSize, pointsCount, scale, offset, mins, maxs) {
this.arrayb = buffer;
this.decoder = pointFormatReaders[pointFormatID];
this.pointsCount = pointsCount;
this.pointSize = pointSize;
this.scale = scale;
this.offset = offset;
this.mins = mins;
this.maxs = maxs;
};
LASDecoder.prototype.getPoint = function(index) {
if (index < 0 || index >= this.pointsCount)
throw new Error("Point index out of range");
var dv = new DataView(this.arrayb, index * this.pointSize, this.pointSize);
return this.decoder(dv);
};
// NACL Module support
// Called by the common.js module.
//
//window.startNaCl = function(name, tc, config, width, height) {
// // check browser support for nacl
// //
// if(!common.browserSupportsNaCl()) {
// return $.event.trigger({
// type: "plasio.nacl.error",
// message: "NaCl support is not available"
// });
// }
// navigator.webkitPersistentStorage.requestQuota(2048 * 2048, function(bytes) {
// common.updateStatus(
// 'Allocated ' + bytes + ' bytes of persistant storage.');
// common.attachDefaultListeners();
// common.createNaClModule(name, tc, config, width, height);
// },
// function(e) {
// $.event.trigger({
// type: "plasio.nacl.error",
// message: "Could not allocate persistant storage"
// });
// });
// $(document).on("plasio.nacl.available", function() {
// scope.LASModuleWasLoaded = true;
// });
//};
scope.LAZLoader = LAZLoader;
scope.LASLoader = LASLoader;
scope.LASFile = LASFile;
scope.LASDecoder = LASDecoder;
scope.LASModuleWasLoaded = false;
//})(module.exports);
})(this);

5140
PCSurvey/libs/plasio/vendor/bluebird.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
// laz-loader-worker.js
//
//importScripts('laz-perf.js');
let instance = null; // laz-perf instance
function readAs(buf, Type, offset, count) {
count = (count === undefined || count === 0 ? 1 : count);
var sub = buf.slice(offset, offset + Type.BYTES_PER_ELEMENT * count);
var r = new Type(sub);
if (count === undefined || count === 1)
return r[0];
var ret = [];
for (var i = 0 ; i < count ; i ++) {
ret.push(r[i]);
}
return ret;
}
function parseLASHeader(arraybuffer) {
var o = {};
o.pointsOffset = readAs(arraybuffer, Uint32Array, 32*3);
o.pointsFormatId = readAs(arraybuffer, Uint8Array, 32*3+8);
o.pointsStructSize = readAs(arraybuffer, Uint16Array, 32*3+8+1);
o.pointsCount = readAs(arraybuffer, Uint32Array, 32*3 + 11);
var start = 32*3 + 35;
o.scale = readAs(arraybuffer, Float64Array, start, 3); start += 24; // 8*3
o.offset = readAs(arraybuffer, Float64Array, start, 3); start += 24;
var bounds = readAs(arraybuffer, Float64Array, start, 6); start += 48; // 8*6;
o.maxs = [bounds[0], bounds[2], bounds[4]];
o.mins = [bounds[1], bounds[3], bounds[5]];
return o;
}
function handleEvent(msg) {
switch(msg.type) {
case "open":
try {
instance = new Module.LASZip();
var abInt = new Uint8Array(msg.arraybuffer);
var buf = Module._malloc(msg.arraybuffer.byteLength);
instance.arraybuffer = msg.arraybuffer;
instance.buf = buf;
Module.HEAPU8.set(abInt, buf);
instance.open(buf, msg.arraybuffer.byteLength);
instance.readOffset = 0;
postMessage({ type: "open", status: 1});
}catch(e) {
debugger;
postMessage({ type: "open", status: 0, details: e });
}
break;
case "header":
if (!instance)
throw new Error("You need to open the file before trying to read header");
var header = parseLASHeader(instance.arraybuffer);
header.pointsFormatId &= 0x3f;
instance.header = header;
postMessage({type: "header", status: 1, header: header});
break;
case "read":
if (!instance)
throw new Error("You need to open the file before trying to read stuff");
var start = msg.start, count = msg.count, skip = msg.skip;
var o = instance;
if (!o.header)
throw new Error("You need to query header before reading, I maintain state that way, sorry :(");
var pointsToRead = Math.min(count * skip, o.header.pointsCount - o.readOffset);
var bufferSize = Math.ceil(pointsToRead / skip);
var pointsRead = 0;
let buffer = new ArrayBuffer(bufferSize * o.header.pointsStructSize);
let this_buf = new Uint8Array(buffer);
var buf_read = Module._malloc(o.header.pointsStructSize);
for (var i = 0 ; i < pointsToRead ; i ++) {
o.getPoint(buf_read);
if (i % skip === 0) {
var a = new Uint8Array(Module.HEAPU8.buffer, buf_read, o.header.pointsStructSize);
this_buf.set(a, pointsRead * o.header.pointsStructSize, o.header.pointsStructSize);
pointsRead ++;
}
o.readOffset ++;
}
Module._free(buf_read);
let transferables = [buffer];
postMessage({
type: 'header',
status: 1,
buffer: buffer,
count: pointsRead,
hasMoreData: o.readOffset < o.header.pointsCount
}, transferables);
break;
case "close":
if (instance !== null) {
Module._free(instance.buf);
instance.delete();
instance = null;
}else{
debugger;
}
postMessage({ type: "close", status: 1});
break;
}
}
onmessage = function(event) {
try {
handleEvent(event.data);
} catch(e) {
debugger;
postMessage({type: event.data.type, status: 0, details: e});
}
};

File diff suppressed because one or more lines are too long