quanyawei
2024-04-29 f64742aeed083684ead735a8a7e13c4be4685682
fix: 热力图修改
1 files modified
665 ■■■■■ changed files
src/views/hotMap/index.vue 665 ●●●●● patch | view | raw | blame | history
src/views/hotMap/index.vue
@@ -75,6 +75,13 @@
          >
            截图
          </el-button>
          <!-- <el-button
            class="btn"
            style="margin-bottom: 5px"
            @click="drawRectangle"
          >
            绘制矩形
          </el-button> -->
        </el-form-item>
      </el-form>
    </div>
@@ -112,6 +119,173 @@
      props: { checkStrictly: true, label: 'name', value: 'id', children: 'children' },
      orgId: [],
      city: '苏州',
      selectYcLocationInfor: {},
      ycPoints: [
        {
          id: 117,
          name: '月亮广场',
          radius: 50,
          centerPoint: [120.162594, 33.335508],
          zoom: 15,
          path: [[
            [
              120.14212385147812,
              33.3501711960911
            ],
            [
              120.18375173538925,
              33.3501711960911
            ],
            [
              120.18375173538925,
              33.32428486558254
            ],
            [
              120.14212385147812,
              33.32428486558254
            ],
            [
              120.14212385147812,
              33.3501711960911
            ],
          ]]
        },
        {
          id: 118,
          name: '宝龙广场',
          radius: 100,
          centerPoint: [120.159189, 33.362052],
          zoom: 15,
          path: [[
            [
              120.14180812194945,
              33.376155594175906
            ],
            [
              120.1767841275036,
              33.376155594175906
            ],
            [
              120.1767841275036,
              33.349560021621436
            ],
            [
              120.14180812194945,
              33.349560021621436
            ],
            [
              120.14180812194945,
              33.376155594175906
            ]
          ]]
        },
        {
          id: 119,
          name: '开发区管委会',
          zoom: 16,
          radius: 100,
          centerPoint: [120.216872, 33.378334],
          path: [
            [
              [
                120.20549907401204,
                33.38532153338434
              ],
              [
                120.22927417472005,
                33.38532153338434
              ],
              [
                120.22927417472005,
                33.37125561579751
              ],
              [
                120.20549907401204,
                33.37125561579751
              ],
              [
                120.20549907401204,
                33.38532153338434
              ]
            ]
          ]
        },
        {
          id: 120,
          name: '盐城电厂',
          zoom: 15,
          radius: 60,
          centerPoint: [120.123716, 33.400926],
          path: [[
            [
              120.10800871968269,
              33.411207878716695
            ],
            [
              120.13839278340339,
              33.411207878716695
            ],
            [
              120.13839278340339,
              33.39053545526069
            ],
            [
              120.10800871968269,
              33.39053545526069
            ]
          ]]
        },
        {
          id: 121,
          name: '市监测站',
          zoom: 16,
          radius: 60,
          centerPoint: [120.159868, 33.392545],
          path: [[
            [
              120.1529805980623,
              33.39872613771991
            ],
            [
              120.16664913520219,
              33.39872613771991
            ],
            [
              120.16664913520219,
              33.38616740820813
            ],
            [
              120.1529805980623,
              33.38616740820813
            ]
          ]]
        },
        {
          id: 122,
          name: '大丰高级中学',
          zoom: 16,
          radius: 100,
          centerPoint: [120.433178, 33.203129],
          path: [[
            [
              120.42407972171901,
              33.21116367463085
            ],
            [
              120.4417823012173,
              33.21116367463085
            ],
            [
              120.4417823012173,
              33.196926006173
            ],
            [
              120.42407972171901,
              33.196926006173
            ]
          ]]
        },
      ],
      formInline: {
        city: '',
        cityCode: '',
@@ -123,8 +297,26 @@
      },
      selectSensor: {code: 'a34002',
        name: 'PM10',
        maxNumber: 500,
        src: require('@/assets/images/tl_PM10.png'),
        colorList: [{
          maxNumber: 50,
          color: '#12a112'
        }, {
          maxNumber: 150,
          color: '#feff01'
        }, {
          maxNumber: 250,
          color: '#fd8200'
        }, {
          maxNumber: 350,
          color: '#fd0001'
        }, {
          maxNumber: 420,
          color: '#95014b'
        }, {
          maxNumber: 500,
          color: '#7e0226'
        }],
        gradient: {
          0: '#12a112',
          0.1: '#12a112',
@@ -137,8 +329,26 @@
      sensorArr: [
        { code: 'a34002',
          name: 'PM10',
          maxNumber: 500,
          src: require('@/assets/images/tl_PM10.png'),
          colorList: [{
            maxNumber: 50,
            color: '#12a112'
          }, {
            maxNumber: 150,
            color: '#feff01'
          }, {
            maxNumber: 250,
            color: '#fd8200'
          }, {
            maxNumber: 350,
            color: '#fd0001'
          }, {
            maxNumber: 420,
            color: '#95014b'
          }, {
            maxNumber: 500,
            color: '#7e0226'
          }],
          gradient: {
            0: '#12a112',
            0.1: '#12a112',
@@ -150,84 +360,148 @@
          }},
        { code: 'a34004',
          name: 'PM2.5',
          maxNumber: 350,
          colorList: [{
            maxNumber: 35,
            color: '#12a112'
          }, {
            maxNumber: 75,
            color: '#feff01'
          }, {
            maxNumber: 115,
            color: '#fd8200'
          }, {
            maxNumber: 150,
            color: '#fd0001'
          }, {
            maxNumber: 250,
            color: '#95014b'
          }, {
            maxNumber: 350,
            color: '#7e0226'
          }],
          src: require('@/assets/images/tl_PM2.5.png'),
          gradient: {
            0: '#12a112',
            0.1: '#12a112',
            0.21: '#feff01',
            0.32: '#fd8200',
            0.42: '#fd0001',
            0.71: '#95014b',
            1: '#7e0226'
          } },
          gradient: {}
        },
        { code: 'a21026',
          name: 'SO2',
          maxNumber: 150,
          src: require('@/assets/images/tl_SO2.png'),
          gradient: {
            1: '#feff01',
            0.3: '#12a112',
          }
          colorList: [{
            maxNumber: 50,
            color: '#12a112'
          }, {
            maxNumber: 150,
            color: '#feff01'
          }, {
            maxNumber: 475,
            color: '#fd8200'
          }, {
            maxNumber: 800,
            color: '#fd0001'
          }, {
            maxNumber: 1600,
            color: '#95014b'
          }, {
            maxNumber: 2100,
            color: '#7e0226'
          }],
          gradient: {}
        },
        { code: 'a21004',
          name: 'NO2',
          maxNumber: 400,
          src: require('@/assets/images/tl_NO2.png'),
          gradient: {
            0: '#12a112',
            0.1: '#12a112',
            0.15: '#feff01',
            0.19: '#feff01',
            0.20: '#fd8200',
            0.25: '#fd8200',
            0.45: '#fd8200',
            0.5: '#fd0001',
            0.7: '#95014b',
            1: '#7e0226'
          }},
          colorList: [{
            maxNumber: 40,
            color: '#12a112'
          }, {
            maxNumber: 80,
            color: '#feff01'
          }, {
            maxNumber: 180,
            color: '#fd8200'
          }, {
            maxNumber: 280,
            color: '#fd0001'
          }, {
            maxNumber: 565,
            color: '#95014b'
          }, {
            maxNumber: 750,
            color: '#7e0226'
          }],
          gradient: {}
        },
        { code: 'a21005',
          name: 'CO',
          maxNumber: 48,
          src: require('@/assets/images/tl_CO.png'),
          gradient: {
            0.0: '#12a112',
            0.04: '#12a112',
            0.083: '#feff01',
            0.29: '#fd8200',
            0.5: '#fd0001',
            0.75: '#95014b',
            1: '#7e0226'
          }},
          colorList: [{
            maxNumber: 2,
            color: '#12a112'
          }, {
            maxNumber: 4,
            color: '#feff01'
          }, {
            maxNumber: 14,
            color: '#fd8200'
          }, {
            maxNumber: 24,
            color: '#fd0001'
          }, {
            maxNumber: 36,
            color: '#95014b'
          }, {
            maxNumber: 48,
            color: '#7e0226'
          }],
          gradient: {}
        },
        { code: 'a05024',
          name: 'O3',
          maxNumber: 500,
          src: require('@/assets/images/tl_O3.png'),
          gradient: {
            0: '#12a112',
            0.32: '#12a112',
            0.33: '#feff01',
            0.4: '#feff01',
            0.41: '#fd8200',
            0.6: '#fd8200',
            0.61: '#fd0001',
            0.8: '#fd0001',
            0.9: '#95014b',
            1: '#7e0226'
          } },
          colorList: [{
            maxNumber: 160,
            color: '#12a112'
          }, {
            maxNumber: 200,
            color: '#feff01'
          }, {
            maxNumber: 300,
            color: '#fd8200'
          }, {
            maxNumber: 400,
            color: '#fd0001'
          }, {
            maxNumber: 800,
            color: '#95014b'
          }, {
            maxNumber: 1000,
            color: '#7e0226'
          }],
          gradient: {}
        },
        { code: 'a99054',
          name: 'TVOC',
          maxNumber: 4,
          src: require('@/assets/images/tl_TVOCNew.png'),
          gradient: {
            0: '#12a112',
            0.12: '#12a112',
            0.25: '#feff01',
            0.375: '#fd8200',
            0.5: '#fd0001',
            0.75: '#95014b',
            1: '#7e0226'
          }}
          colorList: [{
            maxNumber: 0.5,
            color: '#12a112'
          }, {
            maxNumber: 1,
            color: '#feff01'
          }, {
            maxNumber: 1.5,
            color: '#fd8200'
          }, {
            maxNumber: 2,
            color: '#fd0001'
          }, {
            maxNumber: 3,
            color: '#95014b'
          }, {
            maxNumber: 4,
            color: '#7e0226'
          }],
          gradient: {}
        }
      ],
      heatMapData: [],
      dataType: 'datetimerange',
