HERE Technologies and Wherobots announce partnership Learn More

What is LiDAR Data? How It Works, Formats, and Sources

Authors

LiDAR (light detection and ranging) data is a set of 3D points measured by a laser scanner, which times each light pulse's round trip to a surface. Each point carries x, y, and z coordinates, the echo's strength (intensity), its order (return number), and a class code such as ground, vegetation, building, or water. Airborne LiDAR data maps terrain, tree canopy, and buildings over whole regions. The U.S. Geological Survey (USGS) describes LiDAR data as the basis for elevation models with a vertical accuracy of about 10 cm. This article tests one claim with Portland data. The claim is that a 30 m radar map of the surface, minus the LiDAR ground height, gives the mean height of a forest and fails on towers.

Key takeaways

  • LiDAR times laser pulses to measure distance. Satellite positioning and a motion sensor place each measurement on the map.
  • One pulse can return several echoes, from canopy top to ground, so LiDAR maps terrain under forest.
  • LiDAR data is stored as LAS, compressed as LAZ, and streamed as Cloud Optimized Point Cloud (COPC) files. Each point carries a standard class code.
  • The main derived products are digital terrain models (DTM) and digital surface models (DSM), canopy height models (CHM) computed as DSM − DTM, and building heights.
  • The USGS 3D Elevation Program publishes free LiDAR data for the United States at quality levels 1 and 2 (QL1 and QL2).

What LiDAR data is

The National Oceanic and Atmospheric Administration (NOAA) defines LiDAR as a remote sensing method that uses light in the form of a pulsed laser to measure ranges to the Earth. The range is half the round-trip time multiplied by the speed of light. Each measurement becomes one point.

The raw product is a point cloud: a loose set of points, with no grid and no lines between them. One survey samples every surface the pulses reached: ground, trees, roofs, power lines, and parked cars. Photogrammetry also builds point clouds, from overlapping photographs. LiDAR data adds several returns per pulse, which reach the ground through gaps in a canopy.

How LiDAR works

The laser scanner measures the range and angle of each pulse. A GNSS (Global Navigation Satellite System) receiver records the scanner's position by satellite, and an inertial measurement unit records its roll, pitch, and heading. Wehr and Lohr laid out these components and the positioning math in Airborne laser scanning: an introduction and overview (1999). In NOAA's description, topographic LiDAR uses near-infrared light to map land, and bathymetric LiDAR uses green light that penetrates water to map riverbeds and the seafloor.

Diagram of one airborne LiDAR pulse passing through a tree. Four yellow points mark the first return at the canopy top, two returns inside the crown, and the last return on the ground. A second pulse returns once from a building roof labeled class 6. A dashed pink line traces the surface model over the canopy and roof, a gray line traces the ground, and an arrow marks canopy height as DSM minus DTM. A side panel shows the full waveform with four energy peaks at the same heights
One pulse, several returns. Discrete-return sensors keep the peaks as points; full-waveform sensors such as GEDI (Global Ecosystem Dynamics Investigation) record the whole returned signal. Ground returns build the terrain model and first returns build the surface model.

Returns. A pulse spreads into a footprint, so part of the beam hits the canopy top, part hits branches, and part reaches the ground.

Discrete return vs full waveform. Most survey sensors record discrete returns, a few peaks per pulse. Full-waveform sensors record the whole returned signal, including the structure between peaks. Mallet and Bretar reviewed the method in Full-waveform topographic lidar: state-of-the-art (2009).

Point density. Density sets what a survey can resolve. The USGS quality levels require at least 2 pulses per square meter for QL2 and at least 8 for QL1. Both require 10 cm vertical accuracy on open ground, measured as RMSEz, the root mean square error of heights. A QL1 survey resolves roof planes and individual crowns that QL2 blurs.

Airborne, terrestrial, mobile, and spaceborne LiDAR

PlatformTypical carrierWhat it covers
Airborne laser scanning (ALS)Aircraft, helicopter, droneRegional terrain, forests, cities; the source of 3DEP and most national programs
Terrestrial laser scanning (TLS)TripodBuilding facades, bridges, mines, and forest plots at high density
Mobile laser scanning (MLS)Car, train, backpackRoad and rail corridors, street furniture, utility poles
SpaceborneSatellite, space stationGlobal samples of ice, forest height, and terrain along orbit tracks

