Skip to content

Commit 3829ad5

Browse files
committed
Add streamable property to Stage and Pipeline
1 parent 4effb52 commit 3829ad5

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

pdal/drivers.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import json
22
import subprocess
33
from dataclasses import dataclass, field
4-
from typing import Callable, ClassVar, Mapping, Optional, Sequence, Type
4+
from typing import Callable, ClassVar, FrozenSet, Mapping, Optional, Sequence, Type
55

66
from .pipeline import Filter, Reader, Stage, Writer
77

8+
StreamableTypes: FrozenSet
9+
810

911
@dataclass
1012
class Option:
@@ -67,6 +69,7 @@ def inject_pdal_drivers() -> None:
6769
).stdout
6870
)
6971
)
72+
streamable = []
7073
for d in drivers:
7174
name = d["name"]
7275
d_options = [Option(**option_dict) for option_dict in (options.get(name) or ())]
@@ -78,3 +81,7 @@ def inject_pdal_drivers() -> None:
7881
pass
7982
driver = Driver(name, d["description"], d_options)
8083
setattr(driver.type, driver.short_name, staticmethod(driver.factory))
84+
if d["streamable"]:
85+
streamable.append(driver.name)
86+
global StreamableTypes
87+
StreamableTypes = frozenset(streamable)

pdal/pipeline.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
except ModuleNotFoundError: # pragma: no cover
1212
Mesh = None
1313

14-
from . import libpdalpython
14+
from . import drivers, libpdalpython
1515

1616
LogLevelToPDAL = {
1717
logging.ERROR: 0,
@@ -42,6 +42,10 @@ def __init__(
4242
def stages(self) -> List[Stage]:
4343
return list(self._stages)
4444

45+
@property
46+
def streamable(self) -> bool:
47+
return all(stage.streamable for stage in self._stages)
48+
4549
@property
4650
def schema(self) -> Any:
4751
return json.loads(super().schema)
@@ -124,6 +128,10 @@ def __init__(self, **options: Any):
124128
def type(self) -> str:
125129
return cast(str, self._options["type"])
126130

131+
@property
132+
def streamable(self) -> bool:
133+
return self.type in drivers.StreamableTypes
134+
127135
@property
128136
def tag(self) -> Optional[str]:
129137
return self._options.get("tag")

test/test_pipeline.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,41 @@ def test_infer_stage_type(self):
223223
assert pdal.Reader().type == ""
224224
assert pdal.Writer().type == ""
225225

226+
def test_streamable(self):
227+
"""Can we distinguish streamable from non-streamable stages and pipeline"""
228+
rs = pdal.Reader(type="readers.las", filename="foo")
229+
assert rs.streamable is True
230+
assert pdal.Reader.las("foo").streamable is True
231+
assert pdal.Reader("foo.las").streamable is True
232+
233+
rn = pdal.Reader(type="readers.pts", filename="foo")
234+
assert rn.streamable is False
235+
assert pdal.Reader.pts("foo").streamable is False
236+
assert pdal.Reader("foo.pts").streamable is False
237+
238+
fs = pdal.Filter(type="filters.crop")
239+
assert fs.streamable is True
240+
assert pdal.Filter.crop().streamable is True
241+
242+
fn = pdal.Filter(type="filters.cluster")
243+
assert fn.streamable is False
244+
assert pdal.Filter.cluster().streamable is False
245+
246+
ws = pdal.Writer(type="writers.ogr", filename="foo")
247+
assert ws.streamable is True
248+
assert pdal.Writer.ogr(filename="foo").streamable is True
249+
assert pdal.Writer("foo.shp").streamable is True
250+
251+
wn = pdal.Writer(type="writers.glb", filename="foo")
252+
assert wn.streamable is False
253+
assert pdal.Writer.gltf("foo").streamable is False
254+
assert pdal.Writer("foo.glb").streamable is False
255+
256+
assert (rs | fs | ws).streamable is True
257+
assert (rn | fs | ws).streamable is False
258+
assert (rs | fn | ws).streamable is False
259+
assert (rs | fs | wn).streamable is False
260+
226261
# fails against PDAL master; see https://github.com/PDAL/PDAL/issues/3566
227262
@pytest.mark.xfail
228263
@pytest.mark.parametrize("filename", ["reproject.json", "reproject.py"])

0 commit comments

Comments
 (0)