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

Commit

Permalink
Add method to multiple extra dimensions at once
Browse files Browse the repository at this point in the history
Its more efficient to add many extra dimensions at once.

Also change the the second style name used for float and double from 'float' to 'float32' and 'double' to 'float64' to match numpy:

  str(np.dtype('double')) = 'float64'
  str(np.dtype('float64')) = 'float64'
  str(np.dtype('f8')) = 'float64'
  • Loading branch information
tmontaigu committed Dec 9, 2020
1 parent 9161e77 commit bbba9fb
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ if you need metada informations that are contained in the header.
Sometimes files are big, too big to be read entirely and fit into your RAM.
The object returned by the :func:`pylas.open` function, :class:`pylas.lasreader.LasReader`
can also be used to read points chunk by chunk, which will allow you to do some
can also be used to read points chunk by chunk by using :meth:`pylas.lasreader.LasReader.chunk_iterator`, which will allow you to do some
processing on large files (splitting, filtering, etc)

.. code:: python
Expand Down
11 changes: 9 additions & 2 deletions docs/lessbasic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ The Allowed base types for an extra dimensions are:
+-------------------------+-------------+-------------+
| i8 or int64 | 64 | signed |
+-------------------------+-------------+-------------+
| f4 or float | 32 | floating |
| f4 or float32 | 32 | floating |
+-------------------------+-------------+-------------+
| f8 or double | 64 | floating |
| f8 or float32 | 64 | floating |
+-------------------------+-------------+-------------+

You can prepend the number '2' or '3' to one of the above base type to define an extra dimension
Expand Down Expand Up @@ -63,6 +63,13 @@ and an array field of 3 doubles for each points.
Although the specification of the ExtraBytesVlr appeared in the 1.4 LAS Spec, pylas allows to
add new dimensions to file with version < 1.4

.. note::

If you are adding multiple extra dimensions use :meth:`pylas.LasBase.add_extra_dims`
as it is more efficient (it allows to allocate all the dimensions at once instead
of re-allocating each time a new dimension is added.


Custom VLRs
===========

Expand Down
4 changes: 2 additions & 2 deletions pylas/extradims.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"int32",
"uint64",
"int64",
"float",
"double",
"float32",
"float64",
)

_extra_dims_style_1_array_2 = tuple(
Expand Down
47 changes: 37 additions & 10 deletions pylas/lasdatas/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import pathlib
from typing import Union, Optional
from typing import Union, Optional, Tuple, List

import numpy as np

Expand Down Expand Up @@ -157,6 +157,12 @@ def __setitem__(self, key, value):
def add_extra_dim(self, name: str, type: str, description: str = ""):
"""Adds a new extra dimension to the point record
.. note::
If you plan on adding multiple extra dimensions,
prefer :meth:`pylas.LasBase.add_extra_dims` as it will
save re-allocations and data copy
Parameters
----------
name: str
Expand All @@ -166,22 +172,43 @@ def add_extra_dim(self, name: str, type: str, description: str = ""):
description: str, optional
a small description of the dimension
"""
name = name.replace(" ", "_")
type_id = extradims.get_id_for_extra_dim_type(type)
# convert to u1, i2, style
type = extradims.get_type_for_extra_dim(type_id)
extra_byte = ExtraBytesStruct(
data_type=type_id, name=name.encode(), description=description.encode()
)
self.add_extra_dims([(name, type, description)])

def add_extra_dims(self, type_tuples: List[Tuple[str,...]]):
""" Add multiple extra dimensions at once
Parameters
----------
type_tuples:
a list of tuple describing the dimensions to add
[(name, type, description), (name2, other_type)]
The description is optional
"""
extra_bytes_structs = []
tuples = []
for name, type, *rest in type_tuples:
name = name.replace(" ", "_")
if rest:
description = rest[0]
else:
description = ""
type_id = extradims.get_id_for_extra_dim_type(type)
tuples.append((name, extradims.get_type_for_extra_dim(type_id)))
extra_bytes_structs.append(ExtraBytesStruct(
data_type=type_id, name=name.encode(), description=description.encode()
))

try:
extra_bytes_vlr = self.vlrs.get("ExtraBytesVlr")[0]
except IndexError:
extra_bytes_vlr = ExtraBytesVlr()
self.vlrs.append(extra_bytes_vlr)
finally:
extra_bytes_vlr.extra_bytes_structs.append(extra_byte)
self.points.add_extra_dim(name, type)
extra_bytes_vlr.extra_bytes_structs.extend(extra_bytes_structs)
self.points.add_extra_dims(tuples)



def update_header(self):
"""Update the information stored in the header
Expand Down
2 changes: 1 addition & 1 deletion pylas/point/dims.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ def from_type_str(
first_digits = "".join(itertools.takewhile(lambda l: l.isdigit(), type_str))
if first_digits:
num_elements = int(first_digits)
type_str = type_str[len(first_digits) :]
type_str = type_str[len(first_digits):]
else:
num_elements = 1

Expand Down
10 changes: 7 additions & 3 deletions pylas/point/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
import logging
from abc import ABC, abstractmethod
from typing import NoReturn, Any
from typing import NoReturn, Any, List, Tuple

import numpy as np

Expand Down Expand Up @@ -151,12 +151,16 @@ def copy_fields_from(self, other_record):
except ValueError:
pass

def add_extra_dim(self, name, type_tuple):
self.point_format.add_extra_dimension(name, type_tuple)
def add_extra_dims(self, dim_tuples: List[Tuple[str, str]]):
for name, type_str in dim_tuples:
self.point_format.add_extra_dimension(name, type_str)
old_array = self.array
self._array = np.zeros_like(old_array, dtype=self.point_format.dtype())
self.copy_fields_from(old_array)

def add_extra_dim(self, name, type_str):
self.add_extra_dims([(name, type_str)])

def memoryview(self):
return memoryview(self.array)

Expand Down

0 comments on commit bbba9fb

Please sign in to comment.