openlayers结合turf 画(绘制)贝塞尔样本曲线仿marks3d火星科技(含draw拓展)

基础用法

    • pointArr:存储绘制的点的数组。
    • isDrawing:布尔值,控制绘制状态。
  1. 绘制函数

    • updateLine:清除源中的所有特征,并在绘制状态下,如果点数组长度大于1,则添加贝塞尔曲线特征。
    • updateLineWithTemporaryPoint:在绘制状态下,将临时点添加到点数组中,清除源,并添加贝塞尔曲线特征。
    • genBezierGeom:使用 Turf.js 的 lineStringbezierSpline 函数生成贝塞尔曲线的 GeoJSON 特征。
  2. 事件监听

    • pointermove:在地图上移动时,如果处于绘制状态,使用当前坐标更新贝塞尔曲线。
    • click:在地图上点击时,如果处于绘制状态,将点击的坐标添加到点数组中,并更新贝塞尔曲线。
    • dblclick:在地图上双击时,结束绘制状态。
xml 复制代码
<!DOCTYPE html>
<html lang="">
<head>
  <meta charset="utf-8" />
  <script src="https://openlayers.org/en/v5.3.0/build/ol.js"></script>
  <link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css">
  <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
</head>
<body>
<div id="map" class="map"></div>
<script>
  const bSource = new ol.source.Vector({
    wrapX: false,
  });
  const bLayer = new ol.layer.Vector({
    source: bSource
  });
  let map = new ol.Map({
    target: 'map',
    layers: [bLayer],
    view: new ol.View({
      center: [0, 0],
      projection: "EPSG:4326",
      zoom: 4
    })
  });
  let pointArr = [[0,0], [11,11]];
  let isDrawing = true; // 控制绘制状态
  updateLine();
  function updateLine(){
    bSource.clear();
    if (isDrawing) {
      if (pointArr.length > 1) {
        bSource.addFeature((new ol.format.GeoJSON()).readFeature(genBezierGeom()));
      }
    }
  }

  map.on('pointermove', function(evt) {
    const coordinate = evt.coordinate;
    if (isDrawing) {
      updateLineWithTemporaryPoint(coordinate);
    }
  });

  map.on('click', function(evt) {
    if (isDrawing) {
      pointArr.push(evt.coordinate);
      updateLine();
    }
  });

  map.on('dblclick', function() {
    isDrawing = false; // 结束绘制
  });

  function updateLineWithTemporaryPoint(coordinate) {
    if (isDrawing) {
      const tempPointArr = [...pointArr, coordinate];
      bSource.clear();
      if (tempPointArr.length > 1) {
        bSource.addFeature((new ol.format.GeoJSON()).readFeature(genBezierGeom(tempPointArr)));
      }
    }
  }

  function genBezierGeom(points = pointArr) {
    var line = turf.lineString(points);
    var curved = turf.bezierSpline(line, {sharpness: 1});
    const lineFeature = turf.lineString(curved.geometry.coordinates);
    return lineFeature;
  }
</script>
<style>
    #map{
        width: 100vw;
        height: 100vh;
    }
    *{
        margin: 0;
        padding: 0;
    }
</style>
</body>
</html>

拓展openlayers的draw方法

  • option.type = 'polyline':指定绘制的类型为折线(polyline)。
  • option.geometryFunction:定义一个函数,用于自定义几何体的形状。在这里,它被用来将普通的折线转换为贝塞尔曲线。
arduino 复制代码
option.type = 'polyline'
option.geometryFunction = function (coordinates: any, geometry: any) {
  if (!geometry) {
    geometry = new ol.geom.LineString([])
  }
  if (coordinates.length > 1) {
    const line: any = {
      type: 'Feature',
      geometry: {
        type: 'LineString',
        coordinates: coordinates
      }
    }
    const curved = turf.bezierSpline(line)
    geometry.setCoordinates(curved.geometry.coordinates)
  }
  return geometry
}
```
const draw = new ol.interaction.Draw(option)
map.addInteraction(draw)
```
相关推荐
大龄程序员狗哥3 分钟前
第30篇:使用Flask部署你的第一个AI模型——打造简易Web API(项目实战)
前端·人工智能·flask
AI砖家28 分钟前
解剖 Claude Code:如何搭建一个企业级的私有化 AI 编程助手
前端·人工智能·ai编程
用户5757303346241 小时前
拒绝“首屏爆炸”:用 React 哨兵模式与懒加载打造丝滑列表
前端
大腕先生1 小时前
通用分页超详细介绍(附带源代码解析&页面展示效果)
xml·java·linux·服务器·开发语言·前端·idea
睿智的海鸥2 小时前
Markdown 语法大全详解
开发语言·前端·javascript·css·html
Highcharts.js2 小时前
用Highcharts如何动态向一个序列添加点
前端·javascript·react.js·highcharts
HookJames2 小时前
设计Section 09 · Cost & Lead Time Factors 的完整 Block Editor 操作步骤
前端
玖玖passion2 小时前
React 常用 Hooks 函数及使用方法完全指南(useState / useEffect / useRef / useContext / useCallback / useMemo / useReducer)
前端·javascript
Awu12272 小时前
⚡精通Claude第6课-Hooks钩子系统:从前端视角玩转AI自动化工作流
前端·aigc·claude
椰猫子2 小时前
Spring Framework(Bean)
java·前端·spring