-
-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
r.in.pdal: Improve PDAL error handling (#4750)
* r.in.pdal: Improve PDAL error handling Some non-conformant LAS files trigger an error in PDAL library that results in an unhandled exit from r.in.pdal module. This code catches all PDAL errors and reports them in a GRASS way. One of error sources is lack of SRS information in the imported LAS file. This code propogates SRS check override from GRASS to PDAL library thus eliminating an error observed by non-conformant 1.4 LAS files. Fixes: #4157 * r.in.pdal: update copyright notice * r.in.pdal: enable reader.las "nosrs" option only in PDAL >= 2.4.3 * r.in.pdal: use PDAL defined macros to determine its version Reduces overhead of the configure stage * r.in.pdal: remove debugging pritnout left by accident * r.in.pdal: do not pass unused parameter to functions if "nosrs" is not available
- Loading branch information
Showing
4 changed files
with
206 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
""" | ||
Name: r.in.pdal info printing and error handling tests | ||
Purpose: Validates output of LAS file property printing and handling | ||
of broken LAS files | ||
Author: Maris Nartiss | ||
Copyright: (C) 2024 by Maris Nartiss and the GRASS Development Team | ||
Licence: This program is free software under the GNU General Public | ||
License (>=v2). Read the file COPYING that comes with GRASS | ||
for details. | ||
""" | ||
|
||
import os | ||
import pathlib | ||
import shutil | ||
import unittest | ||
from tempfile import TemporaryDirectory | ||
|
||
from grass.script import core as grass | ||
from grass.script import read_command | ||
from grass.gunittest.case import TestCase | ||
from grass.gunittest.main import test | ||
|
||
|
||
class InfoTest(TestCase): | ||
""" | ||
Test printing of extent and metadata | ||
This test requires pdal CLI util to be available. | ||
""" | ||
|
||
@classmethod | ||
@unittest.skipIf(shutil.which("pdal") is None, "Cannot find pdal utility") | ||
def setUpClass(cls): | ||
"""Ensures expected computational region and generated data""" | ||
cls.use_temp_region() | ||
cls.runModule("g.region", n=18, s=0, e=18, w=0, res=6) | ||
|
||
cls.data_dir = os.path.join(pathlib.Path(__file__).parent.absolute(), "data") | ||
cls.point_file = os.path.join(cls.data_dir, "points.csv") | ||
cls.tmp_dir = TemporaryDirectory() | ||
cls.las_file = os.path.join(cls.tmp_dir.name, "points.las") | ||
grass.call( | ||
[ | ||
"pdal", | ||
"translate", | ||
"-i", | ||
cls.point_file, | ||
"-o", | ||
cls.las_file, | ||
"-r", | ||
"text", | ||
"-w", | ||
"las", | ||
"--writers.las.format=0", | ||
"--writers.las.extra_dims=all", | ||
"--writers.las.minor_version=4", | ||
] | ||
) | ||
cls.broken_las = os.path.join(cls.tmp_dir.name, "broken.las") | ||
pathlib.Path(cls.broken_las).write_bytes(b"LASF") | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
"""Remove the temporary region and generated data""" | ||
cls.tmp_dir.cleanup() | ||
cls.del_temp_region() | ||
|
||
@unittest.skipIf(shutil.which("r.in.pdal") is None, "Cannot find r.in.pdal") | ||
def test_extent_bad(self): | ||
"""A broken LAS file should result in an error""" | ||
self.assertModuleFail("r.in.pdal", input=self.broken_las, flags="g", quiet=True) | ||
|
||
@unittest.skipIf(shutil.which("r.in.pdal") is None, "Cannot find r.in.pdal") | ||
def test_info_bad(self): | ||
"""A broken LAS file should result in an error""" | ||
self.assertModuleFail("r.in.pdal", input=self.broken_las, flags="p", quiet=True) | ||
|
||
@unittest.skipIf(shutil.which("r.in.pdal") is None, "Cannot find r.in.pdal") | ||
def test_extent_good(self): | ||
"""Reported extent should match provided data""" | ||
out = read_command("r.in.pdal", input=self.las_file, flags="g", quiet=True) | ||
for kvp in out.strip().split(" "): | ||
key, value = kvp.split("=") | ||
if key == "n": | ||
self.assertAlmostEqual(float(value), 17, places=6) | ||
continue | ||
if key == "s": | ||
self.assertAlmostEqual(float(value), 1, places=6) | ||
continue | ||
if key == "e": | ||
self.assertAlmostEqual(float(value), 17, places=6) | ||
continue | ||
if key == "w": | ||
self.assertAlmostEqual(float(value), 1, places=6) | ||
continue | ||
if key == "t": | ||
self.assertAlmostEqual(float(value), 28, places=6) | ||
continue | ||
if key == "b": | ||
self.assertAlmostEqual(float(value), 1, places=6) | ||
|
||
@unittest.skipIf(shutil.which("r.in.pdal") is None, "Cannot find r.in.pdal") | ||
def test_info_good(self): | ||
"""Validate successful file info printing""" | ||
out = read_command("r.in.pdal", input=self.las_file, flags="p", quiet=True) | ||
self.assertIn("File version = 1.4", out) | ||
self.assertIn("File signature: LASF", out) | ||
self.assertIn("Point count: 53", out) | ||
|
||
|
||
if __name__ == "__main__": | ||
test() |