vue3-openlayers 点击多边形弹框,高亮多边形,自定义属性传递,鼠标悬浮多边形上动态修改鼠标样式

本篇介绍一下使用vue3-openlayers点击多边形弹框,高亮多边形,自定义属性传递,鼠标悬浮多边形上动态修改鼠标样式

1 需求

  • 加载天地图,polygon
  • 传递自定义属性
  • 标悬浮在polygon上,根据自定义属性,动态修改鼠标样式为pointer
  • 点击polygon,根据自定义属性,高亮,弹框

2 分析

主要是 vue3-openlayers 中 地图事件,overlay等功能的使用

3 实现

javascript 复制代码
<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
    ref="mapRef"
    @click="handleClick"
    @pointermove="handlePointerMove"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />

    <ol-tile-layer>
      <ol-source-tianditu
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
        ref="sourceRef"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-tile-layer>
      <ol-source-tianditu
        :isLabel="true"
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-vector-layer>
      <ol-source-vector>
        <ol-feature :properties="{ pointer: true }">
          <ol-geom-polygon
            :coordinates="[
              [
                [112, 31],
                [113, 32.2],
                [114, 30.5],
                [112, 31]
              ]
            ]"
          ></ol-geom-polygon>
          <ol-style>
            <ol-style-fill color="rgba(228, 147, 87, 0.4)"></ol-style-fill>
            <ol-style-stroke color="rgba(228, 147, 87, 1)" :width="3"></ol-style-stroke>
          </ol-style>
        </ol-feature>
				<ol-feature >
          <ol-geom-polygon
            :coordinates="[
              [
                [114, 31],
                [115, 32.2],
                [115, 30.5],
                [114, 31]
              ]
            ]"
          ></ol-geom-polygon>
          <ol-style>
            <ol-style-fill color="rgba(255, 128, 87, 0.4)"></ol-style-fill>
            <ol-style-stroke color="rgba(255, 128, 87, 1)" :width="3"></ol-style-stroke>
          </ol-style>
        </ol-feature>
      </ol-source-vector>
    </ol-vector-layer>
    <ol-overlay ref="overlayRef" :autoPan="true" :position="position" v-if="info">
      <div class="overlay-content">
        {{ info }}
      </div>
    </ol-overlay>
  </ol-map>
</template>

<script setup lang="ts">
import { Fill, Stroke, Style } from 'ol/style';
import { toStringHDMS } from 'ol/coordinate.js';
import {  toLonLat } from 'ol/proj';


const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const rotation = ref(0);
const mapRef = ref();
const overlayRef = ref(null);
const key = '替换为天地图key';
const sourceRef = ref(null);
const feature = ref();
const info=ref();
const position=ref();
// layerType  img, vec, ter, cia, cta
//  'vec', 'cva'  矢量底图, 矢量注记
//  'img', 'cia'  影像底图, 影像注记
//  'ter', 'cta'  地形晕渲, 地形注记

const style = new Style({
  fill: new Fill({
    color: 'rgba(228, 147, 87, 0.4)'
  }),
  stroke: new Stroke({
    color: 'rgba(228, 147, 87, 1)',
    width: 3
  })
});

onMounted(() => {
  const source = sourceRef.value?.source;
	const overlay = overlayRef.value?.overlay;
});

const handleClick = e => {
  //click事件也可以用mapRef在mounted中进行绑定 mapRef.value.map.on('click', (e: any) => {}),类似openlayers原生写法
  if (feature.value) {
    feature.value.setStyle(style);
		info.value='';
  }
  const features = mapRef.value.map.getFeaturesAtPixel(e.pixel);
  const f = features.find(f => f.getProperties().pointer);
  const highLight = style.clone();
  highLight.getFill()?.setColor('rgba(255, 255, 100, 0.4)');
  highLight.getStroke()?.setColor('rgba(255, 255, 100, 1)');
  if (f) {
    feature.value = f;
    f.setStyle(highLight);
    const coordinate = e.coordinate;
    const hdms = toStringHDMS(toLonLat(coordinate));
		info.value='当前经纬度:'+ hdms ;
		position.value=coordinate;
  }
};

const handlePointerMove = e => {
  mapRef.value.map.getTargetElement().style.cursor = 'auto';
  const features = mapRef.value.map.getFeaturesAtPixel(e.pixel);
  features.forEach(feature => {
    const property = feature.getProperties();
    if (property.pointer) {
      mapRef.value.map.getTargetElement().style.cursor = 'pointer'; //设置鼠标样式
    } else {
      mapRef.value.map.getTargetElement().style.cursor = 'auto';
    }
  });
};
</script>
<style scoped lang="scss">
.overlay-content {
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 5px 10px rgb(2 2 2 / 20%);
  padding: 10px 20px;
  font-size: 16px;
  color: black;
}</style>
相关推荐
huabuyu9 分钟前
基于 React + MarkdownIt 的 Markdown 渲染器实践:支持地图标签和长按复制
前端
在这儿不行14 分钟前
Android 15边到边模式
前端
源猿人17 分钟前
企业级文件浏览系统的Vue实现:架构设计与最佳实践
前端·javascript·数据可视化
红红大虾17 分钟前
Defold引擎中关于CollectionProxy的使用
前端·游戏开发
最后一个农民工23 分钟前
vue3实现仿豆包模版式智能输入框
前端·vue.js
xw51 小时前
uni-app中v-if使用”异常”
前端·uni-app
!win !1 小时前
uni-app中v-if使用”异常”
前端·uni-app
IT_陈寒2 小时前
Java 性能优化:5个被低估的JVM参数让你的应用吞吐量提升50%
前端·人工智能·后端
南囝coding2 小时前
《独立开发者精选工具》第 018 期
前端·后端