Spaces:
Running
Running
| """ | |
| 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> | |
| """ | |