class SelectionTest(TestCase): """Test input dimension selection and filtering This test requires pdal CLI util to be available. This tests expects r.in.ascii to work properly. """ @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", ] ) @classmethod def tearDownClass(cls): """Remove the temporary region and generated data""" cls.tmp_dir.cleanup() cls.del_temp_region() def tearDown(self): """Remove the outputs created by the import This is executed after each test run. """ self.runModule("g.remove", flags="f", type="raster", name=self.imp_raster) self.runModule("g.remove", flags="f", type="raster", name=self.ref_raster) try: self.runModule("g.remove", flags="f", type="raster", name=self.base_raster) except AttributeError: pass @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_dimension(self): """Test LAS dimension selection""" self.imp_raster = "imp_intensity" self.ref_raster = "ref_intensity" self.assertModule( "r.in.pdal", input=self.las_file, output=self.imp_raster, flags="o", quiet=True, method="mean", type="CELL", dimension="intensity", ) self.assertRasterExists(self.imp_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_mean_intensity.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.imp_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_user_dimension(self): """Test PDAL user dimension selection""" self.imp_raster = "imp_cellid" self.ref_raster = "ref_cellid" self.assertModule( "r.in.pdal", input=self.las_file, output=self.imp_raster, flags="o", quiet=True, method="mode", type="CELL", user_dimension="CellID", ) self.assertRasterExists(self.imp_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_mode_cellid.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.imp_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_filter(self): """Test input filtering""" self.imp_raster = "imp_filtered" self.ref_raster = "ref_filtered" self.assertModule( "r.in.pdal", input=self.las_file, output=self.imp_raster, flags="o", quiet=True, method="mode", type="CELL", dimension="source", zrange=(2, 10), irange=(10, 20), drange=(1, 1), ) self.assertRasterExists(self.imp_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_filter_z_int_source.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.imp_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_base_raster(self): """Test Z adjustement by base raster""" self.imp_raster = "imp_base_adj" self.ref_raster = "ref_base_adj" self.base_raster = "base_raster" self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_mean_z.ascii"), output=self.base_raster, ) self.assertModule( "r.in.pdal", input=self.las_file, output=self.imp_raster, flags="o", quiet=True, method="max", base_raster=self.base_raster, ) self.assertRasterExists(self.imp_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_base_adj.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.imp_raster, self.ref_raster, 0.001)
class FilterTest(TestCase): """Test case for filter and selection options This tests expects v.random and v.out.lidar to work properly. """ # Setup variables to be used for outputs vector_points = "vinlidar_filters_original" imported_points = "vinlidar_filters_imported" las_file = "vinlidar_filters_points.las" npoints = 300 @classmethod def setUpClass(cls): """Ensures expected computational region and generated data""" cls.use_temp_region() cls.runModule("g.region", n=20, s=10, e=25, w=15, res=1) cls.runModule( "v.in.ascii", input="-", stdin_=POINTS, flags="z", z=3, cat=0, separator="comma", output=cls.vector_points, columns="x double precision, y double precision," " z double precision, return_n integer," " n_returns integer, class_n integer", ) cls.runModule( "v.out.lidar", input=cls.vector_points, layer=1, output=cls.las_file, return_column="return_n", n_returns_column="n_returns", class_column="class_n", ) @classmethod def tearDownClass(cls): """Remove the temporary region and generated data""" cls.runModule("g.remove", flags="f", type="vector", name=cls.vector_points) if os.path.isfile(cls.las_file): os.remove(cls.las_file) cls.del_temp_region() def tearDown(self): """Remove the outputs created by the import This is executed after each test run. """ self.runModule("g.remove", flags="f", type="vector", name=self.imported_points) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_no_filter(self): """Test to see if the standard outputs are created This shows if the inpute data are as expected. """ self.assertModule("v.in.pdal", input=self.las_file, output=self.imported_points) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=19)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def return_filter(self, name, npoints): """Mid return filter test""" self.assertModule( "v.in.pdal", input=self.las_file, output=self.imported_points, return_filter=name, ) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=npoints)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_first_return_filter(self): """First return filter test""" self.return_filter("first", 9) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_mid_return_filter(self): """Mid return filter test""" self.return_filter("mid", 5) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_last_return_filter(self): """Last return filter test""" self.return_filter("last", 5) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def class_filter(self, class_n, npoints): """Actual code for testing class filter""" self.assertModule( "v.in.pdal", input=self.las_file, output=self.imported_points, class_filter=class_n, ) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=npoints)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_class_2_filter(self): """Test to filter classes""" self.class_filter(2, 2) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_class_3_filter(self): """Test to filter classes""" self.class_filter(3, 5) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_class_4_filter(self): """Test to filter classes""" self.class_filter(4, 4) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_class_5_filter(self): """Test to filter classes""" self.class_filter(5, 8) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def return_and_class_filter(self, return_name, class_n, npoints): """Return and class filter combined test code""" self.assertModule( "v.in.pdal", input=self.las_file, output=self.imported_points, return_filter=return_name, class_filter=class_n, ) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=npoints)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_first_return_and_class_filter(self): """Combined test for return and class""" self.return_and_class_filter("first", 2, 2) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_last_return_and_class_filter(self): """Combined test for return and class""" self.return_and_class_filter("last", 5, 3) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def zrange_filter(self, zrange, npoints): """Actual code for zrange option test""" self.assertModule("v.in.pdal", input=self.las_file, output=self.imported_points, zrange=zrange) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=npoints)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_zrange_filter(self): """Test zrange option""" self.zrange_filter((130.1, 139.9), 3) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_non_int_zrange_filter(self): """Test zrange option with float number One test point has z right under and one other right above the min. """ self.zrange_filter((140.5, 900), 8) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_zrange_and_class_filter(self): """zrange and class_filter option combined test""" self.assertModule( "v.in.pdal", input=self.las_file, output=self.imported_points, zrange=(141, 900), class_filter=5, ) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=4)) @unittest.skipIf( shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_zrange_and_return_filter(self): """zrange and class_filter option combined test""" self.assertModule( "v.in.pdal", input=self.las_file, output=self.imported_points, zrange=(141, 900), return_filter="last", ) self.assertVectorExists(self.imported_points) self.assertVectorFitsTopoInfo(vector=self.imported_points, reference=dict(points=2))
class BasicTest(TestCase): """Test case for watershed module This tests expects v.random and v.out.lidar to work properly. """ # Setup variables to be used for outputs vector_generated = "vinlidar_basic_generated" vector_points = "vinlidar_basic_original" imported_points = "vinlidar_basic_imported" las_file = "vinlidar_basic_points.las" npoints = 300 @classmethod def setUpClass(cls): """Ensures expected computational region and generated data""" cls.use_temp_region() cls.runModule("g.region", n=20, s=10, e=25, w=15, res=1) cls.runModule( "v.random", flags="zb", output=cls.vector_generated, npoints=cls.npoints, zmin=200, zmax=500, seed=100, ) cls.runModule( "v.category", input=cls.vector_generated, output=cls.vector_points, option="del", cat=-1, ) cls.runModule("v.out.lidar", input=cls.vector_points, output=cls.las_file) @classmethod def tearDownClass(cls): """Remove the temporary region and generated data""" cls.runModule( "g.remove", flags="f", type="vector", name=(cls.vector_points, cls.vector_generated), ) if os.path.isfile(cls.las_file): os.remove(cls.las_file) cls.del_temp_region() def tearDown(self): """Remove the outputs created by the import This is executed after each test run. """ self.runModule("g.remove", flags="f", type="vector", name=self.imported_points) @unittest.skipIf(shutil_which("v.in.pdal") is None, "Cannot find v.in.pdal") def test_same_data(self): """Test to see if the standard outputs are created""" self.assertModule( "v.in.pdal", input=self.las_file, flags="c", output=self.imported_points ) self.assertVectorExists(self.imported_points) self.assertVectorEqualsVector( actual=self.imported_points, reference=self.vector_points, digits=2, precision=0.01, )
class BinningTest(TestCase): """Test binning methods This test requires pdal CLI util to be available. This tests expects r.in.ascii to work properly. """ @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", ] ) @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 tearDown(self): """Remove the outputs created by the import This is executed after each test run. """ self.runModule("g.remove", flags="f", type="raster", name=self.bin_raster) self.runModule("g.remove", flags="f", type="raster", name=self.ref_raster) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_n(self): """Test binning with n method""" self.bin_raster = "bin_n" self.ref_raster = "ref_n" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="n", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_n_all.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_min(self): self.bin_raster = "bin_min" self.ref_raster = "ref_min" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="min", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_min_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_max(self): self.bin_raster = "bin_max" self.ref_raster = "ref_max" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="max", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_max_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_range(self): self.bin_raster = "bin_range" self.ref_raster = "ref_range" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="range", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_range_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_sum(self): self.bin_raster = "bin_sum" self.ref_raster = "ref_sum" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="sum", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_sum_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_mean(self): self.bin_raster = "bin_mean" self.ref_raster = "ref_mean" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="mean", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_mean_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0.0001) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_stddev(self): self.bin_raster = "bin_stddev" self.ref_raster = "ref_stddev" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="stddev", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_stddev_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0.0001) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_variance(self): self.bin_raster = "bin_variance" self.ref_raster = "ref_variance" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="variance", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_variance_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0.0001) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_coeff_var(self): self.bin_raster = "bin_coeff_var" self.ref_raster = "ref_coeff_var" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="coeff_var", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_coeff_var_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0.0001) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_median(self): self.bin_raster = "bin_median" self.ref_raster = "ref_median" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="median", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_median_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0.0001) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_mode(self): self.bin_raster = "bin_mode" self.ref_raster = "ref_mode" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="mode", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_mode_z.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_sidnmax(self): self.bin_raster = "bin_sidnmax" self.ref_raster = "ref_sidnmax" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="sidnmax", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_sidnmax_all.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0) @unittest.skipIf(shutil_which("r.in.pdal") is None, "Cannot find r.in.pdal") def test_method_sidnmin(self): self.bin_raster = "bin_sidnmin" self.ref_raster = "ref_sidnmin" self.assertModule( "r.in.pdal", input=self.las_file, output=self.bin_raster, flags="o", quiet=True, method="sidnmin", ) self.assertRasterExists(self.bin_raster) self.runModule( "r.in.ascii", input=os.path.join(self.data_dir, "res_sidnmin_all.ascii"), output=self.ref_raster, ) self.assertRastersEqual(self.bin_raster, self.ref_raster, 0)