voxcity 0.6.6__py3-none-any.whl → 0.6.7__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.
Potentially problematic release.
This version of voxcity might be problematic. Click here for more details.
- voxcity/geoprocessor/grid.py +45 -33
- {voxcity-0.6.6.dist-info → voxcity-0.6.7.dist-info}/METADATA +1 -1
- {voxcity-0.6.6.dist-info → voxcity-0.6.7.dist-info}/RECORD +6 -6
- {voxcity-0.6.6.dist-info → voxcity-0.6.7.dist-info}/AUTHORS.rst +0 -0
- {voxcity-0.6.6.dist-info → voxcity-0.6.7.dist-info}/LICENSE +0 -0
- {voxcity-0.6.6.dist-info → voxcity-0.6.7.dist-info}/WHEEL +0 -0
voxcity/geoprocessor/grid.py
CHANGED
|
@@ -263,14 +263,19 @@ def calculate_grid_size(side_1, side_2, u_vec, v_vec, meshsize):
|
|
|
263
263
|
>>> mesh = 10 # Desired 10-unit mesh
|
|
264
264
|
>>> grid_size, adj_mesh = calculate_grid_size(side1, side2, u, v, mesh)
|
|
265
265
|
"""
|
|
266
|
-
# Calculate
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
266
|
+
# Calculate total side lengths in meters using the relationship between side vectors and unit vectors
|
|
267
|
+
# u_vec and v_vec represent degrees per meter along each side direction
|
|
268
|
+
dist_side_1_m = np.linalg.norm(side_1) / (np.linalg.norm(u_vec) + 1e-12)
|
|
269
|
+
dist_side_2_m = np.linalg.norm(side_2) / (np.linalg.norm(v_vec) + 1e-12)
|
|
270
|
+
|
|
271
|
+
# Calculate number of cells (nx along u, ny along v), rounding to nearest integer and ensuring at least 1
|
|
272
|
+
grid_size_0 = max(1, int(dist_side_1_m / meshsize + 0.5))
|
|
273
|
+
grid_size_1 = max(1, int(dist_side_2_m / meshsize + 0.5))
|
|
274
|
+
|
|
275
|
+
# Adjust mesh sizes (in meters) to exactly fit the sides with the calculated number of cells
|
|
276
|
+
adjusted_mesh_size_0 = dist_side_1_m / grid_size_0
|
|
277
|
+
adjusted_mesh_size_1 = dist_side_2_m / grid_size_1
|
|
278
|
+
|
|
274
279
|
return (grid_size_0, grid_size_1), (adjusted_mesh_size_0, adjusted_mesh_size_1)
|
|
275
280
|
|
|
276
281
|
def create_coordinate_mesh(origin, grid_size, adjusted_meshsize, u_vec, v_vec):
|
|
@@ -908,12 +913,19 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
908
913
|
Process buildings using fast rasterio-based approach.
|
|
909
914
|
Faster but less precise for overlapping footprints.
|
|
910
915
|
"""
|
|
911
|
-
# Set up transform for rasterio
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
916
|
+
# Set up transform for rasterio using rotated basis defined by u_vec and v_vec
|
|
917
|
+
# Step vectors in coordinate units (degrees) per cell
|
|
918
|
+
u_step = adjusted_meshsize[0] * u_vec
|
|
919
|
+
v_step = adjusted_meshsize[1] * v_vec
|
|
920
|
+
|
|
921
|
+
# Define the top-left corner so that row=0 is the northern edge
|
|
922
|
+
top_left = origin + grid_size[1] * v_step
|
|
923
|
+
|
|
924
|
+
# Affine transform mapping (col, row) -> (x, y)
|
|
925
|
+
# x = a*col + b*row + c ; y = d*col + e*row + f
|
|
926
|
+
# col increases along u_step; row increases southward, hence -v_step
|
|
927
|
+
transform = Affine(u_step[0], -v_step[0], top_left[0],
|
|
928
|
+
u_step[1], -v_step[1], top_left[1])
|
|
917
929
|
|
|
918
930
|
# Process buildings data
|
|
919
931
|
filtered_gdf = filtered_gdf.copy()
|
|
@@ -934,9 +946,9 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
934
946
|
regular_buildings = filtered_gdf[~filtered_gdf['is_inner']].copy()
|
|
935
947
|
regular_buildings = regular_buildings.sort_values('height', ascending=True, na_position='first')
|
|
936
948
|
|
|
937
|
-
#
|
|
938
|
-
|
|
939
|
-
|
|
949
|
+
# Temporary raster grids in rasterio's (rows=ny, cols=nx) order
|
|
950
|
+
height_raster = np.zeros((grid_size[1], grid_size[0]), dtype=np.float64)
|
|
951
|
+
id_raster = np.zeros((grid_size[1], grid_size[0]), dtype=np.float64)
|
|
940
952
|
|
|
941
953
|
# Vectorized rasterization
|
|
942
954
|
if len(regular_buildings) > 0:
|
|
@@ -949,9 +961,9 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
949
961
|
if pd.notna(height) and height > 0]
|
|
950
962
|
|
|
951
963
|
if height_shapes:
|
|
952
|
-
|
|
964
|
+
height_raster = features.rasterize(
|
|
953
965
|
height_shapes,
|
|
954
|
-
out_shape=grid_size,
|
|
966
|
+
out_shape=(grid_size[1], grid_size[0]),
|
|
955
967
|
transform=transform,
|
|
956
968
|
fill=0,
|
|
957
969
|
dtype=np.float64
|
|
@@ -962,9 +974,9 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
962
974
|
zip(valid_buildings.geometry, valid_buildings['id'])]
|
|
963
975
|
|
|
964
976
|
if id_shapes:
|
|
965
|
-
|
|
977
|
+
id_raster = features.rasterize(
|
|
966
978
|
id_shapes,
|
|
967
|
-
out_shape=grid_size,
|
|
979
|
+
out_shape=(grid_size[1], grid_size[0]),
|
|
968
980
|
transform=transform,
|
|
969
981
|
fill=0,
|
|
970
982
|
dtype=np.float64
|
|
@@ -977,17 +989,17 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
977
989
|
if inner_shapes:
|
|
978
990
|
inner_mask = features.rasterize(
|
|
979
991
|
inner_shapes,
|
|
980
|
-
out_shape=grid_size,
|
|
992
|
+
out_shape=(grid_size[1], grid_size[0]),
|
|
981
993
|
transform=transform,
|
|
982
994
|
fill=0,
|
|
983
995
|
dtype=np.uint8
|
|
984
996
|
)
|
|
985
|
-
|
|
986
|
-
|
|
997
|
+
height_raster[inner_mask > 0] = 0
|
|
998
|
+
id_raster[inner_mask > 0] = 0
|
|
987
999
|
|
|
988
1000
|
# Simplified min_height grid
|
|
989
1001
|
building_min_height_grid = np.empty(grid_size, dtype=object)
|
|
990
|
-
|
|
1002
|
+
min_heights_raster = np.zeros((grid_size[1], grid_size[0]), dtype=np.float64)
|
|
991
1003
|
|
|
992
1004
|
if len(regular_buildings) > 0:
|
|
993
1005
|
valid_buildings = regular_buildings[regular_buildings.geometry.is_valid].copy()
|
|
@@ -997,27 +1009,27 @@ def _process_with_rasterio(filtered_gdf, grid_size, adjusted_meshsize, origin, u
|
|
|
997
1009
|
if pd.notna(min_h)]
|
|
998
1010
|
|
|
999
1011
|
if min_height_shapes:
|
|
1000
|
-
|
|
1012
|
+
min_heights_raster = features.rasterize(
|
|
1001
1013
|
min_height_shapes,
|
|
1002
|
-
out_shape=grid_size,
|
|
1014
|
+
out_shape=(grid_size[1], grid_size[0]),
|
|
1003
1015
|
transform=transform,
|
|
1004
1016
|
fill=0,
|
|
1005
1017
|
dtype=np.float64
|
|
1006
1018
|
)
|
|
1007
1019
|
|
|
1008
1020
|
# Convert to list format (simplified)
|
|
1021
|
+
# Convert raster (ny, nx) to internal orientation (nx, ny) with north-up
|
|
1022
|
+
building_height_grid = np.flipud(height_raster).T
|
|
1023
|
+
building_id_grid = np.flipud(id_raster).T
|
|
1024
|
+
min_heights = np.flipud(min_heights_raster).T
|
|
1025
|
+
|
|
1009
1026
|
for i in range(grid_size[0]):
|
|
1010
1027
|
for j in range(grid_size[1]):
|
|
1011
1028
|
if building_height_grid[i, j] > 0:
|
|
1012
1029
|
building_min_height_grid[i, j] = [[min_heights[i, j], building_height_grid[i, j]]]
|
|
1013
1030
|
else:
|
|
1014
1031
|
building_min_height_grid[i, j] = []
|
|
1015
|
-
|
|
1016
|
-
# Fix north-south orientation by flipping grids
|
|
1017
|
-
building_height_grid = np.flipud(building_height_grid)
|
|
1018
|
-
building_id_grid = np.flipud(building_id_grid)
|
|
1019
|
-
building_min_height_grid = np.flipud(building_min_height_grid)
|
|
1020
|
-
|
|
1032
|
+
|
|
1021
1033
|
return building_height_grid, building_min_height_grid, building_id_grid, filtered_gdf
|
|
1022
1034
|
|
|
1023
1035
|
def create_building_height_grid_from_open_building_temporal_polygon(meshsize, rectangle_vertices, output_dir):
|
|
@@ -16,7 +16,7 @@ voxcity/exporter/obj.py,sha256=h1_aInpemcsu96fSTwjKMqX2VZAFYbZbElWd4M1ogyI,27973
|
|
|
16
16
|
voxcity/generator.py,sha256=J61i6-bvgOlNQWgxlkSvOZ7CLAjRgh_XRYwslWkKxVM,55756
|
|
17
17
|
voxcity/geoprocessor/__init__.py,sha256=WYxcAQrjGucIvGHF0JTC6rONZzL3kCms1S2vpzS6KaU,127
|
|
18
18
|
voxcity/geoprocessor/draw.py,sha256=avXQwbGQWG3ZPPI8mwy0YN0K_aG4NMBdXI0vDg7yad0,35837
|
|
19
|
-
voxcity/geoprocessor/grid.py,sha256=
|
|
19
|
+
voxcity/geoprocessor/grid.py,sha256=D4sqoIGK2P1U8uuVQZ-447SD0Yrv6qS_zlmDtKoLDe8,71257
|
|
20
20
|
voxcity/geoprocessor/mesh.py,sha256=A7uaCMWfm82KEoYPfQYpxv6xMtQKaU2PBVDfKTpngqg,32027
|
|
21
21
|
voxcity/geoprocessor/network.py,sha256=YynqR0nq_NUra_cQ3Z_56KxfRia1b6-hIzGCj3QT-wE,25137
|
|
22
22
|
voxcity/geoprocessor/polygon.py,sha256=DfzXf6R-qoWXEZv1z1aHCVfr-DCuCFw6lieQT5cNHPA,61188
|
|
@@ -30,8 +30,8 @@ voxcity/utils/lc.py,sha256=722Gz3lPbgAp0mmTZ-g-QKBbAnbxrcgaYwb1sa7q8Sk,16189
|
|
|
30
30
|
voxcity/utils/material.py,sha256=H8K8Lq4wBL6dQtgj7esUW2U6wLCOTeOtelkTDJoRgMo,10007
|
|
31
31
|
voxcity/utils/visualization.py,sha256=ZR9N-XKfydeSStO53IM2hGXyZJoeBiAyIMWw9Cb2MPM,116449
|
|
32
32
|
voxcity/utils/weather.py,sha256=2Jtg-rIVJcsTtiKE-KuDnhIqS1-MSS16_zFRzj6zmu4,36435
|
|
33
|
-
voxcity-0.6.
|
|
34
|
-
voxcity-0.6.
|
|
35
|
-
voxcity-0.6.
|
|
36
|
-
voxcity-0.6.
|
|
37
|
-
voxcity-0.6.
|
|
33
|
+
voxcity-0.6.7.dist-info/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
|
|
34
|
+
voxcity-0.6.7.dist-info/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
|
|
35
|
+
voxcity-0.6.7.dist-info/METADATA,sha256=lICJOYiGbMdF2Lee90GLEP-KBz3S71jHDaHucZrYs7g,26091
|
|
36
|
+
voxcity-0.6.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
37
|
+
voxcity-0.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|