diff --git a/internal/assets/static/js/app.js b/internal/assets/static/js/app.js
index 0ca2c8d..0ff34f1 100644
--- a/internal/assets/static/js/app.js
+++ b/internal/assets/static/js/app.js
@@ -100,8 +100,19 @@ class SkyView {
}
// Map Initialization
- initializeMap() {
- this.map = L.map('map').setView([51.4700, -0.4600], 10);
+ async initializeMap() {
+ // Get origin from server
+ let origin = { latitude: 51.4700, longitude: -0.4600 }; // fallback
+ try {
+ const response = await fetch('/api/origin');
+ if (response.ok) {
+ origin = await response.json();
+ }
+ } catch (error) {
+ console.warn('Could not fetch origin, using default:', error);
+ }
+
+ this.map = L.map('map').setView([origin.latitude, origin.longitude], 10);
// Dark tile layer
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
@@ -117,9 +128,20 @@ class SkyView {
document.getElementById('toggle-sources').addEventListener('click', () => this.toggleSources());
}
- initializeCoverageMap() {
+ async initializeCoverageMap() {
if (!this.coverageMap) {
- this.coverageMap = L.map('coverage-map').setView([51.4700, -0.4600], 10);
+ // Get origin from server
+ let origin = { latitude: 51.4700, longitude: -0.4600 }; // fallback
+ try {
+ const response = await fetch('/api/origin');
+ if (response.ok) {
+ origin = await response.json();
+ }
+ } catch (error) {
+ console.warn('Could not fetch origin for coverage map, using default:', error);
+ }
+
+ this.coverageMap = L.map('coverage-map').setView([origin.latitude, origin.longitude], 10);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap contributors'
diff --git a/internal/server/server.go b/internal/server/server.go
index d47d1e7..c69649c 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -18,12 +18,20 @@ import (
"skyview/internal/merger"
)
+// OriginConfig represents the reference point configuration
+type OriginConfig struct {
+ Latitude float64 `json:"latitude"`
+ Longitude float64 `json:"longitude"`
+ Name string `json:"name,omitempty"`
+}
+
// Server handles HTTP requests and WebSocket connections
type Server struct {
port int
merger *merger.Merger
staticFiles embed.FS
server *http.Server
+ origin OriginConfig
// WebSocket management
wsClients map[*websocket.Conn]bool
@@ -50,11 +58,12 @@ type AircraftUpdate struct {
}
// NewServer creates a new HTTP server
-func NewServer(port int, merger *merger.Merger, staticFiles embed.FS) *Server {
+func NewServer(port int, merger *merger.Merger, staticFiles embed.FS, origin OriginConfig) *Server {
return &Server{
port: port,
merger: merger,
staticFiles: staticFiles,
+ origin: origin,
wsClients: make(map[*websocket.Conn]bool),
upgrader: websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
@@ -107,6 +116,7 @@ func (s *Server) setupRoutes() http.Handler {
api.HandleFunc("/aircraft/{icao}", s.handleGetAircraftDetails).Methods("GET")
api.HandleFunc("/sources", s.handleGetSources).Methods("GET")
api.HandleFunc("/stats", s.handleGetStats).Methods("GET")
+ api.HandleFunc("/origin", s.handleGetOrigin).Methods("GET")
api.HandleFunc("/coverage/{sourceId}", s.handleGetCoverage).Methods("GET")
api.HandleFunc("/heatmap/{sourceId}", s.handleGetHeatmap).Methods("GET")
@@ -180,6 +190,11 @@ func (s *Server) handleGetStats(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(stats)
}
+func (s *Server) handleGetOrigin(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(s.origin)
+}
+
func (s *Server) handleGetCoverage(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
sourceID := vars["sourceId"]
diff --git a/static/js/app.js b/static/js/app.js
index 0ca2c8d..0ff34f1 100644
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -100,8 +100,19 @@ class SkyView {
}
// Map Initialization
- initializeMap() {
- this.map = L.map('map').setView([51.4700, -0.4600], 10);
+ async initializeMap() {
+ // Get origin from server
+ let origin = { latitude: 51.4700, longitude: -0.4600 }; // fallback
+ try {
+ const response = await fetch('/api/origin');
+ if (response.ok) {
+ origin = await response.json();
+ }
+ } catch (error) {
+ console.warn('Could not fetch origin, using default:', error);
+ }
+
+ this.map = L.map('map').setView([origin.latitude, origin.longitude], 10);
// Dark tile layer
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
@@ -117,9 +128,20 @@ class SkyView {
document.getElementById('toggle-sources').addEventListener('click', () => this.toggleSources());
}
- initializeCoverageMap() {
+ async initializeCoverageMap() {
if (!this.coverageMap) {
- this.coverageMap = L.map('coverage-map').setView([51.4700, -0.4600], 10);
+ // Get origin from server
+ let origin = { latitude: 51.4700, longitude: -0.4600 }; // fallback
+ try {
+ const response = await fetch('/api/origin');
+ if (response.ok) {
+ origin = await response.json();
+ }
+ } catch (error) {
+ console.warn('Could not fetch origin for coverage map, using default:', error);
+ }
+
+ this.coverageMap = L.map('coverage-map').setView([origin.latitude, origin.longitude], 10);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap contributors'