# laspy.lasdata module

## LasData

class laspy.lasdata.LasData(header: LasHeader, points: PackedPointRecord | ScaleAwarePointRecord | None = None)

  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: VLRList | None
  add_extra_dim(params: ExtraBytesParams) → None

    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

    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

    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

    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

    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: LazBackend | Sequence[LazBackend] | None = None) → None
  write(destination: BinaryIO, do_compress: bool | None = None, laz_backend: LazBackend | Sequence[LazBackend] | None = 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

    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])