voxcity 0.5.29__py3-none-any.whl → 0.5.30__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.

@@ -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, drawn_polygon_vertices)
395
+ tuple: (map_object, drawn_polygons)
395
396
  - map_object: ipyleaflet Map instance with building footprints and drawing controls
396
- - drawn_polygon_vertices: List that gets updated with (lon,lat) coordinates
397
- whenever a new polygon is drawn. Coordinates are in GeoJSON order.
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
- drawn_polygon_vertices = [] # We'll store the newly drawn polygon's vertices here (lon, lat).
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
- print("Vertices of the drawn polygon (Lon-Lat):")
485
-
486
- # Keep GeoJSON (lon,lat) format, skip last repeated coordinate
487
- for coord in coordinates[:-1]:
488
- lon = coord[0]
489
- lat = coord[1]
490
- drawn_polygon_vertices.append((lon, lat))
491
- print(f" - (lon, lat) = ({lon}, {lat})")
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, drawn_polygon_vertices
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