Voltar aos projetos
Logotipo de Analemma

Analemma

Ferramenta web que permite visualizar trajetórias solares e lunares a partir de qualquer localização geográfica.

AstronomiaAutomação

Um sistema completo para captura fotográfica automatizada e visualização interativa de analemas solares e lunares.

Este projeto automatiza a captura periódica de imagens provenientes de webcams públicas, gerando sequências (timelapses) que evidenciam o movimento aparente do Sol e da Lua ao longo do tempo. As imagens são capturadas em momentos astronômicos precisos mediante GitHub Actions e consumidas posteriormente em um Visualizador Web Moderno (PWA) de alto desempenho. Todo o sistema funciona sem requerer bancos de dados tradicionais, baseando-se no próprio sistema de arquivos de um repositório Git.


Arquitetura do Software

Para manter o código sustentável, escalável e testável, o núcleo do orquestrador fotográfico (src/) foi estruturado seguindo estritamente os preceitos de Clean Architecture e Domain-Driven Design (DDD).

1. Domain Layer

É o coração do software. Aqui residem as regras de negócio puras, independentes de qualquer framework ou infraestrutura externa:

  • Entidades (Location, Camera): Um Location encapsula dados geográficos (país, estado, cidade) e gera identificadores dinâmicos. Uma Camera está vinculada a um Location e mantém sua orientação cardinal.
  • Value Objects: Objetos como CelestialObject padronizam o vocabulário de domínio.
  • Contratos (Interfaces): Abstrações como ScheduleRepository que definem como o domínio espera obter ou persistir dados.

2. Application Layer

Contém os casos de uso principais. Atua como o orquestrador que coordena o Domínio e a Infraestrutura para cumprir com os requisitos do sistema.

  • Scheduler: É o encarregado de revisar os horários programados de cada Location. Se a hora atual de execução coincidir (ou estiver no limiar) de uma captura programada, coordena o serviço de captura correspondente para obter a imagem.

3. Infrastructure Layer

Onde o código interage com serviços externos, I/O e frameworks:

  • Serviços de Captura: Utiliza-se Puppeteer (PuppeteerCaptureService) para visitar páginas web de webcams públicas, aguardar o carregamento de componentes multimídia e extrair limpos os quadros (screenshots) do fluxo de vídeo ou canvas sem incluir a interface web.
  • ConfigScheduleRepository: Um repositório dinâmico que usa configurações para calcular horários precisos de captura nas coordenadas de cada Location registradas em src/config/locations.ts.

Ciclo de Orquestração

O orquestrador está projetado para ser executado ciclicamente através do GitHub Actions, otimizando recursos mediante um cronjob.

sequenceDiagram
    participant GH as GitHub Actions (Cron)
    participant App as Scheduler
    participant Repo as ConfigScheduleRepository
    participant Cam as PuppeteerCaptureService
    participant FS as File System / Git

    GH->>App: Executa ciclo horário (minuto 0)
    App->>Repo: Consulta horas de captura para o dia
    Repo-->>App: Retorna { sun: '12:05', moon: '03:45' }
    App->>App: Avalia se a hora do sistema (America/La_Paz) coincide

    alt Coincide com evento Solar no limiar
        App->>Cam: Inicia Puppeteer Headless
        Cam-->>App: Extrai e retorna buffer de imagem (Screenshot)
        App->>FS: Salva arquivo em 'captures/sun/{location}/{camera}/{YYYY-MM-DD}.jpg'
        GH->>FS: Realiza Git Commit e Push ao repositório
    end

Configuração e Variáveis de Ambiente

O sistema baseia-se em configurações centralizadas, requerendo muito pouco para ser executado. O principal é a sincronização temporal.

VariávelDescrição
TZCrítico: Garante a configuração do fuso horário em America/La_Paz (UTC-4). A aplicação utiliza esta âncora para sincronizar e comparar os horários astronômicos esperados com o cronjob horário.

Web Viewer

Esta é uma aplicação web interativa projetada especificamente para visualizar fluidamente dezenas de milhares de capturas fotográficas (timelapses) geradas pelo orquestrador principal do projeto, evidenciando os trajetos do Sol e da Lua ao longo de extensos períodos de tempo.


Arquitetura UI e Experiência do Usuário (UX)

A aplicação web foi concebida para oferecer um desempenho superior, especialmente ao manipular um grande volume de imagens em alta resolução sem comprometer a memória ou fluidez do navegador.

Transições Fluidas

Implementa-se uma navegação que intercepta os cliques do usuário e carrega dinamicamente a próxima página no DOM sem recarregar a tela inteira. Isso garante que o estado da interface, como o tema visual ou a navegação principal, permaneça ininterrupto.

Persistência do Modo Escuro

O esquema de cores escuro/claro é detectado a partir do sistema e mantido consistentemente ao longo das sessões do usuário. Graças à sincronização com as transições de página, não existem oscilações visuais (“flickering”) ao navegar entre diferentes visualizações.


O Coração do Visualizador: O Reprodutor

Um desafio crítico ao visualizar milhares de imagens (ex. um Analema anual possui 365 quadros de alta resolução) é o colapso da memória do dispositivo do usuário final. Para mitigá-lo, o reprodutor de imagens apoia-se em uma arquitetura leve e otimizada:

stateDiagram-v2
    [*] --> Initialization: Carrega dataset URLs
    Initialization --> BufferedLoading: Pré-carrega primeira imagem (Preview)
    BufferedLoading --> BackgroundLoading: Carregamento progressivo de lotes
    BackgroundLoading --> Ready: Atinge-se o limiar mínimo (ex. 20%)
    Ready --> Playback: Usuário inicia reprodução
    Playback --> Tick: Atualiza imagem baseado em FPS
    Tick --> UpdateFrame: Renderiza próximo quadro
    UpdateFrame --> Playback: Loop se houver mais quadros

1. Carregamento Bufferizado Assíncrono (Buffered Loading)

Em vez de forçar o navegador a baixar todas as imagens antes de permitir a interação, o reprodutor inicia um processo em segundo plano que baixa as imagens em pequenos lotes assíncronos. A reprodução é habilitada assim que uma porcentagem mínima de quadros já está disponível localmente, prevenindo bloqueios visuais.

2. Controle Dinâmico de Velocidade

O usuário tem controle total sobre a velocidade de reprodução, que pode ser ajustada em tempo real. O reprodutor recalcula instantaneamente os intervalos de transição entre quadros (FPS) sem interrupções.


Indexação sem Bancos de Dados Relacionais

Todo o sistema está projetado para dispensar infraestruturas complexas como bancos de dados SQL ou NoSQL.

Em seu lugar, o visualizador web indexa diretamente a estrutura de pastas estáticas onde residem as imagens (captures/) durante o processo de compilação:

graph LR
    A["Processo de Construção"] -->|Leitura do sistema de arquivos| B(Diretório estático 'captures/')
    B --> C{Analisa a estrutura hierárquica}
    C -->|Classificação por localização e câmera| D[Agrupa sequências fotográficas]
    D --> E[Gera índice de metadados JSON]
    E -.->|Alimenta as visualizações web| F(Renderização e Filtros UI)

Este índice leve é consumido pela interface web, permitindo aplicar filtros rápidos e precisos no lado do cliente sem requerer requisições de rede adicionais nem latência.


Pronto para Dispositivos Móveis e Offline

O visualizador web incorpora recursos avançados para maximizar seu alcance:

  • Metadados Otimizados para garantir que os links compartilhados em redes sociais incluam imagens e descrições representativas.
  • Configurado como Progressive Web App (PWA), permitindo sua instalação direta em dispositivos.
  • Modo Offline Básico, implementando políticas de cache mediante um Service Worker para oferecer uma experiência contínua mesmo com redes instáveis.
  • Tipografias Auto-hospedadas, evitando tempos de carregamento adicionais ou dependências de servidores externos.

Arraste para mover o diagrama. Use + e − para dar zoom, as setas para movê-lo e 0 para redefinir a visualização.

Vamos trabalhar juntos

Engenheiro de Software e desenvolvedor Senior Full-Stack, trabalho remotamente a partir de Santa Cruz, Bolívia. Aberto a novas oportunidades.