MapBox GL地图上绘制圆形区域,在区域中心点添加标记点及文本提示的实现方法

MapBox GL地图上绘制圆形区域,在区域中心点添加标记点及文本提示的实现方法:

// 绘制影响区域
const addArea = (circle) => {if (!map.current || !circle) return;const areaId = `circle-area`;const epicenterId = `circle-epicenter`;const radiusKm = circle.strongRadius;// 使用传入的中心点坐标const epicenter = [parseFloat(circle.longitude), parseFloat(circle.latitude)];// 清除旧图层clearLayers();// 创建圆形多边形const polygon = createCirclePolygon(epicenter, radiusKm);// 添加数据源map.current.addSource(areaId, {type: 'geojson',data: polygon});// 添加区域填充层map.current.addLayer({id: `${areaId}-fill`,type: 'fill',source: areaId,paint: {'fill-color': '#FF4D4F','fill-opacity': 0.2}});// 添加区域边框层map.current.addLayer({id: `${areaId}-border`,type: 'line',source: areaId,paint: {'line-color': '#FF4D4F','line-width': 3,'line-dasharray': [2, 2]}});// 创建文字元素并添加到地图const textElement = document.createElement('div');textElement.className = 'circle-text';textElement.style.cssText = `position: absolute;transform: translate(-50%, -100%);background: rgba(0, 0, 0, 0.9);color: white;padding: 6px 10px;border-radius: 6px;font-size: 12px;font-weight: bold;white-space: pre-line;text-align: center;max-width: 150px;word-break: break-word;z-index: 10;pointer-events: none;border: 2px solid #ff4d4f;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);line-height: 1.4;`;textElement.textContent = `覆盖半径为${radiusKm || 'XX'}公里`;// 将文字元素添加到地图容器const mapContainerEl = map.current.getContainer();mapContainerEl.appendChild(textElement);// 更新文字位置随地图移动const updateTextPosition = () => {const point = map.current.project(epicenter);textElement.style.left = `${point.x}px`;textElement.style.top = `${point.y}px`;};map.current.on('move', updateTextPosition);updateTextPosition();// 创建图标标记 - 只创建一个标记const iconElement = document.createElement('div');iconElement.className = 'circle-icon';iconElement.style.width = '40px';iconElement.style.height = '40px';iconElement.style.backgroundImage = `url(${require('@assets/images/map/earthquakeCenter.png')})`;iconElement.style.backgroundSize = 'contain';iconElement.style.backgroundRepeat = 'no-repeat';iconElement.style.cursor = 'pointer';iconElement.title = `覆盖半径为${radiusKm || 'XX'}公里`;const marker = new window.mapboxgl.Marker({element: iconElement,anchor: 'center'}).setLngLat(epicenter).addTo(map.current);// 管理标记状态setMarkers(prev => [...prev, {id: epicenterId,marker: marker,element: iconElement,type: 'circle',textElement: textElement,updateTextPosition: updateTextPosition}]);
};// 清理图层
const clearLayers = () => {const areaId = 'circle-area';const epicenterId = 'circle-epicenter';if (map.current) {// 移除图层if (map.current.getLayer(`${areaId}-fill`)) map.current.removeLayer(`${areaId}-fill`);if (map.current.getLayer(`${areaId}-border`)) map.current.removeLayer(`${areaId}-border`);if (map.current.getSource(areaId)) map.current.removeSource(areaId);// 使用函数式更新来访问最新的markers状态setMarkers(prev => {// 在当前作用域内清理标记prev.forEach(marker => {if (marker.id === epicenterId) {if (marker.marker) {marker.marker.remove();}if (marker.textElement && marker.textElement.parentNode) {marker.textElement.parentNode.removeChild(marker.textElement);}if (marker.updateTextPosition) {map.current.off('move', marker.updateTextPosition);}}});// 从状态中移除标记return prev.filter(marker => marker.id !== epicenterId);});}
};// 创建精确的圆形多边形(考虑投影变形)const createCirclePolygon = (center, radiusKm, points = 64) => {const coords = [];const latRad = center[1] * Math.PI / 180;// 计算经度和纬度的每公里度数const latKm = 1 / 110.574;const lngKm = 1 / (111.320 * Math.cos(latRad));for (let i = 0; i < points; i++) {const angle = (i / points) * 2 * Math.PI;const dx = radiusKm * Math.cos(angle) * lngKm;const dy = radiusKm * Math.sin(angle) * latKm;coords.push([center[0] + dx, center[1] + dy]);}// 闭合多边形coords.push(coords[0]);return {type: 'Feature',geometry: {type: 'Polygon',coordinates: [coords]},properties: {radius: radiusKm}};};

上述方法的调用:

addArea({depth: 10,latitude: 40.62,magnitude: 3.55,strongRadius: 4.5,longitude: 115.369
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920257.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Docker Compose 的若依多服务一键部署java项目实践

基于Docker Compose的若依多服务一键部署实践 在项目开发中&#xff0c;多服务部署常常让人头疼。环境配置复杂、操作步骤繁琐&#xff0c;稍不注意就容易出错。不过&#xff0c;有了 Docker Compose &#xff0c;这些问题就简单多啦&#xff01;它能帮我们高效编排多个容器&am…

MyBatis-Plus 使用 Wrapper 自定义 SQL 查询

目录 1. 注意事项 2. 示例代码 2.1 实体类 2.2 Mapper 接口 2.3 测试类 3. 运行效果 4. 总结 在实际项目中&#xff0c;虽然 MyBatis-Plus 提供了丰富的内置方法和 QueryWrapper 条件构造器&#xff0c;但有时我们需要 自定义 SQL 来实现更复杂的查询逻辑。 MyBatis-Plu…

NumPy/PyTorch/C char数组内存排布

1. 关于 np.random.randn(2, 3) 的数据存储数据类型 (Data Type)&#xff1a;np.random.randn 默认生成的是 64位&#xff08;8字节&#xff09;双精度浮点数 (numpy.float64)。所以每个数字占 8个字节&#xff0c;而不是8位&#xff08;1字节&#xff09;。这是一个关键区别。…

Elasticsearch精准匹配与全文检索对比

在 Elasticsearch 中&#xff0c;精准匹配检索和全文检索匹配检索是两种核心查询方式&#xff0c;主要区别在于匹配规则、分词处理、适用场景和底层实现逻辑。以下是详细对比&#xff1a;一、核心区别总结特性精准匹配&#xff08;Term Query&#xff09;全文检索&#xff08;M…

【鸿蒙开发001】上下翻页-翻书效果实现【可复用】

先看效果&#xff1a;一、设计思路&#xff1a;根据所需要的最终效果&#xff0c;最终设计如下&#xff1a;&#xff08;1&#xff09;整体设计了4个模块&#xff0c;这里分别标记为&#xff1a;A1&#xff0c;A2&#xff0c;B1&#xff0c;B2。具体说明如下&#xff1a;A模块&…

H20 性能表现之 Qwen3-235B

上期为大家分享了H20性能表现之Qwen3-Coder-480B&#xff08;以下称480B&#xff09;&#xff0c;今天&#xff0c;我为大家继续带来新的评测&#xff0c;这次&#xff0c;介绍的是 Qwen3-235B-A22B-Instruct-2507&#xff08;以下称235B&#xff09;&#xff0c;这也是阿里这阵…

Diagnosing bias and variance|诊断偏差和方差

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

前端性能优化:从指标监控到全链路落地(2024最新实战指南)

前端性能优化&#xff1a;从指标监控到全链路落地&#xff08;2024最新实战指南&#xff09; 引言&#xff1a;性能不是“可选项”&#xff0c;而是“生存线” 在前端开发中&#xff0c;“性能优化”常被视为“锦上添花”的工作——但数据告诉我们&#xff0c;它早已成为决定…

Kafka面试精讲 Day 1:Kafka核心概念与分布式架构

【Kafka面试精讲 Day 1】Kafka核心概念与分布式架构 在“Kafka面试精讲”系列的第1天&#xff0c;我们将深入解析Apache Kafka最根本的基石——核心概念与分布式架构。作为大数据和后端开发领域面试中的“必考题”&#xff0c;诸如“Kafka是如何实现高吞吐量的&#xff1f;”、…

github copilot学生认证教程,免费使用两年Copilot Pro!!(避免踩坑版)

先放结果&#xff0c;本人是先后申请了三次&#xff1a; 1、第一次直接用的学生证&#xff0c;打开对着电脑摄像头直接拍了一张&#xff0c;失败了&#xff0c;如下&#xff0c;理由是没有开启双重认证&#xff01;&#xff01;&#xff0c;并且学生证内页没有学校名称&#x…

Shiro介绍以及一个原始例子

目录基本功能核心组件应用场景优势Shiro 核心工作流程&#xff08;以 Web 应用登录为例&#xff09;一个例子【验证&#xff0c;授权]:Shiro 是一个强大且易用的 Java 安全框架&#xff0c;提供了 身份验证、授权、加密和会话管理等功能&#xff0c;可帮助开发人员轻松确保应用…

AI-调查研究-59-机器人 行业职业地图:发展路径、技能要求与薪资全解读

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布&#xff01;“快的…

LeetCode算法日记 - Day 22: 提莫攻击、Z字形变换

目录 1. 提莫攻击 1.1 题目解析 1.2 解法 1.3 代码实现 2. Z字形变换 2.1 题目解析 2.2 解法 2.3 代码实现 1. 提莫攻击 495. 提莫攻击 - 力扣&#xff08;LeetCode&#xff09; 在《英雄联盟》的世界中&#xff0c;有一个叫 “提莫” 的英雄。他的攻击可以让敌方英…

Unity笔记(七)——四元数、延迟函数、协同程序

写在前面&#xff1a;写本系列(自用)的目的是回顾已经学过的知识、记录新学习的知识或是记录心得理解&#xff0c;方便自己以后快速复习&#xff0c;减少遗忘。主要是C#代码部分。六、四元数欧拉角具有旋转约定&#xff0c;也就是说&#xff0c;无论你调整角度的顺序是什么&…

用大语言模型提升语音翻译:一种全新的端到端方法

用大语言模型提升语音翻译:一种全新的端到端方法 在语音翻译领域,如何将说话内容快速准确地转化为另一种语言,一直是研究者们关注的焦点。随着大语言模型(LLM)的兴起,我们迎来了一个全新的机遇:利用LLM的强大能力,来提升语音翻译系统的性能。最近,一项名为“End-to-E…

freeModbus TCP收发数据一段时间后,出现掉线情况(time out问题)

话说这个是真难找啊。我仅仅发表我找到的问题。我在接收几十到几百次数据的时候&#xff0c;会出现连接超时&#xff0c;也就是time out。而且ping也ping不通。也就是说明lwip出了问题。首先我先介绍modbus的这个流程。首先是函数eMBTCPInit( MB_TCP_PORT_USE_DEFAULT )我们进入…

Linux Web环境一键安装脚本集合(非docker)

✨重磅&#xff01;盹猫的个人小站正式上线啦&#xff5e;诚邀各位技术大佬前来探秘&#xff01;✨ —— 专为开发者打造的宝藏基地&#xff0c;等你来探索&#xff01; 这里有&#xff1a; &#x1f525; 硬核技术干货&#xff1a;编程技巧、开发经验、踩坑指南&#xff0c;带…

原生安卓#基于Android的爱好者分享论坛的设计与实现/基于Android在线论坛系统app/基于Android的论坛系统的设计与实现的设计与实现

原生安卓#基于Android的爱好者分享论坛的设计与实现/基于Android在线论坛系统app/基于Android的论坛系统的设计与实现的设计与实现

基于Android的超市购物系统的设计与实现、基于android的在线商城app/基于android的在线销售系统app#android

基于Android的超市购物系统的设计与实现、基于android的在线商城app/基于android的在线销售系统app#android

C++14 到 C++20 全面解析:语言新特性、标准库演进与实战案例

一、前言C 作为一门历史悠久且不断演进的编程语言&#xff0c;在 C11 之后进入了“现代化”的快车道。C11 被称为 C 的第二次诞生&#xff0c;引入了 lambda 表达式、智能指针、右值引用、并发支持等革命性特性。然而&#xff0c;C 的标准化进程并没有止步于此。C14、C17 和 C2…