voxcity 0.6.12__tar.gz → 0.6.14__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.6.12 → voxcity-0.6.14}/PKG-INFO +1 -1
- {voxcity-0.6.12 → voxcity-0.6.14}/pyproject.toml +1 -1
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/draw.py +95 -6
- {voxcity-0.6.12 → voxcity-0.6.14}/AUTHORS.rst +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/LICENSE +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/README.md +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/citygml.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/eubucco.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/gee.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/mbfp.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/oemj.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/osm.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/overture.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/downloader/utils.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/exporter/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/exporter/cityles.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/exporter/envimet.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/exporter/magicavoxel.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/exporter/obj.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/generator.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/grid.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/mesh.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/network.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/polygon.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/geoprocessor/utils.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/simulator/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/simulator/solar.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/simulator/utils.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/simulator/view.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/utils/__init__.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/utils/lc.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/utils/material.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/utils/visualization.py +0 -0
- {voxcity-0.6.12 → voxcity-0.6.14}/src/voxcity/utils/weather.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "voxcity"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.14"
|
|
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"
|
|
@@ -33,12 +33,13 @@ from ipyleaflet import (
|
|
|
33
33
|
WidgetControl,
|
|
34
34
|
Circle,
|
|
35
35
|
basemaps,
|
|
36
|
-
basemap_to_tiles
|
|
36
|
+
basemap_to_tiles,
|
|
37
|
+
TileLayer
|
|
37
38
|
)
|
|
38
39
|
from geopy import distance
|
|
39
40
|
import shapely.geometry as geom
|
|
40
41
|
import geopandas as gpd
|
|
41
|
-
from ipywidgets import VBox, HBox, Button, FloatText, Label, Output, HTML
|
|
42
|
+
from ipywidgets import VBox, HBox, Button, FloatText, Label, Output, HTML, Checkbox
|
|
42
43
|
import pandas as pd
|
|
43
44
|
from IPython.display import display, clear_output
|
|
44
45
|
|
|
@@ -885,12 +886,21 @@ def draw_additional_trees(tree_gdf=None, initial_center=None, zoom=17, rectangle
|
|
|
885
886
|
|
|
886
887
|
# Create map
|
|
887
888
|
m = Map(center=(center_lat, center_lon), zoom=zoom, scroll_wheel_zoom=True)
|
|
888
|
-
# Add
|
|
889
|
+
# Add Google Satellite basemap with Esri fallback
|
|
889
890
|
try:
|
|
890
|
-
|
|
891
|
+
google_sat = TileLayer(
|
|
892
|
+
url='https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
|
|
893
|
+
name='Google Satellite',
|
|
894
|
+
attribution='Google Satellite'
|
|
895
|
+
)
|
|
896
|
+
# Replace default base layer with Google Satellite
|
|
897
|
+
m.layers = tuple([google_sat])
|
|
891
898
|
except Exception:
|
|
892
|
-
|
|
893
|
-
|
|
899
|
+
try:
|
|
900
|
+
m.layers = tuple([basemap_to_tiles(basemaps.Esri.WorldImagery)])
|
|
901
|
+
except Exception:
|
|
902
|
+
# Fallback silently if basemap cannot be added
|
|
903
|
+
pass
|
|
894
904
|
|
|
895
905
|
# If rectangle_vertices provided, draw its edges on the map
|
|
896
906
|
if rectangle_vertices is not None and len(rectangle_vertices) >= 4:
|
|
@@ -924,6 +934,7 @@ def draw_additional_trees(tree_gdf=None, initial_center=None, zoom=17, rectangle
|
|
|
924
934
|
top_height_input = FloatText(value=10.0, description='Top height (m):', disabled=False, style={'description_width': 'initial'})
|
|
925
935
|
bottom_height_input = FloatText(value=4.0, description='Bottom height (m):', disabled=False, style={'description_width': 'initial'})
|
|
926
936
|
crown_diameter_input = FloatText(value=6.0, description='Crown diameter (m):', disabled=False, style={'description_width': 'initial'})
|
|
937
|
+
fixed_prop_checkbox = Checkbox(value=True, description='Fixed proportion', indent=False)
|
|
927
938
|
|
|
928
939
|
add_mode_button = Button(description='Add', button_style='success')
|
|
929
940
|
remove_mode_button = Button(description='Remove', button_style='')
|
|
@@ -937,6 +948,7 @@ def draw_additional_trees(tree_gdf=None, initial_center=None, zoom=17, rectangle
|
|
|
937
948
|
top_height_input,
|
|
938
949
|
bottom_height_input,
|
|
939
950
|
crown_diameter_input,
|
|
951
|
+
fixed_prop_checkbox,
|
|
940
952
|
hover_info,
|
|
941
953
|
status_output
|
|
942
954
|
])
|
|
@@ -946,6 +958,83 @@ def draw_additional_trees(tree_gdf=None, initial_center=None, zoom=17, rectangle
|
|
|
946
958
|
|
|
947
959
|
# State for mode
|
|
948
960
|
mode = 'add'
|
|
961
|
+
# Fixed proportion state
|
|
962
|
+
base_bottom_ratio = bottom_height_input.value / top_height_input.value if top_height_input.value else 0.4
|
|
963
|
+
base_crown_ratio = crown_diameter_input.value / top_height_input.value if top_height_input.value else 0.6
|
|
964
|
+
updating_params = False
|
|
965
|
+
|
|
966
|
+
def recompute_from_top(new_top: float):
|
|
967
|
+
nonlocal updating_params
|
|
968
|
+
if new_top <= 0:
|
|
969
|
+
return
|
|
970
|
+
new_bottom = max(0.0, base_bottom_ratio * new_top)
|
|
971
|
+
new_crown = max(0.0, base_crown_ratio * new_top)
|
|
972
|
+
updating_params = True
|
|
973
|
+
bottom_height_input.value = new_bottom
|
|
974
|
+
crown_diameter_input.value = new_crown
|
|
975
|
+
updating_params = False
|
|
976
|
+
|
|
977
|
+
def recompute_from_bottom(new_bottom: float):
|
|
978
|
+
nonlocal updating_params
|
|
979
|
+
if base_bottom_ratio <= 0:
|
|
980
|
+
return
|
|
981
|
+
new_top = max(0.0, new_bottom / base_bottom_ratio)
|
|
982
|
+
new_crown = max(0.0, base_crown_ratio * new_top)
|
|
983
|
+
updating_params = True
|
|
984
|
+
top_height_input.value = new_top
|
|
985
|
+
crown_diameter_input.value = new_crown
|
|
986
|
+
updating_params = False
|
|
987
|
+
|
|
988
|
+
def recompute_from_crown(new_crown: float):
|
|
989
|
+
nonlocal updating_params
|
|
990
|
+
if base_crown_ratio <= 0:
|
|
991
|
+
return
|
|
992
|
+
new_top = max(0.0, new_crown / base_crown_ratio)
|
|
993
|
+
new_bottom = max(0.0, base_bottom_ratio * new_top)
|
|
994
|
+
updating_params = True
|
|
995
|
+
top_height_input.value = new_top
|
|
996
|
+
bottom_height_input.value = new_bottom
|
|
997
|
+
updating_params = False
|
|
998
|
+
|
|
999
|
+
def on_toggle_fixed(change):
|
|
1000
|
+
nonlocal base_bottom_ratio, base_crown_ratio
|
|
1001
|
+
if change['name'] == 'value':
|
|
1002
|
+
if change['new']:
|
|
1003
|
+
# Capture current ratios as baseline
|
|
1004
|
+
top = float(top_height_input.value) or 1.0
|
|
1005
|
+
bot = float(bottom_height_input.value)
|
|
1006
|
+
crn = float(crown_diameter_input.value)
|
|
1007
|
+
base_bottom_ratio = max(0.0, bot / top)
|
|
1008
|
+
base_crown_ratio = max(0.0, crn / top)
|
|
1009
|
+
else:
|
|
1010
|
+
# Keep last ratios but do not auto-update
|
|
1011
|
+
pass
|
|
1012
|
+
|
|
1013
|
+
def on_top_change(change):
|
|
1014
|
+
if change['name'] == 'value' and fixed_prop_checkbox.value and not updating_params:
|
|
1015
|
+
try:
|
|
1016
|
+
recompute_from_top(float(change['new']))
|
|
1017
|
+
except Exception:
|
|
1018
|
+
pass
|
|
1019
|
+
|
|
1020
|
+
def on_bottom_change(change):
|
|
1021
|
+
if change['name'] == 'value' and fixed_prop_checkbox.value and not updating_params:
|
|
1022
|
+
try:
|
|
1023
|
+
recompute_from_bottom(float(change['new']))
|
|
1024
|
+
except Exception:
|
|
1025
|
+
pass
|
|
1026
|
+
|
|
1027
|
+
def on_crown_change(change):
|
|
1028
|
+
if change['name'] == 'value' and fixed_prop_checkbox.value and not updating_params:
|
|
1029
|
+
try:
|
|
1030
|
+
recompute_from_crown(float(change['new']))
|
|
1031
|
+
except Exception:
|
|
1032
|
+
pass
|
|
1033
|
+
|
|
1034
|
+
fixed_prop_checkbox.observe(on_toggle_fixed, names='value')
|
|
1035
|
+
top_height_input.observe(on_top_change, names='value')
|
|
1036
|
+
bottom_height_input.observe(on_bottom_change, names='value')
|
|
1037
|
+
crown_diameter_input.observe(on_crown_change, names='value')
|
|
949
1038
|
|
|
950
1039
|
def set_mode(new_mode):
|
|
951
1040
|
nonlocal mode
|
|
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
|