voxcity 0.5.29__tar.gz → 0.5.30__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.29 → voxcity-0.5.30}/PKG-INFO +1 -1
- {voxcity-0.5.29 → voxcity-0.5.30}/pyproject.toml +1 -1
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/draw.py +71 -19
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/polygon.py +1344 -1178
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity.egg-info/PKG-INFO +1 -1
- {voxcity-0.5.29 → voxcity-0.5.30}/AUTHORS.rst +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/CONTRIBUTING.rst +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/HISTORY.rst +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/LICENSE +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/MANIFEST.in +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/README.md +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/docs/Makefile +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/docs/_static/logo.png +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/docs/conf.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/docs/logo.png +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/docs/make.bat +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/setup.cfg +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/citygml.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/eubucco.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/gee.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/mbfp.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/oemj.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/osm.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/overture.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/downloader/utils.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/exporter/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/exporter/cityles.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/exporter/envimet.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/exporter/magicavoxel.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/exporter/obj.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/generator.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/grid.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/mesh.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/network.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/geoprocessor/utils.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/simulator/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/simulator/solar.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/simulator/utils.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/simulator/view.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/utils/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/utils/lc.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/utils/material.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/utils/visualization.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity/utils/weather.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity.egg-info/SOURCES.txt +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity.egg-info/dependency_links.txt +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity.egg-info/requires.txt +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/src/voxcity.egg-info/top_level.txt +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/tests/__init__.py +0 -0
- {voxcity-0.5.29 → voxcity-0.5.30}/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.30
|
|
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>
|
|
@@ -372,6 +372,7 @@ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=Non
|
|
|
372
372
|
- Enables free-form polygon drawing
|
|
373
373
|
- Captures vertices in consistent (lon,lat) format
|
|
374
374
|
- Maintains GeoJSON compatibility
|
|
375
|
+
- Supports multiple polygons with unique IDs and colors
|
|
375
376
|
|
|
376
377
|
3. Map Initialization:
|
|
377
378
|
- Automatic centering based on input data
|
|
@@ -391,10 +392,10 @@ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=Non
|
|
|
391
392
|
Default of 17 is optimized for building-level detail.
|
|
392
393
|
|
|
393
394
|
Returns:
|
|
394
|
-
tuple: (map_object,
|
|
395
|
+
tuple: (map_object, drawn_polygons)
|
|
395
396
|
- map_object: ipyleaflet Map instance with building footprints and drawing controls
|
|
396
|
-
-
|
|
397
|
-
|
|
397
|
+
- drawn_polygons: List of dictionaries with 'id', 'vertices', and 'color' keys for all drawn polygons.
|
|
398
|
+
Each polygon has a unique ID and color for easy identification.
|
|
398
399
|
|
|
399
400
|
Note:
|
|
400
401
|
- Building footprints are displayed in blue with 20% opacity
|
|
@@ -402,6 +403,8 @@ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=Non
|
|
|
402
403
|
- Drawing tools are restricted to polygon creation only
|
|
403
404
|
- All coordinates are handled in (lon,lat) order internally
|
|
404
405
|
- The function automatically determines appropriate map bounds
|
|
406
|
+
- Each polygon gets a unique ID and different colors for easy identification
|
|
407
|
+
- Use get_polygon_vertices() helper function to extract specific polygon data
|
|
405
408
|
"""
|
|
406
409
|
# ---------------------------------------------------------
|
|
407
410
|
# 1. Determine a suitable map center via bounding box logic
|
|
@@ -452,7 +455,10 @@ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=Non
|
|
|
452
455
|
# -----------------------------------------------------------------
|
|
453
456
|
# 3. Enable drawing of polygons, capturing the vertices in Lon-Lat
|
|
454
457
|
# -----------------------------------------------------------------
|
|
455
|
-
|
|
458
|
+
# Store multiple polygons with IDs and colors
|
|
459
|
+
drawn_polygons = [] # List of dicts with 'id', 'vertices', 'color' keys
|
|
460
|
+
polygon_counter = 0
|
|
461
|
+
polygon_colors = ['red', 'blue', 'green', 'orange', 'purple', 'brown', 'pink', 'gray', 'olive', 'cyan']
|
|
456
462
|
|
|
457
463
|
draw_control = DrawControl(
|
|
458
464
|
polygon={
|
|
@@ -475,27 +481,36 @@ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=Non
|
|
|
475
481
|
ipyleaflet's DrawControl returns standard GeoJSON (lon, lat).
|
|
476
482
|
We'll keep them as (lon, lat).
|
|
477
483
|
"""
|
|
478
|
-
# Clear any previously stored vertices
|
|
479
|
-
drawn_polygon_vertices.clear()
|
|
480
|
-
|
|
481
484
|
if action == 'created' and geo_json['geometry']['type'] == 'Polygon':
|
|
485
|
+
nonlocal polygon_counter
|
|
486
|
+
polygon_counter += 1
|
|
487
|
+
|
|
482
488
|
# The polygon's first ring
|
|
483
489
|
coordinates = geo_json['geometry']['coordinates'][0]
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
#
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
490
|
+
vertices = [(coord[0], coord[1]) for coord in coordinates[:-1]]
|
|
491
|
+
|
|
492
|
+
# Assign color (cycle through colors)
|
|
493
|
+
color = polygon_colors[polygon_counter % len(polygon_colors)]
|
|
494
|
+
|
|
495
|
+
# Store polygon data
|
|
496
|
+
polygon_data = {
|
|
497
|
+
'id': polygon_counter,
|
|
498
|
+
'vertices': vertices,
|
|
499
|
+
'color': color
|
|
500
|
+
}
|
|
501
|
+
drawn_polygons.append(polygon_data)
|
|
502
|
+
|
|
503
|
+
print(f"Polygon {polygon_counter} drawn with {len(vertices)} vertices (color: {color}):")
|
|
504
|
+
for i, (lon, lat) in enumerate(vertices):
|
|
505
|
+
print(f" Vertex {i+1}: (lon, lat) = ({lon}, {lat})")
|
|
506
|
+
print(f"Total polygons: {len(drawn_polygons)}")
|
|
492
507
|
|
|
493
508
|
draw_control.on_draw(handle_draw)
|
|
494
509
|
m.add_control(draw_control)
|
|
495
510
|
|
|
496
|
-
return m,
|
|
511
|
+
return m, drawn_polygons
|
|
497
512
|
|
|
498
|
-
def draw_additional_buildings(building_gdf=None, initial_center=None, zoom=17):
|
|
513
|
+
def draw_additional_buildings(building_gdf=None, initial_center=None, zoom=17, rectangle_vertices=None):
|
|
499
514
|
"""
|
|
500
515
|
Creates an interactive map for drawing building footprints with height input.
|
|
501
516
|
|
|
@@ -563,6 +578,8 @@ def draw_additional_buildings(building_gdf=None, initial_center=None, zoom=17):
|
|
|
563
578
|
min_lon, min_lat, max_lon, max_lat = bounds
|
|
564
579
|
center_lon = (min_lon + max_lon) / 2
|
|
565
580
|
center_lat = (min_lat + max_lat) / 2
|
|
581
|
+
elif rectangle_vertices is not None:
|
|
582
|
+
center_lon, center_lat = (rectangle_vertices[0][0] + rectangle_vertices[2][0]) / 2, (rectangle_vertices[0][1] + rectangle_vertices[2][1]) / 2
|
|
566
583
|
else:
|
|
567
584
|
center_lon, center_lat = -100.0, 40.0
|
|
568
585
|
|
|
@@ -758,8 +775,43 @@ def draw_additional_buildings(building_gdf=None, initial_center=None, zoom=17):
|
|
|
758
775
|
return m, updated_gdf
|
|
759
776
|
|
|
760
777
|
|
|
778
|
+
def get_polygon_vertices(drawn_polygons, polygon_id=None):
|
|
779
|
+
"""
|
|
780
|
+
Extract vertices from drawn polygons data structure.
|
|
781
|
+
|
|
782
|
+
This helper function provides a convenient way to extract polygon vertices
|
|
783
|
+
from the drawn_polygons list returned by display_buildings_and_draw_polygon().
|
|
784
|
+
|
|
785
|
+
Args:
|
|
786
|
+
drawn_polygons: The drawn_polygons list returned from display_buildings_and_draw_polygon()
|
|
787
|
+
polygon_id (int, optional): Specific polygon ID to extract. If None, returns all polygons.
|
|
788
|
+
|
|
789
|
+
Returns:
|
|
790
|
+
If polygon_id is specified: List of (lon, lat) tuples for that polygon
|
|
791
|
+
If polygon_id is None: List of lists, where each inner list contains (lon, lat) tuples
|
|
792
|
+
|
|
793
|
+
Example:
|
|
794
|
+
>>> m, polygons = display_buildings_and_draw_polygon()
|
|
795
|
+
>>> # Draw some polygons...
|
|
796
|
+
>>> vertices = get_polygon_vertices(polygons, polygon_id=1) # Get polygon 1
|
|
797
|
+
>>> all_vertices = get_polygon_vertices(polygons) # Get all polygons
|
|
798
|
+
"""
|
|
799
|
+
if not drawn_polygons:
|
|
800
|
+
return []
|
|
801
|
+
|
|
802
|
+
if polygon_id is not None:
|
|
803
|
+
# Return specific polygon
|
|
804
|
+
for polygon in drawn_polygons:
|
|
805
|
+
if polygon['id'] == polygon_id:
|
|
806
|
+
return polygon['vertices']
|
|
807
|
+
return [] # Polygon not found
|
|
808
|
+
else:
|
|
809
|
+
# Return all polygons
|
|
810
|
+
return [polygon['vertices'] for polygon in drawn_polygons]
|
|
811
|
+
|
|
812
|
+
|
|
761
813
|
# Simple convenience function
|
|
762
|
-
def create_building_editor(building_gdf=None, initial_center=None, zoom=17):
|
|
814
|
+
def create_building_editor(building_gdf=None, initial_center=None, zoom=17, rectangle_vertices=None):
|
|
763
815
|
"""
|
|
764
816
|
Creates and displays an interactive building editor.
|
|
765
817
|
|
|
@@ -776,6 +828,6 @@ def create_building_editor(building_gdf=None, initial_center=None, zoom=17):
|
|
|
776
828
|
>>> # Draw buildings on the displayed map
|
|
777
829
|
>>> print(buildings) # Automatically contains all drawn buildings
|
|
778
830
|
"""
|
|
779
|
-
m, gdf = draw_additional_buildings(building_gdf, initial_center, zoom)
|
|
831
|
+
m, gdf = draw_additional_buildings(building_gdf, initial_center, zoom, rectangle_vertices)
|
|
780
832
|
display(m)
|
|
781
833
|
return gdf
|