File size: 8,631 Bytes
841baa5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# Importing the required libraries
import streamlit as st
import pandas as pd
import numpy as np
import snowflake.connector
import folium
from streamlit_folium import st_folium
import pycountry_convert as pc

# Setup web page - App Title, Page Title and Page Layout
APP_TITLE = 'Plotting F1 Circuit Locations into a map on Streamlit on Hugging Face using Folium'
st.set_page_config(
    page_title='F1 Circuits', 
    layout='wide',
    menu_items={'Get Help': 'https://www.linkedin.com/in/daanbakboord',
                'About': "This app is powered by Snowflake, Streamlit, Hugging Face and Folium | Developed by DaAnalytics (Daan Bakboord)"
    }
)

# Initialize connection.
# Uses st.experimental_singleton to only run once.
@st.experimental_singleton
def init_connection():
    #return snowflake.connector.connect(**st.secrets["snowflake"])
    return snowflake.connector.connect(
            user        = st.secrets["user"],
            password    = st.secrets["password"],
            account     = st.secrets["account"],
            role        = st.secrets["role"]
        )

# Create context 
def create_sf_session_object():

    if "snowflake_context" not in st.session_state:

        ctx = init_connection()
        
        st.session_state['snowflake_context'] = ctx

    else: 

        ctx = st.session_state['snowflake_context']

    return ctx

# Get Continent based on Country
def country_convert(country_name):
    
    try:

        country_code = pc.country_name_to_country_alpha2(country_name, cn_name_format='default')
  
        continent_name = pc.country_alpha2_to_continent_code(country_code)

        return pc.convert_continent_code_to_continent_name(continent_name)

    except (KeyError, TypeError):    
    
        return (country_name)

# Base color on Continent 
# 'darkblue', 'white', 'lightblue', 'pink', 'gray', 'green', 'orange', 'darkred', 'black', 'blue', 'cadetblue'
#, 'lightgreen', 'purple', 'darkgreen', 'red', 'beige', 'lightred', 'darkpurple', 'lightgray'

## 'Oceania', 'Asia', 'Europe', 'North America', 'UK', 'South America', 'UAE',
## 'Africa', 'Korea'

def marker_color(continent_name):
    if continent_name == 'Asia':   
        color = 'pink'
    elif continent_name == 'Africa':   
        color = 'green'
    elif continent_name == 'Europe':   
        color = 'blue'
    elif continent_name == 'North America':   
        color = 'red'
    elif continent_name == 'South America':   
        color = 'orange'
    elif continent_name == 'Oceania':   
        color = 'purple' 
    elif  continent_name == 'UK':   
        color = 'beige'     
    elif  continent_name == 'UAE':   
        color = 'lightgreen'      
    elif  continent_name == 'Korea':   
        color = 'cadetblue'       
    else:
        color = 'grey'
    return color    

def load_data(cur, map_type):

    global df_f1_con_circuits 

    global df_f1_cou_circuits 

    global df_qo_f1_circuits
    
    # Connect to DEMO_DB database
    cur.execute("USE DATABASE DEMO_DB")

    # Connect to PRE_F1PY schema
    f1_pre_schema = 'PRE_F1PY'

    cur.execute("USE SCHEMA " + f1_pre_schema)

    # Select Query F1 Circuits

    sql_f1_circuits = """select replace(name, '"','') as name
                     ,      lat
                     ,      lng
                     ,      replace(country, '"','') as country
                     ,      replace(url, '"','') as url
                     from   demo_db.pre_f1py.pre_f1py_circuits
                  """

    # Query F1 Circuits
    cur.execute(sql_f1_circuits)

    # Convert Query output to a DataFrame
    df_qo_f1_circuits = cur.fetch_pandas_all()

    # Add Continent to df_f1_circuits DataFrame
    df_qo_f1_circuits['CONTINENT'] = df_qo_f1_circuits['COUNTRY'].apply(country_convert)

    # Create Continents DataFrame
    df_f1_con_circuits = df_qo_f1_circuits['CONTINENT'].unique()

    # Create Country DataFrame
    df_f1_cou_circuits = df_qo_f1_circuits['COUNTRY'].unique()

def filter_data(map_type, detail):

    global df_f1_circuits

    if map_type == 'World':

        df_f1_circuits = df_qo_f1_circuits

    elif map_type == 'Continent':  

        # Filter df_f1_circuits DataFrame on 'Europe' Continent
        df_f1_circuits = df_qo_f1_circuits.loc[df_qo_f1_circuits['CONTINENT'] == detail]

    elif map_type == 'Country':

        # Filter df_f1_circuits DataFrame on Country
        df_f1_circuits = df_qo_f1_circuits.loc[df_qo_f1_circuits['COUNTRY'] == detail]   

    # Draw the Folium Map
    draw_folium_map(map_type)   

