Skip to Content

镜像地球开放平台

图片方式接入

通过图片方式将气象图层接入到 WebGIS 项目中,支持 React 和 Vue 示例,包含温度图层、雷达图及点击取值功能。

通过图片方式加载气象图层是最基础、也是接入门槛最低的方式。本指南将展示如何使用 Leaflet 在 React 和 Vue 项目中加载图层。

1. 业务流程

图片图层是通过单张带有地理范围的图片(Image Overlay)形式提供。在拼接图片 URL 之前,我们需要先获取最新的数据时间(time)。

  1. 获取时间:调用 meta 接口获取对应模型的可用时间列表,并取最新起报时间。
  2. 拼接 URL:将 timemodelelement_level 组合,生成单张图片 URL。格式如:https://api.mirror-earth.com/api/vis/part/{model}/{element}/{time}.webp?apikey={apikey}
    • 关于投影:图片默认是以墨卡托投影(EPSG
      )返回(即接口自身默认 tms=3857)。如果您使用的底层地图为 WGS84 等距圆柱投影(EPSG
      ),可以直接在 URL 的 query 传参中加入 tms=4326 以返回匹配的地图图片。
  3. 加载到地图:指定对应模型和要素的地理范围(Bounds),使用 Leaflet 的 L.imageOverlay 将该 URL 叠加到地图上。
  4. 点击取值:根据点击位置的经纬度,调用取值 API 获取该点的具体气象数据。

2. 示例应用 (Playground)

下面的代码示例展示了如何在项目中通过 Leaflet 加载图层(以 HRES 的温度图层、雷达图为例),并实现点击取值功能。

import React, { useEffect, useRef, useState } from 'react';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';

const API_KEY = 'YOUR_API_KEY';

// 获取对应模型可用时间列表的最新时间
const fetchTime = async (model: string) => {
  const metaUrl = `https://api.mirror-earth.com/api/vis/${model}/meta?apikey=${API_KEY}&timezone=Asia/Shanghai`;
  const response = await fetch(metaUrl);
  const result = await response.json();
  // 取列表中的第一个(最新时间)
  return result.data[0];
};

const MapComponent = () => {
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstance = useRef<L.Map | null>(null);
  const [clickedValue, setClickedValue] = useState<string | null>(null);        

  useEffect(() => {
    if (!mapRef.current || mapInstance.current) return;

    // 初始化地图
    const map = L.map(mapRef.current).setView([35.0, 105.0], 4);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    mapInstance.current = map;

    const loadLayers = async () => {
      // --- HRES 温度图层接入 ---
      const hresTime = await fetchTime('hres');
      
      // HRES 覆盖中日韩区域的 bbox,格式为 [[南, 西], [北, 东]]
      const hresBounds: L.LatLngBoundsExpression = [
        [14.9587, 69.9588], 
        [55.0412, 140.0799] // 参考 1-quickstart 的 hres 覆盖范围
      ];
      const tempUrl = `https://api.mirror-earth.com/api/vis/part/hres/temperature_2m/${hresTime}.webp?apikey=${API_KEY}&timezone=Asia/Shanghai`;
      const tempLayer = L.imageOverlay(tempUrl, hresBounds, { opacity: 0.7 });
      tempLayer.addTo(map);

      // --- 雷达图层接入 ---
      const radarTime = await fetchTime('radar');
      
      // 雷达覆盖范围的 bbox
      const radarBounds: L.LatLngBoundsExpression = [
        [15.5201, 71.965], 
        [54.0081, 148.7043] // 参考 1-quickstart 的 radar 覆盖范围
      ];
      const radarUrl = `https://api.mirror-earth.com/api/vis/part/radar/composite_reflectivity/${radarTime}.webp?apikey=${API_KEY}&timezone=Asia/Shanghai`;
      const radarLayer = L.imageOverlay(radarUrl, radarBounds, { opacity: 0.7 });
      
      // 可选:将雷达图也可以添加到地图上
      // radarLayer.addTo(map);
    };

    loadLayers();

    // 点击取值
    map.on('click', async (e) => {
      const { lat, lng } = e.latlng;
      // 调用单点取值接口获取气象数据
      const valueApiUrl = `https://api.mirror-earth.com/v1/point/hres/temperature_2m?lat=${lat}&lon=${lng}&apikey=${API_KEY}`;
      try {
        const response = await fetch(valueApiUrl);
        const data = await response.json();
        setClickedValue(`坐标: ${lat.toFixed(2)}, ${lng.toFixed(2)} | 温度: ${data.value}℃`);
      } catch (err) {
        setClickedValue('获取数据失败');
      }
    });

    return () => {
      map.remove();
      mapInstance.current = null;
    };
  }, []);

  return (
    <div>
      <div ref={mapRef} style={{ width: '100%', height: '500px' }} />
      {clickedValue && (
        <div style={{ marginTop: '10px', padding: '10px', background: '#f0f0f0', borderRadius: '4px' }}>
          点击结果: {clickedValue}
        </div>
      )}
    </div>
  );
};

export default MapComponent;

Previous

快速开始

Next

WebGL方式接入