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²P2
                const 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底图和红色贝塞尔曲线)

OpenLayers一个强大的JavaScript库,用于创建交互式地图。要在两点之间绘制一个三角形,你可以利用它的矢量图层(Vector Layer)和几何对象(Geometry),例如SimpleGeometry或Polygon。以下是一个基本步骤: 1. 首先,你需要创建一个`VectorSource`,这将是你的数据源: ```javascript const vectorSource = new ol.source.Vector({ // 你可以在这里添加数据点,比如两个点 }); ``` 2. 创建两个点Feature,并将它们添加到source中: ```javascript const point1 = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon1, lat1])), }); vectorSource.addFeature(point1); const point2 = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon2, lat2])), }); vectorSource.addFeature(point2); ``` 3. 创建一个`Triangle`几何,通常由三个点组成,这里我们可以计算三点连线: ```javascript // 计算第三点坐标 const point3 = ol.extent.getCenter([ ol.proj.transform([lon1, lat1], 'EPSG:4326', 'EPSG:3857'), ol.proj.transform([lon2, lat2], 'EPSG:4326', 'EPSG:3857') ]); const triangle = new ol.geom.Polygon([[point1.getGeometry().getCoordinates(), point2.getGeometry().getCoordinates(), point3]]); ``` 4. 将这个三角形添加到一个新的Feature并添加到source中: ```javascript const triangleFeature = new ol.Feature({geometry: triangle}); vectorSource.addFeature(triangleFeature); ``` 5. 最后,在地图上添加矢量图层来显示三角形: ```javascript const layer = new ol.layer.Vector({ source: vectorSource, }); map.addLayer(layer); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值