@@ -293,6 +567,29 @@
    }
  },
  methods: {
    drawRectangle () {
      AMap.plugin('AMap.MouseTool', () => {
        let mouseTool = new AMap.MouseTool(this.map)
        mouseTool.rectangle({
          strokeColor: 'red',
          strokeOpacity: 0.5,
          strokeWeight: 6,
          fillColor: 'blue',
          fillOpacity: 0.5,
          // strokeStyle还支持 solid
          strokeStyle: 'solid',
        // strokeDasharray: [30,10],
        })
        mouseTool.on('draw', function (event) {
          // event.obj 为绘制出来的覆盖物对象
          let data = event.obj.getPath()
          let allpoint = []
          data.forEach(item => {
            allpoint.push([item.R, item.Q])
          })
        })
      })
    },
    download () {
      const ref = this.$refs.content // 截图区域
      html2canvas(ref, {
@@ -308,7 +605,6 @@
      })
    },
    getDateFun (item) {
      console.log(item)
      this.activeItem = item
      if (this.orgId.length > 0) {
        this.getData(item.name)
@@ -321,18 +617,13 @@
        this.map.remove(this.heatmap)
        this.heatmap = null
      }
      console.log('this.heatmap', this.heatmap)
    },
    // 初始化地图
    initMap () {
      let zoom = 10
      if (this.formInline.cityCode === '320900') {
        zoom = this.formInline.areName === 'dafengqu' ? 15 : 13
      }
      var map = new AMap.Map('mapd', {
        resizeEnable: true,
        zoomEnable: false,
        zoom: zoom
        zoom: this.formInline.cityCode === '320900' ? this.selectYcLocationInfor.zoom : 10
      })
      this.map = map
      map.on('click', function (e) {
@@ -343,6 +634,7 @@
    },
    init1 () { // 区域遮盖
      var that = this
      if (that.polygon) {
        that.map.remove(that.polygon)
        that.map.remove(that.districtSearch)
@@ -354,46 +646,19 @@
          extensions: 'all',
          subdistrict: 0
        }).search(that.formInline.cityCode, function (status, result) { // 外多边形坐标数组和内多边形坐标数组
          var outer = [
          let outer = [
            new AMap.LngLat(-360, 90, true),
            new AMap.LngLat(-360, -90, true),
            new AMap.LngLat(360, -90, true),
            new AMap.LngLat(360, 90, true)
          ]
          var pathArray = [outer]
          let ycPoints = {
            areas: [{ // 围栏1
              rejectTexture: true, // 是否屏蔽自定义地图的纹理
              path: [[
                [120.06316306, 33.41753995999999],
                [120.2617243421, 33.41753995999999],
                [120.2617243421, 33.308387182],
                [120.06316306, 33.308387182],
                [120.06316306, 33.41753995999999]
              ]]
            }]
          }
          var holes = result.districtList[0].boundaries
          console.log('that.formInline', that.formInline)
          let pathArray = [outer]
          let holes = result.districtList[0].boundaries
          if (that.formInline.cityCode === '320900') {
            // 盐城
            that.map.setCenter([120.16, 33.36])
            if (that.formInline.areName === 'dafengqu') {
              that.map.setCenter([120.435345, 33.203704])
              ycPoints = {
                areas: [{ // 围栏1
                  rejectTexture: true, // 是否屏蔽自定义地图的纹理
                  path: [[ [120.41615942, 33.215693],
                    [120.45416756599998, 33.215693],
                    [120.45416756599998, 33.192137742599996],
                    [120.41615942000003, 33.19213774259998],
                    [120.41615942, 33.215693] ]]
                }]
              }
            }
            pathArray.push.apply(pathArray, ycPoints.areas[0].path)
            let locationInfor = _.find(that.ycPoints, { id: that.formInline.areName })
            that.map.setCenter(locationInfor.centerPoint)
            pathArray.push.apply(pathArray, locationInfor.path)
          } else {
            pathArray.push.apply(pathArray, holes)
            that.map.setCity(that.formInline.city)
@@ -418,6 +683,7 @@
        params: {
          id: this.orgId[0],
          startTime: newVal,
          monitorId: this.formInline.areName,
          type: this.selectSensor.code,
          form: this.formInline.dayType
        }
@@ -428,11 +694,8 @@
              this.createHeatMap()
            }
            this.heatMapData = res.data
            this.dataProcessing(this.heatMapData)
            this.heatmap.setDataSet({
              data: this.heatMapData,
              max: this.selectSensor.maxNumber
            })
          } else {
            this.map.remove(this.heatmap)
            this.heatmap = null
@@ -442,118 +705,78 @@
          console.log(err)
        })
    },
    findMaxNumberForValue (value, colorList) {
      let matchedMaxItem = null
      for (let item of colorList) {
        if (value <= item.maxNumber) {
          matchedMaxItem = item
          break // 找到后退出循环
        }
      }
      return matchedMaxItem
    },
    getGradientOption (matchedMaxItem) {
      let gradient = {}
      this.selectSensor.colorList.forEach(item => {
        if (item.maxNumber <= matchedMaxItem.maxNumber) {
          console.log('item', item)
          let key = (item.maxNumber / matchedMaxItem.maxNumber).toFixed(1)
          gradient[key] = item.color
        }
      }
      )
      let keysArray = Object.keys(gradient)
      let valuesArray = Object.values(gradient)
      console.log('keysArray', keysArray, valuesArray)
      let obj = {}
      keysArray.forEach((item, index) => {
        console.log(item, index, parseInt(item))
        if (Number(item) !== 1) {
          obj[Number(item)] = valuesArray[index]
          if (Number(item) + 0.1 < keysArray[index + 1]) {
            obj[Number(item) + 0.1] = valuesArray[index + 1]
          }
        } else {
          obj[Number(item)] = valuesArray[index]
        }
      })
      obj[0] = '#12a112'
      return obj
    },
    dataProcessing (heatMapData) {
      // 获取最大值
      console.log('this.heatMapData', this.heatMapData)
      const max = heatMapData.reduce((prev, current) => (prev.count > current.count ? prev : current)).count
      // so2
      if (this.selectSensor.code === 'a21026') {
        if (max > 150 && max <= 475) {
          this.selectSensor.maxNumber = 475
          this.heatmap.setOptions({
            gradient: {
              0.1: '#12a112',
              0.2: '#feff01',
              0.3: '#feff01',
              0.32: '#fd8200',
              0.4: '#fd8200',
              1: '#fd8200'
            }
          })
        }
        if (max > 475 && max <= 1000) {
          this.selectSensor.maxNumber = 1000
          this.heatmap.setOptions({
            gradient: {
              0: '#12a112',
              0.05: '#12a112',
              0.15: '#feff01',
              0.47: '#fd8200',
              0.5: '#fd0001',
              0.8: '#fd0001',
              0.9: '#95014b',
              1: '#7e0226'
            }
          })
        }
      } else if (this.selectSensor.code === 'a05024') {
        if (max > 150 && max <= 475) {}
      }
      let matchedMaxItem = this.findMaxNumberForValue(max, this.selectSensor.colorList)
      let gradient = this.getGradientOption(matchedMaxItem)
      this.heatmap.setDataSet({
        data: this.heatMapData,
        max: matchedMaxItem.maxNumber
      })
      this.heatmap.setOptions({
        gradient: gradient
      })
    },
    // 聚合点
    setMarkers (curData) {
      curData.forEach((item, index) => {
        let div = document.createElement('div')
        let bgColor = 'hsla(180, 100%, 50%, 0.7)'
        let fontColor = '#000'
        let borderColor = 'hsl(180, 100%, 40%)'
        let shadowColor = 'hsl(180, 100%, 50%)'
        div.id = 'pint' + index
        div.style.backgroundColor = bgColor
        let size = 40
        div.style.width = div.style.height = size + 'px'
        div.style.border = 'solid 1px ' + borderColor
        div.style.borderRadius = size / 2 + 'px'
        div.style.boxShadow = '0 0 1px ' + shadowColor
        div.innerHTML = Math.floor(Number(item.count))
        div.style.lineHeight = size + 'px'
        div.style.color = fontColor
        div.style.fontSize = '14px'
        div.style.textAlign = 'center'
        let marker = new AMap.Marker({
          position: [item.lng, item.lat],
          title: item.name,
          extData: Math.floor(Number(item.count)),
          anchor: 'center',
          // 将 html 传给 content
          content: div,
          // 以 icon 的 [center bottom] 为原点
          offset: new AMap.Pixel(3, 10)
      let markerList = []
      curData.forEach(item => {
        // let marker = new AMap.Marker({
        //   position: new AMap.LngLat(item.lng, item.lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
        //   title: item.name,
        // })
        let marker = new AMap.Text({
          text: item.name, // 标记显示的文本内容
          anchor: 'center', // 设置文本标记锚点位置
          draggable: false, // 是否可拖拽
          cursor: 'pointer', // 指定鼠标悬停时的鼠标样式。
          angle: 10, // 点标记的旋转角度
          position: [item.lng, item.lat], // 点标记在地图上显示的位置
        })
        this.markerList.push(marker)
        markerList.push(marker)
      })
      this.map.add(this.markerList)
      var count = this.markerList.length
      // eslint-disable-next-line no-new
      if (this.markerClusterer) {
        this.markerClusterer.clearMarkers()
      }
      let that = this
      AMap.plugin('AMap.MarkerClusterer', function () {
        that.markerClusterer = new AMap.MarkerClusterer(that.map, that.markerList, {
          gridSize: 100,
          renderClusterMarker: function (context) {
            let contNumber = 0
            context.markers.forEach((item, index) => {
              console.log('indexitem', index, item.getExtData())
              contNumber += item.getExtData()
            })
            console.log('contNumber', contNumber)
            let factor = Math.pow(context.count / count, 1 / 18)
            let div = document.createElement('div')
            let Hue = 180 - factor * 180
            let bgColor = 'hsla(' + Hue + ',100%,50%,0.7)'
            let fontColor = 'hsla(' + Hue + ',100%,20%,1)'
            let borderColor = 'hsla(' + Hue + ',100%,40%,1)'
            let shadowColor = 'hsla(' + Hue + ',100%,50%,1)'
            div.style.backgroundColor = bgColor
            let size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20)
            div.style.width = div.style.height = size + 'px'
            div.style.border = 'solid 1px ' + borderColor
            div.style.borderRadius = size / 2 + 'px'
            div.style.boxShadow = '0 0 1px ' + shadowColor
            div.innerHTML = contNumber
            div.style.lineHeight = size + 'px'
            div.style.color = fontColor
            div.style.fontSize = '14px'
            div.style.textAlign = 'center'
            context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))
            context.marker.setContent(div)
            console.log('context.marker----------------', context.marker)
          }
        })
      })
      this.map.add(markerList)
    },
    getDayListData () {
      this.$request({
@@ -580,13 +803,7 @@
        .then(res => {
          this.orgData = res.data.map(item => {
            if (item.id === 73) {
              item.children = [{
                id: 'shiqu',
                name: '市区'
              }, {
                id: 'dafengqu',
                name: '大丰区'
              }]
              item.children = this.ycPoints
            }
            return item
          })
@@ -597,14 +814,12 @@
    },
    createHeatMap () {
      let that = this
      let radius = this.formInline.areName === 'shiqu' ? 100 : 100
      console.log('radius', radius)
      // let radius = this.formInline.cityCode === '320900' ? this.selectYcLocationInfor.radius : 100
      this.map.plugin(['AMap.Heatmap'], function () {
        // 初始化heatmap对象
        that.heatmap = new AMap.Heatmap(that.map, {
          radius: radius, // 给定半径
          opacity: [0.5, 1],
          gradient: that.selectSensor.gradient
          radius: 100, // 给定半
          opacity: [0.5, 0.5]
        })
      })
    },
@@ -632,21 +847,21 @@
      }
    },
    regionData (id) {
      console.log('id', id)
      let cityData = _.find(this.orgData, { id: id[0] })
      if (id[0] === 73) {
        if (id[1]) {
          this.formInline.areName = id[1]
        }
        this.selectYcLocationInfor = _.find(this.ycPoints, { id: id[1] })
        this.formInline.city = cityData.cityName
        this.formInline.cityCode = String(cityData.cityCode)
      } else {
        this.formInline.areName = ''
        this.formInline.city = cityData.areaName
        this.formInline.cityCode = String(cityData.areaCode)
      }
    },
    selectHourData (data) {
      console.log('ccccc', this.formInline)
      if (data) {
        this.formInline.starTime = data[0]
        this.formInline.endTime = data[1]