voxcity 0.7.0__py3-none-any.whl → 1.0.13__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.
Files changed (81) hide show
  1. voxcity/__init__.py +14 -14
  2. voxcity/downloader/ocean.py +559 -0
  3. voxcity/exporter/__init__.py +12 -12
  4. voxcity/exporter/cityles.py +633 -633
  5. voxcity/exporter/envimet.py +733 -728
  6. voxcity/exporter/magicavoxel.py +333 -333
  7. voxcity/exporter/netcdf.py +238 -238
  8. voxcity/exporter/obj.py +1480 -1480
  9. voxcity/generator/__init__.py +47 -44
  10. voxcity/generator/api.py +727 -675
  11. voxcity/generator/grids.py +394 -379
  12. voxcity/generator/io.py +94 -94
  13. voxcity/generator/pipeline.py +582 -282
  14. voxcity/generator/update.py +429 -0
  15. voxcity/generator/voxelizer.py +18 -6
  16. voxcity/geoprocessor/__init__.py +75 -75
  17. voxcity/geoprocessor/draw.py +1494 -1219
  18. voxcity/geoprocessor/merge_utils.py +91 -91
  19. voxcity/geoprocessor/mesh.py +806 -806
  20. voxcity/geoprocessor/network.py +708 -708
  21. voxcity/geoprocessor/raster/__init__.py +2 -0
  22. voxcity/geoprocessor/raster/buildings.py +435 -428
  23. voxcity/geoprocessor/raster/core.py +31 -0
  24. voxcity/geoprocessor/raster/export.py +93 -93
  25. voxcity/geoprocessor/raster/landcover.py +178 -51
  26. voxcity/geoprocessor/raster/raster.py +1 -1
  27. voxcity/geoprocessor/utils.py +824 -824
  28. voxcity/models.py +115 -113
  29. voxcity/simulator/solar/__init__.py +66 -43
  30. voxcity/simulator/solar/integration.py +336 -336
  31. voxcity/simulator/solar/sky.py +668 -0
  32. voxcity/simulator/solar/temporal.py +792 -434
  33. voxcity/simulator_gpu/__init__.py +115 -0
  34. voxcity/simulator_gpu/common/__init__.py +9 -0
  35. voxcity/simulator_gpu/common/geometry.py +11 -0
  36. voxcity/simulator_gpu/core.py +322 -0
  37. voxcity/simulator_gpu/domain.py +262 -0
  38. voxcity/simulator_gpu/environment.yml +11 -0
  39. voxcity/simulator_gpu/init_taichi.py +154 -0
  40. voxcity/simulator_gpu/integration.py +15 -0
  41. voxcity/simulator_gpu/kernels.py +56 -0
  42. voxcity/simulator_gpu/radiation.py +28 -0
  43. voxcity/simulator_gpu/raytracing.py +623 -0
  44. voxcity/simulator_gpu/sky.py +9 -0
  45. voxcity/simulator_gpu/solar/__init__.py +178 -0
  46. voxcity/simulator_gpu/solar/core.py +66 -0
  47. voxcity/simulator_gpu/solar/csf.py +1249 -0
  48. voxcity/simulator_gpu/solar/domain.py +561 -0
  49. voxcity/simulator_gpu/solar/epw.py +421 -0
  50. voxcity/simulator_gpu/solar/integration.py +2953 -0
  51. voxcity/simulator_gpu/solar/radiation.py +3019 -0
  52. voxcity/simulator_gpu/solar/raytracing.py +686 -0
  53. voxcity/simulator_gpu/solar/reflection.py +533 -0
  54. voxcity/simulator_gpu/solar/sky.py +907 -0
  55. voxcity/simulator_gpu/solar/solar.py +337 -0
  56. voxcity/simulator_gpu/solar/svf.py +446 -0
  57. voxcity/simulator_gpu/solar/volumetric.py +1151 -0
  58. voxcity/simulator_gpu/solar/voxcity.py +2953 -0
  59. voxcity/simulator_gpu/temporal.py +13 -0
  60. voxcity/simulator_gpu/utils.py +25 -0
  61. voxcity/simulator_gpu/view.py +32 -0
  62. voxcity/simulator_gpu/visibility/__init__.py +109 -0
  63. voxcity/simulator_gpu/visibility/geometry.py +278 -0
  64. voxcity/simulator_gpu/visibility/integration.py +808 -0
  65. voxcity/simulator_gpu/visibility/landmark.py +753 -0
  66. voxcity/simulator_gpu/visibility/view.py +944 -0
  67. voxcity/utils/__init__.py +11 -0
  68. voxcity/utils/classes.py +194 -0
  69. voxcity/utils/lc.py +80 -39
  70. voxcity/utils/shape.py +230 -0
  71. voxcity/visualizer/__init__.py +24 -24
  72. voxcity/visualizer/builder.py +43 -43
  73. voxcity/visualizer/grids.py +141 -141
  74. voxcity/visualizer/maps.py +187 -187
  75. voxcity/visualizer/renderer.py +1146 -928
  76. {voxcity-0.7.0.dist-info → voxcity-1.0.13.dist-info}/METADATA +56 -52
  77. voxcity-1.0.13.dist-info/RECORD +116 -0
  78. voxcity-0.7.0.dist-info/RECORD +0 -77
  79. {voxcity-0.7.0.dist-info → voxcity-1.0.13.dist-info}/WHEEL +0 -0
  80. {voxcity-0.7.0.dist-info → voxcity-1.0.13.dist-info}/licenses/AUTHORS.rst +0 -0
  81. {voxcity-0.7.0.dist-info → voxcity-1.0.13.dist-info}/licenses/LICENSE +0 -0
