{"id":48879148,"url":"https://github.com/bebablub/wp-flyover","last_synced_at":"2026-04-16T02:01:02.493Z","repository":{"id":323416983,"uuid":"1093138801","full_name":"bebablub/wp-flyover","owner":"bebablub","description":"Upload GPX files and render animated flyover maps with MapLibre and an elevation chart in WordPress","archived":false,"fork":false,"pushed_at":"2025-11-10T03:20:02.000Z","size":5841,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-10T03:23:46.655Z","etag":null,"topics":["cycling","flyover","gpx-files","javascript","map","php","terrain","wordpress","wordpress-plugin"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bebablub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-10T00:42:11.000Z","updated_at":"2025-11-10T03:20:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bebablub/wp-flyover","commit_stats":null,"previous_names":["bebablub/wp-flyover"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/bebablub/wp-flyover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bebablub%2Fwp-flyover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bebablub%2Fwp-flyover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bebablub%2Fwp-flyover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bebablub%2Fwp-flyover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bebablub","download_url":"https://codeload.github.com/bebablub/wp-flyover/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bebablub%2Fwp-flyover/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31867712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"online","status_checked_at":"2026-04-16T02:00:06.042Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cycling","flyover","gpx-files","javascript","map","php","terrain","wordpress","wordpress-plugin"],"created_at":"2026-04-16T02:01:01.577Z","updated_at":"2026-04-16T02:01:02.486Z","avatar_url":"https://github.com/bebablub.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flyover GPX\n\nUpload GPX files and render animated flyover maps with MapLibre and an elevation chart in WordPress.\n\nThis plugin adds a Track post type, a simple admin uploader, a REST endpoint serving parsed GPX data, and a front‑end player with play/pause controls, progress bar, and a synced elevation chart.\n\n## Features\n\n- Animated flyover map (MapLibre GL) with smooth camera\n- Elevation-based route coloring – progressive route changes color based on gradient (flat vs steep sections)\n- Photos on the map (thumbnails + fullscreen on cue) with image overlay support during video recording\n- Labels for maximum speed and elevation\n- HUD overlays (speed, distance, elevation, heading) – toggleable\n- Multi-weather heatmap overlays with 4 separate colored layers (snow, rain, fog, clouds) using admin-configurable colors\n- Day/Night overlay with configurable colors\n- Weather visualizations: colored heatmaps, temperature circles, and wind arrows with configurable radius\n- Wind analysis: per-point wind speed/direction, wind impact factor chart, wind rose distribution (16 sectors)\n- Multi-tab Chart.js visualizations: Elevation, Biometrics (HR/Cadence), Temperature, Power, Wind Impact, Wind Rose, and All Data\n- Chart area selection \u0026 zoom with reset and synchronized map marker filtering (excludes polar charts)\n- Video recording – record MP4/WebM videos of the flyover animation with customizable settings\n- Privacy mode (hide first/last N km for playback window only)\n- Dark mode‑friendly UI\n- Admin tools: Add New Track page, sortable stats, live preview\n- Configurable defaults (height, zoom, pitch, chart colors, elevation coloring)\n- Custom styling: inline style.json or vector style URL; OSM raster fallback\n- Backend GPX simplification enabled by default with dynamic targets for large tracks\n- Admin toggle for tile prefetching (reduce third‑party tile requests/quota usage)\n- Lazy-loaded chart data with caching for 60% faster initial render on large tracks\n- Shortcode to embed anywhere with per-shortcode feature overrides\n- WP-CLI support for batch imports and automation\n- REST API + AJAX fallback with caching (2h weather cache)\n\n### Player UX\n\n- Dark splash overlay with Play; hidden immediately on any Play (map or controls)\n- User zoom/rotate allowed during playback\n- Click progress bar to seek; camera moves to the marker\n- Chart: vertical cursor + position dot; secondary speed line (km/h) on right axis\n- Optional top x‑axis shows distance (km) while primary x‑axis is time\n- Auto zoom‑out to full bounds at the end; default zoom restored on restart\n- Initial stopped view fits the full track; on Play, the map smoothly zooms in\n\n## Demo\n\n### Screenshots\n\n\u003cdiv align=\"center\" style=\"display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin: 20px 0;\"\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot1.jpg\" alt=\"Main interface with map and charts\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eMain interface with map and charts\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot2.jpg\" alt=\"Photos on map\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003ePhotos on map\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot3.jpg\" alt=\"Weather \u0026 Wind analysis\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eWeather \u0026 Wind analysis\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot4.jpg\" alt=\"Elevation highlighted on map\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eElevation highlighted on map\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot5.jpg\" alt=\"Weather overlay\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eWeather overlay\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot6.jpg\" alt=\"Weather overlay\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eAdmin Panel: Plugin settings\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv style=\"flex: 0 0 30%; min-width: 250px; margin-bottom: 20px;\"\u003e\n    \u003cimg src=\"demo/screenshot7.jpg\" alt=\"Weather overlay\" style=\"width: 100%; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\" /\u003e\n    \u003cp style=\"text-align: center; margin: 8px 0 0; color: #666; font-size: 0.9em;\"\u003eAdmin Panel: Track edit\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n### Demo Video\n[![Watch the demo video](demo/video1.jpg)](demo/video1.mp4)\n*Click the image above to watch the demo video (recorded with plugin internal functionality)*\n\n## Requirements\n\n- WordPress 6.0+\n- PHP 7.4+\n\n## Installation\n\n1. Copy the `flyover-gpx` directory into your WordPress `wp-content/plugins` folder.\n2. If developing from source, install dependencies:\n\n```bash\ncd wp-content/plugins/flyover-gpx\ncomposer install --no-interaction --no-dev\n```\n\n3. Activate the plugin in WordPress → Plugins.\n\n## Getting Started\n\n1. Go to Settings → Flyover GPX.\n2. Upload a `.gpx` file (≤ 20MB). The plugin parses it, computes stats, and creates a Track post.\n3. On the Tracks list, use “Copy Shortcode” to embed it in a page or post.\n4. Optionally open “Preview Map” to quickly verify the flyover.\n\n## Shortcode\n\nEmbed a track:\n\n```text\n[flyover_gpx id=\"123\"]\n```\n\nParameters:\n\n- `id` (required): The Track post ID.\n- `style` (optional): `raster` (default) or `vector`.\n- `height` (optional): Container height (e.g. `620px`, `60vh`). Default `620px`.\n- `zoom` (optional): Initial zoom level. Default is set in Settings → Flyover GPX.\n- `style_url` (optional): A MapLibre style URL when `style=\"vector\"`. Ignored if an inline style JSON is configured in settings.\n- `privacy` (optional): Override privacy mode for this embed. Accepts `true|false|1|0|yes|no|on|off`. Defaults to the admin setting.\n- `privacy_km` (optional): Override privacy distance in kilometers for this embed. Example: `privacy_km=\"3\"`. Defaults to the admin setting.\n- `hud` (optional): Toggle the live HUD overlay (speed/distance/elevation/heading). Accepts `true|false|1|0|yes|no|on|off`. Defaults to admin setting.\n- `elevation_coloring` (optional): Enable/disable elevation-based route coloring for this embed. Accepts `true|false|1|0|yes|no|on|off`. Defaults to admin setting.\n- `speed` (optional): Override default playback speed for this embed. Example: `speed=\"50\"`. Defaults to admin setting.\n- `gpx_download` (optional): Show/hide the GPX download button for this embed. Accepts `true|false|1|0|yes|no|on|off`. Defaults to admin setting.\n\nAdditional per-shortcode overrides (all optional, defaulting to admin settings):\n\n- Display \u0026 Elevation Coloring\n  - `show_labels`: `true|false` – show max elevation/speed labels on chart\n  - `elevation_color_flat`: hex color (e.g. `#00ff00`)\n  - `elevation_color_steep`: hex color (e.g. `#ff0000`)\n- Chart Colors\n  - `speed_chart_color`, `cadence_chart_color`, `temperature_chart_color`, `power_chart_color`\n  - `wind_impact_chart_color`, `wind_rose_chart_color`\n  - `wind_rose_color_north`, `wind_rose_color_south`, `wind_rose_color_east`, `wind_rose_color_west`\n- Features\n  - `photos_enabled`: `true|false`\n  - `weather_visible_by_default`: `true|false`\n  - `wind_analysis_enabled`: `true|false`\n  - `daynight_enabled`: `true|false` (chart visualization)\n  - `daynight_map_enabled`: `true|false` (map overlay)\n  - `daynight_visible_by_default`: `true|false`\n  - `daynight_map_color`: hex color (night overlay)\n\nExamples:\n\n```text\n[flyover_gpx id=\"123\" height=\"60vh\"]\n[flyover_gpx id=\"123\" style=\"vector\" style_url=\"https://demostyle.server/styles/outdoors/style.json\"]\n[flyover_gpx id=\"123\" privacy=\"true\" privacy_km=\"2.5\"]\n[flyover_gpx id=\"123\" hud=\"false\"]\n[flyover_gpx id=\"123\" elevation_coloring=\"true\" speed=\"75\"]\n[flyover_gpx id=\"123\" gpx_download=\"true\"]\n[flyover_gpx id=\"123\" show_labels=\"true\" speed_chart_color=\"#1976d2\" power_chart_color=\"#059669\"]\n[flyover_gpx id=\"123\" wind_analysis_enabled=\"true\" wind_impact_chart_color=\"#ff6b35\" wind_rose_chart_color=\"#4ecdc4\"]\n```\n\nNotes:\n\n- If a vector `style_url` fails to load, the player falls back to OSM raster tiles.\n- Multiple instances per page are supported. The first container uses `fgpx-app`, additional embeds use `fgpx-app-N`.\n- Disabling tile prefetching sets MapLibre’s `prefetchZoomDelta` to 0 and skips prewarm to minimize extra requests.\n\n### Inline Style JSON (Admin)\n\nYou can paste a complete MapLibre `style.json` into Settings → Flyover GPX → Shortcode Defaults → “Inline style JSON (optional)”.\n\n- If present, this inline style is used for all players and takes precedence over the `style_url` and raster default.\n- If blank, the player uses `style=\"vector\"` + `style_url=\"...\"` when provided; otherwise it falls back to OSM raster.\n\nExample minimal style JSON with OSM raster source (only for dev, does not provide all features):\n\n```json\n{\n  \"version\": 8,\n  \"name\": \"FGPX Raster Minimal\",\n  \"sources\": {\n    \"osm\": {\n      \"type\": \"raster\",\n      \"tiles\": [\"https://tile.openstreetmap.org/{z}/{x}/{y}.png\"],\n      \"tileSize\": 512,\n      \"minzoom\": 0,\n      \"maxzoom\": 18,\n      \"attribution\": \"© OpenStreetMap contributors\"\n    }\n  },\n  \"layers\": [\n    { \"id\": \"background\", \"type\": \"background\", \"paint\": { \"background-color\": \"#000\" } },\n    {\n      \"id\": \"osm\",\n      \"type\": \"raster\",\n      \"source\": \"osm\",\n      \"paint\": { \"raster-fade-duration\": 0 }\n    }\n  ]\n}\n```\n\nExample style for 3D terrain rendering and points of interrest (for all features):\n\n```json\n{\n  \"version\": 8,\n  \"glyphs\": \"https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=YOUR_KEY\",\n  \"sources\": {\n    \"terrain\": {\n      \"type\": \"raster-dem\",\n      \"url\": \"https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=YOUR_KEY\",\n      \"tileSize\": 512\n    },\n    \"satellite\": {\n      \"type\": \"raster\",\n      \"tiles\": [\n        \"https://api.maptiler.com/maps/satellite/{z}/{x}/{y}.jpg?key=YOUR_KEY\"\n      ],\n      \"tileSize\": 512,\n      \"minzoom\": 0,\n      \"maxzoom\": 20\n    },\n    \"openmaptiles\": {\n      \"type\": \"vector\",\n      \"url\": \"https://api.maptiler.com/tiles/v3/tiles.json?key=YOUR_KEY\"\n    }\n  },\n  \"layers\": [\n    {\n      \"id\": \"bg\",\n      \"type\": \"background\",\n      \"paint\": { \"background-color\": \"#000000\" }\n    },\n    {\n      \"id\": \"satellite\",\n      \"type\": \"raster\",\n      \"source\": \"satellite\",\n      \"minzoom\": 0,\n      \"maxzoom\": 20,\n      \"paint\": {\n        \"raster-fade-duration\": 350\n      }\n    },\n    {\n      \"id\": \"cycleways\",\n      \"type\": \"line\",\n      \"source\": \"openmaptiles\",\n      \"source-layer\": \"transportation\",\n      \"filter\": [\n        \"any\",\n        [\"==\", [\"get\", \"class\"], \"cycleway\"],\n        [\n          \"all\",\n          [\"==\", [\"get\", \"class\"], \"path\"],\n          [\"in\", [\"get\", \"bicycle\"], [\"literal\", [\"yes\", \"designated\", \"official\"]]]\n        ]\n      ],\n      \"layout\": {\n        \"line-cap\": \"round\",\n        \"line-join\": \"round\"\n      },\n      \"paint\": {\n        \"line-color\": \"#00c853\",\n        \"line-width\": 2,\n        \"line-blur\": 0.2\n      }\n    },\n    {\n      \"id\": \"place-labels\",\n      \"type\": \"symbol\",\n      \"source\": \"openmaptiles\",\n      \"source-layer\": \"place\",\n      \"layout\": {\n        \"text-field\": [\"get\", \"name\"],\n        \"text-font\": [\"Open Sans Bold\", \"Arial Unicode MS Bold\"],\n        \"text-size\": 14,\n        \"text-anchor\": \"center\",\n        \"text-allow-overlap\": false\n      },\n      \"paint\": {\n        \"text-color\": \"#ffffff\",\n        \"text-halo-color\": \"#000000\",\n        \"text-halo-width\": 1\n      }\n    },\n    {\n      \"id\": \"water-name-labels\",\n      \"type\": \"symbol\",\n      \"source\": \"openmaptiles\",\n      \"source-layer\": \"water_name\",\n      \"layout\": {\n        \"text-field\": [\"get\", \"name\"],\n        \"text-font\": [\"Open Sans Italic\", \"Arial Unicode MS Regular\"],\n        \"text-size\": 12,\n        \"symbol-placement\": \"line\",\n        \"text-allow-overlap\": false\n      },\n      \"paint\": {\n        \"text-color\": \"#4FC3F7\",\n        \"text-halo-color\": \"#000000\",\n        \"text-halo-width\": 0.5\n      }\n    }\n  ]\n}\n```\n\n## Low‑request styles (copy/paste into “Inline style JSON”)\n\nDownstripped raster style (fewest requests, no API key, no labels)\n- Single raster source (OSM), no glyphs/sprites/vector/DEM\n- 512px tiles and maxzoom 18 to reduce the number of tile requests\n- Best choice when you’re hitting MapTiler limits\n- Adds global DEM (Terrarium encoding) to enable 3D terrain without an API key\n- Limits DEM to maxzoom 12 and keeps 256px raster base to control request volume\n- Note: enabling terrain increases requests versus the minimal style\n\n```json\n{\n  \"version\": 8,\n  \"name\": \"FGPX Raster + Terrain (Terrarium)\",\n  \"sources\": {\n    \"osm\": {\n      \"type\": \"raster\",\n      \"tiles\": [\"https://tile.openstreetmap.org/{z}/{x}/{y}.png\"],\n      \"tileSize\": 512,\n      \"minzoom\": 0,\n      \"maxzoom\": 18,\n      \"attribution\": \"© OpenStreetMap contributors\"\n    },\n    \"terrain\": {\n      \"type\": \"raster-dem\",\n      \"tiles\": [\"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png\"],\n      \"encoding\": \"terrarium\",\n      \"tileSize\": 256,\n      \"minzoom\": 0,\n      \"maxzoom\": 12,\n      \"attribution\": \"© Mapzen, AWS Terrain Tiles\"\n    }\n  },\n  \"layers\": [\n    { \"id\": \"background\", \"type\": \"background\", \"paint\": { \"background-color\": \"#000\" } },\n    {\n      \"id\": \"osm\",\n      \"type\": \"raster\",\n      \"source\": \"osm\",\n      \"paint\": { \"raster-fade-duration\": 0 }\n    }\n  ],\n  \"terrain\": { \"source\": \"terrain\", \"exaggeration\": 1.0 }\n}\n```\n\nNotes\n- These styles intentionally remove labels/icons to eliminate glyph and sprite requests.\n- Using 512px raster tiles and capping maxzoom saves requests, especially at higher zooms.\n- If you need satellite, swap the `tiles` URL under `osm` with a satellite raster provider, but check usage terms/quotas.\n- For the fewest requests overall, use the “Raster Minimal” style and disable tile prefetching in the plugin settings.\n\n## REST API\n\n- Base: `/wp-json/fgpx/v1`\n- Endpoint: `GET /track/{id}`\n```json\n{\n  \"id\": 123,\n  \"name\": \"my-ride.gpx\",\n  \"stats\": {\n    \"total_distance_m\": 42195.3,\n    \"moving_time_s\": 10800,\n    \"average_speed_m_s\": 3.9,\n    \"elevation_gain_m\": 520,\n    \"min_elevation_m\": 120,\n    \"max_elevation_m\": 980\n  },\n  \"geojson\": {\n    \"type\": \"LineString\",\n    \"coordinates\": [ [lon, lat, ele], ... ],\n    \"properties\": {\n      \"timestamps\": [\"2024-02-01T10:00:00Z\", null, ...],\n      \"cumulativeDistance\": [0, 12.3, ...],\n      \"heartRates\": [152, 154, null, ...],\n      \"cadences\": [88, 86, null, ...],\n      \"temperatures\": [21.4, 21.6, 21.5, ...],\n      \"powers\": [210, 215, 205, ...],\n      \"windSpeeds\": [5.2, 4.8, 5.0, ...],\n      \"windDirections\": [220, 225, 230, ...],\n      \"windImpacts\": [0.92, 1.05, 1.02, ...]\n    }\n  },\n  \"bounds\": [minLon, minLat, maxLon, maxLat],\n  \"points_count\": 12345,\n  \"simplified\": true,\n  \"photos\": [\n    {\n      \"id\": 49785,\n      \"title\": \"IMG_20250824_112847a\",\n      \"caption\": \"Carolinen Hütte\",\n      \"description\": \"Die Carolinen Hütte bei Rohrbach\",\n      \"lat\": 49.000894,\n      \"lon\": 11.381095,\n      \"timestamp\": \"2025-08-24T11:28:47+00:00\",\n      \"thumbUrl\": \"https://.../IMG_2025...-225x300.jpg\",\n      \"fullUrl\": \"https://.../IMG_2025...-768x1024.jpg\"\n    }\n  ]\n}\n```\n\n## Privacy Mode\n\n- Enable in Settings → Flyover GPX → “Enable privacy mode”.\n- Configure “Privacy distance (km)” (default 3). Playback will start after the first N km and finish N km before the end.\n- The map camera, progress line, chart cursor, photo cues, and weather overlays all respect the trimmed window. Stats (distance, time, avg speed, gain) remain computed from the full GPX.\n- Shortcode/CLI can override privacy enablement and distance on a per-embed basis.\n\n## Video Recording\n\nThe plugin includes built-in video recording capabilities to create MP4/WebM videos of your flyover animations:\n\n- **Record Button**: Available in the player controls during playback\n- **Format Support**: Automatically detects and uses the best supported format (MP4 H.264, WebM VP9, or WebM VP8)\n- **Image Overlay**: Photos and markers are included in the recorded video\n- **Customizable Settings**: Recording quality and frame rate can be configured\n- **Download**: Completed videos are automatically downloaded to your device\n\nTo record a video:\n1. Start playback of your GPX track\n2. Click the record button in the player controls\n3. The video will capture the entire flyover animation\n4. Download begins automatically when recording completes\n\nNotes:\n\n- Recording includes map, route, HUD, chart cursor, and active overlays (photos/weather/day-night)\n- Requires a modern browser with MediaRecorder API; codec availability varies by browser/OS\n\n## WP‑CLI\n\nImport GPX Files (creates a Track; optionally inserts a shortcode into an existing post and publishes it):\n\n```bash\nwp fgpx import --file=/abs/path/ride.gpx [options]\n```\n\n**Options:**\n\n```bash\n--file=\u003cpath\u003e                         # required, absolute path to GPX file\n--post=\u003cid\u003e                           # post ID to embed shortcode into\n--title=\u003cstring\u003e                      # optional track title (defaults to filename)\n--privacy=\u003con|off\u003e                    # privacy mode toggle\n--privacy-km=\u003cfloat\u003e                  # privacy distance in km\n--hud=\u003con|off\u003e                        # HUD overlay toggle\n--elevation-coloring=\u003con|off\u003e         # elevation-based coloring toggle\n--speed=\u003cint\u003e                         # default playback speed\n--show-labels=\u003con|off\u003e                # show max elev/speed labels\n--elevation-color-flat=\u003chex\u003e          # flat terrain color\n--elevation-color-steep=\u003chex\u003e         # steep terrain color\n--speed-chart-color=\u003chex\u003e             # speed chart color\n--cadence-chart-color=\u003chex\u003e           # cadence chart color\n--temperature-chart-color=\u003chex\u003e       # temperature chart color\n--power-chart-color=\u003chex\u003e             # power chart color\n--wind-impact-chart-color=\u003chex\u003e       # wind impact chart color\n--wind-rose-chart-color=\u003chex\u003e         # wind rose chart color (default)\n--wind-rose-color-north=\u003chex\u003e         # wind rose north color\n--wind-rose-color-south=\u003chex\u003e         # wind rose south color\n--wind-rose-color-east=\u003chex\u003e          # wind rose east color\n--wind-rose-color-west=\u003chex\u003e          # wind rose west color\n--photos-enabled=\u003con|off\u003e             # enable photo thumbnails/overlay\n--weather-visible-by-default=\u003con|off\u003e # weather buttons visibility at load\n--wind-analysis-enabled=\u003con|off\u003e      # enable wind impact analysis\n--daynight-enabled=\u003con|off\u003e           # enable day/night chart visualization\n--daynight-map-enabled=\u003con|off\u003e       # enable day/night map overlay\n--daynight-visible-by-default=\u003con|off\u003e# default visibility for day/night overlay\n--daynight-map-color=\u003chex\u003e            # night overlay color\n--publish                              # publish the target post after shortcode insertion\n```\n\n**Examples:**\n\n```bash\n# Simple import\nwp fgpx import --file=/uploads/ride.gpx\n\n# Import with shortcode insertion and common toggles\nwp fgpx import --file=/uploads/ride.gpx --post=123 --publish \\\n  --title=\"Mountain Ride\" --privacy=on --privacy-km=3 --hud=on --elevation-coloring=on --speed=75\n\n# Customize visuals and features per-embed\nwp fgpx import --file=/uploads/ride.gpx --post=123 \\\n  --show-labels=on --speed-chart-color=\"#1976d2\" --power-chart-color=\"#059669\" \\\n  --photos-enabled=on --weather-visible-by-default=on --daynight-enabled=on --daynight-map-color=\"#000080\"\n\n# Wind analysis focused\nwp fgpx import --file=/uploads/ride.gpx --post=123 \\\n  --wind-analysis-enabled=on --wind-impact-chart-color=\"#ff6b35\" --wind-rose-chart-color=\"#4ecdc4\"\n```\n\n## Theming\n\n- Minimal CSS in `flyover-gpx/assets/css/front.css` with variables like `--fgpx-border`, `--fgpx-card-bg` for light/dark.\n- The player respects `prefers-color-scheme` and adapts colors accordingly.\n\n## Development\n\n- Source code uses a small PHP core and a single front‑end JS (`assets/js/front.js`).\n- PHP GPX parsing via `sibyxs/phpgpx` (declared in `composer.json`).\n- Autoloading is PSR‑4 (`FGpx\\\\` → `includes/`). If `vendor/autoload.php` is missing, the plugin shows an admin notice to run Composer.\n- Debug logging systems: JavaScript (`DBG`) respects `FGPX.debugLogging`; PHP uses `ErrorHandler::debug()`/`warning()` with admin toggle\n- Performance settings: backend simplification enabled by default with dynamic target; lazy viewport loading; prefetch toggle; asset fallback detection\n- Frontend caching: localStorage cache for processed track data with automatic expiry and safe fallback\n\nBuild/Install locally:\n\n```bash\ncomposer install\n```\n\nFolder layout:\n\n```text\nflyover-gpx/\n  flyover-gpx.php\n  includes/\n    Options.php\n    ErrorHandler.php\n    AssetManager.php\n    DatabaseOptimizer.php\n    Plugin.php\n    Rest.php\n    Admin.php\n    CLI.php\n  assets/\n    css/front.css\n    js/front.js\n  composer.json\n```\n\n## Limitations \u0026 Notes\n\n- One player instance per page (container id is fixed to `fgpx-app`).\n- Upload limit: 20MB per GPX file.\n- Large tracks are simplified on the backend by default; dynamic targets avoid over/under‑simplification.\n- Local caching is best‑effort and expires automatically; the player gracefully falls back to live fetch.\n- Weather data is cached server‑side (≈2h) to limit API calls.\n- Chart zoom is unavailable for polar charts (wind rose) by design.\n- Video recording requires a modern browser with MediaRecorder API support.\n\n## Known Bugs\n\n## Note\n\nThis plugin was developed with the help of AI coding tools.\n\n## License\n\nMIT. See `LICENSE` if provided; otherwise, embed licensing details as appropriate for your project.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbebablub%2Fwp-flyover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbebablub%2Fwp-flyover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbebablub%2Fwp-flyover/lists"}