NASA's ICESat-2 launched in September 2018. Its ATLAS (Advanced Topographic Laser Altimeter System) laser fires 10,000 times a second at 532 nm across six beams and counts single photons. Markus and colleagues set out its design in The Ice, Cloud, and land Elevation Satellite-2 (ICESat-2): science requirements, concept, and implementation (2017). GEDI was installed on the International Space Station in December 2018. Its three full-waveform lasers produce eight ground tracks of 25 m footprints. Dubayah and colleagues described it in The Global Ecosystem Dynamics Investigation: high-resolution laser ranging of the Earth's forests and topography (2020).

LiDAR data formats LAS, LAZ, and COPC

LAS is the binary exchange format for point clouds. It is owned by the American Society for Photogrammetry and Remote Sensing (ASPRS) and maintained in the open. The Open Geospatial Consortium (OGC) has recognized LAS as a community standard since 2018. Each point record holds x, y, z, intensity, return number, number of returns, scan angle, GPS time, and a classification code. LAS 1.5, approved in August 2025, drops the legacy point formats 0 to 5 and keeps formats 6 to 10.

LAZ is LAS with lossless compression. Martin Isenburg's LASzip (2013) produces files 7 to 25 percent of the original size. Cloud Optimized Point Cloud (COPC) is a LAZ 1.4 file with its points sorted into nested cubes (an octree) and an index of where each cube sits. A client can download one area or level of detail over HTTP without the whole file.

LiDAR classification codes

The LAS specification defines the ASPRS standard point classes. These are the values for point formats 6 to 10:

CodeClassCodeClass
0Created, never classified11Road surface
1Unclassified13Wire, guard (shield)
2Ground14Wire, conductor (phase)
3Low vegetation15Transmission tower
4Medium vegetation16Wire-structure connector
5High vegetation17Bridge deck
6Building18High noise
7Low point (noise)19Overhead structure
9Water20Ignored ground
10Rail21, 22Snow, temporal exclusion

Codes 8 and 12 and the range 23 to 63 are reserved, and 64 to 255 are free for user definitions.

From point cloud to DEM, DSM, CHM, and building heights

Most analysts use LiDAR data after it is gridded into rasters, usually GeoTIFF:

  • Digital terrain model (DTM). Ground points (class 2) are interpolated into a bare-earth grid, the digital elevation model that 3DEP publishes at 1 m.
  • Digital surface model (DSM). The highest or first returns are gridded into a surface that includes canopy and roofs.
  • Canopy height model (CHM). The DSM minus the DTM gives the height of everything above ground. The National Ecological Observatory Network (NEON) builds its 1 m CHM product this way.
  • Building heights. Building points (class 6) inside a footprint, minus the ground under it, give roof height. The Overture Maps Foundation estimated heights for millions of US buildings from 3DEP LiDAR and published them under an open license.

Where to download LiDAR data

The main public LiDAR archives are free:

  • USGS 3DEP. The 3D Elevation Program collects LiDAR across the United States to the Lidar Base Specification. The LidarExplorer map shows coverage and serves point clouds as LAZ tiles and the 1 m DEMs made from them. The point clouds are also an AWS open dataset. LAZ tiles sit in a requester-pays bucket (the downloader pays transfer costs), and Entwine Point Tiles, a streamable octree format, sit in a public one.
  • NOAA. The Data Access Viewer serves NOAA's coastal topographic and bathymetric LiDAR.
  • OpenTopography. A facility at the San Diego Supercomputer Center, funded by the National Science Foundation (NSF), hosts and processes academic and agency surveys worldwide on request. Krishnan and colleagues described the design in OpenTopography: a services oriented architecture for community access to LIDAR topography (2011).
  • National programs. The Netherlands publishes its national elevation dataset, Actueel Hoogtebestand Nederland (AHN), as open data. England's Environment Agency publishes its National LIDAR Programme at 1 m.

LiDAR data examples

  • National elevation. 3DEP's 1 m bare-earth DEMs supply terrain for flood models and flood risk data, where a small change in ground height changes which buildings flood.
  • Global forest structure. GEDI waveforms measure canopy height and vertical structure, which its science team uses to estimate forest biomass and its change.
  • Ice and sea ice. ICESat-2 measures elevation change of glaciers and ice sheets and the thickness distribution of sea ice.
  • Building heights for maps. The same Overture project reported that fewer than 20 percent of US OpenStreetMap buildings carried a height tag. Overture's LiDAR-derived heights address that gap.
  • Utilities and transport. The ASPRS classes for rail, wires, and towers (10 and 13 to 15) let utilities and railways map corridors and the vegetation near them.

