Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ const App = () => {

const propagation = usePropagation(config.location, dxLocation, config.propagation);
const mySpots = useMySpots(config.callsign);
const satellites = useSatellites(config.location);
const satellites = useSatellites(config.location, config.satellite);
const localWeather = useWeather(config.location, config.allUnits);
const dxWeather = useWeather(dxLocation, config.allUnits);
const localAlerts = useWeatherAlerts(config.location);
Expand Down
84 changes: 79 additions & 5 deletions src/components/SettingsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ export const SettingsPanel = ({
const [swapHeaderClocks, setSwapHeaderClocks] = useState(config?.swapHeaderClocks || false);
const [showMutualReception, setShowMutualReception] = useState(config?.showMutualReception ?? true);
const [gridSquare, setGridSquare] = useState(config?.locator || '');
const [lat, setLat] = useState(config?.location?.lat ?? 0);
const [lon, setLon] = useState(config?.location?.lon ?? 0);
const [lat, setLat] = useState(config?.location?.lat || 0);
const [lon, setLon] = useState(config?.location?.lon || 0);
const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt || 100);
const [minElev, setMinElev] = useState(config?.satellite?.minElev || 5.0);
const [layout, setLayout] = useState(config?.layout || 'modern');
const [mouseZoom, setMouseZoom] = useState(config?.mouseZoom || 50);
const [timezone, setTimezone] = useState(config?.timezone || '');
Expand Down Expand Up @@ -177,8 +179,10 @@ export const SettingsPanel = ({
if (config) {
setCallsign(config.callsign || '');
setheaderSize(config.headerSize || 1.0);
setLat(config.location?.lat ?? 0);
setLon(config.location?.lon ?? 0);
setLat(config.location?.lat || 0);
setLon(config.location?.lon || 0);
setStationAlt(config.location?.stationAlt || 100);
setMinElev(config.satellite?.minElev || 5.0);
setLayout(config.layout || 'modern');
setMouseZoom(config.mouseZoom || 50);
setTimezone(config.timezone || '');
Expand Down Expand Up @@ -419,7 +423,8 @@ export const SettingsPanel = ({
headerSize: headerSize,
swapHeaderClocks,
showMutualReception,
location: { lat: parseFloat(lat), lon: parseFloat(lon) },
location: { lat: parseFloat(lat) || 0, lon: parseFloat(lon) || 0, stationAlt: parseInt(stationAlt) || 100 },
satellite: { minElev: parseFloat(minElev) || 5.0 },
theme,
customTheme,
layout,
Expand Down Expand Up @@ -3360,6 +3365,75 @@ export const SettingsPanel = ({
Footprints
</label>
</div>

{/* station altitude and minimum elevation inputs */}
<div
style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px', marginBottom: '12px' }}
>
<div>
<label
style={{
display: 'block',
marginBottom: '6px',
color: 'var(--text-muted)',
fontSize: '11px',
textTransform: 'uppercase',
}}
>
Station Altitude [m]
</label>
<input
type="number"
step="1"
value={isNaN(stationAlt) ? '' : stationAlt}
onChange={(e) => setStationAlt(e.target.valueAsNumber ?? 100)}
style={{
width: '100%',
padding: '10px',
background: 'var(--bg-tertiary)',
border: '1px solid var(--border-color)',
borderRadius: '6px',
color: 'var(--text-primary)',
fontSize: '14px',
fontFamily: 'JetBrains Mono, monospace',
boxSizing: 'border-box',
}}
/>
</div>
<div>
<label
style={{
display: 'block',
marginBottom: '6px',
color: 'var(--text-muted)',
fontSize: '11px',
textTransform: 'uppercase',
}}
>
Minimum Elevation [°]
</label>
<input
type="number"
step="0.1"
min="-5.0"
max="89.0"
value={isNaN(minElev) ? '' : minElev}
onChange={(e) => setMinElev(isNaN(e.target.valueAsNumber) ? 5.0 : e.target.valueAsNumber)}
style={{
width: '100%',
padding: '10px',
background: 'var(--bg-tertiary)',
border: '1px solid var(--border-color)',
borderRadius: '6px',
color: 'var(--text-primary)',
fontSize: '14px',
fontFamily: 'JetBrains Mono, monospace',
boxSizing: 'border-box',
}}
/>
</div>
</div>

{/* Lead Time Slider WIP
<div style={{ marginTop: '8px' }}>
<label style={{
Expand Down
15 changes: 10 additions & 5 deletions src/hooks/useSatellites.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function round(value, decimals) {
return Math.round(value * factor) / factor;
}

export const useSatellites = (observerLocation) => {
export const useSatellites = (observerLocation, satelliteConfig) => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [tleData, setTleData] = useState({});
Expand Down Expand Up @@ -51,7 +51,7 @@ export const useSatellites = (observerLocation) => {
const observerGd = {
longitude: satellite.degreesToRadians(observerLocation.lon),
latitude: satellite.degreesToRadians(observerLocation.lat),
height: 0.1, // km above sea level
height: (observerLocation.stationAlt || 100) / 1000, // above sea level [km], stationAlt is [m]), defaults to 100m
};

Object.entries(tleData).forEach(([name, tle]) => {
Expand Down Expand Up @@ -82,10 +82,13 @@ export const useSatellites = (observerLocation) => {
const elevation = satellite.radiansToDegrees(lookAngles.elevation);
const rangeSat = lookAngles.rangeSat;

// Calculate range-rate and doppler factor, only if satellite is above horizon
const isVisible = elevation >= satelliteConfig.minElev; // visible only if above minimum elevation

// Calculate range-rate and doppler factor, only if satellite is visible
let dopplerFactor = 1;
let rangeRate = 0;
if (elevation > 0) {

if (isVisible) {
const observerEcf = satellite.geodeticToEcf(observerGd);
const velocityEcf = satellite.eciToEcf(velocityEci, gmst);
dopplerFactor = satellite.dopplerFactor(observerEcf, positionEcf, velocityEcf);
Expand Down Expand Up @@ -125,6 +128,8 @@ export const useSatellites = (observerLocation) => {

positions.push({
name: tle.name || name,
tle1: line1,
tle2: line2,
lat,
lon,
alt: round(alt, 1),
Expand All @@ -134,7 +139,7 @@ export const useSatellites = (observerLocation) => {
range: round(rangeSat, 1),
rangeRate: round(rangeRate, 3),
dopplerFactor: round(dopplerFactor, 9),
isVisible: elevation > 0,
isVisible, // visible if above minimum elevation
isPopular: tle.priority <= 2,
track,
footprintRadius: Math.round(footprintRadius),
Expand Down
Loading
Loading