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

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1

Python清空Word段落样式的三种方法

《Python清空Word段落样式的三种方法》:本文主要介绍如何用python-docx库清空Word段落样式,提供三种方法:设置为Normal样式、清除直接格式、创建新Normal样式,注意需重... 目录方法一:直接设置段落样式为"Normal"方法二:清除所有直接格式设置方法三:创建新的Normal样

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到