NOTICE: We have updated our Contact Us page.

Ohio Traffic Cameras:

Columbus

An issue has been identified with our site’s caching web pages, and the images are not updating. We do not have an estimated timeframe for when the website will be back up.

HTML
 
<!-- Live Weather Radar Widget Container -->
<div class="radar-widget-container">
  <div id="radar-map"></div>
  <div class="radar-controls">
    <button id="play-pause-btn" class="radar-btn">Pause</button>
    <div id="radar-timestamp" class="radar-time">Loading Live Radar...</div>
  </div>
</div>

<!-- Leaflet Map CSS & JS Dependencies -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

<style>
  .radar-widget-container {
    width: 100%;
    max-width: 800px;
    font-family: system-ui, -apple-system, sans-serif;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
    background: #1e1e1e;
    margin: 0 auto;
  }
  #radar-map {
    height: 450px;
    width: 100%;
  }
  .radar-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 18px;
    background: #2a2a2a;
    color: #ffffff;
  }
  .radar-btn {
    background: #007bff;
    color: #ffffff;
    border: none;
    padding: 8px 18px;
    border-radius: 6px;
    cursor: pointer;
    font-weight: 600;
    transition: background 0.2s ease;
  }
  .radar-btn:hover {
    background: #0056b3;
  }
  .radar-time {
    font-size: 0.9rem;
    color: #cccccc;
  }
</style>

<script>
  // 1. Initialize map view: [Latitude, Longitude], Zoom level (1-18)
  // Default centered over North America: [39.8283, -98.5795], Zoom: 4
  const map = L.map('radar-map').setView([39.8283, -98.5795], 4);

  // 2. Add base map tiles (OpenStreetMap)
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
  }).addTo(map);

  let radarLayers = [];
  let timestamps = [];
  let currentIndex = 0;
  let intervalId = null;

  // 3. Fetch real-time Doppler radar tile frames
  fetch('https://api.rainviewer.com/public/weather-maps.json')
    .then(res => res.json())
    .then(data => {
      // Extract historical and current forecast timestamps
      timestamps = data.radar.past.map(item => item.time);
      if (data.radar.nowcast) {
        timestamps.push(...data.radar.nowcast.map(item => item.time));
      }

      // Preload tile layers for smooth animation
      timestamps.forEach(time => {
        const layer = L.tileLayer(`https://tilecache.rainviewer.com/v2/radar/${time}/256/{z}/{x}/{y}/2/1_1.png`, {
          opacity: 0,
          tileSize: 256,
          attribution: '&copy; <a href="https://www.rainviewer.com">RainViewer</a>'
        });
        radarLayers.push(layer);
        layer.addTo(map);
      });

      showFrame(timestamps.length - 1);
      startAnimation();
    })
    .catch(err => console.error("Error loading radar data:", err));

  function showFrame(index) {
    radarLayers.forEach((layer, i) => {
      layer.setOpacity(i === index ? 0.75 : 0);
    });

    const date = new Date(timestamps[index] * 1000);
    document.getElementById('radar-timestamp').innerText = `Radar Time: ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
    currentIndex = index;
  }

  function startAnimation() {
    if (intervalId) clearInterval(intervalId);
    intervalId = setInterval(() => {
      currentIndex = (currentIndex + 1) % timestamps.length;
      showFrame(currentIndex);
    }, 700);
  }

  // Play/Pause Control toggle
  const btn = document.getElementById('play-pause-btn');
  btn.addEventListener('click', () => {
    if (intervalId) {
      clearInterval(intervalId);
      intervalId = null;
      btn.innerText = 'Play';
    } else {
      startAnimation();
      btn.innerText = 'Pause';
    }
  });
</script>