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

本文主要是介绍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>

这篇关于openlayers 点击多边形弹框,高亮多边形,自定义属性传递,鼠标悬浮多边形上动态修改鼠标样式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072998

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

韦季李输入法_输入法和鼠标的深度融合

在数字化输入的新纪元,传统键盘输入方式正悄然进化。以往,面对实体键盘,我们常需目光游离于屏幕与键盘之间,以确认指尖下的精准位置。而屏幕键盘虽直观可见,却常因占据屏幕空间,迫使我们在操作与视野间做出妥协,频繁调整布局以兼顾输入与界面浏览。 幸而,韦季李输入法的横空出世,彻底颠覆了这一现状。它不仅对输入界面进行了革命性的重构,更巧妙地将鼠标这一传统外设融入其中,开创了一种前所未有的交互体验。 想象

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d