0
# Core I/O Operations
1
2
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.
3
4
## Capabilities
5
6
### Reading LAS Files
7
8
Read entire LAS files into memory with support for LAZ decompression and selective field loading.
9
10
```python { .api }
11
def read(source, closefd=True, laz_backend=None, decompression_selection=None, encoding_errors="strict") -> LasData:
12
"""
13
Read an entire LAS file into memory.
14
15
Parameters:
16
- source: str, Path, or file-like object - LAS/LAZ file to read
17
- closefd: bool - Whether to close file descriptor (default: True)
18
- laz_backend: LazBackend or list of LazBackend - Compression backend selection
19
- decompression_selection: DecompressionSelection - Fields to decompress (LAZ only)
20
- encoding_errors: str - How to handle encoding errors (default: "strict")
21
22
Returns:
23
LasData: Complete LAS data container with header, points, and VLRs
24
"""
25
```
26
27
**Usage Example:**
28
```python
29
import laspy
30
31
# Read entire file
32
las = laspy.read('data.las')
33
print(f"Loaded {len(las.points)} points")
34
35
# Read LAZ with specific backend
36
las = laspy.read('data.laz', laz_backend=laspy.LazBackend.Lazrs)
37
38
# Read only specific fields (for point formats 6-10)
39
from laspy import DecompressionSelection
40
selection = DecompressionSelection.base() # Only basic fields
41
las = laspy.read('data.laz', decompression_selection=selection)
42
```
43
44
### Opening LAS Files
45
46
Open LAS files for reading, writing, or appending with flexible mode support.
47
48
```python { .api }
49
def open(source, mode="r", closefd=True, laz_backend=None, header=None, do_compress=None, encoding_errors="strict", read_evlrs=True, decompression_selection=None):
50
"""
51
Open LAS file in specified mode.
52
53
Parameters:
54
- source: str, Path, or file-like object - File to open
55
- mode: str - Access mode ("r", "w", "a") (default: "r")
56
- closefd: bool - Whether to close file descriptor (default: True)
57
- laz_backend: LazBackend - Compression backend for LAZ files
58
- header: LasHeader - Required for write mode, header for new file
59
- do_compress: bool - Force compression on/off (overrides file extension)
60
- encoding_errors: str - How to handle encoding errors (default: "strict")
61
- read_evlrs: bool - Whether to read Extended VLRs (default: True)
62
- decompression_selection: DecompressionSelection - Fields to decompress
63
64
Returns:
65
Union[LasReader, LasWriter, LasAppender]: Handler based on mode
66
"""
67
```
68
69
**Usage Examples:**
70
```python
71
import laspy
72
73
# Read mode - returns LasReader
74
with laspy.open('input.las') as reader:
75
header = reader.header
76
points = reader.read_points(1000)
77
78
# Write mode - returns LasWriter (requires header)
79
header = laspy.LasHeader(point_format=3, version=(1, 2))
80
with laspy.open('output.las', mode='w', header=header) as writer:
81
writer.write_points(points)
82
83
# Append mode - returns LasAppender
84
with laspy.open('existing.las', mode='a') as appender:
85
appender.append_points(new_points)
86
87
# Write compressed LAZ
88
with laspy.open('output.laz', mode='w', header=header, do_compress=True) as writer:
89
writer.write_points(points)
90
```
91
92
### Creating New LAS Data
93
94
Create new empty LAS data containers with specified point formats and versions.
95
96
```python { .api }
97
def create(*, point_format=None, file_version=None) -> LasData:
98
"""
99
Create new empty LAS data container.
100
101
Parameters:
102
- point_format: int or PointFormat - Point format ID (default: 3)
103
- file_version: tuple or Version - LAS version (default: (1, 2))
104
105
Returns:
106
LasData: New empty LAS data container with header
107
"""
108
```
109
110
**Usage Example:**
111
```python
112
import laspy
113
import numpy as np
114
115
# Create new LAS with default format
116
las = laspy.create()
117
118
# Create with specific point format and version
119
las = laspy.create(point_format=6, file_version=(1, 4))
120
121
# Add points
122
las.x = np.array([1.0, 2.0, 3.0])
123
las.y = np.array([1.0, 2.0, 3.0])
124
las.z = np.array([1.0, 2.0, 3.0])
125
las.classification = np.array([2, 2, 2], dtype=np.uint8)
126
127
# Update header and write
128
las.update_header()
129
las.write('new_file.las')
130
```
131
132
### Memory Mapping LAS Files
133
134
Memory-map LAS files for efficient random access without loading entire file into memory.
135
136
```python { .api }
137
def mmap(filename) -> LasMMAP:
138
"""
139
Memory-map a LAS file for efficient access.
140
141
Parameters:
142
- filename: str or Path - LAS file to memory-map
143
144
Returns:
145
LasMMAP: Memory-mapped LAS data (extends LasData)
146
147
Note: Only works with uncompressed LAS files, not LAZ
148
"""
149
```
150
151
**Usage Example:**
152
```python
153
import laspy
154
155
# Memory-map large LAS file
156
with laspy.mmap('large_file.las') as las:
157
# Access subset of points efficiently
158
subset = las.points[1000:2000]
159
print(f"Subset bounds: {subset.x.min()}-{subset.x.max()}")
160
161
# Modify points in-place
162
las.classification[las.z < 100] = 2 # Ground class
163
```
164
165
### Converting Between Formats
166
167
Convert LAS data between different point formats and file versions.
168
169
```python { .api }
170
def convert(source_las, *, point_format_id=None, file_version=None) -> LasData:
171
"""
172
Convert LAS data to different point format or file version.
173
174
Parameters:
175
- source_las: LasData - Source LAS data to convert
176
- point_format_id: int - Target point format ID
177
- file_version: tuple or Version - Target LAS version
178
179
Returns:
180
LasData: Converted LAS data with new format/version
181
"""
182
```
183
184
**Usage Example:**
185
```python
186
import laspy
187
188
# Load source data
189
source = laspy.read('input.las')
190
print(f"Source format: {source.header.point_format.id}")
191
192
# Convert to point format 6 (adds GPS time, RGB)
193
converted = laspy.convert(source, point_format_id=6)
194
print(f"Target format: {converted.header.point_format.id}")
195
196
# Check what dimensions might be lost
197
from laspy.point.format import lost_dimensions
198
lost = lost_dimensions(source.header.point_format, converted.header.point_format)
199
print(f"Lost dimensions: {lost}")
200
201
# Write converted data
202
converted.write('converted.las')
203
```
204
205
## Error Handling
206
207
All I/O operations can raise `LaspyException` or its subclasses:
208
209
```python { .api }
210
class LaspyException(Exception): ...
211
class LazError(LaspyException): ... # LAZ compression errors
212
class FileVersionNotSupported(LaspyException): ... # Unsupported LAS versions
213
class PointFormatNotSupported(LaspyException): ... # Unsupported point formats
214
```
215
216
**Example Error Handling:**
217
```python
218
import laspy
219
from laspy.errors import LaspyException, LazError
220
221
try:
222
las = laspy.read('file.laz')
223
except LazError as e:
224
print(f"LAZ decompression failed: {e}")
225
except FileVersionNotSupported as e:
226
print(f"Unsupported LAS version: {e}")
227
except LaspyException as e:
228
print(f"General laspy error: {e}")
229
```
230
231
## Supported Formats
232
233
Check format and version support:
234
235
```python { .api }
236
def supported_point_formats() -> Set[int]:
237
"""Get set of supported LAS point format IDs."""
238
239
def supported_versions() -> Set[str]:
240
"""Get set of supported LAS version strings."""
241
```
242
243
**Usage:**
244
```python
245
import laspy
246
247
# Check what's supported
248
formats = laspy.supported_point_formats() # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
249
versions = laspy.supported_versions() # {'1.2', '1.3', '1.4'}
250
251
print(f"Supported point formats: {sorted(formats)}")
252
print(f"Supported LAS versions: {sorted(versions)}")
253
```