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

Commit

Permalink
do something more rebust abour EVLRs when piping to laszip
Browse files Browse the repository at this point in the history
  • Loading branch information
tmontaigu committed Mar 9, 2020
1 parent 3439539 commit 817ab19
Showing 1 changed file with 34 additions and 16 deletions.
50 changes: 34 additions & 16 deletions pylas/lasdatas/las14.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class LasData(LasBase):
def __init__(self, *, header=None, vlrs=None, points=None, evlrs=None):
super().__init__(header=header, vlrs=vlrs, points=points)
self.laszip_was_called = False
self.evlrs = [] if evlrs is None else evlrs

def update_header(self):
Expand All @@ -15,6 +16,7 @@ def update_header(self):
self.header.global_encoding.wkt = 1

self.header.start_of_waveform_data_packet_record = 0

if len(self.points_data) > ctypes_max_limit(
self.header.__class__.legacy_point_count.size
):
Expand All @@ -23,20 +25,36 @@ def update_header(self):
self.header.legacy_point_count = len(self.points_data)

def write_to(self, out_stream, do_compress=False):
# When compressing data, we cannot know in advance the size of the compressed points
# LAS 1.4 may have evlrs located after the point data, and the header has a field
# that must give the offset to first evlr
# so in the case of writing compressed points we have to update the header
# written with seek + write
start = out_stream.tell()
super().write_to(out_stream, do_compress=do_compress)

# when do_compress=True, and that the method to compress
# is piping data through laszip we will write evlrs 2 times
# once when we write the data (with do_compress=False)
# to laszip stdin and the other time after the data laszip returned us
# it's a bit a bit strange but should do no harm
raw_evlrs = evlrs.RawEVLRList.from_list(self.evlrs)
if len(self.evlrs) > 0:
self.header.start_of_first_evlr = out_stream.tell()
self.header.number_of_evlr = len(raw_evlrs)
self.header.update_evlrs_info_in_stream(self, out_stream, start)
out_stream.seek(self.header.start_of_first_evlr)

raw_evlrs.write_to(out_stream)
out_stream.seek(start)
if not do_compress:
if len(self.evlrs) > 0:
self.header.number_of_evlr = len(self.evlrs)
self.header.start_of_first_evlr = self.header.point_size * self.header.point_count

super().write_to(out_stream, do_compress=do_compress)
if len(self.evlrs) > 0:
raw_evlrs = evlrs.RawEVLRList.from_list(self.evlrs)
raw_evlrs.write_to(out_stream)
else:
super().write_to(out_stream, do_compress=do_compress)
# if laszip was called, the out_stream already contains the evlrs
# because we were called with write_to(laszip_sdtin, do_compress=False)
# and laszip has taken care of writting the LAZ file, so we do not have to
# write evlrs
if len(self.evlrs) > 0 and not self.laszip_was_called:
self.header.number_of_evlr = len(self.evlrs)
self.header.start_of_first_evlr = out_stream.tell()
self.header.update_evlrs_info_in_stream(self, out_stream, start)
out_stream.seek(self.header.start_of_first_evlr)
raw_evlrs = evlrs.RawEVLRList.from_list(self.evlrs)
raw_evlrs.write_to(out_stream)
self.laszip_was_called = False

def _compress_with_laszip_executable(self, out_stream):
super()._compress_with_laszip_executable(out_stream)
self.laszip_was_called = True

0 comments on commit 817ab19

Please sign in to comment.