VControlLidar
Overview
The VControlLidar component wraps maplibre-gl-lidar, providing a full-featured LiDAR point cloud viewer with:
- LAS/LAZ/COPC file support (LAS 1.0 - 1.4)
- Dynamic COPC streaming for large point clouds
- Multiple color schemes (elevation, intensity, classification, RGB)
- Classification legend with toggle visibility
- Point picking with attribute tooltips
- Z-offset adjustment for alignment
- Interactive GUI control panel
Installation
Install the required dependency (maplibre-gl-lidar 0.21 or later):
pnpm add maplibre-gl-lidar
Import the CSS in your app:
import 'maplibre-gl-lidar/style.css';
Usage
<script setup lang="ts">
import { VMap } from '@geoql/v-maplibre';
import { VControlLidar } from '@geoql/v-maplibre/lidar';
import 'maplibre-gl-lidar/style.css';
const mapOptions = {
style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
center: [-123.075, 44.05],
zoom: 14,
pitch: 60,
maxPitch: 85,
};
const lidarOptions = {
collapsed: false,
pointSize: 2,
colorScheme: 'elevation',
pickable: true,
autoZoom: true,
};
const copcUrl = 'https://s3.amazonaws.com/hobu-lidar/autzen-classified.copc.laz';
</script>
<template>
<VMap :options="mapOptions" style="height: 500px">
<VControlLidar
position="top-right"
:options="lidarOptions"
:default-url="copcUrl"
@load="(info) => console.log('Loaded:', info)"
/>
</VMap>
</template>
Props
options
- Type:
LidarControlOptions - Required:
false
Configuration options for the LiDAR control.
interface LidarControlOptions {
collapsed?: boolean; // Start collapsed (default: true)
title?: string; // Panel title (default: 'LiDAR Viewer')
panelWidth?: number; // Panel width in pixels (default: 365)
panelMaxHeight?: number; // Panel max height (default: 500)
pointSize?: number; // Point size in pixels (default: 2)
opacity?: number; // Opacity 0-1 (default: 1.0)
colorScheme?: ColorScheme; // Color scheme (default: 'elevation')
usePercentile?: boolean; // Use 2-98% percentile for coloring
pointBudget?: number; // Max points to display (default: 1000000)
pickable?: boolean; // Enable point picking (default: false)
autoZoom?: boolean; // Auto zoom to data (default: true)
copcLoadingMode?: 'full' | 'dynamic'; // Loading mode for COPC
streamingPointBudget?: number; // Max points for streaming (default: 5000000)
}
type ColorScheme = 'elevation' | 'intensity' | 'classification' | 'rgb';
position
- Type:
'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' - Required:
false - Default:
'top-right'
Position of the control on the map.
defaultUrl
- Type:
string - Required:
false
URL of a point cloud file to auto-load on mount.
classificationStyles
- Type:
ClassificationStyles(Record<number, { name?: string; color?: [number, number, number] }>) - Required:
false
Reactive display name and colour per classification code, for example custom classes (64-255) from an annotation tool. The overrides apply to point colours, the classification legend and the hover tooltip. A code without an entry keeps its ASPRS name and colour. Setting the prop to undefined clears the overrides.
<VControlLidar
:classification-styles="{
64: { name: 'Solar panel', color: [255, 196, 0] },
65: { name: 'Antenna', color: [255, 64, 160] },
}"
/>
Events
@load
Emitted when a point cloud has been successfully loaded.
- Payload:
{ pointCloud: PointCloudInfo }
interface PointCloudInfo {
id: string;
name: string;
pointCount: number;
bounds: PointCloudBounds;
hasRGB: boolean;
hasIntensity: boolean;
hasClassification: boolean;
source: string;
wkt?: string;
}
@loadstart
Emitted when loading begins.
@loaderror
Emitted when loading fails.
- Payload:
{ error: Error }
@unload
Emitted when a point cloud is unloaded.
@statechange
Emitted when control state changes.
@stylechange
Emitted when styling changes (point size, color scheme, etc.).
@streamingstart / @streamingstop
Emitted when COPC streaming starts or stops.
@streamingprogress
Emitted during streaming with progress info.
@budgetreached
Emitted when point budget limit is reached.
@pointclick
Emitted when the user clicks a point. Needs pickable: true in options.
- Payload:
{ point?: PickedPointInfo }withpointCloudId,index,longitude,latitude,elevation,classification,intensity, RGB, the screenx/y, and every extra attribute inattributes.
<VControlLidar
:options="{ pickable: true }"
@pointclick="({ point }) => console.log(point?.classification)"
/>
Exposed Methods
Access methods via template ref:
<script setup lang="ts">
import { ref } from 'vue';
const lidarRef = ref();
const loadFile = async (url: string) => {
await lidarRef.value.loadPointCloud(url);
};
</script>
<template>
<VControlLidar ref="lidarRef" />
</template>
loadPointCloud(source)
Load a point cloud from URL, File, or ArrayBuffer.
await lidarRef.value.loadPointCloud('https://example.com/data.copc.laz');
unloadPointCloud(id?)
Unload a point cloud by ID, or all if no ID provided.
flyToPointCloud(id?)
Fly to a point cloud's bounds.
setPointSize(size)
Set the point size in pixels.
setColorScheme(scheme)
Set the color scheme: 'elevation', 'intensity', 'classification', or 'rgb'.
setOpacity(opacity)
Set opacity (0-1).
toggle() / expand() / collapse()
Toggle, expand, or collapse the control panel.
getState()
Get the current control state.
getPointClouds()
Get array of loaded point clouds.
stopStreaming(id?)
Stop streaming for a specific dataset or all.
isStreaming(id?)
Check if streaming is active.
pauseStreaming(id) / resumeStreaming(id)
Pause level-of-detail streaming for a COPC/EPT cloud: no new nodes load and none are evicted, so the loaded points stay in place (useful while you edit or measure them). resumeStreaming refreshes the nodes for the current view. isStreamingLoading(id) reports whether node requests are still in flight.
loadRegion(id, bounds, options?) / clearPinnedRegion(id)
Load a COPC region [west, south, east, north] at full resolution and pin it, so streaming never evicts it. options.maxPoints caps the region size. Resolves with { nodes, points }. clearPinnedRegion releases the region.
const { points } = await lidarRef.value.loadRegion(
cloudId,
[-123.08, 44.05, -123.07, 44.06],
{ maxPoints: 2_000_000 },
);
setClassificationStyles(styles) / getClassificationStyles()
Imperative form of the classificationStyles prop.
Color Schemes
- elevation: Viridis-like color ramp based on Z values
- intensity: Grayscale based on intensity attribute
- classification: ASPRS standard classification colors
- rgb: Use embedded RGB colors (if available)
COPC Streaming
For large COPC files, dynamic streaming loads only visible points:
<VControlLidar
:options="{
copcLoadingMode: 'dynamic',
streamingPointBudget: 10_000_000,
}"
/>
Features:
- Viewport-based loading (only loads visible octree nodes)
- Level-of-detail based on zoom level
- Center-first priority
- Configurable point budget
Supported Formats
- LAS 1.0 - 1.4 (all versions)
- LAZ (compressed LAS)
- COPC (Cloud Optimized Point Cloud) with dynamic streaming
TypeScript
import type {
LidarControlOptions,
ColorScheme,
CopcLoadingMode,
PointCloudInfo,
PointCloudBounds,
ClassificationStyles,
PickedPointInfo,
LidarPointClickEventData,
LidarRegionLoadResult,
} from '@geoql/v-maplibre/lidar';