Parameters
Loading metadata...
- Total points
- Displayed points
- Files:
Display a massive point cloud by aggregating dozens of datasets.
import { Vector3 } from "three";
import { MapControls } from "three/examples/jsm/controls/MapControls.js";
import Instance from "@giro3d/giro3d/core/Instance.js";
import PointCloud from "@giro3d/giro3d/entities/PointCloud.js";
import Inspector from "@giro3d/giro3d/gui/Inspector.js";
import AggregatePointCloudSource from "@giro3d/giro3d/sources/AggregatePointCloudSource";
import COPCSource from "@giro3d/giro3d/sources/COPCSource.js";
import { setLazPerfPath } from "@giro3d/giro3d/sources/las/config.js";
import ColorMap from "@giro3d/giro3d/core/layer/ColorMap.js";
function bindDropDown(id, onChange) {
const element = document.getElementById(id);
if (!(element instanceof HTMLSelectElement)) {
throw new Error(
"invalid binding element: expected HTMLSelectElement, got: " +
element.constructor.name,
);
}
element.onchange = () => {
onChange(element.value);
};
const callback = (v) => {
element.value = v;
onChange(element.value);
};
const setOptions = (options) => {
const items = options.map(
(opt) =>
`<option value=${opt.id} ${opt.selected ? "selected" : ""}>${opt.name}</option>`,
);
element.innerHTML = items.join("\n");
};
return [callback, element.value, element, setOptions];
}
function bindNumberInput(id, onChange) {
const element = document.getElementById(id);
if (!(element instanceof HTMLInputElement)) {
throw new Error(
"invalid binding element: expected HTMLInputElement, got: " +
element.constructor.name,
);
}
element.onchange = () => {
onChange(element.valueAsNumber);
};
const callback = (v) => {
element.value = v.toString();
onChange(element.valueAsNumber);
};
return [callback, element.valueAsNumber, element];
}
function bindProgress(id) {
const element = document.getElementById(id);
if (!(element instanceof HTMLDivElement)) {
throw new Error(
"invalid binding element: expected HTMLDivElement, got: " +
element.constructor.name,
);
}
const setProgress = (normalized, text) => {
element.style.width = `${Math.round(normalized * 100)}%`;
if (text) {
element.innerText = text;
}
};
return [setProgress, element.parentElement];
}
function bindToggle(id, onChange) {
const element = document.getElementById(id);
if (!(element instanceof HTMLInputElement)) {
throw new Error(
"invalid binding element: expected HTMLButtonElement, got: " +
element.constructor.name,
);
}
element.oninput = function oninput() {
onChange(element.checked);
};
const callback = (v) => {
element.checked = v;
onChange(element.checked);
};
return [callback, element.checked, element];
}
function formatPointCount(count, numberFormat = undefined) {
let displayedPointCount = count;
let suffix = "";
if (count > 1_000_000) {
displayedPointCount /= 1_000_000;
suffix = "M";
} else if (count > 1_000_000_000) {
displayedPointCount /= 1_000_000_000;
suffix = "B";
}
if (numberFormat == null) {
numberFormat = new Intl.NumberFormat(undefined, {
maximumFractionDigits: 2,
});
}
return numberFormat.format(displayedPointCount) + suffix;
}
function makeColorRamp(
preset,
discrete = false,
invert = false,
mirror = false,
) {
let nshades = discrete ? 10 : 256;
const values = colormap({ colormap: preset, nshades });
const colors = values.map((v) => new Color(v));
if (invert) {
colors.reverse();
}
if (mirror) {
const mirrored = [...colors, ...colors.reverse()];
return mirrored;
}
return colors;
}
// LAS processing requires the WebAssembly laz-perf library
// This path is specific to your project, and must be set accordingly.
setLazPerfPath("/assets/wasm");
Instance.registerCRS(
"EPSG:2154",
"+proj=lcc +lat_0=46.5 +lon_0=3 +lat_1=49 +lat_2=44 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs",
);
const instance = new Instance({
target: "view",
crs: "EPSG:2154",
backgroundColor: "black",
renderer: {
logarithmicDepthBuffer: true,
},
});
instance.renderingOptions.enableEDL = true;
instance.renderingOptions.EDLStrength = 5;
const colormaps = {
Intensity: new ColorMap(makeColorRamp("jet"), 0, 100),
Z: new ColorMap(makeColorRamp("portland"), 0, 100),
};
const datasets = [
"LHD_FXX_0657_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0657_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0651_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0650_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0653_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0655_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0652_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0656_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0654_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0649_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0648_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0647_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0646_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0644_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0645_6859_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6868_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6864_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6865_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6866_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6867_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6860_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6861_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6862_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6863_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6857_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6858_PTS_O_LAMB93_IGN69.copc.laz",
"LHD_FXX_0658_6859_PTS_O_LAMB93_IGN69.copc.laz",
];
const server = "https://3d.oslandia.com/giro3d/pointclouds/lidarhd/paris/";
const source = new AggregatePointCloudSource({
sources: datasets.map((dataset) => new COPCSource({ url: server + dataset })),
});
const pointCloud = new PointCloud({ source });
const [setProgress, progressElement] = bindProgress("progress");
source.addEventListener("progress", () => setProgress(source.progress));
pointCloud.showVolume = true;
async function onInitialized(entity) {
progressElement.style.display = "none";
document.getElementById("options").style.display = "block";
entity.colorMap = colormaps.Z;
entity.setActiveAttribute("Z");
document.getElementById("point-count").innerText = formatPointCount(
entity.pointCount,
);
document.getElementById("file-count").innerText =
source.sources.length.toString();
const volume = entity.getBoundingBox();
const center = volume.getCenter(new Vector3());
const camera = instance.view.camera;
const lookAt = new Vector3(center.x, center.y, volume.min.z);
camera.position.set(center.x, center.y - 1, volume.max.z * 10);
camera.lookAt(lookAt);
const controls = new MapControls(camera, instance.domElement);
controls.target.copy(lookAt);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
instance.view.setControls(controls);
instance.notifyChange(camera);
const metadata = await source.getMetadata();
// Update the Z colormap with the min/max height of the datasets.
colormaps.Z.min = volume.min.z * 1.1;
colormaps.Z.max = volume.max.z * 0.6;
colormaps.Intensity.min = 0;
colormaps.Intensity.max = 5000;
const [, , , setAvailableAttributes] = bindDropDown(
"attribute",
(attribute) => {
entity.setActiveAttribute(attribute);
entity.colorMap = colormaps[attribute];
},
);
setAvailableAttributes(
metadata.attributes.map((att, index) => ({
id: att.name,
name: att.name,
selected: index === 0,
})),
);
bindToggle("show-volume", (show) => (entity.showVolume = show));
bindToggle("show-tile-volumes", (show) => (entity.showNodeVolumes = show));
bindToggle("edl", (edl) => {
instance.renderingOptions.enableEDL = edl;
instance.notifyChange();
});
bindNumberInput("point-budget", (v) => {
if (v <= 0) {
entity.pointBudget = null;
} else {
entity.pointBudget = v;
}
});
instance.addEventListener("update-end", () => {
document.getElementById("displayed-point-count").innerText =
formatPointCount(entity.displayedPointCount);
});
}
instance.add(pointCloud).then(onInitialized).catch(console.error);
Inspector.attach("inspector", instance);
<!doctype html>
<html lang="en">
<head>
<title>Massive point cloud</title>
<meta charset="UTF-8" />
<meta name="name" content="aggregate_pointcloud" />
<meta
name="description"
content="Display a massive point cloud by aggregating dozens of datasets."
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="https://giro3d.org/images/favicon.svg" />
<link
href="https://giro3d.org/assets/bootstrap-custom.css"
rel="stylesheet"
/>
<script src="https://giro3d.org/assets/bootstrap.bundle.min.js"></script>
<link
rel="stylesheet"
type="text/css"
href="https://giro3d.org/latest/examples/css/example.css"
/>
</head>
<body>
<div id="view" class="m-0 p-0 w-100 h-100"></div>
<div
id="inspector"
class="position-absolute top-0 start-0 mh-100 overflow-auto"
></div>
<div class="side-pane-with-status-bar" style="width: 25rem">
<!--Parameters -->
<div class="card">
<div class="card-header">Parameters</div>
<div class="card-body">
<div class="progress" role="progressbar">
<div
class="progress-bar bg-info progress-bar-striped progress-bar-animated text-dark"
id="progress"
style="width: 0%"
>
Loading metadata...
</div>
</div>
<div id="options" style="display: none">
<ul class="list-group mb-3" id="table">
<li class="list-group-item">
Total points
<b id="point-count" class="d-float float-end"></b>
</li>
<li
class="list-group-item"
title="The number of points currently displayed"
>
Displayed points
<b id="displayed-point-count" class="d-float float-end"></b>
</li>
<li class="list-group-item">
Files: <b id="file-count" class="d-float float-end"></b>
</li>
</ul>
<!-- Active attribute selector -->
<div class="input-group" id="attribute-group">
<label class="input-group-text col-5" for="attribute"
>Dimension</label
>
<select
class="form-select"
id="attribute"
autocomplete="off"
title="Sets the active attribute of the point cloud"
></select>
</div>
<!-- Point budget -->
<div class="input-group mt-1" id="attribute-group">
<label class="input-group-text col-5" for="attribute"
>Point budget</label
>
<input
type="number"
min="-1"
max="99999999999"
value="-1"
step="1"
class="form-control"
id="point-budget"
autocomplete="off"
/>
</div>
<!-- Show volume -->
<div class="form-check form-switch mt-2">
<input
class="form-check-input"
type="checkbox"
role="switch"
checked
id="show-volume"
autocomplete="off"
/>
<label
title="Show the volume of the octree"
class="form-check-label"
for="show-volume"
>Show dataset volume</label
>
</div>
<!-- Show octree volumes -->
<div class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
role="switch"
id="show-tile-volumes"
autocomplete="off"
/>
<label
title="Show the volume of the octree"
class="form-check-label"
for="show-tile-volumes"
>Show octrees</label
>
</div>
<!-- Eye Dome Lighting -->
<div class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
role="switch"
checked
id="edl"
autocomplete="off"
/>
<label
title="Toggles Eye Dome Lighting post-processing effect"
class="form-check-label"
for="edl"
>Eye Dome Lighting</label
>
</div>
</div>
</div>
</div>
</div>
<script type="module" src="index.js"></script>
<script>
/* activate popovers */
const popoverTriggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]'),
);
popoverTriggerList.map(
// bootstrap is used as script in the template, disable warning about undef
// eslint-disable-next-line no-undef
(popoverTriggerEl) =>
new bootstrap.Popover(popoverTriggerEl, {
trigger: "hover",
placement: "left",
content: document.getElementById(
popoverTriggerEl.getAttribute("data-bs-content"),
).innerHTML,
html: true,
}),
);
</script>
</body>
</html>
{
"name": "aggregate_pointcloud",
"dependencies": {
"@giro3d/giro3d": "0.41.0"
},
"devDependencies": {
"vite": "^3.2.3"
},
"scripts": {
"start": "vite",
"build": "vite build"
}
}