ign-pdal-tools 1.7.7__tar.gz → 1.7.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/PKG-INFO +1 -1
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/ign_pdal_tools.egg-info/PKG-INFO +1 -1
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/_version.py +1 -1
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/add_points_in_pointcloud.py +9 -20
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/las_info.py +26 -1
- ign_pdal_tools-1.7.8/test/test_add_points_in_pointcloud.py +117 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_las_info.py +21 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_unlock.py +4 -0
- ign_pdal_tools-1.7.7/test/test_add_points_in_pointcloud.py +0 -172
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/LICENSE.md +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/README.md +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/ign_pdal_tools.egg-info/SOURCES.txt +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/ign_pdal_tools.egg-info/dependency_links.txt +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/ign_pdal_tools.egg-info/top_level.txt +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/add_points_in_las.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/color.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/las_add_buffer.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/las_clip.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/las_merge.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/las_remove_dimensions.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/pcd_info.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/replace_attribute_in_las.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/standardize_format.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pdaltools/unlock_file.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/pyproject.toml +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/setup.cfg +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_add_points_in_las.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_color.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_las_add_buffer.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_las_clip.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_las_merge.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_las_remove_dimensions.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_pcd_info.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_replace_attribute_in_las.py +0 -0
- {ign_pdal_tools-1.7.7 → ign_pdal_tools-1.7.8}/test/test_standardize_format.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
import shutil
|
|
2
3
|
|
|
3
4
|
import geopandas as gpd
|
|
4
5
|
import laspy
|
|
@@ -7,7 +8,7 @@ from pyproj import CRS
|
|
|
7
8
|
from pyproj.exceptions import CRSError
|
|
8
9
|
from shapely.geometry import box
|
|
9
10
|
|
|
10
|
-
from pdaltools.las_info import get_epsg_from_las,
|
|
11
|
+
from pdaltools.las_info import get_epsg_from_las, get_tile_bbox
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def parse_args(argv=None):
|
|
@@ -38,23 +39,6 @@ def parse_args(argv=None):
|
|
|
38
39
|
return parser.parse_args(argv)
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
def get_tile_bbox(input_las, tile_width=1000) -> tuple:
|
|
42
|
-
"""
|
|
43
|
-
Get the theoretical bounding box (xmin, ymin, xmax, ymax) of a LIDAR tile
|
|
44
|
-
using its origin and the predefined tile width.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
input_las (str): Path to the LIDAR `.las/.laz` file.
|
|
48
|
-
tile_width (int): Width of the tile in meters (default: 1000).
|
|
49
|
-
|
|
50
|
-
Returns:
|
|
51
|
-
tuple: Bounding box as (xmin, ymin, xmax, ymax).
|
|
52
|
-
"""
|
|
53
|
-
origin_x, origin_y = get_tile_origin_using_header_info(input_las)
|
|
54
|
-
bbox = (origin_x, origin_y - tile_width, origin_x + tile_width, origin_y)
|
|
55
|
-
return bbox
|
|
56
|
-
|
|
57
|
-
|
|
58
42
|
def clip_3d_points_to_tile(input_points: str, input_las: str, crs: str, tile_width: int) -> gpd.GeoDataFrame:
|
|
59
43
|
"""
|
|
60
44
|
Add points from a GeoJSON file in the LIDAR's tile.
|
|
@@ -98,9 +82,14 @@ def add_points_to_las(
|
|
|
98
82
|
crs (str): CRS of the data.
|
|
99
83
|
virtual_points_classes (int): The classification value to assign to those virtual points (default: 66).
|
|
100
84
|
"""
|
|
101
|
-
|
|
85
|
+
|
|
102
86
|
if input_points_with_z.empty:
|
|
103
|
-
|
|
87
|
+
print(
|
|
88
|
+
"No points to add. All points of the geojson file are outside the tile. Copying the input file to output"
|
|
89
|
+
)
|
|
90
|
+
shutil.copy(input_las, output_las)
|
|
91
|
+
|
|
92
|
+
return
|
|
104
93
|
|
|
105
94
|
# Extract XYZ coordinates and additional attribute (classification)
|
|
106
95
|
x_coords = input_points_with_z.geometry.x
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
from typing import Dict, Tuple
|
|
5
6
|
|
|
6
7
|
import laspy
|
|
@@ -51,6 +52,23 @@ def get_tile_origin_using_header_info(filename: str, tile_width: int = 1000) ->
|
|
|
51
52
|
return infer_tile_origin(minx, maxx, miny, maxy, tile_width)
|
|
52
53
|
|
|
53
54
|
|
|
55
|
+
def get_tile_bbox(input_las, tile_width=1000) -> tuple:
|
|
56
|
+
"""
|
|
57
|
+
Get the theoretical bounding box (xmin, ymin, xmax, ymax) of a LIDAR tile
|
|
58
|
+
using its origin and the predefined tile width.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
input_las (str): Path to the LIDAR `.las/.laz` file.
|
|
62
|
+
tile_width (int): Width of the tile in meters (default: 1000).
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
tuple: Bounding box as (xmin, ymin, xmax, ymax).
|
|
66
|
+
"""
|
|
67
|
+
origin_x, origin_y = get_tile_origin_using_header_info(input_las, tile_width)
|
|
68
|
+
bbox = (origin_x, origin_y - tile_width, origin_x + tile_width, origin_y)
|
|
69
|
+
return bbox
|
|
70
|
+
|
|
71
|
+
|
|
54
72
|
def get_epsg_from_header_info(metadata):
|
|
55
73
|
if "srs" not in metadata.keys():
|
|
56
74
|
raise RuntimeError("EPSG could not be inferred from metadata: No 'srs' key in metadata.")
|
|
@@ -143,7 +161,14 @@ def parse_filename(file: str):
|
|
|
143
161
|
For example Semis_2021_0000_1111_LA93_IGN69.las"""
|
|
144
162
|
basename = os.path.basename(file) # Make sure that we work on the base name and not the full path
|
|
145
163
|
|
|
146
|
-
|
|
164
|
+
try:
|
|
165
|
+
prefix1, prefix2, coordx, coordy, suffix = basename.split("_", 4)
|
|
166
|
+
except ValueError:
|
|
167
|
+
raise ValueError(
|
|
168
|
+
f"Filename {Path(file).name} does not have the expected format. "
|
|
169
|
+
"Expected prefix1_prefix2_coordx_coordy_suffix"
|
|
170
|
+
)
|
|
171
|
+
|
|
147
172
|
prefix = f"{prefix1}_{prefix2}"
|
|
148
173
|
|
|
149
174
|
return prefix, int(coordx), int(coordy), suffix
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import geopandas as gpd
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from pdaltools import add_points_in_pointcloud
|
|
9
|
+
from pdaltools.count_occurences.count_occurences_for_attribute import (
|
|
10
|
+
compute_count_one_file,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
TEST_PATH = os.path.dirname(os.path.abspath(__file__))
|
|
14
|
+
TMP_PATH = os.path.join(TEST_PATH, "tmp/add_points_in_pointcloud")
|
|
15
|
+
DATA_LIDAR_PATH = os.path.join(TEST_PATH, "data/decimated_laz")
|
|
16
|
+
DATA_POINTS_PATH = os.path.join(TEST_PATH, "data/points_3d")
|
|
17
|
+
|
|
18
|
+
INPUT_PCD = os.path.join(DATA_LIDAR_PATH, "test_semis_2023_0292_6833_LA93_IGN69.laz")
|
|
19
|
+
INPUT_POINTS = os.path.join(DATA_POINTS_PATH, "Points_virtuels_0292_6833.geojson")
|
|
20
|
+
OUTPUT_FILE = os.path.join(TMP_PATH, "test_semis_2023_0292_6833_LA93_IGN69.laz")
|
|
21
|
+
|
|
22
|
+
# Cropped las tile used to test adding points that belong to the theorical tile but not to the
|
|
23
|
+
# effective las file extent
|
|
24
|
+
INPUT_PCD_CROPPED = os.path.join(DATA_LIDAR_PATH, "test_semis_2021_0382_6565_LA93_IGN69_cropped.laz")
|
|
25
|
+
INPUT_POINTS_FOR_CROPPED_PCD = os.path.join(DATA_POINTS_PATH, "Points_virtuels_0382_6565.geojson")
|
|
26
|
+
OUTPUT_FILE_CROPPED_PCD = os.path.join(TMP_PATH, "test_semis_2021_0382_6565_LA93_IGN69.laz")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def setup_module(module):
|
|
30
|
+
os.makedirs(TMP_PATH, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.mark.parametrize(
|
|
34
|
+
"epsg",
|
|
35
|
+
[
|
|
36
|
+
"EPSG:2154", # should work when providing an epsg value
|
|
37
|
+
None, # Should also work with no epsg value (get from las file)
|
|
38
|
+
],
|
|
39
|
+
)
|
|
40
|
+
def test_clip_3d_points_to_tile(epsg):
|
|
41
|
+
# With EPSG
|
|
42
|
+
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(INPUT_POINTS, INPUT_PCD, epsg, 1000)
|
|
43
|
+
assert len(points_clipped) == 678 # check the entity's number of points
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.mark.parametrize(
|
|
47
|
+
"input_file, epsg, expected_nb_points",
|
|
48
|
+
[
|
|
49
|
+
(INPUT_PCD, "EPSG:2154", 2423), # should work when providing an epsg value
|
|
50
|
+
(INPUT_PCD, None, 2423), # Should also work with no epsg value (get from las file)
|
|
51
|
+
(INPUT_PCD_CROPPED, None, 2423),
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
def test_add_points_to_las(input_file, epsg, expected_nb_points):
|
|
55
|
+
# Ensure the output file doesn't exist before the test
|
|
56
|
+
if Path(OUTPUT_FILE).exists():
|
|
57
|
+
os.remove(OUTPUT_FILE)
|
|
58
|
+
|
|
59
|
+
points = gpd.read_file(INPUT_POINTS)
|
|
60
|
+
add_points_in_pointcloud.add_points_to_las(points, input_file, OUTPUT_FILE, epsg, 68)
|
|
61
|
+
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
62
|
+
|
|
63
|
+
point_count = compute_count_one_file(OUTPUT_FILE)["68"]
|
|
64
|
+
assert point_count == expected_nb_points # Add all points from geojson
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.mark.parametrize(
|
|
68
|
+
"input_file, input_points, epsg, expected_nb_points",
|
|
69
|
+
[
|
|
70
|
+
(INPUT_PCD, INPUT_POINTS, None, 678), # should add only points within tile extent
|
|
71
|
+
(INPUT_PCD_CROPPED, INPUT_POINTS_FOR_CROPPED_PCD, None, 186),
|
|
72
|
+
(
|
|
73
|
+
INPUT_PCD_CROPPED,
|
|
74
|
+
INPUT_POINTS,
|
|
75
|
+
None,
|
|
76
|
+
0,
|
|
77
|
+
), # Should add no points when there is only points outside the tile extent
|
|
78
|
+
(
|
|
79
|
+
INPUT_PCD_CROPPED,
|
|
80
|
+
INPUT_POINTS_FOR_CROPPED_PCD,
|
|
81
|
+
"EPSG:2154",
|
|
82
|
+
186,
|
|
83
|
+
), # Should work with or without an input epsg
|
|
84
|
+
],
|
|
85
|
+
)
|
|
86
|
+
def test_add_points_from_geojson_to_las(input_file, input_points, epsg, expected_nb_points):
|
|
87
|
+
# Ensure the output file doesn't exist before the test
|
|
88
|
+
if Path(OUTPUT_FILE).exists():
|
|
89
|
+
os.remove(OUTPUT_FILE)
|
|
90
|
+
|
|
91
|
+
add_points_in_pointcloud.add_points_from_geojson_to_las(input_points, input_file, OUTPUT_FILE, 68, epsg, 1000)
|
|
92
|
+
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
93
|
+
point_count = compute_count_one_file(OUTPUT_FILE)["68"]
|
|
94
|
+
assert point_count == expected_nb_points # Add all points from geojson
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_parse_args():
|
|
98
|
+
# sanity check for arguments parsing
|
|
99
|
+
args = add_points_in_pointcloud.parse_args(
|
|
100
|
+
[
|
|
101
|
+
"--input_geojson",
|
|
102
|
+
"data/points_3d/Points_virtuels_0292_6833.geojson",
|
|
103
|
+
"--input_las",
|
|
104
|
+
"data/decimated_laz/test_semis_2023_0292_6833_LA93_IGN69.laz",
|
|
105
|
+
"--output_las",
|
|
106
|
+
"data/output/test_semis_2023_0292_6833_LA93_IGN69.laz",
|
|
107
|
+
"--virtual_points_classes",
|
|
108
|
+
"68",
|
|
109
|
+
"--spatial_ref",
|
|
110
|
+
"EPSG:2154",
|
|
111
|
+
"--tile_width",
|
|
112
|
+
"1000",
|
|
113
|
+
]
|
|
114
|
+
)
|
|
115
|
+
parsed_args_keys = args.__dict__.keys()
|
|
116
|
+
main_parameters = inspect.signature(add_points_in_pointcloud.add_points_from_geojson_to_las).parameters.keys()
|
|
117
|
+
assert set(parsed_args_keys) == set(main_parameters)
|
|
@@ -45,6 +45,27 @@ def test_get_tile_origin_using_header_info():
|
|
|
45
45
|
assert (origin_x, origin_y) == (COORD_X * TILE_COORD_SCALE, COORD_Y * TILE_COORD_SCALE)
|
|
46
46
|
|
|
47
47
|
|
|
48
|
+
@pytest.mark.parametrize(
|
|
49
|
+
"tile_filename, tile_width, expected_bbox",
|
|
50
|
+
[
|
|
51
|
+
( # Standard 1000m tile width
|
|
52
|
+
os.path.join(DATA_PATH, "decimated_laz", "test_semis_2023_0292_6833_LA93_IGN69.laz"),
|
|
53
|
+
1000,
|
|
54
|
+
(292000.0, 6832000.0, 293000.0, 6833000.0),
|
|
55
|
+
),
|
|
56
|
+
(
|
|
57
|
+
# Test 50m tile
|
|
58
|
+
INPUT_FILE,
|
|
59
|
+
50,
|
|
60
|
+
(INPUT_MINS[0], INPUT_MINS[1], INPUT_MAXS[0], INPUT_MAXS[1]),
|
|
61
|
+
),
|
|
62
|
+
],
|
|
63
|
+
)
|
|
64
|
+
def test_get_tile_bbox(tile_filename, tile_width, expected_bbox):
|
|
65
|
+
bbox = las_info.get_tile_bbox(tile_filename, tile_width)
|
|
66
|
+
assert bbox == expected_bbox # check the bbox from LIDAR tile
|
|
67
|
+
|
|
68
|
+
|
|
48
69
|
def test_get_epsg_from_quickinfo_metadata_ok():
|
|
49
70
|
metadata = las_info.las_info_metadata(INPUT_FILE)
|
|
50
71
|
assert las_info.get_epsg_from_header_info(metadata) == "2154"
|
|
@@ -52,6 +52,10 @@ def test_copy_and_hack_decorator_color():
|
|
|
52
52
|
assert os.path.isfile(LAS_FILE)
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
@pytest.mark.xfail(
|
|
56
|
+
reason="Unlock is deprecated as versions of pdal >= 2.7.2 don't raise an error anymore when GlobalEncoding "
|
|
57
|
+
"is not set correctly for WKT see https://github.com/PDAL/PDAL/releases/tag/2.7.2"
|
|
58
|
+
)
|
|
55
59
|
def test_unlock_file():
|
|
56
60
|
TMP_FILE = os.path.join(TMPDIR, "unlock_file.laz")
|
|
57
61
|
shutil.copy(LAZ_FILE, TMP_FILE)
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import inspect
|
|
2
|
-
import os
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
import pdal
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
from pdaltools import add_points_in_pointcloud
|
|
9
|
-
|
|
10
|
-
TEST_PATH = os.path.dirname(os.path.abspath(__file__))
|
|
11
|
-
TMP_PATH = os.path.join(TEST_PATH, "data/output")
|
|
12
|
-
DATA_LIDAR_PATH = os.path.join(TEST_PATH, "data/decimated_laz")
|
|
13
|
-
DATA_POINTS_PATH = os.path.join(TEST_PATH, "data/points_3d")
|
|
14
|
-
|
|
15
|
-
INPUT_FILE = os.path.join(DATA_LIDAR_PATH, "test_semis_2023_0292_6833_LA93_IGN69.laz")
|
|
16
|
-
INPUT_POINTS = os.path.join(DATA_POINTS_PATH, "Points_virtuels_0292_6833.geojson")
|
|
17
|
-
OUTPUT_FILE = os.path.join(TMP_PATH, "test_semis_2023_0292_6833_LA93_IGN69.laz")
|
|
18
|
-
|
|
19
|
-
INPUT_FILE_SMALL = os.path.join(DATA_LIDAR_PATH, "test_semis_2021_0382_6565_LA93_IGN69.laz")
|
|
20
|
-
INPUT_POINTS_SMALL = os.path.join(DATA_POINTS_PATH, "Points_virtuels_0382_6565.geojson")
|
|
21
|
-
OUTPUT_FILE_SMALL = os.path.join(TMP_PATH, "test_semis_2021_0382_6565_LA93_IGN69.laz")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def setup_module(module):
|
|
25
|
-
os.makedirs("test/data/output", exist_ok=True)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def test_get_tile_bbox():
|
|
29
|
-
bbox = add_points_in_pointcloud.get_tile_bbox(INPUT_FILE, 1000)
|
|
30
|
-
assert bbox == (292000.0, 6832000.0, 293000.0, 6833000.0) # check the bbox from LIDAR tile
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_clip_3d_points_to_tile():
|
|
34
|
-
# With EPSG
|
|
35
|
-
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(INPUT_POINTS, INPUT_FILE, "EPSG:2154", 1000)
|
|
36
|
-
assert len(points_clipped) == 678 # chech the entity's number of points
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def test_clip_3d_points_to_tile_from_epsg_none():
|
|
40
|
-
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(INPUT_POINTS, INPUT_FILE, None, 1000)
|
|
41
|
-
assert len(points_clipped) == 678 # chech the entity's number of points
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def test_add_line_to_lidar():
|
|
45
|
-
# Ensure the output file doesn't exist before the test
|
|
46
|
-
if Path(OUTPUT_FILE).exists():
|
|
47
|
-
os.remove(OUTPUT_FILE)
|
|
48
|
-
|
|
49
|
-
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(INPUT_POINTS, INPUT_FILE, "EPSG:2154", 1000)
|
|
50
|
-
|
|
51
|
-
add_points_in_pointcloud.add_points_to_las(points_clipped, INPUT_FILE, OUTPUT_FILE, "EPSG:2154", 68)
|
|
52
|
-
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
53
|
-
|
|
54
|
-
# Filter pointcloud by classes
|
|
55
|
-
pipeline = (
|
|
56
|
-
pdal.Reader.las(filename=OUTPUT_FILE, nosrs=True)
|
|
57
|
-
| pdal.Filter.range(
|
|
58
|
-
limits="Classification[68:68]",
|
|
59
|
-
)
|
|
60
|
-
| pdal.Filter.stats()
|
|
61
|
-
)
|
|
62
|
-
pipeline.execute()
|
|
63
|
-
metadata = pipeline.metadata
|
|
64
|
-
# Count the pointcloud's number from classe "68"
|
|
65
|
-
point_count = metadata["metadata"]["filters.stats"]["statistic"][0]["count"]
|
|
66
|
-
assert point_count == 678
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def test_add_line_to_lidar_from_epsg_none():
|
|
70
|
-
# Ensure the output file doesn't exist before the test
|
|
71
|
-
if Path(OUTPUT_FILE).exists():
|
|
72
|
-
os.remove(OUTPUT_FILE)
|
|
73
|
-
|
|
74
|
-
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(INPUT_POINTS, INPUT_FILE, None, 1000)
|
|
75
|
-
|
|
76
|
-
add_points_in_pointcloud.add_points_to_las(points_clipped, INPUT_FILE, OUTPUT_FILE, None, 68)
|
|
77
|
-
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
78
|
-
|
|
79
|
-
# Filter pointcloud by classes
|
|
80
|
-
pipeline = (
|
|
81
|
-
pdal.Reader.las(filename=OUTPUT_FILE, nosrs=True)
|
|
82
|
-
| pdal.Filter.range(
|
|
83
|
-
limits="Classification[68:68]",
|
|
84
|
-
)
|
|
85
|
-
| pdal.Filter.stats()
|
|
86
|
-
)
|
|
87
|
-
pipeline.execute()
|
|
88
|
-
metadata = pipeline.metadata
|
|
89
|
-
# Count the pointcloud's number from classe "68"
|
|
90
|
-
point_count = metadata["metadata"]["filters.stats"]["statistic"][0]["count"]
|
|
91
|
-
assert point_count == 678
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def test_get_tile_bbox_small():
|
|
95
|
-
# Tile is not complete (NOT 1km * 1km)
|
|
96
|
-
bbox = add_points_in_pointcloud.get_tile_bbox(INPUT_FILE_SMALL, 1000)
|
|
97
|
-
assert bbox == (382000.0, 6564000.0, 383000.0, 6565000.0) # return BBOX 1km * 1km
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def test_add_line_to_lidar_small():
|
|
101
|
-
# Ensure the output file doesn't exist before the test
|
|
102
|
-
if Path(OUTPUT_FILE_SMALL).exists():
|
|
103
|
-
os.remove(OUTPUT_FILE_SMALL)
|
|
104
|
-
|
|
105
|
-
# Tile is not complete (NOT 1km * 1km)
|
|
106
|
-
points_clipped = add_points_in_pointcloud.clip_3d_points_to_tile(
|
|
107
|
-
INPUT_POINTS_SMALL, INPUT_FILE_SMALL, "EPSG:2154", 1000
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
add_points_in_pointcloud.add_points_to_las(points_clipped, INPUT_FILE_SMALL, OUTPUT_FILE_SMALL, "EPSG:2154", 68)
|
|
111
|
-
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
112
|
-
|
|
113
|
-
# Filter pointcloud by classes
|
|
114
|
-
pipeline = (
|
|
115
|
-
pdal.Reader.las(filename=OUTPUT_FILE_SMALL, nosrs=True)
|
|
116
|
-
| pdal.Filter.range(
|
|
117
|
-
limits="Classification[68:68]",
|
|
118
|
-
)
|
|
119
|
-
| pdal.Filter.stats()
|
|
120
|
-
)
|
|
121
|
-
pipeline.execute()
|
|
122
|
-
metadata = pipeline.metadata
|
|
123
|
-
# Count the pointcloud's number from classe "68"
|
|
124
|
-
point_count = metadata["metadata"]["filters.stats"]["statistic"][0]["count"]
|
|
125
|
-
assert point_count == 186
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def test_add_points_from_geojson_to_las():
|
|
129
|
-
# Ensure the output file doesn't exist before the test
|
|
130
|
-
if Path(OUTPUT_FILE).exists():
|
|
131
|
-
os.remove(OUTPUT_FILE)
|
|
132
|
-
|
|
133
|
-
add_points_in_pointcloud.add_points_from_geojson_to_las(
|
|
134
|
-
INPUT_POINTS, INPUT_FILE, OUTPUT_FILE, 68, "EPSG:2154", 1000
|
|
135
|
-
)
|
|
136
|
-
assert Path(OUTPUT_FILE).exists() # check output exists
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def test_add_points_from_geojson_to_las_no_epsg():
|
|
140
|
-
# Ensure the output file doesn't exist before the test
|
|
141
|
-
if Path(OUTPUT_FILE).exists():
|
|
142
|
-
os.remove(OUTPUT_FILE)
|
|
143
|
-
|
|
144
|
-
INPUT_FILE_WITHOUT_EPSG = os.path.join(TEST_PATH, "data/test_noepsg_043500_629205_IGN69.laz")
|
|
145
|
-
|
|
146
|
-
with pytest.raises(RuntimeError, match="does not have a valid EPSG code"):
|
|
147
|
-
add_points_in_pointcloud.add_points_from_geojson_to_las(
|
|
148
|
-
INPUT_POINTS, INPUT_FILE_WITHOUT_EPSG, OUTPUT_FILE, 68, None, 1000
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def test_parse_args():
|
|
153
|
-
# sanity check for arguments parsing
|
|
154
|
-
args = add_points_in_pointcloud.parse_args(
|
|
155
|
-
[
|
|
156
|
-
"--input_geojson",
|
|
157
|
-
"data/points_3d/Points_virtuels_0292_6833.geojson",
|
|
158
|
-
"--input_las",
|
|
159
|
-
"data/decimated_laz/test_semis_2023_0292_6833_LA93_IGN69.laz",
|
|
160
|
-
"--output_las",
|
|
161
|
-
"data/output/test_semis_2023_0292_6833_LA93_IGN69.laz",
|
|
162
|
-
"--virtual_points_classes",
|
|
163
|
-
"68",
|
|
164
|
-
"--spatial_ref",
|
|
165
|
-
"EPSG:2154",
|
|
166
|
-
"--tile_width",
|
|
167
|
-
"1000",
|
|
168
|
-
]
|
|
169
|
-
)
|
|
170
|
-
parsed_args_keys = args.__dict__.keys()
|
|
171
|
-
main_parameters = inspect.signature(add_points_in_pointcloud.add_points_from_geojson_to_las).parameters.keys()
|
|
172
|
-
assert set(parsed_args_keys) == set(main_parameters)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|