1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
from argparse import ArgumentParser
from pathlib import Path
import numpy as np
import laspy
def main(args):
files = (
[args.in_path]
if args.in_path.is_file()
else list(args.in_path.glob("*.la[s-z]"))
)
if args.out_path.suffix and len(files) > 1:
raise SystemExit("in_path is a directory and out path is a file")
for i, path in enumerate(files, start=1):
print(f"{i} / {len(files)} -> {path}")
las = laspy.read(path)
dimensions = (
dim for dim in las.point_format.dimensions if dim.name not in args.exclude
)
for dimension in dimensions:
print(f"\t{dimension.name}", end="")
if np.any(las[dimension.name] != 0) and args.keep_existing:
print("...skipped because it is already populated")
continue
if dimension.kind == laspy.DimensionKind.FloatingPoint:
las[dimension.name] = np.random.uniform(
low=dimension.min, high=dimension.max, size=len(las.points)
)
else:
type_str = (
dimension.type_str()
if dimension.kind != laspy.DimensionKind.BitField
else "u1"
)
las[dimension.name] = np.random.randint(
dimension.min, dimension.max + 1, len(las.points), type_str
)
print()
if args.out_path.suffix:
las.write(args.out_path)
else:
las.write(args.out_path / path.name)
if __name__ == "__main__":
parser = ArgumentParser("Randomize fields of your las file")
parser.add_argument("in_path", type=Path)
parser.add_argument("out_path", type=Path)
parser.add_argument("--keep-existing", action="store_true")
parser.add_argument("--exclude", nargs="*", default=["X", "Y", "Z"])
args = parser.parse_args()
main(args)
|