voxcity/models.py CHANGED
@@ -1,113 +1,115 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass, field
4
- from typing import Tuple, Optional, Dict, Any
5
-
6
- import numpy as np
7
-
8
-
9
- @dataclass
10
- class GridMetadata:
11
- crs: str
12
- bounds: Tuple[float, float, float, float]
13
- meshsize: float
14
-
15
-
16
- @dataclass
17
- class BuildingGrid:
18
- heights: np.ndarray
19
- min_heights: np.ndarray # object-dtype array of lists per cell
20
- ids: np.ndarray
21
- meta: GridMetadata
22
-
23
-
24
- @dataclass
25
- class LandCoverGrid:
26
- classes: np.ndarray
27
- meta: GridMetadata
28
-
29
-
30
- @dataclass
31
- class DemGrid:
32
- elevation: np.ndarray
33
- meta: GridMetadata
34
-
35
-
36
- @dataclass
37
- class VoxelGrid:
38
- classes: np.ndarray
39
- meta: GridMetadata
40
-
41
-
42
- @dataclass
43
- class CanopyGrid:
44
- top: np.ndarray
45
- meta: GridMetadata
46
- bottom: Optional[np.ndarray] = None
47
-
48
-
49
- @dataclass
50
- class VoxCity:
51
- voxels: VoxelGrid
52
- buildings: BuildingGrid
53
- land_cover: LandCoverGrid
54
- dem: DemGrid
55
- tree_canopy: CanopyGrid
56
- extras: Dict[str, Any] = field(default_factory=dict)
57
-
58
-
59
- @dataclass
60
- class PipelineConfig:
61
- rectangle_vertices: Any
62
- meshsize: float
63
- building_source: Optional[str] = None
64
- land_cover_source: Optional[str] = None
65
- canopy_height_source: Optional[str] = None
66
- dem_source: Optional[str] = None
67
- output_dir: str = "output"
68
- trunk_height_ratio: Optional[float] = None
69
- static_tree_height: Optional[float] = None
70
- remove_perimeter_object: Optional[float] = None
71
- mapvis: bool = False
72
- gridvis: bool = True
73
- # Structured options for strategies and I/O/visualization
74
- land_cover_options: Dict[str, Any] = field(default_factory=dict)
75
- building_options: Dict[str, Any] = field(default_factory=dict)
76
- canopy_options: Dict[str, Any] = field(default_factory=dict)
77
- dem_options: Dict[str, Any] = field(default_factory=dict)
78
- io_options: Dict[str, Any] = field(default_factory=dict)
79
- visualize_options: Dict[str, Any] = field(default_factory=dict)
80
-
81
-
82
- # -----------------------------
83
- # Mesh data structures
84
- # -----------------------------
85
-
86
- @dataclass
87
- class MeshModel:
88
- vertices: np.ndarray # (N, 3) float
89
- faces: np.ndarray # (M, 3|4) int
90
- colors: Optional[np.ndarray] = None # (M, 4) uint8 or None
91
- name: Optional[str] = None
92
-
93
-
94
- @dataclass
95
- class MeshCollection:
96
- """Container for named meshes with simple add/access helpers."""
97
- meshes: Dict[str, MeshModel] = field(default_factory=dict)
98
-
99
- def add(self, name: str, mesh: MeshModel) -> None:
100
- self.meshes[name] = mesh
101
-
102
- def get(self, name: str) -> Optional[MeshModel]:
103
- return self.meshes.get(name)
104
-
105
- def __iter__(self):
106
- return iter(self.meshes.items())
107
-
108
- # Compatibility: some renderers expect `collection.items.items()`
109
- @property
110
- def items(self) -> Dict[str, MeshModel]:
111
- return self.meshes
112
-
113
-
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Tuple, Optional, Dict, Any
5
+
6
+ import numpy as np
7
+
8
+
9
+ @dataclass
10
+ class GridMetadata:
11
+ crs: str
12
+ bounds: Tuple[float, float, float, float]
13
+ meshsize: float
14
+
15
+
16
+ @dataclass
17
+ class BuildingGrid:
18
+ heights: np.ndarray
19
+ min_heights: np.ndarray # object-dtype array of lists per cell
20
+ ids: np.ndarray
21
+ meta: GridMetadata
22
+
23
+
24
+ @dataclass
25
+ class LandCoverGrid:
26
+ classes: np.ndarray
27
+ meta: GridMetadata
28
+
29
+
30
+ @dataclass
31
+ class DemGrid:
32
+ elevation: np.ndarray
33
+ meta: GridMetadata
34
+
35
+
36
+ @dataclass
37
+ class VoxelGrid:
38
+ classes: np.ndarray
39
+ meta: GridMetadata
40
+
41
+
42
+ @dataclass
43
+ class CanopyGrid:
44
+ top: np.ndarray
45
+ meta: GridMetadata
46
+ bottom: Optional[np.ndarray] = None
47
+
48
+
49
+ @dataclass
50
+ class VoxCity:
51
+ voxels: VoxelGrid
52
+ buildings: BuildingGrid
53
+ land_cover: LandCoverGrid
54
+ dem: DemGrid
55
+ tree_canopy: CanopyGrid
56
+ extras: Dict[str, Any] = field(default_factory=dict)
57
+
58
+
59
+ @dataclass
60
+ class PipelineConfig:
61
+ rectangle_vertices: Any
62
+ meshsize: float
63
+ building_source: Optional[str] = None
64
+ land_cover_source: Optional[str] = None
65
+ canopy_height_source: Optional[str] = None
66
+ dem_source: Optional[str] = None
67
+ output_dir: str = "output"
68
+ trunk_height_ratio: Optional[float] = None
69
+ static_tree_height: Optional[float] = None
70
+ remove_perimeter_object: Optional[float] = None
71
+ mapvis: bool = False
72
+ gridvis: bool = True
73
+ # Parallel download mode: if True, downloads run concurrently using ThreadPoolExecutor
74
+ parallel_download: bool = False
75
+ # Structured options for strategies and I/O/visualization
76
+ land_cover_options: Dict[str, Any] = field(default_factory=dict)
77
+ building_options: Dict[str, Any] = field(default_factory=dict)
78
+ canopy_options: Dict[str, Any] = field(default_factory=dict)
79
+ dem_options: Dict[str, Any] = field(default_factory=dict)
80
+ io_options: Dict[str, Any] = field(default_factory=dict)
81
+ visualize_options: Dict[str, Any] = field(default_factory=dict)
82
+
83
+
84
+ # -----------------------------
85
+ # Mesh data structures
86
+ # -----------------------------
87
+
88
+ @dataclass
89
+ class MeshModel:
90
+ vertices: np.ndarray # (N, 3) float
91
+ faces: np.ndarray # (M, 3|4) int
92
+ colors: Optional[np.ndarray] = None # (M, 4) uint8 or None
93
+ name: Optional[str] = None
94
+
95
+
96
+ @dataclass
97
+ class MeshCollection:
98
+ """Container for named meshes with simple add/access helpers."""
99
+ meshes: Dict[str, MeshModel] = field(default_factory=dict)
100
+
101
+ def add(self, name: str, mesh: MeshModel) -> None:
102
+ self.meshes[name] = mesh
103
+
104
+ def get(self, name: str) -> Optional[MeshModel]:
105
+ return self.meshes.get(name)
106
+
107
+ def __iter__(self):
108
+ return iter(self.meshes.items())
109
+
110
+ # Compatibility: some renderers expect `collection.items.items()`
111
+ @property
112
+ def items(self) -> Dict[str, MeshModel]:
113
+ return self.meshes
114
+
115
+
@@ -1,43 +1,66 @@
1
- """
2
- Solar Irradiance Simulation Package
3
-
4
- Public API exports for the refactored solar simulator. The implementation
5
- is decomposed into focused stages:
6
- 1) kernels.py - Low-level kernels for visibility/irradiance
7
- 2) radiation.py - Physics: convert geometry to irradiance
8
- 3) temporal.py - Time-series integration and solar position
9
- 4) integration.py- High-level workflows and I/O
10
- """
11
-
12
- # Stage 1: Kernels / Solar position
13
- from .kernels import ( # noqa: F401
14
- compute_direct_solar_irradiance_map_binary,
15
- )
16
- from .temporal import ( # noqa: F401
17
- get_solar_positions_astral,
18
- )
19
-
20
- # Stage 2: Radiation
21
- from .radiation import ( # noqa: F401
22
- get_direct_solar_irradiance_map,
23
- get_diffuse_solar_irradiance_map,
24
- get_global_solar_irradiance_map,
25
- compute_solar_irradiance_for_all_faces,
26
- get_building_solar_irradiance,
27
- )
28
-
29
- # Stage 3: Temporal
30
- from .temporal import ( # noqa: F401
31
- get_cumulative_global_solar_irradiance,
32
- get_cumulative_building_solar_irradiance,
33
- _configure_num_threads,
34
- _auto_time_batch_size,
35
- )
36
-
37
- # Stage 4: Integration
38
- from .integration import ( # noqa: F401
39
- get_global_solar_irradiance_using_epw,
40
- get_building_global_solar_irradiance_using_epw,
41
- save_irradiance_mesh,
42
- load_irradiance_mesh,
43
- )
1
+ """
2
+ Solar Irradiance Simulation Package
3
+
4
+ Public API exports for the refactored solar simulator. The implementation
5
+ is decomposed into focused stages:
6
+ 1) kernels.py - Low-level kernels for visibility/irradiance
7
+ 2) radiation.py - Physics: convert geometry to irradiance
8
+ 3) temporal.py - Time-series integration and solar position
9
+ 4) integration.py- High-level workflows and I/O
10
+ 5) sky.py - Sky hemisphere discretization methods
11
+ """
12
+
13
+ # Stage 1: Kernels / Solar position
14
+ from .kernels import ( # noqa: F401
15
+ compute_direct_solar_irradiance_map_binary,
16
+ )
17
+ from .temporal import ( # noqa: F401
18
+ get_solar_positions_astral,
19
+ )
20
+
21
+ # Sky discretization methods
22
+ from .sky import ( # noqa: F401
23
+ # Tregenza (145 patches)
24
+ generate_tregenza_patches,
25
+ get_tregenza_patch_index,
26
+ get_tregenza_patch_index_fast,
27
+ TREGENZA_BANDS,
28
+ TREGENZA_BAND_BOUNDARIES,
29
+ # Reinhart (subdivided Tregenza)
30
+ generate_reinhart_patches,
31
+ # Uniform grid
32
+ generate_uniform_grid_patches,
33
+ # Fibonacci spiral
34
+ generate_fibonacci_patches,
35
+ # Sun position binning
36
+ bin_sun_positions_to_patches,
37
+ bin_sun_positions_to_tregenza_fast,
38
+ # Utilities
39
+ get_patch_info,
40
+ visualize_sky_patches,
41
+ )
42
+
43
+ # Stage 2: Radiation
44
+ from .radiation import ( # noqa: F401
45
+ get_direct_solar_irradiance_map,
46
+ get_diffuse_solar_irradiance_map,
47
+ get_global_solar_irradiance_map,
48
+ compute_solar_irradiance_for_all_faces,
49
+ get_building_solar_irradiance,
50
+ )
51
+
52
+ # Stage 3: Temporal
53
+ from .temporal import ( # noqa: F401
54
+ get_cumulative_global_solar_irradiance,
55
+ get_cumulative_building_solar_irradiance,
56
+ _configure_num_threads,
57
+ _auto_time_batch_size,
58
+ )
59
+
60
+ # Stage 4: Integration
61
+ from .integration import ( # noqa: F401
62
+ get_global_solar_irradiance_using_epw,
63
+ get_building_global_solar_irradiance_using_epw,
64
+ save_irradiance_mesh,
65
+ load_irradiance_mesh,
66
+ )