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.
- voxcity/__init__.py +14 -14
- voxcity/exporter/__init__.py +12 -12
- voxcity/exporter/cityles.py +633 -633
- voxcity/exporter/envimet.py +733 -728
- voxcity/exporter/magicavoxel.py +333 -333
- voxcity/exporter/netcdf.py +238 -238
- voxcity/exporter/obj.py +1480 -1480
- voxcity/generator/__init__.py +47 -44
- voxcity/generator/api.py +721 -675
- voxcity/generator/grids.py +381 -379
- voxcity/generator/io.py +94 -94
- voxcity/generator/pipeline.py +282 -282
- voxcity/generator/update.py +429 -0
- voxcity/generator/voxelizer.py +18 -6
- voxcity/geoprocessor/__init__.py +75 -75
- voxcity/geoprocessor/draw.py +1488 -1219
- voxcity/geoprocessor/merge_utils.py +91 -91
- voxcity/geoprocessor/mesh.py +806 -806
- voxcity/geoprocessor/network.py +708 -708
- voxcity/geoprocessor/raster/buildings.py +435 -428
- voxcity/geoprocessor/raster/export.py +93 -93
- voxcity/geoprocessor/raster/landcover.py +5 -2
- voxcity/geoprocessor/utils.py +824 -824
- voxcity/models.py +113 -113
- voxcity/simulator/solar/__init__.py +66 -43
- voxcity/simulator/solar/integration.py +336 -336
- voxcity/simulator/solar/sky.py +668 -0
- voxcity/simulator/solar/temporal.py +792 -434
- voxcity/utils/__init__.py +11 -0
- voxcity/utils/classes.py +194 -0
- voxcity/utils/lc.py +80 -39
- voxcity/utils/shape.py +230 -0
- voxcity/visualizer/__init__.py +24 -24
- voxcity/visualizer/builder.py +43 -43
- voxcity/visualizer/grids.py +141 -141
- voxcity/visualizer/maps.py +187 -187
- voxcity/visualizer/renderer.py +1145 -928
- {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/METADATA +90 -49
- {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/RECORD +42 -38
- {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/WHEEL +0 -0
- {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/licenses/AUTHORS.rst +0 -0
- {voxcity-0.7.0.dist-info → voxcity-1.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import geopandas as gpd
|
|
3
|
-
from shapely.geometry import box
|
|
4
|
-
from pyproj import CRS, Transformer
|
|
5
|
-
from ...utils.orientation import ensure_orientation, ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def grid_to_geodataframe(grid_ori, rectangle_vertices, meshsize):
|
|
9
|
-
"""
|
|
10
|
-
Converts a 2D grid to a GeoDataFrame with cell polygons and values.
|
|
11
|
-
Output CRS: EPSG:4326
|
|
12
|
-
"""
|
|
13
|
-
grid = ensure_orientation(grid_ori.copy(), ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP)
|
|
14
|
-
|
|
15
|
-
min_lon = min(v[0] for v in rectangle_vertices)
|
|
16
|
-
max_lon = max(v[0] for v in rectangle_vertices)
|
|
17
|
-
min_lat = min(v[1] for v in rectangle_vertices)
|
|
18
|
-
max_lat = max(v[1] for v in rectangle_vertices)
|
|
19
|
-
|
|
20
|
-
rows, cols = grid.shape
|
|
21
|
-
|
|
22
|
-
wgs84 = CRS.from_epsg(4326)
|
|
23
|
-
web_mercator = CRS.from_epsg(3857)
|
|
24
|
-
transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
|
|
25
|
-
transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
|
|
26
|
-
|
|
27
|
-
min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
|
|
28
|
-
max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
|
|
29
|
-
|
|
30
|
-
cell_size_x = (max_x - min_x) / cols
|
|
31
|
-
cell_size_y = (max_y - min_y) / rows
|
|
32
|
-
|
|
33
|
-
polygons = []
|
|
34
|
-
values = []
|
|
35
|
-
|
|
36
|
-
for i in range(rows):
|
|
37
|
-
for j in range(cols):
|
|
38
|
-
cell_min_x = min_x + j * cell_size_x
|
|
39
|
-
cell_max_x = min_x + (j + 1) * cell_size_x
|
|
40
|
-
cell_min_y = max_y - (i + 1) * cell_size_y
|
|
41
|
-
cell_max_y = max_y - i * cell_size_y
|
|
42
|
-
cell_min_lon, cell_min_lat = transformer_to_wgs84.transform(cell_min_x, cell_min_y)
|
|
43
|
-
cell_max_lon, cell_max_lat = transformer_to_wgs84.transform(cell_max_x, cell_max_y)
|
|
44
|
-
cell_poly = box(cell_min_lon, cell_min_lat, cell_max_lon, cell_max_lat)
|
|
45
|
-
polygons.append(cell_poly)
|
|
46
|
-
values.append(grid[i, j])
|
|
47
|
-
|
|
48
|
-
gdf = gpd.GeoDataFrame({'geometry': polygons, 'value': values}, crs=CRS.from_epsg(4326))
|
|
49
|
-
return gdf
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def grid_to_point_geodataframe(grid_ori, rectangle_vertices, meshsize):
|
|
53
|
-
"""
|
|
54
|
-
Converts a 2D grid to a GeoDataFrame with point geometries at cell centers and values.
|
|
55
|
-
Output CRS: EPSG:4326
|
|
56
|
-
"""
|
|
57
|
-
import geopandas as gpd
|
|
58
|
-
from shapely.geometry import Point
|
|
59
|
-
|
|
60
|
-
grid = ensure_orientation(grid_ori.copy(), ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP)
|
|
61
|
-
|
|
62
|
-
min_lon = min(v[0] for v in rectangle_vertices)
|
|
63
|
-
max_lon = max(v[0] for v in rectangle_vertices)
|
|
64
|
-
min_lat = min(v[1] for v in rectangle_vertices)
|
|
65
|
-
max_lat = max(v[1] for v in rectangle_vertices)
|
|
66
|
-
|
|
67
|
-
rows, cols = grid.shape
|
|
68
|
-
|
|
69
|
-
wgs84 = CRS.from_epsg(4326)
|
|
70
|
-
web_mercator = CRS.from_epsg(3857)
|
|
71
|
-
transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
|
|
72
|
-
transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
|
|
73
|
-
|
|
74
|
-
min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
|
|
75
|
-
max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
|
|
76
|
-
|
|
77
|
-
cell_size_x = (max_x - min_x) / cols
|
|
78
|
-
cell_size_y = (max_y - min_y) / rows
|
|
79
|
-
|
|
80
|
-
points = []
|
|
81
|
-
values = []
|
|
82
|
-
for i in range(rows):
|
|
83
|
-
for j in range(cols):
|
|
84
|
-
cell_center_x = min_x + (j + 0.5) * cell_size_x
|
|
85
|
-
cell_center_y = max_y - (i + 0.5) * cell_size_y
|
|
86
|
-
center_lon, center_lat = transformer_to_wgs84.transform(cell_center_x, cell_center_y)
|
|
87
|
-
points.append(Point(center_lon, center_lat))
|
|
88
|
-
values.append(grid[i, j])
|
|
89
|
-
|
|
90
|
-
gdf = gpd.GeoDataFrame({'geometry': points, 'value': values}, crs=CRS.from_epsg(4326))
|
|
91
|
-
return gdf
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
import numpy as np
|
|
2
|
+
import geopandas as gpd
|
|
3
|
+
from shapely.geometry import box
|
|
4
|
+
from pyproj import CRS, Transformer
|
|
5
|
+
from ...utils.orientation import ensure_orientation, ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def grid_to_geodataframe(grid_ori, rectangle_vertices, meshsize):
|
|
9
|
+
"""
|
|
10
|
+
Converts a 2D grid to a GeoDataFrame with cell polygons and values.
|
|
11
|
+
Output CRS: EPSG:4326
|
|
12
|
+
"""
|
|
13
|
+
grid = ensure_orientation(grid_ori.copy(), ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP)
|
|
14
|
+
|
|
15
|
+
min_lon = min(v[0] for v in rectangle_vertices)
|
|
16
|
+
max_lon = max(v[0] for v in rectangle_vertices)
|
|
17
|
+
min_lat = min(v[1] for v in rectangle_vertices)
|
|
18
|
+
max_lat = max(v[1] for v in rectangle_vertices)
|
|
19
|
+
|
|
20
|
+
rows, cols = grid.shape
|
|
21
|
+
|
|
22
|
+
wgs84 = CRS.from_epsg(4326)
|
|
23
|
+
web_mercator = CRS.from_epsg(3857)
|
|
24
|
+
transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
|
|
25
|
+
transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
|
|
26
|
+
|
|
27
|
+
min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
|
|
28
|
+
max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
|
|
29
|
+
|
|
30
|
+
cell_size_x = (max_x - min_x) / cols
|
|
31
|
+
cell_size_y = (max_y - min_y) / rows
|
|
32
|
+
|
|
33
|
+
polygons = []
|
|
34
|
+
values = []
|
|
35
|
+
|
|
36
|
+
for i in range(rows):
|
|
37
|
+
for j in range(cols):
|
|
38
|
+
cell_min_x = min_x + j * cell_size_x
|
|
39
|
+
cell_max_x = min_x + (j + 1) * cell_size_x
|
|
40
|
+
cell_min_y = max_y - (i + 1) * cell_size_y
|
|
41
|
+
cell_max_y = max_y - i * cell_size_y
|
|
42
|
+
cell_min_lon, cell_min_lat = transformer_to_wgs84.transform(cell_min_x, cell_min_y)
|
|
43
|
+
cell_max_lon, cell_max_lat = transformer_to_wgs84.transform(cell_max_x, cell_max_y)
|
|
44
|
+
cell_poly = box(cell_min_lon, cell_min_lat, cell_max_lon, cell_max_lat)
|
|
45
|
+
polygons.append(cell_poly)
|
|
46
|
+
values.append(grid[i, j])
|
|
47
|
+
|
|
48
|
+
gdf = gpd.GeoDataFrame({'geometry': polygons, 'value': values}, crs=CRS.from_epsg(4326))
|
|
49
|
+
return gdf
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def grid_to_point_geodataframe(grid_ori, rectangle_vertices, meshsize):
|
|
53
|
+
"""
|
|
54
|
+
Converts a 2D grid to a GeoDataFrame with point geometries at cell centers and values.
|
|
55
|
+
Output CRS: EPSG:4326
|
|
56
|
+
"""
|
|
57
|
+
import geopandas as gpd
|
|
58
|
+
from shapely.geometry import Point
|
|
59
|
+
|
|
60
|
+
grid = ensure_orientation(grid_ori.copy(), ORIENTATION_NORTH_UP, ORIENTATION_SOUTH_UP)
|
|
61
|
+
|
|
62
|
+
min_lon = min(v[0] for v in rectangle_vertices)
|
|
63
|
+
max_lon = max(v[0] for v in rectangle_vertices)
|
|
64
|
+
min_lat = min(v[1] for v in rectangle_vertices)
|
|
65
|
+
max_lat = max(v[1] for v in rectangle_vertices)
|
|
66
|
+
|
|
67
|
+
rows, cols = grid.shape
|
|
68
|
+
|
|
69
|
+
wgs84 = CRS.from_epsg(4326)
|
|
70
|
+
web_mercator = CRS.from_epsg(3857)
|
|
71
|
+
transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
|
|
72
|
+
transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
|
|
73
|
+
|
|
74
|
+
min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
|
|
75
|
+
max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
|
|
76
|
+
|
|
77
|
+
cell_size_x = (max_x - min_x) / cols
|
|
78
|
+
cell_size_y = (max_y - min_y) / rows
|
|
79
|
+
|
|
80
|
+
points = []
|
|
81
|
+
values = []
|
|
82
|
+
for i in range(rows):
|
|
83
|
+
for j in range(cols):
|
|
84
|
+
cell_center_x = min_x + (j + 0.5) * cell_size_x
|
|
85
|
+
cell_center_y = max_y - (i + 0.5) * cell_size_y
|
|
86
|
+
center_lon, center_lat = transformer_to_wgs84.transform(cell_center_x, cell_center_y)
|
|
87
|
+
points.append(Point(center_lon, center_lat))
|
|
88
|
+
values.append(grid[i, j])
|
|
89
|
+
|
|
90
|
+
gdf = gpd.GeoDataFrame({'geometry': points, 'value': values}, crs=CRS.from_epsg(4326))
|
|
91
|
+
return gdf
|
|
92
|
+
|
|
93
|
+
|
|
@@ -17,9 +17,12 @@ from .core import translate_array
|
|
|
17
17
|
def tree_height_grid_from_land_cover(land_cover_grid_ori: np.ndarray) -> np.ndarray:
|
|
18
18
|
"""
|
|
19
19
|
Convert a land cover grid to a tree height grid.
|
|
20
|
+
|
|
21
|
+
Expects 1-based land cover indices where class 5 is Tree.
|
|
20
22
|
"""
|
|
21
|
-
land_cover_grid = np.flipud(land_cover_grid_ori)
|
|
22
|
-
|
|
23
|
+
land_cover_grid = np.flipud(land_cover_grid_ori)
|
|
24
|
+
# 1-based indices: 1=Bareland, 2=Rangeland, 3=Shrub, 4=Agriculture, 5=Tree, etc.
|
|
25
|
+
tree_translation_dict = {1: 0, 2: 0, 3: 0, 4: 0, 5: 10, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0}
|
|
23
26
|
tree_height_grid = translate_array(np.flipud(land_cover_grid), tree_translation_dict).astype(int)
|
|
24
27
|
return tree_height_grid
|
|
25
28
|
|