Skip to content
This repository has been archived by the owner on Aug 18, 2022. It is now read-only.

Commit

Permalink
Merge pull request #7 from tmontaigu/lazperf-extrabytes
Browse files Browse the repository at this point in the history
Update Lazperf usage to bring extrabytes compression/decompression
  • Loading branch information
tmontaigu committed Jul 12, 2018
2 parents 33a0aca + 6d45530 commit f058c37
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 26 deletions.
29 changes: 19 additions & 10 deletions pylas/compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import numpy as np

from .errors import LazPerfNotFound
from .point.dims import get_dtype_of_format_id, POINT_FORMAT_DIMENSIONS
from .errors import LazPerfNotFound, PylasError
from .point.dims import get_dtype_of_format_id

HAS_LAZPERF = False

Expand Down Expand Up @@ -45,36 +45,45 @@ def uncompressed_id_to_compressed(point_format_id):
return (2 ** 7) | point_format_id


def decompress_buffer(compressed_buffer, point_format_id, point_count, laszip_vlr):
def decompress_buffer(compressed_buffer, points_dtype, point_count, laszip_vlr):
raise_if_no_lazperf()

ndtype = get_dtype_of_format_id(point_format_id)
point_compressed = np.frombuffer(compressed_buffer, dtype=np.uint8)

vlr_data = np.frombuffer(laszip_vlr.record_data, dtype=np.uint8)
decompressor = lazperf.VLRDecompressor(point_compressed, vlr_data)
decompressor = lazperf.VLRDecompressor(point_compressed, points_dtype.itemsize, vlr_data)

point_uncompressed = decompressor.decompress_points(point_count)

point_uncompressed = np.frombuffer(
point_uncompressed, dtype=ndtype, count=point_count
point_uncompressed, dtype=points_dtype, count=point_count
)

return point_uncompressed


def create_laz_vlr(point_format_id):
def create_laz_vlr(points_record):
raise_if_no_lazperf()
record_schema = lazperf.RecordSchema()

point_format_dimensions = POINT_FORMAT_DIMENSIONS[point_format_id]
if points_record.point_format_id >= 6:
raise PylasError("Can't compress points with format it >= 6")
record_schema.add_point()

if "gps_time" in point_format_dimensions:
if "gps_time" in points_record.dimensions_names:
record_schema.add_gps_time()

if "red" in point_format_dimensions:
if "red" in points_record.dimensions_names:
record_schema.add_rgb()

official_dtype = get_dtype_of_format_id(points_record.point_format_id)

num_extra_bytes = points_record.array.dtype.itemsize - official_dtype.itemsize
if num_extra_bytes > 0:
record_schema.add_extra_bytes(num_extra_bytes)
elif num_extra_bytes < 0:
raise PylasError("Incoherent number of extra bytes ({})".format(num_extra_bytes))

return lazperf.LazVLR(record_schema)


Expand Down
11 changes: 1 addition & 10 deletions pylas/lasdatas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,7 @@ def write_to(self, out_stream, do_compress=False):
self.update_header()

if do_compress:
try:
_ = self.vlrs.index("ExtraBytesVlr")
except ValueError:
pass
else:
raise NotImplementedError(
"Lazperf cannot compress LAS with extra bytes"
)

laz_vrl = create_laz_vlr(self.header.point_format_id)
laz_vrl = create_laz_vlr(self.points_data)
self.vlrs.append(known.LasZipVlr(laz_vrl.data()))
raw_vlrs = vlrlist.RawVLRList.from_list(self.vlrs)

Expand Down
6 changes: 4 additions & 2 deletions pylas/lasdatas/las14.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ def update_header(self):
if len(self.vlrs.get("WktCoordinateSystemVlr")) == 1:
self.header.global_encoding.wkt = 1

def add_extra_dim(self, name, type, description=''):
def add_extra_dim(self, name, type, description=""):
name = name.replace(" ", "_")
type_id = extradims.get_id_for_extra_dim_type(type)
extra_byte = ExtraBytesStruct(data_type=type_id, name=name.encode(), description=description.encode())
extra_byte = ExtraBytesStruct(
data_type=type_id, name=name.encode(), description=description.encode()
)

try:
extra_bytes_vlr = self.vlrs.get("ExtraBytesVlr")[0]
Expand Down
5 changes: 3 additions & 2 deletions pylas/lasreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def _read_points(self, vlrs):

if self.header.are_points_compressed:
laszip_vlr = vlrs.pop(vlrs.index("LasZipVlr"))
points = self._read_compressed_points_data(laszip_vlr)
points = self._read_compressed_points_data(laszip_vlr, extra_dims)
else:
points = record.PackedPointRecord.from_stream(
self.stream,
Expand All @@ -118,7 +118,7 @@ def _read_points(self, vlrs):
)
return points

def _read_compressed_points_data(self, laszip_vlr):
def _read_compressed_points_data(self, laszip_vlr, extra_dims):
""" reads the compressed point record
"""
offset_to_chunk_table = struct.unpack("<q", self.stream.read(8))[0]
Expand All @@ -137,6 +137,7 @@ def _read_compressed_points_data(self, laszip_vlr):
self.header.point_format_id,
self.header.point_count,
laszip_vlr,
extra_dims=extra_dims
)
return points

Expand Down
8 changes: 6 additions & 2 deletions pylas/point/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,17 @@ def from_buffer(cls, buffer, point_format_id, count, offset=0, extra_dims=None):

@classmethod
def from_compressed_buffer(
cls, compressed_buffer, point_format_id, count, laszip_vlr
cls, compressed_buffer, point_format_id, count, laszip_vlr, extra_dims=None
):
""" Construct the point record by reading and decompressing the points data from
the input buffer
"""
point_dtype = dims.get_dtype_of_format_id(point_format_id)
if extra_dims is not None:
point_dtype = dims.dtype_append(point_dtype, extra_dims)

uncompressed = decompress_buffer(
compressed_buffer, point_format_id, count, laszip_vlr
compressed_buffer, point_dtype, count, laszip_vlr
)
return cls(uncompressed, point_format_id)

Expand Down

0 comments on commit f058c37

Please sign in to comment.