Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23ad1973fb | ||
|
|
d80382bd3f | ||
|
|
291b5d973e | ||
|
|
59cb076640 | ||
|
|
71c8e832ba | ||
|
|
5652cc7e40 | ||
|
|
86fccdc773 | ||
|
|
61aa9cd89f | ||
|
|
f550875107 | ||
|
|
4c6fe6faeb | ||
|
|
efb2d8ed04 |
@@ -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. |
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
"label": "Sternenhimmel",
|
||||
"menu_group": "Himmel & Planeten"
|
||||
},
|
||||
"beobachtungsvorschlaege.php": {
|
||||
"label": "Beobachtungsvorschläge",
|
||||
"menu_group": "Sternenhimmel & Karten"
|
||||
},
|
||||
"drehbare_sternkarte.php": {
|
||||
"label": "Drehbare Sternkarte",
|
||||
"menu_group": "Himmel & Planeten"
|
||||
@@ -146,6 +150,7 @@
|
||||
"jupitersystem.php",
|
||||
"tagbogen.php",
|
||||
"sternenhimmel.php",
|
||||
"beobachtungsvorschlaege.php",
|
||||
"drehbare_sternkarte.php",
|
||||
"meteorshowers.php",
|
||||
"geocron/index.php",
|
||||
|
||||
@@ -270,6 +270,7 @@ CREATE TABLE IF NOT EXISTS `dso_objects` (
|
||||
`cstar_names` text DEFAULT NULL,
|
||||
`identifiers` longtext DEFAULT NULL,
|
||||
`common_names` longtext DEFAULT NULL,
|
||||
`common_names_german` longtext DEFAULT NULL,
|
||||
`ned_notes` longtext DEFAULT NULL,
|
||||
`openngc_notes` longtext DEFAULT NULL,
|
||||
`image` varchar(255) DEFAULT NULL,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Berechnung und Filter für Beobachtungsvorschläge
|
||||
|
||||
Stand: 15. September 2026. Die GUI ist mit einer eigenständigen Berechnung verbunden. Grundlage sind die Projektstruktur und lesende Abfragen der konfigurierten Datenbank.
|
||||
|
||||
## Aufbau
|
||||
|
||||
- `public/beobachtungsvorschlaege.php`: Formular, Standardstandort und Sitzungstoken.
|
||||
- `public/js/observation_suggestions.js`: Anfrage und Ergebnisliste mit 50 Zielen pro Seite.
|
||||
- `public/ajax/observation_suggestions.php`: POST-Endpunkt mit Anmeldung, derselben Seitenberechtigung wie die GUI, CSRF-Prüfung und erneuter serverseitiger Abfrage des Standardstandorts.
|
||||
- `public/observation_suggestions_helpers.php`: Katalogauswahl und Python-Prozess mit temporärer JSON-Datei, Shell-freiem Aufruf und 90-Sekunden-Zeitlimit.
|
||||
- `public/py/observation_suggestions_api.py`: eigenständige Berechnung mit der lokalen Astronomy-Engine-Bibliothek und dem vorhandenen Kometen-Bahnhelfer `comets.py`. Kein Import und kein Aufruf von `api.py`.
|
||||
|
||||
Der Browser darf Filter senden, aber weder fremde Standorte noch Katalogdaten vorgeben. Die Berechnung schreibt keine Daten in die Datenbank. Der Python-Prozess benötigt Python 3.10+ und eine verfügbare Zeitzonendatenbank (`zoneinfo`, auf Windows gegebenenfalls das Paket `tzdata`).
|
||||
|
||||
## Zuordnung der Checkboxen
|
||||
|
||||
| GUI-Wert | Quelle / Auswahl |
|
||||
| --- | --- |
|
||||
| `open_clusters` | `dso_objects.object_type_abrev = 'OCl'` |
|
||||
| `globular_clusters` | `GCl` |
|
||||
| `galaxies` | `G`, `GPair`, `GTrpl`, `GGroup` |
|
||||
| `nebulae` | `Neb`, `EmN`, `HII`, `RfN`, `SNR`, `Cl+N` |
|
||||
| `planetary_nebulae` | `PN` |
|
||||
| `double_stars` | Zunächst `dso_objects` mit `**`; kein vollständiger Doppelsternkatalog |
|
||||
| `variable_stars` | Kandidaten aus `star_hipparcos` mit nicht leerem `var`; Periodizität und Ereignisvorhersagen benötigen zusätzliche geprüfte Daten |
|
||||
| `comets` | Bahnelemente aus `comets_mpc`; Position und scheinbare Helligkeit zeitabhängig berechnen |
|
||||
| `moon`, `planets` | Bestehende astronomische Berechnungen |
|
||||
|
||||
`Cl+N` wird eindeutig der Nebel-Auswahl zugeordnet. Mehrere ausgewählte Typen werden vereinigt; ein Objekt soll nur einmal erscheinen.
|
||||
|
||||
Nur explizit zugeordnete DSO-Typen berücksichtigen. Insbesondere `Dup` (Dubletten), `NonEx` (nicht existente Objekte), `Other`, einfache Sterne (`*`) und Novae (`Nova`) nicht automatisch übernehmen. Sternassoziationen (`*Ass`) sind vorerst keiner Checkbox zugeordnet.
|
||||
|
||||
## Größe und Helligkeit
|
||||
|
||||
- Der Größenfilter gilt ausschließlich für die fünf Deep-Sky-Gruppen in der Tabelle, niemals für Einzelsterne, Doppelsterne, Veränderliche, Planeten, Mond oder Kometen.
|
||||
- Die maximale Deep-Sky-Größe wird im Formular in Bogenminuten eingegeben und ist auf 60′ begrenzt; ein leeres Feld hebt die jeweilige Grenze auf. Intern wird weiterhin in Bogensekunden gerechnet.
|
||||
- Als Größenmaß dient die große Achse `major_axis`: Bogenminuten × 60 = Bogensekunden. Der Import übernimmt diesen Wert unverändert; die Einheit ist in der [OpenNGC-Katalogbeschreibung](https://github.com/mattiaverga/OpenNGC/blob/master/NGC_guide.txt) dokumentiert. Fehlende oder nicht positive Größen werden bei aktiver Größengrenze ausgelassen.
|
||||
- Für Deep Sky die visuelle Helligkeit `v_mag` verwenden. Andere Filterbänder nicht stillschweigend als V-Helligkeit einsetzen. `cstar_v_mag` ist die Helligkeit des Zentralsterns, nicht des gesamten Nebels.
|
||||
- Vorgabe: 12 mag oder heller, also numerisch `v_mag <= 12`.
|
||||
- Bei aktiver Helligkeitsgrenze Objekte ohne Helligkeitsangabe standardmäßig auslassen. Die neue, zunächst nicht ausgewählte Checkbox `include_unknown_magnitude` erlaubt ihre gesonderte Aufnahme als „Helligkeit unbekannt“. Alle anderen anwendbaren Filter gelten weiterhin.
|
||||
- Ohne Helligkeitsgrenze schränkt ein fehlender Helligkeitswert die Auswahl nicht ein.
|
||||
- Bei Sternen und Kometen die jeweils passende scheinbare Helligkeit verwenden; die absolute Kometenhelligkeit ist kein direkter Ersatz.
|
||||
|
||||
## Beobachtungsnacht
|
||||
|
||||
- Standardstandort des Benutzers aus dem gemeinsamen Header verwenden.
|
||||
- Datum bezeichnet den Abend bis zum folgenden Morgen; Vorgabe ist heute in der Standortzeitzone.
|
||||
- Sonnenhöhe höchstens −12° als Vorgabe. Erste und zweite Hälfte des passenden nächtlichen Zeitfensters sind separat auswählbar, zunächst beide.
|
||||
- Höhe, Azimut, Sonnenhöhe und optionalen Mondabstand für den jeweiligen Zeitpunkt berechnen. Die Auswahl der Nachtabschnitte und die Bedingungen müssen gleichzeitig erfüllt sein.
|
||||
|
||||
## Verfahren und Genauigkeit
|
||||
|
||||
1. Suche zwischen 12 Uhr am gewählten Datum und 12 Uhr am Folgetag in Standortzeit nach Unterschreitungen der Sonnenhöhen-Grenze. Sonnenhöhe: topozentrischer Sonnenmittelpunkt, ohne atmosphärische Refraktion. Übergänge werden im Fünf-Minuten-Raster gesucht und per Intervallhalbierung auf etwa eine Sekunde eingegrenzt.
|
||||
2. Teile jeden gefundenen Dunkelabschnitt in zwei gleich lange Hälften. Zeitrechnung erfolgt intern in UTC; dadurch werden Sommerzeitwechsel berücksichtigt. Bei durchgängiger Dunkelheit wird die Begrenzung auf 12 Uhr bis 12 Uhr ausdrücklich angezeigt; bei fehlender Dunkelphase gibt es eine entsprechende Meldung.
|
||||
3. Prüfe die ausgewählten Abschnitte alle fünf Minuten einschließlich der Randpunkte. DSO- und Sternkoordinaten werden vom J2000-System in das horizontale System des Beobachters gedreht, einschließlich Präzession/Nutation. Sterneigenbewegung und jährliche Aberration der Katalogsterne sind in dieser Planungsversion nicht enthalten. Höhen sind geometrisch, ohne Refraktion; Azimut zählt von Nord über Ost.
|
||||
4. Für Mond und Planeten liefert Astronomy Engine topozentrische Positionen mit Lichtlaufzeit und Aberration sowie modellierte Helligkeiten. Kometen verwenden den vorhandenen Zweikörper-Bahnhelfer, mit iterierter Lichtlaufzeit und Beobachterparallaxe; Bahnstörungen sind nicht enthalten. Bahnepoche und Modellcharakter werden angezeigt.
|
||||
5. Prüfe alle Filter gemeinsam an jedem Zeitpunkt. Der Mondabstand greift nur bei Mond über dem geometrischen Horizont und niemals für den Mond selbst. Zusammenhängende passende Messpunkte bilden ungefähre Zeitfenster. Sehr kurze Fenster oder kurze Unterbrechungen zwischen Messpunkten können unentdeckt bleiben.
|
||||
6. Die Spalte „Zeit der größten Höhe (ca.)“ zeigt den passenden Messpunkt mit der größten Höhe innerhalb der ausgewählten Filter und Nachtabschnitte. Das muss nicht die Kulmination der gesamten Nacht sein. Höhe, Azimut und Helligkeit der Ergebniszeile beziehen sich auf diesen Zeitpunkt.
|
||||
7. Die GUI sortiert zunächst nach Höhe absteigend. Alle acht Spalten sind per Überschrift auf- und absteigend sortierbar, jeweils über die komplette Ergebnisliste vor der Paginierung. Höhe und Azimut sind getrennte Spalten. Zeiten werden nach ihrem tatsächlichen Zeitpunkt, Zahlen numerisch und Objektnamen mit natürlicher Zahlensortierung verglichen. Zeitfenster werden nach ihrem ersten Beginn sortiert. Fehlende Werte der gewählten Sortierspalte bleiben in beiden Richtungen am Ende. Ein Sortierwechsel springt zur ersten Seite; eine neue Berechnung behält die Sortierauswahl bei.
|
||||
|
||||
Sichtbarkeit bedeutet hier Erfüllung der gewählten geometrischen und Helligkeitsfilter, keine Garantie für visuelle Erkennbarkeit. Wetter, Seeing, lokale Horizonthindernisse, Teleskopöffnung und Flächenhelligkeit gehen noch nicht in eine Bewertung ein. Veränderliche werden anhand der Kataloghelligkeit gefiltert; aktuelle Helligkeiten und Extremzeiten werden nicht behauptet.
|
||||
|
||||
## Prüfung
|
||||
|
||||
Ergebnisbegrenzung: Das Feld „Maximal pro Objektgruppe“ ist mit 30 vorbelegt. Der Button „Hellste je Gruppe anzeigen“ wählt aus sämtlichen berechneten Treffern je Checkbox-Gruppe maximal X Objekte nach aufsteigender mag-Helligkeit aus. Bei gleicher Helligkeit entscheidet die größere Höhe, danach Name und Kennung. Unbekannte Helligkeiten werden in dieser Auswahl ausgelassen. Anschließend greifen die gewählten Sortierkriterien und die Paginierung. Die Begrenzung bleibt bei erneuter Berechnung aktiv; „Alle Treffer anzeigen“ hebt sie ohne Neuberechnung auf. Beim ersten Laden ist die Begrenzung noch nicht angewendet.
|
||||
|
||||
Mehrfachsortierung in der GUI: Ein normaler Überschriftenklick ersetzt die Sortierkriterien. Umschalt + Klick oder der aktivierte Modus „Weitere Sortierkriterien hinzufügen“ ergänzt ein Kriterium bzw. kehrt die Richtung eines vorhandenen Kriteriums um. Nummerierte Pfeile und ein lesbarer Statustext zeigen die Priorität. Folge-Kriterien entscheiden bei gleichen Werten der vorherigen Kriterien; fehlende Werte folgen innerhalb der jeweiligen Gruppe am Ende. Die Kriterien bleiben bei einer neuen Berechnung erhalten.
|
||||
|
||||
`python -m unittest discover -s public/py -p test_observation_suggestions_api.py`
|
||||
|
||||
Die Tests prüfen unter anderem Azimut über Norden, Größenausnahmen, Helligkeitsrichtung, Mondabstand, Nachthälften, Sommerzeitwechsel, Polartag/-nacht und die Koordinatentransformation gegen den separaten Horizont-Aufruf der Bibliothek. Zusätzlich wurde ein vollständiger Browserdurchlauf mit echten Katalogdaten, Paginierung und schmalem Bildschirm geprüft; API-Prüfungen deckten fehlende Anmeldung, ungültigen CSRF-Token und unzulässige Filterwerte ab.
|
||||
|
||||
## Datenlücken
|
||||
|
||||
Bei der Prüfung hatten nur 1.379 von 10.489 einzelnen Galaxien und 9 von 245 DSO-Doppelsternen eine V-Helligkeit. Daher die Option für unbekannte Helligkeiten.
|
||||
|
||||
In `star_hipparcos` waren 5.990 Sterne mit nicht leerem `var` vorhanden. Das allein belegt weder eine stabile Periode noch ein bevorstehendes Minimum oder Maximum. Dazu siehe [Datenquellen für veränderliche Sterne](DATENQUELLEN_VERAENDERLICHE_STERNE.md).
|
||||
@@ -0,0 +1,98 @@
|
||||
# Datenquellen für Minima und Maxima veränderlicher Sterne
|
||||
|
||||
Recherchestand: 15. September 2026. Überlegungen für die Seite „Beobachtungsvorschläge“; noch keine Implementierung oder Datenübernahme.
|
||||
|
||||
## Empfehlung
|
||||
|
||||
Für einen ersten, überschaubaren Sternbestand würde ich **BAV-Vorhersagen als Ausgangspunkt**, **AAVSO VSX für Stammdaten und Referenzen** und **VarAstro beziehungsweise AAVSO-Beobachtungen zur Überprüfung** verwenden. Eine einzige Quelle sollte nicht ungeprüft alle Sterntypen abdecken.
|
||||
|
||||
Dabei drei unterschiedliche Datenarten getrennt behandeln:
|
||||
|
||||
- **Vorhersagen:** bereits berechnete zukünftige Minima oder Maxima.
|
||||
- **Ephemeridenelemente:** Referenzzeitpunkt und Periode, aus denen wir Ereignisse berechnen können.
|
||||
- **Beobachtungen:** tatsächlich gemessene Helligkeiten oder Extremzeiten; damit lassen sich Vorhersagen prüfen und aktualisieren.
|
||||
|
||||
## 1. BAV – fertige Jahresvorhersagen
|
||||
|
||||
Die Bundesdeutsche Arbeitsgemeinschaft für Veränderliche Sterne veröffentlicht das BAV Circular. Heft 1 beschreibt Programme und Anwendung; Heft 2 enthält Ephemeriden unter anderem für Bedeckungsveränderliche, kurzperiodische Pulsatoren und Mirasterne. Auf der Übersichtsseite ist die Ausgabe 2026 verlinkt.
|
||||
|
||||
Links:
|
||||
|
||||
- [BAV Circular mit Jahresausgaben](https://www.bav-astro.de/index.php/veroeffentlichungen/bav-circular)
|
||||
- [BAV: Vorhersagen](https://www.bav-astro.eu/index.php/materialien-beobachter/134-vorhersagen)
|
||||
- [BAV Circular 2026, Heft 1: Erläuterungen (PDF)](https://www.bav-astro.eu/images/BAV-Veroeffentlichungen/BAV%20Circular/BAVC_2026_Heft_1.pdf)
|
||||
|
||||
**Einschätzung:** Besonders geeignet für den fachlichen Einstieg und als Vergleich für eigene Berechnungen. Die konkrete Abdeckung von Algol und Mira muss im jeweiligen Heft geprüft werden; nicht für jeden Katalogstern gibt es eine Vorhersage.
|
||||
|
||||
**Zu beachten:** Laut Heft 1 sind die Vorhersagen in Heft 2 in **MEZ** angegeben, auch während der Sommerzeit. Zur Anzeige als MESZ muss dann eine Stunde hinzukommen. Die Übersicht nennt auch eine Korrektur zu einer früheren Ausgabe: immer Jahr und Berichtigungen beachten. PDF-Zugriff ist belegt; eine dokumentierte maschinenlesbare Schnittstelle wurde hier nicht verifiziert.
|
||||
|
||||
## 2. AAVSO VSX – Sternkatalog und Ephemeridenelemente
|
||||
|
||||
Der International Variable Star Index liefert unter anderem Veränderlichentyp, Helligkeitsbereich und Periode sowie Literaturhinweise. Bei geeigneten Einträgen steht eine Epoche als Referenz für die Phase zur Verfügung.
|
||||
|
||||
Links:
|
||||
|
||||
- [VSX-Suche](https://vsx.aavso.org/index.php?ql=1&view=search.top)
|
||||
- [VSX-Handbuch (PDF)](https://vsx.aavso.org/_images/Manual.pdf)
|
||||
- [VSX: Fragen und Erläuterungen](https://vsx.aavso.org/index.php?view=about.faq)
|
||||
|
||||
**Einschätzung:** Geeignet als Grundlage einer kleinen lokalen Sternliste. Suchnamen wären beispielsweise `bet Per` / Algol und `omi Cet` / Mira; Identität und Komponenten müssen am Eintrag geprüft werden.
|
||||
|
||||
**Zu beachten:** Die Bedeutung der Epoche hängt vom Sterntyp ab: bei Bedeckungsveränderlichen ein Minimum, bei den meisten Pulsatoren ein Maximum; es gibt Ausnahmen. Die Spalten für maximale und minimale **Helligkeit** sind keine Ereignistermine. Das Handbuch verwendet heliocentrische julianische Tage (HJD) und Perioden in Tagen. Aktualität und Herkunft der Elemente pro Stern prüfen. Eine aktuelle API mit garantierten Feldern und Abrufgrenzen wurde nicht verifiziert.
|
||||
|
||||
## 3. VarAstro / tschechische Fachsektion – Bedeckungsminima
|
||||
|
||||
VarAstro wird von der Sektion für veränderliche Sterne und Exoplaneten der Tschechischen Astronomischen Gesellschaft betrieben. Das Portal führt die früheren Angebote unter var.astro.cz / var2.astro.cz und das O–C-Gateway fort. Die Fachsektion verweist für Bedeckungsveränderliche ausdrücklich auf Minima-Vorhersagen im Portal.
|
||||
|
||||
Links:
|
||||
|
||||
- [VarAstro, englischer Einstieg](https://var3.astro.cz/en)
|
||||
- [VarAstro, Hauptportal](https://var.astro.cz/cs/Home/)
|
||||
- [Fachsektion: Beobachtungsprogramme und Minima-Vorhersagen](https://sphe.astro.cz/en/observation-programs/)
|
||||
|
||||
**Einschätzung:** Gute ergänzende Quelle für Algol-artige Sterne: Vorhersagen und gemessene Minima ermöglichen einen Vergleich. Ein O–C-Diagramm zeigt die Differenz zwischen beobachtetem und berechnetem Ereigniszeitpunkt und kann veraltete Elemente sichtbar machen.
|
||||
|
||||
**Zu beachten:** Laut Portal stehen die meisten Funktionen erst nach Anmeldung zur Verfügung. Sternabdeckung, Export und automatisierter Abruf wurden nicht geprüft. Alte BRNO-Links sollten nicht ungeprüft als zukünftige Schnittstelle eingeplant werden.
|
||||
|
||||
## 4. AAVSO-Beobachtungen – besonders für Mira-Sterne
|
||||
|
||||
Die AAVSO International Database enthält Helligkeitsmessungen, die sich über die Datensuche herunterladen lassen. Das ist eine Grundlage, um den aktuellen Verlauf einer Lichtkurve zu beurteilen; sie liefert nicht automatisch fertige Zukunftstermine.
|
||||
|
||||
Links:
|
||||
|
||||
- [AAVSO: Daten suchen und herunterladen, mit Nutzungshinweisen](https://aavso.org/search-and-download-data/)
|
||||
- [AAVSO: Sammlung zu gemessenen LPV-Maxima und -Minima](https://www.aavso.org/index.php/category/tags/maxmin)
|
||||
- [Fachartikel: Maxima und O–C-Diagramme für 489 Mirasterne (2013, PDF)](https://www.aavso.org/sites/default/files/jaavso/v41n2/348.pdf)
|
||||
|
||||
**Einschätzung:** Für Mira-Vorhersagen sind jüngere Beobachtungen ein wertvoller Abgleich. Historische Extremzeiten helfen, Schwankungen zwischen den Zyklen einzuschätzen.
|
||||
|
||||
**Zu beachten:** Bei der Maxima-/Minima-Sammlung unterscheidet AAVSO veröffentlichte Daten bis 2008 und vorläufige spätere Daten. Die tatsächliche zeitliche Abdeckung ist je Stern zu prüfen. Einen laufenden **LPV-Vorhersagedienst für 2026** konnte diese Recherche nicht bestätigen. Der ältere [AAVSO-Bulletin-Link](https://www.aavso.org/aavso-bulletin) ließ sich beim Abruf nicht verifizieren; deshalb vorerst keine zentrale Abhängigkeit darauf aufbauen.
|
||||
|
||||
## Wie daraus später Beobachtungsvorschläge werden könnten
|
||||
|
||||
Die folgenden Punkte sind ein eigener Umsetzungsvorschlag, keine bereits vorhandene Funktion.
|
||||
|
||||
### Algol und andere Bedeckungsveränderliche
|
||||
|
||||
Mit einem passenden Referenzminimum `T0` und einer Periode `P` ergibt ein lineares Modell die folgenden gleichartigen Minima als `T(E) = T0 + E × P`, wobei `E` eine ganze Zykluszahl ist. Das reicht nur, solange die Elemente im betrachteten Zeitraum brauchbar sind; jüngere Minima und O–C-Verläufe dienen als Kontrolle. Fachlicher Hintergrund: [SPHE-Beobachtungsprogramme](https://sphe.astro.cz/en/observation-programs/).
|
||||
|
||||
Haupt- und Nebenminimum getrennt führen. Andere Extremphasen nicht pauschal durch eine halbe Periode ergänzen: Dafür muss die Lichtkurve beziehungsweise das Modell des Sterns bekannt sein. Für den Einstieg würde ich bei Algol zunächst nur geprüfte Hauptminima vorschlagen.
|
||||
|
||||
### Mira und andere langperiodische Pulsatoren
|
||||
|
||||
Das VSX-Handbuch weist ausdrücklich auf Zyklusschwankungen bei Miras hin. Eine mittlere Periode ist daher keine Garantie für ein exakt eintretendes Maximum. Quelle: [VSX-Handbuch](https://vsx.aavso.org/_images/Manual.pdf).
|
||||
|
||||
Ich würde ein **ungefähres Zeitfenster** um ein erwartetes Maximum ausgeben, möglichst anhand jüngerer Beobachtungen aktualisiert. Breite und Qualität des Fensters müssen aus den konkreten Daten folgen; keine allgemeine Genauigkeit behaupten. Ein Minimum sollte nur erscheinen, wenn dafür eigene belastbare Angaben vorliegen.
|
||||
|
||||
### Gemeinsame Anforderungen
|
||||
|
||||
- Pro Stern: eindeutige Kennung, Koordinaten, Typ, Helligkeitsbereich mit Filterband und Quellenlink.
|
||||
- Pro Ephemeride: Referenzzeit, Periode, Ereignistyp, Zeitstandard, Veröffentlichungs-/Aktualisierungsstand und gegebenenfalls Unsicherheit.
|
||||
- Pro Ereignis: „beobachtet“ oder „vorhergesagt“, Herkunft und Genauigkeit kenntlich machen.
|
||||
- HJD/BJD und die zugehörige Zeitskala nicht ungeprüft als UTC interpretieren; die Zeitumrechnung vor einer minutengenauen Anzeige fachlich festlegen.
|
||||
- Anschließend für den Benutzerstandort prüfen: Stern über dem Horizont, ausreichende Höhe und dunkler Himmel. Ein Ereignistermin allein bedeutet noch keine Beobachtbarkeit.
|
||||
- Vor einer Datenanbindung die tatsächlichen Exportmöglichkeiten, Nutzungsbedingungen und Aktualisierungsintervalle der ausgewählten Quellen prüfen.
|
||||
|
||||
## Sinnvoller nächster Schritt
|
||||
|
||||
Zunächst exemplarisch **Algol und Mira** anhand der aktuellen Einträge und Jahresvorhersagen prüfen: Welche Ereignisse sind vorhanden, wie frisch sind die Grundlagen und stimmen unabhängige Quellen überein? Erst danach eine kleine Auswahl weiterer Sterne aufnehmen und das Importformat entscheiden. Damit bleibt die spätere Umsetzung fachlich prüfbar und überschaubar.
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
session_start();
|
||||
require_once __DIR__ . '/../auth_helpers.php';
|
||||
require_once __DIR__ . '/../observation_suggestions_helpers.php';
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Cache-Control: no-store');
|
||||
|
||||
function observationReply(array $data, int $status = 200): never
|
||||
{
|
||||
http_response_code($status);
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Allow: POST');
|
||||
observationReply(['ok' => false, 'error' => 'Bitte die Berechnung über das Formular starten.'], 405);
|
||||
}
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
observationReply(['ok' => false, 'error' => 'Bitte erneut anmelden.'], 401);
|
||||
}
|
||||
$token = $_POST['csrf_token'] ?? null;
|
||||
if (!is_string($token) || !isset($_SESSION['observation_csrf']) || !hash_equals($_SESSION['observation_csrf'], $token)) {
|
||||
observationReply(['ok' => false, 'error' => 'Sitzung abgelaufen. Bitte die Seite neu laden.'], 403);
|
||||
}
|
||||
|
||||
try {
|
||||
$cfg = require __DIR__ . '/../../config/database.php';
|
||||
$pdo = new PDO(sprintf('mysql:host=%s;dbname=%s;charset=%s', $cfg['host'], $cfg['dbname'], $cfg['charset'] ?? 'utf8mb4'),
|
||||
$cfg['user'], $cfg['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
|
||||
$userId = (int) $_SESSION['user_id'];
|
||||
if (!currentUserIsAdminLike()) {
|
||||
$permission = $pdo->prepare('SELECT 1 FROM app_user_page_permissions WHERE user_id = ? AND page_key = ? LIMIT 1');
|
||||
$permission->execute([$userId, 'beobachtungsvorschlaege.php']);
|
||||
if (!$permission->fetchColumn()) {
|
||||
observationReply(['ok' => false, 'error' => 'Keine Berechtigung für Beobachtungsvorschläge.'], 403);
|
||||
}
|
||||
}
|
||||
$stmt = $pdo->prepare('SELECT name, latitude, longitude, elevation, timezone FROM app_user_locations
|
||||
WHERE user_id = ? AND is_default = 1 LIMIT 1');
|
||||
$stmt->execute([$userId]);
|
||||
$location = $stmt->fetch();
|
||||
if (!$location) {
|
||||
observationReply(['ok' => false, 'error' => 'Bitte zuerst einen Standardstandort in den Favoriten hinterlegen.'], 422);
|
||||
}
|
||||
$filters = [];
|
||||
foreach (['observation_date', 'object_size_min', 'object_size_max', 'object_magnitude', 'object_altitude_min',
|
||||
'object_altitude_max', 'object_azimuth_start', 'object_azimuth_end', 'sun_altitude_max', 'moon_separation_min',
|
||||
'include_unknown_magnitude'] as $key) {
|
||||
$value = $_POST[$key] ?? '';
|
||||
if (!is_string($value) || strlen($value) > 32) {
|
||||
observationReply(['ok' => false, 'error' => 'Ungültige Filterangabe.'], 422);
|
||||
}
|
||||
if (in_array($key, ['object_size_min', 'object_size_max'], true) && $value !== '') {
|
||||
if (is_numeric($value)) {
|
||||
$value = (string) ((float) $value * 60);
|
||||
}
|
||||
}
|
||||
$filters[$key] = $value;
|
||||
}
|
||||
foreach (['object_types' => ['moon', 'planets', 'open_clusters', 'globular_clusters', 'galaxies', 'nebulae',
|
||||
'planetary_nebulae', 'double_stars', 'variable_stars', 'comets'], 'night_halves' => ['first', 'second']] as $key => $allowed) {
|
||||
$values = $_POST[$key] ?? [];
|
||||
if (!is_array($values) || !$values || count($values) > count($allowed)) {
|
||||
observationReply(['ok' => false, 'error' => 'Bitte mindestens einen Objekttyp und eine Nachthälfte auswählen.'], 422);
|
||||
}
|
||||
foreach ($values as $value) {
|
||||
if (!is_string($value) || !in_array($value, $allowed, true)) {
|
||||
observationReply(['ok' => false, 'error' => 'Ungültige Auswahl.'], 422);
|
||||
}
|
||||
}
|
||||
$filters[$key] = array_values(array_unique($values));
|
||||
}
|
||||
// No session lock while Python is working; other pages remain usable.
|
||||
session_write_close();
|
||||
set_time_limit(120);
|
||||
$payload = ['filters' => $filters, 'location' => $location, 'objects' => observationCatalog($pdo, $filters['object_types'])];
|
||||
$result = runObservationSuggestions($payload);
|
||||
observationReply($result, $result['ok'] ? 200 : 422);
|
||||
} catch (Throwable $e) {
|
||||
error_log('Observation suggestions: ' . $e->getMessage());
|
||||
observationReply(['ok' => false, 'error' => $e instanceof RuntimeException && !($e instanceof PDOException)
|
||||
? $e->getMessage() : 'Die Beobachtungsvorschläge konnten nicht berechnet werden. Bitte später erneut versuchen.'], 500);
|
||||
}
|
||||
@@ -125,6 +125,7 @@ function manageablePublicPages(): array
|
||||
'tagbogen.php' => 'Tagbogen',
|
||||
'daemmerungszeiten.php' => 'Dämmerungszeiten',
|
||||
'sternenhimmel.php' => 'Sternenhimmel',
|
||||
'beobachtungsvorschlaege.php' => 'Beobachtungsvorschläge',
|
||||
'drehbare_sternkarte.php' => 'Drehbare Sternkarte',
|
||||
'meteorshowers.php' => 'Meteorströme',
|
||||
'geocron/index.php' => 'Geocron',
|
||||
@@ -134,6 +135,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',
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
session_start();
|
||||
|
||||
$pageTitle = 'Beobachtungsvorschläge';
|
||||
$headerIntroPre = 'Beobachtung planen';
|
||||
$headerIntroTitle = 'Beobachtungsvorschläge';
|
||||
$headerIntroSub = 'Beobachtungsziele für eine Nacht am eigenen Teleskop eingrenzen.';
|
||||
|
||||
require __DIR__ . '/header.php';
|
||||
|
||||
try {
|
||||
$observationTimezone = new DateTimeZone((string) ($currentLocation['timezone'] ?? 'Europe/Berlin'));
|
||||
} catch (Exception $e) {
|
||||
$observationTimezone = new DateTimeZone('Europe/Berlin');
|
||||
}
|
||||
$observationToday = (new DateTimeImmutable('now', $observationTimezone))->format('Y-m-d');
|
||||
$_SESSION['observation_csrf'] ??= bin2hex(random_bytes(32));
|
||||
?>
|
||||
|
||||
<style>
|
||||
.observation-gui { display: grid; gap: 1.5rem; }
|
||||
.observation-gui .card { margin-bottom: 0; min-width: 0; }
|
||||
.observation-notice { padding: 0.85rem 1rem; border-left: 3px solid var(--gold); background: var(--bg-card2); border-radius: var(--radius); }
|
||||
.observation-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
|
||||
.observation-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
|
||||
.observation-gui .form-group { min-width: 0; margin-bottom: 0; }
|
||||
.observation-gui .form-group input,
|
||||
.observation-gui .form-group select { width: 100%; min-width: 0; box-sizing: border-box; color-scheme: dark; }
|
||||
.observation-gui fieldset { min-width: 0; border: 0; padding: 0; margin: 0 0 1.5rem; }
|
||||
.observation-gui fieldset:last-child { margin-bottom: 0; }
|
||||
.observation-gui legend { font-weight: 600; margin-bottom: 0.65rem; }
|
||||
.observation-help { color: var(--text-dim); font-size: 0.85rem; line-height: 1.6; margin: 0.6rem 0 0; }
|
||||
.observation-wide { grid-column: 1 / -1; }
|
||||
.observation-types { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
|
||||
.observation-choice { display: flex; align-items: center; gap: 0.65rem; cursor: pointer; }
|
||||
.observation-choice input { accent-color: var(--gold); width: 1.1rem; height: 1.1rem; flex-shrink: 0; }
|
||||
.observation-gui input:focus-visible,
|
||||
.observation-gui select:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
|
||||
.observation-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-top: 1.5rem; }
|
||||
.observation-actions button:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.observation-empty { padding: 1.5rem; text-align: center; border: 1px dashed var(--border); border-radius: var(--radius); }
|
||||
.observation-table-wrap { overflow-x: auto; margin-top: 1rem; }
|
||||
.observation-results-table { width: 100%; }
|
||||
.observation-results-table td { vertical-align: top; }
|
||||
.observation-results-table small { display: block; color: var(--text-dim); max-width: 22rem; }
|
||||
.observation-results-table td:nth-child(n+3) { white-space: nowrap; }
|
||||
.observation-object-image { display: block; width: 4rem; height: 4rem; object-fit: cover; border-radius: .3rem; }
|
||||
.observation-image-dialog { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: min(92vw, 900px); max-width: none; max-height: 92vh; margin: 0; padding: 0; border: 1px solid rgba(226,193,93,.55); border-radius: var(--radius); background: linear-gradient(145deg, rgba(34,40,68,.99), rgba(7,10,25,.99) 55%, rgba(24,20,42,.99)); color: var(--text); box-shadow: 0 2px 0 rgba(255,255,255,.12) inset, 0 0 0 1px rgba(0,0,0,.7), 0 18px 0 -10px rgba(200,168,75,.16), 0 34px 0 -18px rgba(200,168,75,.1), 0 35px 95px rgba(0,0,0,.85); animation: observation-dialog-in .22s ease-out; }
|
||||
.observation-image-dialog::backdrop { background: rgba(0,0,8,.86); backdrop-filter: blur(5px); }
|
||||
.observation-image-dialog-content { position: relative; padding: 3.2rem 1rem 1rem; transform-style: preserve-3d; }
|
||||
.observation-image-dialog-title { position: absolute; top: 1rem; left: 1rem; margin: 0; color: var(--gold); font-size: 1rem; }
|
||||
.observation-image-dialog-close { position: absolute; top: .55rem; right: .7rem; border: 0; background: transparent; color: var(--text-dim); font-size: 1.8rem; line-height: 1; cursor: pointer; }
|
||||
.observation-image-dialog-close:hover { color: var(--gold); }
|
||||
.observation-image-dialog-image { display: block; max-width: 100%; max-height: 82vh; margin: 0 auto; object-fit: contain; border: 1px solid rgba(226,193,93,.3); border-radius: .35rem; box-shadow: 0 12px 25px rgba(0,0,0,.58), 0 2px 0 rgba(255,255,255,.1) inset; transform: translateZ(12px); }
|
||||
@keyframes observation-dialog-in { from { opacity: 0; transform: translate(-50%, -50%) scale(.92) rotateX(4deg); } to { opacity: 1; transform: translate(-50%, -50%) scale(1) rotateX(0); } }
|
||||
.observation-sort { border: 0; background: transparent; color: inherit; font: inherit; text-transform: inherit; letter-spacing: inherit; text-align: left; cursor: pointer; padding: 0.35rem 0; }
|
||||
.observation-sort:hover { color: var(--gold); }
|
||||
.observation-sort:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
|
||||
.observation-sort-indicator { margin-left: 0.35rem; }
|
||||
.observation-gui [hidden] { display: none; }
|
||||
@media (max-width: 760px) {
|
||||
.observation-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (max-width: 440px) {
|
||||
.observation-fields, .observation-types { grid-template-columns: 1fr; }
|
||||
.observation-gui .card { padding: 1.1rem; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<form class="observation-gui" id="observation-form" action="ajax/observation_suggestions.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['observation_csrf'], ENT_QUOTES, 'UTF-8') ?>">
|
||||
<p class="observation-notice">Finde Ziele für deine Beobachtungsnacht. Die Sichtbarkeit wird in Schritten von fünf Minuten geprüft; Zeitfenster und beste Zeiten sind Näherungen.</p>
|
||||
|
||||
<section class="card" aria-labelledby="observation-selection-title">
|
||||
<h2 id="observation-selection-title">Beobachtungsnacht und Standort</h2>
|
||||
<div class="observation-fields">
|
||||
<div class="form-group">
|
||||
<label for="observation-date">Datum der Beobachtungsnacht</label>
|
||||
<input type="date" id="observation-date" name="observation_date" value="<?= $observationToday ?>" min="1900-01-01" max="2100-12-31" required aria-describedby="observation-time-help">
|
||||
</div>
|
||||
<fieldset aria-describedby="observation-time-help">
|
||||
<legend>Nachthälften</legend>
|
||||
<div class="observation-types">
|
||||
<label class="observation-choice"><input type="checkbox" name="night_halves[]" value="first" checked> Erste Nachthälfte</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="night_halves[]" value="second" checked> Zweite Nachthälfte</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<label for="observation-location">Beobachtungsstandort</label>
|
||||
<input type="text" id="observation-location" value="<?= htmlspecialchars((string) ($currentLocation['name'] ?? 'Kein Standardstandort hinterlegt'), ENT_QUOTES, 'UTF-8') ?>" readonly aria-describedby="observation-location-help">
|
||||
<p class="observation-help" id="observation-location-help">Es gilt immer dein Standardstandort aus dem Header.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="observation-help" id="observation-time-help">Das Datum bezeichnet die Nacht vom gewählten Abend bis zum folgenden Morgen. Die eingestellte Sonnenhöhe begrenzt den Beobachtungszeitraum; die Nachthälften teilen diesen in zwei gleich lange Abschnitte. Beide auswählen für die ganze Nacht.</p>
|
||||
</section>
|
||||
|
||||
<div class="observation-grid">
|
||||
<section class="card" aria-labelledby="observation-object-title">
|
||||
<h2 id="observation-object-title">Eigenschaften der Objekte</h2>
|
||||
<fieldset>
|
||||
<legend>Scheinbare Größe – nur Deep Sky (Bogenminuten)</legend>
|
||||
<div class="observation-fields">
|
||||
<div class="form-group">
|
||||
<label for="object-size-min">Minimum (′)</label>
|
||||
<input type="number" id="object-size-min" name="object_size_min" min="0" max="60" step="any" placeholder="Keine Untergrenze" aria-describedby="object-size-help">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="object-size-max">Maximum (′)</label>
|
||||
<input type="number" id="object-size-max" name="object_size_max" min="0" max="60" step="any" value="60" placeholder="Keine Obergrenze" aria-describedby="object-size-help">
|
||||
</div>
|
||||
</div>
|
||||
<p class="observation-help" id="object-size-help">Dieser Filter gilt nur für Galaxien, Sternhaufen und Nebel einschließlich planetarischer Nebel. Verglichen wird die größte Katalogausdehnung. Bei gesetzter Größengrenze werden Deep-Sky-Objekte ohne Größenangabe ausgelassen. Maximal 60′.</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Helligkeit</legend>
|
||||
<div class="form-group">
|
||||
<label for="object-magnitude">Grenzgröße / schwächste Helligkeit (mag)</label>
|
||||
<input type="number" id="object-magnitude" name="object_magnitude" step="0.1" value="12" placeholder="z. B. 12,0" aria-describedby="object-magnitude-help">
|
||||
</div>
|
||||
<p class="observation-help" id="object-magnitude-help">12 mag bedeutet: 12 mag oder heller. Kleinere und negative mag-Werte sind heller. Leer lassen für keine Grenze. Bei Galaxien und Nebeln sagt die Gesamthelligkeit allein wenig über die Erkennbarkeit aus.</p>
|
||||
<label class="observation-choice" style="margin-top: 0.85rem;"><input type="checkbox" name="include_unknown_magnitude" value="1" aria-describedby="unknown-magnitude-help"> Auch Objekte ohne Helligkeitsangabe</label>
|
||||
<p class="observation-help" id="unknown-magnitude-help">Bei gesetzter Grenzgröße werden diese sonst ausgelassen. Wenn ausgewählt, erscheinen sie am Ende als „Helligkeit unbekannt“; die Grenzgröße lässt sich für sie nicht prüfen.</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Objekttypen</legend>
|
||||
<div class="observation-types">
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="moon" checked> Mond</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="planets" checked> Planeten</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="open_clusters" checked> Offene Sternhaufen</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="globular_clusters" checked> Kugelsternhaufen</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="galaxies" checked> Galaxien & Galaxiengruppen</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="nebulae" checked aria-describedby="nebulae-help"> Nebel</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="planetary_nebulae" checked> Planetarische Nebel</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="double_stars" checked> Doppelsterne</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="variable_stars" checked> Veränderliche Sterne</label>
|
||||
<label class="observation-choice"><input type="checkbox" name="object_types[]" value="comets" checked> Kometen</label>
|
||||
</div>
|
||||
<p class="observation-help" id="nebulae-help">„Nebel“ umfasst Emissions- und Reflexionsnebel, H-II-Regionen, Supernovaüberreste und Sternhaufen mit Nebel. Planetarische Nebel sind separat auswählbar.</p>
|
||||
</fieldset>
|
||||
</section>
|
||||
|
||||
<section class="card" aria-labelledby="observation-sky-title">
|
||||
<h2 id="observation-sky-title">Himmelsbereich und Dunkelheit</h2>
|
||||
<fieldset>
|
||||
<legend>Höhe über dem Horizont</legend>
|
||||
<div class="observation-fields">
|
||||
<div class="form-group">
|
||||
<label for="object-altitude-min">Minimum (°)</label>
|
||||
<input type="number" id="object-altitude-min" name="object_altitude_min" min="0" max="90" step="1" value="20" aria-describedby="object-altitude-help">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="object-altitude-max">Maximum (°)</label>
|
||||
<input type="number" id="object-altitude-max" name="object_altitude_max" min="0" max="90" step="1" value="90" aria-describedby="object-altitude-help">
|
||||
</div>
|
||||
</div>
|
||||
<p class="observation-help" id="object-altitude-help">0° = Horizont · 90° = Zenit. Eine Obergrenze kann bei eingeschränktem Einblick oder einer azimutalen Montierung hilfreich sein.</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Azimut / Himmelsrichtung</legend>
|
||||
<div class="observation-fields">
|
||||
<div class="form-group">
|
||||
<label for="object-azimuth-start">Von (°)</label>
|
||||
<input type="number" id="object-azimuth-start" name="object_azimuth_start" min="0" max="360" step="1" value="0" aria-describedby="object-azimuth-help">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="object-azimuth-end">Bis (°)</label>
|
||||
<input type="number" id="object-azimuth-end" name="object_azimuth_end" min="0" max="360" step="1" value="360" aria-describedby="object-azimuth-help">
|
||||
</div>
|
||||
</div>
|
||||
<p class="observation-help" id="object-azimuth-help">Nord 0°/360° · Ost 90° · Süd 180° · West 270°.<br>Der Bereich verläuft über Ost, Süd und West. 0° bis 360° umfasst alle Richtungen; 300° bis 60° führt über Norden.</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Dunkelheit</legend>
|
||||
<div class="form-group">
|
||||
<label for="sun-altitude-max">Sonne höchstens auf Höhe (°)</label>
|
||||
<input type="number" id="sun-altitude-max" name="sun_altitude_max" min="-90" max="0" step="1" value="-12" aria-describedby="sun-altitude-help">
|
||||
</div>
|
||||
<p class="observation-help" id="sun-altitude-help">Negative Werte liegen unter dem Horizont. −6°: Ende der bürgerlichen, −12°: Ende der nautischen, −18°: Ende der astronomischen Abenddämmerung.</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Mondlicht berücksichtigen (optional)</legend>
|
||||
<div class="form-group">
|
||||
<label for="moon-separation-min">Mindestabstand zum Mond (°)</label>
|
||||
<input type="number" id="moon-separation-min" name="moon_separation_min" min="0" max="180" step="1" placeholder="Keine Einschränkung" aria-describedby="moon-separation-help">
|
||||
</div>
|
||||
<p class="observation-help" id="moon-separation-help">Für andere Ziele bei Mond über dem Horizont gedacht; gilt nicht für den Mond als Beobachtungsziel.</p>
|
||||
</fieldset>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="card" aria-labelledby="observation-suggestions-title">
|
||||
<h2 id="observation-suggestions-title">Beobachtungsvorschläge</h2>
|
||||
<div class="observation-actions">
|
||||
<button type="submit" class="btn btn-primary" id="observation-submit">Vorschläge berechnen</button>
|
||||
<span class="observation-help" id="observation-status" role="status" aria-live="polite">Noch keine Vorschläge berechnet.</span>
|
||||
</div>
|
||||
<p id="observation-error" role="alert" hidden></p>
|
||||
<div id="observation-results" hidden>
|
||||
<p class="observation-help" id="observation-summary"></p>
|
||||
<ul class="observation-help" id="observation-warnings"></ul>
|
||||
<div class="observation-actions">
|
||||
<label class="observation-choice"><input type="checkbox" id="observation-limit-enabled" checked aria-describedby="observation-group-limit-help"> Auf die hellsten je Gruppe begrenzen</label>
|
||||
<div class="form-group">
|
||||
<label for="observation-group-limit">Maximal pro Objektgruppe</label>
|
||||
<input type="number" id="observation-group-limit" form="observation-display-options" min="1" step="1" value="30" required aria-describedby="observation-group-limit-help">
|
||||
</div>
|
||||
</div>
|
||||
<p class="observation-help" id="observation-group-limit-help">Je Objekttyp aus der Auswahl bleiben die X hellsten Treffer nach der angezeigten mag-Helligkeit. Bei gleicher Helligkeit zählt die größere Höhe. Objekte ohne Helligkeitsangabe werden bei dieser Begrenzung ausgelassen.</p>
|
||||
<p class="observation-help" id="observation-limit-status" role="status" aria-live="polite"></p>
|
||||
<label class="observation-choice"><input type="checkbox" id="observation-multi-sort"> Weitere Sortierkriterien hinzufügen (auch ohne Umschalttaste)</label>
|
||||
<p class="observation-help" id="observation-sort-summary" role="status" aria-live="polite"></p>
|
||||
<div class="observation-table-wrap">
|
||||
<table class="data-table observation-results-table">
|
||||
<caption>Klick auf eine Überschrift setzt das Hauptkriterium. Umschalt + Klick ergänzt weitere Kriterien; erneuter Klick kehrt die Richtung um. Das nächste Kriterium entscheidet bei gleichen Werten. Fehlende Werte folgen innerhalb der jeweiligen Sortiergruppe am Ende.</caption>
|
||||
<thead><tr>
|
||||
<th scope="col">Bild</th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="name">Objekt<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="type">Typ<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="magnitude">Helligkeit<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="size">Größe<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="window" title="Nach Beginn des ersten passenden Zeitfensters sortieren">Passendes Zeitfenster (ca.)<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="time" title="Zeitpunkt der größten geprüften Höhe innerhalb deiner Filter">Zeit der größten Höhe (ca.)<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
<th scope="col" aria-sort="descending"><button type="button" class="observation-sort" data-sort="altitude">Höhe<span class="observation-sort-indicator" aria-hidden="true">↓</span></button></th>
|
||||
<th scope="col"><button type="button" class="observation-sort" data-sort="azimuth">Azimut<span class="observation-sort-indicator" aria-hidden="true">↕</span></button></th>
|
||||
</tr></thead>
|
||||
<tbody id="observation-rows"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="observation-actions">
|
||||
<button type="button" class="btn btn-secondary" id="observation-previous">Zurück</button>
|
||||
<span id="observation-pagination"></span>
|
||||
<button type="button" class="btn btn-secondary" id="observation-next">Weiter</button>
|
||||
</div>
|
||||
</div>
|
||||
<noscript><p>Bitte JavaScript aktivieren, um die Vorschläge auf dieser Seite anzuzeigen.</p></noscript>
|
||||
</section>
|
||||
</form>
|
||||
<form id="observation-display-options"></form>
|
||||
<dialog class="observation-image-dialog" id="observation-image-dialog" aria-labelledby="observation-image-dialog-title">
|
||||
<div class="observation-image-dialog-content">
|
||||
<button type="button" class="observation-image-dialog-close" id="observation-image-dialog-close" aria-label="Bildfenster schließen">×</button>
|
||||
<h2 class="observation-image-dialog-title" id="observation-image-dialog-title"></h2>
|
||||
<img class="observation-image-dialog-image" id="observation-image-dialog-image" alt="">
|
||||
</div>
|
||||
</dialog>
|
||||
<script src="js/observation_suggestions.js" defer></script>
|
||||
|
||||
<?php require __DIR__ . '/footer.php'; ?>
|
||||
@@ -203,6 +203,69 @@ $pdo = new PDO(
|
||||
);
|
||||
|
||||
$userId = isset($_SESSION['user_id']) ? (int) $_SESSION['user_id'] : 0;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $userId > 0) {
|
||||
$action = $_POST['action'] ?? '';
|
||||
$cometId = (int) ($_POST['comet_id'] ?? 0);
|
||||
|
||||
if ($action === 'add_comet' && $cometId > 0) {
|
||||
$stmtCheck = $pdo->prepare("
|
||||
SELECT `id`
|
||||
FROM `comets_mpc`
|
||||
WHERE `id` = :id
|
||||
LIMIT 1
|
||||
");
|
||||
$stmtCheck->execute([':id' => $cometId]);
|
||||
|
||||
if ($stmtCheck->fetch()) {
|
||||
$stmtInsert = $pdo->prepare("
|
||||
INSERT INTO `app_user_comets` (
|
||||
`user_id`,
|
||||
`comet_id`,
|
||||
`is_favorite`,
|
||||
`created_at`
|
||||
) VALUES (
|
||||
:user_id,
|
||||
:comet_id,
|
||||
0,
|
||||
NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`comet_id` = VALUES(`comet_id`)
|
||||
");
|
||||
$stmtInsert->execute([
|
||||
':user_id' => $userId,
|
||||
':comet_id' => $cometId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === 'remove_comet' && $cometId > 0) {
|
||||
$stmtCount = $pdo->prepare("
|
||||
SELECT COUNT(*)
|
||||
FROM `app_user_comets`
|
||||
WHERE `user_id` = :user_id
|
||||
");
|
||||
$stmtCount->execute([':user_id' => $userId]);
|
||||
$cometCount = (int) $stmtCount->fetchColumn();
|
||||
|
||||
if ($cometCount > 1) {
|
||||
$stmtDelete = $pdo->prepare("
|
||||
DELETE FROM `app_user_comets`
|
||||
WHERE `user_id` = :user_id
|
||||
AND `comet_id` = :comet_id
|
||||
");
|
||||
$stmtDelete->execute([
|
||||
':user_id' => $userId,
|
||||
':comet_id' => $cometId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: comets.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$today = new DateTimeImmutable('today', new DateTimeZone('UTC'));
|
||||
$windowStart = $today->modify('-180 days');
|
||||
$windowEnd = $today->modify('+365 days');
|
||||
@@ -632,6 +695,9 @@ arsort($orbitTypeCounts);
|
||||
<th data-sortable>Perihel</th>
|
||||
<th data-sortable>Abstand</th>
|
||||
<th data-sortable title="Grobe Helligkeitsschaetzung fuer heute nach H + 5 log(Delta) + 2,5 * n * log(r).">m grob</th>
|
||||
<?php if ($loggedIn): ?>
|
||||
<th></th>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -664,6 +730,19 @@ arsort($orbitTypeCounts);
|
||||
<td data-sort-value="<?= h((string) $perihelionTs) ?>"><?= h((string) $comet['perihelion_date_display']) ?></td>
|
||||
<td data-sort-value="<?= h((string) ($comet['days_from_today'] ?? '')) ?>"><span class="comets-days <?= $daysClass ?>"><?= h($daysLabel) ?></span></td>
|
||||
<td data-sort-value="<?= h((string) ($comet['estimated_magnitude'] ?? '')) ?>" title="r = <?= h((string) $comet['heliocentric_distance_display']) ?> AE, Δ = <?= h((string) $comet['geocentric_distance_display']) ?> AE"><?= h((string) $comet['estimated_magnitude_display']) ?></td>
|
||||
<?php if ($loggedIn): ?>
|
||||
<td class="action-cell">
|
||||
<?php if (count($trackedComets) > 1): ?>
|
||||
<form method="post" action="comets.php" onsubmit="return confirm('Komet wirklich aus deiner Liste entfernen?');">
|
||||
<input type="hidden" name="action" value="remove_comet">
|
||||
<input type="hidden" name="comet_id" value="<?= (int) $comet['id'] ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger">Entfernen</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<span class="hint">Letzter Komet</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
@@ -689,6 +768,9 @@ arsort($orbitTypeCounts);
|
||||
<th data-sortable>Perihel</th>
|
||||
<th data-sortable>Abstand</th>
|
||||
<th data-sortable title="Grobe Helligkeitsschaetzung fuer heute nach H + 5 log(Delta) + 2,5 * n * log(r).">m grob</th>
|
||||
<?php if ($loggedIn): ?>
|
||||
<th></th>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -722,6 +804,17 @@ arsort($orbitTypeCounts);
|
||||
<td data-sort-value="<?= h((string) $perihelionTs) ?>"><?= h((string) $comet['perihelion_date_display']) ?></td>
|
||||
<td data-sort-value="<?= h((string) ($comet['days_from_today'] ?? '')) ?>"><span class="comets-days <?= $daysClass ?>"><?= h($daysLabel) ?></span></td>
|
||||
<td data-sort-value="<?= h((string) ($comet['estimated_magnitude'] ?? '')) ?>" title="r = <?= h((string) $comet['heliocentric_distance_display']) ?> AE, Δ = <?= h((string) $comet['geocentric_distance_display']) ?> AE"><?= h((string) $comet['estimated_magnitude_display']) ?></td>
|
||||
<?php if ($loggedIn): ?>
|
||||
<td class="action-cell">
|
||||
<?php if ((int) $comet['is_tracked'] !== 1): ?>
|
||||
<form method="post" action="comets.php">
|
||||
<input type="hidden" name="action" value="add_comet">
|
||||
<input type="hidden" name="comet_id" value="<?= (int) $comet['id'] ?>">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Hinzufügen</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
||||
@@ -2569,6 +2569,26 @@ body.moonphase-page.has-modal {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Licht-Testregler (moonphase.php): als Flex-Kind von .moon-side erbt dieser
|
||||
Block sonst "overflow: hidden" von .moon-side > * und wuerde bei geoeffnetem
|
||||
<details> zusammengedrueckt, sodass untere Regler verdeckt sind. Eigener,
|
||||
in sich scrollbarer Bereich behebt das, unabhaengig vom verfuegbaren Platz. */
|
||||
#moonLightDebugPanel summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#moonLightDebugPanel[open] {
|
||||
overflow-y: auto;
|
||||
max-height: 320px;
|
||||
}
|
||||
|
||||
/* .moon-controls setzt display:flex und wuerde damit das hidden-Attribut
|
||||
(Browser-Standard: display:none) ausser Kraft setzen - Autoren-CSS gewinnt
|
||||
sonst immer gegen UA-Stile. Explizit erzwingen, solange [hidden] gesetzt ist. */
|
||||
#moonLightDebugPanel[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.control-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -4656,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'],
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -165,6 +166,7 @@ $menuGroups = [
|
||||
'title' => 'Sternenhimmel & Karten',
|
||||
'links' => [
|
||||
['href' => 'sternenhimmel.php', 'label' => 'Sternenhimmel'],
|
||||
['href' => 'beobachtungsvorschlaege.php', 'label' => 'Beobachtungsvorschläge'],
|
||||
['href' => 'drehbare_sternkarte.php', 'label' => 'Drehbare Sternkarte'],
|
||||
['href' => 'satellitenhimmel.php', 'label' => 'Satellitenhimmel'],
|
||||
['href' => 'tagbogen.php', 'label' => 'Tagbogen'],
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
#
|
||||
# Columns: DSO, Year of discovery, Discoverer
|
||||
# Separator: [tab]
|
||||
#
|
||||
# Source:
|
||||
# - SEDS Messier Database: http://www.messier.seds.org
|
||||
#
|
||||
M 1 1731-06-10 John Bevis
|
||||
M 2 1746-09-11 Jean-Dominique Maraldi
|
||||
M 3 1764-05-03 Charles Messier
|
||||
M 4 1746 Philippe Loys de Chéseaux
|
||||
M 5 1702-05-05 Gottfried Kirch
|
||||
M 6 1654 Giovanni Batista Hodierna
|
||||
M 7 130 Ptolemy
|
||||
M 8 1654 Giovanni Batista Hodierna
|
||||
M 9 1764-05-28 Charles Messier
|
||||
M 10 1764-05-29 Charles Messier
|
||||
M 11 1681 Gottfried Kirch
|
||||
M 12 1764-05-30 Charles Messier
|
||||
M 13 1714 Edmond Halley
|
||||
M 14 1764-06-01 Charles Messier
|
||||
M 15 1746-09-07 Jean-Dominique Maraldi
|
||||
M 16 1745 Philippe Loys de Chéseaux
|
||||
M 17 1745 Philippe Loys de Chéseaux
|
||||
M 18 1764-06-03 Charles Messier
|
||||
M 19 1764-06-05 Charles Messier
|
||||
M 20 1764-06-05 Charles Messier
|
||||
M 21 1764-06-05 Charles Messier
|
||||
M 22 1665-08-26 Abraham Ihle
|
||||
M 23 1764-06-20 Charles Messier
|
||||
M 24 1764-06-20 Charles Messier
|
||||
M 25 1745 Philippe Loys de Chéseaux
|
||||
M 26 1764-06-20 Charles Messier
|
||||
M 27 1764-07-12 Charles Messier
|
||||
M 28 1764-07-27 Charles Messier
|
||||
M 29 1764-07-29 Charles Messier
|
||||
M 30 1764-08-03 Charles Messier
|
||||
M 31 905 Abd-al-Rahman Al Sufi
|
||||
M 32 1749-10-29 Guillaume Legentil
|
||||
M 33 1654 Giovanni Batista Hodierna
|
||||
M 34 1654 Giovanni Batista Hodierna
|
||||
M 35 1745 Philippe Loys de Chéseaux
|
||||
M 36 1654 Giovanni Batista Hodierna
|
||||
M 37 1654 Giovanni Batista Hodierna
|
||||
M 38 1654 Giovanni Batista Hodierna
|
||||
M 39 1764-10-24 Charles Messier
|
||||
M 40 1764 Charles Messier
|
||||
M 41 -325 Aristoteles
|
||||
M 42 1611 Johann Baptist Cysatus
|
||||
M 43 1731 Jean-Jacques Dortous de Mairan
|
||||
M 44 -260 Aratos of Soli
|
||||
M 45 -750 Homer
|
||||
M 46 1771-02-19 Charles Messier
|
||||
M 47 1654 Giovanni Batista Hodierna
|
||||
M 48 1771-02-19 Charles Messier
|
||||
M 49 1771-02-19 Charles Messier
|
||||
M 50 1711 Giovanni Cassini
|
||||
M 51 1773-10-13 Charles Messier
|
||||
M 52 1774-09-07 Charles Messier
|
||||
M 53 1775-02-03 Johann Elert Bode
|
||||
M 54 1778-07-24 Charles Messier
|
||||
M 55 1752-06-16 Nicholas Louis de Lacaille
|
||||
M 56 1779-01-23 Charles Messier
|
||||
M 57 1779-01-31 Charles Messier
|
||||
M 58 1779-04-15 Charles Messier
|
||||
M 59 1779-04-11 Johann Gottfried Koehler
|
||||
M 60 1779-04-11 Johann Gottfried Koehler
|
||||
M 61 1779 Barnabus Oriani
|
||||
M 62 1771-06-07 Charles Messier
|
||||
M 63 1779-06-14 Pierre Méchain
|
||||
M 64 1779-03-23 Edward Pigott
|
||||
M 65 1780-03-01 Charles Messier
|
||||
M 66 1780-03-01 Charles Messier
|
||||
M 67 1779 Johann Gottfried Koehler
|
||||
M 68 1780-04-09 Charles Messier
|
||||
M 69 1780-08-31 Charles Messier
|
||||
M 70 1780-08-31 Charles Messier
|
||||
M 71 1745 Philippe Loys de Chéseaux
|
||||
M 72 1780-08-29 Pierre Méchain
|
||||
M 73 1780-10-04 Charles Messier
|
||||
M 74 1780-09 Pierre Méchain
|
||||
M 75 1780-08-27 Pierre Méchain
|
||||
M 76 1780-09-05 Pierre Méchain
|
||||
M 77 1780-10-29 Pierre Méchain
|
||||
M 78 1780 Pierre Méchain
|
||||
M 79 1780-10-26 Pierre Méchain
|
||||
M 80 1781-01-04 Charles Messier
|
||||
M 81 1774-12-31 Johann Elert Bode
|
||||
M 82 1774-12-31 Johann Elert Bode
|
||||
M 83 1752-02-23 Nicholas Louis de Lacaille
|
||||
M 84 1781-03-18 Charles Messier
|
||||
M 85 1781-03-04 Pierre Méchain
|
||||
M 86 1781-03-18 Charles Messier
|
||||
M 87 1781-03-18 Charles Messier
|
||||
M 88 1781-03-18 Charles Messier
|
||||
M 89 1781-03-18 Charles Messier
|
||||
M 90 1781-03-18 Charles Messier
|
||||
M 91 1781-03-18 Charles Messier
|
||||
M 92 1777-12-27 Johann Elert Bode
|
||||
M 93 1781-03-20 Charles Messier
|
||||
M 94 1781-03-22 Pierre Méchain
|
||||
M 95 1781-03-20 Pierre Méchain
|
||||
M 96 1781-03-20 Pierre Méchain
|
||||
M 97 1781-02-16 Pierre Méchain
|
||||
M 98 1781-03-15 Pierre Méchain
|
||||
M 99 1781-03-15 Pierre Méchain
|
||||
M 100 1781-03-15 Pierre Méchain
|
||||
M 101 1781-03-27 Pierre Méchain
|
||||
M 102 1781-03 Pierre Méchain
|
||||
M 103 1781 Pierre Méchain
|
||||
M 104 1781-05-06 Pierre Méchain
|
||||
M 105 1781-03-24 Pierre Méchain
|
||||
M 106 1781 Pierre Méchain
|
||||
M 107 1782-04 Pierre Méchain
|
||||
M 108 1781-02-19 Pierre Méchain
|
||||
M 109 1781-04 Charles Messier
|
||||
M 110 1773-08-10 Charles Messier
|
||||
C 1 1831-11-03 John Herschel
|
||||
C 2 1788-11-25 William Herschel
|
||||
C 3 1793-04-06 William Herschel
|
||||
C 4 1794-10-18 William Herschel
|
||||
C 5 1895 W.F. Denning
|
||||
C 6 1786-02-15 William Herschel
|
||||
C 7 1788 William Herschel
|
||||
C 8 1787 William Herschel
|
||||
C 10 1783-09-27 Carolina Herschel
|
||||
C 11 1787 William Herschel
|
||||
C 12 1798-09-09 William Herschel
|
||||
C 13 1780-08-18 William Herschel
|
||||
C 14 -130 Hipparcos
|
||||
C 15 1793-09-06 William Herschel
|
||||
C 16 1788-09-26 William Herschel
|
||||
C 17 1829-09-08 John Herschel
|
||||
C 18 1787-11-30 William Herschel
|
||||
C 19 1894-07-28 Maximilian Wolf
|
||||
C 20 1786-10-24 William Herschel
|
||||
C 21 1788-04-27 William Herschel
|
||||
C 22 1784-10-06 William Herschel
|
||||
C 23 1784-10-06 William Herschel
|
||||
C 24 1786-10-17 William Herschel
|
||||
C 25 1788-12-31 William Herschel
|
||||
C 26 1787-03-17 William Herschel
|
||||
C 27 1792-09-15 William Herschel
|
||||
C 28 1654 Giovanni Batista Hodierna
|
||||
C 29 1785-05-01 William Herschel
|
||||
C 30 1784 William Herschel
|
||||
C 31 1892-03-21 Johann Schaeberle
|
||||
C 32 1787 William Herschel
|
||||
C 38 1785 William Herschel
|
||||
C 44 1784 William Herschel
|
||||
C 49 1690 John Flamsteed
|
||||
C 50 1690 John Flamsteed
|
||||
C 51 1906 Max Wolf
|
||||
C 53 1787-02-22 William Herschel
|
||||
C 55 1782-09-07 William Herschel
|
||||
C 57 1884-08-17 E.E. Barnard
|
||||
C 58 1783-02-26 Caroline Herschel
|
||||
C 63 1824 Karl Ludwig Harding
|
||||
C 64 1654 Giovanni Batista Hodierna
|
||||
C 65 1783 Caroline Herschel
|
||||
C 71 1752-03-19 Nicholas Louis de Lacaille
|
||||
C 72 1826-08-04 James Dunlop
|
||||
C 73 1826-05-29 James Dunlop
|
||||
C 75 1751 Nicholas Louis de Lacaille
|
||||
C 76 1654 Giovanni Batista Hodierna
|
||||
C 77 1826-08-04 James Dunlop
|
||||
C 78 1826-03-19 N. Cacciatore
|
||||
C 79 1826-05-28 James Dunlop
|
||||
C 80 1677 Edmond Halley
|
||||
C 81 1826-05-14 James Dunlop
|
||||
C 84 1826-04-29 James Dunlop
|
||||
C 85 -964 Al Sufi
|
||||
C 86 1751 Nicholas Louis de Lacaille
|
||||
C 87 1826-11-24 James Dunlop
|
||||
C 91 1752-01-25 Nicholas Louis de Lacaille
|
||||
C 92 1752-01-25 Nicholas Louis de Lacaille
|
||||
C 93 1826-07-28 James Dunlop
|
||||
C 94 1752-03-25 Nicholas Louis de Lacaille
|
||||
C 95 1752-03-05 Nicholas Louis de Lacaille
|
||||
C 96 1752-01-04 Nicholas Louis de Lacaille
|
||||
C 97 1752-03-05 Nicholas Louis de Lacaille
|
||||
C 99 1499 Vincente Yanez Pinzon
|
||||
C 102 1752-03-03 Nicholas Louis de Lacaille
|
||||
C 103 1751-12-05 Nicholas Louis de Lacaille
|
||||
C 104 1826-08-01 James Dunlop
|
||||
C 105 1752-03-17 Nicholas Louis de Lacaille
|
||||
C 106 1751-09-14 Nicholas Louis de Lacaille
|
||||
C 107 1826-06-01 James Dunlop
|
||||
C 108 1826-04-30 James Dunlop
|
||||
C 109 1835 John Herschel
|
||||
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 549 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 374 KiB |
|
After Width: | Height: | Size: 993 KiB |
|
After Width: | Height: | Size: 598 KiB |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 901 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 565 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 878 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 979 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 705 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 587 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 266 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 445 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 171 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 278 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 309 KiB After Width: | Height: | Size: 309 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 440 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 210 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 295 KiB After Width: | Height: | Size: 295 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 249 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |