Native Python ASPRS LAS read/write library for processing LiDAR point cloud data
—
High-level functions for reading, writing, creating, and memory-mapping LAS files. These functions provide the primary entry points for working with LAS/LAZ data and support streaming, chunked processing, and multiple compression backends.
Read entire LAS files into memory with support for LAZ decompression and selective field loading.
def read(source, closefd=True, laz_backend=None, decompression_selection=None, encoding_errors="strict") -> LasData:
"""
Read an entire LAS file into memory.
Parameters:
- source: str, Path, or file-like object - LAS/LAZ file to read
- closefd: bool - Whether to close file descriptor (default: True)
- laz_backend: LazBackend or list of LazBackend - Compression backend selection
- decompression_selection: DecompressionSelection - Fields to decompress (LAZ only)
- encoding_errors: str - How to handle encoding errors (default: "strict")
Returns:
LasData: Complete LAS data container with header, points, and VLRs
"""Usage Example:
import laspy
# Read entire file
las = laspy.read('data.las')
print(f"Loaded {len(las.points)} points")
# Read LAZ with specific backend
las = laspy.read('data.laz', laz_backend=laspy.LazBackend.Lazrs)
# Read only specific fields (for point formats 6-10)
from laspy import DecompressionSelection
selection = DecompressionSelection.base() # Only basic fields
las = laspy.read('data.laz', decompression_selection=selection)Open LAS files for reading, writing, or appending with flexible mode support.
def open(source, mode="r", closefd=True, laz_backend=None, header=None, do_compress=None, encoding_errors="strict", read_evlrs=True, decompression_selection=None):
"""
Open LAS file in specified mode.
Parameters:
- source: str, Path, or file-like object - File to open
- mode: str - Access mode ("r", "w", "a") (default: "r")
- closefd: bool - Whether to close file descriptor (default: True)
- laz_backend: LazBackend - Compression backend for LAZ files
- header: LasHeader - Required for write mode, header for new file
- do_compress: bool - Force compression on/off (overrides file extension)
- encoding_errors: str - How to handle encoding errors (default: "strict")
- read_evlrs: bool - Whether to read Extended VLRs (default: True)
- decompression_selection: DecompressionSelection - Fields to decompress
Returns:
Union[LasReader, LasWriter, LasAppender]: Handler based on mode
"""Usage Examples:
import laspy
# Read mode - returns LasReader
with laspy.open('input.las') as reader:
header = reader.header
points = reader.read_points(1000)
# Write mode - returns LasWriter (requires header)
header = laspy.LasHeader(point_format=3, version=(1, 2))
with laspy.open('output.las', mode='w', header=header) as writer:
writer.write_points(points)
# Append mode - returns LasAppender
with laspy.open('existing.las', mode='a') as appender:
appender.append_points(new_points)
# Write compressed LAZ
with laspy.open('output.laz', mode='w', header=header, do_compress=True) as writer:
writer.write_points(points)Create new empty LAS data containers with specified point formats and versions.
def create(*, point_format=None, file_version=None) -> LasData:
"""
Create new empty LAS data container.
Parameters:
- point_format: int or PointFormat - Point format ID (default: 3)
- file_version: tuple or Version - LAS version (default: (1, 2))
Returns:
LasData: New empty LAS data container with header
"""Usage Example:
import laspy
import numpy as np
# Create new LAS with default format
las = laspy.create()
# Create with specific point format and version
las = laspy.create(point_format=6, file_version=(1, 4))
# Add points
las.x = np.array([1.0, 2.0, 3.0])
las.y = np.array([1.0, 2.0, 3.0])
las.z = np.array([1.0, 2.0, 3.0])
las.classification = np.array([2, 2, 2], dtype=np.uint8)
# Update header and write
las.update_header()
las.write('new_file.las')Memory-map LAS files for efficient random access without loading entire file into memory.
def mmap(filename) -> LasMMAP:
"""
Memory-map a LAS file for efficient access.
Parameters:
- filename: str or Path - LAS file to memory-map
Returns:
LasMMAP: Memory-mapped LAS data (extends LasData)
Note: Only works with uncompressed LAS files, not LAZ
"""Usage Example:
import laspy
# Memory-map large LAS file
with laspy.mmap('large_file.las') as las:
# Access subset of points efficiently
subset = las.points[1000:2000]
print(f"Subset bounds: {subset.x.min()}-{subset.x.max()}")
# Modify points in-place
las.classification[las.z < 100] = 2 # Ground classConvert LAS data between different point formats and file versions.
def convert(source_las, *, point_format_id=None, file_version=None) -> LasData:
"""
Convert LAS data to different point format or file version.
Parameters:
- source_las: LasData - Source LAS data to convert
- point_format_id: int - Target point format ID
- file_version: tuple or Version - Target LAS version
Returns:
LasData: Converted LAS data with new format/version
"""Usage Example:
import laspy
# Load source data
source = laspy.read('input.las')
print(f"Source format: {source.header.point_format.id}")
# Convert to point format 6 (adds GPS time, RGB)
converted = laspy.convert(source, point_format_id=6)
print(f"Target format: {converted.header.point_format.id}")
# Check what dimensions might be lost
from laspy.point.format import lost_dimensions
lost = lost_dimensions(source.header.point_format, converted.header.point_format)
print(f"Lost dimensions: {lost}")
# Write converted data
converted.write('converted.las')All I/O operations can raise LaspyException or its subclasses:
class LaspyException(Exception): ...
class LazError(LaspyException): ... # LAZ compression errors
class FileVersionNotSupported(LaspyException): ... # Unsupported LAS versions
class PointFormatNotSupported(LaspyException): ... # Unsupported point formatsExample Error Handling:
import laspy
from laspy.errors import LaspyException, LazError
try:
las = laspy.read('file.laz')
except LazError as e:
print(f"LAZ decompression failed: {e}")
except FileVersionNotSupported as e:
print(f"Unsupported LAS version: {e}")
except LaspyException as e:
print(f"General laspy error: {e}")Check format and version support:
def supported_point_formats() -> Set[int]:
"""Get set of supported LAS point format IDs."""
def supported_versions() -> Set[str]:
"""Get set of supported LAS version strings."""Usage:
import laspy
# Check what's supported
formats = laspy.supported_point_formats() # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
versions = laspy.supported_versions() # {'1.2', '1.3', '1.4'}
print(f"Supported point formats: {sorted(formats)}")
print(f"Supported LAS versions: {sorted(versions)}")Install with Tessl CLI
npx tessl i tessl/pypi-laspy