当前位置: 首页 > ops >正文

openlayers利用已知的三个经纬度的坐标点 , 绘制一个贝塞尔曲线

以下是使用OpenLayers根据三个经纬度点绘制贝塞尔曲线的完整实现方案。贝塞尔曲线通过控制点生成平滑曲线,特别适合绘制地图上的弧线、路径等。

实现思路

  1. 贝塞尔曲线原理:使用三个点(起点、控制点、终点)生成二阶贝塞尔曲线。
  2. 坐标转换:将WGS 84经纬度点转换为Web Mercator投影(EPSG:3857)以在地图上正确显示。
  3. 曲线计算:通过贝塞尔公式计算曲线上的多个点,形成近似曲线。
  4. 地图渲染:使用OpenLayers的LineString几何对象绘制曲线。

代码实现

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>OpenLayers贝塞尔曲线绘制</title><script src="https://cdn.jsdelivr.net/npm/ol@7.3.0/dist/ol.js"></script><link href="https://cdn.jsdelivr.net/npm/ol@7.3.0/ol.css" rel="stylesheet"><style>.map {width: 100%;height: 400px;}</style>
</head>
<body><div id="map" class="map"></div><script>// 1. 定义三个经纬度点(起点、控制点、终点)const startPoint = [116.3, 39.9]; // 北京(起点)const controlPoint = [110.0, 30.5]; // 控制点(黄海海域)const endPoint = [121.4, 31.2]; // 上海(终点)// 2. 经纬度转Web Mercator投影const transformPoints = (points) => {return points.map(point => ol.proj.transform(point, 'EPSG:4326', 'EPSG:3857'));};// 3. 计算二阶贝塞尔曲线上的点function calculateBezierPoints(start, control, end, segments = 50) {const points = [];for (let t = 0; t <= 1; t += 1 / segments) {// 二阶贝塞尔公式: B(t) = (1-t)²P0 + 2(1-t)tP1 + t²P2const x = Math.pow(1 - t, 2) * start[0] + 2 * (1 - t) * t * control[0] + Math.pow(t, 2) * end[0];const y = Math.pow(1 - t, 2) * start[1] + 2 * (1 - t) * t * control[1] + Math.pow(t, 2) * end[1];points.push([x, y]);}return points;}// 4. 转换坐标并计算贝塞尔曲线const [startMerc, controlMerc, endMerc] = transformPoints([startPoint, controlPoint, endPoint]);const bezierPoints = calculateBezierPoints(startMerc, controlMerc, endMerc, 100);// 5. 创建地图const map = new ol.Map({target: 'map',layers: [new ol.layer.Tile({source: new ol.source.OSM()  // 使用OpenStreetMap作为底图})],view: new ol.View({center: ol.proj.transform([118, 35], 'EPSG:4326', 'EPSG:3857'),zoom: 5})});// 6. 创建贝塞尔曲线要素const bezierCurve = new ol.geom.LineString(bezierPoints);const feature = new ol.Feature({geometry: bezierCurve,name: '贝塞尔曲线'});// 7. 设置曲线样式feature.setStyle(new ol.style.Style({stroke: new ol.style.Stroke({color: 'rgba(255, 0, 0, 0.8)',  // 红色半透明width: 3,lineDash: [10, 5]  // 虚线样式})}));// 8. 添加曲线到地图const vectorSource = new ol.source.Vector({features: [feature]});const vectorLayer = new ol.layer.Vector({source: vectorSource});map.addLayer(vectorLayer);// 9. 添加起点、控制点和终点标记const addMarker = (coord, label) => {const marker = new ol.Feature({geometry: new ol.geom.Point(coord),name: label});marker.setStyle(new ol.style.Style({image: new ol.style.Circle({radius: 6,fill: new ol.style.Fill({ color: 'blue' }),stroke: new ol.style.Stroke({ color: 'white', width: 2 })}),text: new ol.style.Text({text: label,font: '14px Arial',fill: new ol.style.Fill({ color: 'black' }),stroke: new ol.style.Stroke({ color: 'white', width: 2 }),offsetY: -10})}));vectorSource.addFeature(marker);};addMarker(startMerc, '起点');addMarker(controlMerc, '控制点');addMarker(endMerc, '终点');</script>
</body>
</html>

核心代码解析

  1. 贝塞尔曲线计算

    • 使用二阶贝塞尔公式:( B(t) = (1-t)^2P_0 + 2(1-t)tP_1 + t^2P_2 )
    • 通过参数t从0到1的变化,计算曲线上的多个点,segments参数控制精度
  2. 坐标转换

    • 使用ol.proj.transform()将WGS 84经纬度转换为Web Mercator坐标
    • 确保所有点在同一投影系统下计算
  3. 地图渲染

    • 使用LineString几何对象表示曲线
    • 通过Style设置曲线样式(颜色、宽度、虚线等)
    • 添加标记点显示起点、控制点和终点

效果展示

在这里插入图片描述

(注:实际运行时会显示OpenStreetMap底图和红色贝塞尔曲线)

http://www.xdnf.cn/news/5134.html

相关文章:

  • LeetCode 39 LeetCode 40 组合总和问题详解:回溯算法与剪枝优化(Java实现)
  • 鸿蒙 所有API缩略图鉴
  • PyTorch API 10 - benchmark、data、批处理、命名张量
  • 如何创建伪服务器,伪接口
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月10日第73弹
  • linux搭建hadoop学习
  • 测试左移系列-产品经理实战-实战认知1
  • 简易图片编辑工具,支持抠图和替换背景
  • 如何启动vue项目及vue语法组件化不同标签应对的作用说明
  • 使用互斥锁保护临界
  • “AI+城市治理”智能化解决方案
  • 前端面试每日三题 - Day 30
  • VScode密钥(公钥,私钥)实现免密登录【很细,很全,附带一些没免密登录成功的一些解决方法】
  • [Linux]多线程(二)原生线程库---pthread库的使用
  • 学习黑客5 分钟深入浅出理解Linux Common Directories
  • Spark MLlib网页长青
  • Python-函数
  • Git Github Tutorial
  • STL-list
  • 【生存技能】ubuntu 24.04 如何pip install
  • OSCP - Proving Grounds - EvilBox-One
  • 软考中级数据库备考-上午篇
  • 使用FastAPI和React以及MongoDB构建全栈Web应用01 概述
  • 养生:开启健康生活的密钥
  • 使用定时器监视当前PID 如果当前程序关闭 UI_Core.exe 也随之自动关闭实现方法
  • 用纯HTML和CSS仿写知乎登录页面
  • Python中的事件循环是什么?事件是怎么个事件?循环是怎么个循环
  • ABB电机控制和保护单元与Profibus DP主站转Modbus TCP网关快速通讯案例
  • 【Pandas】pandas DataFrame corr
  • 计算机网络 4-2-2 网络层(IPv4)