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

iTowns / itowns / 21708227267

05 Feb 2026 10:37AM UTC coverage: 88.096% (+0.05%) from 88.045%
21708227267

Pull #2685

github

web-flow
Merge 4dc0865cf into 483bfa8e5
Pull Request #2685: Add automatic ESPG projection fetching, generic examples for point clouds & a lil bit of cleaning

2777 of 3588 branches covered (77.4%)

Branch coverage included in aggregate %.

64 of 105 new or added lines in 5 files covered. (60.95%)

2 existing lines in 1 file now uncovered.

28335 of 31728 relevant lines covered (89.31%)

930.92 hits per line

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

94.86
/packages/Main/src/Source/PotreeSource.ts
1
import Source from 'Source/Source';
1✔
2
import Fetcher from 'Provider/Fetcher';
1✔
3
import PotreeBinParser from 'Parser/PotreeBinParser';
1✔
4

1✔
5
type PotreeBBox = {
1✔
6
    lx: number; ly: number; lz: number;
1✔
7
    ux: number; uy: number; uz: number;
1✔
8
}
1✔
9

1✔
10
interface PotreeCloud {
1✔
11
    boundingBox: PotreeBBox;
1✔
12
    tightBoundingBox: PotreeBBox;
1✔
13
    pointAttributes: 'LAS' | 'LAZ' | /* BINARY format */ string[];
1✔
14
    spacing: number;
1✔
15
    scale: number;
1✔
16
    hierarchyStepSize: number;
1✔
17
    octreeDir: string;
1✔
18
}
1✔
19

1✔
20
interface PotreeSourceParameters {
1✔
21
    /**
1✔
22
     * URL of the cloud.js file, or base URL of the pointcloud if `file` is
1✔
23
     * provided (deprecated).
1✔
24
     */
1✔
25
    url: string;
1✔
26
    /**
1✔
27
     * @deprecated Use `url` parameter with the full URL to the cloud.js file
1✔
28
     * instead.
1✔
29
     */
1✔
30
    file?: string;
1✔
31
    crs: string;
1✔
32
    cloud?: PotreeCloud;
1✔
33
    networkOptions?: RequestInit;
1✔
34
}
1✔
35

1✔
36
/**
1✔
37
 * PotreeSource are object containing informations on how to fetch
1✔
38
 * points cloud resources.
1✔
39
 *
1✔
40
 */
1✔
41

