Vue中开启关闭风场

摘要:
divref=“emap”id=“map”>divi=“popup”class=“ol popup”>ahref=“#”id=“popup closer”class=“ol popup closeer”>divclass=“close_on”>el-buttontype=“primary”size=“default”@click=“closeWind”>-->
<template>
  <div class="box">
    <div ref="emap" id="map"></div>
    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content"></div>
    </div>
    <div class="close_on">
      <!-- <el-button type="primary" size="default" @click="addWind"></el-button>
      <el-button type="primary" size="default" @click="closeWind">关闭风场</el-button> -->
      <el-button :loading="loading" type="primary" size="mini">
        <span v-if="online" @click="addWind">开启风场</span>
        <span v-else @click="closeWind">关闭风场</span>
      </el-button>
    </div>
  </div>
</template>

<script>
import 'ol/ol.css'
import Map from 'ol/Map'
import Stamen from 'ol/source/Stamen'
import VectorSource from 'ol/source/Vector'
import View from 'ol/View'
import { Heatmap as HeatmapLayer, Tile as TileLayer, Vector as LayerVec } from 'ol/layer'
import GeoJSON from 'ol/format/GeoJSON'

import olsourceOSM from 'ol/source/OSM'
import { get as getProjection, transform, fromLonLat } from 'ol/proj'

import { Vector as SourceVec, Cluster } from 'ol/source'
import { Feature, Overlay } from 'ol'
import { Point } from 'ol/geom'
import { Style, Icon, Stroke, Fill, Text, Circle } from 'ol/style'

import { WindLayer } from 'ol-wind'

