Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move trick to pass params to a writer to las_info #42

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
41 changes: 5 additions & 36 deletions pdaltools/las_add_buffer.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down Expand Up @@ -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,
Expand Down
36 changes: 35 additions & 1 deletion pdaltools/las_info.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
41 changes: 41 additions & 0 deletions test/test_las_info.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import test.utils as tu

import pdal
import pytest

from pdaltools import las_info
Expand Down Expand Up @@ -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
Loading