psalama commited on
Commit
b939fb6
·
1 Parent(s): 192f0dd

Modularize python code

Browse files
Files changed (1) hide show
  1. data.py +88 -0
data.py CHANGED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import geopandas as gpd
2
+ import pandas as pd
3
+ from arcgis.features import FeatureLayer
4
+ from arcgis.geometry import Geometry
5
+ from shapely.geometry import shape
6
+ from shapely.ops import unary_union
7
+
8
+ # all data processing functions
9
+ def get_gdf_from_feature_layer(url):
10
+ # Access the ArcGIS feature layer
11
+ feature_layer = FeatureLayer(url)
12
+
13
+ # Use the query() method to get all features where 'Borough' is 'MN'
14
+ sdf = feature_layer.query(where="Borough='MN'", out_sr=4326, as_df=True)
15
+
16
+ # Convert the 'SHAPE' column from ArcGIS's JSON-based format into a Shapely geometry
17
+ sdf['geometry'] = sdf['SHAPE'].apply(lambda x: Geometry(x).as_shapely)
18
+
19
+ # Convert the SpatialDataFrame to a GeoDataFrame
20
+ gdf = gpd.GeoDataFrame(sdf, geometry='geometry')
21
+
22
+ return gdf
23
+
24
+ def process_buildings(input_gdf, sensitive_sites_gdf, default_building_height_m, multiplier_factor):
25
+ # List to store all intersected sensitive sites
26
+ intersected_sites = []
27
+
28
+ # List to store all buffers
29
+ buffers = []
30
+
31
+ intersection_desc = ""
32
+
33
+ # Iterate over each building in the input file
34
+ for idx, building in input_gdf.iterrows():
35
+ building_name = building.get('building_name', 'Unnamed building')
36
+
37
+ # If the 'building_height' field exists and its value is not null or zero for this building,
38
+ # use it as the building height. Otherwise, use the default building height provided by the user.
39
+ if 'building_height' in building and pd.notnull(building['building_height']) and building['building_height'] != 0:
40
+ building_height_m = building['building_height'] * 0.3048
41
+ else:
42
+ building_height_m = default_building_height_m
43
+
44
+ buffer_distance_m = building_height_m * multiplier_factor
45
+
46
+ # Convert building's geometry to EPSG:3857 for accurate meter-based distance measurement
47
+ building_geometry = gpd.GeoSeries([building['geometry']], crs="EPSG:4326")
48
+ building_geometry_m = building_geometry.to_crs("EPSG:3857")
49
+
50
+ # Create a buffer around the building and convert it to a GeoDataFrame
51
+ building_buffer = building_geometry_m.buffer(buffer_distance_m)
52
+ building_buffer_gdf = gpd.GeoDataFrame(geometry=building_buffer, crs="EPSG:3857")
53
+ building_buffer_gdf = building_buffer_gdf.to_crs("EPSG:4326")
54
+
55
+ # Convert back to feet for storing and printing, rounding to the nearest foot
56
+ building_height_ft = round(building_height_m / 0.3048)
57
+ buffer_distance_ft = round(buffer_distance_m / 0.3048)
58
+
59
+ # Assign additional attributes
60
+ building_buffer_gdf['building_name'] = building_name
61
+ building_buffer_gdf['building_height'] = building_height_ft
62
+ building_buffer_gdf['buffer_distance'] = buffer_distance_ft
63
+
64
+ buffers.append(building_buffer_gdf)
65
+
66
+ # Check if the buffer intersects with any sensitive sites
67
+ intersects = gpd.overlay(building_buffer_gdf, sensitive_sites_gdf, how='intersection')
68
+
69
+ if not intersects.empty:
70
+ 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."
71
+ intersected_sites.append(intersects)
72
+ else:
73
+ 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."
74
+
75
+ if intersection_desc == "":
76
+ intersection_desc = building_intersect_desc
77
+ else:
78
+ intersection_desc += "\n" + building_intersect_desc
79
+
80
+ return buffers, intersected_sites, intersection_desc
81
+
82
+ def get_max_extent(*gdfs): # takes in unlimited number of gdfs and calculates max/min xy extents
83
+ minx = min(gdf.total_bounds[0] for gdf in gdfs)
84
+ miny = min(gdf.total_bounds[1] for gdf in gdfs)
85
+ maxx = max(gdf.total_bounds[2] for gdf in gdfs)
86
+ maxy = max(gdf.total_bounds[3] for gdf in gdfs)
87
+
88
+ return minx, miny, maxx, maxy