maplibre-gl-lidar 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +395 -0
- package/dist/LidarControl-BFJN1DIQ.js +37815 -0
- package/dist/LidarControl-BFJN1DIQ.js.map +1 -0
- package/dist/LidarControl-CQjIl4U5.cjs +37814 -0
- package/dist/LidarControl-CQjIl4U5.cjs.map +1 -0
- package/dist/index.cjs +21 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -0
- package/dist/laz-perf.wasm +0 -0
- package/dist/laz_rs_wasm_bg.wasm +0 -0
- package/dist/libs/laz_rs_wasm_bg.wasm +0 -0
- package/dist/maplibre-gl-lidar.css +570 -0
- package/dist/react.cjs +179 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.mjs +179 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/colorizers/ColorScheme.d.ts +60 -0
- package/dist/types/lib/colorizers/ColorScheme.d.ts.map +1 -0
- package/dist/types/lib/colorizers/index.d.ts +3 -0
- package/dist/types/lib/colorizers/index.d.ts.map +1 -0
- package/dist/types/lib/colorizers/types.d.ts +17 -0
- package/dist/types/lib/colorizers/types.d.ts.map +1 -0
- package/dist/types/lib/core/DeckOverlay.d.ts +64 -0
- package/dist/types/lib/core/DeckOverlay.d.ts.map +1 -0
- package/dist/types/lib/core/LidarControl.d.ts +318 -0
- package/dist/types/lib/core/LidarControl.d.ts.map +1 -0
- package/dist/types/lib/core/LidarControlReact.d.ts +35 -0
- package/dist/types/lib/core/LidarControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/ViewportManager.d.ts +105 -0
- package/dist/types/lib/core/ViewportManager.d.ts.map +1 -0
- package/dist/types/lib/core/types.d.ts +235 -0
- package/dist/types/lib/core/types.d.ts.map +1 -0
- package/dist/types/lib/gui/DualRangeSlider.d.ts +46 -0
- package/dist/types/lib/gui/DualRangeSlider.d.ts.map +1 -0
- package/dist/types/lib/gui/FileInput.d.ts +44 -0
- package/dist/types/lib/gui/FileInput.d.ts.map +1 -0
- package/dist/types/lib/gui/PanelBuilder.d.ts +117 -0
- package/dist/types/lib/gui/PanelBuilder.d.ts.map +1 -0
- package/dist/types/lib/gui/RangeSlider.d.ts +50 -0
- package/dist/types/lib/gui/RangeSlider.d.ts.map +1 -0
- package/dist/types/lib/gui/index.d.ts +7 -0
- package/dist/types/lib/gui/index.d.ts.map +1 -0
- package/dist/types/lib/hooks/index.d.ts +3 -0
- package/dist/types/lib/hooks/index.d.ts.map +1 -0
- package/dist/types/lib/hooks/useLidarState.d.ts +52 -0
- package/dist/types/lib/hooks/useLidarState.d.ts.map +1 -0
- package/dist/types/lib/hooks/usePointCloud.d.ts +53 -0
- package/dist/types/lib/hooks/usePointCloud.d.ts.map +1 -0
- package/dist/types/lib/layers/PointCloudManager.d.ts +136 -0
- package/dist/types/lib/layers/PointCloudManager.d.ts.map +1 -0
- package/dist/types/lib/layers/index.d.ts +3 -0
- package/dist/types/lib/layers/index.d.ts.map +1 -0
- package/dist/types/lib/layers/types.d.ts +71 -0
- package/dist/types/lib/layers/types.d.ts.map +1 -0
- package/dist/types/lib/loaders/CopcStreamingLoader.d.ts +217 -0
- package/dist/types/lib/loaders/CopcStreamingLoader.d.ts.map +1 -0
- package/dist/types/lib/loaders/PointCloudLoader.d.ts +61 -0
- package/dist/types/lib/loaders/PointCloudLoader.d.ts.map +1 -0
- package/dist/types/lib/loaders/index.d.ts +5 -0
- package/dist/types/lib/loaders/index.d.ts.map +1 -0
- package/dist/types/lib/loaders/streaming-types.d.ts +122 -0
- package/dist/types/lib/loaders/streaming-types.d.ts.map +1 -0
- package/dist/types/lib/loaders/types.d.ts +83 -0
- package/dist/types/lib/loaders/types.d.ts.map +1 -0
- package/dist/types/lib/utils/helpers.d.ts +91 -0
- package/dist/types/lib/utils/helpers.d.ts.map +1 -0
- package/dist/types/lib/utils/index.d.ts +2 -0
- package/dist/types/lib/utils/index.d.ts.map +1 -0
- package/dist/types/react.d.ts +6 -0
- package/dist/types/react.d.ts.map +1 -0
- package/package.json +118 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Open Geospatial Solutions
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# maplibre-gl-lidar
|
|
2
|
+
|
|
3
|
+
A MapLibre GL JS plugin for visualizing LiDAR point clouds using deck.gl.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Load and visualize LAS/LAZ/COPC point cloud files (LAS 1.0 - 1.4)
|
|
8
|
+
- **Dynamic COPC streaming** - viewport-based loading for large cloud-optimized point clouds
|
|
9
|
+
- Multiple color schemes: elevation, intensity, classification, RGB
|
|
10
|
+
- **Percentile-based coloring** - use 2-98% percentile range for better color distribution (clips outliers)
|
|
11
|
+
- Interactive GUI control panel with scrollable content
|
|
12
|
+
- **Point picking** - hover over points to see all available attributes (coordinates, elevation, intensity, classification, RGB, GPS time, return number, etc.)
|
|
13
|
+
- **Z offset adjustment** - shift point clouds vertically for alignment
|
|
14
|
+
- **Elevation filtering** - filter points by elevation range
|
|
15
|
+
- Automatic coordinate transformation (projected CRS to WGS84)
|
|
16
|
+
- Programmatic API for loading and styling
|
|
17
|
+
- React integration with hooks
|
|
18
|
+
- deck.gl PointCloudLayer with optimized chunking for large datasets
|
|
19
|
+
- TypeScript support
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install maplibre-gl-lidar
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Basic Usage (Vanilla JS/TypeScript)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import maplibregl from 'maplibre-gl';
|
|
33
|
+
import { LidarControl } from 'maplibre-gl-lidar';
|
|
34
|
+
import 'maplibre-gl-lidar/style.css';
|
|
35
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
36
|
+
|
|
37
|
+
const map = new maplibregl.Map({
|
|
38
|
+
container: 'map',
|
|
39
|
+
style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
40
|
+
center: [-122.4, 37.8],
|
|
41
|
+
zoom: 12,
|
|
42
|
+
pitch: 60,
|
|
43
|
+
maxPitch: 85, // Allow higher pitch for better 3D viewing
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
map.on('load', () => {
|
|
47
|
+
// Add the LiDAR control
|
|
48
|
+
const lidarControl = new LidarControl({
|
|
49
|
+
title: 'LiDAR Viewer',
|
|
50
|
+
collapsed: true,
|
|
51
|
+
pointSize: 2,
|
|
52
|
+
colorScheme: 'elevation',
|
|
53
|
+
pickable: true, // Enable point picking for hover tooltips
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
map.addControl(lidarControl, 'top-right');
|
|
57
|
+
|
|
58
|
+
// Listen for events
|
|
59
|
+
lidarControl.on('load', (event) => {
|
|
60
|
+
console.log('Point cloud loaded:', event.pointCloud);
|
|
61
|
+
lidarControl.flyToPointCloud();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Load a point cloud programmatically
|
|
65
|
+
lidarControl.loadPointCloud('https://s3.amazonaws.com/hobu-lidar/autzen-classified.copc.laz');
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### React Usage
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { useEffect, useRef, useState } from 'react';
|
|
73
|
+
import maplibregl, { Map } from 'maplibre-gl';
|
|
74
|
+
import { LidarControlReact, useLidarState } from 'maplibre-gl-lidar/react';
|
|
75
|
+
import 'maplibre-gl-lidar/style.css';
|
|
76
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
77
|
+
|
|
78
|
+
function App() {
|
|
79
|
+
const mapContainer = useRef<HTMLDivElement>(null);
|
|
80
|
+
const [map, setMap] = useState<Map | null>(null);
|
|
81
|
+
const { state, setColorScheme, setPointSize } = useLidarState();
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!mapContainer.current) return;
|
|
85
|
+
|
|
86
|
+
const mapInstance = new maplibregl.Map({
|
|
87
|
+
container: mapContainer.current,
|
|
88
|
+
style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
89
|
+
center: [-122.4, 37.8],
|
|
90
|
+
zoom: 12,
|
|
91
|
+
pitch: 60,
|
|
92
|
+
maxPitch: 85, // Allow higher pitch for better 3D viewing
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
mapInstance.on('load', () => setMap(mapInstance));
|
|
96
|
+
|
|
97
|
+
return () => mapInstance.remove();
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div style={{ width: '100%', height: '100vh' }}>
|
|
102
|
+
<div ref={mapContainer} style={{ width: '100%', height: '100%' }} />
|
|
103
|
+
{map && (
|
|
104
|
+
<LidarControlReact
|
|
105
|
+
map={map}
|
|
106
|
+
title="LiDAR Viewer"
|
|
107
|
+
pointSize={state.pointSize}
|
|
108
|
+
colorScheme={state.colorScheme}
|
|
109
|
+
onLoad={(pc) => console.log('Loaded:', pc)}
|
|
110
|
+
/>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## API Reference
|
|
118
|
+
|
|
119
|
+
### LidarControl
|
|
120
|
+
|
|
121
|
+
The main control class implementing MapLibre's `IControl` interface.
|
|
122
|
+
|
|
123
|
+
#### Constructor Options
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
interface LidarControlOptions {
|
|
127
|
+
// Panel settings
|
|
128
|
+
collapsed?: boolean; // Start collapsed (default: true)
|
|
129
|
+
position?: string; // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
|
|
130
|
+
title?: string; // Panel title (default: 'LiDAR Viewer')
|
|
131
|
+
panelWidth?: number; // Panel width in pixels (default: 365)
|
|
132
|
+
panelMaxHeight?: number; // Panel max height with scrollbar (default: 500)
|
|
133
|
+
className?: string; // Custom CSS class
|
|
134
|
+
|
|
135
|
+
// Point cloud styling
|
|
136
|
+
pointSize?: number; // Point size in pixels (default: 2)
|
|
137
|
+
opacity?: number; // Opacity 0-1 (default: 1.0)
|
|
138
|
+
colorScheme?: ColorScheme; // Color scheme (default: 'elevation')
|
|
139
|
+
usePercentile?: boolean; // Use 2-98% percentile for coloring (default: true)
|
|
140
|
+
pointBudget?: number; // Max points to display (default: 1000000)
|
|
141
|
+
|
|
142
|
+
// Filters and adjustments
|
|
143
|
+
elevationRange?: [number, number] | null; // Elevation filter
|
|
144
|
+
zOffsetEnabled?: boolean; // Enable Z offset adjustment (default: false)
|
|
145
|
+
zOffset?: number; // Z offset in meters (default: 0)
|
|
146
|
+
|
|
147
|
+
// Interaction
|
|
148
|
+
pickable?: boolean; // Enable point picking/hover tooltips (default: false)
|
|
149
|
+
pickInfoFields?: string[]; // Fields to show in tooltip (default: all)
|
|
150
|
+
|
|
151
|
+
// Behavior
|
|
152
|
+
autoZoom?: boolean; // Auto zoom to data after loading (default: true)
|
|
153
|
+
|
|
154
|
+
// COPC Streaming (dynamic loading)
|
|
155
|
+
copcLoadingMode?: 'full' | 'dynamic'; // Loading mode for COPC files (default: 'dynamic')
|
|
156
|
+
streamingPointBudget?: number; // Max points for streaming (default: 5000000)
|
|
157
|
+
streamingMaxConcurrentRequests?: number; // Concurrent node requests (default: 4)
|
|
158
|
+
streamingViewportDebounceMs?: number; // Viewport change debounce (default: 150)
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Methods
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Loading
|
|
166
|
+
loadPointCloud(source: string | File | ArrayBuffer, options?: { loadingMode?: 'full' | 'dynamic' }): Promise<PointCloudInfo>
|
|
167
|
+
loadPointCloudStreaming(source: string | File | ArrayBuffer, options?: StreamingLoaderOptions): Promise<PointCloudInfo>
|
|
168
|
+
stopStreaming(): void // Stop dynamic loading and clean up
|
|
169
|
+
unloadPointCloud(id?: string): void
|
|
170
|
+
getPointClouds(): PointCloudInfo[]
|
|
171
|
+
flyToPointCloud(id?: string): void
|
|
172
|
+
|
|
173
|
+
// Styling
|
|
174
|
+
setPointSize(size: number): void
|
|
175
|
+
setOpacity(opacity: number): void
|
|
176
|
+
setColorScheme(scheme: ColorScheme): void
|
|
177
|
+
setUsePercentile(usePercentile: boolean): void
|
|
178
|
+
getUsePercentile(): boolean
|
|
179
|
+
setElevationRange(min: number, max: number): void
|
|
180
|
+
clearElevationRange(): void
|
|
181
|
+
setPickable(pickable: boolean): void
|
|
182
|
+
|
|
183
|
+
// Z Offset
|
|
184
|
+
setZOffsetEnabled(enabled: boolean): void
|
|
185
|
+
setZOffset(offset: number): void
|
|
186
|
+
getZOffset(): number
|
|
187
|
+
|
|
188
|
+
// Pick info customization
|
|
189
|
+
setPickInfoFields(fields?: string[]): void
|
|
190
|
+
getPickInfoFields(): string[] | undefined
|
|
191
|
+
|
|
192
|
+
// Panel control
|
|
193
|
+
toggle(): void
|
|
194
|
+
expand(): void
|
|
195
|
+
collapse(): void
|
|
196
|
+
|
|
197
|
+
// Events
|
|
198
|
+
on(event: LidarControlEvent, handler: LidarControlEventHandler): void
|
|
199
|
+
off(event: LidarControlEvent, handler: LidarControlEventHandler): void
|
|
200
|
+
|
|
201
|
+
// State
|
|
202
|
+
getState(): LidarState
|
|
203
|
+
getMap(): MapLibreMap | undefined
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Events
|
|
207
|
+
|
|
208
|
+
- `load` - Point cloud loaded successfully
|
|
209
|
+
- `loadstart` - Loading started
|
|
210
|
+
- `loaderror` - Loading failed
|
|
211
|
+
- `unload` - Point cloud unloaded
|
|
212
|
+
- `statechange` - Control state changed
|
|
213
|
+
- `stylechange` - Styling changed
|
|
214
|
+
- `collapse` - Panel collapsed
|
|
215
|
+
- `expand` - Panel expanded
|
|
216
|
+
- `streamingstart` - Dynamic streaming started
|
|
217
|
+
- `streamingstop` - Dynamic streaming stopped
|
|
218
|
+
- `streamingprogress` - Streaming progress update
|
|
219
|
+
- `budgetreached` - Point budget limit reached
|
|
220
|
+
|
|
221
|
+
### Color Schemes
|
|
222
|
+
|
|
223
|
+
- `'elevation'` - Viridis-like color ramp based on Z values
|
|
224
|
+
- `'intensity'` - Grayscale based on intensity attribute
|
|
225
|
+
- `'classification'` - ASPRS standard classification colors
|
|
226
|
+
- `'rgb'` - Use embedded RGB colors (if available)
|
|
227
|
+
|
|
228
|
+
### Percentile-Based Coloring
|
|
229
|
+
|
|
230
|
+
By default, elevation and intensity coloring uses the 2nd-98th percentile range instead of the full min-max range. This clips outliers and provides better color distribution across the point cloud.
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// Percentile coloring is enabled by default
|
|
234
|
+
const control = new LidarControl({
|
|
235
|
+
colorScheme: 'elevation',
|
|
236
|
+
usePercentile: true, // default
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Disable to use full value range (min-max)
|
|
240
|
+
control.setUsePercentile(false);
|
|
241
|
+
|
|
242
|
+
// Check current setting
|
|
243
|
+
console.log(control.getUsePercentile()); // true or false
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The percentile toggle is also available in the GUI panel when using "Elevation" or "Intensity" color schemes. Uncheck "Use percentile range (2-98%)" to use the full value range.
|
|
247
|
+
|
|
248
|
+
### Point Picking
|
|
249
|
+
|
|
250
|
+
When `pickable` is enabled, hovering over points displays a tooltip with all available attributes:
|
|
251
|
+
|
|
252
|
+
- **X, Y, Z** - Coordinates and elevation
|
|
253
|
+
- **Intensity** - Reflectance value
|
|
254
|
+
- **Classification** - ASPRS class name (Ground, Building, Vegetation, etc.)
|
|
255
|
+
- **Red, Green, Blue** - RGB color values (if available)
|
|
256
|
+
- **GpsTime** - GPS timestamp
|
|
257
|
+
- **ReturnNumber / NumberOfReturns** - Return information
|
|
258
|
+
- **PointSourceId** - Scanner source ID
|
|
259
|
+
- **ScanAngle** - Scan angle
|
|
260
|
+
- And more (EdgeOfFlightLine, ScanDirectionFlag, UserData, etc.)
|
|
261
|
+
|
|
262
|
+
Enable via constructor option or toggle in the GUI panel:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// Via constructor
|
|
266
|
+
const control = new LidarControl({ pickable: true });
|
|
267
|
+
|
|
268
|
+
// Or programmatically
|
|
269
|
+
control.setPickable(true);
|
|
270
|
+
|
|
271
|
+
// Optionally filter which fields to display
|
|
272
|
+
control.setPickInfoFields(['Classification', 'Intensity', 'GpsTime', 'ReturnNumber']);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Z Offset
|
|
276
|
+
|
|
277
|
+
Shift point clouds vertically for alignment with terrain or other data:
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// Via constructor
|
|
281
|
+
const control = new LidarControl({
|
|
282
|
+
zOffsetEnabled: true,
|
|
283
|
+
zOffset: 50, // Shift up 50 meters
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Or programmatically
|
|
287
|
+
control.setZOffsetEnabled(true);
|
|
288
|
+
control.setZOffset(50);
|
|
289
|
+
|
|
290
|
+
// Get current offset
|
|
291
|
+
console.log(control.getZOffset()); // 50
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The Z offset can also be adjusted interactively via the "Z Offset" checkbox and slider in the GUI panel.
|
|
295
|
+
|
|
296
|
+
### Dynamic COPC Streaming
|
|
297
|
+
|
|
298
|
+
For large COPC (Cloud Optimized Point Cloud) files, dynamic streaming loads only the points visible in the current viewport, dramatically reducing initial load time and memory usage.
|
|
299
|
+
|
|
300
|
+
**Key features:**
|
|
301
|
+
- **Viewport-based loading** - Only loads octree nodes visible in the current map view
|
|
302
|
+
- **Level-of-detail (LOD)** - Automatically selects appropriate detail level based on zoom
|
|
303
|
+
- **Center-first priority** - Points near the viewport center load first
|
|
304
|
+
- **Point budget** - Limits total points in memory (default: 5 million)
|
|
305
|
+
|
|
306
|
+
**How it works:**
|
|
307
|
+
1. When loading a COPC file (from URL or local file), dynamic mode is used by default
|
|
308
|
+
2. As you pan/zoom the map, new nodes are streamed based on viewport
|
|
309
|
+
3. Deeper octree levels (more detail) load as you zoom in
|
|
310
|
+
4. Parent nodes provide coverage where child nodes don't exist
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// Dynamic loading is the default for COPC files
|
|
314
|
+
const control = new LidarControl();
|
|
315
|
+
control.loadPointCloud('https://example.com/large-pointcloud.copc.laz');
|
|
316
|
+
|
|
317
|
+
// Explicitly set loading mode
|
|
318
|
+
const control = new LidarControl({
|
|
319
|
+
copcLoadingMode: 'dynamic', // or 'full' for complete load
|
|
320
|
+
streamingPointBudget: 10_000_000, // 10 million points max
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Override per-load
|
|
324
|
+
control.loadPointCloud(file, { loadingMode: 'full' }); // Force full load
|
|
325
|
+
control.loadPointCloud(url, { loadingMode: 'dynamic' }); // Force streaming
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Loading modes:**
|
|
329
|
+
- `'dynamic'` (default for COPC) - Stream nodes based on viewport, ideal for large files
|
|
330
|
+
- `'full'` - Load entire point cloud upfront, better for small files
|
|
331
|
+
|
|
332
|
+
**Note:** Non-COPC files (regular LAS/LAZ) always use full loading mode since they don't have the octree structure required for streaming.
|
|
333
|
+
|
|
334
|
+
### React Hooks
|
|
335
|
+
|
|
336
|
+
#### useLidarState
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
const {
|
|
340
|
+
state,
|
|
341
|
+
setState,
|
|
342
|
+
setPointSize,
|
|
343
|
+
setOpacity,
|
|
344
|
+
setColorScheme,
|
|
345
|
+
setUsePercentile,
|
|
346
|
+
setElevationRange,
|
|
347
|
+
setZOffsetEnabled,
|
|
348
|
+
setZOffset,
|
|
349
|
+
toggle,
|
|
350
|
+
reset,
|
|
351
|
+
} = useLidarState(initialState?);
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
#### usePointCloud
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
const { data, loading, error, progress, load, reset } = usePointCloud();
|
|
358
|
+
|
|
359
|
+
// Load a file
|
|
360
|
+
await load(file);
|
|
361
|
+
console.log(`Loaded ${data.pointCount} points`);
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Supported Formats
|
|
365
|
+
|
|
366
|
+
- LAS 1.0 - 1.4 (all versions supported via copc.js + loaders.gl fallback)
|
|
367
|
+
- LAZ (compressed LAS)
|
|
368
|
+
- COPC (Cloud Optimized Point Cloud) - with dynamic streaming support
|
|
369
|
+
|
|
370
|
+
**Note:** LAS 1.2 and 1.4 are loaded using copc.js for optimal performance. LAS 1.0, 1.1, and 1.3 files automatically fall back to @loaders.gl/las.
|
|
371
|
+
|
|
372
|
+
## Coordinate Systems
|
|
373
|
+
|
|
374
|
+
Point clouds are automatically transformed to WGS84 (EPSG:4326) for display on the map. The loader reads the WKT coordinate reference system from the file and uses proj4 to transform coordinates. Supported features:
|
|
375
|
+
|
|
376
|
+
- Projected coordinate systems (State Plane, UTM, etc.)
|
|
377
|
+
- Compound coordinate systems (horizontal + vertical)
|
|
378
|
+
- Automatic unit conversion (feet to meters for elevation)
|
|
379
|
+
|
|
380
|
+
## Dependencies
|
|
381
|
+
|
|
382
|
+
- [deck.gl](https://deck.gl/) - WebGL visualization layers
|
|
383
|
+
- [copc.js](https://github.com/connormanning/copc.js) - COPC/LAS/LAZ parsing (LAS 1.2/1.4)
|
|
384
|
+
- [@loaders.gl/las](https://loaders.gl/modules/las/docs) - LAS parsing fallback (LAS 1.0/1.1/1.3)
|
|
385
|
+
- [laz-perf](https://github.com/hobu/laz-perf) - LAZ decompression
|
|
386
|
+
- [proj4](http://proj4js.org/) - Coordinate transformation
|
|
387
|
+
- [maplibre-gl](https://maplibre.org/) - Map rendering
|
|
388
|
+
|
|
389
|
+
## License
|
|
390
|
+
|
|
391
|
+
MIT
|
|
392
|
+
|
|
393
|
+
## Credits
|
|
394
|
+
|
|
395
|
+
The sample dataset [autzen-classified.copc.laz](https://s3.amazonaws.com/hobu-lidar/autzen-classified.copc.laz) is from [Hobu, Inc.](https://hobu.co). Credits to [Howard Butler](https://github.com/hobu).
|