&1'; $output = []; $resultCode = 0; exec($command, $output, $resultCode); $joined = trim(implode("\n", $output)); $debugOutput = $output; if ($resultCode !== 0) { $lastError = $joined !== '' ? $joined : ('Fehlercode ' . $resultCode . ' bei ' . $pythonBinary); continue; } $decoded = json_decode($joined, true); if (!is_array($decoded)) { $lastError = $joined !== '' ? 'Python-Ausgabe war kein gültiges JSON.' : 'Python lieferte keine Ausgabe zurück.'; continue; } if (!($decoded['ok'] ?? false)) { return [ 'ok' => false, 'error' => (string)($decoded['error'] ?? 'Unbekannter Python-Fehler'), 'debug' => $joined, ]; } return ['ok' => true, 'data' => $decoded]; } return [ 'ok' => false, 'error' => $lastError, 'debug' => implode("\n", $debugOutput), ]; } $defaultLocation = null; $pdo = null; $pageError = null; $pageLocation = null; $detailMapStars = []; $constellationLines = []; $detailMapCatalogLimit = 8.0; $isAjax = isset($_POST['ajax']) && (string)$_POST['ajax'] === '1'; try { $config = require __DIR__ . '/../config/database.php'; $dsn = sprintf( 'mysql:host=%s;dbname=%s;charset=%s', $config['host'], $config['dbname'], $config['charset'] ?? 'utf8mb4' ); $pdo = new PDO( $dsn, $config['user'], $config['pass'], [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); if ($loggedIn && isset($_SESSION['user_id'])) { $stmtLocation = $pdo->prepare( 'SELECT id, name, latitude, longitude, elevation, timezone FROM app_user_locations WHERE user_id = ? AND is_default = 1 LIMIT 1' ); $stmtLocation->execute([(int)$_SESSION['user_id']]); $defaultLocation = $stmtLocation->fetch() ?: null; } } catch (Throwable $exception) { $pageError = $exception->getMessage(); } if (!empty($defaultLocation) && is_array($defaultLocation)) { $pageLocation = [ 'name' => (string)($defaultLocation['name'] ?? ''), 'latitude' => isset($defaultLocation['latitude']) ? (float)$defaultLocation['latitude'] : null, 'longitude' => isset($defaultLocation['longitude']) ? (float)$defaultLocation['longitude'] : null, 'elevation' => isset($defaultLocation['elevation']) && $defaultLocation['elevation'] !== null ? (float)$defaultLocation['elevation'] : 0.0, 'timezone' => (string)($defaultLocation['timezone'] ?? 'Europe/Berlin'), ]; } $timezoneName = $pageLocation['timezone'] ?? 'Europe/Berlin'; try { $timezone = new DateTimeZone($timezoneName); } catch (Throwable $exception) { $timezoneName = 'Europe/Berlin'; $timezone = new DateTimeZone($timezoneName); } $todayYear = (int)(new DateTimeImmutable('now', $timezone))->format('Y'); $selectedYear = isset($_POST['year']) && preg_match('/^\d{4}$/', (string)$_POST['year']) ? (int)$_POST['year'] : $todayYear; $selectedYear = max(1900, min(2100, $selectedYear)); if (!$isAjax && $pageError === null && $pdo instanceof PDO && $pageLocation !== null && $pageLocation['latitude'] !== null && $pageLocation['longitude'] !== null) { try { $stmtDetailMap = $pdo->query( "SELECT `hip`, `proper`, `bf`, `con`, `mag`, `ra`, `dec`, `dist` FROM `star_hipparcos` WHERE `mag` IS NOT NULL AND `ra` IS NOT NULL AND `dec` IS NOT NULL AND `mag` <= 8.0 ORDER BY `mag` ASC, `proper` ASC, `bf` ASC, `hip` ASC" ); foreach ($stmtDetailMap->fetchAll() as $row) { $proper = trim((string)($row['proper'] ?? '')); $bf = trim((string)($row['bf'] ?? '')); $hip = isset($row['hip']) ? (int)$row['hip'] : 0; $label = $proper !== '' ? $proper : ($bf !== '' ? $bf : ($hip > 0 ? 'HIP ' . $hip : 'Unbenannter Stern')); $detailMapStars[] = [ 'hip' => $hip, 'label' => $label, 'constellation' => trim((string)($row['con'] ?? '')), 'mag' => isset($row['mag']) ? (float)$row['mag'] : null, 'ra' => isset($row['ra']) ? (float)$row['ra'] : null, 'dec' => isset($row['dec']) ? (float)$row['dec'] : null, 'distLy' => isset($row['dist']) && $row['dist'] !== null && (float)$row['dist'] > 0.0 ? (float)$row['dist'] * 3.26156 : 1000.0, ]; } $stmtLines = $pdo->query( "SELECT cl.`id` AS line_id, clp.`point_index`, sh.`ra` AS ra_hours, sh.`dec` AS dec_deg FROM `constellation_lines` cl INNER JOIN `constellation_line_points` clp ON clp.`line_id` = cl.`id` INNER JOIN `star_hipparcos` sh ON sh.`hip` = clp.`hip_number` WHERE sh.`ra` IS NOT NULL AND sh.`dec` IS NOT NULL ORDER BY cl.`id`, clp.`point_index`" ); foreach ($stmtLines->fetchAll() as $row) { $lineId = (int)$row['line_id']; $constellationLines[$lineId][] = [ 'ra' => isset($row['ra_hours']) ? (float)$row['ra_hours'] : null, 'dec' => isset($row['dec_deg']) ? (float)$row['dec_deg'] : null, ]; } } catch (Throwable $exception) { $pageError = $exception->getMessage(); $detailMapStars = []; $constellationLines = []; } } if ($isAjax) { header('Content-Type: application/json; charset=utf-8'); if ($pageLocation === null || $pageLocation['latitude'] === null || $pageLocation['longitude'] === null) { echo json_encode([ 'ok' => false, 'error' => 'Kein Standard-Standort gesetzt. Bitte zuerst in den Einstellungen einen Standard-Standort hinterlegen.', ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } if ($pageError !== null || !($pdo instanceof PDO)) { echo json_encode([ 'ok' => false, 'error' => $pageError ?? 'Die Datenbank ist nicht verfuegbar.', ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } try { $pythonResult = runPythonApi( __DIR__ . '/py/api.py', 'moon_planet_occultations_for_year', [ (string)$pageLocation['latitude'], (string)$pageLocation['longitude'], (string)$pageLocation['elevation'], (string)$selectedYear, $timezoneName, ] ); if (!$pythonResult['ok']) { echo json_encode([ 'ok' => false, 'error' => $pythonResult['error'] ?? 'Unbekannter Python-Fehler', 'debug' => $pythonResult['debug'] ?? null, ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } echo json_encode([ 'ok' => true, 'results' => $pythonResult['data']['results'] ?? [], 'selected_year' => $selectedYear, ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } catch (Throwable $exception) { echo json_encode([ 'ok' => false, 'error' => $exception->getMessage(), ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } } require __DIR__ . '/header.php'; if (!empty($currentLocation) && is_array($currentLocation)) { $pageLocation = [ 'name' => (string)($currentLocation['name'] ?? ''), 'latitude' => isset($currentLocation['latitude']) ? (float)$currentLocation['latitude'] : null, 'longitude' => isset($currentLocation['longitude']) ? (float)$currentLocation['longitude'] : null, 'elevation' => isset($currentLocation['elevation']) && $currentLocation['elevation'] !== null ? (float)$currentLocation['elevation'] : 0.0, 'timezone' => (string)($currentLocation['timezone'] ?? 'Europe/Berlin'), ]; } ?>

Kein Standard-Standort gesetzt

Fuer die Berechnung wird der Standard-Standort aus der Datenbank verwendet. Bitte wähle in den Einstellungen einen Standard-Standort aus.

Datenbank nicht verfuegbar

Die Sterndaten konnten nicht geladen werden.

Technischer Hinweis:

Standort ° / °
Berechnung

Bereit zur Berechnung

Wähle ein Jahr und starte die Auswertung mit dem Button. Mond-Planeten-Bedeckungen sind an einem festen Standort selten – es ist normal, wenn in manchen Jahren keine gefunden werden.