LiDAR data in Wherobots

WherobotsDB reads LiDAR-derived rasters directly and queries LiDAR points as tables.

Derived rasters. 3DEP publishes its 1 m DEMs as Cloud Optimized GeoTIFFs in a public bucket, and RS_FromPath opens them as out-db rasters. The file stays in the bucket, and a query reads only the tiles it needs:

SELECT RS_MetaData(r) AS md, RS_BandPixelType(r) AS pt, RS_BandNoDataValue(r) AS nd, RS_SRID(r) AS srid
FROM (SELECT RS_FromPath('s3://prd-tnm/StagedProducts/Elevation/1m/Projects/OR_PortlandMetro_B24/TIFF/USGS_1M_10_x52y505_OR_PortlandMetro_B24.tif') AS r)

The tile from the 2024 Portland Metro survey holds 10,012 by 10,012 pixels of 1 m heights, stored as 32-bit floating-point numbers (float32). Its spatial reference identifier (SRID) is 26910, which is NAD83 (North American Datum of 1983) on Universal Transverse Mercator (UTM) zone 10N. It uses 512-pixel internal tiles, and −999999 marks missing values (NoData). A canopy height model or DSM stored as GeoTIFF loads the same way. RS_MapAlgebra subtracts one from the other in a single statement.

Point tables. The Wherobots documentation lists no LAS or LAZ reader, so point clouds are converted first. The Point Data Abstraction Library (PDAL) has an Arrow writer that writes LAS points to GeoParquet, one row per point. That file loads as a Havasu table, the WherobotsDB table format, with an ST_PointZ geometry for each point. ST_3DDWithin and ST_3DDistance then find points within a 3D distance of each other. A spatial join with ST_Intersects assigns every point to a parcel or building footprint.

The walkthrough uses Portland, Oregon, where these sources overlap:

LayerSource in the querySensorGridFormatWhat the queries read
Ground (DTM)3DEP 1 m DEM, OR_PortlandMetro_B24Airborne LiDAR, 20241 m, North American Vertical Datum of 1988 (NAVD88) heightsCloud Optimized GeoTIFF files on S3; tile x52y505 is 10,012 by 10,012 pixelsTwo tiles, x52y504 and x52y505, in both queries
Surface (DSM)Copernicus DEM GLO-30TanDEM-X X-band radar, 2011 to 20151 arc-second, about 30 m, Earth Gravitational Model 2008 (EGM2008) heightsHavasu raster tableOne tile in each query
Canopy (CHM)Meta and WRI CHMv2Optical imagery, model trained on airborne LiDARAbout 1 m, heights in metersHavasu raster tableTwo tiles that cover the four zones (forest query only)
ZonesOverture land useMap dataPolygonsHavasu vector tableFour named polygons (forest query only)
BuildingsOverture buildingsMap dataPolygons with a height attributeHavasu vector tableFootprints of 2,000 m² or more with a height inside a 2 km box over downtown Portland; 117 in the result (building query only)

WherobotsDB reads the rasters and the vector polygons in one SQL statement; most stacks pick one data model.

The Copernicus DEM is a surface model that includes trees and buildings. Surface minus ground measures how much height a 30 m radar model records over forest and towers.

Forest height from radar surface minus LiDAR ground

The first query takes four Overture land use polygons: three forested parks in the West Hills and the Albina rail yard as open ground. It computes the mean of each raster inside each polygon, a zonal statistic. RS_ZonalStatsAll returns the sum and count of pixels per raster tile, so a zone spanning several tiles is weighted by its pixels in each.

