Feed the platform a LiDAR point cloud and building footprints and get back automatic LoD1.2 / LoD1.3 / LoD2.2 building models, rendered on the map as native mesh graphics — powered by the roofer engine behind the Dutch 3D BAG. Add a 30-command forestry LiDAR toolkit and a complete Gaussian splat pipeline, from training to a synced 3D viewer.
roofer is the fully automatic reconstruction tool behind the Dutch 3D BAG — roughly 10 million buildings nationwide. VoltGrid drives it end to end: pick a point cloud (.las / .laz / .copc.laz) and a 2D footprint polygon GeoPackage, choose a level of detail, and the resulting CityJSONSeq buildings appear on the map as esri/geometry/Mesh graphics — no manual modelling in the loop.
roofer-buildings layer.window.MapApp.runRooferReconstruction.# probe → reconstruct → poll → fetch GET /api/roof/capabilities → always 200 POST /api/roof/reconstruct { pointCloudPath, footprintGpkgPath, lod: "2.2" } GET /api/roof/jobs/{jobId} { "status": "complete", "buildingCount": 312 } GET /api/roof/jobs/{jobId}/output → CityJSONSeq, one fragment per line
roofer is an optional external dependency, invoked as a separate process. The app never bundles it — and never breaks without it.
Without roofer installed, /api/roof/capabilities reports {available:false} and POST /api/roof/reconstruct returns 503 with an install hint — the rest of the app is unaffected.
roofer is GPLv3. The app invokes it as a separate process and consumes its CityJSONSeq output, so GPLv3 does not extend to the app. Redistribute roofer's binary yourself and you take on GPLv3 attribution and source-offer obligations.
Aerial LiDAR or dense image matching (AHN4, USGS 3DEP) plus cadastral footprints (Dutch BAG pand, OSM building=*) with a stable building-id column.
MaxBuildings (default 5000) caps in-map mesh count — above ~10k Mesh graphics become unwieldy. Raise it in appsettings.json for larger datasets.
A 30-command forestry LiDAR toolkit — ground filtering, canopy analysis, tree segmentation — sits alongside roofer in the platform's Point Cloud & 3D Reconstruction suite.
roofer follows the platform's proven external-CLI pattern: 3-tier CLI resolution (config path → PATH → runtimes dir), an availability probe, and async-job bookkeeping over REST.
The splat training pipeline turns photo sets or video into Gaussian splats on-device, then drops the result straight into the 3D viewer. Two interchangeable backends sit behind one API — the provider is a config switch, and both run as separate subprocesses.
Queued → Sfm → Training → Exporting → Completed, with progress in the viewer's Training Jobs panel and over REST.georef field at train time or via POST /api/splats/{id}/meta.# which trainers are installed? GET /api/splats/train/availability { "postshot": true, "opensplat": false } # multipart: photos/video + name, provider, steps… POST /api/splats/train → 202 + job GET /api/splats/train/jobs/{id} { "status": "Training", "progress": 42 } # done → registered in /api/splats + viewer
A hardware-accelerated WebView2 viewer renders Gaussian splats via Spark and OGC 3D Tiles via iTowns — served entirely by the in-process local server, with the camera kept in sync with the main ArcGIS SceneView.
Upload .ply / .splat / .ksplat / .spz / .rad via POST /api/splats. Spark 2.x streams paged .rad LoD datasets of 100M+ splats.
Drop a .zip tileset or .3tz; it's unpacked server-side and served from /api/3dtiles/<id>/tileset.json into iTowns' native OGC3DTilesLayer.
The viewer and the main ArcGIS map publish/subscribe camera state over /api/sync/camera plus an SSE stream — move either window and the other follows, echo-back suppressed.
Switch between a Globe scene (EPSG:4978 ECEF, place splats by lon/lat) and a projected planar scene positioned in meters.
three, iTowns, and Spark are vendored locally and served by the in-process server — no runtime CDN calls, matching the platform's LAN-first posture.
The viewer runs in WebView2 on the Edge runtime with GPU-accelerated WebGL by default — the right substrate for GPU-heavy splatting.
Performance statements are workload-dependent: reconstruction time varies with point density and CPU; CPU-only splat training is roughly 100× slower than GPU; COLMAP SfM alone can take 10+ minutes for ~100 photos. Trainer availability depends on separately installed third-party binaries and their licenses.
Reconstruct buildings from the point clouds you already have, analyze forests with FUSION/LDV, and capture reality as Gaussian splats — all from one desktop, no cloud required.