Add zoom-aware symbology, fix globe popovers, expand geo coverage (#34)

* Add zoom-aware symbology, fix globe popovers, expand geo coverage

Map rendering improvements based on user feedback:
- Globe markers now scale with camera altitude (onZoom hook)
- Priority-based visibility culls low-priority markers at world view
- Globe popovers use getScreenCoords for accurate positioning
- Flat map labels hidden at low zoom, revealed progressively
- Default globe altitude lowered from 2.5 to 1.8 for better fill
- Americas region zoom tightened to CONUS focus

Geographic coverage expansion:
- 4 new OpenSky air theaters: Caribbean, Gulf of Guinea, Cape Route, Horn of Africa
- Flight corridors now span Americas and Africa
- NOAA alerts extract centroid lat/lon from GeoJSON geometry
- EPA RadNet stations geocoded with hardcoded coords for 10 US cities
- ISS + Tiangong positions estimated from TLE orbital elements
- GDELT geoEvents() now called in briefing for mapped event points
- New legend entries: Weather Alert, EPA RadNet, Space Station, GDELT Event

* Fix null-safe coordinate checks and remove injected data blob

- Use `!= null` instead of truthy checks for lat/lon in noaa.mjs
  and inject.mjs so valid 0-coordinates (equator/prime meridian)
  are not silently dropped
- Reset jarvis.html `let D` back to null placeholder so generated
  runtime data is not part of the PR diff

* Remove re-injected data blob from jarvis.html

Reset let D back to null — previous commit was correct but
inject.mjs build verification re-injected the payload.
This commit is contained in:
calesthio
2026-03-17 19:34:08 -07:00
committed by GitHub
parent d63c69bb05
commit a8682c50d0
6 changed files with 234 additions and 58 deletions

View File

@@ -104,11 +104,26 @@ export async function briefing() {
keywords.some(k => a.title?.toLowerCase().includes(k))
);
// Geo events — get mapped event locations (separate API, respects rate limit)
await delay(5500);
let geoPoints = [];
try {
const geo = await geoEvents('conflict OR military OR protest OR crisis', { maxPoints: 30, timespan: '24h' });
geoPoints = (geo?.features || []).filter(f => f.geometry?.coordinates).map(f => ({
lat: f.geometry.coordinates[1],
lon: f.geometry.coordinates[0],
name: f.properties?.name || f.properties?.html || '',
count: f.properties?.count || 1,
type: f.properties?.type || 'event',
}));
} catch (e) { /* geo endpoint optional — don't break briefing */ }
return {
source: 'GDELT',
timestamp: new Date().toISOString(),
totalArticles: articles.length,
allArticles: articles,
geoPoints,
conflicts: categorize(['military', 'conflict', 'war', 'strike', 'missile', 'attack', 'bomb', 'troops']),
economy: categorize(['economy', 'recession', 'inflation', 'market', 'sanctions', 'tariff', 'trade', 'gdp']),
health: categorize(['pandemic', 'outbreak', 'epidemic', 'disease', 'virus', 'health']),