Windy Community
    • Unread
    • Categories
    • Groups
    • Go to windy.com
    • Register
    • Login

    Philippines Radar Are Unavaliable

    Scheduled Pinned Locked Moved Bug Reports
    2 Posts 2 Posters 68 Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N Offline
      niubowen
      last edited by

      1000016168.jpg
      Philippines's radar image are Unavaliable since 4am today,and I noticed that a new radar api had been
      seen in panahon'site(include Reflectivity and Mosaic-qpe),it looks that old radar api are unavaliable
      (The code is rebuild by AI,original code from beta.js)

      /**
       * PANaHON 雷达 API 调用模块
       * 基础地址: https://www.panahon.gov.ph
       * 适用于产品: mosaic-qpe, hybrid-reflectivity, rainfall_estimate
       */
      
      const API_BASE = 'https://www.panahon.gov.ph';
      
      // 辅助函数:从 cookie 中获取 XSRF-TOKEN(前端环境)
      function getCsrfToken() {
          const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
          return match ? decodeURIComponent(match[1]) : '';
      }
      
      // 通用请求方法
      async function request(endpoint, options = {}) {
          const url = endpoint.startsWith('http') ? endpoint : API_BASE + endpoint;
          const res = await fetch(url, {
              credentials: 'include', // 携带 cookie
              ...options
          });
          if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
          return res.json();
      }
      
      /**
       * 1. 获取雷达时间线(所有帧的 URL 和时间戳)
       * @param {string} product - 产品名: 'mosaic-qpe' | 'hybrid-reflectivity' | 'rainfall_estimate'
       * @returns {Promise}
       */
      async function getRadarTimeline(product) {
          const data = await request(`/api/v1/radar/timeline?sublayer=${product}`);
          if (!data.success || !data.data) throw new Error('Invalid timeline response');
          const urls = data.data.image_urls;
          const obsDates = data.data.observation_dates;
          const stamps = Object.keys(obsDates).map(k => parseInt(k)).sort((a,b) => a-b);
          if (urls.length !== stamps.length) throw new Error('Mismatch between URLs and timestamps');
          return { imageUrls: urls, timeStamps: stamps };
      }
      
      /**
       * 2. 获取单帧雷达图像的 URL(通过 index)
       * @param {string} product - 产品名
       * @param {number} index - 帧索引(从 0 开始,与 timeline 返回的顺序一致)
       * @param {string} token - CSRF token(可选,若不传则自动从 cookie 读取)
       * @returns {string} 图像 URL
       */
      function getRadarImageUrl(product, index, token = null) {
          const csrf = token || getCsrfToken();
          const url = `${API_BASE}/api/v1/radar-image?token=${csrf}&sublayer=${product}&index=${index}&_=${Date.now()}`;
          return url;
      }
      
      /**
       * 3. 查询指定坐标点的雷达数值(降水量或反射率)
       * @param {number} lng - 经度
       * @param {number} lat - 纬度
       * @param {string} product - 产品名
       * @param {number} index - 帧索引
       * @param {string} token - CSRF token(可选)
       * @returns {Promise} 数值,若无效返回 null
       */
      async function getRadarPointValue(lng, lat, product, index, token = null) {
          const csrf = token || getCsrfToken();
          const url = `/api/v1/radar-image/point?sublayer=${product}&lon=${lng}&lat=${lat}&v=1&index=${index}&token=${csrf}`;
          const data = await request(url);
          if (data && data.values && data.values[0] < 9999) {
              let val = data.values[0];
              if (product === 'mosaic-qpe' || product === 'rainfall_estimate') {
                  return parseFloat(val.toFixed(1));
              } else {
                  return Math.round(val);
              }
          }
          return null;
      }
      
      /**
       * 4. 预加载所有帧图像(返回 Image 对象数组)
       * @param {string} product - 产品名
       * @param {string[]} imageUrls - 从 getRadarTimeline 获得的 URL 列表(可选,若不传则自动获取)
       * @param {Function} onProgress - 进度回调 (loaded, total)
       * @returns {Promise}
       */
      async function preloadAllFrames(product, imageUrls = null, onProgress = null) {
          let urls = imageUrls;
          if (!urls) {
              const timeline = await getRadarTimeline(product);
              urls = timeline.imageUrls;
          }
          const images = new Array(urls.length);
          for (let i = 0; i < urls.length; i++) {
              const img = new Image();
              await new Promise((resolve, reject) => {
                  img.onload = () => { images[i] = img; resolve(); };
                  img.onerror = () => reject(new Error(`Failed to load frame ${i}`));
                  img.src = getRadarImageUrl(product, i);
              });
              if (onProgress) onProgress(i + 1, urls.length);
          }
          return images;
      }
      
      // ================= 使用示例 =================
      (async () => {
          try {
              // 示例1:获取降水产品时间线
              const timeline = await getRadarTimeline('mosaic-qpe');
              console.log(`共 ${timeline.imageUrls.length} 帧,最新时间: ${new Date(timeline.timeStamps.at(-1) * 1000)}`);
              
              // 示例2:查询某一点在最新帧上的降水量
              const latestIndex = timeline.imageUrls.length - 1;
              const value = await getRadarPointValue(121.77, 12.88, 'mosaic-qpe', latestIndex);
              console.log(`马尼拉附近降水量: ${value} mm/hr`);
              
              // 示例3:预加载所有帧(显示进度)
              await preloadAllFrames('hybrid-reflectivity', null, (loaded, total) => {
                  console.log(`预加载进度: ${loaded}/${total}`);
              });
          } catch (err) {
              console.error('API 调用失败:', err);
          }
      })();
      
      
      SutyS 1 Reply Last reply Reply Quote 0
      • SutyS Offline
        Suty Windy Staff @niubowen
        last edited by

        @niubowen Hello, do you still have an issue with displaying data over Philippines?

        1 Reply Last reply Reply Quote 0
        • First post
          Last post
        Windy Community  |  Powered by excellent NodeBB
        Terms of Use     Privacy Policy     Windy.com