voxcity 0.6.17__tar.gz → 0.6.19__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.

Files changed (39) hide show
  1. {voxcity-0.6.17 → voxcity-0.6.19}/PKG-INFO +7 -3
  2. {voxcity-0.6.17 → voxcity-0.6.19}/README.md +1 -1
  3. {voxcity-0.6.17 → voxcity-0.6.19}/pyproject.toml +3 -1
  4. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/exporter/__init__.py +2 -1
  5. voxcity-0.6.19/src/voxcity/exporter/netcdf.py +211 -0
  6. voxcity-0.6.19/src/voxcity/exporter/obj.py +1406 -0
  7. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/utils/visualization.py +31 -0
  8. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/utils/weather.py +209 -50
  9. voxcity-0.6.17/src/voxcity/exporter/obj.py +0 -655
  10. {voxcity-0.6.17 → voxcity-0.6.19}/AUTHORS.rst +0 -0
  11. {voxcity-0.6.17 → voxcity-0.6.19}/LICENSE +0 -0
  12. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/__init__.py +0 -0
  13. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/__init__.py +0 -0
  14. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/citygml.py +0 -0
  15. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/eubucco.py +0 -0
  16. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/gee.py +0 -0
  17. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/mbfp.py +0 -0
  18. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/oemj.py +0 -0
  19. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/osm.py +0 -0
  20. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/overture.py +0 -0
  21. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/downloader/utils.py +0 -0
  22. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/exporter/cityles.py +0 -0
  23. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/exporter/envimet.py +0 -0
  24. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/exporter/magicavoxel.py +0 -0
  25. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/generator.py +0 -0
  26. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/__init__.py +0 -0
  27. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/draw.py +0 -0
  28. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/grid.py +0 -0
  29. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/mesh.py +0 -0
  30. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/network.py +0 -0
  31. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/polygon.py +0 -0
  32. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/geoprocessor/utils.py +0 -0
  33. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/simulator/__init__.py +0 -0
  34. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/simulator/solar.py +0 -0
  35. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/simulator/utils.py +0 -0
  36. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/simulator/view.py +0 -0
  37. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/utils/__init__.py +0 -0
  38. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/utils/lc.py +0 -0
  39. {voxcity-0.6.17 → voxcity-0.6.19}/src/voxcity/utils/material.py +0 -0
@@ -1,8 +1,10 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: voxcity
3
- Version: 0.6.17
3
+ Version: 0.6.19
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
  License: MIT
6
+ License-File: AUTHORS.rst
7
+ License-File: LICENSE
6
8
  Author: Kunihiko Fujiwara
7
9
  Author-email: fujiwara.kunihiko@takenaka.co.jp
8
10
  Maintainer: Kunihiko Fujiwara
@@ -27,6 +29,7 @@ Requires-Dist: ipyleaflet
27
29
  Requires-Dist: joblib
28
30
  Requires-Dist: lxml
29
31
  Requires-Dist: matplotlib
32
+ Requires-Dist: netCDF4
30
33
  Requires-Dist: numba
31
34
  Requires-Dist: numpy
32
35
  Requires-Dist: osmnx
@@ -51,6 +54,7 @@ Requires-Dist: timezonefinder
51
54
  Requires-Dist: tqdm
52
55
  Requires-Dist: trimesh
53
56
  Requires-Dist: typer
57
+ Requires-Dist: xarray
54
58
  Project-URL: bugs, https://github.com/kunifujiwara/voxcity/issues
55
59
  Project-URL: changelog, https://github.com/kunifujiwara/voxcity/blob/master/changelog.md
56
60
  Project-URL: homepage, https://github.com/kunifujiwara/voxcity
@@ -232,7 +236,7 @@ Generate voxel data grids and corresponding building geoJSON:
232
236
  from voxcity.generator import get_voxcity
233
237
 
234
238
  voxcity_grid, building_height_grid, building_min_height_grid, \
