• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

iTowns / itowns / 10635241580

30 Aug 2024 03:26PM UTC coverage: 86.966% (-2.8%) from 89.766%
10635241580

push

github

jailln
feat(3dtiles): add new OGC3DTilesLayer using 3d-tiles-renderer-js

Deprecate C3DTilesLayer (replaced by OGC3DTilesLayer).
Add new iGLTFLoader that loads gltf 1.0 and 2.0 files.

2791 of 3694 branches covered (75.55%)

Branch coverage included in aggregate %.

480 of 644 new or added lines in 8 files covered. (74.53%)

2144 existing lines in 111 files now uncovered.

24319 of 27479 relevant lines covered (88.5%)

1024.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.29
/src/Parser/LASParser.js
1
import * as THREE from 'three';
1✔
2
import { spawn, Thread, Transfer } from 'threads';
1✔
3

1✔
4
let _lazPerf;
1✔
5
let _thread;
1✔
6

1✔
7
function workerInstance() {
3✔
8
    return new Worker(
3✔
9
        /* webpackChunkName: "itowns_lasparser" */
3✔
10
        new URL('../Worker/LASLoaderWorker.js', import.meta.url),
3✔
11
        { type: 'module' },
3✔
12
    );
3✔
13
}
3✔
14

1✔
15
async function loader() {
3✔
16
    if (_thread) { return _thread; }
3!
17
    _thread = await spawn(workerInstance());
3✔
18
    if (_lazPerf) { _thread.lazPerf(_lazPerf); }
3✔
19
    return _thread;
3✔
20
}
3✔
21

1✔
22
function buildBufferGeometry(attributes) {
2✔
23
    const geometry = new THREE.BufferGeometry();
2✔
24

2✔
25
    const positionBuffer = new THREE.BufferAttribute(attributes.position, 3);
2✔
26
    geometry.setAttribute('position', positionBuffer);
2✔
27

2✔
28
    const intensityBuffer = new THREE.BufferAttribute(attributes.intensity, 1);
2✔
29
    geometry.setAttribute('intensity', intensityBuffer);
2✔
30

2✔
31
    const returnNumber = new THREE.BufferAttribute(attributes.returnNumber, 1);
2✔
32
    geometry.setAttribute('returnNumber', returnNumber);
2✔
33

2✔
34
    const numberOfReturns = new THREE.BufferAttribute(attributes.numberOfReturns, 1);
2✔
35
    geometry.setAttribute('numberOfReturns', numberOfReturns);
2✔
36

2✔
37
    const classBuffer = new THREE.BufferAttribute(attributes.classification, 1);
2✔
38
    geometry.setAttribute('classification', classBuffer);
2✔
39

2✔
40
    const pointSourceID = new THREE.BufferAttribute(attributes.pointSourceID, 1);
2✔
41
    geometry.setAttribute('pointSourceID', pointSourceID);
2✔
42

2✔
43
    if (attributes.color) {
2✔
44
        const colorBuffer = new THREE.BufferAttribute(attributes.color, 4, true);
1✔
45
        geometry.setAttribute('color', colorBuffer);
1✔
46
    }
1✔
47
    const scanAngle = new THREE.BufferAttribute(attributes.scanAngle, 1);
2✔
48
    geometry.setAttribute('scanAngle', scanAngle);
2✔
49

2✔
50
    geometry.userData.origin = new THREE.Vector3().fromArray(attributes.origin);
2✔
51

2✔
52
    return geometry;
2✔
53
}
2✔
54

1✔
55
/** The LASParser module provides a [parse]{@link
1✔
56
 * module:LASParser.parse} method that takes a LAS or LAZ (LASZip) file in, and
1✔
57
 * gives a `THREE.BufferGeometry` containing all the necessary attributes to be
1✔
58
 * displayed in iTowns. It uses the
1✔
59
 * [copc.js](https://github.com/connormanning/copc.js/) library.
1✔
60
 *
1✔
61
 * @module LASParser
1✔
62
 */