-- Lidar ground, radar surface, and lidar-trained canopy height for four Portland zones
WITH zones AS (
  SELECT names.primary AS zone, ST_SetSRID(geometry, 4326) AS geom,
         ST_AreaSpheroid(geometry) / 10000 AS ha
  FROM wherobots_open_data.overture_maps_foundation.base_land_use
  WHERE bbox.xmax > -122.76 AND bbox.xmin < -122.66 AND bbox.ymax > 45.48 AND bbox.ymin < 45.56
    AND names.primary IN ('Washington Park', 'Hoyt Arboretum', 'Marquam Nature Park', 'Albina Yard')
),
dtm AS (
  -- USGS 3DEP 1 m bare-earth DEM from the 2024 Portland Metro lidar survey (NAD83 / UTM 10N, NAVD88)
  SELECT RS_FromPath(concat('s3://prd-tnm/StagedProducts/Elevation/1m/Projects/OR_PortlandMetro_B24/TIFF/USGS_1M_10_',
                            t, '_OR_PortlandMetro_B24.tif')) AS rast
  FROM VALUES ('x52y504'), ('x52y505') AS v(t)
),
ground AS (
  SELECT /*+ BROADCAST(d) */ z.zone, RS_ZonalStatsAll(d.rast, z.geom, 1, false, true) AS s
  FROM zones z CROSS JOIN dtm d
),
surface AS (
  -- Copernicus GLO-30, a radar digital surface model (EGM2008 heights)
  SELECT z.zone, RS_ZonalStatsAll(c.rast, z.geom, 1, false, true) AS s
  FROM zones z JOIN wherobots_open_data.copernicus_dem.glo_30m c ON ST_Intersects(c.footprint, z.geom)
),
canopy AS (
  -- Meta and WRI canopy height model, metres, trained on airborne lidar
  SELECT z.zone, RS_ZonalStatsAll(m.rast, z.geom, 1, false, true) AS s
  FROM zones z JOIN wherobots_open_data.meta_canopy_height.global_v2 m ON ST_Intersects(m.footprint, z.geom)
),
agg AS (
  SELECT 'ground' AS layer, zone, SUM(s.sum) AS total, SUM(s.count) AS n, MAX(s.max) AS mx FROM ground WHERE s.count > 0 GROUP BY zone
  UNION ALL
  SELECT 'surface', zone, SUM(s.sum), SUM(s.count), MAX(s.max) FROM surface WHERE s.count > 0 GROUP BY zone
  UNION ALL
  SELECT 'canopy', zone, SUM(s.sum), SUM(s.count), MAX(s.max) FROM canopy WHERE s.count > 0 GROUP BY zone
)
SELECT z.zone, ROUND(z.ha, 1) AS ha,
       ROUND(MAX(CASE WHEN layer = 'ground'  THEN total / n END), 2) AS lidar_ground_m,
       ROUND(MAX(CASE WHEN layer = 'surface' THEN total / n END), 2) AS radar_surface_m,
       ROUND(MAX(CASE WHEN layer = 'surface' THEN total / n END) - MAX(CASE WHEN layer = 'ground' THEN total / n END), 2) AS surface_minus_ground_m,
       ROUND(MAX(CASE WHEN layer = 'canopy'  THEN total / n END), 2) AS mean_canopy_m,
       MAX(CASE WHEN layer = 'canopy' THEN mx END) AS max_canopy_m,
       MAX(CASE WHEN layer = 'ground' THEN n END) AS ground_px,
       MAX(CASE WHEN layer = 'surface' THEN n END) AS surface_px,
       MAX(CASE WHEN layer = 'canopy' THEN n END) AS canopy_px
FROM zones z JOIN agg a ON a.zone = z.zone
GROUP BY z.zone, z.ha
ORDER BY mean_canopy_m DESC

It ran in 144 seconds. Washington Park holds 1,963,217 LiDAR ground pixels and 2,935 radar pixels.

ZoneAreaLiDAR groundRadar surfaceSurface − groundCanopy model meanCanopy model max
Marquam Nature Park83.7 ha180.28 m203.88 m23.60 m22.80 m49 m
Washington Park194.9 ha182.53 m196.76 m14.22 m14.55 m50 m
Hoyt Arboretum65.1 ha227.66 m240.19 m12.52 m14.38 m50 m
Albina Yard85.0 ha10.54 m9.59 m−0.95 m0.03 m23 m
Paired horizontal bar chart for four Portland zones. Marquam Nature Park: canopy model mean 22.80 m, radar surface minus lidar ground 23.60 m. Washington Park: 14.55 m and 14.22 m. Hoyt Arboretum: 14.38 m and 12.52 m. Albina rail yard: 0.03 m and minus 0.95 m
Mean height above 3DEP LiDAR ground in four Portland zones. Over forest, Copernicus GLO-30 minus the LiDAR ground lands within 1.9 m of the CHMv2 canopy mean; over the open rail yard it reads −0.95 m.

