Initial Vibe coded project
This commit is contained in:
commit
0891cf12a5
21 files changed
+2830
No files matched your search
+188
@@ -0,0 +1,188 @@
|
||||
|
||||
# Flight Map Requirements
|
||||
|
||||
## Purpose
|
||||
|
||||
Create a Python program that generates an SVG map of a rectangular geographic
|
||||
area with recorded aircraft flight tracks overlaid, suitable for drawing with
|
||||
a physical pen plotter.
|
||||
|
||||
## Separate collection and plotting workflow
|
||||
|
||||
- Provide separate command-line commands for flight-data collection and SVG
|
||||
generation. Run collection first; generate maps later from the saved database.
|
||||
- The collection command accepts optional opposite map corners and the SQLite
|
||||
database destination. If corners are omitted, use the default map area
|
||||
including Uithoorn in the Netherlands. It records flight data without
|
||||
generating an SVG or requiring map or terrain downloads.
|
||||
- Store a recording-session record containing a session identifier, the
|
||||
normalized requested map bounds, the expanded collection bounds, the flight
|
||||
data source, the collection interval, and the recording start and end times.
|
||||
Preserve this metadata across interruption or restart.
|
||||
- Associate every stored flight observation with its recording session so its
|
||||
map area and collection context remain identifiable.
|
||||
- The plotting command accepts the database, a recording-session selection,
|
||||
an optional time interval within that recording, and output settings.
|
||||
Use the selected session's stored map bounds rather than requiring the user
|
||||
to enter the map area again.
|
||||
- Plotting must not contact OpenSky or start flight-data collection. It may
|
||||
obtain OpenStreetMap-derived vector data and terrain elevation data
|
||||
separately as needed.
|
||||
- Allow multiple maps with different time selections and output settings to be
|
||||
generated from the same recording without modifying the recorded flight
|
||||
observations or session metadata.
|
||||
- Report missing sessions, invalid time selections, and absence of usable
|
||||
observations explicitly.
|
||||
- Provide a purge command requiring an exact session identifier and explicit
|
||||
confirmation to permanently delete that session's observations and metadata
|
||||
in one transaction. Preserve all other sessions and their observations.
|
||||
- Purging a missing session or database must report an error without creating
|
||||
a database. Stop collection for the selected session before purging it.
|
||||
|
||||
## Map input and output
|
||||
|
||||
- At collection time, accept the longitude and latitude of two opposite corners
|
||||
of the map, validate coordinates, and normalize their order.
|
||||
- Provide a predefined default rectangular map area that includes the city of
|
||||
Uithoorn in the Netherlands. Explicitly supplied corners override this default.
|
||||
- Default southwest corner: latitude 52.232025, longitude 4.784498.
|
||||
Default northeast corner: latitude 52.253985, longitude 4.863525.
|
||||
Command-line bounds use longitude first: 4.784498 52.232025 4.863525 52.253985.
|
||||
- Store the actual bounds used, including when the default is selected, in the
|
||||
recording session. Later plotting must use those stored bounds rather than
|
||||
a potentially changed application default.
|
||||
- At plotting time, load the map bounds from the selected recording session.
|
||||
- Obtain OpenStreetMap-derived vector map data, either as vector tiles or
|
||||
geographic feature data, following the source's usage policy and including
|
||||
the required attribution. Standard raster map tiles are not suitable for
|
||||
the pen-plotter output.
|
||||
- Cache downloaded vector map data persistently by source, geographic bounds,
|
||||
and feature query. Reuse it across plotting runs without downloading it
|
||||
again. Provide a configurable cache directory and an explicit refresh option.
|
||||
- Write cache entries atomically so interrupted downloads or writes do not
|
||||
replace a previously usable entry. Report damaged cache entries explicitly.
|
||||
- Generate an SVG using a consistent geographic projection for the map and
|
||||
flight tracks.
|
||||
- Handle invalid input and download failures with clear error messages.
|
||||
|
||||
## Pen-plotter output
|
||||
|
||||
- Render map features and flight tracks as vector paths or line geometry,
|
||||
without embedded raster images or reliance on filled areas, shading, or
|
||||
other screen-only effects.
|
||||
- Render all labels and attribution as paths, using single-line stroke
|
||||
lettering suitable for pen plotting rather than relying on installed fonts
|
||||
or tracing filled glyph outlines.
|
||||
- Resolve clipping into the exported geometry so map features stop at the map
|
||||
boundary and flight-track extensions remain within the output page. Do not
|
||||
rely on SVG clipping masks being supported by the plotter software.
|
||||
- Specify physical page dimensions and a matching SVG viewBox so the intended
|
||||
drawing size is preserved when imported into plotter software.
|
||||
- Keep map geometry, flight tracks, and lettering in separate named SVG groups
|
||||
for independent selection and plotting.
|
||||
- Select and simplify map features to keep the drawing legible at its physical
|
||||
output size. Omit minor pedestrian and cycle paths and suppress building
|
||||
outlines whose shorter dimension is smaller than three pen widths.
|
||||
|
||||
## Flight data and local recording
|
||||
|
||||
- Use OpenSky Network as the initial flight-data source.
|
||||
- Retrieve live aircraft state vectors for the selected geographic area.
|
||||
- Query an area slightly larger than the map so recorded flight paths can
|
||||
extend beyond the map boundary.
|
||||
- Collect positions periodically, respecting OpenSky's current authentication
|
||||
requirements, rate limits, and usage terms.
|
||||
- Store observations locally in SQLite so maps can be generated later without
|
||||
fetching those observations again.
|
||||
- Store the aircraft's ICAO identifier, callsign when available, position
|
||||
timestamp, longitude, latitude, and available altitude measurements.
|
||||
- Support generating a map from locally recorded observations for a selected
|
||||
time interval.
|
||||
- Do not require historical data from before local recording began. Unrestricted
|
||||
historical access is not assumed.
|
||||
- Report recording failures explicitly and handle missing fields and gaps in
|
||||
coverage without inventing observations.
|
||||
- Initial use is non-commercial, subject to OpenSky's applicable terms and
|
||||
attribution requirements.
|
||||
|
||||
## Flight-track rendering
|
||||
|
||||
- Overlay recorded flight paths that cross the requested map area.
|
||||
- Fit smooth interpolating curves through recorded flight positions rather
|
||||
than drawing angular polylines. Export flight paths as cubic Bezier geometry
|
||||
suitable for a pen plotter. Two-point tracks may remain straight.
|
||||
- Do not smooth across track gaps, on-ground interruptions, or flight changes.
|
||||
Handle repeated positions without generating invalid curve coordinates.
|
||||
- Clip the actual curves to the output bounds, not just their sample points,
|
||||
and use the same curved in-map portions for time and average-height selection.
|
||||
- Extend the visible tracks a little beyond the map boundary using actual
|
||||
recorded positions from the surrounding area, not fabricated extrapolation.
|
||||
- Keep the map background within its requested bounds and provide space in the
|
||||
SVG for the extended tracks and their labels.
|
||||
- Identify each flight track with its date, time, callsign or flight number when
|
||||
available, and average height above the map's average ground elevation.
|
||||
- Do not present an OpenSky callsign as a verified passenger-facing flight
|
||||
number. Callsign-to-flight-number lookup is not required for the initial
|
||||
version.
|
||||
- Calculate the map's average ground elevation from terrain elevation data
|
||||
covering the requested map bounds, excluding the surrounding collection area.
|
||||
Use an area-weighted mean or an equivalent equal-area sampling method.
|
||||
- Calculate each track's average height as its average aircraft altitude over
|
||||
the portion inside the requested map bounds minus the map's average ground
|
||||
elevation. Outside-map extensions must not affect this calculation.
|
||||
- Use compatible units and a common vertical reference for aircraft altitude
|
||||
and terrain elevation, applying conversions where needed. Do not subtract
|
||||
terrain elevation directly from uncorrected barometric pressure altitude.
|
||||
- Label the result explicitly as average height above the map's average ground
|
||||
level, with units. This is not height above the terrain directly beneath each
|
||||
aircraft position and must not be presented as terrain clearance.
|
||||
- Indicate when the height cannot be calculated because compatible aircraft
|
||||
altitude or sufficient terrain data is unavailable; do not silently substitute
|
||||
altitude above sea level or assume zero ground elevation.
|
||||
- Make labels readable and indicate unavailable metadata explicitly.
|
||||
|
||||
## Implementation and validation
|
||||
|
||||
- Implement the program in Python with a command-line interface.
|
||||
- Document installation, the separate collection and plotting commands,
|
||||
session selection, map generation, configuration, data-source limitations,
|
||||
and attribution.
|
||||
- Test coordinate handling, projection, local recording, track selection,
|
||||
average ground elevation, vertical-reference compatibility, average-height
|
||||
calculation, missing elevation data, and SVG generation.
|
||||
- Test persistence of session bounds and observation associations, plotting
|
||||
after collection has stopped, and repeated plotting without changing the
|
||||
recorded flight data. Verify that collection does not require map or terrain
|
||||
services and plotting makes no OpenSky requests.
|
||||
- Test that omitting map corners selects the Uithoorn default, explicit corners
|
||||
override it, and the selected bounds are persisted for later plotting.
|
||||
- Validate that the exported SVG contains drawable vector geometry, path-based
|
||||
lettering, correct physical dimensions, and geometry clipped to its intended
|
||||
bounds, with no raster images or dependence on text rendering or clipping
|
||||
masks.
|
||||
- Include an end-to-end test using fixed sample data without requiring live
|
||||
network access.
|
||||
- Test cache reuse, separate entries for different map areas, explicit refresh,
|
||||
and preservation of cached data when refresh fails.
|
||||
|
||||
## Initial implementation defaults and limitations
|
||||
|
||||
- Use Overpass to obtain OpenStreetMap roads, waterways, building outlines, and
|
||||
water outlines, with local Overpass JSON also accepted for offline plotting.
|
||||
- Default to A4 landscape (297 by 210 mm), 12 mm page margins, a 0.3 mm pen,
|
||||
and track extensions of up to 4 mm beyond the map border.
|
||||
- Collect every 30 seconds within a 2,000 m margin around the saved map area.
|
||||
- Display timestamps in UTC using date and 24-hour time, and heights in metres.
|
||||
- Accept local terrain GeoTIFFs with a declared vertical reference. For
|
||||
orthometric terrain, accept a matching geoid-separation raster for converting
|
||||
ellipsoidal aircraft heights. Require explicit confirmation of the geometric
|
||||
altitude interpretation before calculating heights; otherwise label them
|
||||
unavailable. Never silently substitute barometric altitude.
|
||||
- Estimate average ground elevation using a 64 by 64 equal-area sampling grid.
|
||||
Any missing terrain sample makes the average unavailable.
|
||||
- Use time-weighted aircraft altitude with linear interpolation between recorded
|
||||
timestamps, restricted to the smoothed path's portion inside the map. Use
|
||||
centripetal Catmull-Rom interpolation converted to cubic Bezier curves for
|
||||
flight paths. Split tracks at changes
|
||||
in callsign, on-ground observations, or gaps exceeding 120 seconds by default.
|
||||
- Reject antimeridian-crossing bounds and latitudes outside [-85, 85] explicitly.
|
||||
Reference in new issue
Block a user