跳到主要内容

全球风向

示例

结果
Loading...
实时编辑器
function render(props) {
  const container = useRef(null);

  const dataUrl = useBaseUrl('/json/wind.json');

  const initChat = (map, option) => {
    const chart = new EChartsLayer(option, {
      stopEvent: false,
      hideOnMoving: false,
      hideOnZooming: false,
      forcedPrecomposeRerender: true,
    });

    chart.appendTo(map);
  }

  const init = async () => {
    const map = new ol.Map({
      target: container.current,
      view: new ol.View({
        projection: 'EPSG:4326',
        zoom: 5,
        rotation: 0,
        center: [113.53450137499999, 34.44104525],
      }),
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
          }),
        }),
      ],
    });

    const windData = await fetch(dataUrl).then(res => res.json());

    const data = [];
    let p = 0;
    let maxMag = 0;
    let minMag = Infinity;
    for (let j = 0; j < windData.ny; j++) {
      for (let i = 0; i < windData.nx; i++, p++) {
        const vx = windData.data[p][0];
        const vy = windData.data[p][1];
        const mag = Math.sqrt(vx * vx + vy * vy);
        // 数据是一个一维数组
        // [ [经度, 维度,向量经度方向的值,向量维度方向的值] ]
        data.push([
          i / windData.nx * 360 - 180,
          j / windData.ny * 180 - 90,
          vx,
          vy,
          mag
        ]);
        maxMag = Math.max(mag, maxMag);
        minMag = Math.min(mag, minMag);
      }
    }

    const option = {
      title: {
        text: '风场',
        left: 'center',
        top: 'top',
        textStyle: {
          color: '#fff'
        }
      },
      visualMap: {
        left: 'left',
        min: minMag,
        max: maxMag,
        dimension: 4,
        inRange: {
          // color: ['green', 'yellow', 'red']
          color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
        },
        realtime: false,
        calculable: true,
        textStyle: {
          color: '#fff'
        }
      },
      series: [
        {
          type: 'flowGL',
          data: data,
          particleDensity: 64,
          particleSpeed: 2,
          particleSize: 1,
          gridWidth: windData.nx,
          gridHeight: windData.ny,
          itemStyle: {
            opacity: 0.7
          }
        }
      ]
    };

    initChat(map, option);

    function resize(target) {}

    return {
      resize,
    }
  }

  useEffect(() => {
    const { resize } = init();

    return () => {
    };
  }, []);

  return (
    <div className="live-wrap">
      <div ref={container} className="map-content" />
    </div>
  );
}