ign-pdal-tools 1.12.0__py3-none-any.whl → 1.12.2__py3-none-any.whl
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.12.0.dist-info → ign_pdal_tools-1.12.2.dist-info}/METADATA +1 -1
- {ign_pdal_tools-1.12.0.dist-info → ign_pdal_tools-1.12.2.dist-info}/RECORD +10 -10
- pdaltools/_version.py +1 -1
- pdaltools/create_random_laz.py +49 -49
- pdaltools/las_comparison.py +45 -33
- pdaltools/replace_attribute_in_las.py +2 -16
- pdaltools/standardize_format.py +2 -31
- {ign_pdal_tools-1.12.0.dist-info → ign_pdal_tools-1.12.2.dist-info}/WHEEL +0 -0
- {ign_pdal_tools-1.12.0.dist-info → ign_pdal_tools-1.12.2.dist-info}/licenses/LICENSE.md +0 -0
- {ign_pdal_tools-1.12.0.dist-info → ign_pdal_tools-1.12.2.dist-info}/top_level.txt +0 -0
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
ign_pdal_tools-1.12.
|
|
2
|
-
pdaltools/_version.py,sha256=
|
|
1
|
+
ign_pdal_tools-1.12.2.dist-info/licenses/LICENSE.md,sha256=iVzCFZTUXeiqP8bP474iuWZiWO_kDCD4SPh1Wiw125Y,1120
|
|
2
|
+
pdaltools/_version.py,sha256=hNkZafWzNyaa6UC2MRErLwCS5CjHrj7c2pqE_mjcoug,75
|
|
3
3
|
pdaltools/add_points_in_pointcloud.py,sha256=6NclQeAFYyVz3kfJ114BEFKfM5nwWWC2c8iN4IpaPOc,12662
|
|
4
4
|
pdaltools/color.py,sha256=vJgpb8dOvT5rnq5NdVOaMdGc_pKL3damLy4HwGvigJQ,14472
|
|
5
|
-
pdaltools/create_random_laz.py,sha256=
|
|
5
|
+
pdaltools/create_random_laz.py,sha256=kFe5iHeHlkgKWRIKjK5l1AD65OG4qLYwAZdO1Wcvuos,5255
|
|
6
6
|
pdaltools/las_add_buffer.py,sha256=rnFExAfi0KqlQpL4hDMh2aC08AcYdSHSB6WPG5RyFIc,11274
|
|
7
7
|
pdaltools/las_clip.py,sha256=GvEOYu8RXV68e35kU8i42GwSkbo4P9TvmS6rkrdPmFM,1034
|
|
8
|
-
pdaltools/las_comparison.py,sha256=
|
|
8
|
+
pdaltools/las_comparison.py,sha256=B9hFGbmD0x4JEN4oHbiQFNbd0T-9P3mnAN67Czu0pZk,4505
|
|
9
9
|
pdaltools/las_info.py,sha256=lMKxKzsViptDENI1wOlANG4qOvdc19ixyasYKD-N1ck,9512
|
|
10
10
|
pdaltools/las_merge.py,sha256=tcFVueV9X9nNEaoAl5zCduY5DETlBg63MAgP2SuKiNo,4121
|
|
11
11
|
pdaltools/las_remove_dimensions.py,sha256=f8imGhN6LNTuQ1GMJQRzIIV3Wab_oRPOyEnKi1CgfiM,2318
|
|
12
12
|
pdaltools/las_rename_dimension.py,sha256=zXEKHyx1uQ3U0oZYo_BTnqbTHGSq5TIZHqZn_EPqNKQ,2576
|
|
13
13
|
pdaltools/pcd_info.py,sha256=NIAH5KGikVDQLlbCcw9FuaPqe20UZvRfkHsDZd5kmZA,3210
|
|
14
|
-
pdaltools/replace_attribute_in_las.py,sha256=
|
|
15
|
-
pdaltools/standardize_format.py,sha256=
|
|
14
|
+
pdaltools/replace_attribute_in_las.py,sha256=MHpIizSupgWtbizteoRH8FKDE049hrAh4v_OhmRmSPU,4318
|
|
15
|
+
pdaltools/standardize_format.py,sha256=I2oNiwhSMtr4e5ZK9qbB_yKmy3twOoO6QLiSFu4_AaI,3905
|
|
16
16
|
pdaltools/unlock_file.py,sha256=G2odk0cpp_X9r49Y90oK88v3qlihaMfg6acwmWqblik,1958
|
|
17
|
-
ign_pdal_tools-1.12.
|
|
18
|
-
ign_pdal_tools-1.12.
|
|
19
|
-
ign_pdal_tools-1.12.
|
|
20
|
-
ign_pdal_tools-1.12.
|
|
17
|
+
ign_pdal_tools-1.12.2.dist-info/METADATA,sha256=cOFyIrusuyvAsB_nrIRUaV0Y9h-Nle8ou8FU3POAoAA,5778
|
|
18
|
+
ign_pdal_tools-1.12.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
ign_pdal_tools-1.12.2.dist-info/top_level.txt,sha256=KvGW0ZzqQbhCKzB5_Tp_buWMZyIgiO2M2krWF_ecOZc,10
|
|
20
|
+
ign_pdal_tools-1.12.2.dist-info/RECORD,,
|
pdaltools/_version.py
CHANGED
pdaltools/create_random_laz.py
CHANGED
|
@@ -1,78 +1,82 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import laspy
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
import sys
|
|
5
4
|
import argparse
|
|
6
|
-
import pdal
|
|
7
5
|
from pyproj import CRS
|
|
8
|
-
from typing import List, Tuple
|
|
6
|
+
from typing import List, Tuple
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
|
|
9
|
+
def create_random_laz(
|
|
10
|
+
output_file: str,
|
|
11
|
+
point_format: int = 3,
|
|
12
|
+
num_points: int = 100,
|
|
13
|
+
crs: int = 2154,
|
|
14
|
+
center: Tuple[float, float] = (650000, 6810000),
|
|
15
|
+
extra_dims: List[Tuple[str, str]] = [],
|
|
16
|
+
):
|
|
14
17
|
"""
|
|
15
18
|
Create a test LAZ file with EPSG code and additional dimensions.
|
|
16
|
-
|
|
19
|
+
|
|
17
20
|
Args:
|
|
18
21
|
output_file: Path to save the LAZ file
|
|
19
22
|
point_format: Point format of the LAZ file (default: 3)
|
|
20
23
|
num_points: Number of points to generate
|
|
21
24
|
crs: EPSG code of the CRS (default: 2154)
|
|
22
|
-
center: Tuple of floats (x, y) of the center of the area to generate points in
|
|
25
|
+
center: Tuple of floats (x, y) of the center of the area to generate points in
|
|
26
|
+
(default: (650000, 6810000) ; around Paris)
|
|
23
27
|
extra_dims: List of tuples (dimension_name, dimension_type) where type can be:
|
|
24
28
|
'float32', 'float64', 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64'
|
|
25
29
|
"""
|
|
26
|
-
|
|
30
|
+
|
|
27
31
|
# Create a new point cloud
|
|
28
32
|
header = laspy.LasHeader(point_format=point_format, version="1.4")
|
|
29
|
-
|
|
33
|
+
|
|
30
34
|
# Map string types to numpy types
|
|
31
35
|
type_mapping = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
"float32": np.float32,
|
|
37
|
+
"float64": np.float64,
|
|
38
|
+
"int8": np.int8,
|
|
39
|
+
"int16": np.int16,
|
|
40
|
+
"int32": np.int32,
|
|
41
|
+
"int64": np.int64,
|
|
42
|
+
"uint8": np.uint8,
|
|
43
|
+
"uint16": np.uint16,
|
|
44
|
+
"uint32": np.uint32,
|
|
45
|
+
"uint64": np.uint64,
|
|
42
46
|
}
|
|
43
|
-
|
|
47
|
+
|
|
44
48
|
for dim_name, dim_type in extra_dims:
|
|
45
49
|
if dim_type not in type_mapping:
|
|
46
50
|
raise ValueError(f"Unsupported dimension type: {dim_type}. Supported types: {list(type_mapping.keys())}")
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
numpy_type = type_mapping[dim_type]
|
|
49
53
|
header.add_extra_dim(laspy.ExtraBytesParams(name=dim_name, type=numpy_type))
|
|
50
|
-
|
|
54
|
+
|
|
51
55
|
# Create point cloud
|
|
52
56
|
las = laspy.LasData(header)
|
|
53
57
|
las.header.add_crs(CRS.from_string(f"epsg:{crs}"))
|
|
54
|
-
|
|
58
|
+
|
|
55
59
|
# Generate random points in a small area
|
|
56
60
|
las.x = np.random.uniform(center[0] - 1000, center[0] + 1000, num_points)
|
|
57
61
|
las.y = np.random.uniform(center[1] - 1000, center[1] + 1000, num_points)
|
|
58
62
|
las.z = np.random.uniform(0, 200, num_points)
|
|
59
|
-
|
|
63
|
+
|
|
60
64
|
# Generate random intensity values
|
|
61
65
|
las.intensity = np.random.randint(0, 255, num_points)
|
|
62
|
-
|
|
66
|
+
|
|
63
67
|
# Generate random classification values
|
|
64
|
-
# 66 is the max value for classification of IGN LidarHD
|
|
68
|
+
# 66 is the max value for classification of IGN LidarHD
|
|
65
69
|
# cf. https://geoservices.ign.fr/sites/default/files/2022-05/DT_LiDAR_HD_1-0.pdf
|
|
66
|
-
if point_format > 3:
|
|
70
|
+
if point_format > 3:
|
|
67
71
|
num_classifications = 66
|
|
68
72
|
else:
|
|
69
73
|
num_classifications = 10
|
|
70
74
|
las.classification = np.random.randint(0, num_classifications, num_points)
|
|
71
|
-
|
|
75
|
+
|
|
72
76
|
# Generate random values for each extra dimension
|
|
73
77
|
for dim_name, dim_type in extra_dims:
|
|
74
78
|
numpy_type = type_mapping[dim_type]
|
|
75
|
-
|
|
79
|
+
|
|
76
80
|
# Generate appropriate random values based on the type
|
|
77
81
|
if numpy_type in [np.float32, np.float64]:
|
|
78
82
|
las[dim_name] = np.random.uniform(0, 10, num_points).astype(numpy_type)
|
|
@@ -80,7 +84,7 @@ def create_random_laz(output_file: str, point_format: int = 3, num_points: int =
|
|
|
80
84
|
las[dim_name] = np.random.randint(-100, 100, num_points).astype(numpy_type)
|
|
81
85
|
elif numpy_type in [np.uint8, np.uint16, np.uint32, np.uint64]:
|
|
82
86
|
las[dim_name] = np.random.randint(0, 100, num_points).astype(numpy_type)
|
|
83
|
-
|
|
87
|
+
|
|
84
88
|
# Write to file
|
|
85
89
|
las.write(output_file)
|
|
86
90
|
dimensions = list(las.point_format.dimension_names)
|
|
@@ -91,7 +95,7 @@ def create_random_laz(output_file: str, point_format: int = 3, num_points: int =
|
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
|
|
94
|
-
def test_output_file(result
|
|
98
|
+
def test_output_file(result: dict, output_file: str):
|
|
95
99
|
|
|
96
100
|
# Validate output file path
|
|
97
101
|
output_path = Path(output_file)
|
|
@@ -103,15 +107,6 @@ def test_output_file(result : dict, output_file: str):
|
|
|
103
107
|
print(f"Number of points: {result['num_points']}")
|
|
104
108
|
print(f"Dimensions available: {result['dimensions']}")
|
|
105
109
|
|
|
106
|
-
# Print available dimensions using PDAL
|
|
107
|
-
pipeline = pdal.Pipeline() | pdal.Reader.las(result['output_file'])
|
|
108
|
-
pipeline.execute()
|
|
109
|
-
points = pipeline.arrays[0]
|
|
110
|
-
dimensions = list(points.dtype.fields.keys())
|
|
111
|
-
print("\nAvailable dimensions in input file:")
|
|
112
|
-
for dim in dimensions:
|
|
113
|
-
print(f"- {dim}")
|
|
114
|
-
|
|
115
110
|
|
|
116
111
|
def parse_args():
|
|
117
112
|
# Parse arguments (assuming argparse is used)
|
|
@@ -119,28 +114,33 @@ def parse_args():
|
|
|
119
114
|
parser.add_argument("--output_file", type=str, help="Path to save the LAZ file")
|
|
120
115
|
parser.add_argument("--point_format", type=int, default=3, help="Point format of the LAZ file")
|
|
121
116
|
parser.add_argument("--num_points", type=int, default=100, help="Number of points to generate")
|
|
122
|
-
parser.add_argument(
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"--extra_dims", type=str, nargs="*", default=[], help="Extra dimensions in the format name:type"
|
|
119
|
+
)
|
|
123
120
|
parser.add_argument("--crs", type=int, default=2154, help="Projection code")
|
|
124
|
-
parser.add_argument(
|
|
121
|
+
parser.add_argument(
|
|
122
|
+
"--center", type=str, default="650000,6810000", help="Center of the area to generate points in"
|
|
123
|
+
)
|
|
125
124
|
return parser.parse_args()
|
|
126
125
|
|
|
127
126
|
|
|
128
127
|
def main():
|
|
129
|
-
|
|
128
|
+
|
|
130
129
|
# Parse arguments
|
|
131
130
|
args = parse_args()
|
|
132
|
-
|
|
131
|
+
|
|
133
132
|
# Parse extra dimensions
|
|
134
133
|
extra_dims = [tuple(dim.split(":")) for dim in args.extra_dims]
|
|
135
|
-
|
|
134
|
+
|
|
136
135
|
# Parse center
|
|
137
136
|
center = tuple(map(float, args.center.split(",")))
|
|
138
137
|
|
|
139
138
|
# Call create_random_laz
|
|
140
139
|
result = create_random_laz(args.output_file, args.point_format, args.num_points, args.crs, center, extra_dims)
|
|
141
|
-
|
|
140
|
+
|
|
142
141
|
# Test output file
|
|
143
|
-
test_output_file(result, args.output_file)
|
|
142
|
+
test_output_file(result, args.output_file)
|
|
143
|
+
|
|
144
144
|
|
|
145
145
|
if __name__ == "__main__":
|
|
146
146
|
main()
|
pdaltools/las_comparison.py
CHANGED
|
@@ -2,50 +2,58 @@ import laspy
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
import numpy as np
|
|
4
4
|
import argparse
|
|
5
|
+
from typing import Tuple
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
def compare_las_dimensions(file1: Path, file2: Path, dimensions: list = None) -> Tuple[bool, int, float]:
|
|
7
9
|
"""
|
|
8
10
|
Compare specified dimensions between two LAS files.
|
|
9
11
|
If no dimensions are specified, compares all available dimensions.
|
|
10
12
|
Sorts points by x,y,z,gps_time coordinates before comparison to ensure point order consistency.
|
|
11
|
-
|
|
13
|
+
|
|
12
14
|
Args:
|
|
13
15
|
file1: Path to the first LAS file
|
|
14
16
|
file2: Path to the second LAS file
|
|
15
17
|
dimensions: List of dimension names to compare (optional)
|
|
16
|
-
|
|
18
|
+
|
|
17
19
|
Returns:
|
|
18
20
|
bool: True if all specified dimensions are identical, False otherwise
|
|
21
|
+
int: Number of points with different dimensions
|
|
22
|
+
float: Percentage of points with different dimensions
|
|
19
23
|
"""
|
|
20
24
|
try:
|
|
21
25
|
# Read both LAS files
|
|
22
26
|
las1 = laspy.read(file1)
|
|
23
27
|
las2 = laspy.read(file2)
|
|
24
|
-
|
|
28
|
+
|
|
25
29
|
# Check if files have the same number of points
|
|
26
30
|
if len(las1) != len(las2):
|
|
27
31
|
print(f"Files have different number of points: {len(las1)} vs {len(las2)}")
|
|
28
|
-
return False
|
|
29
|
-
|
|
32
|
+
return False, 0, 0
|
|
33
|
+
print(f"Files have the same number of points: {len(las1)} vs {len(las2)}")
|
|
34
|
+
|
|
30
35
|
# Sort points by x,y,z,gps_time coordinates
|
|
31
36
|
# Create sorting indices
|
|
32
37
|
sort_idx1 = np.lexsort((las1.z, las1.y, las1.x, las1.gps_time))
|
|
33
38
|
sort_idx2 = np.lexsort((las2.z, las2.y, las2.x, las2.gps_time))
|
|
34
|
-
|
|
39
|
+
|
|
35
40
|
# If no dimensions specified, compare all dimensions
|
|
36
41
|
dimensions_las1 = sorted(las1.point_format.dimension_names)
|
|
37
42
|
dimensions_las2 = sorted(las2.point_format.dimension_names)
|
|
38
|
-
|
|
43
|
+
|
|
39
44
|
if dimensions is None:
|
|
40
45
|
if dimensions_las1 != dimensions_las2:
|
|
41
46
|
print("Files have different dimensions")
|
|
42
|
-
return False
|
|
43
|
-
dimensions = dimensions_las1
|
|
47
|
+
return False, 0, 0
|
|
48
|
+
dimensions = dimensions_las1
|
|
44
49
|
else:
|
|
45
50
|
for dim in dimensions:
|
|
46
51
|
if dim not in dimensions_las1 or dim not in dimensions_las2:
|
|
47
|
-
print(
|
|
48
|
-
|
|
52
|
+
print(
|
|
53
|
+
f"Dimension '{dim}' is not found in one or both files.\n"
|
|
54
|
+
f"Available dimensions: {las1.point_format.dimension_names}"
|
|
55
|
+
)
|
|
56
|
+
return False, 0, 0
|
|
49
57
|
|
|
50
58
|
# Compare each dimension
|
|
51
59
|
for dim in dimensions:
|
|
@@ -53,7 +61,7 @@ def compare_las_dimensions(file1: Path, file2: Path, dimensions: list = None) ->
|
|
|
53
61
|
# Get sorted dimension arrays
|
|
54
62
|
dim1 = np.array(las1[dim])[sort_idx1]
|
|
55
63
|
dim2 = np.array(las2[dim])[sort_idx2]
|
|
56
|
-
|
|
64
|
+
|
|
57
65
|
# Compare dimensions
|
|
58
66
|
if not np.array_equal(dim1, dim2):
|
|
59
67
|
# Find differences
|
|
@@ -63,43 +71,47 @@ def compare_las_dimensions(file1: Path, file2: Path, dimensions: list = None) ->
|
|
|
63
71
|
print(f"Point {idx}: file1={dim1[idx]}, file2={dim2[idx]}")
|
|
64
72
|
if len(diff_indices) > 10:
|
|
65
73
|
print(f"... and {len(diff_indices) - 10} more differences")
|
|
66
|
-
return False
|
|
67
|
-
|
|
74
|
+
return False, len(diff_indices), 100 * len(diff_indices) / len(las1)
|
|
75
|
+
|
|
68
76
|
except KeyError:
|
|
69
77
|
print(f"Dimension '{dim}' not found in one or both files")
|
|
70
|
-
return False
|
|
71
|
-
|
|
72
|
-
return True
|
|
73
|
-
|
|
78
|
+
return False, 0, 0
|
|
79
|
+
|
|
80
|
+
return True, 0, 0
|
|
81
|
+
|
|
74
82
|
except laspy.errors.LaspyException as e:
|
|
75
83
|
print(f"LAS file error: {str(e)}")
|
|
76
|
-
return False
|
|
84
|
+
return False, 0, 0
|
|
77
85
|
except FileNotFoundError as e:
|
|
78
86
|
print(f"File not found: {str(e)}")
|
|
79
|
-
return False
|
|
87
|
+
return False, 0, 0
|
|
80
88
|
except ValueError as e:
|
|
81
89
|
print(f"Value error: {str(e)}")
|
|
82
|
-
return False
|
|
90
|
+
return False, 0, 0
|
|
91
|
+
|
|
83
92
|
|
|
84
93
|
# Update main function to use the new compare function
|
|
85
|
-
def main():
|
|
86
|
-
parser = argparse.ArgumentParser(description=
|
|
87
|
-
parser.add_argument(
|
|
88
|
-
parser.add_argument(
|
|
89
|
-
parser.add_argument(
|
|
90
|
-
|
|
94
|
+
def main():
|
|
95
|
+
parser = argparse.ArgumentParser(description="Compare dimensions between two LAS files")
|
|
96
|
+
parser.add_argument("file1", type=str, help="Path to first LAS file")
|
|
97
|
+
parser.add_argument("file2", type=str, help="Path to second LAS file")
|
|
98
|
+
parser.add_argument(
|
|
99
|
+
"--dimensions", nargs="*", help="List of dimensions to compare. If not specified, compares all dimensions."
|
|
100
|
+
)
|
|
101
|
+
|
|
91
102
|
args = parser.parse_args()
|
|
92
|
-
|
|
103
|
+
|
|
93
104
|
file1 = Path(args.file1)
|
|
94
105
|
file2 = Path(args.file2)
|
|
95
|
-
|
|
106
|
+
|
|
96
107
|
if not file1.exists() or not file2.exists():
|
|
97
108
|
print("Error: One or both files do not exist")
|
|
98
109
|
exit(1)
|
|
99
|
-
|
|
110
|
+
|
|
100
111
|
result = compare_las_dimensions(file1, file2, args.dimensions)
|
|
101
|
-
print(f"Dimensions comparison result: {'identical' if result else 'different'}")
|
|
112
|
+
print(f"Dimensions comparison result: {'identical' if result[0] else 'different'}")
|
|
102
113
|
return result
|
|
103
114
|
|
|
115
|
+
|
|
104
116
|
if __name__ == "__main__":
|
|
105
|
-
main()
|
|
117
|
+
main()
|
|
@@ -4,13 +4,12 @@ import argparse
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
|
-
import tempfile
|
|
8
7
|
from collections import Counter
|
|
9
8
|
from typing import Dict, List
|
|
10
9
|
|
|
11
10
|
import pdal
|
|
12
11
|
|
|
13
|
-
from pdaltools.standardize_format import
|
|
12
|
+
from pdaltools.standardize_format import get_writer_parameters
|
|
14
13
|
from pdaltools.unlock_file import copy_and_hack_decorator
|
|
15
14
|
|
|
16
15
|
|
|
@@ -106,26 +105,13 @@ def parse_replacement_map_from_path_or_json_string(replacement_map):
|
|
|
106
105
|
return parsed_map
|
|
107
106
|
|
|
108
107
|
|
|
109
|
-
def replace_values_clean(
|
|
110
|
-
input_file: str,
|
|
111
|
-
output_file: str,
|
|
112
|
-
replacement_map: Dict,
|
|
113
|
-
attribute: str = "Classification",
|
|
114
|
-
writer_parameters: Dict = {},
|
|
115
|
-
):
|
|
116
|
-
filename = os.path.basename(output_file)
|
|
117
|
-
with tempfile.NamedTemporaryFile(suffix=filename) as tmp:
|
|
118
|
-
replace_values(input_file, tmp.name, replacement_map, attribute, writer_parameters)
|
|
119
|
-
exec_las2las(tmp.name, output_file)
|
|
120
|
-
|
|
121
|
-
|
|
122
108
|
def main():
|
|
123
109
|
args = parse_args()
|
|
124
110
|
writer_params_from_parser = dict(dataformat_id=args.record_format, a_srs=args.projection)
|
|
125
111
|
writer_parameters = get_writer_parameters(writer_params_from_parser)
|
|
126
112
|
replacement_map = parse_replacement_map_from_path_or_json_string(args.replacement_map)
|
|
127
113
|
|
|
128
|
-
|
|
114
|
+
replace_values(args.input_file, args.output_file, replacement_map, args.attribute, writer_parameters)
|
|
129
115
|
|
|
130
116
|
|
|
131
117
|
if __name__ == "__main__":
|
pdaltools/standardize_format.py
CHANGED
|
@@ -9,9 +9,6 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import argparse
|
|
12
|
-
import os
|
|
13
|
-
import platform
|
|
14
|
-
import subprocess as sp
|
|
15
12
|
import tempfile
|
|
16
13
|
from typing import Dict, List
|
|
17
14
|
|
|
@@ -79,8 +76,8 @@ def get_writer_parameters(new_parameters: Dict) -> Dict:
|
|
|
79
76
|
params = STANDARD_PARAMETERS | new_parameters
|
|
80
77
|
return params
|
|
81
78
|
|
|
82
|
-
|
|
83
|
-
def
|
|
79
|
+
@copy_and_hack_decorator
|
|
80
|
+
def standardize(
|
|
84
81
|
input_file: str, output_file: str, params_from_parser: Dict, classes_to_remove: List = [], rename_dims: List = []
|
|
85
82
|
) -> None:
|
|
86
83
|
params = get_writer_parameters(params_from_parser)
|
|
@@ -109,32 +106,6 @@ def rewrite_with_pdal(
|
|
|
109
106
|
pipeline.execute()
|
|
110
107
|
|
|
111
108
|
|
|
112
|
-
def exec_las2las(input_file: str, output_file: str):
|
|
113
|
-
if platform.processor() == "arm" and platform.architecture()[0] == "64bit":
|
|
114
|
-
las2las = "las2las64"
|
|
115
|
-
else:
|
|
116
|
-
las2las = "las2las"
|
|
117
|
-
r = sp.run([las2las, "-i", input_file, "-o", output_file], stderr=sp.PIPE, stdout=sp.PIPE)
|
|
118
|
-
if r.returncode == 1:
|
|
119
|
-
msg = r.stderr.decode()
|
|
120
|
-
print(msg)
|
|
121
|
-
raise RuntimeError(msg)
|
|
122
|
-
|
|
123
|
-
output = r.stdout.decode()
|
|
124
|
-
for line in output.splitlines():
|
|
125
|
-
print(line)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
@copy_and_hack_decorator
|
|
129
|
-
def standardize(
|
|
130
|
-
input_file: str, output_file: str, params_from_parser: Dict, class_points_removed: [], rename_dims: []
|
|
131
|
-
) -> None:
|
|
132
|
-
filename = os.path.basename(output_file)
|
|
133
|
-
with tempfile.NamedTemporaryFile(suffix=filename) as tmp:
|
|
134
|
-
rewrite_with_pdal(input_file, tmp.name, params_from_parser, class_points_removed, rename_dims)
|
|
135
|
-
exec_las2las(tmp.name, output_file)
|
|
136
|
-
|
|
137
|
-
|
|
138
109
|
def main():
|
|
139
110
|
args = parse_args()
|
|
140
111
|
params_from_parser = dict(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|