1✔
42
class PotreeSource extends Source {
1✔
43
    extensionOctree: 'hrc';
1✔
44

1✔
45
    // Properties initialized after fetching cloud file
1✔
46
    boundsConforming!: [number, number, number, number, number, number];
1✔
47
    pointAttributes!: string[];
1✔
48
    baseurl!: string;
1✔
49
    scale!: number;
1✔
50
    zmin!: number;
1✔
51
    zmax!: number;
1✔
52
    spacing!: number;
1✔
53
    hierarchyStepSize!: number;
1✔
54

1✔
55
    /**
1✔
56
     * @param source - An object that can contain all properties of a
1✔
57
     * PotreeSource.
1✔
58
     *
1✔
59
     * This `cloud` file stores information about the potree cloud in
1✔
60
     * JSON format. The structure is :
1✔
61
     * * __`version`__ - The cloud.js format may change over time. The version
1✔
62
     * number is necessary so that parsers know how to interpret the data.
1✔
63
     * * __`octreeDir`__ - Directory or URL where node data is stored.
1✔
64
     *          Usually points to "data".
1✔
65
     * * __`boundingBox`__ - Contains the minimum and maximum of the axis
1✔
66
     *          aligned bounding box.
1✔
67
     * This bounding box is cubic and aligned to fit to the octree root.
1✔
68
     * * __`tightBoundingBox`__ - This bounding box thightly fits
1✔
69
     *          the point data.
1✔
70
     * * __`pointAttributes`__ - Declares the point data format. May be 'LAS',
1✔
71
     *          'LAZ' or in case if the BINARY format an array of attributes
1✔
72
     *          like `['POSITION_CARTESIAN', 'COLOR_PACKED', 'INTENSITY']`
1✔
73
     * * __ `POSITION_CARTESIAN`__ - 3 x 32bit signed integers for x/y/z
1✔
74
     *          coordinates
1✔
75
     * * __`COLOR_PACKED`__ - 4 x unsigned byte for r,g,b,a colors.
1✔
76
     * * __`spacing`__ - The minimum distance between points at root level.
1✔
77
     * ```
1✔
78
     * {
1✔
79
     *     version: '1.6',
1✔
80
     *     octreeDir: 'data',
1✔
81
     *     boundingBox: {
1✔
82
     *         lx: -4.9854,
1✔
83
     *         ly: 1.0366,
1✔
84
     *         lz: -3.4494,
1✔
85
     *         ux: 0.702300000000001,
1✔
86
     *         uy: 6.7243,
1✔
87
     *         uz: 2.2383
1✔
88
     *     },
1✔
89
     *     tightBoundingBox: {
1✔
90
     *         lx: -4.9854,
1✔
91
     *         ly: 1.0375,
1✔
92
     *         lz: -3.4494,
1✔
93
     *         ux: -0.7889,
1✔
94
     *         uy: 6.7243,
1✔
95
     *         uz: 1.1245
1✔
96
     *     },
1✔
97
     *     pointAttributes: [
1✔
98
     *         'POSITION_CARTESIAN',
1✔
99
     *         'COLOR_PACKED'
1✔
100
     *     ],
1✔
101
     *     spacing: 0.03,
1✔
102
     *     scale: 0.001,
1✔
103
     *     hierarchyStepSize: 5
1✔
104
     * }
1✔
105
     * ```
1✔
106
     *
1✔
107
     */
1✔
108
    constructor(source: PotreeSourceParameters) {
1✔
109
        if (!source.crs) {
6✔
110
            // with better data and the spec this might be removed
1✔
111
            throw new Error('New PotreeSource: crs is required');
1✔
112
        }
1✔
113

5✔
114
        let url: string;
5✔
115
        if (source.file) {
6!
NEW
116
            console.warn(
×
NEW
117
                'PotreeSource: deprecated file parameter. ' +
×
NEW
118
                'Use url with the full path to cloud.js instead (e.g., url: "https://example.com/pointcloud/cloud.js").',
×
NEW
119
            );
×
NEW
120
            url = new URL(source.file, source.url).href;
×
121
        } else {
6✔
122
            url = source.url;
5✔
123
        }
5✔
124

5✔
125
        super({ ...source, url });
5✔
126
        this.baseurl = new URL('.', url).href;
5✔
127
        this.fetcher = Fetcher.arrayBuffer;
5✔
128
        this.extensionOctree = 'hrc';
5✔
129

5✔
130
        // For cloud specification visit:
5✔
131
        // https://github.com/PropellerAero/potree-propeller-private/blob/master/docs/file_format.md#cloudjs
5✔
132
        this.whenReady = (
5✔
133
            source.cloud ?
5✔
134
                Promise.resolve(source.cloud) :
6✔
135
            Fetcher.json(this.url, this.networkOptions) as Promise<PotreeCloud>)
6✔
136
            .then((cloud) => {
6✔
137
                this.boundsConforming = [
5✔
138
                    cloud.tightBoundingBox.lx,
5✔
139
                    cloud.tightBoundingBox.ly,
5✔
140
                    cloud.tightBoundingBox.lz,
5✔
141
                    cloud.tightBoundingBox.ux,
5✔
142
                    cloud.tightBoundingBox.uy,
5✔
143
                    cloud.tightBoundingBox.uz,
5✔
144
                ];
5✔
145
                if (Array.isArray(cloud.pointAttributes)) {
5✔
146
                    this.pointAttributes = cloud.pointAttributes;
5✔
147
                } else {
5!
NEW
148
                    throw new Error('[PotreeSource] Unsupported LAS/LAZ format');
×
NEW
149
                }
×
150
                this.baseurl = new URL(`${cloud.octreeDir}/r`, this.baseurl).href;
5✔
151

5✔
152
                this.parser = PotreeBinParser.parse;
5✔
153
                this.scale = cloud.scale;
5✔
154

5✔
155
                this.zmin = cloud.tightBoundingBox.lz;
5✔
156
                this.zmax = cloud.tightBoundingBox.uz;
5✔
157

5✔
158
                this.spacing = cloud.spacing;
5✔
159
                this.hierarchyStepSize = cloud.hierarchyStepSize;
5✔
160

5✔
161
                return cloud;
5✔
162
            });
6✔
163
    }
6✔
164
}
1✔
165

1✔
166
export default PotreeSource;
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