File size: 3,942 Bytes
bc686cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt

def process_buildings(input_gdf, sensitive_sites_gdf, default_building_height_m, multiplier_factor):
    # List to store all intersected sensitive sites
    intersected_sites = []
    
    # List to store all buffers
    buffers = []

    intersection_desc = ""
    
    # Iterate over each building in the input file
    for idx, building in input_gdf.iterrows():
        building_name = building.get('building_name', 'Unnamed building')
        
        # If the 'building_height' field exists and its value is not null or zero for this building,
        # use it as the building height. Otherwise, use the default building height provided by the user.
        if 'building_height' in building and pd.notnull(building['building_height']) and building['building_height'] != 0:
            building_height_m = building['building_height'] * 0.3048
        else:
            building_height_m = default_building_height_m

        buffer_distance_m = building_height_m * multiplier_factor

        # Convert building's geometry to EPSG:3857 for accurate meter-based distance measurement
        building_geometry = gpd.GeoSeries([building['geometry']], crs="EPSG:4326")
        building_geometry_m = building_geometry.to_crs("EPSG:3857")

        # Create a buffer around the building and convert it to a GeoDataFrame
        building_buffer = building_geometry_m.buffer(buffer_distance_m)
        building_buffer_gdf = gpd.GeoDataFrame(geometry=building_buffer, crs="EPSG:3857")
        building_buffer_gdf = building_buffer_gdf.to_crs("EPSG:4326")

        # Convert back to feet for storing and printing, rounding to the nearest foot
        building_height_ft = round(building_height_m / 0.3048)
        buffer_distance_ft = round(buffer_distance_m / 0.3048)

        # Assign additional attributes
        building_buffer_gdf['building_name'] = building_name
        building_buffer_gdf['building_height'] = building_height_ft
        building_buffer_gdf['buffer_distance'] = buffer_distance_ft

        buffers.append(building_buffer_gdf)

        # Check if the buffer intersects with any sensitive sites
        intersects = gpd.overlay(building_buffer_gdf, sensitive_sites_gdf, how='intersection')
        
        if not intersects.empty:
            building_intersect_desc = f"Building {idx} ({building_name}), height: {building_height_ft}, buffer distance: {buffer_distance_ft} is in the vicinity of a sensitive site."
            intersected_sites.append(intersects)
        else:
            building_intersect_desc = f"Building {idx} ({building_name}), height: {building_height_ft}, buffer distance: {buffer_distance_ft} is not in the vicinity of any sensitive sites."

        if intersection_desc == "":
            intersection_desc = building_intersect_desc
        else:
            intersection_desc += "\n" + building_intersect_desc
    
    return buffers, intersected_sites, intersection_desc

def get_max_extent(*gdfs): # takes in unlimited number of gdfs and calculates max/min xy extents
    minx = min(gdf.total_bounds[0] for gdf in gdfs)
    miny = min(gdf.total_bounds[1] for gdf in gdfs)
    maxx = max(gdf.total_bounds[2] for gdf in gdfs)
    maxy = max(gdf.total_bounds[3] for gdf in gdfs)
    
    return minx, miny, maxx, maxy

def create_plot(filename, extent, *gdfs): # takes in unlimited number of gdfs
    fig, ax = plt.subplots(figsize=(10, 8)) #Sets image size by width & height (in inches)
    
    colors = ['tan', 'mediumseagreen', 'thistle', 'lightcoral', 'sienna', 'yellow'] # Extend/improve this list as needed

    for idx, gdf in enumerate(gdfs):
        gdf.plot(ax=ax, color=colors[idx % len(colors)]) # Cycle through colors

    ax.set_xlim(extent[0], extent[2])
    ax.set_ylim(extent[1], extent[3])

    # Hide axes
    ax.axis('off')

    plt.savefig(filename, bbox_inches='tight', pad_inches=0) # remove padding