openlayers绘制图标并定位到图标

该文展示了一个Vue3项目中利用TypeScript和SASS,通过OpenLayers库来绘制地图、设置图标以及实现图标位置的点击和定位功能。代码示例包括创建地图、定义矢量图层、设置图标样式以及处理点击事件以改变图标颜色。
摘要由CSDN通过智能技术生成

openlayers绘制图标并定位到图标

环境

vue3 ts sass

具体代码

<template>
  <div class="btn-wrapper">
    <span style="color: red"> 上一个定位的点 {{ prePoint }}</span>
    <button
      class="button"
      v-for="(item, index) in data"
      :key="index"
      @click="handleMoveToTarget(item)"
    >
      定位到目标 item
    </button>
  </div>
  <div id="map" class="map"></div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import 'ol/ol.css'
import { Map, View, Feature } from 'ol'
import { XYZ, Vector as SourceVector } from 'ol/source'
import TileLayer from 'ol/layer/Tile'
import { Vector as LayerVector } from 'ol/layer'
import { Style, Icon, Text, Fill, Stroke } from 'ol/style'
import { Point } from 'ol/geom'

const data = [
  [158.6, 29.8],
  [159, 30.5],
  [159.4, 30.9],
  [160.2, 31.8],
  [160.5, 32.2],
  [162.4, 33.4],
  [164, 34.3],
  [166.2, 35.7],
  [167.6, 36.3]
]

const map = ref<Map>()
const prePoint = ref<number[]>([])

const customLayer = new LayerVector({
  source: new SourceVector()
})

const setItem = (point: number[], color = '#000') => {
  const anchor = new Feature({
    name: `[${point}]`,
    geometry: new Point(point)
  })

  // 设置样式,在样式中就可以设置图标
  anchor.setStyle(
    new Style({
      image: new Icon({
        src: '/logo.png',
        width: 60,
        height: 60,
        color: color
      }),
      text: new Text({
        textAlign: 'center', // 位置
        textBaseline: 'middle', // 基准线
        font: 'normal 12px 微软雅黑', // 文字样式
        text: anchor.get('name'),
        // text: '文字样式',
        fill: new Fill({
          // 文本填充样式(即文字颜色)
          color: '#fff'
        }),
        stroke: new Stroke({
          color: '#999',
          width: 1
        })
      }),
      stroke: new Stroke({
        color: '#fff',
        width: 100
      })
    })
  )
  // 添加点击事件
  ;(anchor.on as any)('click', (e: any) => {
    console.log(e, 'e')
  })

  customLayer.getSource()?.addFeature(anchor)
}

const init = () => {
  map.value = new Map({
    target: 'map',
    layers: [
      new TileLayer({
        source: new XYZ({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
          wrapX: false
        })
      }),
      customLayer
    ],
    view: new View({
      projection: 'EPSG:4326',
      // 定位
      // center: [110.592595, 20.911173],
      center: [158.6, 29.8],
      zoom: 8,
      maxZoom: 18,
      minZoom: 1
    })
  })

  data.forEach((item) => {
    setItem(item)
  })

  map.value?.on('click', function (this: any, e) {
    console.log(e.pixel)
    console.log(this)

    this.forEachFeatureAtPixel(e.pixel, function (feature: any) {
      // 为点击的feature发送自定义的click消息
      feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event: e })
    })
  })
}

// 定位到目标
const handleMoveToTarget = (point: number[]) => {
  // 还原原来的颜色
  if (prePoint.value.length) {
    setItem(prePoint.value)
  }

  let zoom = map.value?.getView().getZoom() as number
  const duration = 2000
  map.value?.getView().animate(
    {
      center: point,
      duration: duration
    },
    (e) => {
      console.log(e, 'callback-1')
    }
  )

  map.value?.getView().animate(
    {
      zoom: zoom - 1,
      duration: duration / 2
    },
    {
      zoom: zoom,
      duration: duration / 2
    },
    (e) => {
      console.log(e, 'callback-2')
      setItem(point, '#0f0')

      prePoint.value = point
    }
  )
}

onMounted(init)
</script>

<style lang="scss">
.map {
  height: 100vh;
  width: 100%;
  background-color: #000;
}

.btn-wrapper {
  width: 100%;
  position: fixed;
  left: 150px;
  top: 30px;
  z-index: 2;

  .button + .button {
    margin-left: 20px;
  }
}
</style>

文档

http://openlayers.vip/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaofei0627

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值