openlayers实现自定义路径
# 概述
本文主要讲述如何在 Openlayers 上选择点,并且将这些点连成一条线作为一条路径。
# 效果展示
- 选点
- 连点成线
# 实现方案
实现步骤也是按照两个思路,先选点,后连线。其中主要涉及到 Openlayers 中Draw
、Feature
和Overlay
等概念,以及动态修改Feature
的样式,涉及到调整线填充图片时的角度调整。
# 选点
选点成线需要明确路径是带有方向的,它的点一般分为三种路线,即起点、途径点和终点。起点和终点就是路径的首末两端,途径点就是起点和终点之间的点,上图中带有数字标识的点,可以有任意个。
因此可以如下定义变量PointFeature
,用于保存调用Draw
方法绘制的feature
。
const PointFeature = ref({
start_point: null,
route_points: [],
end_point: null,
});
2
3
4
5
选点核心逻辑
选点主要通过ol/interaction
的Draw
方法实现。用一个变量activeIndex
来标识当前绘制点的类型,(UI 上可以用一个按钮组),如下:
const drawStart = () => {
exitDraw();
draw = new Draw({
source: vectorLayer.getSource(),
type: "Point",
style: styles.selectPointStyle,
});
mapInstance.addInteraction(draw);
draw.on("drawend", function (event) {
const feature = event.feature;
console.log(feature.getGeometry().getCoordinates(), event);
if (activeIndex.value == listChildren[0].value) {
//起点
if (PointFeature.value.start_point) {
vectorLayer.getSource().removeFeature(PointFeature.value.start_point);
}
PointFeature.value.start_point = feature;
} else if (activeIndex.value == listChildren[1].value) {
//途径点
PointFeature.value.route_points.push(feature);
const coordinates = feature.getGeometry().getCoordinates();
addOverlay({
coordinates,
index: PointFeature.value.route_points.length,
});
} else {
//终点
if (PointFeature.value.end_point) {
vectorLayer.getSource().removeFeature(PointFeature.value.end_point);
}
PointFeature.value.end_point = feature;
}
feature.setStyle(getPointsStyle());
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
绘制结束时会触发 Openlayers 的drawend
事件,通过判断activeIndex
类型来区分点类型,将绘制的feature
即event.feature
保存到PointFeature
中去。这段代码涉及到vectorLayer.getSource().removeFeature()
方法的调用,就是保证起点和终点的唯一性。
最后调用feature.setStyle()
方法就是给不同点的渲染不同的样式。
# 连点成线
在上面提到PointFeature
变量中保存了选点生成的feature
,可以通过feature.getGeometry().getCoordinates()
方法来获取点的坐标信息。
实现如下:
const lineFeature = new Feature({
geometry: new LineString(PathResult.value),
});
const lineStyle = getStyleFunction({
color: "#25C2F2",
width: 4,
imgsrc: rightImg,
wrapperRotation: (r) => -r,
});
lineFeature.setStyle(lineStyle);
vectorLayer.getSource().addFeature(lineFeature);
2
3
4
5
6
7
8
9
10
11
12
13
14
这段代码就是生成一个线要素,值得一提的是自定义方法getStyleFunction
,该方法在Openlayers用图片填充点 (opens new window)有介绍过,主要就是加载一个图片,然后自动计算线条是否有角度,并且将图片旋转一定的角度,与线条方向保持一致。