Py.Cafe

wybert/

2sfca-analysis

2-Step Floating Catchment Area Analysis

DocsPricing
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import streamlit as st
import pandas as pd
import geopandas as gpd


def get_distance(row):
    distance = (row["dx"] - row["sx"])**2 + (row["dy"] - row["sy"])**2
    distance = distance**0.5
    return distance


## Title and description
st.title('2SFCA')

st.markdown('This app calculates the 2-Step Floating Catchment Area (2SFCA) accessibility score for a given supply and demand dataset.')


## Upload data and preprocess the data

cols = st.columns(2)
supply = cols[0].file_uploader('Upload supply data', type=['csv', 'xlsx','zip', 'geojson', 'gpkg'])
# upload target data
demand = cols[1].file_uploader('Upload demand data', type=['csv', 'xlsx', 'zip', 'geojson','gpkg'])


if supply and demand:
    # read supply data
    if supply.name.endswith('.csv'):
        supply_data = pd.read_csv(supply)
    elif supply.name.endswith('.xlsx'):
        supply_data = pd.read_excel(supply)
    elif supply.name.endswith('.zip'):
        supply_data = gpd.read_file(f'zip://{supply.name}')
    elif supply.name.endswith('.geojson'):
        supply_data = gpd.read_file(supply)
    elif supply.name.endswith('.gpkg'):
        supply_data = gpd.read_file(supply)


    # read demand data
    if demand.name.endswith('.csv'):
        demand_data = pd.read_csv(demand)
    elif demand.name.endswith('.xlsx'):
        demand_data = pd.read_excel(demand)
    elif demand.name.endswith('.zip'):
        demand_data = gpd.read_file(f'zip://{demand.name}')
    elif demand.name.endswith('.geojson'):
        demand_data = gpd.read_file(demand)
    elif demand.name.endswith('.gpkg'):
        demand_data = gpd.read_file(demand)


## preview the data
    cols[0].write(supply_data.head())
    cols[1].write(demand_data.head())
    # plot supply data
    supply_data["lat"] = supply_data.geometry.y
    supply_data["lon"] = supply_data.geometry.x
    demand_data["lat"] = demand_data.geometry.y
    demand_data["lon"] = demand_data.geometry.x
    import matplotlib.pyplot as plt
    fig0 , ax0 = plt.subplots(figsize=(8, 6))
    supply_data.plot(ax=ax0, color='red')
    cols[0].pyplot(fig0)

    fig1 , ax1 = plt.subplots(figsize=(8, 6))
    demand_data.plot(ax=ax1, color='blue')
    cols[1].pyplot(fig1)

## 2sfca parameters
    s_va = cols[0].selectbox(
    "Supply Variable",
    supply_data.columns)
    d_va = cols[1].selectbox(
    "Demand Variable",
    demand_data.columns)

    radius = cols[0].slider('Select Service radius', min_value=0, max_value=100000, value=32180, step=1000)
    buffer_radius = supply_data.buffer(radius)
    fig_b , ax_b = plt.subplots(figsize=(8, 6))
    buffer_radius.plot(ax=ax_b)
    cols[1].pyplot(fig_b)
    # buffer_radius.plot()

## Run 2sfca
    if st.button('Run'):

# calculate distance matrix
        supply_data["sx"],supply_data["sy"] = supply_data.geometry.x,supply_data.geometry.y
        supply_data["sid"] = supply_data.index
        demand_data["dx"],demand_data["dy"] = demand_data.geometry.x,demand_data.geometry.y
        demand_data["did"] = demand_data.index
        joint_data = demand_data.merge(supply_data,how="cross")
        joint_data["distance"] = joint_data.apply(get_distance,axis=1)
        distance_matrix = joint_data.pivot_table(index="did",columns="sid",values="distance")
        d_matrix = distance_matrix.values

## calculate access score
        import aceso
        model = aceso.TwoStepFCA(radius=radius)
        demand_data['access_score'] = model.calculate_accessibility_scores(
            distance_matrix=d_matrix,
            demand_array=demand_data[d_va].values,
            supply_array = supply_data[s_va].values
        )

#  plot access score
        st.write(demand_data.head())
        # plot access score
        fig_c = plt.figure()
        ax = plt.gca()
        demand_data.plot(column='access_score', legend=True, ax=ax)
        st.pyplot(fig_c)
 # download access score
        demand_data.to_csv('access_score.csv', index=False)
        st.download_button(label='Download access score', data='access_score.csv', file_name='access_score.csv', mime='text/csv')