Groundstation Datasets Overview Groundstation datasets provide geographic locations and metadata for commercial satellite ground facilities worldwide. This data is essential for:
Computing contact opportunities : Determine when satellites are visible from ground stations Network planning : Analyze coverage and redundancy across multiple providers Mission design : Evaluate downlink opportunities for different orbit configurations Brahe includes embedded GeoJSON data for 6 major commercial groundstation providers, totaling 50+ facilities globally. All data is:
Offline-capable : No network requests required Comprehensive : Global coverage across multiple providers Standardized : Consistent format with geographic coordinates and metadata Up-to-date : Maintained as provider networks evolve When to Use Use groundstation datasets when you need to:
Compute visibility windows for satellite-to-ground contacts Plan downlink schedules for data collection Analyze network coverage and redundancy Compare provider capabilities across different locations Available Providers Brahe includes groundstation data from six major commercial providers:
Provider Description Atlas Atlas Space Operations AWS Amazon Web Services Ground Station KSAT Kongsberg Satellite Services Leaf Leaf Space NASA DSN NASA Deep Space Network NASA NEN NASA Near Earth Network SSC Swedish Space Corporation Viasat Viasat
Usage Loading Groundstations Load groundstation data from one or more providers:
Python Rust
import brahe as bh
# Initialize EOP data
bh . initialize_eop ()
# Load groundstations from a single provider
ksat_stations = bh . datasets . groundstations . load ( "ksat" )
print ( f "KSAT stations: { len ( ksat_stations ) } " )
# Load all available providers at once
all_stations = bh . datasets . groundstations . load_all ()
print ( f "Total stations (all providers): { len ( all_stations ) } " )
# List available providers
providers = bh . datasets . groundstations . list_providers ()
print ( f " \n Available providers: { ', ' . join ( providers ) } " )
# Load multiple specific providers
aws_stations = bh . datasets . groundstations . load ( "aws" )
ssc_stations = bh . datasets . groundstations . load ( "ssc" )
combined = aws_stations + ssc_stations
print ( f " \n Combined AWS + SSC: { len ( combined ) } stations" )
# Expected output:
# KSAT stations: 36
# Total stations (all providers): 96
# Available providers: atlas, aws, ksat, leaf, ssc, viasat
# Combined AWS + SSC: 22 stations
use brahe as bh ;
fn main () {
bh :: initialize_eop (). unwrap ();
// Load groundstations from a single provider
let ksat_stations = bh :: datasets :: groundstations :: load_groundstations ( "ksat" ). unwrap ();
println! ( "KSAT stations: {}" , ksat_stations . len ());
// Load all available providers at once
let all_stations = bh :: datasets :: groundstations :: load_all_groundstations (). unwrap ();
println! ( "Total stations (all providers): {}" , all_stations . len ());
// List available providers
let providers = bh :: datasets :: groundstations :: list_providers ();
println! ( " \n Available providers: {}" , providers . join ( ", " ));
// Load multiple specific providers
let aws_stations = bh :: datasets :: groundstations :: load_groundstations ( "aws" ). unwrap ();
let ssc_stations = bh :: datasets :: groundstations :: load_groundstations ( "ssc" ). unwrap ();
let combined : Vec < _ > = aws_stations
. iter ()
. chain ( ssc_stations . iter ())
. cloned ()
. collect ();
println! ( " \n Combined AWS + SSC: {} stations" , combined . len ());
// Expected output:
// KSAT stations: 36
// Total stations (all providers): 96
// Available providers: atlas, aws, ksat, leaf, ssc, viasat
// Combined AWS + SSC: 22 stations
}
Accessing Properties Each groundstation includes geographic coordinates and metadata:
Python Rust
import brahe as bh
# Initialize EOP data
bh . initialize_eop ()
# Load KSAT groundstations
stations = bh . datasets . groundstations . load ( "ksat" )
# Access the first station
station = stations [ 0 ]
# Geographic coordinates (degrees and meters)
name = station . get_name () if station . get_name () else "Unknown"
print ( f "Station: { name } " )
print ( f "Latitude: { station . lat : .4f } °" )
print ( f "Longitude: { station . lon : .4f } °" )
print ( f "Altitude: { station . alt : .1f } m" )
# Access metadata properties
props = station . properties
print ( f " \n Provider: { props [ 'provider' ] } " )
print ( f "Frequency bands: { ', ' . join ( props [ 'frequency_bands' ]) } " )
# Show all stations with their locations
print ( f " \n { len ( stations ) } KSAT Stations:" )
for i , gs in enumerate ( stations , 1 ):
gs_name = gs . get_name () if gs . get_name () else "Unknown"
print ( f " { i : 2d } . { gs_name : 30s } ( { gs . lat : 7.3f } °, { gs . lon : 8.3f } °)" )
# Expected output:
# Station: Prudhoe Bay
# Latitude: 70.2000°
# Longitude: -148.4700°
# Altitude: 0.0 m
# Provider: KSAT
# Frequency bands: S, X
# 36 KSAT Stations:
# 1. Prudhoe Bay ( 70.200°, -148.470°)
# 2. Athens ( 37.850°, 22.620°)
# 3. Awarua (-46.530°, 168.380°)
use brahe as bh ;
use bh :: utils :: Identifiable ;
fn main () {
bh :: initialize_eop (). unwrap ();
// Load KSAT groundstations
let stations = bh :: datasets :: groundstations :: load_groundstations ( "ksat" ). unwrap ();
// Access the first station
let station = & stations [ 0 ];
// Geographic coordinates (degrees and meters)
let name = station . get_name (). unwrap_or ( "Unknown" );
println! ( "Station: {}" , name );
println! ( "Latitude: {:.4}°" , station . lat ());
println! ( "Longitude: {:.4}°" , station . lon ());
println! ( "Altitude: {:.1} m" , station . alt ());
// Show all stations with their locations
println! ( " \n {} KSAT Stations:" , stations . len ());
for ( i , gs ) in stations . iter (). enumerate () {
let gs_name = gs . get_name (). unwrap_or ( "Unknown" );
println! (
"{:2}. {:30} ({:7.3}°, {:8.3}°)" ,
i + 1 ,
gs_name ,
gs . lat (),
gs . lon ()
);
}
// Expected output:
// Station: Prudhoe Bay
// Latitude: 70.2000°
// Longitude: -148.4700°
// Altitude: 0.0 m
// 36 KSAT Stations:
// 1. Prudhoe Bay ( 70.200°, -148.470°)
// 2. Athens ( 37.850°, 22.620°)
// 3. Awarua (-46.530°, 168.380°)
}
Computing Access Windows Use groundstation data with brahe's access computation to find contact opportunities:
Python Rust
import brahe as bh
import numpy as np
# Initialize EOP data
bh . initialize_eop ()
# Load groundstations from a provider
stations = bh . datasets . groundstations . load ( "ksat" )
print ( f "Computing access for { len ( stations ) } KSAT stations" )
# Create a sun-synchronous orbit satellite
epoch = bh . Epoch . from_datetime ( 2024 , 1 , 1 , 0 , 0 , 0.0 , 0.0 , bh . TimeSystem . UTC )
oe = np . array ([ bh . R_EARTH + 600e3 , 0.001 , 97.8 , 0.0 , 0.0 , 0.0 ])
state = bh . state_koe_to_eci ( oe , bh . AngleFormat . DEGREES )
propagator = bh . KeplerianPropagator . from_eci ( epoch , state , 60.0 ) . with_name ( "EO-Sat" )
# Define access constraint (minimum 5° elevation)
constraint = bh . ElevationConstraint ( min_elevation_deg = 5.0 )
# Compute access windows for 24 hours
duration = 24.0 * 3600.0 # seconds
windows = bh . location_accesses (
stations , [ propagator ], epoch , epoch + duration , constraint
)
# Display results
print ( f " \n Total access windows: { len ( windows ) } " )
print ( " \n First 5 windows:" )
for i , window in enumerate ( windows [: 5 ], 1 ):
duration_min = ( window . end - window . start ) / 60.0
print ( f " { i } . { window . location_name : 20s } -> { window . satellite_name : 10s } " )
print ( f " Start: { window . start } " )
print ( f " Duration: { duration_min : .1f } minutes" )
# Expected output:
# Computing access for 36 KSAT stations
# Total access windows: 213
# First 5 windows:
# 1. Long Beach -> EO-Sat
# Start: 2024-01-01 00:05:08.313 UTC
# Duration: 8.9 minutes
# 2. Thomaston -> EO-Sat
# Start: 2024-01-01 00:07:15.029 UTC
# Duration: 1.7 minutes
# 3. Inuvik -> EO-Sat
# Start: 2024-01-01 00:13:53.159 UTC
# Duration: 10.1 minutes
# 4. Fairbanks -> EO-Sat
# Start: 2024-01-01 00:14:39.836 UTC
# Duration: 8.3 minutes
# 5. Prudhoe Bay -> EO-Sat
# Start: 2024-01-01 00:15:18.853 UTC
# Duration: 9.7 minutes
use brahe as bh ;
use bh :: access :: location_accesses ;
use bh :: utils :: Identifiable ;
use nalgebra as na ;
fn main () {
bh :: initialize_eop (). unwrap ();
// Load groundstations from a provider
let stations = bh :: datasets :: groundstations :: load_groundstations ( "ksat" ). unwrap ();
println! ( "Computing access for {} KSAT stations" , stations . len ());
// Create a sun-synchronous orbit satellite
let epoch = bh :: Epoch :: from_datetime ( 2024 , 1 , 1 , 0 , 0 , 0.0 , 0.0 , bh :: TimeSystem :: UTC );
let oe = na :: SVector :: < f64 , 6 > :: new (
bh :: R_EARTH + 600e3 ,
0.001 ,
97.8_ f64 . to_radians (),
0.0 ,
0.0 ,
0.0 ,
);
let state = bh :: state_koe_to_eci ( oe , bh :: AngleFormat :: Radians );
let propagator =
bh :: KeplerianPropagator :: from_eci ( epoch , state , 60.0 ). with_name ( "EO-Sat" );
// Define access constraint (minimum 5° elevation)
let constraint = bh :: ElevationConstraint :: new ( Some ( 5.0 ), None ). unwrap ();
// Compute access windows for 24 hours
let duration = 24.0 * 3600.0 ; // seconds
let windows = location_accesses (
& stations ,
& vec! [ propagator ],
epoch ,
epoch + duration ,
& constraint ,
None ,
None ,
None ,
). unwrap ();
// Display results
println! ( " \n Total access windows: {}" , windows . len ());
println! ( " \n First 5 windows:" );
for ( i , window ) in windows . iter (). take ( 5 ). enumerate () {
let duration_min = ( window . end () - window . start ()) / 60.0 ;
let loc_name = window . location_name . as_deref (). unwrap_or ( "Unknown" );
let sat_name = window . satellite_name . as_deref (). unwrap_or ( "Unknown" );
println! (
"{}. {:20} -> {:10}" ,
i + 1 ,
loc_name ,
sat_name
);
println! ( " Start: {}" , window . start ());
println! ( " Duration: {:.1} minutes" , duration_min );
}
// Expected output:
// Computing access for 36 KSAT stations
// Total access windows: 213
// First 5 windows:
// 1. Long Beach -> EO-Sat
// Start: 2024-01-01 00:05:08.313 UTC
// Duration: 8.9 minutes
// 2. Thomaston -> EO-Sat
// Start: 2024-01-01 00:07:15.029 UTC
// Duration: 1.7 minutes
// 3. Inuvik -> EO-Sat
// Start: 2024-01-01 00:13:53.159 UTC
// Duration: 10.1 minutes
// 4. Fairbanks -> EO-Sat
// Start: 2024-01-01 00:14:39.836 UTC
// Duration: 8.3 minutes
// 5. Prudhoe Bay -> EO-Sat
// Start: 2024-01-01 00:15:18.853 UTC
// Duration: 9.7 minutes
}
Each groundstation is represented as a PointLocation with standardized properties:
import brahe as bh
stations = bh . datasets . groundstations . load ( "ksat" )
station = stations [ 0 ]
# Geographic coordinates (WGS84)
lon = station . lon () # Longitude in degrees
lat = station . lat () # Latitude in degrees
alt = station . alt () # Altitude in meters
# Metadata properties
props = station . properties
name = station . get_name () # Station name
provider = props [ "provider" ] # Provider name (e.g., "KSAT")
bands = props [ "frequency_bands" ] # Supported bands (e.g., ["S", "X"])
All groundstations include these standard properties:
provider : Provider name (string, e.g., "KSAT", "Atlas") frequency_bands : List of supported frequency bands (e.g., ["S", "X", "Ka"]) Additional properties may be included in future releases as data becomes available.
See Also