From 47caaa82b9d2026f255ed9bd6dffd35a83a4ddb1 Mon Sep 17 00:00:00 2001 From: AdrianSolberg Date: Wed, 15 Oct 2025 13:44:06 +0200 Subject: [PATCH] fix(#1): fix precision loss in coversion Also update .gitignore --- .gitignore | 2 ++ lasConverter.py | 70 ++++++++++++++++--------------------------------- 2 files changed, 25 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 1533e9a..b30bf2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ #survey content /surveys/* /output_las/* +.DS_Store +.venv \ No newline at end of file diff --git a/lasConverter.py b/lasConverter.py index 52db308..df96912 100644 --- a/lasConverter.py +++ b/lasConverter.py @@ -25,36 +25,12 @@ def CSV_2_LAS(surveys_folders, output_folder, output_name="merged_final1.las", c dir_to_id = {name: i+1 for i, name in enumerate(top_dirs)} pd.DataFrame(list(dir_to_id.items()), columns=["top_dir","id"]).to_csv(output_folder / "dir_mapping.csv", index=False) - # Create LAS header template - header = laspy.LasHeader(point_format=6, version="1.4") - header.scales = (1, 1, 1) - header.offsets = (0, 0, 0) - - # Add extra dimensions - header.add_extra_dim(laspy.ExtraBytesParams(name="accepted", type=np.uint8)) - header.add_extra_dim(laspy.ExtraBytesParams(name="TVU", type=np.float32)) - header.add_extra_dim(laspy.ExtraBytesParams(name="THU", type=np.float32)) - temp_folder = output_folder / "tmp" temp_folder.mkdir(exist_ok=True) # Step 1: Write chunked LAS files print("Step 1: Writing LAS chunks...") file_counter = 1 - points_in_file = 0 - writer = None - - def open_new_chunk_file(): - nonlocal file_counter, points_in_file, writer - if writer: - writer.close() - las_path = temp_folder / f"{output_name}_chunk_{file_counter}.las" - writer = laspy.open(str(las_path), mode="w", header=header) - print(f"Writing chunk: {las_path}") - points_in_file = 0 - file_counter += 1 - - open_new_chunk_file() for f in csv_files: top_dir_id = dir_to_id[f.relative_to(surveys_path).parts[0]] @@ -79,29 +55,29 @@ def open_new_chunk_file(): thu = df.iloc[:, 5].to_numpy(dtype=np.float32) ids = np.full(len(df), top_dir_id, dtype=np.uint16) - points = laspy.ScaleAwarePointRecord.zeros(len(df), header=header) - points.X = x - points.Y = y - points.Z = z - points.point_source_id = ids - points["accepted"] = accepted - points["TVU"] = tvu - points["THU"] = thu - - # Split points into multiple LAS chunks if needed - start_idx = 0 - while start_idx < len(points): - remaining_space = max_points_per_file - points_in_file - end_idx = start_idx + remaining_space - chunk = points[start_idx:end_idx] - writer.write_points(chunk) - points_in_file += len(chunk) - start_idx = end_idx - if points_in_file >= max_points_per_file: - open_new_chunk_file() - - if writer: - writer.close() + # Create LAS header template + header = laspy.LasHeader(point_format=6, version="1.4") + + # Add extra dimensions + header.add_extra_dim(laspy.ExtraBytesParams(name="accepted", type=np.uint8)) + header.add_extra_dim(laspy.ExtraBytesParams(name="TVU", type=np.float32)) + header.add_extra_dim(laspy.ExtraBytesParams(name="THU", type=np.float32)) + + las = laspy.LasData(header) + las.x = x + las.y = y + las.z = z + + # Add extra dimensions + las["accepted"] = accepted + las["TVU"] = tvu + las["THU"] = thu + las.point_source_id = ids + + las_path = temp_folder / f"{output_name}_chunk_{file_counter}.las" + las.write(las_path) + print(f"✅ Wrote {las_path}") + file_counter += 1 # Merging chunked LAS files into single LAS print("Step 2: Merging LAS chunks into final LAS...")