pull/27/head
accius 4 days ago
parent c84301e041
commit 073db62b41

@ -214,6 +214,13 @@
border: 2px solid #ffaa00;
}
.moon-marker {
background: radial-gradient(circle, #e8e8f0 0%, #8888aa 100%);
width: 24px;
height: 24px;
border: 2px solid #aaaacc;
}
/* Map style selector */
.map-style-control {
position: absolute;
@ -456,6 +463,97 @@
return { lat: declination, lon: longitude };
};
// Calculate moon position (sublunar point)
const getMoonPosition = (date) => {
// Julian date calculation
const JD = date.getTime() / 86400000 + 2440587.5;
const T = (JD - 2451545.0) / 36525; // Julian centuries from J2000
// Moon's mean longitude
const L0 = (218.316 + 481267.8813 * T) % 360;
// Moon's mean anomaly
const M = (134.963 + 477198.8676 * T) % 360;
const MRad = M * Math.PI / 180;
// Moon's mean elongation
const D = (297.850 + 445267.1115 * T) % 360;
const DRad = D * Math.PI / 180;
// Sun's mean anomaly
const Ms = (357.529 + 35999.0503 * T) % 360;
const MsRad = Ms * Math.PI / 180;
// Moon's argument of latitude
const F = (93.272 + 483202.0175 * T) % 360;
const FRad = F * Math.PI / 180;
// Longitude corrections (simplified)
const dL = 6.289 * Math.sin(MRad)
+ 1.274 * Math.sin(2 * DRad - MRad)
+ 0.658 * Math.sin(2 * DRad)
+ 0.214 * Math.sin(2 * MRad)
- 0.186 * Math.sin(MsRad)
- 0.114 * Math.sin(2 * FRad);
// Moon's ecliptic longitude
const moonLon = ((L0 + dL) % 360 + 360) % 360;
// Moon's ecliptic latitude (simplified)
const moonLat = 5.128 * Math.sin(FRad)
+ 0.281 * Math.sin(MRad + FRad)
+ 0.278 * Math.sin(MRad - FRad);
// Convert ecliptic to equatorial coordinates
const obliquity = 23.439 - 0.0000004 * (JD - 2451545.0);
const oblRad = obliquity * Math.PI / 180;
const moonLonRad = moonLon * Math.PI / 180;
const moonLatRad = moonLat * Math.PI / 180;
// Right ascension
const RA = Math.atan2(
Math.sin(moonLonRad) * Math.cos(oblRad) - Math.tan(moonLatRad) * Math.sin(oblRad),
Math.cos(moonLonRad)
) * 180 / Math.PI;
// Declination
const dec = Math.asin(
Math.sin(moonLatRad) * Math.cos(oblRad) +
Math.cos(moonLatRad) * Math.sin(oblRad) * Math.sin(moonLonRad)
) * 180 / Math.PI;
// Greenwich Mean Sidereal Time
const GMST = (280.46061837 + 360.98564736629 * (JD - 2451545.0)) % 360;
// Sublunar point longitude
const sublunarLon = ((RA - GMST) % 360 + 540) % 360 - 180;
return { lat: dec, lon: sublunarLon };
};
// Calculate moon phase (0-1, 0=new, 0.5=full)
const getMoonPhase = (date) => {
const JD = date.getTime() / 86400000 + 2440587.5;
const T = (JD - 2451545.0) / 36525;
const D = (297.850 + 445267.1115 * T) % 360; // Mean elongation
// Phase angle (simplified)
const phase = ((D + 180) % 360) / 360;
return phase;
};
// Get moon phase emoji
const getMoonPhaseEmoji = (phase) => {
if (phase < 0.0625) return '🌑'; // New moon
if (phase < 0.1875) return '🌒'; // Waxing crescent
if (phase < 0.3125) return '🌓'; // First quarter
if (phase < 0.4375) return '🌔'; // Waxing gibbous
if (phase < 0.5625) return '🌕'; // Full moon
if (phase < 0.6875) return '🌖'; // Waning gibbous
if (phase < 0.8125) return '🌗'; // Last quarter
if (phase < 0.9375) return '🌘'; // Waning crescent
return '🌑'; // New moon
};
const calculateSunTimes = (lat, lon, date) => {
const dayOfYear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000);
const declination = -23.45 * Math.cos((360/365) * (dayOfYear + 10) * Math.PI / 180);
@ -2155,6 +2253,7 @@
const deMarkerRef = useRef(null);
const dxMarkerRef = useRef(null);
const sunMarkerRef = useRef(null);
const moonMarkerRef = useRef(null);
const potaMarkersRef = useRef([]);
const mySpotsMarkersRef = useRef([]);
const mySpotsLinesRef = useRef([]);
@ -2286,6 +2385,7 @@
if (deMarkerRef.current) map.removeLayer(deMarkerRef.current);
if (dxMarkerRef.current) map.removeLayer(dxMarkerRef.current);
if (sunMarkerRef.current) map.removeLayer(sunMarkerRef.current);
if (moonMarkerRef.current) map.removeLayer(moonMarkerRef.current);
// DE Marker
const deIcon = L.divIcon({
@ -2321,8 +2421,56 @@
.bindPopup('Subsolar Point')
.addTo(map);
// Moon marker
const moonPos = getMoonPosition(new Date());
const moonPhase = getMoonPhase(new Date());
const moonEmoji = getMoonPhaseEmoji(moonPhase);
const moonIcon = L.divIcon({
className: 'custom-marker moon-marker',
html: moonEmoji,
iconSize: [24, 24],
iconAnchor: [12, 12]
});
moonMarkerRef.current = L.marker([moonPos.lat, moonPos.lon], { icon: moonIcon })
.bindPopup(`Sublunar Point<br><span style="font-size: 24px">${moonEmoji}</span>`)
.addTo(map);
}, [deLocation, dxLocation]);
// Update sun and moon positions every minute
useEffect(() => {
if (!mapInstanceRef.current) return;
const map = mapInstanceRef.current;
const updateCelestialBodies = () => {
// Update sun position
if (sunMarkerRef.current) {
const sunPos = getSunPosition(new Date());
sunMarkerRef.current.setLatLng([sunPos.lat, sunPos.lon]);
}
// Update moon position
if (moonMarkerRef.current) {
const moonPos = getMoonPosition(new Date());
const moonPhase = getMoonPhase(new Date());
const moonEmoji = getMoonPhaseEmoji(moonPhase);
moonMarkerRef.current.setLatLng([moonPos.lat, moonPos.lon]);
// Update moon icon to reflect current phase
const moonIcon = L.divIcon({
className: 'custom-marker moon-marker',
html: moonEmoji,
iconSize: [24, 24],
iconAnchor: [12, 12]
});
moonMarkerRef.current.setIcon(moonIcon);
moonMarkerRef.current.setPopupContent(`Sublunar Point<br><span style="font-size: 24px">${moonEmoji}</span>`);
}
};
const interval = setInterval(updateCelestialBodies, 60000); // Every minute
return () => clearInterval(interval);
}, []);
// Update POTA markers
// Update my spots markers and connection lines
useEffect(() => {
@ -2763,6 +2911,7 @@
<span style={{ color: '#00ff00' }}>● DE</span>
<span style={{ color: '#ff4444' }}>● DX</span>
<span style={{ color: '#ffff00' }}>☀ Sun</span>
<span style={{ color: '#aaccff' }}>🌙 Moon</span>
</div>
</div>
</div>

Loading…
Cancel
Save

Powered by TurnKey Linux.