一、前言

工作上来了个需求,就是在地图上画一条端点有箭头的线(其实就是画带箭头轨迹线)。
因为第一次做,所以想了挺久,因为知识面不够,最后只能用最蠢的方法:硬画,步骤如下:① 画线段 ② 画起点的符号 ③画终点的符号

用Mapbox GL JS 来实现的话,就是绘制line图层、symbol图层就可以了,效果如下:

仅在线要素的两端绘制

在线段的每一个端点绘制

二、实现

@turf/turf 版本:6.5.0
mapbox-gl 版本: 2.10.0
vue 版本:2.6.14

首先是创建个地图,这部分不是本篇博客的重点,有需要可以参考这篇博客:
搭建基于Vue的Mapbox GL开发框架 | ╰ 羽翼 ╮的博客 (fengwc.cn)

turf.js的下载:npm install @turf/turf


1. 画线

数据格式:GeoJSON
const testJson =

{"type": "FeatureCollection","features": [{"type": "Feature","properties": {},"geometry": {"coordinates": [[112.87972209292184,22.784618902192463],[113.68808368655016,23.434484281968352],[113.0473822753035,23.511377287669646]],"type": "LineString"}}]
}

向地图中添加类型为geojson的数据源,然后再添加类型为line的图层。

map.addSource('trackSource', {type: 'geojson',data: testJson
})
map.addLayer({id: 'trackLayer',type: 'line',source: 'trackSource',paint: {'line-color': '#FFFF00','line-width': 3}
})

2. 获取端点坐标

这部分使用了turf.js的一些方法:

  • 几何对象遍历:geomEach
  • 线段遍历:segmentEach
  • 由一个坐标生成一个点:point
// turf.geomEach可以遍历几何对象(一个完整的多段线),从而获得线串头和尾的坐标
const that = this
turf.geomEach(testJson, function (lineString) {// 获取线头和线尾,并将其转化为GeoJSON格式(turf.point)const lineStart = turf.point(lineString.coordinates[0])const lineEnd = turf.point(lineString.coordinates[lineString.coordinates.length - 1])// 将点存起来that.lineStartList.push(lineStart)that.lineEndList.push(lineEnd)
})

3. 绘制端点符号

上面的过程中,我们以及绘制好了线要素,也得到了端点的geojson并存放在了一个数组中(lineStartList),现在就依据端点数组开始画符号。
这一步实际上就是为地图添加一个symbol图层。

添加符号

// 加载图片
map.loadImage(require('@/assets/jugg.png'), function (_error, img) {map.addImage('lineStartPoint', img)
})

添加数据源

