diff --git a/lastools.py b/lastools.py new file mode 100644 index 0000000..d46b264 --- /dev/null +++ b/lastools.py @@ -0,0 +1,73 @@ +import os +import subprocess + + +def call_lastools(tool_name, las_in, las_out=None, args=None): + """Send commands to the lastools library. + + Requires lastools in system path. + + Args: + tool_name: name of lastools binary + las_in: bytes from stdout, or path to input point cloud + las_out: '-stdout' to pipe output, or path to output point cloud + args: list of additional arguments, formatted for lastools + + Returns: + bytes of output las, if las_out='-stdout' + None, if las_out='path/to/las/file' + + Examples: + + # Convert xyz file to las and pipe stdout to a python bytes object + las_data = call_lastools('txt2las', las_in='points.xyz', las_out='-stdout', + args=['-parse', 'sxyz']) + + # Clip las_data with a shapefile, and save to a new las file + call_lastools('lascrop', las_in=las_data, las_out='points.las', + args=['-poly', 'boundary.shp']) + """ + + # Start building command string + cmd = [tool_name] + + # Parse input + if type(las_in) == bytes: + # Pipe input las bytes to stdin + cmd += ['-stdin'] + stdin = las_in + else: + # Load las from file path + cmd += ['-i', las_in] + stdin = None + + # Parse output + if las_out == '-stdout': + # Pipe output las to stdout + cmd += ['-stdout'] + elif las_out: + # Save output las to file + cmd += ['-o', las_out] + + # Append additional lastools arguments, if provided + if args: + cmd += args + + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE) + stdout, stderr = process.communicate(input=stdin) + + # Handle errors, if detected + if process.returncode != 0: + print("Error: {} failed on {}".format(tool_name, + os.path.basename(las_in))) + print(stderr.decode()) + + # Output piped stdout if required + if las_out == '-stdout': + return stdout + else: + return None