def draw_folium_map(map_type):
    
    global CircuitsMap
    
    # Creating the Folium Map 
    CircuitsMap = folium.Map(location=[df_f1_circuits.LAT.mean()
                                        , df_f1_circuits.LNG.mean()]
                                        , zoom_start=5
                                        , control_scale=True
                                        , tiles='openstreetmap')

    # Adding Tile Layers
    folium.TileLayer('openstreetmap').add_to(CircuitsMap)
    folium.TileLayer('cartodb positron').add_to(CircuitsMap)
    folium.TileLayer('stamenterrain').add_to(CircuitsMap)
    folium.TileLayer('stamentoner').add_to(CircuitsMap)
    folium.TileLayer('stamenwatercolor').add_to(CircuitsMap)
    folium.TileLayer('cartodbdark_matter').add_to(CircuitsMap)

    # Other mapping code (e.g. lines, markers etc.)
    folium.LayerControl().add_to(CircuitsMap)

    # Add Markers to the map
    if map_type == 'World':

        for index, location_info in df_f1_circuits.iterrows():
            folium.Marker([location_info["LAT"], location_info["LNG"]], popup='<a href=' + location_info["URL"] + ' target="_blank">' + location_info["NAME"] + '</a>', icon=folium.Icon(icon_color='white', icon="car", prefix='fa', color=marker_color(location_info["CONTINENT"]))).add_to(CircuitsMap)   

    elif map_type == 'Continent':  

        for index, location_info in df_f1_circuits.iterrows():
            folium.Marker([location_info["LAT"], location_info["LNG"]], popup='<a href=' + location_info["URL"] + ' target="_blank">' + location_info["NAME"] + '</a>', icon=folium.Icon(icon_color='white', icon="car", prefix='fa', color=marker_color(location_info["CONTINENT"]))).add_to(CircuitsMap)
    
    elif map_type == 'Country':

        for index, location_info in df_f1_circuits.iterrows():
            folium.Marker([location_info["LAT"], location_info["LNG"]], popup='<a href=' + location_info["URL"] + ' target="_blank">' + location_info["NAME"] + '</a>', icon=folium.Icon(icon_color='white', icon="car", prefix='fa', color='darkgreen')).add_to(CircuitsMap)   

    # Zoom to LAT, LONG bounds
    lft_dwn = df_f1_circuits[['LAT', 'LNG']].min().values.tolist() # Left Down
    top_rgt = df_f1_circuits[['LAT', 'LNG']].max().values.tolist() # Top Right
    
    CircuitsMap.fit_bounds([lft_dwn, top_rgt]) 

# Main code
if __name__ == "__main__":

    #v_user = st.secrets["user"]
    #st.sidebar.title(v_user)
    
    # Connect to Snowflake
    ctx = create_sf_session_object()
    cur = ctx.cursor()

    # Select Map type to show
    st.sidebar.title("Select Map Type")

    map_type = st.sidebar.radio(
    "Which map would you like to show?",
    ('World', 'Continent', 'Country'))

    # Load Data into a DataFrame
    load_data(cur, map_type)

    if map_type == 'World':

        detail = map_type

        st.sidebar.write('You selected:', detail)

    elif map_type == 'Continent':
        
        idx = int(np.where(df_f1_con_circuits == "Europe")[0][0])
        
        continent = st.sidebar.selectbox(
            'Which continent would you like to see?',
            (df_f1_con_circuits)
             , index = idx)

        detail = continent    

        st.sidebar.write('You selected:', detail)
    
    elif map_type == 'Country':
               
        idx = int(np.where(df_f1_cou_circuits == "France")[0][0])
        
        country = st.sidebar.selectbox(
            'Which country would you like to see?',
            (df_f1_cou_circuits)
             , index = idx)

        detail = country    

        st.sidebar.write('You selected:', detail)

    # Filter Data based on Map Type
    filter_data(map_type, detail)

    # Draw the 'World' folium Map
    # draw_folium_map(map_type)

    st.title('Plotting F1 Circuit Locations into a map on Streamlit on Hugging Face using Folium')
    
    if map_type == 'World':
     
        st.subheader('Map of the ' + map_type )

    else:
        
        st.subheader('Map of ' + map_type + ' ' + detail)
  

    # Render Folium Map in Streamlit
    st_data = st_folium(CircuitsMap, width = 1250)