vue 使用openlayers加载图片,并实现图片上标点,点击弹窗

vue 使用openlayers加载图片,并实现图片上标点,点击弹窗

  • 安装
npm install ol@7.5.1 --save
  • vue组件

<template>
  <div class="generalized">
    <div id="map" ref="myMap" style="width: 100%; height: 100%"></div>

    <!-- 弹窗 -->
    <div v-if="isShowPopup" class="popup" :style="{ left: left + 'px', top: top + 'px' }">
      <div class="p-header">
        {{ selectRow.name }}

        <div class="close" @click="isShowPopup = false">x</div>
      </div>
      <div class="p-content">
        <div class="p-row">
          <span>点位信息1:</span>
          <span>1111</span>
        </div>
        <div class="p-row">
          <span>点位信息2:</span>
          <span>2222</span>
        </div>
      </div>
    </div>

    <!-- -->
  </div>
</template>

<script>
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Point } from 'ol/geom'
import * as olInteraction from 'ol/interaction'
import DragRotateAndZoom from 'ol/interaction/DragRotateAndZoom'
import ImageLayer from 'ol/layer/Image'
import { ImageStatic } from 'ol/source'
import { getCenter } from 'ol/extent'
import { Projection } from 'ol/proj'
import { Icon, Style, Text } from 'ol/style'
import Fill from 'ol/style/Fill'
import Feature from 'ol/Feature'
import Stroke from 'ol/style/Stroke'

//导入相关模块
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { TileWMS, Vector as VectorSource } from 'ol/source'
export default {
  data() {
    return {
      map: null, // map地图
      imgy: '',
      imgx: '',
      // 图标管理器
      iconLayer: '',
      // 图标集合
      featureList: [],
      // 点位列表
      pointsList: [
        {
          x: 157,
          y: 616,
          zIndex: 2,
          icon: require('../../assets/marker1.png'),
          name: '点位1',
          pointId: 1,
          alarmFlag: false,
        },
        {
          x: 157,
          y: 686,
          zIndex: 2,
          icon: require('../../assets/marker2.png'),
          name: '点位2',
          pointId: 2,
          alarmFlag: false,
        },
      ],
      left: 0,
      top: 0,
      isShowPopup: false,
      selectRow: {},
    }
  },

  mounted() {
   this.initMap()
  },

  methods: {
    /**
     * 初始化地图
     */
    initMap() {
      // 图片的宽高
      this.imgy = 992
      this.imgx = 3557
      let extent = [0, 0,  this.imgx, this.imgy]
      let projection = new Projection({
        code: 'xkcd-image',
        units: 'pixels',
        extent: extent,
      })

      this.map = new Map({
        //地图容器ID
        target: 'map',
        interactions: olInteraction.defaults().extend([new DragRotateAndZoom()]),
        //引入地图
        layers: [
          new ImageLayer({
            source: new ImageStatic({
              url: require('@/assets/要加载的图片.jpg'),
              projection: projection,
              imageExtent: extent,
            }),
          }),
        ],
        view: new View({
          projection: projection,
          center: [this.imgx * 0.5, this.imgy * 0.6],
          // 当前缩放倍数
          zoom: 2.5,
          // 最大缩放倍数
          maxZoom: 7,
          // 最小缩放倍数
          minZoom: 1,
        }),
      })

      /**
       * 添加图标
       */
      this.pointsList.forEach((item) => {
        this.addDevicePoint(item)
      })

      const vectorSource = new VectorSource()
      this.iconLayer = new VectorLayer({
        source: vectorSource,
      })
      // 将图标数组添加到图层中
      this.iconLayer.getSource().addFeatures(this.featureList)
      // 添加图层
      this.map.addLayer(this.iconLayer)

      this.mapClick()
    },



    // 添加图标
    addDevicePoint(item) {
      // 设置图片位置
      const iconFeature = new Feature({
        geometry: new Point([item.x, item.y]),
      })
      // 设置样式,这里使用图片
      iconFeature.setStyle([
        new Style({
          image: new Icon({
            // 指定锚 x 值的单位。的值'fraction'表示 x 值是图标的一部分。的值'pixels'表示以像素为单位的 x 值。
            anchorXUnits: 'fraction',
            // 左下角为原点
            anchorOrigin: 'bottom-left',
            anchorYUnits: 'fraction',
            anchor: [0.5, 0],
            src: item.icon,
            scale: 0.6,
          }),
          zIndex: item.zIndex,
        }),
        new Style({
          text: new Text({
            text: '',
            font: '14px Microsoft YaHei',
            offsetY: -15,
            offsetX: 15,
            padding: [5, 10, 5, 15],
            textAlign: 'left',
            backgroundFill: new Fill({
              color: item.alarmFlag ? 'rgba(249, 88, 87, 0.5)' : 'rgba(0,111,255,0.5)', //提示背景色
            }),
            fill: new Fill({
              color: '#fff',
            }),
          }),
          zIndex: item.zIndex,
        }),
      ])
      // 给图层设置设备图标name和id属性,用作独立 区分
      iconFeature.name = item.name
      iconFeature.id_ = item.pointId
      // 将图片Feature添加到Source
      this.featureList.push(iconFeature)
    },
    // 监听地图点击事件
    mapClick() {
      var _this = this
      this.map.on('singleclick', (evt) => {
        console.log(evt.coordinate, evt)

        this.left = evt.pixel_[0]
        this.top = evt.pixel_[1]

        var feature = _this.map.forEachFeatureAtPixel(evt.pixel, function (feature) {
          return feature
        })

        if (feature) {
          var id_ = feature.id_
          this.pointsList.forEach((element) => {
            if (element.pointId == id_) {
              this.selectRow = element
            }
          })

          console.log(id_)
        } else {
          this.selectRow = {}
        }

        this.isShowPopup = feature ? true : false

        console.log('feature:', feature)
      })
    },
  },
}
</script>

