ign-pdal-tools 1.12.3__py3-none-any.whl → 1.13.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ign-pdal-tools
3
- Version: 1.12.3
3
+ Version: 1.13.0
4
4
  Summary: Library for common LAS files manipulation with PDAL
5
5
  Author-email: Guillaume Liegard <guillaume.liegard@ign.fr>
6
6
  Description-Content-Type: text/markdown
@@ -1,20 +1,20 @@
1
- ign_pdal_tools-1.12.3.dist-info/licenses/LICENSE.md,sha256=iVzCFZTUXeiqP8bP474iuWZiWO_kDCD4SPh1Wiw125Y,1120
2
- pdaltools/_version.py,sha256=imnrJGefuTNyDbmr09xOFtEVybYZhC7mSJkI2WzqG1Y,75
3
- pdaltools/add_points_in_pointcloud.py,sha256=Q8rCgLi81IsGRUf77tsVb1WJIF-IGLdFk-rC5NA0itE,12679
1
+ ign_pdal_tools-1.13.0.dist-info/licenses/LICENSE.md,sha256=iVzCFZTUXeiqP8bP474iuWZiWO_kDCD4SPh1Wiw125Y,1120
2
+ pdaltools/_version.py,sha256=e2YiSbYkwkZS7qav4oHKZKNWlgK0RiKNeOJMR4ehiLE,75
3
+ pdaltools/add_points_in_pointcloud.py,sha256=VM2HW2b1Ul_I8jtXaOpTsmyGjiEFgoSi8AmCLuj6gH8,12697
4
4
  pdaltools/color.py,sha256=vJgpb8dOvT5rnq5NdVOaMdGc_pKL3damLy4HwGvigJQ,14472
5
- pdaltools/create_random_laz.py,sha256=kFe5iHeHlkgKWRIKjK5l1AD65OG4qLYwAZdO1Wcvuos,5255
5
+ pdaltools/create_random_laz.py,sha256=XuHH4G8Nrs8DB-F8bkcIeto7JtmrlrNGF_R66oxGCbQ,6069
6
6
  pdaltools/las_add_buffer.py,sha256=rnFExAfi0KqlQpL4hDMh2aC08AcYdSHSB6WPG5RyFIc,11274
7
7
  pdaltools/las_clip.py,sha256=GvEOYu8RXV68e35kU8i42GwSkbo4P9TvmS6rkrdPmFM,1034
8
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
- pdaltools/las_rename_dimension.py,sha256=zXEKHyx1uQ3U0oZYo_BTnqbTHGSq5TIZHqZn_EPqNKQ,2576
12
+ pdaltools/las_rename_dimension.py,sha256=FEWIcq0ZZiv9xWbCLDRE9Hzb5K0YYfoi3Z8IZFEs-uU,2887
13
13
  pdaltools/pcd_info.py,sha256=NIAH5KGikVDQLlbCcw9FuaPqe20UZvRfkHsDZd5kmZA,3210
14
14
  pdaltools/replace_attribute_in_las.py,sha256=MHpIizSupgWtbizteoRH8FKDE049hrAh4v_OhmRmSPU,4318
15
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.3.dist-info/METADATA,sha256=inI_jvR-SofWol9ZIbQS10hQtDPp173eXjOq8Rj1aLk,5778
18
- ign_pdal_tools-1.12.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- ign_pdal_tools-1.12.3.dist-info/top_level.txt,sha256=KvGW0ZzqQbhCKzB5_Tp_buWMZyIgiO2M2krWF_ecOZc,10
20
- ign_pdal_tools-1.12.3.dist-info/RECORD,,
17
+ ign_pdal_tools-1.13.0.dist-info/METADATA,sha256=vDALkrn5DTjmZxajqmuFyB5EaFygXyGxTumBoTQQLLg,5778
18
+ ign_pdal_tools-1.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ ign_pdal_tools-1.13.0.dist-info/top_level.txt,sha256=KvGW0ZzqQbhCKzB5_Tp_buWMZyIgiO2M2krWF_ecOZc,10
20
+ ign_pdal_tools-1.13.0.dist-info/RECORD,,
pdaltools/_version.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.12.3"
1
+ __version__ = "1.13.0"
2
2
 
3
3
 
4
4
  if __name__ == "__main__":
