voxcity 0.5.9__py3-none-any.whl → 0.5.11__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.

Potentially problematic release.


This version of voxcity might be problematic. Click here for more details.

voxcity/generator.py CHANGED
@@ -689,6 +689,14 @@ def get_voxcity(rectangle_vertices, building_source, land_cover_source, canopy_h
689
689
  voxcity_grid_vis[-1, -1, -1] = -99 # Add marker to fix camera location and angle of view
690
690
  visualize_3d_voxel(voxcity_grid_vis, voxel_size=meshsize, save_path=kwargs["voxelvis_img_save_path"])
691
691
 
692
+ # Save all data if a save path is provided
693
+ save_voxcity = kwargs.get("save_voxctiy_data", True)
694
+ if save_voxcity:
695
+ save_path = kwargs.get("save_data_path", f"{output_dir}/voxcity_data.pkl")
696
+ save_voxcity_data(save_path, voxcity_grid, building_height_grid, building_min_height_grid,
697
+ building_id_grid, canopy_height_grid, land_cover_grid, dem_grid,
698
+ building_gdf, meshsize, rectangle_vertices)
699
+
692
700
  return voxcity_grid, building_height_grid, building_min_height_grid, building_id_grid, canopy_height_grid, land_cover_grid, dem_grid, building_gdf
693
701
 
694
702
  def get_voxcity_CityGML(rectangle_vertices, land_cover_source, canopy_height_source, meshsize, url_citygml=None, citygml_path=None, **kwargs):
@@ -817,6 +825,14 @@ def get_voxcity_CityGML(rectangle_vertices, land_cover_source, canopy_height_sou
817
825
  # Generate 3D voxel grid
818
826
  voxcity_grid = create_3d_voxel(building_height_grid, building_min_height_grid, building_id_grid, land_cover_grid, dem_grid, canopy_height_grid, meshsize, land_cover_source)
819
827
 
828
+ # Save all data if a save path is provided
829
+ save_voxcity = kwargs.get("save_voxctiy_data", True)
830
+ if save_voxcity:
831
+ save_path = kwargs.get("save_data_path", f"{output_dir}/voxcity_data.pkl")
832
+ save_voxcity_data(save_path, voxcity_grid, building_height_grid, building_min_height_grid,
833
+ building_id_grid, canopy_height_grid, land_cover_grid, dem_grid,
834
+ building_gdf, meshsize, rectangle_vertices)
835
+
820
836
  return voxcity_grid, building_height_grid, building_min_height_grid, building_id_grid, canopy_height_grid, land_cover_grid, dem_grid, filtered_buildings
821
837
 
822
838
  def replace_nan_in_nested(arr, replace_value=10.0):
@@ -844,4 +860,89 @@ def replace_nan_in_nested(arr, replace_value=10.0):
844
860
  if isinstance(arr[i][j][k][l], float) and np.isnan(arr[i][j][k][l]):
845
861
  arr[i][j][k][l] = replace_value
846
862
 
847
- return np.array(arr, dtype=object)
863
+ return np.array(arr, dtype=object)
864
+
865
+ def save_voxcity_data(output_path, voxcity_grid, building_height_grid, building_min_height_grid,
866
+ building_id_grid, canopy_height_grid, land_cover_grid, dem_grid,
867
+ building_gdf, meshsize, rectangle_vertices):
868
+ """Save voxcity data to a file for later loading.
869
+
870
+ Args:
871
+ output_path: Path to save the data file
872
+ voxcity_grid: 3D voxel grid of the complete city model
873
+ building_height_grid: 2D grid of building heights
874
+ building_min_height_grid: 2D grid of minimum building heights
875
+ building_id_grid: 2D grid of building IDs
876
+ canopy_height_grid: 2D grid of tree canopy heights
877
+ land_cover_grid: 2D grid of land cover classifications
878
+ dem_grid: 2D grid of ground elevation
879
+ building_gdf: GeoDataFrame of building footprints and metadata
880
+ meshsize: Size of each grid cell in meters
881
+ rectangle_vertices: List of coordinates defining the area of interest
882
+ """
883
+ import pickle
884
+ import os
885
+
886
+ # Create directory if it doesn't exist
887
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
888
+
889
+ # Create a dictionary with all the data
890
+ data_dict = {
891
+ 'voxcity_grid': voxcity_grid,
892
+ 'building_height_grid': building_height_grid,
893
+ 'building_min_height_grid': building_min_height_grid,
894
+ 'building_id_grid': building_id_grid,
895
+ 'canopy_height_grid': canopy_height_grid,
896
+ 'land_cover_grid': land_cover_grid,
897
+ 'dem_grid': dem_grid,
898
+ 'building_gdf': building_gdf,
899
+ 'meshsize': meshsize,
900
+ 'rectangle_vertices': rectangle_vertices
901
+ }
902
+
903
+ # Save the data to a file using pickle
904
+ with open(output_path, 'wb') as f:
905
+ pickle.dump(data_dict, f)
906
+
907
+ print(f"Voxcity data saved to {output_path}")
908
+
909
+ def load_voxcity_data(input_path):
910
+ """Load voxcity data from a saved file.
911
+
912
+ Args:
913
+ input_path: Path to the saved data file
914
+
915
+ Returns:
916
+ tuple: All the voxcity data components including:
917
+ - voxcity_grid: 3D voxel grid of the complete city model
918
+ - building_height_grid: 2D grid of building heights
919
+ - building_min_height_grid: 2D grid of minimum building heights
920
+ - building_id_grid: 2D grid of building IDs
921
+ - canopy_height_grid: 2D grid of tree canopy heights
922
+ - land_cover_grid: 2D grid of land cover classifications
923
+ - dem_grid: 2D grid of ground elevation
924
+ - building_gdf: GeoDataFrame of building footprints and metadata
925
+ - meshsize: Size of each grid cell in meters
926
+ - rectangle_vertices: List of coordinates defining the area of interest
927
+ """
928
+ import pickle
929
+
930
+ # Load the data from the file
931
+ with open(input_path, 'rb') as f:
932
+ data_dict = pickle.load(f)
933
+
934
+ print(f"Voxcity data loaded from {input_path}")
935
+
936
+ # Return all components as a tuple
937
+ return (
938
+ data_dict['voxcity_grid'],
939
+ data_dict['building_height_grid'],
940
+ data_dict['building_min_height_grid'],
941
+ data_dict['building_id_grid'],
942
+ data_dict['canopy_height_grid'],
943
+ data_dict['land_cover_grid'],
944
+ data_dict['dem_grid'],
945
+ data_dict['building_gdf'],
946
+ data_dict['meshsize'],
947
+ data_dict['rectangle_vertices']
948
+ )
@@ -1,4 +1,5 @@
1
1
  import numpy as np
2
+ import os
2
3
  import trimesh
3
4
  import matplotlib.colors as mcolors
4
5
  import matplotlib.cm as cm
@@ -304,4 +305,107 @@ def export_meshes(meshes, output_directory, base_filename):
304
305
  # Export individual meshes as STL
305
306
  for class_id, mesh in meshes.items():
306
307
  # Convert class_id to a string for filename
307
- mesh.export(f"{output_directory}/{base_filename}_{class_id}.stl")
308
+ mesh.export(f"{output_directory}/{base_filename}_{class_id}.stl")
309
+
310
+ def split_vertices_manual(mesh):
311
+ """
312
+ Imitate trimesh's split_vertices() by giving each face its own copy of vertices.
313
+ This ensures every face is truly disconnected, preventing smooth shading in Rhino.
314
+ """
315
+ new_meshes = []
316
+
317
+ # For each face, build a small, one-face mesh
318
+ for face_idx, face in enumerate(mesh.faces):
319
+ face_coords = mesh.vertices[face]
320
+
321
+ # Create mini-mesh without colors first
322
+ mini_mesh = trimesh.Trimesh(
323
+ vertices=face_coords,
324
+ faces=[[0, 1, 2]],
325
+ process=False # skip merging/cleaning
326
+ )
327
+
328
+ # If the mesh has per-face colors, set the face color properly
329
+ if (mesh.visual.face_colors is not None
330
+ and len(mesh.visual.face_colors) == len(mesh.faces)):
331
+ # Create a visual object with the face color (for one face)
332
+ face_color = mesh.visual.face_colors[face_idx]
333
+ color_visual = trimesh.visual.ColorVisuals(
334
+ mesh=mini_mesh,
335
+ face_colors=np.array([face_color]), # One face, one color
336
+ vertex_colors=None
337
+ )
338
+ mini_mesh.visual = color_visual
339
+
340
+ new_meshes.append(mini_mesh)
341
+
342
+ # Concatenate all the single-face meshes
343
+ out_mesh = trimesh.util.concatenate(new_meshes)
344
+ return out_mesh
345
+
346
+ def save_obj_from_colored_mesh(meshes, output_path, base_filename):
347
+ """
348
+ Save colored meshes as OBJ and MTL files.
349
+
350
+ Parameters
351
+ ----------
352
+ meshes : dict
353
+ Dictionary of trimesh.Trimesh objects with face colors.
354
+ output_path : str
355
+ Directory path where to save the files.
356
+ base_filename : str
357
+ Base name for the output files (without extension).
358
+
359
+ Returns
360
+ -------
361
+ tuple
362
+ Paths to the saved (obj_file, mtl_file).
363
+ """
364
+
365
+ os.makedirs(output_path, exist_ok=True)
366
+ obj_path = os.path.join(output_path, f"{base_filename}.obj")
367
+ mtl_path = os.path.join(output_path, f"{base_filename}.mtl")
368
+
369
+ # Combine all meshes
370
+ combined_mesh = trimesh.util.concatenate(list(meshes.values()))
371
+ combined_mesh = split_vertices_manual(combined_mesh)
372
+
373
+ # Create unique materials for each unique face color
374
+ face_colors = combined_mesh.visual.face_colors
375
+ unique_colors = np.unique(face_colors, axis=0)
376
+
377
+ # Write MTL file
378
+ with open(mtl_path, 'w') as mtl_file:
379
+ for i, color in enumerate(unique_colors):
380
+ material_name = f'material_{i}'
381
+ mtl_file.write(f'newmtl {material_name}\n')
382
+ # Convert RGBA to RGB float values
383
+ rgb = color[:3].astype(float) / 255.0
384
+ mtl_file.write(f'Kd {rgb[0]:.6f} {rgb[1]:.6f} {rgb[2]:.6f}\n')
385
+ mtl_file.write(f'd {color[3]/255.0:.6f}\n\n') # Alpha value
386
+
387
+ # Create material groups based on face colors
388
+ color_to_material = {tuple(c): f'material_{i}' for i, c in enumerate(unique_colors)}
389
+
390
+ # Write OBJ file
391
+ with open(obj_path, 'w') as obj_file:
392
+ obj_file.write(f'mtllib {os.path.basename(mtl_path)}\n')
393
+
394
+ # Write vertices
395
+ for vertex in combined_mesh.vertices:
396
+ obj_file.write(f'v {vertex[0]:.6f} {vertex[1]:.6f} {vertex[2]:.6f}\n')
397
+
398
+ # Write faces grouped by material
399
+ current_material = None
400
+ for face_idx, face in enumerate(combined_mesh.faces):
401
+ face_color = tuple(face_colors[face_idx])
402
+ material_name = color_to_material[face_color]
403
+
404
+ if material_name != current_material:
405
+ obj_file.write(f'usemtl {material_name}\n')
406
+ current_material = material_name
407
+
408
+ # OBJ indices are 1-based
409
+ obj_file.write(f'f {face[0]+1} {face[1]+1} {face[2]+1}\n')
410
+
411
+ return obj_path, mtl_path
@@ -41,7 +41,8 @@ from ..geoprocessor.mesh import (
41
41
  create_voxel_mesh,
42
42
  create_sim_surface_mesh,
43
43
  create_city_meshes,
44
- export_meshes
44
+ export_meshes,
45
+ save_obj_from_colored_mesh
45
46
  )
46
47
  # from ..exporter.obj import save_obj_from_colored_mesh
47
48
  from .material import get_material_dict
@@ -1531,6 +1532,7 @@ def visualize_voxcity_multi_view(voxel_array, meshsize, **kwargs):
1531
1532
  projection_type = kwargs.get("projection_type", "perspective")
1532
1533
  distance_factor = kwargs.get("distance_factor", 1.0)
1533
1534
  save_obj = kwargs.get("save_obj", False)
1535
+ show_views = kwargs.get("show_views", True)
1534
1536
 
1535
1537
  # Create meshes
1536
1538
  print("Creating voxel meshes...")
@@ -1567,21 +1569,22 @@ def visualize_voxcity_multi_view(voxel_array, meshsize, **kwargs):
1567
1569
  os.makedirs(output_directory, exist_ok=True)
1568
1570
  export_meshes(meshes, output_directory, base_filename)
1569
1571
 
1570
- # Create and save multiple views
1571
- print("Creating multiple views...")
1572
- # Create output directory if it doesn't exist
1573
- os.makedirs(output_directory, exist_ok=True)
1574
- image_files = create_multi_view_scene(meshes, output_directory=output_directory, projection_type=projection_type, distance_factor=distance_factor)
1575
-
1576
- # Display each view separately
1577
- for view_name, img_file in image_files:
1578
- plt.figure(figsize=(12, 8))
1579
- img = plt.imread(img_file)
1580
- plt.imshow(img)
1581
- plt.title(view_name.replace('_', ' ').title(), pad=20)
1582
- plt.axis('off')
1583
- plt.show()
1584
- plt.close()
1572
+ if show_views:
1573
+ # Create and save multiple views
1574
+ print("Creating multiple views...")
1575
+ # Create output directory if it doesn't exist
1576
+ os.makedirs(output_directory, exist_ok=True)
1577
+ image_files = create_multi_view_scene(meshes, output_directory=output_directory, projection_type=projection_type, distance_factor=distance_factor)
1578
+
1579
+ # Display each view separately
1580
+ for view_name, img_file in image_files:
1581
+ plt.figure(figsize=(12, 8))
1582
+ img = plt.imread(img_file)
1583
+ plt.imshow(img)
1584
+ plt.title(view_name.replace('_', ' ').title(), pad=20)
1585
+ plt.axis('off')
1586
+ plt.show()
1587
+ plt.close()
1585
1588
 
1586
1589
  # After creating the meshes and before visualization
1587
1590
  if save_obj:
@@ -1633,6 +1636,8 @@ def visualize_voxcity_multi_view_with_multiple_sim_grids(voxel_array, meshsize,
1633
1636
  dem_grid_ori = kwargs.get("dem_grid", None)
1634
1637
  projection_type = kwargs.get("projection_type", "perspective")
1635
1638
  distance_factor = kwargs.get("distance_factor", 1.0)
1639
+ show_views = kwargs.get("show_views", True)
1640
+ save_obj = kwargs.get("save_obj", False)
1636
1641
 
1637
1642
  if dem_grid_ori is not None:
1638
1643
  dem_grid = dem_grid_ori - np.min(dem_grid_ori)
@@ -1681,27 +1686,33 @@ def visualize_voxcity_multi_view_with_multiple_sim_grids(voxel_array, meshsize,
1681
1686
  os.makedirs(output_directory, exist_ok=True)
1682
1687
  export_meshes(meshes, output_directory, base_filename)
1683
1688
 
1684
- # Create and save multiple views
1685
- print("Creating multiple views...")
1686
- os.makedirs(output_directory, exist_ok=True)
1687
- image_files = create_multi_view_scene(
1688
- meshes,
1689
- output_directory=output_directory,
1690
- projection_type=projection_type,
1691
- distance_factor=distance_factor
1692
- )
1689
+ if show_views:
1690
+ # Create and save multiple views
1691
+ print("Creating multiple views...")
1692
+ os.makedirs(output_directory, exist_ok=True)
1693
+ image_files = create_multi_view_scene(
1694
+ meshes,
1695
+ output_directory=output_directory,
1696
+ projection_type=projection_type,
1697
+ distance_factor=distance_factor
1698
+ )
1693
1699
 
1694
- # Display each view separately
1695
- for view_name, img_file in image_files:
1696
- plt.figure(figsize=(12, 8))
1697
- img = plt.imread(img_file)
1698
- plt.imshow(img)
1699
- plt.title(view_name.replace('_', ' ').title(), pad=20)
1700
- plt.axis('off')
1701
- plt.show()
1702
- plt.close()
1700
+ # Display each view separately
1701
+ for view_name, img_file in image_files:
1702
+ plt.figure(figsize=(12, 8))
1703
+ img = plt.imread(img_file)
1704
+ plt.imshow(img)
1705
+ plt.title(view_name.replace('_', ' ').title(), pad=20)
1706
+ plt.axis('off')
1707
+ plt.show()
1708
+ plt.close()
1703
1709
 
1704
- return meshes
1710
+ # After creating the meshes and before visualization
1711
+ if save_obj:
1712
+ output_directory = kwargs.get('output_directory', 'output')
1713
+ output_file_name = kwargs.get('output_file_name', 'voxcity_mesh')
1714
+ obj_path, mtl_path = save_obj_from_colored_mesh(meshes, output_directory, output_file_name)
1715
+ print(f"Saved mesh files to:\n {obj_path}\n {mtl_path}")
1705
1716
 
1706
1717
  def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None, **kwargs):
1707
1718
  """
@@ -1778,6 +1789,7 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
1778
1789
  colorbar_title = kwargs.get("colorbar_title", "")
1779
1790
  value_name = kwargs.get("value_name", None)
1780
1791
  nan_color = kwargs.get("nan_color", "gray")
1792
+ show_views = kwargs.get("show_views", True)
1781
1793
  save_obj = kwargs.get("save_obj", False)
1782
1794
 
1783
1795
  if value_name is None:
@@ -1900,28 +1912,28 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
1900
1912
  print("Creating multiple views...")
1901
1913
  # Create output directory if it doesn't exist
1902
1914
  os.makedirs(output_directory, exist_ok=True)
1903
- image_files = create_multi_view_scene(meshes, output_directory=output_directory,
1915
+
1916
+ if show_views:
1917
+ image_files = create_multi_view_scene(meshes, output_directory=output_directory,
1904
1918
  projection_type=projection_type,
1905
1919
  distance_factor=distance_factor)
1906
1920
 
1907
- # Display each view separately
1908
- for view_name, img_file in image_files:
1909
- plt.figure(figsize=(24, 16))
1910
- img = plt.imread(img_file)
1911
- plt.imshow(img)
1912
- plt.title(view_name.replace('_', ' ').title(), pad=20)
1913
- plt.axis('off')
1914
- plt.show()
1915
- plt.close()
1921
+ # Display each view separately
1922
+ for view_name, img_file in image_files:
1923
+ plt.figure(figsize=(24, 16))
1924
+ img = plt.imread(img_file)
1925
+ plt.imshow(img)
1926
+ plt.title(view_name.replace('_', ' ').title(), pad=20)
1927
+ plt.axis('off')
1928
+ plt.show()
1929
+ plt.close()
1916
1930
 
1917
1931
  # After creating the meshes and before visualization
1918
1932
  if save_obj:
1919
1933
  output_directory = kwargs.get('output_directory', 'output')
1920
1934
  output_file_name = kwargs.get('output_file_name', 'voxcity_mesh')
1921
1935
  obj_path, mtl_path = save_obj_from_colored_mesh(meshes, output_directory, output_file_name)
1922
- print(f"Saved mesh files to:\n {obj_path}\n {mtl_path}")
1923
-
1924
- return image_files
1936
+ print(f"Saved mesh files to:\n {obj_path}\n {mtl_path}")
1925
1937
 
1926
1938
  def visualize_building_sim_results(voxel_array, meshsize, building_sim_mesh, **kwargs):
1927
1939
  """
@@ -1969,75 +1981,9 @@ def visualize_building_sim_results(voxel_array, meshsize, building_sim_mesh, **k
1969
1981
  kwargs["colorbar_title"] = pretty_name
1970
1982
 
1971
1983
  # Call the more general visualization function
1972
- return visualize_voxcity_with_sim_meshes(
1984
+ visualize_voxcity_with_sim_meshes(
1973
1985
  voxel_array,
1974
1986
  meshsize,
1975
1987
  custom_meshes=custom_meshes,
1976
1988
  **kwargs
1977
- )
1978
-
1979
- def save_obj_from_colored_mesh(meshes, output_path, base_filename):
1980
- """
1981
- Save colored meshes as OBJ and MTL files.
1982
-
1983
- Parameters
1984
- ----------
1985
- meshes : dict
1986
- Dictionary of trimesh.Trimesh objects with face colors.
1987
- output_path : str
1988
- Directory path where to save the files.
1989
- base_filename : str
1990
- Base name for the output files (without extension).
1991
-
1992
- Returns
1993
- -------
1994
- tuple
1995
- Paths to the saved (obj_file, mtl_file).
1996
- """
1997
-
1998
- os.makedirs(output_path, exist_ok=True)
1999
- obj_path = os.path.join(output_path, f"{base_filename}.obj")
2000
- mtl_path = os.path.join(output_path, f"{base_filename}.mtl")
2001
-
2002
- # Combine all meshes
2003
- combined_mesh = trimesh.util.concatenate(list(meshes.values()))
2004
-
2005
- # Create unique materials for each unique face color
2006
- face_colors = combined_mesh.visual.face_colors
2007
- unique_colors = np.unique(face_colors, axis=0)
2008
-
2009
- # Write MTL file
2010
- with open(mtl_path, 'w') as mtl_file:
2011
- for i, color in enumerate(unique_colors):
2012
- material_name = f'material_{i}'
2013
- mtl_file.write(f'newmtl {material_name}\n')
2014
- # Convert RGBA to RGB float values
2015
- rgb = color[:3].astype(float) / 255.0
2016
- mtl_file.write(f'Kd {rgb[0]:.6f} {rgb[1]:.6f} {rgb[2]:.6f}\n')
2017
- mtl_file.write(f'd {color[3]/255.0:.6f}\n\n') # Alpha value
2018
-
2019
- # Create material groups based on face colors
2020
- color_to_material = {tuple(c): f'material_{i}' for i, c in enumerate(unique_colors)}
2021
-
2022
- # Write OBJ file
2023
- with open(obj_path, 'w') as obj_file:
2024
- obj_file.write(f'mtllib {os.path.basename(mtl_path)}\n')
2025
-
2026
- # Write vertices
2027
- for vertex in combined_mesh.vertices:
2028
- obj_file.write(f'v {vertex[0]:.6f} {vertex[1]:.6f} {vertex[2]:.6f}\n')
2029
-
2030
- # Write faces grouped by material
2031
- current_material = None
2032
- for face_idx, face in enumerate(combined_mesh.faces):
2033
- face_color = tuple(face_colors[face_idx])
2034
- material_name = color_to_material[face_color]
2035
-
2036
- if material_name != current_material:
2037
- obj_file.write(f'usemtl {material_name}\n')
2038
- current_material = material_name
2039
-
2040
- # OBJ indices are 1-based
2041
- obj_file.write(f'f {face[0]+1} {face[1]+1} {face[2]+1}\n')
2042
-
2043
- return obj_path, mtl_path
1989
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voxcity
3
- Version: 0.5.9
3
+ Version: 0.5.11
4
4
  Summary: voxcity is an easy and one-stop tool to output 3d city models for microclimate simulation by integrating multiple geospatial open-data
5
5
  Author-email: Kunihiko Fujiwara <kunihiko@nus.edu.sg>
6
6
  Maintainer-email: Kunihiko Fujiwara <kunihiko@nus.edu.sg>
@@ -72,6 +72,10 @@ Dynamic: license-file
72
72
  Tutorial preview: <a href="https://colab.research.google.com/drive/1Lofd3RawKMr6QuUsamGaF48u2MN0hfrP?usp=sharing">[Google Colab]</a>
73
73
  </p>
74
74
 
75
+ <p align="center">
76
+ <img src="https://raw.githubusercontent.com/kunifujiwara/VoxCity/main/images/logo.png" alt="Voxcity logo" width="800">
77
+ </p>
78
+
75
79
  # VoxCity
76
80
 
77
81
  **voxcity** is a Python package that provides a seamless solution for grid-based 3D city model generation and urban simulation for cities worldwide. VoxCity's generator module automatically downloads building heights, tree canopy heights, land cover, and terrain elevation within a specified target area, and voxelizes buildings, trees, land cover, and terrain to generate an integrated voxel city model. The simulator module enables users to conduct environmental simulations, including solar radiation and view index analyses. Users can export the generated models using several file formats compatible with external software, such as ENVI-met (INX), Blender, and Rhino (OBJ). Try it out using the [Google Colab Demo](https://colab.research.google.com/drive/1Lofd3RawKMr6QuUsamGaF48u2MN0hfrP?usp=sharing) or your local environment.
@@ -1,5 +1,5 @@
1
1
  voxcity/__init__.py,sha256=el9v3gfybHOF_GUYPeSOqN0-vCrTW0eU1mcvi0sEfeU,252
2
- voxcity/generator.py,sha256=Ae0dAqfrVMLmjeilO2oOm5s-TMPbnLo40Z4TFJaWf5A,42651
2
+ voxcity/generator.py,sha256=qWe2LJsbY2_IYUuI99ZJ5_rRNJ8IQrEIdxND7azYd-M,47045
3
3
  voxcity/downloader/__init__.py,sha256=OgGcGxOXF4tjcEL6DhOnt13DYPTvOigUelp5xIpTqM0,171
4
4
  voxcity/downloader/citygml.py,sha256=R3DvsYJz_S5OPkeA71eEI2U7fBDLcpqdludV6gO1ihw,30305
5
5
  voxcity/downloader/eubucco.py,sha256=XCkkdEPNuWdrnuxzL80Ext37WsgiCiZGueb-aQV5rvI,14476
@@ -17,7 +17,7 @@ voxcity/exporter/obj.py,sha256=M0MT9UZOVYsRJBEJea3qg1uu7NsMXagD24jQnmPaJLo,21629
17
17
  voxcity/geoprocessor/__init_.py,sha256=JzPVhhttxBWvaZ0IGX2w7OWL5bCo_TIvpHefWeNXruA,133
18
18
  voxcity/geoprocessor/draw.py,sha256=8Em2NvazFpYfFJUqG9LofNXaxdghKLL_rNuztmPwn8Q,13911
19
19
  voxcity/geoprocessor/grid.py,sha256=NzUACYEtJ3Wc348ESo_N9VbaXPtSssuF_zad7BtDcmM,56389
20
- voxcity/geoprocessor/mesh.py,sha256=r3cRPLgpbhjwgESBemHWWJ5pEWl2KdkRhID6mdLhios,11171
20
+ voxcity/geoprocessor/mesh.py,sha256=FC0rgL1b8qYDlAwYwVMS0qcFwBTdqv-RFMw89sCnGOk,15124
21
21
  voxcity/geoprocessor/network.py,sha256=opb_kpUCAxDd1qtrWPStqR5reYZtVe96XxazNSen7Lk,18851
22
22
  voxcity/geoprocessor/polygon.py,sha256=8Vb2AbkpKYhq1kk2hQMc-gitmUo9pFIe910v4p1vP2g,37772
23
23
  voxcity/geoprocessor/utils.py,sha256=1BRHp-DDeOA8HG8jplY7Eo75G3oXkVGL6DGONL4BA8A,19815
@@ -28,11 +28,11 @@ voxcity/simulator/view.py,sha256=YufbLuDXrLg1d1dedM6pVyiJ7uHsqY8F2sLLnIoJvB4,749
28
28
  voxcity/utils/__init_.py,sha256=nLYrj2huBbDBNMqfchCwexGP8Tlt9O_XluVDG7MoFkw,98
29
29
  voxcity/utils/lc.py,sha256=RwPd-VY3POV3gTrBhM7TubgGb9MCd3nVah_G8iUEF7k,11562
30
30
  voxcity/utils/material.py,sha256=Vt3IID5Ft54HNJcEC4zi31BCPqi_687X3CSp7rXaRVY,5907
31
- voxcity/utils/visualization.py,sha256=ouDRx_KLm25P47CP3d85HTURYb6JdfT-N2frkSx24cU,88923
31
+ voxcity/utils/visualization.py,sha256=jsKfUoRRW0yRCmJ03I7ESK1Tic_Xk1tcliw-8syr3Y0,87228
32
32
  voxcity/utils/weather.py,sha256=CFPtoqRTajwMRswswDChwQ3BW1cGsnA3orgWHgz7Ehg,26304
33
- voxcity-0.5.9.dist-info/licenses/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
34
- voxcity-0.5.9.dist-info/licenses/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
35
- voxcity-0.5.9.dist-info/METADATA,sha256=GpcuAWPoYHjWeImnW62omaXsIbjpOlwijNWMDwd2_hM,25734
36
- voxcity-0.5.9.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
37
- voxcity-0.5.9.dist-info/top_level.txt,sha256=00b2U-LKfDllt6RL1R33MXie5MvxzUFye0NGD96t_8I,8
38
- voxcity-0.5.9.dist-info/RECORD,,
33
+ voxcity-0.5.11.dist-info/licenses/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
34
+ voxcity-0.5.11.dist-info/licenses/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
35
+ voxcity-0.5.11.dist-info/METADATA,sha256=hK1HErMdMRO_166kD7r3ZeGGT9pZq6Ok54PbcwpCYJA,25885
36
+ voxcity-0.5.11.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
37
+ voxcity-0.5.11.dist-info/top_level.txt,sha256=00b2U-LKfDllt6RL1R33MXie5MvxzUFye0NGD96t_8I,8
38
+ voxcity-0.5.11.dist-info/RECORD,,