Alealejandrooo commited on
Commit
31801e9
1 Parent(s): 8f31a79

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +83 -0
  2. ingest.py +15 -0
  3. process.py +32 -0
app.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from folium.plugins import HeatMap
3
+ from ingest import load_data
4
+ from process import get_lat_lon
5
+ from gradio_folium import Folium
6
+ from folium import Map
7
+
8
+
9
+ def update_header(file_info):
10
+ if file_info is not None:
11
+ filename = file_info.split('/')[-1] # Access the filename from the file_info dictionary
12
+ header = f"<h1>Nordic Balance Postcodes Map: {filename}</h1>" # Update the Markdown content
13
+ return header # Continue to pass the file_info to the next function if necessary
14
+
15
+ def generate_map(file_path):
16
+ # Load the postcodes
17
+ postcode_mapping = load_data('../data/ukpostcodes.csv')
18
+ # Load the data (this needs to be adapted to work outside Flask)
19
+ postcodes = load_data(file_path)
20
+
21
+ # Get latitude, longitude, and count data for the specified postcodes
22
+ lat_lon_data = get_lat_lon(postcodes, postcode_mapping)
23
+
24
+ # Prepare data for different frequency bands
25
+ low_freq_data = [
26
+ [data['latitude'], data['longitude']]
27
+ for data in lat_lon_data
28
+ if data['count'] == 1 and data['latitude'] and data['longitude']
29
+ ]
30
+ med_freq_data = [
31
+ [data['latitude'], data['longitude']]
32
+ for data in lat_lon_data
33
+ if 2 <= data['count'] <= 5 and data['latitude'] and data['longitude']
34
+ ]
35
+ high_freq_data = [
36
+ [data['latitude'], data['longitude']]
37
+ for data in lat_lon_data
38
+ if data['count'] > 5 and data['latitude'] and data['longitude']
39
+ ]
40
+
41
+ # Create your map here using Folium
42
+ map = Map(location=[51.505303, -0.13902], zoom_start=10)
43
+
44
+ # Adding different heatmaps for different frequencies
45
+ if low_freq_data:
46
+ HeatMap(low_freq_data, radius=10, blur=10, gradient={0.8: 'blue', 1: 'lime'}).add_to(map)
47
+ if med_freq_data:
48
+ HeatMap(med_freq_data, radius=15, blur=10, gradient={0.8: 'orange', 1: 'lime'}).add_to(map)
49
+ if high_freq_data:
50
+ HeatMap(high_freq_data, radius=20, blur=10, gradient={0.8: 'red', 1: 'lime'}).add_to(map)
51
+
52
+ return map
53
+
54
+ # Define a Gradio interface
55
+ with gr.Blocks() as demo:
56
+
57
+ with gr.Row():
58
+ header = gr.Markdown(("<h1>Nordic Balance Postcodes Map</h1>"))
59
+
60
+ with gr.Row():
61
+ map = Folium(value = Map(location=[51.505303, -0.13902], zoom_start=10), height=750)
62
+
63
+
64
+ with gr.Row():
65
+ file_uploader = gr.UploadButton(
66
+ label=("Upload"),
67
+ file_count="single",
68
+ file_types=[".csv", ".xlsx", '.xls'],
69
+ interactive=True,
70
+ scale=1,
71
+ )
72
+
73
+ file_uploader.upload(fn = generate_map,
74
+ inputs= file_uploader,
75
+ outputs=map)
76
+
77
+ file_uploader.upload(fn=update_header,
78
+ inputs=file_uploader,
79
+ outputs=header)
80
+
81
+
82
+ if __name__ == "__main__":
83
+ demo.launch()
ingest.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ def load_data(filepath):
4
+ # Check the file extension and load the file accordingly
5
+ if filepath.endswith('.csv'):
6
+ df = pd.read_csv(filepath)
7
+ elif filepath.endswith('.xlsx') or filepath.endswith('.xls'):
8
+ df = pd.read_excel(filepath)
9
+ else:
10
+ raise ValueError("Unsupported file format: Please provide a .csv or .xlsx file")
11
+
12
+ # Convert all string values to lowercase and remove spaces
13
+ df = df.map(lambda x: x.lower().replace(" ", "") if isinstance(x, str) else x)
14
+
15
+ return df
process.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import gradio as gr
3
+
4
+
5
+ def get_lat_lon(postcodes_df, postcode_mapping):
6
+
7
+ try:
8
+
9
+ postcode_mapping.rename(columns={'postcode': 'Postal code'}, inplace=True)
10
+
11
+ # Normalize postcodes to ensure matching and count occurrences
12
+ postcodes_df['Postal code'] = postcodes_df['Postal code'].str.lower().str.replace(' ', '')
13
+ postcode_counts = postcodes_df['Postal code'].value_counts().reset_index()
14
+ postcode_counts.columns = ['Postal code', 'count']
15
+
16
+ # Normalize the postcodes in the mapping DataFrame
17
+ postcode_mapping['Postal code'] = postcode_mapping['Postal code'].str.lower().str.replace(' ', '')
18
+
19
+ # Merge the counts with the mapping data
20
+ result_df = pd.merge(postcode_counts, postcode_mapping, on='Postal code', how='left')
21
+
22
+ # Fill NaN values for latitude and longitude where postcode was not found in the mapping
23
+ result_df['latitude'] = result_df['latitude'].fillna('')
24
+ result_df['longitude'] = result_df['longitude'].fillna('')
25
+
26
+ # Optionally, convert the DataFrame to a dictionary if needed, or work directly with the DataFrame
27
+ results = result_df.to_dict(orient='records')
28
+
29
+ except:
30
+ raise gr.Error('Make sure your file contains the postal codes under a column named "Postal code"')
31
+
32
+ return results