zhangzengfei
2020-09-29 e7b81621eb8b49db5820c7fd46cab79df185ba99
热力图添加选择摄像机
1个文件已添加
4个文件已修改
181 ■■■■■ 已修改文件
src/pages/datapush/index/main.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/heatCamera/index/App.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/heatCamera/index/api.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/heatCamera/index/main.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/search/index/main.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/datapush/index/main.ts
@@ -12,7 +12,6 @@
Vue.filter('moment', function (value, formatString) {
  formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
  return moment(value).format(formatString);
});
new Vue({
src/pages/heatCamera/index/App.vue
@@ -2,73 +2,110 @@
  <div class="heatCamera">
    <div class="camera">
      <nav class="header-nav">
        <div class="logo">
          <img src="image/basic.png" alt />
        </div>
        <div class="toolbar">
          <el-radio-group v-model="dimension">
          <el-radio-group v-model="dimension" size="mini">
            <el-radio-button :label="1">热力图</el-radio-button>
            <el-radio-button :label="2">轨迹图</el-radio-button>
          </el-radio-group>
          <el-select
            v-model="camera"
            filterable
            size="mini"
            style="width:200px;"
            placeholder="请选择摄像机"
            value-key="id"
          >
            <el-option
              v-for="item in allCameras"
              style="font-size:12px"
              :key="item.id"
              :label="item.name"
              :value="item"
              :title="item.name"
            ></el-option>
          </el-select>
          <el-date-picker
            @change="timeChange"
            v-model="timeRange"
            value-format="yyyy-MM-dd HH:mm:ss"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            size="mini"
          ></el-date-picker>
          <el-button type="primary" @click="postCameraData">查询</el-button>
          <el-button
            type="primary"
            @click="postCameraData"
            :loading="querying"
            size="mini"
            icon="el-icon-search"
          >查询</el-button>
        </div>
      </nav>
      <div class="img-area" ref="heatMap">
        <span class="dot" v-for="(item,index) in dots" :style="{top:item.y+'px',left: item.x+'px'}" :key="'d'+index"></span>
        <el-image :src="`${publicPath}images/login-net.png`" fit="contain" ref="img"></el-image>
        <span
          class="dot"
          v-for="(item,index) in dots"
          :style="{top:item.y+'px',left: item.x+'px'}"
          :key="'d'+index"
        ></span>
        <el-image :src="baseImg" fit="contain" ref="img">
          <div slot="error" class="image-slot"></div>
        </el-image>
      </div>
    </div>
  </div>
</template>
<script>
Date.prototype.Format = function (fmt) {
  var o = {
    "M+": this.getMonth() + 1, //月份
    "d+": this.getDate(), //日
    "H+": this.getHours(), //小时
    "m+": this.getMinutes(), //分
    "s+": this.getSeconds(), //秒
    "q+": Math.floor((this.getMonth() + 3) / 3), //季度
    "S": this.getMilliseconds() //毫秒
  };
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  return fmt;
}
import Heatmap from 'heatmap.js';
import { getHeatCameraData } from '@/api/heatCamera'
import { getCamerasByServer } from '@/api/pollConfig'
import { getPersonData } from './api'
export default {
  name: "heatCamera",
  computed: {
    baseImg() {
      let imgUrl = "";
      if (this.camera.snapshot_url && this.camera.snapshot_url.length) {
        imgUrl = '/httpImage/' + this.camera.snapshot_url
      }
      return imgUrl
    }
  },
  data () {
    return {
      publicPath: process.env.BASE_URL,
      querying: false,
      dots: [],
      dimension: 1,
      timeRange: [new Date(2020, 7, 23, 8), new Date()],
      params: {
        cameraIds: ["ba8c1624-55a7-4f20-9c54-01e56448aeb5"],
        startDate: new Date(2020, 7, 23, 8).Format("yyyy-MM-dd HH:mm:ss"),
        endDate: new Date().Format("yyyy-MM-dd HH:mm:ss"),
        //thresholdTime: 100,
      },
      timeRange: [
        this.$moment().format("YYYY-MM-DD 00:00:00"),
        this.$moment().format("YYYY-MM-DD HH:mm:ss")
      ],
      camera: {},
      allCameras: [],
      snapshot_url: "",
      heatmapInstance: null,
    }
  },
  mounted () {
    console.log(Heatmap.create)
    this.getAllCamera();
  },
  methods: {
    timeChange(val) {
      this.params.startDate = val[0];
      this.params.endDate = val[1];
    getAllCamera() {
      getCamerasByServer().then(rsp => {
        if (rsp && rsp.success) {
          this.allCameras = rsp.data
        }
      })
    },
    setHeatmapData(sources) {
      if (sources === null || sources.length < 1) {
@@ -84,7 +121,8 @@
          '.8': 'yellow',
          '0.95': 'rgba(251, 40, 40, 0.3)',
          '0.6': 'rgba(42, 251, 199, 0.3)',
          '0.5': 'rgba(2, 119, 251, 0.3)'
          //'0.5': 'rgba(2, 119, 251, 0.3)'
          '0.5': 'rgba(2, 251, 251, 0.3)'
        }
      };
      var points = {
@@ -111,44 +149,53 @@
    },
    postCameraData() {
      this.dots = [];
      var xhr = new XMLHttpRequest();
      xhr.open('post', '/data/api-v/es/getPersonData');
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.setRequestHeader('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ3NDUwMjU5MjMsInVzZXIiOiJ7XCJpZFwiOlwiZTZjY2QzNmQtNGYxNi00NmZjLTg4ZDUtMDczNjU4NjZkMjA1XCIsXCJwZXJtaXNzaW9uc1wiOltcInByb2R1Y3RNYW5nZTpwdWJsaXNoXCIsXCJjb2RlTWFuZ2U6dmlld1wiLFwiZGV2aWNlTWFuYWdlOmFkZFwiLFwiYWRtaW5NYW5hZ2VcIixcIm9yZGVyTWFuZ2VcIixcImRldmljZU1hbmFnZTp2aWV3XCIsXCJwcm9kdWN0TWFuZ2U6YWRkXCIsXCJhZG1pbk1hbmFnZTp2aWV3XCIsXCJjb2RlTWFuZ2U6YWRkXCIsXCJwcm9kdWN0TWFuZ2U6b2ZmU2FsZVwiLFwib3JkZXJNYW5nZTpjYW5jZWxcIixcInByb2R1Y3RDZW50ZXI6ZG93bmxvYWRcIixcInByb2R1Y3RDZW50ZXI6YnV5XCIsXCJwcm9kdWN0TWFuZ2U6dmlld1wiLFwiYXBpXCIsXCJob21lXCIsXCJvcmRlck1hbmdlOnBheVwiLFwiYWRtaW5NYW5hZ2U6YWRkXCIsXCJvcmRlck1hbmdlOmRvd25sb2FkXCIsXCJwcm9kdWN0Q2VudGVyXCIsXCJkZXZpY2VNYW5hZ2U6dW5iaW5kXCIsXCJvcmRlck1hbmdlOnZpZXdcIixcImFkbWluTWFuYWdlOmVkaXRcIixcImRldmljZU1hbmFnZVwiLFwidmlwTWFuYWdlOmFkZFwiLFwidmlwTWFuYWdlOnZpZXdcIixcInByb2R1Y3RDZW50ZXI6dmlld1wiLFwidmlwTWFuYWdlOmVkaXRcIixcInZpcE1hbmFnZVwiLFwicHJvZHVjdE1hbmdlOmVkaXRcIixcImNvZGVNYW5nZVwiLFwicHJvZHVjdE1hbmdlXCJdLFwidXNlcm5hbWVcIjpcImJhc2ljXCJ9In0.vwjAFkWuEyadRLvIOGK8LFE3MjpY3SQ7j6AlTXnQDG8');
      xhr.send(JSON.stringify(this.params));
      xhr.onload = function () {
        if (xhr.readyState == 4) {
          var response = JSON.parse(xhr.responseText)
          if (response && response.success) {
            console.log(response.data.result)
            debugger
            this.setHeatmapData(response.data.result)
      let params = {};
      if (!this.camera.id || !this.camera.id.length) {
        this.$message({
          type: "error",
          message: "请选择一个摄像机"
        })
        return;
          }
      params.cameraIds = [this.camera.id];
      params.startDate = this.timeRange[0];
      params.endDate = this.timeRange[1];
      this.querying = true;
      getPersonData(params).then(rsp => {
        if (rsp && rsp.success) {
          this.setHeatmapData(rsp.data.result)
        }
        this.mockAsync
      }.bind(this)
        this.querying = false
      }).catch(() => {
        this.querying = false
      })
    },
    formatPoint(data) {
      var converters = {
        "ba8c1624-55a7-4f20-9c54-01e56448aeb5": {
          "scale": 1,
        "default": {
          "scale": 0.66,
          "offsetX": 0,
          "offsetY": 0
        }
      }
      var cv = converters[data.cameraId]
      var cv = converters[data.cameraId] ? converters[data.cameraId] : converters["default"]
      var topLeft = data.personRect.topLeft
      var bottomRight = data.personRect.bottomRight
      // 中心点
      var dataPoint = {
        //x: ((topLeft.x + bottomRight.x) * cv.scale + cv.offsetX * 2) / 2,
        //y: ((topLeft.y + bottomRight.y) * cv.scale + cv.offsetY * 2) / 2,
        x: ((topLeft.x + bottomRight.x) * cv.scale + cv.offsetX * 2) / 2,
        y: ((topLeft.y + bottomRight.y) * cv.scale + cv.offsetX * 2) / 2,
        // value: data.stayTime
        value: 0
        y: ((bottomRight.y) * cv.scale + cv.offsetY),
        value: data.stayTime
      };
      if (dataPoint.y > 720) {
        dataPoint.y = 720
      }
      return dataPoint
    }
@@ -167,7 +214,7 @@
    background-image: linear-gradient(-180deg, #ffffff 13%, #e9ebf2 100%);
  }
  .toolbar {
    width: 680px;
    width: 850px;
    height: 60px;
    //background: rgba(0,0,0,.3);
    position: absolute;
@@ -189,13 +236,15 @@
  .img-area {
    margin: 30px auto;
    width: 1280px;
    height: 720px;
    position: relative;
    font-size: 0;
    background-color: black;
    .dot{
      width: 10px;
      height: 10px;
      background-image: radial-gradient(circle,#04f3ff,#adf7f7,#31e4d3);
      opacity: .5;
      opacity: 0.5;
      border-radius: 50%;
      position: absolute;
      z-index: 1000;
src/pages/heatCamera/index/api.ts
New file
@@ -0,0 +1,11 @@
import request from "@/scripts/httpRequest";
//进出入统计
//ElasticSearchArg :es查询参数
export const getPersonData = (query: any) => {
  return request({
    url: "/data/api-v/es/getPersonData",
    method: "post",
    data: query
  });
};
src/pages/heatCamera/index/main.ts
@@ -2,9 +2,18 @@
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import "@/assets/css/element-variables.scss";
import moment from "moment";
Vue.prototype.$moment = moment;
import App from './App.vue';
Vue.use(ElementUI)
Vue.filter('moment', function (value, formatString) {
    formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
    return moment(value).format(formatString);
});
new Vue({
    el: '#app',
    render: h => h(App)
src/pages/search/index/main.ts
@@ -24,7 +24,6 @@
Vue.filter('moment', function (value, formatString) {
  formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
  return moment(value).format(formatString);
});
export default Vue.prototype.bus = new Vue({