diff --git a/src/pdal/pipeline.py b/src/pdal/pipeline.py index 60a181c0..4310b232 100644 --- a/src/pdal/pipeline.py +++ b/src/pdal/pipeline.py @@ -33,6 +33,13 @@ LogLevelFromPDAL = {v: k for k, v in LogLevelToPDAL.items()} +HaveFileSpecSupport = False +if libpdalpython.getInfo().major == 2 and \ + libpdalpython.getInfo().minor >= 9 or \ + libpdalpython.getInfo().major > 2: + HaveFileSpecSupport = True + + class Pipeline(libpdalpython.Pipeline): def __init__( self, @@ -217,7 +224,25 @@ def __or__(self, other: Union[Stage, Pipeline]) -> Pipeline: class InferableTypeStage(Stage): def __init__(self, filename: Optional[str] = None, **options: Any): if filename: - options["filename"] = filename + if isinstance(filename, dict): + if "path" not in filename: + raise ValueError(f"'path' is missing in the provided filespec: {filename}") + if HaveFileSpecSupport: + options["filename"] = filename + else: + # log that we can't pass FileSpec to PDAL + # because the library version is too old + msg = "PDAL library version is too old for FileSpec support. " \ + "Defaulting to using filename only" + logging.info(msg) + options["filename"] = filename["path"] + + else: + if HaveFileSpecSupport: + filespec = {'path':str(filename)} + options["filename"] = filespec + else: + options["filename"] = filename super().__init__(**options) @property @@ -226,7 +251,18 @@ def type(self) -> str: return super().type except KeyError: filename = self._options.get("filename") - return str(self._infer_type(filename) if filename else "") + if isinstance(filename, dict): + if "path" not in filename: + raise ValueError(f"'path' is missing in the provided filespec: {filename}") + if HaveFileSpecSupport: + path = filename.get('path') + else: + path = filename + + else: + path = str(filename) + + return str(self._infer_type(path) if filename else "") _infer_type = staticmethod(lambda filename: "") diff --git a/test/test_pipeline.py b/test/test_pipeline.py index 46e0a18d..9bb3ba89 100644 --- a/test/test_pipeline.py +++ b/test/test_pipeline.py @@ -3,7 +3,6 @@ import os import sys -from typing import List from itertools import product import numpy as np import pytest @@ -284,6 +283,20 @@ def test_infer_stage_type(self): assert pdal.Writer("foo.xxx").type == "" assert pdal.Reader().type == "" assert pdal.Writer().type == "" + assert pdal.Reader({"path": "foo.las"}).type == "readers.las" + assert pdal.Writer({"path": "foo.las"}).type == "writers.las" + assert pdal.Reader({"path": "foo.xxx"}).type == "" + assert pdal.Writer({"path": "foo.xxx"}).type == "" + assert pdal.Reader({}).type == "" + assert pdal.Writer({}).type == "" + + def test_filespec(self): + """Can transit filespecs""" + spec = {'path':'junk.las', 'headers':{'header1':'header_1', 'header2':'header_2'}, 'query':{'query1':'query_1', 'query2':'query_2'}} + assert pdal.Reader(spec).type == "readers.las" + assert pdal.Reader(spec).options['filename']['path'] == "junk.las" + assert pdal.Reader(spec).options['filename']['headers']['header2'] == "header_2" + assert pdal.Writer("foo.las").type == "writers.las" def test_streamable(self): """Can we distinguish streamable from non-streamable stages and pipeline"""