@@ -169,7 +169,7 @@ def add_points_to_las(
169
169
  pipeline |= pdal.Reader.las(filename=input_las)
170
170
  pipeline |= pdal.Reader.las(filename=tmp.name)
171
171
  pipeline |= pdal.Filter.merge()
172
- pipeline |= pdal.Writer.las(filename=output_las, forward="all", a_srs=a_srs)
172
+ pipeline |= pdal.Writer.las(filename=output_las, forward="all", extra_dims="all", a_srs=a_srs)
173
173
  pipeline.execute()
174
174
 
175
175
 
@@ -8,11 +8,12 @@ from typing import List, Tuple
8
8
 
9
9
  def create_random_laz(
10
10
  output_file: str,
11
- point_format: int = 3,
11
+ point_format: int = 6,
12
12
  num_points: int = 100,
13
13
  crs: int = 2154,
14
14
  center: Tuple[float, float] = (650000, 6810000),
15
15
  extra_dims: List[Tuple[str, str]] = [],
16
+ classifications: List[int] = None,
16
17
  ):
17
18
  """
18
19
  Create a test LAZ file with EPSG code and additional dimensions.
@@ -26,6 +27,7 @@ def create_random_laz(
26
27
  (default: (650000, 6810000) ; around Paris)
27
28
  extra_dims: List of tuples (dimension_name, dimension_type) where type can be:
28
29
  'float32', 'float64', 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64'
30
+ classifications: Optional list of classification values.
29
31
  """
30
32
 
31
33
  # Create a new point cloud
@@ -52,7 +54,7 @@ def create_random_laz(
52
54
  numpy_type = type_mapping[dim_type]
53
55
  header.add_extra_dim(laspy.ExtraBytesParams(name=dim_name, type=numpy_type))
54
56
 
55
- # Create point cloud
57
+ # Create point cloud
56
58
  las = laspy.LasData(header)
57
59
  las.header.add_crs(CRS.from_string(f"epsg:{crs}"))
58
60
 
@@ -64,14 +66,19 @@ def create_random_laz(
64
66
  # Generate random intensity values
65
67
  las.intensity = np.random.randint(0, 255, num_points)
66
68
 
67
- # Generate random classification values
68
- # 66 is the max value for classification of IGN LidarHD
69
- # cf. https://geoservices.ign.fr/sites/default/files/2022-05/DT_LiDAR_HD_1-0.pdf
70
- if point_format > 3:
71
- num_classifications = 66
69
+ # Set classification values
70
+ if classifications:
71
+ # Randomly select from the provided classification values
72
+ las.classification = np.random.choice(classifications, size=num_points, replace=True).astype(np.uint8)
72
73
  else:
73
- num_classifications = 10
74
- las.classification = np.random.randint(0, num_classifications, num_points)
74
+ # Generate random classification values if not provided
75
+ # 66 is the max value for classification of IGN LidarHD
76
+ # cf. https://geoservices.ign.fr/sites/default/files/2022-05/DT_LiDAR_HD_1-0.pdf
77
+ if point_format >= 6:
78
+ num_classifications = 66
79
+ else:
80
+ num_classifications = 10
81
+ las.classification = np.random.randint(0, num_classifications, num_points, dtype=np.uint8)
75
82
 
76
83
  # Generate random values for each extra dimension
77
84
  for dim_name, dim_type in extra_dims:
@@ -112,20 +119,24 @@ def parse_args():
112
119
  # Parse arguments (assuming argparse is used)
113
120
  parser = argparse.ArgumentParser(description="Create a random LAZ file.")
114
121
  parser.add_argument("--output_file", type=str, help="Path to save the LAZ file")
115
- parser.add_argument("--point_format", type=int, default=3, help="Point format of the LAZ file")
122
+ parser.add_argument("--point_format", type=int, default=6, help="Point format of the LAZ file")
116
123
  parser.add_argument("--num_points", type=int, default=100, help="Number of points to generate")
117
124
  parser.add_argument(
118
125
  "--extra_dims", type=str, nargs="*", default=[], help="Extra dimensions in the format name:type"
119
126
  )
120
127
  parser.add_argument("--crs", type=int, default=2154, help="Projection code")
121
128
  parser.add_argument(
122
- "--center", type=str, default="650000,6810000", help="Center of the area to generate points in"
129
+ "--center", type=float, nargs=2, default=[650000.0, 6810000.0],
130
+ help="Center coordinates (x y) of the area to generate points in (space-separated)"
131
+ )
132
+ parser.add_argument(
133
+ "--classifications", type=int, nargs='+',
134
+ help="List of classification values (space-separated)"
123
135
  )
124
136
  return parser.parse_args()
125
137
 
126
138
 
127
139
  def main():
128
-
129
140
  # Parse arguments
130
141
  args = parse_args()
131
142
 
@@ -133,10 +144,21 @@ def main():
133
144
  extra_dims = [tuple(dim.split(":")) for dim in args.extra_dims]
134
145
 
135
146
  # Parse center
136
- center = tuple(map(float, args.center.split(",")))
147
+ center = tuple(args.center[:2]) # Only take first 2 values if more are provided
148
+
149
+ # Parse classifications if provided
150
+ classifications = args.classifications
137
151
 
138
152
  # Call create_random_laz
139
- result = create_random_laz(args.output_file, args.point_format, args.num_points, args.crs, center, extra_dims)
153
+ result = create_random_laz(
154
+ args.output_file,
155
+ args.point_format,
156
+ args.num_points,
157
+ args.crs,
158
+ center,
159
+ extra_dims,
160
+ classifications
161
+ )
140
162
 
141
163
  # Test output file
142
164
  test_output_file(result, args.output_file)
@@ -5,10 +5,12 @@ This script allows renaming dimensions in a LAS file while preserving all other
5
5
  """
6
6
 
7
7
  import argparse
8
+ import logging
8
9
  import pdal
9
10
  import sys
10
11
  from pathlib import Path
11
12
  from pdaltools.las_remove_dimensions import remove_dimensions_from_points
13
+ from pdaltools.las_info import las_info_metadata
12
14
 
13
15
 
14
16
  def rename_dimension(input_file: str, output_file: str, old_dims: list[str], new_dims: list[str]):
@@ -31,8 +33,14 @@ def rename_dimension(input_file: str, output_file: str, old_dims: list[str], new
31
33
  if dim in mandatory_dimensions:
32
34
  raise ValueError(f"New dimension {dim} cannot be a mandatory dimension (X,Y,Z,x,y,z)")
33
35
 
36
+ metadata = las_info_metadata(input_file)
37
+ input_dimensions = metadata["dimensions"]
38
+
34
39
  pipeline = pdal.Pipeline() | pdal.Reader.las(input_file)
35
40
  for old, new in zip(old_dims, new_dims):
41
+ if old not in input_dimensions:
42
+ logging.warning(f"Dimension {old} not found in input file : we cannot rename it")
43
+ continue
36
44
  pipeline |= pdal.Filter.ferry(dimensions=f"{old} => {new}")
37
45
  pipeline |= pdal.Writer.las(output_file)
38
46
  pipeline.execute()