From 933cb47da18629ad3e5736f5286331ee9401cb94 Mon Sep 17 00:00:00 2001 From: Howard Butler Date: Fri, 17 Mar 2023 11:36:31 -0500 Subject: [PATCH] support pipelines --- src/trenchrun/__init__.py | 2 +- src/trenchrun/__version__.py | 0 src/trenchrun/argparser.py | 6 +--- src/trenchrun/data.py | 62 ++++++++++++++++++++++++------------ 4 files changed, 43 insertions(+), 27 deletions(-) delete mode 100644 src/trenchrun/__version__.py diff --git a/src/trenchrun/__init__.py b/src/trenchrun/__init__.py index 244ae31..66455b3 100644 --- a/src/trenchrun/__init__.py +++ b/src/trenchrun/__init__.py @@ -1 +1 @@ -__version__='0.0.4' +__version__='0.0.5' diff --git a/src/trenchrun/__version__.py b/src/trenchrun/__version__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/trenchrun/argparser.py b/src/trenchrun/argparser.py index fb570cc..310ea2f 100644 --- a/src/trenchrun/argparser.py +++ b/src/trenchrun/argparser.py @@ -7,13 +7,9 @@ def get_parser(args): parser = argparse.ArgumentParser(description='Compute the Ambient Absorption imagery product for lidar') parser.add_argument('input', - help='PDAL-readable lidar content', type=pathlib.Path) + help='PDAL-readable lidar content as a file or a pipeline', type=pathlib.Path) parser.add_argument('--output', help='Output filename', type=str, default='exposure') - parser.add_argument('--filters', - help='Filter stages', type =str, default=None) - parser.add_argument('--reader_args', - help='PDAL Reader args as JSON object', type =str, default=None) parser.add_argument('--resolution', help='Raster output resolution', type =float, default=1.0) parser.add_argument('--alpha', diff --git a/src/trenchrun/data.py b/src/trenchrun/data.py index 4feadff..1363fea 100644 --- a/src/trenchrun/data.py +++ b/src/trenchrun/data.py @@ -28,11 +28,38 @@ class Data(object): def __init__(self, args): self.args = args - self.checkValidData() + + if '.json' in self.args.input.suffixes: + self.inputType = 'pipeline' + else: + self.inputType = 'readable' + self.args.intensityPath = pathlib.Path(tempfile.NamedTemporaryFile(suffix='.tif', delete=False).name) self.args.dsmPath = pathlib.Path(tempfile.NamedTemporaryFile(suffix='.tif', delete=False).name) self.args.aoPath = pathlib.Path(tempfile.NamedTemporaryFile(suffix='.tif', delete=False).name) + self.checkValidData() + + def readPipeline(self): + if self.inputType != 'pipeline': + raise RuntimeError("Data type is not pipeline!") + j = self.args.input.read_bytes().decode('utf-8') + stages = pdal.pipeline._parse_stages(j) + p = pdal.Pipeline(stages) + # strip off any writers we're making our own + stages = [] + for stage in p.stages: + if stage.type.split('.')[0] != 'writers': + stages.append(stage) + + p = pdal.Pipeline(stages) + return p + + + def readFile(self): + reader = pdal.Reader(str(self.args.input)) + pipeline = reader.pipeline() + return pipeline def __del__(self): self.args.intensityPath.unlink() @@ -40,9 +67,13 @@ def __del__(self): self.args.aoPath.unlink() def checkValidData(self): - reader = pdal.Reader(str(self.args.input)) - pipeline = reader.pipeline() - qi = pipeline.quickinfo + + if self.inputType == 'pipeline': + reader = self.readPipeline() + else: + reader = self.readFile() + + qi = reader.quickinfo for key in qi: dimensions = [i.strip() for i in qi[key]['dimensions'].split(',')] if 'Intensity' not in dimensions: @@ -76,14 +107,13 @@ def getWriters(self): return intensity | dsm def getPipeline(self): - reader = self.getReader() - filters = self.getFilters() - writers = self.getWriters() - stage = None - if filters: - stage = reader | filters | writers + if self.inputType == 'pipeline': + reader = self.readPipeline() else: - stage = reader | writers + reader = self.readFile() + + writers = self.getWriters() + stage = reader | writers return stage @@ -97,16 +127,6 @@ def execute(self): count = pipeline.execute() logs.logger.info(f'Wrote intensity and dsm for {count} points') - def getFilters(self): - if self.args.filters: - with open(self.args.filters,'r') as f: - j = json.loads(f.read()) - stages = pdal.pipeline._parse_stages(json.dumps(j)) - return pdal.Pipeline(stages) - - else: - return None - def getImageCenter(self): # Run our pipeline