['id' => '25338', 'frequencies' => ['137.620 MHz']], 'NOAA 18' => ['id' => '28654', 'frequencies' => ['137.9125 MHz']], 'NOAA 19' => ['id' => '33591', 'frequencies' => ['137.100 MHz']] ]; public function __construct() { $this->loadTLEData(); } /** * Carrega dados TLE (Two-Line Element) dos satélites NOAA */ private function loadTLEData() { $tleUrl = "https://celestrak.org/NORAD/elements/weather.txt"; try { $content = @file_get_contents($tleUrl); if ($content === false) { throw new Exception("Não foi possível carregar dados TLE"); } $lines = explode("\n", $content); $currentSatellite = null; foreach ($lines as $line) { $line = trim($line); if (empty($line)) continue; // Verifica se é linha de nome do satélite if (!is_numeric(substr($line, 0, 1))) { $currentSatellite = trim($line); if (isset($this->satellites[$currentSatellite])) { $this->tleData[$currentSatellite] = ['name' => $currentSatellite]; } } // Verifica se é linha 1 do TLE elseif (isset($this->tleData[$currentSatellite]) && !isset($this->tleData[$currentSatellite]['line1'])) { $this->tleData[$currentSatellite]['line1'] = $line; } // Verifica se é linha 2 do TLE elseif (isset($this->tleData[$currentSatellite]) && isset($this->tleData[$currentSatellite]['line1']) && !isset($this->tleData[$currentSatellite]['line2'])) { $this->tleData[$currentSatellite]['line2'] = $line; } } } catch (Exception $e) { // Fallback para dados TLE estáticos em caso de erro $this->loadStaticTLE(); } } /** * Dados TLE estáticos como fallback */ private function loadStaticTLE() { $this->tleData = [ 'NOAA 15' => [ 'name' => 'NOAA 15', 'line1' => '1 25338U 98030A 24123.45833333 .00000078 00000+0 00000+0 0 9998', 'line2' => '2 25338 98.7242 103.3862 0011016 73.1596 287.0574 14.25911785421652' ], 'NOAA 18' => [ 'name' => 'NOAA 18', 'line1' => '1 28654U 05018A 24123.45833333 .00000078 00000+0 00000+0 0 9997', 'line2' => '2 28654 98.9242 103.3862 0011016 73.1596 287.0574 14.25911785421652' ], 'NOAA 19' => [ 'name' => 'NOAA 19', 'line1' => '1 33591U 09005A 24123.45833333 .00000078 00000+0 00000+0 0 9996', 'line2' => '2 33591 99.0242 103.3862 0011016 73.1596 287.0574 14.25911785421652' ] ]; } /** * Calcula a posição atual do sol */ private function calculateSunPosition() { // Calcula a posição do sol com base no dia e hora atual $now = new DateTime('now', new DateTimeZone('UTC')); $dayOfYear = $now->format('z'); $timeUTC = $now->format('H') + ($now->format('i') / 60); // Calcula a declinação solar (aproximada) $declination = 23.45 * sin(deg2rad(360 * (284 + $dayOfYear) / 365)); // Calcula o ângulo horário (aproximado) $hourAngle = 15 * ($timeUTC - 12); return [ 'declination' => $declination, 'hour_angle' => $hourAngle, 'utc_time' => $now->format('Y-m-d H:i:s') ]; } /** * Calcula a próxima passagem do satélite */ private function calculateNextPass($satellite, $observerLat, $observerLon, $observerAlt = 0) { if (!isset($this->tleData[$satellite])) { return null; } $tle = $this->tleData[$satellite]; $now = time(); // Simulação simplificada de cálculo de passagem $passes = []; for ($i = 0; $i < 5; $i++) { $timestamp = $now + ($i * 3600 * 3); // A cada 3 horas $elevation = rand(10, 90); // Simulação de elevação $passes[] = [ 'start' => date('Y-m-d H:i:s', $timestamp), 'max_elevation' => $elevation, 'duration' => rand(300, 900) // 5-15 minutos ]; } return $passes; } /** * Obtém dados meteorológicos atuais */ private function getWeatherData() { // Simulação de dados meteorológicos return [ 'temperature' => rand(15, 30), 'humidity' => rand(40, 90), 'pressure' => rand(1000, 1020), 'visibility' => rand(5, 20) ]; } /** * Gera a interface web com globo 3D */ public function renderInterface() { $observerLat = isset($_GET['lat']) ? floatval($_GET['lat']) : -23.5505; // São Paulo $observerLon = isset($_GET['lon']) ? floatval($_GET['lon']) : -46.6333; $selectedSatellite = isset($_GET['satellite']) ? $_GET['satellite'] : 'NOAA 19'; $weather = $this->getWeatherData(); $sunPosition = $this->calculateSunPosition(); echo ' Monitor NOAA - Satélites em Tempo Real

Monitor de Satélites NOAA

Acompanhe em tempo real a passagem dos satélites meteorológicos

Globo Terrestre 3D - Visualização em Tempo Real

Condições Atuais

' . $weather['temperature'] . '°C Temperatura
' . $weather['humidity'] . '% Umidade
' . $weather['pressure'] . ' hPa Pressão
' . $weather['visibility'] . ' km Visibilidade
'; foreach ($this->tleData as $satellite => $data) { $passes = $this->calculateNextPass($satellite, $observerLat, $observerLon); echo '

' . $satellite . '

NORAD ID: ' . $this->satellites[$satellite]['id'] . ' ' . implode(', ', $this->satellites[$satellite]['frequencies']) . '

Próximas Passagens:

'; if ($passes) { foreach ($passes as $pass) { echo '
' . $pass['start'] . '
Elevação: ' . $pass['max_elevation'] . '° Duração: ' . gmdate('i:s', $pass['duration']) . '
'; } } else { echo '

Nenhuma passagem prevista

'; } echo '
'; } echo '
'; } /** * API para obter dados JSON */ public function getAPIResponse() { if (isset($_GET['api']) && $_GET['api'] == 'json') { header('Content-Type: application/json'); $observerLat = isset($_GET['lat']) ? floatval($_GET['lat']) : -23.5505; $observerLon = isset($_GET['lon']) ? floatval($_GET['lon']) : -46.6333; $response = [ 'timestamp' => date('c'), 'satellites' => [] ]; foreach ($this->tleData as $satellite => $data) { $passes = $this->calculateNextPass($satellite, $observerLat, $observerLon); $response['satellites'][] = [ 'name' => $satellite, 'norad_id' => $this->satellites[$satellite]['id'], 'frequencies' => $this->satellites[$satellite]['frequencies'], 'next_passes' => $passes ]; } echo json_encode($response, JSON_PRETTY_PRINT); exit; } } } // Execução do programa $tracker = new NOAASatelliteTracker(); $tracker->getAPIResponse(); $tracker->renderInterface(); ?>