export default {
  name: 'heatmap',
  data() {
    return {
      map: null,
      center: [113.0521, 34.6006],
      heatData: {
        type: 'FeatureCollection',
        features: [
          { type: 'Point', coordinates: [104.4, 31.19], count: 100 },
          { type: 'Point', coordinates: [113.3, 30.6], count: 19 },
          { type: 'Point', coordinates: [123.3, 30.6], count: 419 },
          { type: 'Point', coordinates: [105.3, 30.6], count: 319 },
          { type: 'Point', coordinates: [106.3, 30.6], count: 719 },
          { type: 'Point', coordinates: [109.3, 31.6], count: 519 },
          { type: 'Point', coordinates: [109.3, 30.6], count: 319 },
          { type: 'Point', coordinates: [108.3, 32.6], count: 139 },
          { type: 'Point', coordinates: [118.3, 31.6], count: 129 },
          { type: 'Point', coordinates: [108.3, 33.6], count: 190 },
          { type: 'Point', coordinates: [108.3, 32.6], count: 189 },
          { type: 'Point', coordinates: [100.3, 30.6], count: 1 },
          { type: 'Point', coordinates: [109.3, 30.6], count: 119 },
          { type: 'Point', coordinates: [108.3, 31.6], count: 200 },
          { type: 'Point', coordinates: [118.3, 30.6], count: 300 },
        ],
      },
      view: null,
      points: [
        {
          address: '河南省商丘市',
          name: '测试',
          id: '1000',
          lon: ['113.28', '34.54'],
        },
        {
          address: '河南省郑州市',
          name: '同样是测试',
          id: '1001',
          lon: ['113.28', '35.54'],
        },
      ],
      layer: null,
      windLayers: null,
      online: true,
      loading: false,
    }
  },
  methods: {
    initMap() {
      let _this = this
      let projection = getProjection('EPSG:4326')
      // 热力图层
      let vector = new HeatmapLayer({
        source: new VectorSource({
          features: new GeoJSON().readFeatures(this.heatData, {
            dataProjection: 'EPSG:4326',
            featureProjection: 'EPSG:3857',
          }),
        }),
        blur: 20,
        radius: 10,
      })

      // 底图1
      let tile = new TileLayer({
        source: new olsourceOSM(),
      })

      // 地图中心
      let view = new View({
        center: transform(this.center, 'EPSG:4326', 'EPSG:3857'),
        zoom: 5,
        minZoom: 5,
        maxZoom: 13,
      })

      // 实例化底图
      this.map = new Map({
        layers: [tile, vector],
        target: 'map',
        view,
      })

      // 创建点标记样式
      let createLabelStyle = function(feature) {
        let imgs = ''
        if (feature.values_.id == '1000') {
          imgs = '/static/warning_icon/normal_green.png'
        } else {
          imgs = '/static/warning_icon/normal_red.png'
        }
        return new Style({
          image: new Icon({
            scale: 1,
            opacity: 1,
            src: imgs,
          }),
        })
      }

      // 显示点标记
      for (let i = 0; i < this.points.length; i++) {
        addMarker(this.points[i])
      }
      function addMarker(info) {
        let iconFeature = new Feature({
          geometry: new Point(fromLonLat(info.lon)),
          name: info.name,
          id: info.id,
          address: info.address,
          lon: info.lon,
        })

        // 调用 createLabelStyle, 添加样式
        iconFeature.setStyle(createLabelStyle(iconFeature))

        // 矢量图层数据源
        let vectorSource = new VectorSource({
          features: [iconFeature],
        })
        // 矢量标注图层
        let vectorLayer = new LayerVec({
          source: vectorSource,
        })
        _this.map.addLayer(vectorLayer)
      }

      /*********************显示弹出层**************************/
      let container = document.getElementById('popup')
      let content = document.getElementById('popup-content')
      let popupCloser = document.getElementById('popup-closer')

      // 创建覆盖物图层
      let overlay = new Overlay({
        element: container,
        autoPan: true,
      })

      // 鼠标移入改变样式
      this.map.on('pointermove', function(e) {
        let pixel = _this.map.getEventPixel(e.originalEvent)
        let hit = _this.map.hasFeatureAtPixel(pixel)
        _this.map.getTargetElement().style.cursor = hit ? 'pointer' : ''
      })

      // 设置显示内容
      function addInfo(info) {
        return (content.innerHTML =
          "<p class='info'>" +
          info.address +
          '</p>' +
          "<p class='info'>" +
          info.id +
          '</p>' +
          "<p class='info'>" +
          info.name +
          '</p>')
      }

      // 鼠标点击覆盖物
      this.map.on('click', function(e) {
        let feature = _this.map.forEachFeatureAtPixel(e.pixel, function(feature, layer) {
          return feature
        })
        if (feature) {
          if (!feature.values_.id) {
            return false
          }
          let coodinate = e.coordinate
          content.innerHTML = ''
          addInfo(feature.values_)
          overlay.setPosition(fromLonLat(feature.values_.lon))
          _this.map.addOverlay(overlay)
        }
      })
      // 点击关闭事件
      popupCloser.addEventListener('click', function() {
        overlay.setPosition(undefined)
      })
    },
    addWind() {
      // 开启风场
      let _this = this
      _this.loading = true
      _this.$ajax
        .get('https://sakitam-fdd.github.io/wind-layer/data/wind.json')
        .then(res => {
          let Data = res.data
          this.windLayers = new WindLayer(Data, {
            windOptions: {
              colorScale: [
                'rgb(36,104, 180)',
                'rgb(60,157, 194)',
                'rgb(128,205,193 )',
                'rgb(151,218,168 )',
                'rgb(198,231,181)',
                'rgb(238,247,217)',
                'rgb(255,238,159)',
                'rgb(252,217,125)',
                'rgb(255,182,100)',
                'rgb(252,150,75)',
                'rgb(250,112,52)',
                'rgb(245,64,32)',
                'rgb(237,45,28)',
                'rgb(220,24,32)',
                'rgb(180,0,35)',
              ],
              lineWidth: 2,
              frameRate: 20,
              globalAlpha: 0.6,
              velocityScale: 1 / 50,
              paths: 3000,
              generateParticleOption: false,
            },
          })
          _this.$nextTick(() => {
            _this.map.addLayer(_this.windLayers)
            _this.online = false
            _this.loading = false
            _this.$message({
              type: 'success',
              message: '开启风场成功',
            })
          })
        })
        .catch(e => {
          console.log(e)
        })
    },
    closeWind() {
      // 关闭风场
      this.map.removeLayer(this.windLayers)
      this.online = this.online ? false : true
      this.$message({
        type: 'success',
        message: '关闭风场成功!',
      })
    },
  },
  mounted() {
    this.initMap()
  },
}
</script>
<style>
#popup-content .info {
  margin: 0px;
  padding: 0px;
}
</style>
<style scoped>
.box {
  position: relative;
}

