Newer
Older
ganzhou-feidu / src / utils / freedo / heat.js
wangxitong on 11 Sep 3 KB Default Changelist?
export function heat(dataRaw) {
  if (dataRaw.length == 0) {
    console.warn("热力图数据为空")
    return
  }
  dataRaw.forEach(dataItem => {
    dataItem.lat = Number(dataItem.lat).toFixed(6)
    dataItem.lng = Number(dataItem.lng).toFixed(6)
    dataItem.value = Number(dataItem.value)
  })
  dataRaw = dataRaw.filter(item => item.lng >= 114 && item.lng <= 115)
  const latArr = dataRaw.map(item => item.lat)
  const lonArr = dataRaw.map(item => item.lng)
  const valueArr = dataRaw.map(item => item.value)
  const latMin = Math.min(...latArr)
  const latMax = Math.max(...latArr)
  const lonMin = Math.min(...lonArr)
  const lonMax = Math.max(...lonArr)
  const valueMax = Math.max(...valueArr)
  // 获得边界经纬度
  const lonc = lonMax - lonMin
  const latc = latMax - latMin

  const dataPoints = []
  dataRaw.forEach(dataItem => {
    const current = {
      x: Math.floor((dataItem.lng - lonMin) / lonc * 2048),
      y: Math.floor((latMax - dataItem.lat) / latc * 2048),
      value: dataItem.value
    }
    const existingItem = dataPoints.find(item => item.x === current.x && item.y === current.y)
    if(existingItem) {
      existingItem.value = existingItem.value + current.value
    } else {
      dataPoints.push(current)
    }
  })
  let radius = [120, 100, 80, 60, 40, 32];
  let canvasContainer = document.getElementById('heatmapContainer');
  const data = {
    max: valueMax,
    data: dataPoints
  }
  for (let i = 0; i < 5; i++) {
    let heatmapInstance = h337.create({
      container: canvasContainer,
      radius: radius[i],
      maxOpacity: 0.8,
      minOpacity: .5,
      blur: .85,
      gradient: {
        '0.9': 'red',
        '0.8': 'orange',
        '0.7': 'yellow',
        '0.05': 'green',
        '0': '#001736',
      },
    });
    heatmapInstance.setData(data)

    const rectangle = window.viewer.scene.groundPrimitives.add(new Freedo.GroundPrimitive({
      geometryInstances: new Freedo.GeometryInstance({
        geometry: new Freedo.RectangleGeometry({
          rectangle: Freedo.Rectangle.fromDegrees(lonMin, latMin, lonMax, latMax),
          vertexFormat: Freedo.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat,
        })
      }),
      appearance: new Freedo.MaterialAppearance({
        materialSupport: Freedo.MaterialAppearance.MaterialSupport.TEXTURED,
        material: new Freedo.Material({
          fabric: {
            type: 'Image',
            uniforms: {
              image: heatmapInstance.getDataURL(),
            },
          }
        })
      }),
      releaseMaterials: true,
      show: false, //默认不显示
    }));
    const img = heatmapInstance._renderer.shadowCtx.getImageData(0, 0, 2048, 2048);
    window.heatmapPrimitives.push({
      primitive: rectangle,
      heatmapImageData: img.data,
    });
  }
  onCameraChanged()
}

export function onCameraChanged() {
  if (window.heatmapPrimitives.length > 0) {
    for (let i = 0; i < window.heatmapPrimitives.length; i++) {
      window.heatmapPrimitives[i].primitive.show = false;
    }
    let height = viewer.scene.camera.positionCartographic.height; //相机的海拔高度
    // console.log(height)
    //根据相机高度来决定显示哪个热力图
    if (height > 80000) {
      window.heatmapPrimitives[0].primitive.show = true;
    } else if (height > 40000) {
      window.heatmapPrimitives[1].primitive.show = true;
    } else if (height > 20000) {
      window.heatmapPrimitives[2].primitive.show = true;
    } else if (height > 10000) {
      window.heatmapPrimitives[3].primitive.show = true;
    } else {
      window.heatmapPrimitives[4].primitive.show = true;
    }
  }
}