Over the forested parks, radar surface minus LiDAR ground lands within 0.3 to 1.9 m of the canopy model's mean. Together, a 30 m surface model and a 1 m LiDAR terrain model give a forest's average height. They miss the tallest conifers, 49 to 50 m in the canopy model, which a 30 m cell averages with lower trees. The rail yard, with almost no canopy, reads −0.95 m. That baseline combines radar noise with the gap between two vertical datums, the reference surfaces that heights are measured from: NAVD88 for 3DEP and EGM2008 for GLO-30.

Building heights from radar surface minus LiDAR ground

The second query repeats the subtraction for the downtown buildings listed in the sources table. It groups buildings by the source of their Overture height: USGS LiDAR, OpenStreetMap, or Microsoft's machine-learning heights. It compares each height with the highest radar pixel in the footprint minus the mean LiDAR ground under it. Each raster is clipped once to the box and copied to every worker, so each building reads two small rasters in memory. The query ran in 142 seconds.

-- Radar surface minus lidar ground at downtown Portland buildings, by Overture height source
WITH aoi AS (
  SELECT ST_SetSRID(ST_PolygonFromEnvelope(-122.695, 45.514, -122.670, 45.532), 4326) AS box
),
b AS (
  -- Footprints of 2,000 m2 or more with a height, fully inside the box
  SELECT id, height,
         CASE WHEN exists(sources, s -> s.dataset = 'USGS Lidar') THEN 'USGS Lidar'
              WHEN exists(sources, s -> s.property = '/properties/height'
                                        AND s.dataset = 'Microsoft ML Buildings') THEN 'Microsoft ML'
              ELSE 'OpenStreetMap' END AS height_source,
         ST_SetSRID(geometry, 4326) AS geom
  FROM wherobots_open_data.overture_maps_foundation.buildings_building
  WHERE bbox.xmin > -122.695 AND bbox.xmax < -122.670 AND bbox.ymin > 45.514 AND bbox.ymax < 45.532
    AND height IS NOT NULL AND ST_AreaSpheroid(geometry) >= 2000
),
-- Clip each raster once to the box. RS_Clip(raster, band, geom, allTouched, noDataValue, crop)
dtm AS (
  -- USGS 3DEP 1 m bare-earth DEM from the 2024 Portland Metro lidar survey (NAVD88 heights)
  SELECT /*+ BROADCAST(a) */ RS_Clip(RS_FromPath(concat(
           's3://prd-tnm/StagedProducts/Elevation/1m/Projects/OR_PortlandMetro_B24/TIFF/USGS_1M_10_',
           v.t, '_OR_PortlandMetro_B24.tif')), 1, a.box, true, -999999, true) AS rast
  FROM VALUES ('x52y504'), ('x52y505') AS v(t) CROSS JOIN aoi a
),
dsm AS (
  -- Copernicus DEM GLO-30, a radar digital surface model (EGM2008 heights)
  SELECT /*+ BROADCAST(a) */ RS_Clip(c.rast, 1, a.box, true, -32767, true) AS rast
  FROM wherobots_open_data.copernicus_dem.glo_30m c JOIN aoi a ON ST_Intersects(c.footprint, a.box)
),
zs AS (
  -- Zonal statistics per building on the small clipped rasters, broadcast to every partition
  SELECT /*+ BROADCAST(d) */ 'ground' AS layer, b.id, RS_ZonalStatsAll(d.rast, b.geom, 1, false, true) AS s
  FROM b CROSS JOIN (SELECT rast FROM dtm WHERE rast IS NOT NULL) d
  UNION ALL
  SELECT /*+ BROADCAST(d) */ 'surface', b.id, RS_ZonalStatsAll(d.rast, b.geom, 1, false, true)
  FROM b CROSS JOIN (SELECT rast FROM dsm WHERE rast IS NOT NULL) d
),
per_building AS (
  -- Highest radar surface pixel in the footprint minus the mean lidar ground under it
  SELECT b.id, b.height_source, b.height AS overture_height_m,
         MAX(CASE WHEN z.layer = 'surface' THEN z.s.max END)
           - SUM(CASE WHEN z.layer = 'ground' THEN z.s.sum END)
             / SUM(CASE WHEN z.layer = 'ground' THEN z.s.count END) AS radar_minus_ground_m
  FROM b JOIN zs z ON z.id = b.id
  WHERE z.s.count > 0
  GROUP BY b.id, b.height_source, b.height
)
-- One row per height source plus an all-buildings row (height_source is NULL).
-- SELECT * FROM per_building returns each building.
SELECT height_source, COUNT(*) AS buildings,
       ROUND(corr(overture_height_m, radar_minus_ground_m), 2) AS r,
       ROUND(percentile(overture_height_m, 0.5), 1) AS median_overture_m,
       ROUND(percentile(radar_minus_ground_m - overture_height_m, 0.5), 1) AS median_gap_m,
       COUNT_IF(overture_height_m >= 100) AS towers_100m,
       ROUND(percentile(CASE WHEN overture_height_m >= 100 THEN radar_minus_ground_m END, 0.5), 1) AS towers_radar_m
