欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > openlayers 点击多边形弹框,高亮多边形,自定义属性传递,鼠标悬浮多边形上动态修改鼠标样式

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

2024/10/26 1:17:39 来源:https://blog.csdn.net/weixin_56624286/article/details/139780539  浏览:    关键词:openlayers 点击多边形弹框,高亮多边形,自定义属性传递,鼠标悬浮多边形上动态修改鼠标样式

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

1 需求

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

2 分析

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

  • 为vectorSource填充features,有两种方法:

    1. features: [new Feature()]
    2. features: new GeoJSON().readFeatures(geoJSON)
  • 为vectorLayer填充style,有两种写法:

    1. style:new Style()
    2. style:{‘stroke-color’: ‘rgba(255, 128, 100, 1)’}
  • 获取鼠标点击活悬浮时的features,有两种写法:

    1. map.value.forEachFeatureAtPixel()
    2. map.value.getFeaturesAtPixel()

3 实现


没有录上鼠标样式改变,复制代码查看

<template><div id="map" class="map"></div><div id="popup" class="ol-popup" ref="container"><a href="#" id="popup-closer" class="ol-popup-closer" ref="closer"></a><div id="popup-content" ref="content"></div></div>
</template><script setup lang="ts">
import { Feature, Map, Overlay, View } from 'ol';
import { GeoJSON } from 'ol/format';
import { Polygon } from 'ol/geom';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { get, toLonLat } from 'ol/proj';
import { Vector, XYZ } from 'ol/source';
import { Fill, Stroke, Style } from 'ol/style';
import { toStringHDMS } from 'ol/coordinate.js';const projection = get('EPSG:4326');const layerTypeMap = {vector: ['vec', 'cva'], // [矢量底图, 矢量注记]image: ['img', 'cia'], // [影像底图, 影像注记]terrain: ['ter', 'cta'] // [地形晕渲, 地形注记]
};const map = ref();
const container = ref();
const content = ref();
const closer = ref();
const overlay = shallowRef();
const feature = ref();
const geoJSON = {type: 'FeatureCollection',crs: {type: 'name',properties: {name: 'EPSG:4326'}},features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: [[[112, 31],[113, 32.2],[114, 30.5],[112, 31]]]},properties: {//自定义属性pointer: true}}]
};onMounted(() => {initMap('image');
});const initMap = (layerType = 'image') => {const key = '替换为天地图key';overlay.value = new Overlay({element: container.value,autoPan: {animation: {duration: 250}}});// c: 经纬度投影 w: 墨卡托投影const matrixSet = 'c';map.value = new Map({target: 'map',layers: [// 底图new TileLayer({source: new XYZ({url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=${layerTypeMap[layerType][0]}_${matrixSet}&tk=${key}&x={x}&y={y}&l={z}`,projection})}),// 注记new TileLayer({source: new XYZ({url: `https://t{0-7}.tianditu.gov.cn/DataServer?T=${layerTypeMap[layerType][1]}_${matrixSet}&tk=${key}&x={x}&y={y}&l={z}`,projection})}),new VectorLayer({source: new Vector({features: [new Feature({geometry: new Polygon([[[116, 31],[118, 32.2],[119, 30.5],[116, 31]]]),pointer: true //自定义属性,可用于修改鼠标样式、单击轮廓弹框,改变feature样式})]}),style: new Style({fill: new Fill({color: 'rgba(228, 147, 87, 0.4)'}),stroke: new Stroke({color: 'rgba(228, 147, 87, 1)',width: 3})})}),new VectorLayer({source: new Vector({features: [new Feature({geometry: new Polygon([[[114, 31],[115, 32.2],[116, 30.5],[114, 31]]])})]}),style: {//layer样式可以这样写'stroke-color': 'rgba(255, 255, 100, 1)','stroke-width': 1.5,'fill-color': 'rgba(255, 255, 100, 0.5)','circle-radius': 6,'circle-fill-color': 'rgba(255, 255, 100, 1)'}}),new VectorLayer({source: new Vector({features: new GeoJSON().readFeatures(geoJSON) //读取geojson格式数据}),style: {//layer样式可以这样写'stroke-color': 'rgba(255, 128, 100, 1)','stroke-width': 1.5,'fill-color': 'rgba(255, 128, 100, 0.5)','circle-radius': 6,'circle-fill-color': 'rgba(255, 128, 100, 1)'}})],overlays: [overlay.value],view: new View({center: [116.406393, 39.909006],projection: projection,zoom: 5,maxZoom: 17,minZoom: 1})});map.value.on('pointermove', (e: any) => {// 根据自定义属性改变鼠标样式// 方法一// map.value.getTargetElement().style.cursor = 'auto';// let pixel = map.value.getEventPixel(e.originalEvent);// map.value.forEachFeatureAtPixel(pixel, (feature: any) => {//   const property = feature.getProperties();//   if (property.pointer) {//     map.value.getTargetElement().style.cursor = 'pointer'; //设置鼠标样式//   } else {//     map.value.getTargetElement().style.cursor = 'auto';//   }// });// 方法二map.value.getTargetElement().style.cursor = 'auto';const features = map.value.getFeaturesAtPixel(e.pixel);features.forEach(feature => {const property = feature.getProperties();if (property.pointer) {map.value.getTargetElement().style.cursor = 'pointer'; //设置鼠标样式} else {map.value.getTargetElement().style.cursor = 'auto';}});});map.value.on('click', e => {// 根据自定义属性改变轮廓样式,也可以进行弹框if (feature.value) {feature.value.setStyle();closer.value.onclick();}const features = map.value.getFeaturesAtPixel(e.pixel);const f = features.find(f => f.getProperties().pointer);if (f) {feature.value = f;f.setStyle(new Style({fill: new Fill({color: 'rgba(255, 255, 100, 0.5)'}),stroke: new Stroke({color: 'rgba(255, 255, 100, 1)',width: 3})}));const coordinate = e.coordinate;const hdms = toStringHDMS(toLonLat(coordinate));content.value.innerHTML = '<p>当前经纬度:</p><code>' + hdms + '</code>';overlay.value.setPosition(coordinate);}});closer.value.onclick = function () {overlay.value.setPosition(undefined);closer.value.blur();if (feature.value) {feature.value.setStyle();}return false;};
};
</script>
<style scoped lang="scss">
.map {width: 100%;height: 100%;
}
.ol-popup {position: absolute;background-color: rgba(255, 255, 255, 0.7);box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);padding: 15px;border-radius: 10px;border: 1px solid #cccccc;bottom: 12px;left: -50px;min-width: 280px;
}
.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: rgba(255, 255, 255, 0.7);border-width: 10px;left: 48px;margin-left: -10px;
}
.ol-popup:before {border-top-color: #cccccc;border-width: 11px;left: 48px;margin-left: -11px;
}
.ol-popup-closer {text-decoration: none;position: absolute;top: 2px;right: 8px;
}
.ol-popup-closer:after {content: '✖';
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com