ign-pdal-tools 1.15.1__py3-none-any.whl → 1.15.3__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.15.1
3
+ Version: 1.15.3
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,6 +1,6 @@
1
- ign_pdal_tools-1.15.1.dist-info/licenses/LICENSE.md,sha256=iVzCFZTUXeiqP8bP474iuWZiWO_kDCD4SPh1Wiw125Y,1120
2
- pdaltools/_version.py,sha256=Ifg5508wmTI_52FvVJqD1IBETM-8iJe8gIBnxxVL1UI,75
3
- pdaltools/add_points_in_pointcloud.py,sha256=VM2HW2b1Ul_I8jtXaOpTsmyGjiEFgoSi8AmCLuj6gH8,12697
1
+ ign_pdal_tools-1.15.3.dist-info/licenses/LICENSE.md,sha256=iVzCFZTUXeiqP8bP474iuWZiWO_kDCD4SPh1Wiw125Y,1120
2
+ pdaltools/_version.py,sha256=kbqZcb5X6kCQzhP5k9ki5_yUYO5nUoW5BIsGseJ1Rz4,75
3
+ pdaltools/add_points_in_pointcloud.py,sha256=UJTwoOjC0WKnp_ynNHpwUh1fmbIgw7hq5xoNN8_FxQQ,12965
4
4
  pdaltools/color.py,sha256=s-_rmLK6fIK3UwkUzHVZPEkm6r1LliG5ftGr-jkqyjM,9549
5
5
  pdaltools/create_random_laz.py,sha256=XuHH4G8Nrs8DB-F8bkcIeto7JtmrlrNGF_R66oxGCbQ,6069
6
6
  pdaltools/download_image.py,sha256=DG9PunQsjw7Uyyf4YMVp8LMH0G3Uo4cahx5EZbdi3so,7846
@@ -12,11 +12,11 @@ pdaltools/las_merge.py,sha256=tcFVueV9X9nNEaoAl5zCduY5DETlBg63MAgP2SuKiNo,4121
12
12
  pdaltools/las_remove_dimensions.py,sha256=f8imGhN6LNTuQ1GMJQRzIIV3Wab_oRPOyEnKi1CgfiM,2318
13
13
  pdaltools/las_rename_dimension.py,sha256=FEWIcq0ZZiv9xWbCLDRE9Hzb5K0YYfoi3Z8IZFEs-uU,2887
14
14
  pdaltools/pcd_info.py,sha256=NIAH5KGikVDQLlbCcw9FuaPqe20UZvRfkHsDZd5kmZA,3210
15
- pdaltools/replace_area_in_pointcloud.py,sha256=VyLMDItP-FU4muRV01vbetf5ySgdKeOpc55YESicJ7U,8008
15
+ pdaltools/replace_area_in_pointcloud.py,sha256=fWh9YLwwB7hUndNSIHbCvRVZRfwSrmkv4we0PEd1fJw,8594
16
16
  pdaltools/replace_attribute_in_las.py,sha256=MHpIizSupgWtbizteoRH8FKDE049hrAh4v_OhmRmSPU,4318
17
17
  pdaltools/standardize_format.py,sha256=I2oNiwhSMtr4e5ZK9qbB_yKmy3twOoO6QLiSFu4_AaI,3905
18
18
  pdaltools/unlock_file.py,sha256=G2odk0cpp_X9r49Y90oK88v3qlihaMfg6acwmWqblik,1958
19
- ign_pdal_tools-1.15.1.dist-info/METADATA,sha256=3mwPLGrnvNs6FuL_f6iSbFq1Zb5mlVnTjdGidcs8SLI,6146
20
- ign_pdal_tools-1.15.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
- ign_pdal_tools-1.15.1.dist-info/top_level.txt,sha256=KvGW0ZzqQbhCKzB5_Tp_buWMZyIgiO2M2krWF_ecOZc,10
22
- ign_pdal_tools-1.15.1.dist-info/RECORD,,
19
+ ign_pdal_tools-1.15.3.dist-info/METADATA,sha256=HES6lKZwoiaArDrjrqrazbY-xtcqdjM2QxXG71NV0p4,6146
20
+ ign_pdal_tools-1.15.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ ign_pdal_tools-1.15.3.dist-info/top_level.txt,sha256=KvGW0ZzqQbhCKzB5_Tp_buWMZyIgiO2M2krWF_ecOZc,10
22
+ ign_pdal_tools-1.15.3.dist-info/RECORD,,
pdaltools/_version.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.15.1"
1
+ __version__ = "1.15.3"
2
2
 
3
3
 
4
4
  if __name__ == "__main__":
@@ -6,6 +6,7 @@ import geopandas as gpd
6
6
  import laspy
7
7
  import numpy as np
8
8
  import pdal
9
+ from shapely import set_precision
9
10
  from shapely.geometry import MultiPoint, Point, box
10
11
 
11
12
  from pdaltools.las_info import get_epsg_from_las, get_tile_bbox