FROM per_building
WHERE radar_minus_ground_m IS NOT NULL
GROUP BY GROUPING SETS ((height_source), ())
ORDER BY buildings DESC

It returned 117 buildings:

Overture height sourceBuildingsMedian Overture heightCorrelation (r)Median gap, radar minus Overture
USGS Lidar4915.2 m0.55−4.8 m
Microsoft ML3415.7 m0.08−4.3 m
OpenStreetMap3471.5 m0.04−56.8 m
All buildings11718.5 m0.22−8.0 m
Scatter plot of 117 downtown Portland buildings. The horizontal axis is Overture height from 0 to 175 m, and the vertical axis is Copernicus GLO-30 surface minus 3DEP LiDAR ground. Green points for buildings with USGS LiDAR heights cluster near the one-to-one line at low heights. Pink points for OpenStreetMap heights include every tower but stay low on the vertical axis. The tallest tower, 167 m in Overture, reads 8.0 m
Highest GLO-30 pixel minus mean 3DEP LiDAR ground for 117 Overture buildings in downtown Portland. Buildings with USGS LiDAR heights track the radar surface (r = 0.55); the six towers of 100 m or more read a median 10.8 m.

For low and mid-rise buildings whose Overture height came from USGS LiDAR, the radar surface tracks the height (r = 0.55). It sits a median 4.8 m low, consistent with 30 m cells that mix roofs with streets. The method fails on towers. A tower covers one or two 30 m cells. Synthetic aperture radar looks at the ground from the side, so tall facades are shifted in the image and hide what is behind them. The six towers of 100 m or more, all with OpenStreetMap heights, read a median 10.8 m above the LiDAR ground. The 34 Microsoft machine-learning (ML) heights, median 15.7 m, correlate little with the radar surface (r = 0.08). Overture's LiDAR-sourced heights came from 3DEP point clouds.

The same SQL runs per 3DEP tile across a county or a state. The Model Context Protocol (MCP) is a standard way to connect an AI agent to tools and data. An agent connected through the Wherobots MCP Server can write it from a plain-language request. The models people use every day were trained on text, documents, databases, and the internet. Spatial SQL over elevation rasters and footprints gives those models measured heights of real places, the basis of geospatial AI. Where no LiDAR survey exists, RasterFlow's Meta CHM v1 model estimates canopy height in meters from 60 cm aerial imagery. The imagery comes from the National Agriculture Imagery Program (NAIP), and the output is a raster that the same RS_ functions read.

LiDAR research and what changes at scale

From ranging to mapping

After Wehr and Lohr's 1999 system overview, forestry led the applications. Lefsky, Cohen, Parker, and Harding showed in Lidar remote sensing for ecosystem studies (2002) that LiDAR measures canopy structure directly. Næsset's two-stage procedure (2002) introduced the area-based approach that forest management inventories use. A regression links tree measurements in field plots to LiDAR height statistics, then predicts every cell of the survey. Popescu, Wynne, and Nelson measured individual crown diameter (2003) to estimate tree volume and biomass. Khosravipour and colleagues removed a common artifact, false holes in the canopy surface, with pit-free canopy height models (2014).

Ground filtering

Every DTM depends on separating ground returns from everything else. Axelsson's adaptive TIN (triangulated irregular network) densification (2000) builds a coarse triangle surface from the lowest local points. It adds points within angle and distance limits and rebuilds the surface each pass. Zhang, Chen, Whitman, and colleagues introduced the progressive morphological filter (2003). It removes cars, trees, and buildings with a minimum then maximum filter (an opening) whose window grows step by step. Sithole and Vosselman's experimental comparison of eight filters (2004) found that all did well on smooth rural terrain and all made errors in complex cities and on rough, vegetated slopes. Zhang, Qi, Wan, and colleagues then proposed the cloth simulation filter (2016). It turns the point cloud upside down, drops a simulated cloth on it, and keeps the points the cloth touches. It needs few parameters and ships as a plugin in the open-source CloudCompare.

