在前几期实现离线地图初始化以及规划某一特定区域、打点、出现弹窗的基础上,本文主要阐述如何实现在所规划的区域地图上画线,如果你实现了打点的效果,其实这个相对来说还是算比较简单的,因为和打点的代码大差不差。使用openlayers这个技术研究的内容挺多,这个就需要自己多去专研专研了。
提示:因本文实现的具体效果部分涉及到前面文章的知识点,如有不明白的小伙伴可进行查看前几期的文章哦,文章的的实现流程也是按照步骤来的,但是打点和画线不分先后顺序,由于前几期已经阐述过地图初始化这些具体步骤,所以这篇文章不在进行具体代码的演示,只展示需要实现画线的代码。
目录
一、模拟传入的画线数据
二、实现画线方法
1.计算两个中心点
2.设置线条样式
3.遍历线条数据
4.设置线条数据源和线条图层
5.将线条图层添加到地图
6.整合所有代码
三、初始化地图中调用画线方法
一、模拟传入的画线数据
因为考虑到做项目可能地图的画线数据来于后端,这里就简单模拟一下具体画线的后端数据格式,方便能正常显示地图上的线。强调一下这个数据只是为了便于前端正常查看,若正常做项目,数据应该是后端传给前端,这里的type是为了便于区分线条的颜色,如果项目中没有这项要求,可无需考虑,lineData中是经纬度的数据。
const lines = ref([{type: '500',lineData: [{lon: 120.303543,lat: 31.681019},{lon: 120.266053,lat: 31.550228}]},{type: '220',lineData: [{lon: 120.296595,lat: 31.550228},{lon: 120.275891,lat: 31.910984}]},{type: '500',lineData: [{lon: 120.303543,lat: 31.681019},{lon: 120.266053,lat: 31.550228}]},{type: '220',lineData: [{lon: 120.296595,lat: 31.550228},{lon: 120.275891,lat: 31.910984}]}
])
二、实现画线方法
1.计算两个中心点
为了使所画的线至于两个点的中心,这个写了一个计算两个中心的方法。后续在画线方法中进行使用即可。
const getMidPoint = (point1, point2) => {const lon1 = point1[0]const lat1 = point1[1]const lon2 = point2[0]const lat2 = point2[1]const deltaLon = (lon2 - lon1) / 2const deltaLat = (lat2 - lat1) / 2return [lon1 + deltaLon, lat1 + deltaLat]
}
2.设置线条样式
设置线条的具体样式,因为可能线条的颜色会不一样,所以这里将颜色图标作为变量。
// 线样式const getLineStyle = color => {return new Style({stroke: new Stroke({color: color,width: 1.5})})}
3.遍历线条数据
var lineFeature = new Array()let lineFeature2 = nulllines.value.map((line, index) => {// 确保线在两个点中间const points = line.lineData.map(item => fromLonLat([item.lon, item.lat]))if (points.length >= 2) {// 确保至少有两个点const midPoint = getMidPoint(points[0], points[1]) // 计算中点const lineDataWithMidPoint = [points[0], midPoint, points[1]] // 创建包含中点的数组const lineFeature2 = new Feature({geometry: new LineString(lineDataWithMidPoint)})// 根据类型设置线的样式if (line.type == '500') {lineFeature2.setStyle(getLineStyle('#048c12'))} else if (line.type == '220') {lineFeature2.setStyle(getLineStyle('#fe0303'))} else if (line.type == '110') {lineFeature2.setStyle(getLineStyle('#036bf9'))} lineFeature.push(lineFeature2)}})
4.设置线条数据源和线条图层
const linesSource = new VectorSource({features: lineFeature})const lineLayer = new VectorLayer({zIndex: 665,source: linesSource,style: function (feature, resolution) {return feature.getStyle()}})
5.将线条图层添加到地图
map.value.addLayer(lineLayer)
6.整合所有代码
//画线
const drawLine = () => {// 线样式const getLineStyle = color => {return new Style({stroke: new Stroke({color: color,width: 1.5})})}// let newLines = val || []var lineFeature = new Array()let lineFeature2 = nulllines.value.map((line, index) => {// 确保线在两个点中间const points = line.lineData.map(item => fromLonLat([item.lon, item.lat]))if (points.length >= 2) {// 确保至少有两个点const midPoint = getMidPoint(points[0], points[1]) // 计算中点const lineDataWithMidPoint = [points[0], midPoint, points[1]] // 创建包含中点的数组const lineFeature2 = new Feature({geometry: new LineString(lineDataWithMidPoint)})// 根据类型设置线的样式if (line.type == '500') {lineFeature2.setStyle(getLineStyle('#048c12'))} else if (line.type == '220') {lineFeature2.setStyle(getLineStyle('#fe0303'))} else if (line.type == '110') {lineFeature2.setStyle(getLineStyle('#036bf9'))} lineFeature.push(lineFeature2)}})const linesSource = new VectorSource({features: lineFeature})const lineLayer = new VectorLayer({zIndex: 665,source: linesSource,style: function (feature, resolution) {return feature.getStyle()}})map.value.addLayer(lineLayer)
}
三、初始化地图中调用画线方法
// 初始化地图
const init = () => {drawLine()
}