场景
Vue+Openlayer使用Draw实现交互式绘制线段:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121287934
在上面已经实现交互式绘制线段基础上,怎样实现测量距离。

注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、页面上添加按钮与map
<template>
<div>
<div>
<el-button type="primary" @click="beginCalDistance">开始测距</el-button>
<el-button type="primary" @click="cancleCalDistance">取消测距</el-button>
</div>
<div id="app">
<div id="map" class="map"></div>
</div>
</div>
</template>
2、引入相关依赖
//导入基本模块 import "ol/ol.css"; import Map from "ol/Map"; import View from "ol/View"; import { Fill, Style, Stroke } from "ol/style"; //导入相关模块 import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer"; import { TileWMS, Vector as VectorSource } from "ol/source"; import { Select, Draw } from "ol/interaction"; import { getLength } from "ol/sphere"; import { LineString } from "ol/geom"; import Overlay from "ol/Overlay";
3、声明变量
export default { name: "olMapImageWMSDrawLineAndCalDistance", data() { return { map: null, // map地图 layer: null, //地图图层 lineLayer: null, //线图层 draw: null, lineSource: null, coordinate: [], measureTooltipElement: null, measureTooltip: null, sketch: null, geom: null, }; },
4、在页面初始化之后调用初始化地图的方法
//初始化地图 initMap() { //地图图层 this.layer = new TileLayer({ source: new TileWMS({ //不能设置为0,否则地图不展示。 ratio: 1, url: "http://localhost:8000/geoserver/nyc/wms", params: { LAYERS: "nyc:nyc_roads", STYLES: "", VERSION: "1.1.1", tiled: true, }, serverType: "geoserver", }), }); //线的图层 this.lineSource = new VectorSource({ wrapX: false }); this.lineLayer = new VectorLayer({ source: this.lineSource, }); this.map = new Map({ //地图容器ID target: "map", //引入地图 layers: [this.layer, this.lineLayer], view: new View({ //地图中心点 center: [987777.93778, 213834.81024], zoom: 14, minZoom: 6, // 地图缩放最小级别 maxZoom: 19, }), }); },
5、开始测试按钮的点击事件中
//开始测距 beginCalDistance() { //调用绘图工具并传递类型为线,其他类型有Point,LineString,Polygon,Circle this.onAddInteraction("LineString"); //创建一个新的测距提示 this.createMeasureTooltip(); },
调用绘图功能并传递类型为线以及给地图添加交互onAddInteraction方法
// 绘图工具 onAddInteraction(type) { let self = this; //勾绘矢量图形的类 this.draw = new Draw({ //source代表勾绘的要素属于的数据集 source: self.lineSource, //type 表示勾绘的要素包含的 geometry 类型 type: type, }); //绘制开始时触发的事件 this.draw.on("drawstart", function (evt) { self.sketch = evt.feature; //提示框的坐标 var tooltipCoord = evt.coordinate; //定义一个事件监听,监听几何要素的change事件 var listener = self.sketch.getGeometry().on("change", function (evt) { //获取绘制的几何对象 self.geom = evt.target; //定义一个输出对象,用于记录长度 var output; //判断交互类型是否为线 if (self.geom instanceof LineString) { //输出多线段的长度 output = self.formatLength(self.geom); //获取多线段的最后一个点的坐标 tooltipCoord = self.geom.getLastCoordinate(); } //设置测量提示框的内标签为最终输出结果 self.measureTooltipElement.innerHTML = output; self.measureTooltipElement.className = "ol-tooltip ol-tooltip-static draw_km"; //设置测量提示框的位置坐标 self.measureTooltip.setPosition(tooltipCoord); }); }); //绘制结束时触发的事件 this.draw.on("drawend", function (e) { //输出坐标信息 const geometry = e.feature.getGeometry(); let pointArr = geometry.getCoordinates(); self.coordinate.push(pointArr); console.log("self.coordinate=" + self.coordinate); //移除交互 self.removeDraw(); }); //添加交互 self.map.addInteraction(this.draw); },
创建测距提示的方法createMeasureTooltip
//创建一个新的测距提示 createMeasureTooltip() { let self = this; //如果已经存在帮助提示框则移除 if (self.measureTooltipElement) { self.measureTooltipElement.parentNode.removeChild( self.measureTooltipElement ); } //创建帮助提示要素的div self.measureTooltipElement = document.createElement("div"); //设置帮助提示要素的样式 self.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure"; //创建一个帮助提示的覆盖标注 self.measureTooltip = new Overlay({ element: self.measureTooltipElement, offset: [0, -15], positioning: "bottom-center", }); //将帮助提示的覆盖标注添加到地图中 self.map.addOverlay(self.measureTooltip); },
其中又用到测量距离的方法formatLength
// 测量距离 formatLength(line) { //计算平面距离 var length = getLength(line); //定义输出变量 var output; //如果长度大于1000,则使用km单位,否则使用m单位 if (length > 1000) { output = Math.round((length / 1000) * 100) / 100 + " " + "km"; } else { output = Math.round(length * 100) / 100 + " " + "m"; } return output; },
6、取消测距方法的点击事件
// 取消测距 cancleCalDistance() { let self = this; this.map.removeInteraction(this.draw); this.lineSource.clear(); let layerArr = this.map.getOverlays(); var deleteOverlayArr = []; layerArr.forEach((item) => { if ( item.values_.element.className === "ol-tooltip ol-tooltip-static draw_km" ) { deleteOverlayArr.push(item); } }); deleteOverlayArr.forEach((item) => { self.map.removeOverlay(item); }); },
7、完整示例代码
<template>
<div>
<div>
<el-button type="primary" @click="beginCalDistance">开始测距</el-button>
<el-button type="primary" @click="cancleCalDistance">取消测距</el-button>
</div>
<div id="app">
<div id="map" class="map"></div>
</div>
</div>
</template>
<script>
//导入基本模块
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import { Fill, Style, Stroke } from "ol/style";
//导入相关模块
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { TileWMS, Vector as VectorSource } from "ol/source";
import { Select, Draw } from "ol/interaction";
import { getLength } from "ol/sphere";
import { LineString } from "ol/geom";
import Overlay from "ol/Overlay";
export default {
name: "olMapImageWMSDrawLineAndCalDistance",
data() {
return {
map: null, // map地图
layer: null, //地图图层
lineLayer: null, //线图层
draw: null,
lineSource: null,
coordinate: [],
measureTooltipElement: null,
measureTooltip: null,
sketch: null,
geom: null,
};
},
mounted() {
this.initMap();
},
methods: {
//开始测距
beginCalDistance() {
//调用绘图工具并传递类型为线,其他类型有Point,LineString,Polygon,Circle
this.onAddInteraction("LineString");
//创建一个新的测距提示
this.createMeasureTooltip();
},
// 取消测距
cancleCalDistance() {
let self = this;
this.map.removeInteraction(this.draw);
this.lineSource.clear();
let layerArr = this.map.getOverlays();
var deleteOverlayArr = [];
layerArr.forEach((item) => {
if (
item.values_.element.className ===
"ol-tooltip ol-tooltip-static draw_km"
) {
deleteOverlayArr.push(item);
}
});
deleteOverlayArr.forEach((item) => {
self.map.removeOverlay(item);
});
},
// 绘图工具
onAddInteraction(type) {
let self = this;
//勾绘矢量图形的类
this.draw = new Draw({
//source代表勾绘的要素属于的数据集
source: self.lineSource,
//type 表示勾绘的要素包含的 geometry 类型
type: type,
});
//绘制开始时触发的事件
this.draw.on("drawstart", function (evt) {
self.sketch = evt.feature;
//提示框的坐标
var tooltipCoord = evt.coordinate;
//定义一个事件监听,监听几何要素的change事件
var listener = self.sketch.getGeometry().on("change", function (evt) {
//获取绘制的几何对象
self.geom = evt.target;
//定义一个输出对象,用于记录长度
var output;
//判断交互类型是否为线
if (self.geom instanceof LineString) {
//输出多线段的长度
output = self.formatLength(self.geom);
//获取多线段的最后一个点的坐标
tooltipCoord = self.geom.getLastCoordinate();
}
//设置测量提示框的内标签为最终输出结果
self.measureTooltipElement.innerHTML = output;
self.measureTooltipElement.className =
"ol-tooltip ol-tooltip-static draw_km";
//设置测量提示框的位置坐标
self.measureTooltip.setPosition(tooltipCoord);
});
});
//绘制结束时触发的事件
this.draw.on("drawend", function (e) {
//输出坐标信息
const geometry = e.feature.getGeometry();
let pointArr = geometry.getCoordinates();
self.coordinate.push(pointArr);
console.log("self.coordinate=" + self.coordinate);
//移除交互
self.removeDraw();
});
//添加交互
self.map.addInteraction(this.draw);
},
//删除交互
removeDraw() {
this.map.removeInteraction(this.draw);
},
//创建一个新的测距提示
createMeasureTooltip() {
let self = this;
//如果已经存在帮助提示框则移除
if (self.measureTooltipElement) {
self.measureTooltipElement.parentNode.removeChild(
self.measureTooltipElement
);
}
//创建帮助提示要素的div
self.measureTooltipElement = document.createElement("div");
//设置帮助提示要素的样式
self.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
//创建一个帮助提示的覆盖标注
self.measureTooltip = new Overlay({
element: self.measureTooltipElement,
offset: [0, -15],
positioning: "bottom-center",
});
//将帮助提示的覆盖标注添加到地图中
self.map.addOverlay(self.measureTooltip);
},
//初始化地图
initMap() {
//地图图层
this.layer = new TileLayer({
source: new TileWMS({
//不能设置为0,否则地图不展示。
ratio: 1,
url: "http://localhost:8000/geoserver/nyc/wms",
params: {
LAYERS: "nyc:nyc_roads",
STYLES: "",
VERSION: "1.1.1",
tiled: true,
},
serverType: "geoserver",
}),
});
//线的图层
this.lineSource = new VectorSource({ wrapX: false });
this.lineLayer = new VectorLayer({
source: this.lineSource,
});
this.map = new Map({
//地图容器ID
target: "map",
//引入地图
layers: [this.layer, this.lineLayer],
view: new View({
//地图中心点
center: [987777.93778, 213834.81024],
zoom: 14,
minZoom: 6, // 地图缩放最小级别
maxZoom: 19,
}),
});
},
// 测量距离
formatLength(line) {
//计算平面距离
var length = getLength(line);
//定义输出变量
var output;
//如果长度大于1000,则使用km单位,否则使用m单位
if (length > 1000) {
output = Math.round((length / 1000) * 100) / 100 + " " + "km";
} else {
output = Math.round(length * 100) / 100 + " " + "m";
}
return output;
},
},
};
</script>
<style scoped>
.map {
100%;
height: 800px;
}
</style>