场景
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>