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

iTowns / itowns / 11342622151

15 Oct 2024 08:52AM UTC coverage: 87.082% (+0.1%) from 86.936%
11342622151

Pull #2422

github

web-flow
Merge 1f594815d into cfb9d0f51
Pull Request #2422: Preparation for PR reprojection 'a la volee'

2818 of 3739 branches covered (75.37%)

Branch coverage included in aggregate %.

37 of 42 new or added lines in 5 files covered. (88.1%)

5 existing lines in 2 files now uncovered.

24550 of 27689 relevant lines covered (88.66%)

1183.5 hits per line

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

95.07
/src/Source/CopcSource.js
1
import proj4 from 'proj4';
1✔
2
import { Binary, Info, Las } from 'copc';
1✔
3
import Extent from 'Core/Geographic/Extent';
1✔
4
import Fetcher from 'Provider/Fetcher';
1✔
5
import LASParser from 'Parser/LASParser';
1✔
6
import Source from 'Source/Source';
1✔
7
import * as THREE from 'three';
1✔
8

1✔
9
/**
1✔
10
 * @param {function(number, number):Promise<Uint8Array>} fetcher
1✔
11
 */
1✔
12
async function getHeaders(fetcher) {
1✔
13
    const header =
1✔
14
        Las.Header.parse(await fetcher(0, Las.Constants.minHeaderLength));
1✔
15
    const vlrs = await Las.Vlr.walk(fetcher, header);
1✔
16

1✔
17
    // info VLR: required by COPC
1✔
18
    const infoVlr = Las.Vlr.find(vlrs, 'copc', 1);
1✔
19
    if (!infoVlr) { return Promise.reject('COPC info VLR is required'); }
1!
20
    const info = Info.parse(await Las.Vlr.fetch(fetcher, infoVlr));
1✔
21

1✔
22
    // OGC Coordinate System WKT: required by LAS1.4
1✔
23
    const wktVlr = Las.Vlr.find(vlrs, 'LASF_Projection', 2112);
1✔
24
    if (!wktVlr) { return Promise.reject('LAS1.4 WKT VLR is required'); }
1!
25
    const wkt = Binary.toCString(await Las.Vlr.fetch(fetcher, wktVlr));
1✔
26

1✔
27
    // Extra bytes: optional by LAS1.4
1✔
28
    const ebVlr = Las.Vlr.find(vlrs, 'LASF_Spec', 4);
1✔
29
    const eb = ebVlr ?
1!
30
        Las.ExtraBytes.parse(await Las.Vlr.fetch(fetcher, ebVlr)) :
1✔
31
        [];
1✔
32

1✔
33
    return { header, info, wkt, eb };
1✔
34
}
1✔
35

1✔
36
/**
1✔
37
 * A source for [Cloud Optimised Point Cloud](https://copc.io/) (COPC) data.
1✔
38
 * Such data consists of a [LAZ 1.4](https://www.ogc.org/standard/las/) file
1✔
39
 * that stores compressed points data organized in a clustered octree.
1✔
40
 *
1✔
41
 * A freshly created source fetches and parses portions of the file
1✔
42
 * corresponding to the LAS 1.4 header, all the Variable Length Record (VLR)
1✔
43
 * headers as well the following VLRs:
1✔
44
 * - COPC [`info`](https://copc.io/#info-vlr) record (mandatory)
1✔
45
 * - LAS 1.4 `OGC Coordinate System WKT` record (mandatory, see [Las 1.4
1✔
46
 *   spec](https://portal.ogc.org/files/?artifact_id=74523))
1✔
47
 * - LAS 1.4 `Extra Bytes` record (optional, see [Las 1.4
1✔
48
 *   spec](https://portal.ogc.org/files/?artifact_id=74523))
1✔
49
 *
1✔
50
 * @extends {Source}
1✔
51
 *
1✔
52
 * @property {boolean} isCopcSource - Read-only flag to check that a given
1✔
53
 * object is of type CopcSource.
1✔
54
 * @property {Object} header - LAS header of the source.
1✔
55
 * @property {Object[]} eb - List of headers of each Variable Length Records
1✔
56
 * (VLRs).
1✔
57
 * @property {Object} info - COPC `info` VLR.
1✔
58
 * @property {number[]} info.cube - Bounding box of the octree as a 6-elements.
1✔
59
 * tuple `[minX, minY, minZ, maxX, maxY, maxZ]`. Computed from `center_x`,
1✔
60
 * `center_y`, `center_z` and `halfSize` properties.
1✔
61
 * @property {Object} info.rootHierarchyPage - Hierarchy page of the root node.
1✔
62
 * @property {number} info.rootHierarchyPage.pageOffset - Absolute Offset to the
1✔
63
 * root node data chunk.
1✔
64
 * @property {number} info.rootHierarchyPage.pageOffset - Size (in bytes) of the
1✔
65
 * root node data chunk.
1✔
66
 * @property {number[]} gpsTimeRange - A 2-element tuple denoting the minimum
1✔
67
 * and maximum values of attribute `gpsTime`.
1✔
68
 */
