psalama commited on
Commit
e456660
·
1 Parent(s): 2ac7da0

Modularize - split app.py

Browse files
Files changed (1) hide show
  1. app.py +7 -101
app.py CHANGED
@@ -2,113 +2,19 @@ import gradio as gr
2
  import geopandas as gpd
3
  import pandas as pd
4
  import os
5
- import matplotlib.pyplot as plt
6
- from arcgis.features import FeatureLayer
7
- from arcgis.geometry import Geometry
8
- from shapely.geometry import shape
9
  from shapely.ops import unary_union
10
  #from datasets import load_dataset
11
 
12
  #ds = load_dataset('psalama/NYC_sensitive_sites', data_files=data_files)
13
 
 
 
 
14
 
15
- def get_gdf_from_feature_layer(url):
16
- # Access the ArcGIS feature layer
17
- feature_layer = FeatureLayer(url)
18
-
19
- # Use the query() method to get all features where 'Borough' is 'MN'
20
- sdf = feature_layer.query(where="Borough='MN'", out_sr=4326, as_df=True)
21
-
22
- # Convert the 'SHAPE' column from ArcGIS's JSON-based format into a Shapely geometry
23
- sdf['geometry'] = sdf['SHAPE'].apply(lambda x: Geometry(x).as_shapely)
24
-
25
- # Convert the SpatialDataFrame to a GeoDataFrame
26
- gdf = gpd.GeoDataFrame(sdf, geometry='geometry')
27
-
28
- return gdf
29
-
30
-
31
- def process_buildings(input_gdf, sensitive_sites_gdf, default_building_height_m, multiplier_factor):
32
- # List to store all intersected sensitive sites
33
- intersected_sites = []
34
-
35
- # List to store all buffers
36
- buffers = []
37
-
38
- intersection_desc = ""
39
-
40
- # Iterate over each building in the input file
41
- for idx, building in input_gdf.iterrows():
42
- building_name = building.get('building_name', 'Unnamed building')
43
-
44
- # If the 'building_height' field exists and its value is not null or zero for this building,
45
- # use it as the building height. Otherwise, use the default building height provided by the user.
46
- if 'building_height' in building and pd.notnull(building['building_height']) and building['building_height'] != 0:
47
- building_height_m = building['building_height'] * 0.3048
48
- else:
49
- building_height_m = default_building_height_m
50
-
51
- buffer_distance_m = building_height_m * multiplier_factor
52
-
53
- # Convert building's geometry to EPSG:3857 for accurate meter-based distance measurement
54
- building_geometry = gpd.GeoSeries([building['geometry']], crs="EPSG:4326")
55
- building_geometry_m = building_geometry.to_crs("EPSG:3857")
56
-
57
- # Create a buffer around the building and convert it to a GeoDataFrame
58
- building_buffer = building_geometry_m.buffer(buffer_distance_m)
59
- building_buffer_gdf = gpd.GeoDataFrame(geometry=building_buffer, crs="EPSG:3857")
60
- building_buffer_gdf = building_buffer_gdf.to_crs("EPSG:4326")
61
-
62
- # Convert back to feet for storing and printing, rounding to the nearest foot
63
- building_height_ft = round(building_height_m / 0.3048)
64
- buffer_distance_ft = round(buffer_distance_m / 0.3048)
65
-
66
- # Assign additional attributes
67
- building_buffer_gdf['building_name'] = building_name
68
- building_buffer_gdf['building_height'] = building_height_ft
69
- building_buffer_gdf['buffer_distance'] = buffer_distance_ft
70
-
71
- buffers.append(building_buffer_gdf)
72
-
73
- # Check if the buffer intersects with any sensitive sites
74
- intersects = gpd.overlay(building_buffer_gdf, sensitive_sites_gdf, how='intersection')
75
-
76
- if not intersects.empty:
77
- 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."
78
- intersected_sites.append(intersects)
79
- else:
80
- 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."
81
-
82
- if intersection_desc == "":
83
- intersection_desc = building_intersect_desc
84
- else:
85
- intersection_desc += "\n" + building_intersect_desc
86
-
87
- return buffers, intersected_sites, intersection_desc
88
-
89
- def get_max_extent(*gdfs): # takes in unlimited number of gdfs and calculates max/min xy extents
90
- minx = min(gdf.total_bounds[0] for gdf in gdfs)
91
- miny = min(gdf.total_bounds[1] for gdf in gdfs)
92
- maxx = max(gdf.total_bounds[2] for gdf in gdfs)
93
- maxy = max(gdf.total_bounds[3] for gdf in gdfs)
94
-
95
- return minx, miny, maxx, maxy
96
-
97
- def create_plot(filename, extent, *gdfs): # takes in unlimited number of gdfs
98
- fig, ax = plt.subplots(figsize=(10, 8)) #Sets image size by width & height (in inches)
99
-
100
- colors = ['tan', 'mediumseagreen', 'thistle', 'lightcoral', 'sienna', 'yellow'] # Extend/improve this list as needed
101
-
102
- for idx, gdf in enumerate(gdfs):
103
- gdf.plot(ax=ax, color=colors[idx % len(colors)]) # Cycle through colors
104
-
105
- ax.set_xlim(extent[0], extent[2])
106
- ax.set_ylim(extent[1], extent[3])
107
-
108
- # Hide axes
109
- ax.axis('off')
110
-
111
- plt.savefig(filename, bbox_inches='tight', pad_inches=0) # remove padding
112
 
113
  def ss_intersect(geojson1, ss_geoselect, multiplier_factor, default_building_height):
114
  # Read the GeoJSON files
 
2
  import geopandas as gpd
3
  import pandas as pd
4
  import os
5
+ #import matplotlib.pyplot as plt
6
+ #from arcgis.features import FeatureLayer
7
+ #from arcgis.geometry import Geometry
8
+ #from shapely.geometry import shape
9
  from shapely.ops import unary_union
10
  #from datasets import load_dataset
11
 
12
  #ds = load_dataset('psalama/NYC_sensitive_sites', data_files=data_files)
13
 
14
+ # Import functions from modules in data.py and plot.py
15
+ from data import get_gdf_from_feature_layer, process_buildings, get_max_extent
16
+ from plot import create_plot
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  def ss_intersect(geojson1, ss_geoselect, multiplier_factor, default_building_height):
20
  # Read the GeoJSON files