map.addSource('lineStartPoint-source', {type: 'geojson',data: {type: 'FeatureCollection',features: this.lineStartList // 这个就是那一堆端点}
})

添加图层

map.addLayer({id: 'trackStart', // 图层IDtype: 'symbol', // 图层类型source: 'lineStartPoint-source', // 数据源layout: {'icon-image': 'lineStartPoint', // 图片ID'icon-size': 0.5, // 图片的大小'icon-anchor': 'bottom' // 图片的位置}
})

到这一步就完成了,然后需要注意的是,在想要删除这个端点带符号的线的时候,需要:

  1. 删除图片:map.removeImage('lineStartPoint')
  2. 删除线图层:map.removeLayer('trackLayer')
  3. 删除线数据源:map.removeSource('trackSource')
  4. 删除符号图层:map.removeLayer('trackStart')
  5. 删除符号数据源:map.removeSource('lineStartPoint-source')

这样才能彻底将它从地图上删去。

2022年10月31日更新: 若图片和数据源不会要求切换的话,可以写在constructor() {}里,这样在首次创建类的时候加入图片,而不是每次触发方法时加入图片。


三、完整代码

/** @Date: 2022-10-26 16:38:03* @LastEditTime: 2022-10-26 17:29:44* @FilePath: \mapbox-vue\src\views\endpointDraw\drawTrackLine.js* @Description:绘制端点带符号的线。*/import { map } from '@/utils/creatMapbox' // 地图主体
import * as turf from '@turf/turf' // 引入turf.js
import testJson from '@/assets/line.json' // 引入测试数据export default class DrawTrackLine {lineStartList = [] // 线头坐标列表lineEndList = [] // 线尾坐标列表constructor () {console.log('早上好')}// 绘制轨迹线drawTrackLine () {map.addSource('trackSource', {type: 'geojson',data: testJson})map.addLayer({id: 'trackLayer',type: 'line',source: 'trackSource',paint: {'line-color': '#FFFF00','line-width': 3}})// 遍历轨迹线获取头尾坐标const that = this// turf.segmentEach可以遍历每一个线段/* (本段注释代码中便是在线段每个端点绘制的代码)turf.segmentEach(testJson, function (lineString) {console.log(lineString)// 获取线头和线尾,并将其转化为GeoJSON格式(turf.point)const lineStart = turf.point(lineString.geometry.coordinates[0])const lineEnd = turf.point(lineString.geometry.coordinates[lineString.geometry.coordinates.length - 1])that.lineStartList.push(lineStart)that.lineEndList.push(lineEnd)})*/// turf.geomEach可以遍历几何对象(一个完整的多段线)turf.geomEach(testJson, function (lineString) {// 获取线头和线尾,并将其转化为GeoJSON格式(turf.point)const lineStart = turf.point(lineString.coordinates[0])const lineEnd = turf.point(lineString.coordinates[lineString.coordinates.length - 1])that.lineStartList.push(lineStart)that.lineEndList.push(lineEnd)})this.drawLineSymbol() // 绘制线头线尾的符号}// 绘制线头线尾符号drawLineSymbol () {// 加载图片map.loadImage(require('@/assets/jugg.png'), function (_error, img) {map.addImage('lineStartPoint', img)})map.loadImage(require('@/assets/ernaut.png'), function (_error, img) {map.addImage('lineEndPoint', img)})// 添加数据源map.addSource('lineStartPoint-source', {type: 'geojson',data: {type: 'FeatureCollection',features: this.lineStartList}})map.addSource('lineEndPoint-source', {type: 'geojson',data: {type: 'FeatureCollection',features: this.lineEndList}})// 添加图层map.addLayer({id: 'trackStart', // 图层IDtype: 'symbol', // 图层类型source: 'lineStartPoint-source', // 数据源layout: {'icon-image': 'lineStartPoint', // 图片ID'icon-size': 0.5, // 图片的大小'icon-anchor': 'bottom' // 图片的位置}})map.addLayer({id: 'lineEnd', // 图层IDtype: 'symbol', // 图层类型source: 'lineEndPoint-source', // 数据源layout: {'icon-image': 'lineEndPoint', // 图片ID'icon-size': 0.5,'icon-anchor': 'bottom'}})}// 清除该功能绘制的线段符号等等等等clear () {// 清空端点坐标列表this.lineStartList = []this.lineEndList = []// 删除图层与数据源if (map.hasImage('lineStartPoint')) map.removeImage('lineStartPoint')if (map.hasImage('lineEndPoint')) map.removeImage('lineEndPoint')try {map.removeLayer('trackLayer')map.removeLayer('trackStart')map.removeLayer('lineEnd')map.removeSource('trackSource')map.removeSource('lineStartPoint-source')map.removeSource('lineEndPoint-source')} catch (error) {console.log(error)}}
}

四、写在最后

我觉得这个方法很一般,如果您有更好的实现方案,请评论或私信提出。谢谢谢谢!!!