1✔
69
class CopcSource extends Source {
1✔
70
    /**
1✔
71
     * @param {Object} config - Source configuration
1✔
72
     * @param {string} config.url - URL of the COPC resource.
1✔
73
     * @param {8 | 16} [config.colorDepth=16] - Encoding of the `color`
1✔
74
     * attribute. Either `8` or `16` bits.
1✔
75
     * @param {string} [config._lazPerfBaseUrl] - (experimental) Overrides base
1✔
76
     * url of the `las-zip.wasm` file of the `laz-perf` library.
1✔
77
     * @param {string} [config.crs='EPSG:4326'] - Native CRS of the COPC
1✔
78
     * ressource. Note that this is not for now inferred from the COPC header.
1✔
79
     * @param {RequestInit} [config.networkOptions] - Fetch options (passed
1✔
80
     * directly to `fetch()`), see [the syntax for more information](
1✔
81
     * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Syntax).
1✔
82
     * @param {Object} [config.attribution] - Attribution of the data.
1✔
83
     */
1✔
84
    constructor(config) {
1✔
85
        super(config);
1✔
86

1✔
87
        this.isCopcSource = true;
1✔
88

1✔
89
        this.parser = LASParser.parseChunk;
1✔
90
        this.fetcher = Fetcher.arrayBuffer;
1✔
91

1✔
92
        this.colorDepth = config.colorDepth ?? 16;
1✔
93

1✔
94
        const get = (/** @type {number} */ begin, /** @type {number} */ end) =>
1✔
95
            this.fetcher(this.url, {
7✔
96
                ...this.networkOptions,
7✔
97
                headers: {
7✔
98
                    ...this.networkOptions.headers,
7✔
99
                    range: `bytes=${begin}-${end - 1}`,
7✔
100
                },
7✔
101
            }).then(buffer => new Uint8Array(buffer));
1✔
102
        this.whenReady = getHeaders(get).then((metadata) => {
1✔
103
            this.header = metadata.header;
1✔
104
            this.info = metadata.info;
1✔
105
            this.eb = metadata.eb;
1✔
106

1✔
107
            proj4.defs('unknown', metadata.wkt);
1✔
108
            let projCS;
1✔
109

1✔
110
            if (proj4.defs('unknown').type === 'COMPD_CS') {
1✔
111
                console.warn('CopcSource: compound coordinate system is not yet supported.');
1✔
112
                projCS = proj4.defs('unknown').PROJCS;
1✔
113
            } else {
1!
NEW
114
                projCS = proj4.defs('unknown');
×
NEW
115
            }
×
116

1✔
117
            this.crs = projCS.title || projCS.name || 'EPSG:4326';
1!
118
            if (!(this.crs in proj4.defs)) {
1✔
119
                proj4.defs(this.crs, projCS);
1✔
120
            }
1✔
121

1✔
122
            const bbox = new THREE.Box3();
1✔
123
            bbox.min.fromArray(this.info.cube, 0);
1✔
124
            bbox.max.fromArray(this.info.cube, 3);
1✔
125
            this.extent = Extent.fromBox3(this.crs, bbox);
1✔
126

1✔
127
            return this;
1✔
128
        });
1✔
129
    }
1✔
130
}
1✔
131

1✔
132
export default CopcSource;
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