基础用法
-
pointArr
:存储绘制的点的数组。isDrawing
:布尔值,控制绘制状态。
-
绘制函数:
updateLine
:清除源中的所有特征,并在绘制状态下,如果点数组长度大于1,则添加贝塞尔曲线特征。updateLineWithTemporaryPoint
:在绘制状态下,将临时点添加到点数组中,清除源,并添加贝塞尔曲线特征。genBezierGeom
:使用 Turf.js 的lineString
和bezierSpline
函数生成贝塞尔曲线的 GeoJSON 特征。
-
事件监听:
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)
```