File manager - Edit - /var/www/html/portalHomolog/app/Console/Commands/TestarExtracaoMares.php
Back
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\Storage; use Smalot\PdfParser\Parser; class TestarExtracaoMares extends Command { protected $signature = 'testar:mares {arquivo} {--debug}'; protected $description = 'Testar a extração de dados de tábuas de marés com diagnóstico detalhado'; public function handle() { $arquivo = $this->argument('arquivo'); $debug = $this->option('debug'); if (!Storage::disk('public')->exists($arquivo)) { $this->error("Arquivo não encontrado: $arquivo"); $this->info("Arquivos disponíveis no storage público:"); $arquivos = Storage::disk('public')->files('tabuas_mares'); foreach ($arquivos as $arq) { $this->info(" - $arq"); } return; } $caminhoCompleto = Storage::disk('public')->path($arquivo); $this->info("Processando arquivo: $arquivo"); $this->info("Caminho completo: $caminhoCompleto"); try { // Salvar texto extraído para análise $textoExtraido = $this->extrairTextoPDF($caminhoCompleto); $debugFile = storage_path('app/debug_pdf_text.txt'); file_put_contents($debugFile, $textoExtraido); $this->info("Texto extraído salvo em: " . $debugFile); if ($debug) { $this->info("\n=== PRIMEIRAS 50 LINHAS DO TEXTO EXTRAÍDO ==="); $linhas = explode("\n", $textoExtraido); for ($i = 0; $i < min(50, count($linhas)); $i++) { $this->line("[$i]: " . trim($linhas[$i])); } } $dados = $this->extrairTodosOsDadosMelhorado($textoExtraido); $this->info("\n=== RESULTADOS DA EXTRAÇÃO ==="); $this->info("Ano: " . ($dados['ano'] ?? 'NÃO ENCONTRADO')); $this->info("Localidade: " . ($dados['localidade'] ?? 'NÃO ENCONTRADA')); $this->info("Nível médio: " . ($dados['nivel_medio'] ?? 'NÃO ENCONTRADO')); $this->info("Total de meses: " . count($dados['dados_estruturados'])); foreach ($dados['dados_estruturados'] as $mes => $dias) { $this->info("Mês $mes: " . count($dias) . " dias"); if ($debug && count($dias) > 0) { $primeirosDias = array_slice($dias, 0, 3, true); foreach ($primeirosDias as $dia => $registros) { $this->info(" - Dia $dia: " . count($registros) . " registros"); } } } // Testar datas específicas $this->testarDatasEspecificas($dados); } catch (\Exception $e) { $this->error("Erro ao processar PDF: " . $e->getMessage()); $this->error("Stack trace: " . $e->getTraceAsString()); } } private function extrairTextoPDF($caminhoArquivo) { try { $parser = new Parser(); $pdf = $parser->parseFile($caminhoArquivo); return $pdf->getText(); } catch (\Exception $e) { throw new \Exception('Erro na leitura do PDF: ' . $e->getMessage()); } } /** * EXTRAÇÃO MELHORADA - Versão mais robusta */ private function extrairTodosOsDadosMelhorado($text) { $lines = explode("\n", $text); $dados = [ 'texto_completo' => $text, 'ano' => null, 'localidade' => null, 'nivel_medio' => null, 'dados_estruturados' => [] ]; $meses = [ 'Janeiro' => 1, 'Fevereiro' => 2, 'Março' => 3, 'Abril' => 4, 'Maio' => 5, 'Junho' => 6, 'Julho' => 7, 'Agosto' => 8, 'Setembro' => 9, 'Outubro' => 10, 'Novembro' => 11, 'Dezembro' => 12 ]; // EXTRAÇÃO DE INFORMAÇÕES GERAIS - MAIS ROBUSTA foreach ($lines as $line) { $line = trim($line); // Extrair ano - múltiplos padrões if (preg_match('/- (\d{4})$/', $line, $matches)) { $dados['ano'] = $matches[1]; $this->info("[DEBUG] Ano encontrado: " . $dados['ano']); } // Extrair localidade if (strpos($line, 'PORTO DE ANGRA DOS REIS') !== false) { $dados['localidade'] = trim($line); $this->info("[DEBUG] Localidade encontrada: " . $dados['localidade']); } // Extrair nível médio - múltiplos padrões if (preg_match('/Nível Médio\s+([\d.]+)\s*m/', $line, $matches)) { $dados['nivel_medio'] = floatval($matches[1]); $this->info("[DEBUG] Nível médio encontrado: " . $dados['nivel_medio']); } } // EXTRAÇÃO DE DADOS POR MÊS E DIA - ABORDAGEM COMPLETAMENTE REVISADA $mesAtual = null; $mesNumero = null; $processandoDados = false; foreach ($lines as $index => $line) { $line = trim($line); // VERIFICAR SE É UM MÊS - abordagem mais flexível foreach ($meses as $mesNome => $mesNum) { // Verifica se a linha contém APENAS o nome do mês if ($line === $mesNome) { $mesAtual = $mesNome; $mesNumero = $mesNum; $dados['dados_estruturados'][$mesNumero] = []; $processandoDados = true; $this->info("[DEBUG] Iniciando mês: $mesNome ($mesNumero)"); break; } } if ($processandoDados && $mesNumero) { // PADRÃO 1: Linha completa com dia da semana // Exemplo: "01 QUA 0344 1.16 1047 0.39 1451 1.10 2246 -0.01" if (preg_match('/^(\d{1,2})\s+[A-Z]{3}\s+(\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+)$/', $line, $matches)) { $dia = (int)$matches[1]; $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]); if (!empty($dadosDia)) { $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia; $this->info("[DEBUG] Dia $dia/$mesNumero processado: " . count($dadosDia) . " registros"); } } // PADRÃO 2: Linha com menos dados elseif (preg_match('/^(\d{1,2})\s+[A-Z]{3}\s+(\d{4}\s+[-\d.]+(?:\s+\d{4}\s+[-\d.]+)*)$/', $line, $matches)) { $dia = (int)$matches[1]; $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]); if (!empty($dadosDia)) { $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia; $this->info("[DEBUG] Dia $dia/$mesNumero processado (padrão 2): " . count($dadosDia) . " registros"); } } // PADRÃO 3: Apenas números (dia sem dia da semana) elseif (preg_match('/^(\d{1,2})\s+(\d{4}\s+[-\d.]+(?:\s+\d{4}\s+[-\d.]+)*)$/', $line, $matches)) { $dia = (int)$matches[1]; $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]); if (!empty($dadosDia)) { $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia; $this->info("[DEBUG] Dia $dia/$mesNumero processado (padrão 3): " . count($dadosDia) . " registros"); } } // VERIFICAR SE ENCONTROU O PRÓXIMO MÊS if (isset($lines[$index + 1])) { $proximaLinha = trim($lines[$index + 1]); foreach ($meses as $mesNome => $mesNum) { if ($proximaLinha === $mesNome) { $processandoDados = false; $this->info("[DEBUG] Finalizando mês $mesAtual, próximo mês: $mesNome"); break 2; // Sai dos dois loops } } } } } return $dados; } /** * EXTRAÇÃO DE HORÁRIOS MELHORADA */ private function extrairHorariosDaLinhaMelhorado($linha) { $dados = []; // Padrão MELHORADO para capturar TODOS os pares horário-altura $pattern = '/(\d{4})\s+([-]?\d+\.\d+)/'; if (preg_match_all($pattern, $linha, $matches)) { for ($i = 0; $i < count($matches[1]); $i++) { $horario = $matches[1][$i]; $altura = floatval($matches[2][$i]); // Formatar horário (0344 → 03:44) $horarioFormatado = substr($horario, 0, 2) . ':' . substr($horario, 2, 2); // Determinar tipo de maré $tipo = $this->determinarTipoMare($altura); $dados[] = [ 'horario' => $horarioFormatado, 'altura' => $altura, 'tipo' => $tipo ]; } $this->info("[DEBUG] Extraídos " . count($dados) . " horários da linha: $linha"); } else { $this->warn("[DEBUG] Nenhum horário encontrado na linha: $linha"); } return $dados; } private function determinarTipoMare($altura) { if ($altura < 0) { return 'Baixa'; } if ($altura >= 0.8) { return 'Alta'; } elseif ($altura <= 0.3) { return 'Baixa'; } return $altura >= 0.5 ? 'Alta' : 'Baixa'; } private function testarDatasEspecificas($dados) { $this->info("\n=== TESTE DE DATAS ESPECÍFICAS ==="); $datasTeste = [ [3, 7], // 7 de março [3, 8], // 8 de março [3, 9], // 9 de março [1, 1], // 1 de janeiro [12, 31] // 31 de dezembro ]; foreach ($datasTeste as $data) { list($mes, $dia) = $data; if (isset($dados['dados_estruturados'][$mes][$dia])) { $this->info("Dados para $dia/$mes/" . ($dados['ano'] ?? '2025') . ":"); foreach ($dados['dados_estruturados'][$mes][$dia] as $mare) { $this->info(" {$mare['horario']} - {$mare['altura']}m - {$mare['tipo']}"); } } else { $this->warn("Dados para $dia/$mes/" . ($dados['ano'] ?? '2025') . " NÃO encontrados"); } } } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings