Skip to content

Feature/measurement parser - #4

Merged
roman-dvorak merged 12 commits into
mainfrom
feature/measurement-parser
Jun 28, 2026
Merged

Feature/measurement parser#4
roman-dvorak merged 12 commits into
mainfrom
feature/measurement-parser

Conversation

@roman-dvorak

@roman-dvorak roman-dvorak commented Jun 28, 2026

Copy link
Copy Markdown
Member

This pull request introduces a "parse-later" pipeline for ingesting and processing meteor observation data, adds support for per-device web frontend language preferences, and exposes new API endpoints and schemas to support these features. The main changes include new models and migrations for parsed measurements, a parser module for extracting and converting scientific data, API extensions for device settings and report details, and workflow improvements for Docker builds.

Ingestion and Parsing Pipeline:

  • Added a new ParsedMeasurement model and migration to store render-ready, scientifically parsed data from raw ingests, including event time, coordinates, and quality metrics. [1] [2]
  • Implemented apps.ingest.parser with robust parsing, validation, alt/az to RA/Dec conversion, and time zone resolution for each observation, using the timezonefinder dependency. [1] [2]
  • Added a parse_pending management command to process and update raw ingests into parsed measurements, supporting re-parsing on logic changes.

Web API and Device Settings:

  • Extended the device model and schema to support a persistent per-device web frontend language preference (fe_language), with migration and API endpoints to get and set this preference. [1] [2] [3] [4]
  • Added new API schemas and endpoints for detailed, render-ready measurement reports, including parsed coordinates and event times in both UTC and local time at the observing site. [1] [2]

DevOps and Workflow:

  • Updated the GitHub Actions release workflow to build and push a Docker image for the frontend (meteorpointer-fe).
  • Added the timezonefinder Python package to requirements for offline time zone resolution.

robozor and others added 12 commits June 14, 2026 21:06
Turn raw ingests into a ParsedMeasurement (parse-later, never blocks upload):
validated horizontal coords of the trail's two aim points, derived RA/Dec for
plotting on a star map, the absolute UTC event time, the site, and the site's
IANA time zone.

- parser.py: pure parse_payload() + closed-form altaz_to_radec() (arc-minute
  accurate, no heavy astrometry dep -- exceeds the phone-orientation input
  accuracy); parse_and_store()/ensure_parsed() persistence with parse_version.
- Note: eventTimestamp is Date.now() epoch ms, i.e. already absolute UTC -- not
  a local time. GPS only adds the site IANA zone (timezonefinder, MIT) so the
  UI can show the observer's local civil time.
- ParsedMeasurement model + hand-written migration 0002.
- parse_pending management command (parse new/stale rows, or --all backfill).
- GET /v1/web/reports/{client_key}: lazily-parsed render payload (start/end
  alt/az + ra/dec, event_utc/event_local/event_tz).
- timezonefinder==6.5.7 (MIT). Tests: 15 passed; verified on real data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a self-hosted star map (d3-celestial, BSD-3 -- no external service, no
API calls; library + star/Milky-Way data served from our own nginx) to the
right of the measurements grid. Clicking a row fetches the parsed detail and
draws the local sky for that site and UTC instant, with a horizon, and
overlays the trail (green = start, red = end).

- sky.js: MeteorSky module -- d3-celestial config + a custom canvas layer that
  draws the trail via Celestial.getData/mapProjection, driven by skyview(date,
  location).
- index.html: two-column layout, clickable rows, caption (site-local time +
  alt/az + RA/Dec), and an "O aplikaci" (About) dialog citing every component
  license we must attribute (d3-celestial, D3, star/IAU/Milky-Way data, segno,
  timezonefinder/OSM-ODbL, Django/ninja).
- skytest.html: standalone render harness (verified: stars, constellations,
  horizon and the trail render correctly with real parsed RA/Dec).
- vendor/celestial: d3-celestial libs + minimal data (stars<=6, constellations,
  Milky Way).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
.modal and .layout set display:flex later in the stylesheet than
.hidden{display:none}, so an element with both classes stayed visible --
the About dialog popped up on load and its close button could not hide it.
Make .hidden use !important so it always wins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Localization:
- Web language is now a per-device setting stored in the API: Device.fe_language
  (migration 0002), returned by GET /v1/web/me and set via POST /v1/web/settings.
- frontend/i18n.js: cs/en dictionary + data-i18n DOM application + t(); CZ/EN
  switcher next to "About" persists to the device (and localStorage); language
  loads from /me on sign-in. Cardinal directions are localized too (S/V/J/Z).

Sky view reworked per feedback (the full zenith disk was unsuitable):
- Full-viewport layout: grid left (content width, own scroll), map fills the
  rest (full height + width).