1✔
63
export default {
1✔
64
    /*
1✔
65
     * Set the laz-perf decoder path.
1✔
66
     * @param {string} path - path to `laz-perf.wasm` folder.
1✔
67
     */
1✔
68
    enableLazPerf(path) {
1✔
69
        if (!path) {
2!
UNCOV
70
            throw new Error('Path to laz-perf is mandatory');
×
UNCOV
71
        }
×
72
        _lazPerf = path;
2✔
73
    },
1✔
74

1✔
75
    /**
1✔
76
     * Terminate all worker instances.
1✔
77
     * @returns {Promise<void>}
1✔
78
     */
1✔
79
    terminate() {
1✔
80
        const currentThread = _thread;
3✔
81
        _thread = undefined;
3✔
82
        return Thread.terminate(currentThread);
3✔
83
    },
1✔
84

1✔
85
    /**
1✔
86
     * Parses a chunk of a LAS or LAZ (LASZip) and returns the corresponding
1✔
87
     * `THREE.BufferGeometry`.
1✔
88
     *
1✔
89
     * @param {ArrayBuffer} data - The file content to parse.
1✔
90
     * @param {Object} options
1✔
91
     * @param {Object} options.in - Options to give to the parser.
1✔
92
     * @param {number} options.in.pointCount - Number of points encoded in this
1✔
93
     * data chunk.
1✔
94
     * @param {Object} options.in.header - Partial LAS file header.
1✔
95
     * @param {number} options.in.header.pointDataRecordFormat - Type of Point
1✔
96
     * Data Record contained in the LAS file.
1✔
97
     * @param {number} options.in.header.pointDataRecordLength - Size (in bytes)
1✔
98
     * of the Point Data Record.
1✔
99
     * @param {Object} [options.eb] - Extra bytes LAS VLRs headers.
1✔
100
     * @param { 8 | 16 } [options.in.colorDepth] - Color depth (in bits).
1✔
101
     * Defaults to 8 bits for LAS 1.2 and 16 bits for later versions
1✔
102
     * (as mandatory by the specification)
1✔
103
     *
1✔
104
     * @return {Promise<THREE.BufferGeometry>} A promise resolving with a
1✔
105
     * `THREE.BufferGeometry`.
1✔
106
     */
1✔
107
    async parseChunk(data, options = {}) {
1✔
108
        const lasLoader = await loader();
×
109
        const parsedData = await lasLoader.parseChunk(Transfer(data), {
×
110
            pointCount: options.in.pointCount,
×
111
            header: options.in.header,
×
112
            eb: options.eb,
×
UNCOV
113
            colorDepth: options.in.colorDepth,
×
UNCOV
114
        });
×
UNCOV
115

×
UNCOV
116
        const geometry = buildBufferGeometry(parsedData.attributes);
×
UNCOV
117
        geometry.computeBoundingBox();
×
UNCOV
118
        return geometry;
×
119
    },
1✔
120

1✔
121
    /**
1✔
122
     * Parses a LAS file or a LAZ (LASZip) file and return the corresponding
1✔
123
     * `THREE.BufferGeometry`.
1✔
124
     *
1✔
125
     * @param {ArrayBuffer} data - The file content to parse.
1✔
126
     * @param {Object} [options]
1✔
127
     * @param {Object} [options.in] - Options to give to the parser.
1✔
128
     * @param { 8 | 16 } [options.in.colorDepth] - Color depth (in bits).
1✔
129
     * Defaults to 8 bits for LAS 1.2 and 16 bits for later versions
1✔
130
     * (as mandatory by the specification)
1✔
131
     *
1✔
132
     * @return {Promise} A promise resolving with a `THREE.BufferGeometry`. The
1✔
133
     * header of the file is contained in `userData`.
1✔
134
     */
1✔
135
    async parse(data, options = {}) {
1✔
136
        if (options.out?.skip) {
3!
UNCOV
137
            console.warn("Warning: options 'skip' not supported anymore");
×
UNCOV
138
        }
×
139

3✔
140
        const input = options.in;
3✔
141

3✔
142
        const lasLoader = await loader();
3✔
143
        const parsedData = await lasLoader.parseFile(Transfer(data), {
3✔
144
            colorDepth: input?.colorDepth,
3✔
145
        });
3✔
146

2✔
147
        const geometry = buildBufferGeometry(parsedData.attributes);
2✔
148
        geometry.userData.header = parsedData.header;
2✔
149
        geometry.computeBoundingBox();
2✔
150
        return geometry;
2✔
151
    },
2✔
152
};
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc