From e1ef0f742cb0dc5254fc8f49fd21b6fb2f04e45f Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:50:24 +0000 Subject: [PATCH 1/6] Updating mapping module to use year as a parameter --- mapping/folium_map.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/mapping/folium_map.py b/mapping/folium_map.py index 9cd7edd..d91e0be 100644 --- a/mapping/folium_map.py +++ b/mapping/folium_map.py @@ -3,29 +3,30 @@ import json from mapping.prep_data import * -def create_gdf(): +def create_gdf(period: int): """ Function to create a GeoPandas DataFrame from the spatial data file and then merge feature data into it + # Todo: Control for inflation on wage data """ # Get feature data lad_df = get_df_from_db() # Data cleaning - lad_df_2024 = lad_df[lad_df["year"]==2024] - lad_df_2024 = lad_df_2024.dropna() - lad_df_2024["median_ann_pay"] = lad_df_2024["median_ann_pay"].astype("int64") + lad_df_filtered = lad_df[lad_df["year"]==period] + lad_df_filtered = lad_df_filtered.dropna() + lad_df_filtered["median_ann_pay"] = lad_df_filtered["median_ann_pay"].astype("int64") # Get spatial data gdf = geopandas.read_file("data/local_authority_district_boundaries.geojson") # Join feature data on spatial data gdf = gdf.merge( - lad_df_2024, - how="left", - left_on="LAD24NM", - right_on="lad" + lad_df_filtered, + how="left", + left_on="LAD24NM", + right_on="lad" ) return gdf From 60809effd60e4526e7ebfa3567128b0e2c94e593 Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:50:45 +0000 Subject: [PATCH 2/6] Added script to pre-generate folium maps --- main.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..4b31ee1 --- /dev/null +++ b/main.py @@ -0,0 +1,32 @@ +from mapping.folium_map import * +import yaml + +def main(): + """ + Produce all required map iframes + """ + # Load config + with open("config.yaml") as f: + config = yaml.safe_load(f) + + # Loop through required years + for i in range(2014, 2025): + file_extension = str(i) + + # Create map + geo_df = create_gdf(i) + m = generate_map_from_gdf(geo_df, w=config["width"], h=config["height"]) + + # Serve map to iframe + m.get_root().width = config["width_px"] + m.get_root().height = config["height_px"] + iframe = m.get_root()._repr_html_() + + # Write out iframe to HTML + filename = f"map_{file_extension}.html" + html_file = open(f"static/{filename}", "w") + html_file.write(iframe) + html_file.close + +if __name__ == "__main__": + main() \ No newline at end of file From 2448dc72aa45ef260a78acec05ac7020333868d5 Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:51:07 +0000 Subject: [PATCH 3/6] Pre-generated map files --- static/map_2014.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2015.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2016.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2017.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2018.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2019.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2020.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2021.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2022.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2023.html | 187 +++++++++++++++++++++++++++++++++++++++++++ static/map_2024.html | 187 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 2057 insertions(+) create mode 100644 static/map_2014.html create mode 100644 static/map_2015.html create mode 100644 static/map_2016.html create mode 100644 static/map_2017.html create mode 100644 static/map_2018.html create mode 100644 static/map_2019.html create mode 100644 static/map_2020.html create mode 100644 static/map_2021.html create mode 100644 static/map_2022.html create mode 100644 static/map_2023.html create mode 100644 static/map_2024.html diff --git a/static/map_2014.html b/static/map_2014.html new file mode 100644 index 0000000..97f7af3 --- /dev/null +++ b/static/map_2014.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2015.html b/static/map_2015.html new file mode 100644 index 0000000..adbce14 --- /dev/null +++ b/static/map_2015.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2016.html b/static/map_2016.html new file mode 100644 index 0000000..41f863b --- /dev/null +++ b/static/map_2016.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2017.html b/static/map_2017.html new file mode 100644 index 0000000..4d2b7cb --- /dev/null +++ b/static/map_2017.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2018.html b/static/map_2018.html new file mode 100644 index 0000000..cbd4f3d --- /dev/null +++ b/static/map_2018.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2019.html b/static/map_2019.html new file mode 100644 index 0000000..c15ca83 --- /dev/null +++ b/static/map_2019.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2020.html b/static/map_2020.html new file mode 100644 index 0000000..93e8994 --- /dev/null +++ b/static/map_2020.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2021.html b/static/map_2021.html new file mode 100644 index 0000000..c050a71 --- /dev/null +++ b/static/map_2021.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2022.html b/static/map_2022.html new file mode 100644 index 0000000..00e5769 --- /dev/null +++ b/static/map_2022.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2023.html b/static/map_2023.html new file mode 100644 index 0000000..c696149 --- /dev/null +++ b/static/map_2023.html @@ -0,0 +1,187 @@ + \ No newline at end of file diff --git a/static/map_2024.html b/static/map_2024.html new file mode 100644 index 0000000..4781205 --- /dev/null +++ b/static/map_2024.html @@ -0,0 +1,187 @@ + \ No newline at end of file From f8e5148d2746c0907159a8fc042627901240c28f Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:58:48 +0000 Subject: [PATCH 4/6] removed map generating code form app.py, additional app route to collect user input on the server, unsused for now --- app.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app.py b/app.py index 917d030..38a8af5 100644 --- a/app.py +++ b/app.py @@ -1,16 +1,14 @@ -from flask import Flask, render_template +from flask import Flask, render_template, request from mapping.folium_map import * app = Flask(__name__) @app.route("/") -def home(): +def index(): + return render_template("home.html") - gdf = create_gdf() - m = generate_map_from_gdf(gdf, w=800, h=600) - m.get_root().width = "800px" - m.get_root().height = "600px" - iframe = m.get_root()._repr_html_() - - return render_template("home.html", iframe=iframe) \ No newline at end of file +@app.route("/slider_update", methods=["POST"]) +def slider(): + received_data = request.data + return received_data \ No newline at end of file From 2ddc12312b236d6db601b183280e12fbe6a51cb8 Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:59:19 +0000 Subject: [PATCH 5/6] Updated config so that we can set the size of the maps produced in main.py here --- config.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config.yaml b/config.yaml index 5b61f5b..de418b7 100644 --- a/config.yaml +++ b/config.yaml @@ -1,3 +1,5 @@ # App configs -window_width: 800 -window_height: 600 \ No newline at end of file +width: 800 +width_px: "800px" +height: 600 +height_px: "600px" \ No newline at end of file From 5b3834b1d713e9d1671eac3f7aa854f16bd0e10d Mon Sep 17 00:00:00 2001 From: soderc Date: Wed, 26 Mar 2025 16:59:48 +0000 Subject: [PATCH 6/6] Added javascript to make home.html interactive --- templates/home.html | 290 ++++++++++++++++++++++++++------------------ 1 file changed, 172 insertions(+), 118 deletions(-) diff --git a/templates/home.html b/templates/home.html index 1fd6ab3..dc28eaa 100644 --- a/templates/home.html +++ b/templates/home.html @@ -5,141 +5,153 @@ Coding challenge + + + + @@ -147,13 +159,55 @@

Coding challenge

+

Welcome to the ASAP away day coding challenge.

For this challenge you will work in teams to develop an interactive web application using Flask and Folium.

Below you will see a basic application - it is a Choropleth map showing the median annual pay in 2024 for each local authority in Britain.

+

Basic application

-
{{ iframe|safe }}
+ +
+
+

Year

+ + 2024 +
+ +
+ +
+ +
+ + + +
+

Task 1

Add interactive labels to the map so that we can click on the map to get the data for that local authority.

Task 2