- sky.js is now a custom SVG "horizon dome": a half-circle whose flat bottom is
  the horizon with cardinal-direction marks; altitude grows to the zenith; only
  above-horizon sky is drawn; the view faces the meteor and the trail is green
  (start) -> red (end). Bright stars (Hipparcos) are converted RA/Dec->alt/az
  client-side; the trail uses the measured alt/az directly (exact).
- Verified end-to-end in the browser (CZ/EN switch, trail, cardinal labels).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Map (sky.js):
- Add constellation lines and localized names (cz/en from the IAU dataset).
- Zoom (wheel + on-screen +/-/reset buttons) and pan (drag); double-click
  resets. At default zoom it reads as a half-dome; zoomed in it fills the
  panel (the hemisphere constraint is relaxed), with shaded ground below the
  horizon. Geometry is precomputed in unit coords so zoom/pan only re-applies a
  linear transform (fast).

Licensing / cleanup:
- We no longer use the d3-celestial JS library or D3 (custom SVG renderer), so
  remove celestial.min.js, d3.min.js, d3.geo.projection.min.js, celestial.css
  and the now-unused mw.json. We DO still ship its star/constellation DATA, so
  the About dialog keeps a d3-celestial attribution (reframed as the data
  source, BSD-3) and drops the D3 library citation.

Verified in-browser: constellations + cz/en names, trail, zoom fills the panel,
device language loads from /me on sign-in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The previous version pre-projected once and let zoom/pan linearly transform the
rendered picture, so it felt like moving an image. Replace it with a gnomonic
(rectilinear) camera parameterised by a look direction (azimuth, altitude) and
field of view:
- Drag rotates the look direction: the sky and the cardinal marks scroll, new
  sky appears at the edges, the panel itself stays put.
- Wheel / +/- buttons change the field of view, so zooming out reveals MORE sky
  (not just a smaller image). Double-click resets to face the meteor.
- Adds the alt-azimuth grid (meridians converging at the zenith + almucantars),
  which was missing, plus shaded ground below the horizon.
Per-measurement star/constellation alt-az is precomputed once; each frame only
re-runs the camera transform (rAF-throttled), so navigation is smooth.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per feedback, the free 3D camera felt wrong. Switch to a panorama projection:
x = azimuth, y = altitude. The horizon is a fixed horizontal line that never
moves; dragging only turns the view left/right (azimuth scrolls, cardinal marks
slide along the fixed horizon) as if the observer turned in place; the wheel /
buttons zoom the field of view around the horizon. No vertical pan, no image
transforms. Meridians are vertical lines (constant azimuth), almucantars
horizontal, ground shaded below the fixed horizon line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Converging meridians: x = azimuth-offset * cos(altitude), so the horizon
  stays a full-width horizontal line while meridians taper to the zenith point
  at the top (a dome look), instead of parallel verticals. Grid lines and
  constellations are sampled and drawn as the resulting curves.
- Zoom no longer changes the filled height: the minimum zoom shows the whole
  sky (zenith just past the top edge) so the panel is always full; zooming in
  only narrows the field of view (more detail, fewer objects). No zoom-out
  past the full-sky view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the panorama with a conformal stereographic projection of the local
sky, as on VirtualSky: a circular map with the zenith at the centre and the
horizon as the outer circle. Constellation shapes are undistorted; meridians
are radial lines from the zenith, almucantars concentric circles, cardinal
directions sit around the horizon circle (N top, E left -- looking up), and the
ground is the area outside the circle. Scroll/buttons zoom (toward the cursor),
drag pans, double-click resets. The meteor trail is overlaid green->red.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The stereo projection is now centred on a point ON the horizon in the viewing
direction, so the horizon is a straight horizontal line at the bottom and the
sky domes up above it (not a circle) -- matching VirtualSky. Conformal, so
constellation shapes are correct; meridians converge at the zenith (placed at
~80% of the panel height); drag turns the view left/right with the horizon
fixed; the wheel zooms toward the cursor for more local detail; ground shaded
below the horizon line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Merge the deployment mechanism from main into this (sky-map) branch so the
map version is deployable the same way:

A) Build-time API base via config.js
   - frontend/config.js: window.API_BASE (default /api)
   - app.js reads window.API_BASE instead of hardcoding the API host
   - index.html loads config.js before app.js
   - docker/fe/Dockerfile bakes config.js from the API_BASE build arg
   - docker-compose.yml dev build passes API_BASE=http://localhost:8000

B) CI builds and pushes ghcr.io/bolidozor/meteorpointer-fe (with the sky map)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@roman-dvorak
roman-dvorak merged commit 56107d1 into main Jun 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants