Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions kart/point_cloud/mosaic_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging

from tempfile import NamedTemporaryFile
from kart.subprocess_util import check_output


L = logging.getLogger("kart.point_cloud")


def write_vpc_for_directory(directory_path):
"""
Given a folder containing some LAZ/LAS files, write a mosaic file that
combines them all into a single Virtual Point Cloud (VPC). The VPC will
contain references to the tiles, rather than replicating their contents.
"""
vrt_path = directory_path / f"{directory_path.name}.vpc"

tiles = [str(p) for p in directory_path.glob("*.copc.laz")]
if not tiles:
vrt_path.unlink(missing_ok=True)
return

with NamedTemporaryFile("w+t", suffix=".kart_tiles", encoding="utf-8") as tile_list:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tested it, but whenever I see this kind of thing I think "this will probably break on windows..." but it depends, windows can certainly share an open file between two processes if the processes feel like it, but seems like sometimes they don't.
Anyway if it does break on windows, this will be why.

tile_list.write("\n".join(tiles))
tile_list.flush()

try:
check_output(
[
"pdal_wrench",
"build_vpc",
f"--output={vrt_path}",
f"--input-file-list={tile_list.name}",
]
)
except FileNotFoundError:
L.warning("pdal_wrench not found. Skipping VPC generation.")
return
15 changes: 13 additions & 2 deletions kart/point_cloud/v1.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import logging
import os
import time

from kart.tile.tile_dataset import TileDataset
from kart.list_of_conflicts import ListOfConflicts, InvalidNewValue
from kart.point_cloud.metadata_util import (
Expand All @@ -16,6 +20,9 @@
)


L = logging.getLogger("kart.point_cloud")


class PointCloudV1(TileDataset):
"""A V1 point-cloud (LIDAR) dataset."""

Expand Down Expand Up @@ -66,8 +73,12 @@ def get_tile_path_pattern(

@classmethod
def write_mosaic_for_directory(cls, directory_path):
# TODO: Not yet implemented
pass
from kart.point_cloud.mosaic_util import write_vpc_for_directory

if os.environ.get("KART_POINT_CLOUD_VPCS"):
t0 = time.time()
write_vpc_for_directory(directory_path)
L.info("Generated VPC in %ss", (time.time() - t0))

def get_dirty_dataset_paths(self, workdir_diff_cache):
# TODO - improve finding and handling of non-standard tile filenames.
Expand Down