laspy.lasdata module

LasData

class laspy.lasdata.LasData(header: LasHeader, points: Optional[Union[PackedPointRecord, ScaleAwarePointRecord]] = None)[source]

Bases: object

Class synchronizing all the moving parts of LAS files.

It connects the point record, header, vlrs together.

To access points dimensions using this class you have two possibilities

las = laspy.read('some_file.las')
las.classification
# or
las['classification']
property point_format: PointFormat

Shortcut to get the point format

property xyz: ndarray

Returns a new 2D numpy array with the x,y,z coordinates

>>> import laspy
>>> las = laspy.read("tests/data/simple.las")
>>> xyz = las.xyz
>>> xyz.ndim
2
>>> xyz.shape
(1065, 3)
>>> np.all(xyz[..., 0] == las.x)
True
property points: PackedPointRecord

Returns the point record

property vlrs: VLRList
property evlrs: Optional[VLRList]
add_extra_dim(params: ExtraBytesParams) None[source]

Adds a new extra dimension to the point record

Note

If you plan on adding multiple extra dimensions, prefer add_extra_dims() as it will save re-allocations and data copy

Parameters:

params (ExtraBytesParams) – parameters of the new extra dimension to add

add_extra_dims(params: List[ExtraBytesParams]) None[source]

Add multiple extra dimensions at once

Parameters:

params (list of parameters of the new extra dimensions to add) –

remove_extra_dims(names: Iterable[str]) None[source]

Remove multiple extra dimensions from this object

Parameters:

names (iterable,) – names of the extra dimensions to be removed

Raises:

LaspyException – if you try to remove an extra dimension that do not exist.:

remove_extra_dim(name: str) None[source]

Remove an extra dimensions from this object

Note

If you plan on removing multiple extra dimensions, prefer remove_extra_dims() as it will save re-allocations and data copy

Parameters:

name (str,) – name of the extra dimension to be removed

Raises:

LaspyException – if you try to remove an extra dimension that do not exist.:

update_header() None[source]

Update the information stored in the header to be in sync with the actual data.

This method is called automatically when you save a file using laspy.lasdatas.base.LasBase.write()

write(destination: str, laz_backend: Optional[Union[LazBackend, Sequence[LazBackend]]] = None) None[source]
write(destination: BinaryIO, do_compress: Optional[bool] = None, laz_backend: Optional[Union[LazBackend, Sequence[LazBackend]]] = None) None

Writes to a stream or file

Note

When destination is a string, it will be interpreted as the path were the file should be written to, and whether the file will be compressed depends on the extension used (case insensitive):

  • .laz -> compressed

  • .las -> uncompressed

And the do_compress option will be ignored

Parameters:
  • destination (str or file object) – filename or stream to write to

  • do_compress (bool, optional) – Flags to indicate if you want to compress the data

  • laz_backend (optional, the laz backend to use) – By default, laspy detect available backends

change_scaling(scales=None, offsets=None) None[source]

This changes the scales and/or offset used for the x,y,z dimensions.

It recomputes the internal, non-scaled X,Y,Z dimensions to match the new scales and offsets.

It also updates the header with the new values of scales and offsets.

Parameters:
  • scales (optional) – New scales to be used. If not provided, the scales won’t change.

  • offsets (optional) – New offsets to be used. If not provided, the offsets won’t change.

Example

>>> import laspy
>>> header = laspy.LasHeader()
>>> header.scales = np.array([0.1, 0.1, 0.1])
>>> header.offsets = np.array([0, 0 ,0])
>>> las = laspy.LasData(header=header)
>>> las.x = [10.0]
>>> las.y = [20.0]
>>> las.z = [30.0]
>>> # X = (x - x_offset) / x_scale
>>> assert np.all(las.xyz == [[10.0, 20., 30]])
>>> assert np.all(las.X == [100])
>>> assert np.all(las.Y == [200])
>>> assert np.all(las.Z == [300])

We change the scales (only changing x_scale here) but not the offsets.

The xyz coordinates (double) are the same (minus possible rounding with actual coordinates) However the integer coordinates changed

>>> las.change_scaling(scales=[0.01, 0.1, 0.1])
>>> assert np.all(las.xyz == [[10.0, 20., 30]])
>>> assert np.all(las.X == [1000])
>>> assert np.all(las.Y == [200])
>>> assert np.all(las.Z == [300])

Same idea if we change the offsets, the xyz do not change but XYZ does

>>> las.change_scaling(offsets=[0, 10, 15])
>>> assert np.all(las.xyz == [[10.0, 20., 30]])
>>> assert np.all(las.X == [1000])
>>> assert np.all(las.Y == [100])
>>> assert np.all(las.Z == [150])