voxcity 0.5.6__tar.gz → 0.5.8__tar.gz
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-0.5.6 → voxcity-0.5.8}/PKG-INFO +2 -2
- {voxcity-0.5.6 → voxcity-0.5.8}/pyproject.toml +2 -3
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/exporter/obj.py +2 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/grid.py +1 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/utils/visualization.py +92 -4
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity.egg-info/PKG-INFO +2 -2
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity.egg-info/requires.txt +1 -1
- {voxcity-0.5.6 → voxcity-0.5.8}/AUTHORS.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/CONTRIBUTING.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/HISTORY.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/LICENSE +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/MANIFEST.in +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/README.md +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/Makefile +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/archive/README.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/authors.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/conf.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/index.rst +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/docs/make.bat +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/setup.cfg +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/__init__.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/__init__.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/citygml.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/eubucco.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/gee.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/mbfp.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/oemj.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/omt.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/osm.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/overture.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/downloader/utils.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/exporter/__init_.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/exporter/envimet.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/exporter/magicavoxel.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/generator.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/__init_.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/draw.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/mesh.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/network.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/polygon.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/geoprocessor/utils.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/simulator/__init_.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/simulator/solar.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/simulator/utils.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/simulator/view.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/utils/__init_.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/utils/lc.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/utils/material.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity/utils/weather.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity.egg-info/SOURCES.txt +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity.egg-info/dependency_links.txt +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/src/voxcity.egg-info/top_level.txt +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/tests/__init__.py +0 -0
- {voxcity-0.5.6 → voxcity-0.5.8}/tests/voxelcity.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voxcity
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.8
|
|
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>
|
|
@@ -45,7 +45,7 @@ Requires-Dist: pycountry
|
|
|
45
45
|
Requires-Dist: osm2geojson
|
|
46
46
|
Requires-Dist: seaborn
|
|
47
47
|
Requires-Dist: overturemaps
|
|
48
|
-
Requires-Dist: protobuf
|
|
48
|
+
Requires-Dist: protobuf<6,>=4.21
|
|
49
49
|
Requires-Dist: timezonefinder
|
|
50
50
|
Requires-Dist: astral
|
|
51
51
|
Requires-Dist: osmnx
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "voxcity"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.8"
|
|
4
4
|
requires-python = ">=3.10,<3.13"
|
|
5
5
|
classifiers = [
|
|
6
6
|
"Programming Language :: Python :: 3.10",
|
|
@@ -47,7 +47,7 @@ dependencies = [
|
|
|
47
47
|
"osm2geojson",
|
|
48
48
|
"seaborn",
|
|
49
49
|
"overturemaps",
|
|
50
|
-
"protobuf
|
|
50
|
+
"protobuf>=4.21,<6",
|
|
51
51
|
"timezonefinder",
|
|
52
52
|
"astral",
|
|
53
53
|
"osmnx",
|
|
@@ -56,7 +56,6 @@ dependencies = [
|
|
|
56
56
|
"pyvista",
|
|
57
57
|
"IPython",
|
|
58
58
|
"lxml"
|
|
59
|
-
|
|
60
59
|
]
|
|
61
60
|
|
|
62
61
|
[project.optional-dependencies]
|
|
@@ -11,6 +11,7 @@ from pyproj import Geod, Transformer, CRS
|
|
|
11
11
|
import rasterio
|
|
12
12
|
from affine import Affine
|
|
13
13
|
from shapely.geometry import box, Polygon, Point, MultiPolygon
|
|
14
|
+
import warnings
|
|
14
15
|
|
|
15
16
|
from scipy.interpolate import griddata
|
|
16
17
|
from shapely.errors import GEOSException
|
|
@@ -43,6 +43,7 @@ from ..geoprocessor.mesh import (
|
|
|
43
43
|
create_city_meshes,
|
|
44
44
|
export_meshes
|
|
45
45
|
)
|
|
46
|
+
# from ..exporter.obj import save_obj_from_colored_mesh
|
|
46
47
|
from .material import get_material_dict
|
|
47
48
|
|
|
48
49
|
# def get_voxel_color_map():
|
|
@@ -74,6 +75,7 @@ from .material import get_material_dict
|
|
|
74
75
|
# 13: [150, 166, 190], # 'Building (ground surface)'
|
|
75
76
|
# 14: [239, 228, 176], # 'No Data (ground surface)'
|
|
76
77
|
# }
|
|
78
|
+
|
|
77
79
|
def get_voxel_color_map(color_scheme='default'):
|
|
78
80
|
"""
|
|
79
81
|
Returns a color map for voxel visualization based on the specified color scheme.
|
|
@@ -1528,6 +1530,7 @@ def visualize_voxcity_multi_view(voxel_array, meshsize, **kwargs):
|
|
|
1528
1530
|
vmax = kwargs.get("vmax", np.nanmax(sim_grid))
|
|
1529
1531
|
projection_type = kwargs.get("projection_type", "perspective")
|
|
1530
1532
|
distance_factor = kwargs.get("distance_factor", 1.0)
|
|
1533
|
+
save_obj = kwargs.get("save_obj", False)
|
|
1531
1534
|
|
|
1532
1535
|
# Create meshes
|
|
1533
1536
|
print("Creating voxel meshes...")
|
|
@@ -1579,6 +1582,13 @@ def visualize_voxcity_multi_view(voxel_array, meshsize, **kwargs):
|
|
|
1579
1582
|
plt.axis('off')
|
|
1580
1583
|
plt.show()
|
|
1581
1584
|
plt.close()
|
|
1585
|
+
|
|
1586
|
+
# After creating the meshes and before visualization
|
|
1587
|
+
if save_obj:
|
|
1588
|
+
output_directory = kwargs.get('output_directory', 'output')
|
|
1589
|
+
output_file_name = kwargs.get('output_file_name', 'voxcity_mesh')
|
|
1590
|
+
obj_path, mtl_path = save_obj_from_colored_mesh(meshes, output_directory, output_file_name)
|
|
1591
|
+
print(f"Saved mesh files to:\n {obj_path}\n {mtl_path}")
|
|
1582
1592
|
|
|
1583
1593
|
def visualize_voxcity_multi_view_with_multiple_sim_grids(voxel_array, meshsize, sim_configs, **kwargs):
|
|
1584
1594
|
"""
|
|
@@ -1610,7 +1620,9 @@ def visualize_voxcity_multi_view_with_multiple_sim_grids(voxel_array, meshsize,
|
|
|
1610
1620
|
# Configure PyVista settings
|
|
1611
1621
|
pv.set_plot_theme('document')
|
|
1612
1622
|
pv.global_theme.background = 'white'
|
|
1613
|
-
|
|
1623
|
+
window_width = kwargs.get("window_width", 1024)
|
|
1624
|
+
window_height = kwargs.get("window_height", 768)
|
|
1625
|
+
pv.global_theme.window_size = [window_width, window_height]
|
|
1614
1626
|
pv.global_theme.jupyter_backend = 'static'
|
|
1615
1627
|
|
|
1616
1628
|
# Parse general kwargs
|
|
@@ -1743,7 +1755,9 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
|
|
|
1743
1755
|
# Configure PyVista settings
|
|
1744
1756
|
pv.set_plot_theme('document')
|
|
1745
1757
|
pv.global_theme.background = 'white'
|
|
1746
|
-
|
|
1758
|
+
window_width = kwargs.get("window_width", 1024)
|
|
1759
|
+
window_height = kwargs.get("window_height", 768)
|
|
1760
|
+
pv.global_theme.window_size = [window_width, window_height]
|
|
1747
1761
|
pv.global_theme.jupyter_backend = 'static'
|
|
1748
1762
|
|
|
1749
1763
|
# Parse kwargs
|
|
@@ -1764,6 +1778,7 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
|
|
|
1764
1778
|
colorbar_title = kwargs.get("colorbar_title", "")
|
|
1765
1779
|
value_name = kwargs.get("value_name", None)
|
|
1766
1780
|
nan_color = kwargs.get("nan_color", "gray")
|
|
1781
|
+
save_obj = kwargs.get("save_obj", False)
|
|
1767
1782
|
|
|
1768
1783
|
if value_name is None:
|
|
1769
1784
|
print("Set value_name")
|
|
@@ -1891,7 +1906,7 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
|
|
|
1891
1906
|
|
|
1892
1907
|
# Display each view separately
|
|
1893
1908
|
for view_name, img_file in image_files:
|
|
1894
|
-
plt.figure(figsize=(
|
|
1909
|
+
plt.figure(figsize=(24, 16))
|
|
1895
1910
|
img = plt.imread(img_file)
|
|
1896
1911
|
plt.imshow(img)
|
|
1897
1912
|
plt.title(view_name.replace('_', ' ').title(), pad=20)
|
|
@@ -1899,6 +1914,13 @@ def visualize_voxcity_with_sim_meshes(voxel_array, meshsize, custom_meshes=None,
|
|
|
1899
1914
|
plt.show()
|
|
1900
1915
|
plt.close()
|
|
1901
1916
|
|
|
1917
|
+
# After creating the meshes and before visualization
|
|
1918
|
+
if save_obj:
|
|
1919
|
+
output_directory = kwargs.get('output_directory', 'output')
|
|
1920
|
+
output_file_name = kwargs.get('output_file_name', 'voxcity_mesh')
|
|
1921
|
+
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
|
+
|
|
1902
1924
|
return image_files
|
|
1903
1925
|
|
|
1904
1926
|
def visualize_building_sim_results(voxel_array, meshsize, building_sim_mesh, **kwargs):
|
|
@@ -1952,4 +1974,70 @@ def visualize_building_sim_results(voxel_array, meshsize, building_sim_mesh, **k
|
|
|
1952
1974
|
meshsize,
|
|
1953
1975
|
custom_meshes=custom_meshes,
|
|
1954
1976
|
**kwargs
|
|
1955
|
-
)
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voxcity
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.8
|
|
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>
|
|
@@ -45,7 +45,7 @@ Requires-Dist: pycountry
|
|
|
45
45
|
Requires-Dist: osm2geojson
|
|
46
46
|
Requires-Dist: seaborn
|
|
47
47
|
Requires-Dist: overturemaps
|
|
48
|
-
Requires-Dist: protobuf
|
|
48
|
+
Requires-Dist: protobuf<6,>=4.21
|
|
49
49
|
Requires-Dist: timezonefinder
|
|
50
50
|
Requires-Dist: astral
|
|
51
51
|
Requires-Dist: osmnx
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|