diff --git a/CHANGELOG.md b/CHANGELOG.md index 3848416..a08c8e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# dev +- refactor tool to propagate header infos from one pipeline to another to use it by itself + # 1.5.1 - fix add_buffer: propagate header infos from input to the output - update pdal.Writer params to make sure input format is forwarded except for the specified parameters diff --git a/pdaltools/las_add_buffer.py b/pdaltools/las_add_buffer.py index 749673c..9328cdf 100644 --- a/pdaltools/las_add_buffer.py +++ b/pdaltools/las_add_buffer.py @@ -1,11 +1,14 @@ import argparse import logging import os -from typing import Dict, List +from typing import List import pdal -from pdaltools.las_info import get_buffered_bounds_from_filename +from pdaltools.las_info import ( + get_buffered_bounds_from_filename, + get_writer_parameters_from_reader_metadata, +) from pdaltools.las_merge import create_list @@ -46,40 +49,6 @@ def create_las_with_buffer( ) -def get_writer_parameters_from_reader_metadata(metadata: Dict, a_srs=None) -> Dict: - """As pdal las writers does not permit to pass easily metadata from one file as - parameters for a writer, use a trick to generate writer parameters from the - reader metadata of a previous pipeline: - This function uses the metadata from the reader of a pipeline to provide parameters - to pass to the writer of another pipeline - - To be removed once https://github.com/PDAL/python/issues/147 is solved - - Args: - metadata (Dict): metadata of an executed pipeline (that can be accessed using pipeline.metadata) - Returns: - Dict: parameters to pass to a pdal writer - """ - - reader_metadata = metadata["metadata"]["readers.las"] - - params = { - "major_version": reader_metadata["major_version"], - "minor_version": reader_metadata["minor_version"], - "global_encoding": reader_metadata["global_encoding"], - "extra_dims": "all", - "scale_x": reader_metadata["scale_x"], - "scale_y": reader_metadata["scale_y"], - "scale_z": reader_metadata["scale_z"], - "offset_x": reader_metadata["offset_x"], - "offset_y": reader_metadata["offset_y"], - "offset_z": reader_metadata["offset_z"], - "dataformat_id": reader_metadata["dataformat_id"], - "a_srs": a_srs if a_srs else reader_metadata["comp_spatialreference"], - } - return params - - def las_merge_and_crop( input_dir: str, tile_filename: str, diff --git a/pdaltools/las_info.py b/pdaltools/las_info.py index e832989..50a7f4c 100644 --- a/pdaltools/las_info.py +++ b/pdaltools/las_info.py @@ -1,7 +1,7 @@ import json import logging import os -from typing import Tuple +from typing import Dict, Tuple import osgeo.osr as osr import pdal @@ -151,3 +151,37 @@ def get_buffered_bounds_from_filename( ys = [minY - buffer_width, maxY + buffer_width] return (xs, ys) + + +def get_writer_parameters_from_reader_metadata(metadata: Dict, a_srs=None) -> Dict: + """As pdal las writers does not permit to pass easily metadata from one file as + parameters for a writer, use a trick to generate writer parameters from the + reader metadata of a previous pipeline: + This function uses the metadata from the reader of a pipeline to provide parameters + to pass to the writer of another pipeline + + To be removed once https://github.com/PDAL/python/issues/147 is solved + + Args: + metadata (Dict): metadata of an executed pipeline (that can be accessed using pipeline.metadata) + Returns: + Dict: parameters to pass to a pdal writer + """ + + reader_metadata = metadata["metadata"]["readers.las"] + + params = { + "major_version": reader_metadata["major_version"], + "minor_version": reader_metadata["minor_version"], + "global_encoding": reader_metadata["global_encoding"], + "extra_dims": "all", + "scale_x": reader_metadata["scale_x"], + "scale_y": reader_metadata["scale_y"], + "scale_z": reader_metadata["scale_z"], + "offset_x": reader_metadata["offset_x"], + "offset_y": reader_metadata["offset_y"], + "offset_z": reader_metadata["offset_z"], + "dataformat_id": reader_metadata["dataformat_id"], + "a_srs": a_srs if a_srs else reader_metadata["comp_spatialreference"], + } + return params diff --git a/test/test_las_info.py b/test/test_las_info.py index 84f121d..d93d8fe 100644 --- a/test/test_las_info.py +++ b/test/test_las_info.py @@ -1,6 +1,7 @@ import os import test.utils as tu +import pdal import pytest from pdaltools import las_info @@ -90,3 +91,43 @@ def test_get_buffered_bounds_from_filename_with_buffer(): ) assert xs == [770550 - buffer_width, 770600 + buffer_width] assert ys == [6277550 - buffer_width, 6277600 + buffer_width] + + +def test_get_writer_parameters_from_reader_metadata(): + output_file = os.path.join(TMP_PATH, "writer_with_parameters.las") + output_expected = os.path.join(TMP_PATH, "writer_with_forward.las") + + # First generate the expected output from a pipeline in a single part: + pipeline = pdal.Pipeline() + pipeline |= pdal.Reader.las(filename=INPUT_FILE) + pipeline |= pdal.Writer.las( + filename=output_expected, + forward="all", + ) + pipeline.execute() + + # Use pdal info summary to get metadata about the las file format and not only those of the data + out_expected_metadata = tu.get_pdal_infos_summary(output_expected)["summary"]["metadata"] + + # Generate output from a pipeline separated in 2 parts + pipeline1 = pdal.Pipeline() + pipeline1 |= pdal.Reader.las(filename=INPUT_FILE) + # At this point a useful pipeline wou + pipeline1.execute() + out_data = pipeline.arrays[0] + metadata = pipeline.metadata + + # Here in the expected usecase, you would do stuff to modify your data + params = las_info.get_writer_parameters_from_reader_metadata(metadata) + pipeline2 = pdal.Pipeline(arrays=[out_data]) + pipeline2 |= pdal.Writer(filename=output_file, forward="all", **params) + pipeline2.execute() + + out_metadata = tu.get_pdal_infos_summary(output_file)["summary"]["metadata"] + + # Pop metadata that we don't expect to be the same + for key in ["creation_year", "creation_doy", "software_id"]: + out_metadata.pop(key) + out_expected_metadata.pop(key) + + assert out_metadata == out_expected_metadata