Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StagedTo3DConverter class with initial methods #15

Merged
merged 3 commits into from
May 27, 2022
Merged
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
130 changes: 130 additions & 0 deletions viz_3dtiles/Cesium3DTileset.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
import json
import os
from pathlib import Path
from statistics import mean

class Cesium3DTileset:

Expand Down Expand Up @@ -103,3 +105,131 @@ def write_file(self):
outfile.write(self.to_json())

# print("Tileset saved to " + self.get_filename())

def create_parent_json(
self,
json_paths=[],
save_to=None,
save_as="tileset.json",
remove_children=True
):
"""
Merge all the tileset json files into one main tileset.json file.

Parameters
----------

json_paths : list of strings
The paths to the tileset json files to be merged

save_to : string (optional)
Set the filepath, but not the filename or extension, of
tileset.json. If set to None, then the save_to path on the
tileset instance will be used.

save_as : string (optional)
Set the filename of the tileset, without the extension.
Defaults to "tileset". If set to None, then the save_as string
on the tileset instance will be used.

remove_children : bool
If True, then the children json files will be removed after
they are merged into the parent.
"""

if save_to is None:
save_to = self.save_to

if save_as is None:
save_as = self.save_as

# The tileset.json should be saved at the root of this directory
parent_json_path = os.path.join(save_to, save_as + "." + self.FILE_EXT)

tileset = {
"asset": {
"version": "0.0"
},
"root": {
"boundingVolume": {"box": []},
"geometricError": None,
"refine": "ADD",
"children": []
}
}

# Parent bounding volume is the union of all B3DM bounding volumes
all_bvs = []

# Parent geometric error
all_ges = []

# Check that all the JSON files exist
for json_path in json_paths:

if not os.path.isfile(json_path):
raise ValueError(f"JSON file {json_path} does not exist")

# Read in the json
with open(json_path, "r") as f:
j = json.load(f)

# Get the bounding volume
bv = j["root"]["boundingVolume"]["box"]
# Get the geometric error
ge = j["root"]["geometricError"]

# The URI of the B3DM file should be relative to the parent
# tileset.json file. URL in child JSON is just the filename + ext
# of the B3DM file (not the full path). Assume the child JSON is
# saved in the same directory as the child B3DM.
child_filename = j["root"]["content"]["url"]
child_fullpath = os.path.join(
os.path.dirname(json_path), child_filename)
rel_uri = os.path.relpath(child_fullpath, save_to)

# Make the json/dict
child = {
"geometricError": ge,
"boundingVolume": {"box": bv},
"refine": "ADD",
"content": {
"boundingVolume": {"box": bv},
"uri": rel_uri
}
}

# Add the child to the tileset
tileset["root"]["children"].append(child)

# Add the bounding volume to the list of all bounding volumes
all_bvs.append(bv)

# Add the geometric error to the list of all geometric errors
all_ges.append(ge)

# Calculate the parent bounding volume
mid_x = mean([bv[0] for bv in all_bvs])
mid_y = mean([bv[1] for bv in all_bvs])
mid_z = mean([bv[2] for bv in all_bvs])
width = sum([bv[3] for bv in all_bvs])
length = sum([bv[7] for bv in all_bvs])
parent_bounding_volume = [
mid_x, mid_y, mid_z, width,
0, 0, 0, length, 0, 0, 0, 0]

# Calculate the parent geometric error
parent_geometric_error = sum(all_ges)

# Update the tileset
tileset["root"]["boundingVolume"]["box"] = parent_bounding_volume
tileset["root"]["geometricError"] = parent_geometric_error

# Write the tileset.json
with open(parent_json_path, "w") as f:
json.dump(tileset, f, indent=4)

if remove_children:
# Remove the children
for j in json_paths:
os.remove(j)
1 change: 1 addition & 0 deletions viz_3dtiles/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from .Cesium3DTile import Cesium3DTile
from .Cesium3DTileset import Cesium3DTileset
from .StagedTo3DConverter import StagedTo3DConverter

__version__ = '0.0.1'