split-computed.js 5.16 KB
import defHttp from '../../../api/http'


/**
 * @description 数据预处理
 * @param {*} originalList  原始点位数组
 * @param {*} switchComputed  是否开启计算
 * @param {*} imgWidth  楼层图片宽度
 * @param {*} imgHeight 楼层图片高度
 * @param {*} key_floorId  楼层id
 * @param {*} countnumMaxCache 缓存热力最大值
 * @param {*} relateSwitch 是否开启关联
 * @param {*} relateNum 关联点位数量
 * @returns 
 */
export const dataPreDealWith = ({
    originalList = [], 
    switchComputed = false, 
    imgWidth, 
    imgHeight, 
    key_floorId,
    countnumMaxCache,
    relateSwitch = false,
    relateNum = 3,
}) => {
  return new Promise(async (resolve, reject) => {
    let points = [],
      pointObj = {},
      gateIdInListIndex = {},
      valMax = 1;
    originalList.forEach(item => {
      if (item.countnum > valMax) {
        valMax = item.countnum;
      }
      if (item.countnum > countnumMaxCache) {
        countnumMaxCache = item.countnum;
      }
      pointObj = {
        x: parseInt(item.x * imgWidth / 100),
        y: parseInt(item.y * imgHeight / 100),
        value: item.countnum,
        gateId: item.gateId
      }
      points.push(pointObj)
      gateIdInListIndex[item.gateId] = points.length - 1;
    })

    if (switchComputed) {
      points = await computeDistance(points, 20, key_floorId, gateIdInListIndex, relateSwitch, relateNum);
    }
    console.log(originalList, 
        switchComputed, 
        imgWidth, 
        imgHeight, 
        key_floorId,
        countnumMaxCache,
        points)
    resolve({
        points: points,
        valMax: valMax ? 1 : valMax,
        countnumMaxCache: countnumMaxCache
    })
  })

}


/**
 * @description 通过计算两点之间距离,寻找关联点位
 * @param {*} list list:Array {x, y, value, gateId}
 * @param {*} len  切分的数量
 * @param {*} floorId 楼层ID
 * @param {*} gateIdInListIndex 监控点数据所在list的下标index
 * @param {*} relateSwitch 是否开启获取连通图关系
 * @returns
 */

export const computeDistance = async (list, len, floorId, gateIdInListIndex, relateSwitch = false, relateNum) => {
  let gateToGatesObj = {};
  if (relateSwitch) {
    gateToGatesObj = await getGateToGates(floorId);
  };
  return new Promise(async (resolve, reject) => {
    list.forEach(p1 => {
      p1.distanceArr = [];
      if (p1.x && p1.y) {
        const relateArr = gateToGatesObj[p1.gateId];
        if (relateArr) {
          relateArr.forEach(id => {
            const index = gateIdInListIndex[id];
            const p2 = list[index] || {};
            if (p2.x && p2.y) {
              let a = p1.x - p2.x;
              let b = p1.y - p2.y;
              let c = Math.sqrt(Math.abs(a * a) + Math.abs(b * b));
              p1.distanceArr.push({
                distance: c,
                point: p2,
                splitX: a / len,
                splitY: b / len,
                averValue: (p1.value + p2.value) / 10
              });
              p1.distanceArr.sort((a, b) => a.distance - b.distance)
            }
          })
        } else {
          list.forEach(p2 => {
            if (p2.x && p2.y) {
              let a = p1.x - p2.x;
              let b = p1.y - p2.y;
              let c = Math.sqrt(Math.abs(a * a) + Math.abs(b * b));
              p1.distanceArr.push({
                distance: c,
                point: p2,
                splitX: a / len,
                splitY: b / len,
                averValue: (p1.value + p2.value) / 10
              });
              p1.distanceArr.sort((a, b) => a.distance - b.distance);
              p1.distanceArr.splice(relateNum);
            }
          })
        }
      }
    })
    const newList = await splitPoint(list, len);
    resolve(newList)
  })

}

/**
 * @description 通过distance取距离最小的两个点位,并均分成5个点位
 * @param {*} list 
 * @param {*} len 
 * @returns 
 */

const splitPoint = async (list, len) => {
  return new Promise((resolve, reject) => {
    list.forEach(p => {
      p.distanceArr.forEach((p2) => {
        if (p2.distance > 0) {
          for (let i = 1; i < len; i++) {
            let value = 0;
            if (i < (len / 2 - 1)) {
              value = p2.averValue * i;
            } else if (i == (len / 2)) {
              value = p2.averValue * len / 2;
            } else {
              value = p2.averValue * (i - len / 2 - 1);
            }
            list.push({
              x: p.x - (p2.splitX * i),
              y: p.y - (p2.splitY * i),
              value: value,
            })
          }
        }
      })
    })
    resolve(list)
  })

}

/**
 * @description 通过楼层id获取连通图
 * @param {*} floorId 
 * @returns 
 */
const getGateToGates = (floorId) => {
  return new Promise(async (resolve, reject) => {
    try {
      const res = await defHttp('get', `/gateToGates/floor/${floorId}`)
      let gateToGatesObj = {};
      if (res.data.code === 200) {
        res.data.data.forEach(gate => {
          if (!gateToGatesObj[gate.from]) {
            gateToGatesObj[gate.from] = []
          }
          gateToGatesObj[gate.from].push(gate.to)
        })
      }
      resolve(gateToGatesObj)
    } catch (error) {
      resolve({})
    }
  })
}