【WebGIS实例】(1)MapboxGL绘制端点有符号的线
一、前言
工作上来了个需求,就是在地图上画一条端点有箭头的线(其实就是画带箭头轨迹线)。
因为第一次做,所以想了挺久,因为知识面不够,最后只能用最蠢的方法:硬画,步骤如下:① 画线段 ② 画起点的符号 ③画终点的符号
用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' // 图片的位置}
})
到这一步就完成了,然后需要注意的是,在想要删除这个端点带符号的线的时候,需要:
- 删除图片:
map.removeImage('lineStartPoint')
- 删除线图层:
map.removeLayer('trackLayer')
- 删除线数据源:
map.removeSource('trackSource')
- 删除符号图层:
map.removeLayer('trackStart')
- 删除符号数据源:
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绘制端点有符号的线相关推荐
- winhttp get 实例_实例|CASS的绘制的航道断面,怎么多了两个边沟? 135
大家好,欢迎来到我的专栏.这是我原创的第135篇CASS应用技术干货文章.希望对你有所帮助,写文不易,请点赞哦! 上周有个小伙伴,私信咨询:用CASS算航道断面土方,绘制出来的横断面设计线怎么多了两个 ...
- Asp.Net实例:C# 绘制统计图(一) ——柱状图
Asp.Net实例:C# 绘制统计图 (柱状图, 折线图, 扇形图) 统计图形种类繁多, ...
- CAD制图初学入门之CAD软件中如何绘制剖切符号?
作为一名刚开始进行CAD制图初学入门的人,在使用国产CAD软件绘制剖面图的过程中,不知道该如何添加剖切符号的时候该怎么办呢?接下来的CAD制图初学入门教程就来给大家介绍一下在CAD软件中关于CAD绘制 ...
- Python中Tkinter模块的Canvas控件使用学习(2:绘制简单工程符号)
之前学习HTML5中Canvas绘图方法时,为测试函数功能,使用JavaScript在Canvas中绘制了多种工程图符号,下面两张图是工程图符号的原图.本文参照JavaScript绘图程序,使用p ...
- 技术篇-符号制作-线符号制作
在制图中,需要大量使用到线符号,例如道路.河流.国界.流域界.管线等.线符号制作相对于点符号制作难度稍微增加,因为线符号一般都具有一定的规则,例如一些边界符号,就需要点-杠 的规律进行显示:铁路线是黑 ...
- Revit通过绘制边界和踢面线创建楼梯
在创建楼梯(按草图)时,可以通过绘制边界和踢面,而非使 Revit 自动计算楼梯梯段. 绘制楼梯的迹线时,通过以下方法可以更好地进行控制. 绘制边界线和踢面线的步骤 样例 使用边界和踢面工具绘制的楼梯 ...
- R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战
R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战 目录 R语言使用ggpubr包的ggline函数绘制各种漂亮形式的线图实战
- matlab 绘制有效前沿和资本市场线
matlab 绘制有效前沿和资本市场线 这篇文章将介绍如何利用较新版本的 matlab 中的 Portfolio 对象绘制有效前沿和资本市场线等内容. 数据获取 注册tushare账号 以前推荐用tu ...
- cesium开发系列:SimplePolylineGeometry绘制不同颜色的多段线
记录一下用SimplePolylineGeometry绘制不同颜色的多段线,代码看下面 //创建多段线和每段颜色 addColorLine(){//多颜色线段var m= this;//创建多段线和每 ...
- cesium绘制不同颜色的多段线(SimplePolylineGeometry)
记录一下用SimplePolylineGeometry绘制不同颜色的多段线,代码看下面 //创建多段线和每段颜色 const positions = []; const colors = []; fo ...
最新文章
- [Win7]如何还原[.bat]文件关联
- 爬取了 48048 条评论数据,解读 9.3 分的《毒液》是否值得一看?
- 设计模式学习笔记-观察者模式(转)
- python包介绍:numpy
- springmvc中action跳转
- 常数中有换行符的错误
- css中auto的用法
- 【Alpha】Scrum Meeting 2
- poi导出excel写入公式_poi导出excel公式
- tftpd获取文件失败
- 现实中的CTF大赛都有哪些人参与
- 山东理工ACM【1532】矩阵输出
- 前端学习第二课——基础1——基本标签
- Python画多条线在一个图里
- Ubuntu 18.04 LTS (Bionic Beaver) 已经发布附官网下载链接
- Day 40 多表查询以及pymysql相关操作
- sidebar(侧边栏文字)
- 杨绛十句话,最好背下来
- python计算abcd*4=dcba_abcd乘以4等于dcba的解答方法
- 「儒系」产品经理:管理预期,做好增长的3个核心要素
热门文章
- 如何使用OpenCV-Python-dlib实现有关闭眼的检测、眨眼次数的计算?(附源码,绝对可用)
- VS2010“未能正确加载包”问题解决方法小汇
- PKM全民推广系列四:“个人知识管理”的知识分类体系
- flex布局文字溢出显示省略号失效的解决方法
- 还不快点刷面试题,史上最全Java工程师面试题汇总,全会月薪至少3W
- 魔域充值卡表cq_card里chk_sum参数的算法
- 报错Check constraint “book_chk_1“ is violated。难道MySQL中insert 语句只能一条一条插入?
- 千亿商用车车联网市场,智能车载终端企业如何抢食?
- dubbo反序列化问题 Unable to find class: path
- 超级详细-NMOS、PMOS的工作原理及相关内容整理(下)