voxcity 0.7.0__py3-none-any.whl → 1.0.2__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 (42) hide show
  1. voxcity/__init__.py +14 -14
  2. voxcity/exporter/__init__.py +12 -12
  3. voxcity/exporter/cityles.py +633 -633
  4. voxcity/exporter/envimet.py +733 -728
  5. voxcity/exporter/magicavoxel.py +333 -333
  6. voxcity/exporter/netcdf.py +238 -238
  7. voxcity/exporter/obj.py +1480 -1480
  8. voxcity/generator/__init__.py +47 -44
  9. voxcity/generator/api.py +721 -675
  10. voxcity/generator/grids.py +381 -379
  11. voxcity/generator/io.py +94 -94
  12. voxcity/generator/pipeline.py +282 -282
  13. voxcity/generator/update.py +429 -0
  14. voxcity/generator/voxelizer.py +18 -6
  15. voxcity/geoprocessor/__init__.py +75 -75
  16. voxcity/geoprocessor/draw.py +1488 -1219
  17. voxcity/geoprocessor/merge_utils.py +91 -91
  18. voxcity/geoprocessor/mesh.py +806 -806
  19. voxcity/geoprocessor/network.py +708 -708
  20. voxcity/geoprocessor/raster/buildings.py +435 -428
  21. voxcity/geoprocessor/raster/export.py +93 -93
  22. voxcity/geoprocessor/raster/landcover.py +5 -2
  23. voxcity/geoprocessor/utils.py +824 -824
  24. voxcity/models.py +113 -113
  25. voxcity/simulator/solar/__init__.py +66 -43
  26. voxcity/simulator/solar/integration.py +336 -336
  27. voxcity/simulator/solar/sky.py +668 -0
  28. voxcity/simulator/solar/temporal.py +792 -434
  29. voxcity/utils/__init__.py +11 -0
  30. voxcity/utils/classes.py +194 -0
  31. voxcity/utils/lc.py +80 -39
  32. voxcity/utils/shape.py +230 -0
  33. voxcity/visualizer/__init__.py +24 -24
  34. voxcity/visualizer/builder.py +43 -43
  35. voxcity/visualizer/grids.py +141 -141
  36. voxcity/visualizer/maps.py +187 -187
  37. voxcity/visualizer/renderer.py +1145 -928
  38. {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/METADATA +90 -49
  39. {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/RECORD +42 -38
  40. {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/WHEEL +0 -0
  41. {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/licenses/AUTHORS.rst +0 -0
  42. {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/licenses/LICENSE +0 -0
voxcity/generator/io.py CHANGED
@@ -1,94 +1,94 @@
1
- def save_voxcity_data(output_path, voxcity_grid, building_height_grid, building_min_height_grid,
2
- building_id_grid, canopy_height_grid, land_cover_grid, dem_grid,
3
- building_gdf, meshsize, rectangle_vertices):
4
- import pickle
5
- import os
6
-
7
- os.makedirs(os.path.dirname(output_path), exist_ok=True)
8
-
9
- data_dict = {
10
- 'voxcity_grid': voxcity_grid,
11
- 'building_height_grid': building_height_grid,
12
- 'building_min_height_grid': building_min_height_grid,
13
- 'building_id_grid': building_id_grid,
14
- 'canopy_height_grid': canopy_height_grid,
15
- 'land_cover_grid': land_cover_grid,
16
- 'dem_grid': dem_grid,
17
- 'building_gdf': building_gdf,
18
- 'meshsize': meshsize,
19
- 'rectangle_vertices': rectangle_vertices
20
- }
21
-
22
- with open(output_path, 'wb') as f:
23
- pickle.dump(data_dict, f)
24
-
25
- print(f"Voxcity data saved to {output_path}")
26
-
27
-
28
- def load_voxcity(input_path):
29
- import pickle
30
- import numpy as np
31
- from ..models import GridMetadata, VoxelGrid, BuildingGrid, LandCoverGrid, DemGrid, CanopyGrid, VoxCity
32
-
33
- with open(input_path, 'rb') as f:
34
- obj = pickle.load(f)
35
-
36
- # New format: the entire VoxCity object (optionally wrapped)
37
- if isinstance(obj, VoxCity):
38
- return obj
39
- if isinstance(obj, dict) and obj.get('__format__') == 'voxcity.v2' and isinstance(obj.get('voxcity'), VoxCity):
40
- return obj['voxcity']
41
-
42
- # Legacy dict format fallback
43
- d = obj
44
- rv = d.get('rectangle_vertices') or []
45
- if rv:
46
- xs = [p[0] for p in rv]
47
- ys = [p[1] for p in rv]
48
- bounds = (min(xs), min(ys), max(xs), max(ys))
49
- else:
50
- ny, nx = d['land_cover_grid'].shape
51
- ms = float(d['meshsize'])
52
- bounds = (0.0, 0.0, nx * ms, ny * ms)
53
-
54
- meta = GridMetadata(crs='EPSG:4326', bounds=bounds, meshsize=float(d['meshsize']))
55
-
56
- voxels = VoxelGrid(classes=d['voxcity_grid'], meta=meta)
57
- buildings = BuildingGrid(
58
- heights=d['building_height_grid'],
59
- min_heights=d['building_min_height_grid'],
60
- ids=d['building_id_grid'],
61
- meta=meta,
62
- )
63
- land = LandCoverGrid(classes=d['land_cover_grid'], meta=meta)
64
- dem = DemGrid(elevation=d['dem_grid'], meta=meta)
65
- canopy = CanopyGrid(top=d.get('canopy_height_grid'), bottom=None, meta=meta)
66
-
67
- extras = {
68
- 'rectangle_vertices': d.get('rectangle_vertices'),
69
- 'building_gdf': d.get('building_gdf'),
70
- }
71
-
72
- return VoxCity(voxels=voxels, buildings=buildings, land_cover=land, dem=dem, tree_canopy=canopy, extras=extras)
73
-
74
-
75
-
76
- def save_voxcity(output_path, city):
77
- """Save a VoxCity instance to disk, preserving the entire object."""
78
- import pickle
79
- import os
80
- from ..models import VoxCity as _VoxCity
81
-
82
- if not isinstance(city, _VoxCity):
83
- raise TypeError("save_voxcity expects a VoxCity instance")
84
-
85
- os.makedirs(os.path.dirname(output_path), exist_ok=True)
86
-
87
- with open(output_path, 'wb') as f:
88
- payload = {
89
- '__format__': 'voxcity.v2',
90
- 'voxcity': city,
91
- }
92
- pickle.dump(payload, f)
93
-
94
- print(f"Voxcity data saved to {output_path}")
1
+ def save_voxcity_data(output_path, voxcity_grid, building_height_grid, building_min_height_grid,
2
+ building_id_grid, canopy_height_grid, land_cover_grid, dem_grid,
3
+ building_gdf, meshsize, rectangle_vertices):
4
+ import pickle
5
+ import os
6
+
7
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
8
+
9
+ data_dict = {
10
+ 'voxcity_grid': voxcity_grid,
11
+ 'building_height_grid': building_height_grid,
12
+ 'building_min_height_grid': building_min_height_grid,
13
+ 'building_id_grid': building_id_grid,
14
+ 'canopy_height_grid': canopy_height_grid,
15
+ 'land_cover_grid': land_cover_grid,
16
+ 'dem_grid': dem_grid,
17
+ 'building_gdf': building_gdf,
18
+ 'meshsize': meshsize,
19
+ 'rectangle_vertices': rectangle_vertices
20
+ }
21
+
22
+ with open(output_path, 'wb') as f:
23
+ pickle.dump(data_dict, f)
24
+
25
+ print(f"Voxcity data saved to {output_path}")
26
+
27
+
28
+ def load_voxcity(input_path):
29
+ import pickle
30
+ import numpy as np
31
+ from ..models import GridMetadata, VoxelGrid, BuildingGrid, LandCoverGrid, DemGrid, CanopyGrid, VoxCity
32
+
33
+ with open(input_path, 'rb') as f:
34
+ obj = pickle.load(f)
35
+
36
+ # New format: the entire VoxCity object (optionally wrapped)
37
+ if isinstance(obj, VoxCity):
38
+ return obj
39
+ if isinstance(obj, dict) and obj.get('__format__') == 'voxcity.v2' and isinstance(obj.get('voxcity'), VoxCity):
40
+ return obj['voxcity']
41
+
42
+ # Legacy dict format fallback
43
+ d = obj
44
+ rv = d.get('rectangle_vertices') or []
45
+ if rv:
46
+ xs = [p[0] for p in rv]
47
+ ys = [p[1] for p in rv]
48
+ bounds = (min(xs), min(ys), max(xs), max(ys))
49
+ else:
50
+ ny, nx = d['land_cover_grid'].shape
51
+ ms = float(d['meshsize'])
52
+ bounds = (0.0, 0.0, nx * ms, ny * ms)
53
+
54
+ meta = GridMetadata(crs='EPSG:4326', bounds=bounds, meshsize=float(d['meshsize']))
55
+
56
+ voxels = VoxelGrid(classes=d['voxcity_grid'], meta=meta)
57
+ buildings = BuildingGrid(
58
+ heights=d['building_height_grid'],
59
+ min_heights=d['building_min_height_grid'],
60
+ ids=d['building_id_grid'],
61
+ meta=meta,
62
+ )
63
+ land = LandCoverGrid(classes=d['land_cover_grid'], meta=meta)
64
+ dem = DemGrid(elevation=d['dem_grid'], meta=meta)
65
+ canopy = CanopyGrid(top=d.get('canopy_height_grid'), bottom=None, meta=meta)
66
+
67
+ extras = {
68
+ 'rectangle_vertices': d.get('rectangle_vertices'),
69
+ 'building_gdf': d.get('building_gdf'),
70
+ }
71
+
72
+ return VoxCity(voxels=voxels, buildings=buildings, land_cover=land, dem=dem, tree_canopy=canopy, extras=extras)
73
+
74
+
75
+
76
+ def save_voxcity(output_path, city):
77
+ """Save a VoxCity instance to disk, preserving the entire object."""
78
+ import pickle
79
+ import os
80
+ from ..models import VoxCity as _VoxCity
81
+
82
+ if not isinstance(city, _VoxCity):
83
+ raise TypeError("save_voxcity expects a VoxCity instance")
84
+
85
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
86
+
87
+ with open(output_path, 'wb') as f:
88
+ payload = {
89
+ '__format__': 'voxcity.v2',
90
+ 'voxcity': city,
91
+ }
92
+ pickle.dump(payload, f)
93
+
94
+ print(f"Voxcity data saved to {output_path}")