【WebGIS实例】(1)MapboxGL绘制端点有符号的线相关推荐

  1. winhttp get 实例_实例|CASS的绘制的航道断面,怎么多了两个边沟? 135

    大家好,欢迎来到我的专栏.这是我原创的第135篇CASS应用技术干货文章.希望对你有所帮助,写文不易,请点赞哦! 上周有个小伙伴,私信咨询:用CASS算航道断面土方,绘制出来的横断面设计线怎么多了两个 ...

  2. Asp.Net实例:C# 绘制统计图(一) ——柱状图

                         Asp.Net实例:C# 绘制统计图                           (柱状图, 折线图, 扇形图)         统计图形种类繁多, ...

  3. CAD制图初学入门之CAD软件中如何绘制剖切符号?

    作为一名刚开始进行CAD制图初学入门的人,在使用国产CAD软件绘制剖面图的过程中,不知道该如何添加剖切符号的时候该怎么办呢?接下来的CAD制图初学入门教程就来给大家介绍一下在CAD软件中关于CAD绘制 ...

  4. Python中Tkinter模块的Canvas控件使用学习(2:绘制简单工程符号)

      之前学习HTML5中Canvas绘图方法时,为测试函数功能,使用JavaScript在Canvas中绘制了多种工程图符号,下面两张图是工程图符号的原图.本文参照JavaScript绘图程序,使用p ...

  5. 技术篇-符号制作-线符号制作

    在制图中,需要大量使用到线符号,例如道路.河流.国界.流域界.管线等.线符号制作相对于点符号制作难度稍微增加,因为线符号一般都具有一定的规则,例如一些边界符号,就需要点-杠 的规律进行显示:铁路线是黑 ...

  6. Revit通过绘制边界和踢面线创建楼梯

    在创建楼梯(按草图)时,可以通过绘制边界和踢面,而非使 Revit 自动计算楼梯梯段. 绘制楼梯的迹线时,通过以下方法可以更好地进行控制. 绘制边界线和踢面线的步骤 样例 使用边界和踢面工具绘制的楼梯 ...

  7. R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战

    R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战 目录 R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战

  8. matlab 绘制有效前沿和资本市场线

    matlab 绘制有效前沿和资本市场线 这篇文章将介绍如何利用较新版本的 matlab 中的 Portfolio 对象绘制有效前沿和资本市场线等内容. 数据获取 注册tushare账号 以前推荐用tu ...

  9. cesium开发系列:SimplePolylineGeometry绘制不同颜色的多段线

    记录一下用SimplePolylineGeometry绘制不同颜色的多段线,代码看下面 //创建多段线和每段颜色 addColorLine(){//多颜色线段var m= this;//创建多段线和每 ...

  10. cesium绘制不同颜色的多段线(SimplePolylineGeometry)

    记录一下用SimplePolylineGeometry绘制不同颜色的多段线,代码看下面 //创建多段线和每段颜色 const positions = []; const colors = []; fo ...

最新文章

  1. [Win7]如何还原[.bat]文件关联
  2. 爬取了 48048 条评论数据,解读 9.3 分的《毒液》是否值得一看?
  3. 设计模式学习笔记-观察者模式(转)
  4. python包介绍:numpy
  5. springmvc中action跳转
  6. 常数中有换行符的错误
  7. css中auto的用法
  8. 【Alpha】Scrum Meeting 2
  9. poi导出excel写入公式_poi导出excel公式
  10. tftpd获取文件失败
  11. 现实中的CTF大赛都有哪些人参与
  12. 山东理工ACM【1532】矩阵输出
  13. 前端学习第二课——基础1——基本标签
  14. Python画多条线在一个图里
  15. Ubuntu 18.04 LTS (Bionic Beaver) 已经发布附官网下载链接
  16. Day 40 多表查询以及pymysql相关操作
  17. sidebar(侧边栏文字)
  18. 杨绛十句话,最好背下来
  19. python计算abcd*4=dcba_abcd乘以4等于dcba的解答方法
  20. 「儒系」产品经理:管理预期,做好增长的3个核心要素

热门文章

  1. 如何使用OpenCV-Python-dlib实现有关闭眼的检测、眨眼次数的计算?(附源码,绝对可用)
  2. VS2010“未能正确加载包”问题解决方法小汇
  3. PKM全民推广系列四:“个人知识管理”的知识分类体系
  4. flex布局文字溢出显示省略号失效的解决方法
  5. 还不快点刷面试题,史上最全Java工程师面试题汇总,全会月薪至少3W
  6. 魔域充值卡表cq_card里chk_sum参数的算法
  7. 报错Check constraint “book_chk_1“ is violated。难道MySQL中insert 语句只能一条一条插入?
  8. 千亿商用车车联网市场,智能车载终端企业如何抢食?
  9. dubbo反序列化问题 Unable to find class: path
  10. 超级详细-NMOS、PMOS的工作原理及相关内容整理(下)