Add location-aware automatic default bounding box
The OpenSky "Default bounding box" now follows where flying happens. A new "Automatic" picker mode (the default) resolves the live-map area from a location cascade — drone telemetry → phone GPS → browser geolocation → the user's Region country → Europe — instead of a fixed box. Manual presets and Custom coordinates still work. - Web App: new shared countries.js dataset (all countries + bbox, offline point→country); the bbox picker gains all European countries and an Automatic option (client pref prefs.autoBbox); the Region setting expands from 6 locale entries to all countries; the live map resolves the cascade each poll and sends it as ?bbox=. - API Server: the states endpoint accepts and validates a ?bbox= override (validBBox); the Web App BFF forwards the query; the hub relays new phoneLatitude/phoneLongitude telemetry to the Web App. - Fly App: reports the phone's own GPS (geolocator) alongside telemetry, used as the "your location" fallback. - API panel: the OpenSky bbox picker lists all European countries. Builds verified across web, panel, both Go modules and the Fly App APK. Region list, Automatic default and the cascade ?bbox= override verified in the browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
150758b0bf
commit
94f6876024
@@ -7,9 +7,34 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// validBBox reports whether s is a well-formed "lamin,lomin,lamax,lomax" bounding
|
||||
// box: four numbers, latitudes in [-90,90], longitudes in [-180,180], and min < max
|
||||
// on each axis. Used to vet the Live map's client-supplied ?bbox= override before
|
||||
// it reaches OpenSky.
|
||||
func validBBox(s string) bool {
|
||||
parts := strings.Split(s, ",")
|
||||
if len(parts) != 4 {
|
||||
return false
|
||||
}
|
||||
n := make([]float64, 4)
|
||||
for i, p := range parts {
|
||||
v, err := strconv.ParseFloat(strings.TrimSpace(p), 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
n[i] = v
|
||||
}
|
||||
laMin, loMin, laMax, loMax := n[0], n[1], n[2], n[3]
|
||||
if laMin < -90 || laMax > 90 || loMin < -180 || loMax > 180 {
|
||||
return false
|
||||
}
|
||||
return laMin < laMax && loMin < loMax
|
||||
}
|
||||
|
||||
// Integrations exposes the OpenSky plugin's settings to end users under a
|
||||
// three-layer cascade (superadmin/global → organization → user). Each of the
|
||||
// four settings resolves independently, top wins, and a blank field falls
|
||||
@@ -586,11 +611,19 @@ func (s *Server) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// The Live map may request a specific area (auto cascade: drone → device →
|
||||
// region). Honour a well-formed ?bbox= override; otherwise use the resolved
|
||||
// config bbox. Malformed input is ignored rather than erroring.
|
||||
bbox := res.eff.Bbox
|
||||
if q := strings.TrimSpace(r.URL.Query().Get("bbox")); q != "" && validBBox(q) {
|
||||
bbox = q
|
||||
}
|
||||
|
||||
cfg := map[string]string{
|
||||
"clientId": res.eff.ClientID,
|
||||
"clientSecret": res.eff.ClientSecret,
|
||||
"plan": res.eff.Plan,
|
||||
"bbox": res.eff.Bbox,
|
||||
"bbox": bbox,
|
||||
"allowAnonymous": boolStr(res.allowAnon),
|
||||
}
|
||||
raw, err := s.plugins.InvokeWith(r.Context(), openSkyPlugin, cfg, "states.bbox", nil)
|
||||
|
||||
Reference in New Issue
Block a user