235
- building_id_grid, canopy_height_grid, land_cover_grid, dem_grid, \
239
+ building_id_grid, canopy_height_grid, canopy_bottom_height_grid, land_cover_grid, dem_grid, \
236
240
  building_gdf = get_voxcity(
237
241
  rectangle_vertices,
238
242
  building_source,
@@ -174,7 +174,7 @@ Generate voxel data grids and corresponding building geoJSON:
174
174
  from voxcity.generator import get_voxcity
175
175
 
176
176
  voxcity_grid, building_height_grid, building_min_height_grid, \
177
- building_id_grid, canopy_height_grid, land_cover_grid, dem_grid, \
177
+ building_id_grid, canopy_height_grid, canopy_bottom_height_grid, land_cover_grid, dem_grid, \
178
178
  building_gdf = get_voxcity(
179
179
  rectangle_vertices,
180
180
  building_source,
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "voxcity"
3
- version = "0.6.17"
3
+ version = "0.6.19"
4
4
  description = "voxcity is an easy and one-stop tool to output 3d city models for microclimate simulation by integrating multiple geospatial open-data"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -56,6 +56,8 @@ pyvista = "*"
56
56
  IPython = "*"
57
57
  lxml = "*"
58
58
  scikit-learn = "*"
59
+ xarray = "*"
60
+ netCDF4 = "*"
59
61
 
60
62
  [tool.poetry.group.dev.dependencies]
61
63
  coverage = "*"
@@ -1,4 +1,5 @@
1
1
  from .envimet import *
2
2
  from .magicavoxel import *
3
3
  from .obj import *
4
- from .cityles import *
4
+ from .cityles import *
5
+ from .netcdf import *
@@ -0,0 +1,211 @@
1
+ """
2
+ NetCDF export utilities for VoxCity.
3
+
4
+ This module provides functions to convert a 3D voxel grid produced by
5
+ `voxcity.generator.get_voxcity` into a NetCDF file for portable storage
6
+ and downstream analysis.
7
+
8
+ The voxel values follow VoxCity conventions (see generator.create_3d_voxel):
9
+ - -3: built structures (buildings)
10
+ - -2: vegetation canopy
11
+ - -1: subsurface/underground
12
+ - >= 1: ground-surface land cover code (offset by +1 from source classes)
13
+
14
+ Notes
15
+ -----
16
+ - This writer prefers xarray for NetCDF export. If xarray is not installed,
17
+ a clear error is raised with installation hints.
18
+ - Coordinates are stored as index-based distances in meters from the grid
19
+ origin along the y, x, and z axes. Geographic metadata such as the
20
+ `rectangle_vertices` and `meshsize_m` are stored as global attributes to
21
+ avoid making assumptions about map projection or geodesic conversions.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from pathlib import Path
27
+ from typing import Any, Dict, Mapping, MutableMapping, Optional, Sequence, Tuple
28
+ import json
29
+
30
+ import numpy as np
31
+
32
+ try: # xarray is the preferred backend for NetCDF writing
33
+ import xarray as xr # type: ignore
34
+ XR_AVAILABLE = True
35
+ except Exception: # pragma: no cover - optional dependency
36
+ XR_AVAILABLE = False
37
+
38
+ __all__ = [
39
+ "voxel_to_xarray_dataset",
40
+ "save_voxel_netcdf",
41
+ ]
42
+
43
+
44
+ def _ensure_parent_dir(path: Path) -> None:
45
+ path.parent.mkdir(parents=True, exist_ok=True)
46
+
47
+
48
+ def voxel_to_xarray_dataset(
49
+ voxcity_grid: np.ndarray,
50
+ voxel_size_m: float,
51
+ rectangle_vertices: Optional[Sequence[Tuple[float, float]]] = None,
52
+ extra_attrs: Optional[Mapping[str, Any]] = None,
53
+ ) -> "xr.Dataset":
54
+ """Create an xarray Dataset from a VoxCity voxel grid.
55
+
56
+ Parameters
57
+ ----------
58
+ voxcity_grid
59
+ 3D numpy array with shape (rows, cols, levels) as returned by
60
+ `get_voxcity` (first element of the returned tuple).
61
+ voxel_size_m
62
+ Voxel size (mesh size) in meters.
63
+ rectangle_vertices
64
+ Optional polygon vertices defining the area of interest in
65
+ longitude/latitude pairs, typically the same list passed to
66
+ `get_voxcity`.
67
+ extra_attrs
68
+ Optional mapping of additional global attributes to store in the
69
+ dataset.
70
+
71
+ Returns
72
+ -------
73
+ xr.Dataset
74
+ Dataset containing one DataArray named "voxels" with dims (y, x, z)
75
+ and coordinate variables in meters from origin.
76
+ """
77
+ if not XR_AVAILABLE: # pragma: no cover - optional dependency
78
+ raise ImportError(
79
+ "xarray is required to export NetCDF. Install with: \n"
80
+ " pip install xarray netCDF4\n"
81
+ "or: \n"
82
+ " pip install xarray h5netcdf"
83
+ )
84
+
85
+ if voxcity_grid.ndim != 3:
86
+ raise ValueError(
87
+ f"voxcity_grid must be 3D (rows, cols, levels); got shape={voxcity_grid.shape}"
88
+ )
89
+
90
+ rows, cols, levels = voxcity_grid.shape
91
+
92
+ # Coordinate vectors in meters relative to the grid origin
93
+ # y increases with row index, x increases with column index
94
+ y_m = np.arange(rows, dtype=float) * float(voxel_size_m)
95
+ x_m = np.arange(cols, dtype=float) * float(voxel_size_m)
96
+ z_m = np.arange(levels, dtype=float) * float(voxel_size_m)
97
+
98
+ ds_attrs: MutableMapping[str, Any] = {
99
+ "title": "VoxCity voxel grid",
100
+ "institution": "VoxCity",
101
+ "source": "voxcity.generator.create_3d_voxel",
102
+ "Conventions": "CF-1.10 (partial)",
103
+ # NetCDF attributes must be basic types; serialize complex structures as strings
104
+ "vox_value_meanings": [
105
+ "-3: building",
106
+ "-2: vegetation_canopy",
107
+ "-1: subsurface",
108
+ ">=1: surface_land_cover_code (offset +1)",
109
+ ],
110
+ "meshsize_m": float(voxel_size_m),
111
+ # Store vertices as JSON string for portability
112
+ "rectangle_vertices_lonlat_json": (
113
+ json.dumps([[float(v[0]), float(v[1])] for v in rectangle_vertices])
114
+ if rectangle_vertices is not None else ""
115
+ ),
116
+ "vertical_reference": "z=0 corresponds to min(DEM) as used in voxel construction",
117
+ }
118
+ if extra_attrs:
119
+ ds_attrs.update(dict(extra_attrs))
120
+
121
+ da = xr.DataArray(
122
+ voxcity_grid,
123
+ dims=("y", "x", "z"),
124
+ coords={
125
+ "y": ("y", y_m, {"units": "m", "long_name": "row_distance_from_origin"}),
126
+ "x": ("x", x_m, {"units": "m", "long_name": "col_distance_from_origin"}),
127
+ "z": ("z", z_m, {"units": "m", "positive": "up", "long_name": "height_above_vertical_origin"}),
128
+ },
129
+ name="voxels",
130
+ attrs={
131
+ "units": "category",
132
+ "description": "VoxCity voxel values; see global attribute 'vox_value_meanings'",
133
+ },
134
+ )
135
+
136
+ ds = xr.Dataset({"voxels": da}, attrs=ds_attrs)
137
+ return ds
138
+
139
+
140
+ def save_voxel_netcdf(
141
+ voxcity_grid: np.ndarray,
142
+ output_path: str | Path,
143
+ voxel_size_m: float,
144
+ rectangle_vertices: Optional[Sequence[Tuple[float, float]]] = None,
145
+ extra_attrs: Optional[Mapping[str, Any]] = None,
146
+ engine: Optional[str] = None,
147
+ ) -> str:
148
+ """Save a VoxCity voxel grid to a NetCDF file.
149
+
150
+ Parameters
151
+ ----------
152
+ voxcity_grid
153
+ 3D numpy array (rows, cols, levels) of voxel values.
154
+ output_path
155
+ Path to the NetCDF file to be written. Parent directories will be
156
+ created as needed.
157
+ voxel_size_m
158
+ Voxel size in meters.
159
+ rectangle_vertices
160
+ Optional list of (lon, lat) pairs defining the area of interest.
161
+ Stored as dataset metadata only.
162
+ extra_attrs
163
+ Optional additional global attributes to embed in the dataset.
164
+ engine
165
+ Optional xarray engine, e.g., "netcdf4" or "h5netcdf". If not provided,
166
+ xarray will choose a default; on failure we retry alternate engines.
167
+
168
+ Returns
169
+ -------
170
+ str
171
+ The string path to the written NetCDF file.
172
+ """
173
+ if not XR_AVAILABLE: # pragma: no cover - optional dependency
174
+ raise ImportError(
175
+ "xarray is required to export NetCDF. Install with: \n"
176
+ " pip install xarray netCDF4\n"
177
+ "or: \n"
178
+ " pip install xarray h5netcdf"
179
+ )
180
+
181
+ path = Path(output_path)
182
+ _ensure_parent_dir(path)
183
+
184
+ ds = voxel_to_xarray_dataset(
185
+ voxcity_grid=voxcity_grid,
186
+ voxel_size_m=voxel_size_m,
187
+ rectangle_vertices=rectangle_vertices,
188
+ extra_attrs=extra_attrs,
189
+ )
190
+
191
+ # Attempt to save with the requested or default engine; on failure, try a fallback
192
+ tried_engines = []
193
+ try:
194
+ ds.to_netcdf(path, engine=engine) # type: ignore[call-arg]
195
+ except Exception as e_first: # pragma: no cover - I/O backend dependent
196
+ tried_engines.append(engine or "default")
197
+ for fallback in ("netcdf4", "h5netcdf"):
198
+ try:
199
+ ds.to_netcdf(path, engine=fallback) # type: ignore[call-arg]
200
+ break
201
+ except Exception:
202
+ tried_engines.append(fallback)
203
+ else:
204
+ raise RuntimeError(
205
+ f"Failed to write NetCDF using engines: {tried_engines}. "
206
+ f"Original error: {e_first}"
207
+ )
208
+
209
+ return str(path)
210
+
211
+