EARTHWATCH
LIVE
GLOBAL
Starting…

LAYERS

ALERT CENTRE
SAVE MAP LOCATION
ALERT SIMULATION
Exercises saved-location state, history, sound and browser notifications. It does not create a map hazard or modify live feeds.
MONITORED LOCATION
HISTORICAL REPLAY • LIVE HAZARDS HIDDEN • NOT LIVE
HISTORICAL EVENT LIBRARY
Historical replay library. Live hazards are hidden during replay. Track/impact detail is limited to the observations represented in this data pack.
Ready
INCIDENT ANALYSIS
GLOBAL • ACTIVE WARNINGS
Basemap + labels: OpenFreeMap / OpenStreetMap • Hazards: EarthWatch
TornadoSevere stormWatchLocationGGDACS disaster
Z 2.0
AUTO DECLUTTER • detail increases as you zoom
Wheel: zoom • Drag: pan • Click/touch any warning, track, earthquake or global event for details • QUAKES: USGS • FIRES: NASA FIRMS • EVENTS / ICEBERGS: NASA EONET • TSUNAMI: NOAA • CYCLONES: ATCF / GDACS
STORM ANALYSIS
Storm positions and motion are derived from official warning metadata where supplied. NWS motion bearings are FROM bearings; StormWatch reverses them 180° to draw the projected direction of travel. EarthWatch uses official warning and storm-motion metadata for severe-weather structure. ROTATION markers use authoritative NWS warning metadata (including tornadoDetection / tornadoDamageThreat) where supplied; they are not raw radar-derived mesocyclone detections. Track cones show 30/60-minute extrapolation from supplied storm motion.
ADD LOCATION
Search is used only when you press SEARCH. Search uses OpenStreetMap geocoding. Photon is tried first with Nominatim fallback.
MAJOR EVENT
STARTING EARTHWATCH…
● LIVEVIEW GLOBALZOOM --EVENTS --LOCATIONS --
WEATHERFIREQUAKEVOLCANOCYCLONE
EW 7.37.2
/* EarthWatch v7.23.1 — corrected native RainViewer radar Radar is rendered ONLY as a native MapLibre XYZ raster source. The RainViewer coverage-mask raster from v7.23.1 is intentionally not rendered: its opaque no-coverage tiles were the rectangular blocks visible in the map and made the radar appear geographically detached even though the radar XYZ tiles were native. */ (function(){ const RADAR_SRC='ew7231-radar', RADAR_LAYER='ew7231-radar-layer'; const OLD_LAYERS=['ew7230-radar-layer','ew7230-radar-coverage-layer']; const OLD_SOURCES=['ew7230-radar','ew7230-radar-coverage']; let meta=null, frame=null, metaAt=0, busy=false, timer=0, generation=''; function status(t,c){const e=document.getElementById('radarStatus');if(e){e.textContent=t;e.style.color=c||'#aeb9c8'}} function legacyOff(){ const old=document.getElementById('rainviewerTiles');if(old){old.replaceChildren();old.style.display='none'} ['radarA','radarB'].forEach(id=>{const e=document.getElementById(id);if(e)e.style.display='none'}); const rl=document.getElementById('radarLayer');if(rl)rl.style.display='none'; } async function getMeta(force){ if(!force&&meta&&Date.now()-metaAt<300000)return meta; if(busy)return meta;busy=true; try{const r=await fetch('/api/rainviewer/meta',{cache:'no-store'});if(!r.ok)throw Error('HTTP '+r.status);const j=await r.json(),a=j&&j.radar&&j.radar.past||[];if(!a.length)throw Error('no radar frames');meta=j;frame=a[a.length-1];metaAt=Date.now();return meta}finally{busy=false} } function removeLayer(id){try{if(ewML.getLayer(id))ewML.removeLayer(id)}catch(_){} } function removeSource(id){try{if(ewML.getSource(id))ewML.removeSource(id)}catch(_){} } function purgeOld(){if(!window.ewML)return;OLD_LAYERS.forEach(removeLayer);OLD_SOURCES.forEach(removeSource)} function removeNative(){if(!window.ewML)return;removeLayer(RADAR_LAYER);removeSource(RADAR_SRC);generation=''} function firstOperationalLayer(){ const style=ewML.getStyle(), layers=(style&&style.layers)||[]; // Keep radar above the cartographic base but below EarthWatch operational overlays. const hit=layers.find(l=>/^ew-(?:warning|alert|event|fire|cyclone|quake|tsunami)|^ew7/i.test(String(l.id||''))); return hit&&hit.id; } function addNative(){ if(!window.ewML||!ewML.isStyleLoaded()||!meta||!frame)return false; const g=String(frame.time)+'|'+frame.path; if(generation===g&&ewML.getLayer(RADAR_LAYER))return true; removeNative();purgeOld(); // RainViewer documents this exact XYZ template. MapLibre uses XYZ by default. const radarUrl=meta.host+frame.path+'/256/{z}/{x}/{y}/2/1_1.png'; ewML.addSource(RADAR_SRC,{type:'raster',tiles:[radarUrl],tileSize:256,minzoom:0,maxzoom:7,scheme:'xyz',attribution:'Weather data by RainViewer'}); const before=firstOperationalLayer(); ewML.addLayer({id:RADAR_LAYER,type:'raster',source:RADAR_SRC,paint:{ 'raster-opacity':Number(radarState.opacity||.78), 'raster-fade-duration':0, 'raster-resampling':'linear' }},before); generation=g;return true; } function visibility(on){if(!window.ewML)return;try{if(ewML.getLayer(RADAR_LAYER))ewML.setLayoutProperty(RADAR_LAYER,'visibility',on?'visible':'none')}catch(_){}} async function nativeUpdate(force){ const rs=document.getElementById('radarStatus'),rb=document.getElementById('radarBtn'),rc=document.getElementById('radarControls'); legacyOff();purgeOld();clearTimeout(timer); if(!state.radar){visibility(false);if(rs)rs.style.display='none';if(rc)rc.style.display='none';if(rb)rb.textContent='RADAR OFF';return} if(rb)rb.textContent='RADAR ON';if(rs)rs.style.display='block';if(rc)rc.style.display='block';status('RADAR • GLOBAL • LOADING…','#ffd166'); try{await getMeta(!!force);if(!meta||!frame)throw Error('no frame');if(!addNative())throw Error('map style not ready');visibility(true);const age=Math.max(0,Math.round((Date.now()/1000-frame.time)/60));status('RADAR • '+(age<1?'LATEST':age+' MIN OLD')+' • MAP-LOCKED','#55e28a')} catch(e){status('RADAR • UNAVAILABLE','#ff4d6d');const er=document.getElementById('errors');if(er)er.textContent='RainViewer radar: '+e.message} timer=setTimeout(()=>{if(state.radar)nativeUpdate(true)},300000); } updateRadar=nativeUpdate;renderRainViewerTiles=function(){return nativeUpdate(false)};radarCoverageAvailable=function(){return true}; const op=document.getElementById('radarOpacity');if(op)op.addEventListener('input',function(){radarState.opacity=Number(this.value)/100;try{if(ewML.getLayer(RADAR_LAYER))ewML.setPaintProperty(RADAR_LAYER,'raster-opacity',radarState.opacity)}catch(_){}}); function restore(){purgeOld();if(state.radar){generation='';nativeUpdate(false)}} if(window.ewML){ewML.on('load',restore);ewML.on('styledata',function(){purgeOld();if(state.radar&&!ewML.getLayer(RADAR_LAYER))setTimeout(restore,0)})} window.earthWatchRadarDiagnostics=function(){return{version:'7.23.1',native:true,xyz:true,frame:frame&&frame.time,ageMinutes:frame?Math.max(0,Math.round((Date.now()/1000-frame.time)/60)):null,radarLayer:!!(window.ewML&&ewML.getLayer(RADAR_LAYER)),coverageMaskRendered:false,legacyDomHidden:true,maxNativeZoom:7,mapCenter:window.ewML?ewML.getCenter():null,mapZoom:window.ewML?ewML.getZoom():null}}; })(); \n \n \n\n \n