voxcity 0.5.25__tar.gz → 0.5.27__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.25 → voxcity-0.5.27}/PKG-INFO +1 -1
- {voxcity-0.5.25 → voxcity-0.5.27}/pyproject.toml +1 -1
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/exporter/__init__.py +2 -1
- voxcity-0.5.27/src/voxcity/exporter/cityles.py +368 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/exporter/envimet.py +3 -3
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity.egg-info/PKG-INFO +1 -1
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity.egg-info/SOURCES.txt +1 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/AUTHORS.rst +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/CONTRIBUTING.rst +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/HISTORY.rst +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/LICENSE +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/MANIFEST.in +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/README.md +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/docs/Makefile +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/docs/_static/logo.png +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/docs/conf.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/docs/logo.png +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/docs/make.bat +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/setup.cfg +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/citygml.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/eubucco.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/gee.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/mbfp.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/oemj.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/osm.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/overture.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/downloader/utils.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/exporter/magicavoxel.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/exporter/obj.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/generator.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/draw.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/grid.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/mesh.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/network.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/polygon.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/geoprocessor/utils.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/simulator/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/simulator/solar.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/simulator/utils.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/simulator/view.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/utils/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/utils/lc.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/utils/material.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/utils/visualization.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity/utils/weather.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity.egg-info/dependency_links.txt +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity.egg-info/requires.txt +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/src/voxcity.egg-info/top_level.txt +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/tests/__init__.py +0 -0
- {voxcity-0.5.25 → voxcity-0.5.27}/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.27
|
|
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>
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CityLES Exporter Module for VoxCity
|
|
3
|
+
|
|
4
|
+
This module provides functionality to export VoxCity grid data to the CityLES input file format.
|
|
5
|
+
CityLES is a large-eddy simulation (LES) model for urban environments, requiring specific input files
|
|
6
|
+
describing land use, building geometry, vegetation, and terrain.
|
|
7
|
+
|
|
8
|
+
Key Features:
|
|
9
|
+
- Converts VoxCity grids to CityLES-compatible input files (topog.txt, landuse.txt, dem.txt, vmap.txt, lonlat.txt)
|
|
10
|
+
- Handles land cover, building heights, canopy heights, and digital elevation models
|
|
11
|
+
- Supports flexible mapping from land cover and building types to CityLES codes
|
|
12
|
+
- Generates all required text files and metadata for CityLES runs
|
|
13
|
+
|
|
14
|
+
Main Functions:
|
|
15
|
+
- export_cityles: Main function to export all required CityLES input files
|
|
16
|
+
- export_topog: Exports building geometry (topog.txt)
|
|
17
|
+
- export_landuse: Exports land use grid (landuse.txt)
|
|
18
|
+
- export_dem: Exports digital elevation model (dem.txt)
|
|
19
|
+
- export_vmap: Exports vegetation map (vmap.txt)
|
|
20
|
+
- export_lonlat: Exports longitude/latitude grid (lonlat.txt)
|
|
21
|
+
|
|
22
|
+
Dependencies:
|
|
23
|
+
- numpy: For array operations
|
|
24
|
+
- pathlib: For file and directory management
|
|
25
|
+
- os: For file system operations
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
import numpy as np
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Land cover to CityLES land use mapping
|
|
34
|
+
# Based on common land cover classifications to CityLES codes
|
|
35
|
+
LANDCOVER_TO_CITYLES_LANDUSE = {
|
|
36
|
+
# Built-up areas
|
|
37
|
+
'building': 4, # Concrete building
|
|
38
|
+
'road': 2, # High reflective asphalt without AH
|
|
39
|
+
'parking': 2, # High reflective asphalt without AH
|
|
40
|
+
'pavement': 11, # Concrete (proxy of block)
|
|
41
|
+
|
|
42
|
+
# Vegetation
|
|
43
|
+
'grass': 10, # Grassland
|
|
44
|
+
'forest': 16, # Deciduous broadleaf forest
|
|
45
|
+
'tree': 16, # Deciduous broadleaf forest
|
|
46
|
+
'agriculture': 7, # Dryland cropland and pasture
|
|
47
|
+
'cropland': 7, # Dryland cropland and pasture
|
|
48
|
+
'paddy': 6, # Paddy
|
|
49
|
+
|
|
50
|
+
# Water and bare land
|
|
51
|
+
'water': 9, # Water
|
|
52
|
+
'bare_soil': 8, # Barren or sparsely vegetated
|
|
53
|
+
'sand': 8, # Barren or sparsely vegetated
|
|
54
|
+
|
|
55
|
+
# Default
|
|
56
|
+
'default': 10 # Grassland as default
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Building material mapping
|
|
60
|
+
# Maps building types to CityLES building attribute codes
|
|
61
|
+
BUILDING_MATERIAL_MAPPING = {
|
|
62
|
+
'concrete': 104, # Concrete building
|
|
63
|
+
'residential': 105, # Slate roof (ordinal wooden house)
|
|
64
|
+
'commercial': 104, # Concrete building
|
|
65
|
+
'industrial': 104, # Concrete building
|
|
66
|
+
'default': 104 # Default to concrete building
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Tree type mapping
|
|
70
|
+
TREE_TYPE_MAPPING = {
|
|
71
|
+
'deciduous': 101, # Leaf
|
|
72
|
+
'evergreen': 101, # Leaf (simplified)
|
|
73
|
+
'default': 101 # Default to leaf
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def create_cityles_directories(output_directory):
|
|
78
|
+
"""Create necessary directories for CityLES output"""
|
|
79
|
+
output_path = Path(output_directory)
|
|
80
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
81
|
+
return output_path
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_land_use_code(land_cover_value, land_cover_source=None):
|
|
85
|
+
"""
|
|
86
|
+
Convert land cover value to CityLES land use code
|
|
87
|
+
|
|
88
|
+
Parameters:
|
|
89
|
+
-----------
|
|
90
|
+
land_cover_value : int or str
|
|
91
|
+
Land cover value from VoxCity
|
|
92
|
+
land_cover_source : str, optional
|
|
93
|
+
Source of land cover data (e.g., 'esri', 'esa', 'osm')
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
--------
|
|
97
|
+
int : CityLES land use code (1-17)
|
|
98
|
+
"""
|
|
99
|
+
# If using numeric codes, you might need source-specific mappings
|
|
100
|
+
# This is a simplified example
|
|
101
|
+
if isinstance(land_cover_value, str):
|
|
102
|
+
return LANDCOVER_TO_CITYLES_LANDUSE.get(land_cover_value.lower(),
|
|
103
|
+
LANDCOVER_TO_CITYLES_LANDUSE['default'])
|
|
104
|
+
|
|
105
|
+
# Example mapping for ESRI land cover (adjust based on actual data source)
|
|
106
|
+
if land_cover_source == 'esri':
|
|
107
|
+
esri_mapping = {
|
|
108
|
+
1: 9, # Water -> Water
|
|
109
|
+
2: 16, # Trees -> Deciduous broadleaf forest
|
|
110
|
+
4: 8, # Flooded vegetation -> Barren
|
|
111
|
+
5: 10, # Crops -> Grassland (simplified)
|
|
112
|
+
7: 4, # Built Area -> Concrete building
|
|
113
|
+
8: 8, # Bare ground -> Barren
|
|
114
|
+
9: 3, # Snow/Ice -> Concrete (proxy of jari)
|
|
115
|
+
10: 9, # Clouds -> Water (simplified)
|
|
116
|
+
11: 10 # Rangeland -> Grassland
|
|
117
|
+
}
|
|
118
|
+
return esri_mapping.get(land_cover_value, LANDCOVER_TO_CITYLES_LANDUSE['default'])
|
|
119
|
+
|
|
120
|
+
# Default mapping
|
|
121
|
+
return LANDCOVER_TO_CITYLES_LANDUSE['default']
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def export_topog(building_height_grid, building_id_grid, output_path,
|
|
125
|
+
building_material='default'):
|
|
126
|
+
"""
|
|
127
|
+
Export topog.txt file for CityLES
|
|
128
|
+
|
|
129
|
+
Parameters:
|
|
130
|
+
-----------
|
|
131
|
+
building_height_grid : numpy.ndarray
|
|
132
|
+
2D array of building heights
|
|
133
|
+
building_id_grid : numpy.ndarray
|
|
134
|
+
2D array of building IDs
|
|
135
|
+
output_path : Path
|
|
136
|
+
Output directory path
|
|
137
|
+
building_material : str
|
|
138
|
+
Building material type for mapping
|
|
139
|
+
"""
|
|
140
|
+
filename = output_path / 'topog.txt'
|
|
141
|
+
|
|
142
|
+
# Get building positions (where height > 0)
|
|
143
|
+
building_positions = np.argwhere(building_height_grid > 0)
|
|
144
|
+
n_buildings = len(building_positions)
|
|
145
|
+
|
|
146
|
+
material_code = BUILDING_MATERIAL_MAPPING.get(building_material,
|
|
147
|
+
BUILDING_MATERIAL_MAPPING['default'])
|
|
148
|
+
|
|
149
|
+
with open(filename, 'w') as f:
|
|
150
|
+
# Write number of buildings
|
|
151
|
+
f.write(f"{n_buildings}\n")
|
|
152
|
+
|
|
153
|
+
# Write building data
|
|
154
|
+
for idx, (j, i) in enumerate(building_positions):
|
|
155
|
+
# CityLES uses 1-based indexing
|
|
156
|
+
i_1based = i + 1
|
|
157
|
+
j_1based = j + 1
|
|
158
|
+
height = building_height_grid[j, i]
|
|
159
|
+
|
|
160
|
+
# Format: i j height material_code depth1 depth2 changed_material
|
|
161
|
+
f.write(f"{i_1based} {j_1based} {height:.1f} {material_code} 0.0 0.0 102\n")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def export_landuse(land_cover_grid, output_path, land_cover_source=None):
|
|
165
|
+
"""
|
|
166
|
+
Export landuse.txt file for CityLES
|
|
167
|
+
|
|
168
|
+
Parameters:
|
|
169
|
+
-----------
|
|
170
|
+
land_cover_grid : numpy.ndarray
|
|
171
|
+
2D array of land cover values
|
|
172
|
+
output_path : Path
|
|
173
|
+
Output directory path
|
|
174
|
+
land_cover_source : str, optional
|
|
175
|
+
Source of land cover data
|
|
176
|
+
"""
|
|
177
|
+
filename = output_path / 'landuse.txt'
|
|
178
|
+
|
|
179
|
+
# Flatten the grid and convert to CityLES codes
|
|
180
|
+
flat_grid = land_cover_grid.flatten()
|
|
181
|
+
|
|
182
|
+
with open(filename, 'w') as f:
|
|
183
|
+
for value in flat_grid:
|
|
184
|
+
cityles_code = get_land_use_code(value, land_cover_source)
|
|
185
|
+
f.write(f"{cityles_code}\n")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def export_dem(dem_grid, output_path):
|
|
189
|
+
"""
|
|
190
|
+
Export dem.txt file for CityLES
|
|
191
|
+
|
|
192
|
+
Parameters:
|
|
193
|
+
-----------
|
|
194
|
+
dem_grid : numpy.ndarray
|
|
195
|
+
2D array of elevation values
|
|
196
|
+
output_path : Path
|
|
197
|
+
Output directory path
|
|
198
|
+
"""
|
|
199
|
+
filename = output_path / 'dem.txt'
|
|
200
|
+
|
|
201
|
+
ny, nx = dem_grid.shape
|
|
202
|
+
|
|
203
|
+
with open(filename, 'w') as f:
|
|
204
|
+
for j in range(ny):
|
|
205
|
+
for i in range(nx):
|
|
206
|
+
# CityLES uses 1-based indexing
|
|
207
|
+
i_1based = i + 1
|
|
208
|
+
j_1based = j + 1
|
|
209
|
+
elevation = dem_grid[j, i]
|
|
210
|
+
|
|
211
|
+
f.write(f"{i_1based} {j_1based} {elevation:.1f}\n")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def export_vmap(canopy_height_grid, output_path, tree_base_ratio=0.3, tree_type='default'):
|
|
215
|
+
"""
|
|
216
|
+
Export vmap.txt file for CityLES
|
|
217
|
+
|
|
218
|
+
Parameters:
|
|
219
|
+
-----------
|
|
220
|
+
canopy_height_grid : numpy.ndarray
|
|
221
|
+
2D array of canopy heights
|
|
222
|
+
output_path : Path
|
|
223
|
+
Output directory path
|
|
224
|
+
tree_base_ratio : float
|
|
225
|
+
Ratio of tree base height to total canopy height
|
|
226
|
+
tree_type : str
|
|
227
|
+
Tree type for mapping
|
|
228
|
+
"""
|
|
229
|
+
filename = output_path / 'vmap.txt'
|
|
230
|
+
|
|
231
|
+
# Get tree positions (where canopy height > 0)
|
|
232
|
+
tree_positions = np.argwhere(canopy_height_grid > 0)
|
|
233
|
+
n_trees = len(tree_positions)
|
|
234
|
+
|
|
235
|
+
tree_code = TREE_TYPE_MAPPING.get(tree_type, TREE_TYPE_MAPPING['default'])
|
|
236
|
+
|
|
237
|
+
with open(filename, 'w') as f:
|
|
238
|
+
# Write number of trees
|
|
239
|
+
f.write(f"{n_trees}\n")
|
|
240
|
+
|
|
241
|
+
# Write tree data
|
|
242
|
+
for idx, (j, i) in enumerate(tree_positions):
|
|
243
|
+
# CityLES uses 1-based indexing
|
|
244
|
+
i_1based = i + 1
|
|
245
|
+
j_1based = j + 1
|
|
246
|
+
total_height = canopy_height_grid[j, i]
|
|
247
|
+
lower_height = total_height * tree_base_ratio
|
|
248
|
+
upper_height = total_height
|
|
249
|
+
|
|
250
|
+
# Format: i j lower_height upper_height tree_type
|
|
251
|
+
f.write(f"{i_1based} {j_1based} {lower_height:.1f} {upper_height:.1f} {tree_code}\n")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def export_lonlat(rectangle_vertices, grid_shape, output_path):
|
|
255
|
+
"""
|
|
256
|
+
Export lonlat.txt file for CityLES
|
|
257
|
+
|
|
258
|
+
Parameters:
|
|
259
|
+
-----------
|
|
260
|
+
rectangle_vertices : list of tuples
|
|
261
|
+
List of (lon, lat) vertices defining the area
|
|
262
|
+
grid_shape : tuple
|
|
263
|
+
Shape of the grid (ny, nx)
|
|
264
|
+
output_path : Path
|
|
265
|
+
Output directory path
|
|
266
|
+
"""
|
|
267
|
+
filename = output_path / 'lonlat.txt'
|
|
268
|
+
|
|
269
|
+
ny, nx = grid_shape
|
|
270
|
+
|
|
271
|
+
# Extract bounds from vertices
|
|
272
|
+
lons = [v[0] for v in rectangle_vertices]
|
|
273
|
+
lats = [v[1] for v in rectangle_vertices]
|
|
274
|
+
min_lon, max_lon = min(lons), max(lons)
|
|
275
|
+
min_lat, max_lat = min(lats), max(lats)
|
|
276
|
+
|
|
277
|
+
# Create coordinate grids
|
|
278
|
+
lon_vals = np.linspace(min_lon, max_lon, nx)
|
|
279
|
+
lat_vals = np.linspace(min_lat, max_lat, ny)
|
|
280
|
+
|
|
281
|
+
with open(filename, 'w') as f:
|
|
282
|
+
for j in range(ny):
|
|
283
|
+
for i in range(nx):
|
|
284
|
+
# CityLES uses 1-based indexing
|
|
285
|
+
i_1based = i + 1
|
|
286
|
+
j_1based = j + 1
|
|
287
|
+
lon = lon_vals[i]
|
|
288
|
+
lat = lat_vals[j]
|
|
289
|
+
|
|
290
|
+
f.write(f"{i_1based} {j_1based} {lon:.7f} {lat:.8f}\n")
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def export_cityles(building_height_grid, building_id_grid, canopy_height_grid,
|
|
294
|
+
land_cover_grid, dem_grid, meshsize, land_cover_source,
|
|
295
|
+
rectangle_vertices, output_directory="output/cityles",
|
|
296
|
+
building_material='default', tree_type='default',
|
|
297
|
+
tree_base_ratio=0.3, **kwargs):
|
|
298
|
+
"""
|
|
299
|
+
Export VoxCity data to CityLES format
|
|
300
|
+
|
|
301
|
+
Parameters:
|
|
302
|
+
-----------
|
|
303
|
+
building_height_grid : numpy.ndarray
|
|
304
|
+
2D array of building heights
|
|
305
|
+
building_id_grid : numpy.ndarray
|
|
306
|
+
2D array of building IDs
|
|
307
|
+
canopy_height_grid : numpy.ndarray
|
|
308
|
+
2D array of canopy heights
|
|
309
|
+
land_cover_grid : numpy.ndarray
|
|
310
|
+
2D array of land cover values
|
|
311
|
+
dem_grid : numpy.ndarray
|
|
312
|
+
2D array of elevation values
|
|
313
|
+
meshsize : float
|
|
314
|
+
Grid cell size in meters
|
|
315
|
+
land_cover_source : str
|
|
316
|
+
Source of land cover data (e.g., 'esri', 'esa', 'osm')
|
|
317
|
+
rectangle_vertices : list of tuples
|
|
318
|
+
List of (lon, lat) vertices defining the area
|
|
319
|
+
output_directory : str
|
|
320
|
+
Output directory path
|
|
321
|
+
building_material : str
|
|
322
|
+
Building material type for mapping
|
|
323
|
+
tree_type : str
|
|
324
|
+
Tree type for mapping
|
|
325
|
+
tree_base_ratio : float
|
|
326
|
+
Ratio of tree base height to total canopy height
|
|
327
|
+
**kwargs : dict
|
|
328
|
+
Additional parameters (for compatibility)
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
--------
|
|
332
|
+
str : Path to output directory
|
|
333
|
+
"""
|
|
334
|
+
# Create output directory
|
|
335
|
+
output_path = create_cityles_directories(output_directory)
|
|
336
|
+
|
|
337
|
+
print(f"Exporting CityLES files to: {output_path}")
|
|
338
|
+
|
|
339
|
+
# Export individual files
|
|
340
|
+
print("Exporting topog.txt...")
|
|
341
|
+
export_topog(building_height_grid, building_id_grid, output_path, building_material)
|
|
342
|
+
|
|
343
|
+
print("Exporting landuse.txt...")
|
|
344
|
+
export_landuse(land_cover_grid, output_path, land_cover_source)
|
|
345
|
+
|
|
346
|
+
print("Exporting dem.txt...")
|
|
347
|
+
export_dem(dem_grid, output_path)
|
|
348
|
+
|
|
349
|
+
print("Exporting vmap.txt...")
|
|
350
|
+
export_vmap(canopy_height_grid, output_path, tree_base_ratio, tree_type)
|
|
351
|
+
|
|
352
|
+
print("Exporting lonlat.txt...")
|
|
353
|
+
export_lonlat(rectangle_vertices, building_height_grid.shape, output_path)
|
|
354
|
+
|
|
355
|
+
# Create metadata file for reference
|
|
356
|
+
metadata_file = output_path / 'cityles_metadata.txt'
|
|
357
|
+
with open(metadata_file, 'w') as f:
|
|
358
|
+
f.write("CityLES Export Metadata\n")
|
|
359
|
+
f.write("====================\n")
|
|
360
|
+
f.write(f"Grid shape: {building_height_grid.shape}\n")
|
|
361
|
+
f.write(f"Mesh size: {meshsize} m\n")
|
|
362
|
+
f.write(f"Land cover source: {land_cover_source}\n")
|
|
363
|
+
f.write(f"Building material: {building_material}\n")
|
|
364
|
+
f.write(f"Tree type: {tree_type}\n")
|
|
365
|
+
f.write(f"Bounds: {rectangle_vertices}\n")
|
|
366
|
+
|
|
367
|
+
print(f"CityLES export completed successfully!")
|
|
368
|
+
return str(output_path)
|
|
@@ -147,8 +147,8 @@ def prepare_grids(building_height_grid_ori, building_id_grid_ori, canopy_height_
|
|
|
147
147
|
veg_translation_dict = {
|
|
148
148
|
1: '', # Bareland
|
|
149
149
|
2: '0200XX', # Rangeland
|
|
150
|
-
3: '', # Shrub
|
|
151
|
-
4: '', # Moss and lichen
|
|
150
|
+
3: '0200H1', # Shrub
|
|
151
|
+
4: '0200XX', # Moss and lichen
|
|
152
152
|
5: '0200XX', # Agriculture land
|
|
153
153
|
6: '', # Tree
|
|
154
154
|
7: '0200XX', # Wet land
|
|
@@ -171,7 +171,7 @@ def prepare_grids(building_height_grid_ori, building_id_grid_ori, canopy_height_
|
|
|
171
171
|
11: '0200PG', # Developed space
|
|
172
172
|
12: '0200ST', # Road
|
|
173
173
|
13: '000000', # Building
|
|
174
|
-
14: '
|
|
174
|
+
14: '000000', # No Data
|
|
175
175
|
}
|
|
176
176
|
land_cover_mat_grid = translate_array(land_cover_grid, mat_translation_dict)
|
|
177
177
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voxcity
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.27
|
|
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>
|
|
@@ -27,6 +27,7 @@ src/voxcity/downloader/osm.py
|
|
|
27
27
|
src/voxcity/downloader/overture.py
|
|
28
28
|
src/voxcity/downloader/utils.py
|
|
29
29
|
src/voxcity/exporter/__init__.py
|
|
30
|
+
src/voxcity/exporter/cityles.py
|
|
30
31
|
src/voxcity/exporter/envimet.py
|
|
31
32
|
src/voxcity/exporter/magicavoxel.py
|
|
32
33
|
src/voxcity/exporter/obj.py
|
|
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
|