<style lang="less" scoped>
.generalized {
  width: 100%;
  height: 100%;
  position: relative;
}

.popup {
  position: absolute;
  padding: 5px;
  left: 0px;
  top: 0px;
  width: 140px;
  height: auto;
  background: #2a76d8;
  color: #fff;
  border-radius: 5px;

  .p-header {
    font-size: 14px;
    padding: 5px 5px;
    position: relative;

    .close {
      position: absolute;
      right: -5px;
      top: -5px;
      font-size: 12px;
      padding: 0px 5px;
      color: #fff;
      cursor: pointer;
    }
  }

  .p-content {
    background: #fff;
    padding: 5px;
    border-radius: 5px;
  }

  .p-row {
    font-size: 12px;
    color: #000;
    display: flex;
    justify-content: space-between;
  }
}

.red {
  background: #ff1b1b;
}
</style>

最近更新

  1. TCP协议是安全的吗?

    2024-06-16 02:18:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-16 02:18:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-16 02:18:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-16 02:18:01       20 阅读

热门阅读

  1. Spring框架的原理及应用详解(四)

    2024-06-16 02:18:01       8 阅读
  2. 2024.6.15

    2024-06-16 02:18:01       9 阅读
  3. 【LeetCode 5.】 最长回文子串

    2024-06-16 02:18:01       6 阅读
  4. Mac的m系列芯片安装虚拟机--简单流程

    2024-06-16 02:18:01       10 阅读
  5. git 如何拉取最新代码

    2024-06-16 02:18:01       8 阅读
  6. Nacos入门与实践

    2024-06-16 02:18:01       6 阅读
  7. 08:打印字符

    2024-06-16 02:18:01       5 阅读
  8. kubernetes部署dashboard

    2024-06-16 02:18:01       8 阅读
  9. go 协程

    go 协程

    2024-06-16 02:18:01      6 阅读