jableable commited on
Commit
9cd4526
·
verified ·
1 Parent(s): df6ee5c

Upload new_app.py

Browse files
Files changed (1) hide show
  1. new_app.py +98 -0
new_app.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import keras
3
+ import numpy as np
4
+ from PIL import Image
5
+ import io, os, urllib.request
6
+
7
+ st.set_page_config(layout="wide")
8
+
9
+ @st.cache_data(show_spinner=False, ttl=3600)
10
+ def fetch_satellite_tile(lat, lng, zoom=16, size=(640, 640), api_key=""):
11
+ if not api_key:
12
+ raise RuntimeError("Google Static Maps API key is missing.")
13
+ # Build URL
14
+ size_str = f"{size[0]}x{size[1]}"
15
+ url = (
16
+ "https://maps.googleapis.com/maps/api/staticmap?"
17
+ f"center={lat},{lng}&zoom={zoom}&size={size_str}&maptype=satellite&scale=2&key={api_key}"
18
+ )
19
+ # Fetch with timeout
20
+ req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
21
+ with urllib.request.urlopen(req, timeout=10) as resp:
22
+ buffer = io.BytesIO(resp.read())
23
+ return Image.open(buffer).convert("RGB")
24
+
25
+ @st.cache_resource
26
+ def get_model():
27
+ # compile=False speeds loading; prefer model(...) over .predict for TF
28
+ return keras.models.load_model("0.0008-0.92.keras", compile=False)
29
+
30
+ def preprocess(img: Image.Image, size=(640, 640)) -> np.ndarray:
31
+ img = img.resize(size, Image.BILINEAR)
32
+ arr = np.asarray(img, dtype=np.float32)
33
+ # adjust this normalization to match training
34
+ arr = arr / 255.0
35
+ return np.expand_dims(arr, axis=0)
36
+
37
+ def status_text(pct: float) -> str:
38
+ if pct >= 90:
39
+ return "extremely likely"
40
+ elif pct >= 60:
41
+ return "likely"
42
+ elif pct >= 40:
43
+ return "a coin toss whether"
44
+ elif pct >= 10:
45
+ return "unlikely"
46
+ else:
47
+ return "extremely unlikely"
48
+
49
+ st.markdown("""
50
+ <style>
51
+ .block-container { padding-top: 1rem; padding-bottom: 0rem; padding-left: 5rem; padding-right: 5rem; }
52
+ </style>
53
+ """, unsafe_allow_html=True)
54
+
55
+ img_size = (640, 640)
56
+ model = get_model()
57
+
58
+ col1, col2 = st.columns(2)
59
+ with col1:
60
+ st.header("Overpass Identifier")
61
+ with col2:
62
+ st.image("overpass.png")
63
+
64
+ st.write("---")
65
+
66
+ # Defaults
67
+ lat = st.session_state.get("lat", 39.11)
68
+ lng = st.session_state.get("lng", -86.56)
69
+
70
+ with st.form("coords"):
71
+ st.subheader("Enter latitude/longitude coordinates:")
72
+ c1, c2 = st.columns(2)
73
+ with c1:
74
+ lat = st.number_input("Latitude", value=float(lat), min_value=-90.0, max_value=90.0, step=0.01, format="%.4f")
75
+ with c2:
76
+ lng = st.number_input("Longitude", value=float(lng), min_value=-180.0, max_value=180.0, step=0.01, format="%.4f")
77
+ submitted = st.form_submit_button("Get Image and Prediction")
78
+
79
+ if submitted:
80
+ st.session_state.lat, st.session_state.lng = lat, lng
81
+ api_key = os.getenv("goog_api", "")
82
+ try:
83
+ with st.spinner("Fetching satellite tile..."):
84
+ img = fetch_satellite_tile(lat, lng, size=img_size, api_key=api_key)
85
+ st.image(img, caption=f"{lat:.4f}, {lng:.4f}", use_column_width=True)
86
+
87
+ with st.spinner("Running inference..."):
88
+ x = preprocess(img, size=img_size)
89
+ # Prefer model(x, training=False) for speed; adjust index if your model output differs
90
+ y = model(x, training=False).numpy()
91
+ crossing_chance = float(y[0][1] * 100.0)
92
+
93
+ status = status_text(crossing_chance)
94
+ st.markdown(f"**It’s {status} that there’s an overpass here.**")
95
+ st.write(f"In fact, the likelihood of at least one overpass is **{crossing_chance:.2f}%**.")
96
+
97
+ except Exception as e:
98
+ st.error(f"Error fetching image or running prediction: {e}")