.label {
  font-size: 20px;
}
#map {
  width: 100%;
  height: 99vh;
}
.ol-popup {
  position: absolute;
  background-color: #eeeeee;
  -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  padding: 15px;
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 12px;
  left: -100px;
  width: 180px;
}

.ol-popup:after,
.ol-popup:before {
  top: 100%;
  border: solid transparent;
  content: '';
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
}

.ol-popup:after {
  border-top-color: #eeeeee;
  border-width: 10px;
  left: 48px;
  margin-left: 40px;
}

.ol-popup:before {
  border-top-color: #cccccc;
  border-width: 10px;
  left: 48px;
  margin-left: 40px;
}

.ol-popup-closer {
  text-decoration: none;
  position: absolute;
  top: 2px;
  right: 8px;
}

.ol-popup-closer:after {
  content: '✖';
}

.close_on {
  position: absolute;
  top: 10px;
  right: 10px;
}
</style>


参考链接:
https://github.com/sakitam-fdd/wind-layer(官方github)
https://sakitam-fdd.github.io/wind-layer/ 参考文章:https://blog.csdn.net/u010065726/article/details/106338194/ 注意:需要安装ol和ol-wind, npm i ol ol-wind --save

免责声明:文章转载自《Vue中开启关闭风场》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇聚类算法Mysql 查询优化,索引原理与慢查询优化。下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

趋势买卖--主图叠加

1、趋势买卖(主图叠加)   一、公式编写 1、第一种 N:=20; M:=32;P1:=80;P2:=100; VAR1:=(C+H+O+L)/4;卖出:XMA(VAR1,N)*(1+P1/1000),COLORGREEN,LINETHICK2;买入:XMA(VAR1,M)*(1-P2/1000),COLORMAGENTA,LINETHICK2;幅度:1...

Mac版sublime text右键open in browser 不能识别中文名解决办法

问题描述: Mac下sublime text下打开中文命名的html文件,右键open in browser,浏览器无反应。 解决思路: 要么适应软件,要么改进软件来适应。 1.  将中文名的html文件,改成英文名的html文件来预览。 2.  改造sublime text, 安装插件SideBarEnhancements,使用插件的“open in...

Ubuntu10.04下安装SQLite3(转贴)

Ubuntu linux下安装sqlite3 1.介绍:sqlite3是linux上的小巧的数据库,一个文件就是一个数据库。 2.安装: 要安装sqlite3,可以在终端提示符后运行下列命令: sudo apt-get install sqlite3 检查版本 sqlite3 -version 3.测试 当前目录下建立test.db测试数据库文件 s...

IceCTF Crypto Substituted

题目 Lw! Gyzvecy ke WvyVKT! W'zz by reso dsbdkwksky tzjq teo kly ujr. Teo keujr, gy joy dksurwmq bjdwv vorakeqojalr jmu wkd jaazwvjkwemd. Vorakeqojalr ljd j zemq lwdkeor, jzklesql...

spring security 核心切面

import org.aopalliance.intercept.MethodInterceptor; import org.apache.commons.collections.CollectionUtils; import org.springframework.aop.support.StaticMethodMatcherPointcutAdvis...

【Vue】基于UI库二次组件封装——ant design table(包括支持slot插槽)

vue现在使用非常广泛,对于一些公用的功能我们通常也会封装成组件,同时还有各类的UI组件库给我们开发提供了便利。 为什么要封装成组件 能够把页面抽象成多个相对独立的模块 实现代码重用,提高开发效率和代码质量,使得代码易于维护 为什么要讲基于第三方UI库封装组件 这段时间经手了几个项目,都是后台管理系统的,大家知道后台管理系统最多的就是table以及...