CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-laspy

Native Python ASPRS LAS read/write library for processing LiDAR point cloud data

Pending
Overview
Eval results
Files

core-io.mddocs/

Core I/O Operations

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.

Capabilities

Reading LAS Files

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)

Opening LAS Files

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)

Creating New LAS Data

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 Mapping LAS Files

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 class

Converting Between Formats

Convert 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')

Error Handling

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 formats

Example 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}")

Supported Formats

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

docs

compression.md

copc.md

core-io.md

data-containers.md

index.md

io-handlers.md

point-data.md

vlr.md

tile.json