Neue Seite fuer Mond-Planeten-Bedeckungen mit Jahresberechnung hinzufuegen
Berechnet Bedeckungen der Planeten Merkur bis Neptun durch den Mond fuer ein ganzes Jahr am Standardstandort, inklusive Detailkarte. Ereignisse unter dem Horizont werden weiterhin angezeigt statt gefiltert, dafuer mit eigenem Sichtbarkeits-Hinweis. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,7 @@ Nicht jede Berechnung ist Skyfield oder Astronomy Engine:
|
||||
| `sonnenfinsternis.php` | **Astronomy Engine**, einschließlich lokaler Berechnung für den Standardstandort. |
|
||||
| `mondfinsternis.php` | **Astronomy Engine**. Der Zeitpunkt der Finsternis ist global; eine lokale Sichtbarkeitsbewertung ist davon getrennt. |
|
||||
| `sternbedeckungen.php` | **Astronomy Engine** über die lokale Python-API. Topozentrische Koordinaten und der Standardstandort werden berücksichtigt. |
|
||||
| `mondplanetenbedeckungen.php` | **Astronomy Engine** über die lokale Python-API. Durchsucht ein ganzes Jahr nach Mond-Planeten-Bedeckungen (Merkur bis Neptun) für den Standardstandort; berücksichtigt die scheinbare Scheibengröße von Mond und Planet. |
|
||||
| `moonphase.php` | **Astronomy Engine** im Browser beziehungsweise über die lokale Python-API. |
|
||||
| `moonyear.php` | **Astronomy Engine** für Mondphasen und Mondpositionen. |
|
||||
| `satellitenhimmel.php` | **SGP4** für Satellitenbahnen; Astronomy Engine für astronomischen Kontext wie Sonne, Mond und Dämmerung. |
|
||||
|
||||
@@ -134,6 +134,7 @@ function manageablePublicPages(): array
|
||||
'sonnenfinsternis.php' => 'Sonnenfinsternis',
|
||||
'bedeckung.php' => 'Bedeckungsphänomene',
|
||||
'sternbedeckungen.php' => 'Mond-Stern-Bedeckungen',
|
||||
'mondplanetenbedeckungen.php' => 'Mond-Planeten-Bedeckungen',
|
||||
'monatsvorhersage.php' => 'Monatsvorhersage',
|
||||
'moonyear.php' => 'Mondphasen-Jahresübersicht',
|
||||
'wochenvorhersage.php' => 'Wochenvorhersage',
|
||||
|
||||
@@ -4676,6 +4676,12 @@ body.solarsystem-page:not(.jupitersystem-page) .solarsystem-stage-wrap {
|
||||
box-shadow: inset 0 0 0 1px rgba(143, 230, 141, 0.22);
|
||||
}
|
||||
|
||||
.occult-visibility-below {
|
||||
background: rgba(136, 148, 173, 0.16);
|
||||
color: #9aa6c2;
|
||||
box-shadow: inset 0 0 0 1px rgba(154, 166, 194, 0.22);
|
||||
}
|
||||
|
||||
.occult-detail-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ $menuGroups = [
|
||||
['href' => 'sonnenfinsternis.php', 'label' => 'Sonnenfinsternis'],
|
||||
['href' => 'bedeckung.php', 'label' => 'Bedeckungsphänomene'],
|
||||
['href' => 'sternbedeckungen.php', 'label' => 'Mond-Stern-Bedeckungen'],
|
||||
['href' => 'mondplanetenbedeckungen.php', 'label' => 'Mond-Planeten-Bedeckungen'],
|
||||
],
|
||||
],
|
||||
[
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+155
-2
@@ -5844,6 +5844,154 @@ def action_moon_star_occultations(args: list[str]) -> dict:
|
||||
}
|
||||
|
||||
|
||||
PLANET_OCCULTATION_DEFS = [
|
||||
("Merkur", astronomy.Body.Mercury, "mercury"),
|
||||
("Venus", astronomy.Body.Venus, "venus"),
|
||||
("Mars", astronomy.Body.Mars, "mars"),
|
||||
("Jupiter", astronomy.Body.Jupiter, "jupiter"),
|
||||
("Saturn", astronomy.Body.Saturn, "saturn"),
|
||||
("Uranus", astronomy.Body.Uranus, "uranus"),
|
||||
("Neptun", astronomy.Body.Neptune, "neptune"),
|
||||
]
|
||||
|
||||
|
||||
def compute_moon_planet_occultations_for_range(
|
||||
observer: astronomy.Observer,
|
||||
utc_start: datetime,
|
||||
utc_end: datetime,
|
||||
tz: ZoneInfo,
|
||||
) -> list[dict]:
|
||||
scan_step = timedelta(hours=1)
|
||||
coarse_threshold_deg = 3.0
|
||||
results: list[dict] = []
|
||||
|
||||
for label, body, key in PLANET_OCCULTATION_DEFS:
|
||||
samples: list[tuple[datetime, float]] = []
|
||||
current = utc_start
|
||||
while current <= utc_end:
|
||||
samples.append((current, moon_planet_separation_deg(body, observer, current)))
|
||||
current += scan_step
|
||||
if samples[-1][0] < utc_end:
|
||||
samples.append((utc_end, moon_planet_separation_deg(body, observer, utc_end)))
|
||||
|
||||
seen_ranges: list[tuple[datetime, datetime]] = []
|
||||
for index in range(1, len(samples) - 1):
|
||||
prev_t, prev_sep = samples[index - 1]
|
||||
curr_t, curr_sep = samples[index]
|
||||
next_t, next_sep = samples[index + 1]
|
||||
|
||||
if curr_sep > coarse_threshold_deg:
|
||||
continue
|
||||
if curr_sep > prev_sep or curr_sep > next_sep:
|
||||
continue
|
||||
|
||||
left = max(utc_start, curr_t - scan_step)
|
||||
right = min(utc_end, curr_t + scan_step)
|
||||
|
||||
if any(not (right <= seen_left or left >= seen_right) for seen_left, seen_right in seen_ranges):
|
||||
continue
|
||||
|
||||
min_time_utc, min_sep = refine_minimum_separation(body, observer, left, right)
|
||||
seen_ranges.append((left, right))
|
||||
|
||||
overlap_fraction = moon_planet_overlap_fraction(body, observer, min_time_utc)
|
||||
if overlap_fraction <= 0.0:
|
||||
continue
|
||||
|
||||
time_value = dt_to_time(min_time_utc)
|
||||
moon_eq = astronomy.Equator(astronomy.Body.Moon, time_value, observer, True, True)
|
||||
planet_eq = astronomy.Equator(body, time_value, observer, True, True)
|
||||
sun_eq = astronomy.Equator(astronomy.Body.Sun, time_value, observer, True, True)
|
||||
moon_hor = astronomy.Horizon(time_value, observer, moon_eq.ra, moon_eq.dec, astronomy.Refraction.Normal)
|
||||
planet_hor = astronomy.Horizon(time_value, observer, planet_eq.ra, planet_eq.dec, astronomy.Refraction.Normal)
|
||||
sun_hor = astronomy.Horizon(time_value, observer, sun_eq.ra, sun_eq.dec, astronomy.Refraction.Normal)
|
||||
|
||||
below_horizon = float(moon_hor.altitude) <= 0.0 or float(planet_hor.altitude) <= 0.0
|
||||
|
||||
ingress_time = refine_occultation_contact(body, observer, min_time_utc, -1)
|
||||
egress_time = refine_occultation_contact(body, observer, min_time_utc, 1)
|
||||
|
||||
duration_seconds = None
|
||||
if ingress_time is not None and egress_time is not None:
|
||||
duration_seconds = int(round((egress_time - ingress_time).total_seconds()))
|
||||
|
||||
moon_radius_deg = moon_angular_radius_deg(float(moon_eq.dist))
|
||||
planet_radius_deg = planet_angular_radius_deg(body, float(planet_eq.dist))
|
||||
|
||||
results.append({
|
||||
"planet_key": key,
|
||||
"planet_label": label,
|
||||
"ingress": serialize_occultation_time(ingress_time, tz),
|
||||
"maximum": serialize_occultation_time(min_time_utc, tz),
|
||||
"egress": serialize_occultation_time(egress_time, tz),
|
||||
"partial_start": ingress_time is None,
|
||||
"partial_end": egress_time is None,
|
||||
"duration_seconds": duration_seconds,
|
||||
"separation_arcmin": float(min_sep) * 60.0,
|
||||
"moon_radius_arcmin": moon_radius_deg * 60.0,
|
||||
"planet_radius_arcsec": planet_radius_deg * 3600.0,
|
||||
"overlap_fraction": float(overlap_fraction),
|
||||
"is_total": overlap_fraction >= 0.999,
|
||||
"moon_alt_deg": float(moon_hor.altitude),
|
||||
"planet_alt_deg": float(planet_hor.altitude),
|
||||
"sun_alt_deg": float(sun_hor.altitude),
|
||||
"below_horizon": below_horizon,
|
||||
"visibility": {"key": "below_horizon", "label": "Unter Horizont"} if below_horizon
|
||||
else classify_visibility(float(sun_hor.altitude)),
|
||||
})
|
||||
|
||||
results.sort(
|
||||
key=lambda item: item["maximum"]["utc_iso"] if item["maximum"] else "9999-99-99T99:99:99Z"
|
||||
)
|
||||
return results
|
||||
|
||||
|
||||
def action_moon_planet_occultations_for_year(args: list[str]) -> dict:
|
||||
if len(args) != 5:
|
||||
fail(
|
||||
"Aktion moon_planet_occultations_for_year erwartet 5 Argumente: latitude longitude elevation year timezone",
|
||||
extra={"argv": args},
|
||||
)
|
||||
|
||||
latitude = parse_float(args[0], "Latitude")
|
||||
longitude = parse_float(args[1], "Longitude")
|
||||
elevation = parse_float(args[2], "Elevation")
|
||||
|
||||
try:
|
||||
year = int(args[3])
|
||||
except ValueError as exc:
|
||||
fail("Jahr ist ungueltig.", extra={"details": str(exc), "argv": args})
|
||||
|
||||
timezone_name = args[4]
|
||||
try:
|
||||
tz = ZoneInfo(timezone_name)
|
||||
except Exception as exc:
|
||||
fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)})
|
||||
|
||||
observer = astronomy.Observer(latitude, longitude, elevation)
|
||||
local_start = datetime(year, 1, 1, 0, 0, 0, tzinfo=tz)
|
||||
local_end = datetime(year + 1, 1, 1, 0, 0, 0, tzinfo=tz)
|
||||
utc_start = local_start.astimezone(timezone.utc)
|
||||
utc_end = local_end.astimezone(timezone.utc)
|
||||
|
||||
results = compute_moon_planet_occultations_for_range(observer, utc_start, utc_end, tz)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"action": "moon_planet_occultations_for_year",
|
||||
"selected": {
|
||||
"year": year,
|
||||
"timezone": timezone_name,
|
||||
},
|
||||
"observer": {
|
||||
"latitude": latitude,
|
||||
"longitude": longitude,
|
||||
"elevation": elevation,
|
||||
},
|
||||
"results": results,
|
||||
}
|
||||
|
||||
|
||||
# ── satellite_passes ──────────────────────────────────────────────────────────
|
||||
|
||||
import math as _math
|
||||
@@ -6415,7 +6563,7 @@ def action_barycenter(args: list[str]) -> dict:
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) < 2:
|
||||
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month"]})
|
||||
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month", "moon_planet_occultations_for_year"]})
|
||||
|
||||
action = sys.argv[1]
|
||||
args = sys.argv[2:]
|
||||
@@ -6605,6 +6753,11 @@ def main() -> None:
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
if action == "moon_planet_occultations_for_year":
|
||||
result = action_moon_planet_occultations_for_year(args)
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
if action == "lunar_eclipses_for_year":
|
||||
result = action_lunar_eclipses_for_year(args)
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
@@ -6615,7 +6768,7 @@ def main() -> None:
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month"]})
|
||||
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month", "moon_planet_occultations_for_year"]})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user