import json
import csv
import io
import streamlit as st
# Function to flatten the nested JSON
def flatten_json(json_obj, parent_key='', sep='_'):
"""Recursively flattens a nested JSON object."""
items = []
for k, v in json_obj.items():
new_key = f"{parent_key}{sep}{k}" if parent_key else k
if isinstance(v, dict):
items.extend(flatten_json(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
# Streamlit app
st.title("GeoJSON to CSV Converter for Food.gov.uk data")
st.write("Select JSON files to consolidate and convert into a single CSV.")
# File uploader for JSON files
uploaded_files = st.file_uploader(
"Upload JSON files", type="json", accept_multiple_files=True
)
st.markdown(
"""
Food.gov.uk performs inspections on food retailers and other food
processing establishments in the UK. The relative data include
Hygiene ratings, but also geographical coordinates, making them ideal
to map virtually any cafe, restaurant and many other categories.
However, the data are provided in a nested GeoJson format incompatible
with the conversion tools available with ArcGIS and QGIS.
This simple converter will process one or more GeoJSON files
from Food.gov.uk and consolidate them in a single CSV file while
preserving all data, including Longitude and Latitude.
This can then be imported in ArcGIS, QGIS or other mapping software
and libraries.
# **USAGE:**
The app runs in your browser and nothing is sent online.
It however needs online connection to download the required libraries.
- Click on *Browse Files* and select the files to convert.
- A preview table of the output file will be shown.
- Click on *Download CSV*, under the table, to download the file to your computer.
"""
)
if uploaded_files:
json_data_list = []
for uploaded_file in uploaded_files:
json_data = json.load(uploaded_file)
json_data_list.append(json_data)
# Extract and consolidate establishments from all files
flattened_data = []
for json_data in json_data_list:
establishments = json_data.get("EstablishmentCollection", {}).get("EstablishmentDetail", [])
flattened_data.extend([flatten_json(establishment) for establishment in establishments])
# Ensure there is data to write
if not flattened_data:
st.error("No establishment data found in the uploaded files.")
else:
# Default CSV filename
default_output_filename = "consolidated_output.csv"
# Download button for the resulting CSV
st.write("Consolidated data preview:")
st.dataframe(flattened_data)
# Convert data to CSV format
output_buffer = io.StringIO()
writer = csv.DictWriter(output_buffer, fieldnames=flattened_data[0].keys())
writer.writeheader()
writer.writerows(flattened_data)
# Provide the CSV data for download
st.download_button(
label="Download CSV",
data=output_buffer.getvalue(),
file_name=default_output_filename,
mime="text/csv",
)