Spaces:
Build error
Build error
| 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 |