Deep learning on point clouds

Point clouds have no grid, so early networks voxelized or rendered them first. Qi, Su, Mo, and Guibas removed that step with PointNet (CVPR 2017), a network that reads raw points in any order. PointNet++ (NeurIPS 2017) added groups of nearby points at several scales. Thomas and colleagues' Kernel Point Convolution, KPConv (ICCV 2019), placed convolution kernels at points in space. Semantic3D (Hackel and colleagues, 2017) released over four billion hand-labeled terrestrial LiDAR points in eight classes. Guo and colleagues' survey of deep learning for 3D point clouds (2021) reviews the work that followed.

Spaceborne LiDAR and global canopy height

Airborne surveys are dense and local; spaceborne LiDAR is global and sparse. ICESat-2's land and vegetation product reports ground and canopy heights in 100 m segments along track. Neuenschwander and Pitts describe it in The ATL08 land and vegetation product for the ICESat-2 Mission (2019). GEDI samples canopy height in 25 m footprints. Potapov and colleagues extrapolated GEDI with Landsat to a 30 m global forest height map for 2019 (2021). Lang, Jetz, Schindler, and Wegner trained a deep network on GEDI and Sentinel-2 for a high-resolution canopy height model of the Earth at 10 m (2023). Tolan and colleagues reached 1 m with canopy height maps from Maxar RGB imagery (2024), imagery in red, green, and blue bands. Their vision transformer, trained on aerial LiDAR and calibrated with GEDI, had a reported mean absolute error of 2.8 m. Brandt and colleagues' CHMv2 (2026) rebuilt the model on the DINOv3 image network. They validated it against independent airborne LiDAR and against GEDI and ICESat-2 observations. It is the canopy layer in the Portland queries.

What changes at scale

A 1,000 km² county at the QL1 minimum of 8 pulses per square meter is 8 billion pulses. The 3DEP archive on AWS held more than 12 trillion points when USGS announced it. Stoker and Miller tested whether data from many producers are accurate and consistent across 3DEP (2022). At that scale, analysis needs many machines working in parallel. Jia Yu, Jinxuan Wu, and Mohamed Sarwat introduced spatial processing on Apache Spark with GeoSpark (ACM SIGSPATIAL 2015). Yu, Zhang, and Sarwat described its partitioning, indexing, and join design in Spatial data management in Apache Spark: the GeoSpark perspective and beyond (GeoInformatica, 2019). GeoSpark became Apache Sedona. Its raster functions run the zonal statistics in the queries above in parallel. Raster processing at scale: the out-of-database architecture behind WherobotsDB explains why a zonal statistic reads only the Cloud Optimized GeoTIFF (COG) tiles under each zone.

Open problems

  • Ground under dense canopy and on steep slopes. Few pulses reach the ground in closed forest, and filters confuse slope breaks with objects.
  • Time. Surveys capture one date. In Portland the LiDAR ground is from 2024, the radar surface from 2011 to 2015, and the canopy imagery from varying dates. A building completed after 2015 has LiDAR ground but no radar height.
  • Datums. Mixing products means mixing vertical datums, as in the −0.95 m rail yard baseline.
  • Labels. Deep networks need labeled points, and labeled airborne data is scarce outside a few benchmarks.
  • Points in databases. Point clouds still ship as files and need conversion to tables before SQL beside rasters and vectors.

Conclusions

  1. LiDAR terrain, canopy, and building heights all start from the points labeled ground. Every filter in Sithole and Vosselman's comparison made errors in complex cities and on rough, vegetated slopes. Check how the ground class was made before trusting a 1 m DEM there.
  2. For mean forest height, LiDAR ground plus a 30 m radar surface model can stand in for a LiDAR surface model. Over three Portland parks the difference landed within 0.3 to 1.9 m of the canopy model's mean. The tallest trees, 49 to 50 m, average out in 30 m cells.
  3. Building heights in a city need LiDAR data or a meter-scale surface model. The 49 downtown buildings with USGS LiDAR heights tracked the 30 m radar surface at r = 0.55, a median 4.8 m low. The six towers of 100 m or more read a median 10.8 m.
  4. Before subtracting a LiDAR ground from another product, match the vertical datums and the dates. The −0.95 m rail yard baseline combines the NAVD88 to EGM2008 datum gap with radar noise. A 2024 LiDAR ground under a 2011 to 2015 radar surface gives newer buildings no height.
  5. Rasters made from LiDAR data can be queried in place; LiDAR points need conversion first. Clip each raster once to the area before per-building zonal statistics, so the reads stay in memory. Convert LAS or LAZ points to GeoParquet tables to query them in SQL beside rasters and vectors.

