File size: 4,817 Bytes
096e4b4
 
 
 
fa2e65b
096e4b4
 
 
fa2e65b
 
 
096e4b4
fa2e65b
096e4b4
fa2e65b
 
096e4b4
fa2e65b
096e4b4
 
fa2e65b
096e4b4
 
fa2e65b
096e4b4
 
 
eaef8a3
 
230f41d
62d023c
 
 
eaef8a3
 
62d023c
eaef8a3
 
230f41d
62d023c
 
 
 
 
 
230f41d
eaef8a3
 
fa2e65b
62d023c
fa2e65b
 
 
 
 
 
 
 
 
 
096e4b4
 
 
fa2e65b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
096e4b4
fa2e65b
 
096e4b4
fa2e65b
096e4b4
eaef8a3
096e4b4
fa2e65b
b3ca0aa
 
 
 
f006ee0
b3ca0aa
 
f006ee0
4ce749d
b3ca0aa
 
 
4ce749d
 
 
 
 
 
fa2e65b
 
 
 
 
 
 
 
 
 
 
190ac67
 
 
 
 
 
fa2e65b
 
096e4b4
fa2e65b
 
 
 
096e4b4
fa2e65b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import keras
import numpy as np
from PIL import Image
import io, urllib.request, os

st.set_page_config(layout="wide")


@st.cache_data(show_spinner=False, ttl=600)
def fetch_satellite_tile(lat, lng, zoom=16, size="640x640", api_key=""):
    if not api_key:
        raise RuntimeError("Missing Google Static Maps API key in env var 'goog_api'.")
    url = (
       f"https://maps.googleapis.com/maps/api/staticmap?"
       f"center={lat},{lng}&zoom={zoom}&size={size}&maptype=satellite&key={api_key}"
    )
    buffer = io.BytesIO(urllib.request.urlopen(url, timeout=10).read())
    return Image.open(buffer).convert("RGB")


@st.cache_resource
def get_model():
    # compile=False skips optimizer/state rebuild, which saves time
    return keras.models.load_model("0.0008-0.92.keras", compile=False)

st.markdown("""
<style>
.block-container {
    padding-top: 2.2rem;
    padding-bottom: 0rem;
    padding-left: 5rem;
    padding-right: 5rem;
}
hr { 
    margin-top: 0.0cm;
    margin-bottom: 0.25cm;
}
[data-testid="stImage"] {
    display: flex !important;
    justify-content: center !important;
}
[data-testid="stImage"] img {
    margin: auto;
    display: block;
}
</style>
""", unsafe_allow_html=True)


#title
col1, col2 = st.columns(2)
with col1:
    _, col = st.columns(2)
    with col:
        st.header('Overpass Identifier')
with col2:
    _, col, _ = st.columns(3)
    with col:
        st.image('overpass.png')

st.write("---")

#load model and initialize image size required by model. uploaded images are resized to indicated size
img_height = 640
img_width = 640

state = st.session_state
state.loaded_model = get_model()

#if "loaded_model" not in state:
#    with st.spinner('Loading model. This may take a few seconds...'):
#        state.loaded_model = keras.models.load_model("0.0008-0.92.keras")

if "lat" not in state:
    state.lat = 39.11

if "lng" not in state:
    state.lng = -86.56 

if "coords_submitted" not in state:
    state.coords_submitted = False

if "img" not in state:
    state.img = None

# Preload default image once
if state.img is None:
    try:
        api_key = os.getenv("goog_api", "")
        state.img = fetch_satellite_tile(state.lat, state.lng, api_key=api_key)
    except Exception as e:
        st.info(f"Couldn’t fetch default tile: {e}")

col1, col2, col3 = st.columns([0.8, 1.8, 1.0])  # adjust ratios to taste

with col3:
    st.subheader('Enter latitude/longitude coordinates:')
    with st.form("coords_form"):
        c1, c2 = st.columns(2)
        with c1:
            st.number_input('Latitude', key="lat", min_value=-90.0, max_value=90.0, step=0.01, format="%.2f")
            st.write('The current lat/long are:')
        with c2:
            st.number_input('Longitude', key="lng", min_value=-180.0, max_value=180.0, step=0.01, format="%.2f")
            st.write(f"{st.session_state.lat:.2f}, {st.session_state.lng:.2f}")
        submitted = st.form_submit_button("Get Image and Prediction")

if submitted:
    try:
        api_key = os.getenv("goog_api", "")
        state.img = fetch_satellite_tile(st.session_state.lat, st.session_state.lng, api_key=api_key)
        st.rerun()  # ensures the updated lat/lng render immediately
    except Exception as e:
        st.error(f"Error fetching image: {e}")
    
with col2:
    if state.coords_submitted:
        state.coords_submitted = False
        try:
            api_key = os.getenv("goog_api", "")
            state.img = fetch_satellite_tile(state.lat, state.lng, api_key=api_key)
        except Exception as e:
            st.error(f"Error fetching image: {e}")

    if state.img is not None:
        st.markdown(
            "<div style='display:flex; justify-content:center;'>",
            unsafe_allow_html=True
        )
        st.image(state.img, width=640)
        st.markdown("</div>", unsafe_allow_html=True)

with col1:
    st.subheader("Prediction")
    if state.img is not None:
        img_array = np.array(state.img)
        batch_size = 1
        img_array = np.reshape(img_array,[batch_size,img_height,img_width,3])
        with st.spinner("Running inference..."):
            result = state.loaded_model.predict(img_array)
        crossing_chance = result[0][1]*100
        status = None
        if crossing_chance >= 90:
            status = "extremely likely"
        elif crossing_chance >= 60:
            status = "likely"
        elif crossing_chance >= 40:
            status = "a coin toss whether"
        elif crossing_chance >= 10:
            status = "unlikely"
        elif crossing_chance >= 0:
            status = "extremely unlikely"

        st.write(f"It's {status} there's an overpass here.")
        st.write("")
        st.write(f"In fact, the likelihood of at least one overpass is {np.round(crossing_chance,decimals=2)}%.")