Water_Guardian / src /gps_component.py
Joydeep Das
Initial deploy: Water Guardian with Vedic kernels
654abc5
Raw
History Blame Contribute Delete
3.91 kB
"""
Browser GPS component for Streamlit.
Uses JavaScript Geolocation API to get user's real-time position.
"""
import streamlit as st
import streamlit.components.v1 as components
def gps_button():
"""
Renders a GPS button. When clicked, asks browser for location.
Returns (lat, lon) or (None, None) if denied/unavailable.
Usage:
if st.button('πŸ“ Use My GPS Location'):
lat, lon = gps_button()
if lat:
st.session_state.lat = lat
st.session_state.lon = lon
"""
html = """
<div id="gps-result" style="display:none;"></div>
<script>
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
var lat = position.coords.latitude.toFixed(6);
var lon = position.coords.longitude.toFixed(6);
document.getElementById('gps-result').innerText = lat + ',' + lon;
document.getElementById('gps-result').setAttribute('data-ready', '1');
},
function(error) {
document.getElementById('gps-result').innerText = 'error:' + error.message;
document.getElementById('gps-result').setAttribute('data-ready', '1');
},
{enableHighAccuracy: true, timeout: 10000, maximumAge: 60000}
);
} else {
document.getElementById('gps-result').innerText = 'error:Geolocation not supported';
document.getElementById('gps-result').setAttribute('data-ready', '1');
}
</script>
"""
# This won't work perfectly in Streamlit due to component lifecycle,
# but we'll use a simpler approach: direct JS-inject
return html
# Simpler approach: use st.components.v1.html with callback
GPS_HTML = """
<div id="gps-container" style="padding:10px; text-align:center;">
<button onclick="getGPS()" style="padding:10px 20px; font-size:16px; background:#4CAF50; color:white; border:none; border-radius:5px; cursor:pointer;">
πŸ“ Detect My Location
</button>
<div id="gps-output" style="margin-top:10px; font-family:monospace; color:#333;"></div>
</div>
<script>
function getGPS() {
var output = document.getElementById('gps-output');
output.innerHTML = '⏳ Acquiring GPS...';
if (!navigator.geolocation) {
output.innerHTML = '❌ GPS not supported on this device.';
return;
}
navigator.geolocation.getCurrentPosition(
function(pos) {
var lat = pos.coords.latitude.toFixed(6);
var lon = pos.coords.longitude.toFixed(6);
var acc = pos.coords.accuracy.toFixed(1);
output.innerHTML = 'βœ… Lat: ' + lat + '<br>βœ… Lon: ' + lon + '<br>Accuracy: Β±' + acc + 'm';
// Store in URL params so Streamlit can read on next rerun
var params = new URLSearchParams(window.location.search);
params.set('gps_lat', lat);
params.set('gps_lon', lon);
window.history.replaceState({}, '', '?' + params.toString());
// Trigger Streamlit rerun by clicking invisible button
setTimeout(function() {
window.location.reload();
}, 500);
},
function(err) {
output.innerHTML = '❌ GPS Error: ' + err.message + '<br>Please enter coordinates manually.';
},
{enableHighAccuracy: true, timeout: 15000, maximumAge: 120000}
);
}
// Auto-detect if GPS params are in URL (from previous detection)
var urlParams = new URLSearchParams(window.location.search);
var gpsLat = urlParams.get('gps_lat');
var gpsLon = urlParams.get('gps_lon');
if (gpsLat && gpsLon) {
document.getElementById('gps-output').innerHTML =
'πŸ“ Last GPS: ' + gpsLat + ', ' + gpsLon +
'<br><small>Click button to refresh</small>';
}
</script>
"""