Read more from Wherobots

Load LiDAR-derived elevation and canopy rasters into WherobotsDB with a Wherobots free trial at cloud.wherobots.com.

Frequently asked questions

What is LiDAR data?

LiDAR data is a point cloud: millions of 3D points measured by a laser scanner that times the round trip of each light pulse. Each point has x, y, and z coordinates, an intensity, a return number, and a classification such as ground, vegetation, building, or water. It is the source of most high-resolution terrain, canopy height, and building height maps.

How is LiDAR data collected?

A scanner on an aircraft, drone, vehicle, tripod, or satellite emits laser pulses. It records the time each reflection takes to return, and the speed of light turns that time into a distance. A satellite positioning (GNSS) receiver records where the scanner was, and an inertial unit records which way it pointed. Together they place each return as a point with map coordinates.

What is the difference between LiDAR data and a point cloud?

A point cloud is any set of 3D points, and LiDAR data is a point cloud produced by a laser scanner. Photogrammetry also produces point clouds, from overlapping photographs. LiDAR data adds per-point intensity, return number, and multiple returns per pulse, which is how it maps the ground under vegetation.

What file format is LiDAR data?

LiDAR data is stored in LAS, the binary standard of the American Society for Photogrammetry and Remote Sensing (ASPRS). LAZ is LAS with lossless compression; the LASzip tool writes it at 7 to 25 percent of the LAS size. Cloud Optimized Point Cloud (COPC) is a LAZ 1.4 file with its points grouped into nested cubes, called an octree, so a client can download one area over HTTP. Terrain and canopy grids made from the points are written as GeoTIFF. Points can be converted to GeoParquet tables for SQL analysis.

How accurate is LiDAR data?

USGS quality levels QL1 and QL2 both require 10 cm vertical accuracy on open ground, measured as the root mean square error of heights (RMSEz). QL1 needs at least 8 pulses per square meter and QL2 at least 2. Accuracy falls under dense canopy and on steep slopes, where fewer pulses reach the ground and ground filtering makes more errors.

Where can I download free LiDAR data?

Free LiDAR data for the United States is on the USGS 3D Elevation Program through LidarExplorer and The National Map, and on AWS as LAZ tiles and Entwine Point Tiles. NOAA’s Data Access Viewer serves coastal LiDAR, and OpenTopography hosts academic surveys worldwide. The Netherlands (AHN) and England (Environment Agency National LIDAR Programme) publish national LiDAR data as open data.

Is LiDAR data publicly available?

Yes. Free sources include USGS 3DEP for the United States, NOAA’s coastal surveys, OpenTopography’s research data, and several national programs.

How can I view LiDAR data?

Open a LAS, LAZ, or COPC file in a point cloud viewer such as CloudCompare, or in a browser viewer that streams COPC. USGS LidarExplorer and OpenTopography preview coverage before download. To view terrain or canopy height, load the derived GeoTIFF DEM or canopy height model in any GIS (geographic information system).

What is LiDAR in simple terms?

LiDAR measures distance with light. A scanner fires laser pulses many thousands of times a second and times how long each one takes to bounce back. Each measurement becomes a point in 3D, and together the points form a model of the ground, trees, and buildings below.

What is the difference between a DSM, a DTM, and a canopy height model?

A digital surface model (DSM) is gridded from the first or highest returns and includes trees and roofs. A digital terrain model (DTM) is gridded from ground returns only. A canopy height model is the DSM minus the DTM: the height of vegetation above the ground. The same subtraction inside a building footprint gives building height.

What are LiDAR classification codes?

Classification codes are ASPRS standard values stored with each LAS point. The common ones are 1 unclassified, 2 ground, 3 to 5 low, medium, and high vegetation, 6 building, 7 low noise, 9 water, 17 bridge deck, and 18 high noise. Values 64 to 255 are free for user definitions.