@@ -327,6 +328,10 @@ def add_points_from_geometry_to_las(
327
328
  # Clip points from GeoJSON by LIDAR tile
328
329
  points_clipped = clip_3d_points_to_tile(points_gdf, input_las, spatial_ref, tile_width)
329
330
 
331
+ # Remove duplicate points (due to precision issue) - las file have centrimetric precision
332
+ points_clipped.geometry = set_precision(points_clipped.geometry, grid_size=0.01)
333
+ points_clipped = points_clipped.drop_duplicates()
334
+
330
335
  # Add points by LIDAR tile and save the result
331
336
  add_points_to_las(points_clipped, input_las, output_las, spatial_ref, virtual_points_classes)
332
337
 
@@ -33,13 +33,14 @@ def argument_parser():
33
33
  help="path of the source digital surface model (DSM), used to generate source points",
34
34
  )
35
35
  from_DSM.add_argument(
36
- "--source_ground_area",
36
+ "--source_ground_mask",
37
37
  "-g",
38
38
  required=True,
39
39
  type=str,
40
40
  help=(
41
- "area of the ground, used to intersect source cloud. "
42
- "(shapefile, geojson or other format readable by GDAL)"
41
+ "ground mask, a raster file used to filter source cloud. "
42
+ "Pixel with value > 0 is considered as ground, and define the source cloud we keep. "
43
+ "(tif or other raster format readable by GDAL)"
43
44
  ),
44
45
  )
45
46
  from_DSM.add_argument(
@@ -65,7 +66,7 @@ def add_common_options(parser):
65
66
  "-r",
66
67
  required=True,
67
68
  type=str,
68
- help="area to replace (shapefile, geojson or other format readable by GDAL)",
69
+ help="area to replace (shapefile, geojson or other vector format readable by GDAL)",
69
70
  )
70
71
  parser.add_argument("--output_cloud", "-o", required=True, type=str, help="output cloud file")
71
72
 
@@ -84,7 +85,7 @@ def from_DSM_func(args):
84
85
  replace_area(
85
86
  target_cloud=args.target_cloud,
86
87
  pipeline_source=pipeline_read_from_DSM(
87
- dsm=args.source_dsm, ground_area=args.source_ground_area, classification=args.source_classification
88
+ dsm=args.source_dsm, ground_mask=args.source_ground_mask, classification=args.source_classification
88
89
  ),
89
90
  replacement_area=args.replacement_area,
90
91
  output_cloud=args.output_cloud,
@@ -101,27 +102,35 @@ def get_writer_params(input_file):
101
102
 
102
103
 
103
104
  def pipeline_read_from_cloud(filename):
105
+ print("source cloud: ", filename)
104
106
  pipeline_source = pdal.Pipeline()
105
107
  pipeline_source |= pdal.Reader.las(filename=filename)
106
108
  return pipeline_source
107
109
 
108
110
 
109
- def pipeline_read_from_DSM(dsm, ground_area, classification):
111
+ def pipeline_read_from_DSM(dsm, ground_mask, classification):
112
+ print("DSM: ", dsm)
113
+ print("ground_mask: ", ground_mask)
114
+ print("classification: ", classification)
115
+
110
116
  # get nodata value
111
117
  ds = gdal.Open(dsm)
112
118
  band = ds.GetRasterBand(1)
113
119
  nodata_value = band.GetNoDataValue()
120
+ print("DSM: nodata:", nodata_value)
114
121
  ds.Close()
115
122
 
116
123
  pipeline = pdal.Pipeline()
117
124
  pipeline |= pdal.Reader.gdal(filename=dsm, header="Z")
118
- pipeline |= pdal.Filter.expression(expression=f"Z != {nodata_value}")
119
125
 
120
- pipeline |= pdal.Filter.ferry(dimensions="=> geometryFid")
121
- pipeline |= pdal.Filter.assign(assignment="geometryFid[:]=-1")
122
- pipeline |= pdal.Filter.overlay(column="fid", dimension="geometryFid", datasource=ground_area)
126
+ if nodata_value is not None: # nodata_value may be None and cause bugs
127
+ pipeline |= pdal.Filter.expression(expression=f"Z != {nodata_value}")
128
+
129
+ pipeline |= pdal.Filter.ferry(dimensions="=> ground")
130
+ pipeline |= pdal.Filter.assign(assignment="ground[:]=-1")
131
+ pipeline |= pdal.Filter.colorization(dimensions="ground:1:1.0", raster=ground_mask)
123
132
  # Keep only points in the area
124
- pipeline |= pdal.Filter.expression(expression="geometryFid>=0")
133
+ pipeline |= pdal.Filter.expression(expression="ground>0")
125
134
 
126
135
  # assign class
127
136
  pipeline |= pdal.Filter.ferry(dimensions="=>Classification")
@@ -133,6 +142,11 @@ def pipeline_read_from_DSM(dsm, ground_area, classification):
133
142
  def replace_area(
134
143
  target_cloud, pipeline_source, replacement_area, output_cloud, source_pdal_filter="", target_pdal_filter=""
135
144
  ):
145
+ print("target cloud: ", target_cloud)
146
+ print("replacement area: ", replacement_area)
147
+ print("output cloud: ", output_cloud)
148
+ print("source pdal filter: ", source_pdal_filter)
149
+ print("target pdal filter: ", target_pdal_filter)
136
150
  crops = []
137
151
  # pipeline to read target_cloud and remove points inside the polygon
138
152
  pipeline_target = pdal.Pipeline()