【WebGIS实例】(18)MapboxGL 绘制矢量——线、面

前言

Mapbox GL JS 版本:3.6.0

该博客仅供学习参考,如果您是计划在实际项目中实现该功能,也推荐您直接使用已有的功能库:

  • 官方案例:Draw a polygon and calculate its area
  • mapbox-gl-draw:mapbox/mapbox-gl-draw: Draw tools for mapbox-gl-js

绘制线段

请添加图片描述

/*** @description: 绘制线*/
export class DrawLine {nodeCoordinateList; // 节点坐标pointFeatureCollection; // 点GeoJSON集合lineFeatureCollection; // 线GeoJSON集合constructor(map, callback) {this.map = map;this.addPoint = this.addPoint.bind(this);this.end = this.end.bind(this);this.dynamicAction = this.dynamicAction.bind(this);this.callback = callback; // 回调函数}// 初始化图层init() {// 添加线图层this.map.addLayer({id: "_lineLayer",type: "line",source: {type: "geojson",data: this.lineFeatureCollection,},paint: {"line-color": "#ffff00","line-width": 2,"line-opacity": 1,"line-dasharray": [2, 4],},});// 添加动态线图层this.map.addLayer({id: "_dynamicLineLayer",type: "line",source: {type: "geojson",data: this.lineFeatureCollection,},paint: {"line-color": "#ffff00","line-width": 2,"line-opacity": 1,"line-dasharray": [2, 4],},});// 添加点图层this.map.addLayer({id: "_pointLayer",type: "circle",source: {type: "geojson",data: this.pointFeatureCollection,},paint: {"circle-color": "#ffffff","circle-radius": 3,"circle-stroke-width": 2,"circle-stroke-color": "#ffff00",},});}// 重置数据reset() {this.nodeCoordinateList = [];this.pointFeatureCollection = {type: "FeatureCollection",features: [],};this.lineFeatureCollection = {type: "FeatureCollection",features: [],};}// 开始绘制start() {this.reset();this.init();this.map.doubleClickZoom.disable(); // 禁止双击缩放this.map.getCanvas().style.cursor = "crosshair"; // 设置鼠标样式this.map.on("click", this.addPoint);this.map.on("dblclick", this.end);this.map.on("mousemove", this.dynamicAction);}// 结束绘制end(e) {this.addPoint(e);this.map.off("click", this.addPoint);this.map.off("dblclick", this.end);this.map.off("mousemove", this.dynamicAction);// this.map.once('click', (e) => { // ! 连续绘制//   this.clear()//   this.start()// })this.map.getCanvas().style.cursor = ""; // 恢复鼠标样式this.callback && this.callback(this.nodeCoordinateList);}// 清除绘制clear() {this.map.getCanvas().style.cursor = ""; // 恢复鼠标样式this.map.doubleClickZoom.enable(); // 恢复双击缩放this.map.off("click", this.addPoint);this.map.off("dblclick", this.end);this.map.off("mousemove", this.dynamicAction);if (this.map.getSource("_pointLayer")) {this.map.removeLayer("_pointLayer");this.map.removeSource("_pointLayer");}if (this.map.getSource("_lineLayer")) {this.map.removeLayer("_lineLayer");this.map.removeSource("_lineLayer");}if (this.map.getSource("_dynamicLineLayer")) {this.map.removeLayer("_dynamicLineLayer");this.map.removeSource("_dynamicLineLayer");}}// 添加点addPoint(e) {const lngLat = [e.lngLat.lng, e.lngLat.lat];const pointList = this.pointFeatureCollection;const lineList = this.lineFeatureCollection;if (pointList.features.length > 0) {let prev = pointList.features[pointList.features.length - 1];lineList.features.push({type: "Feature",geometry: {type: "LineString",coordinates: [prev.geometry.coordinates, lngLat],},});this.map.getSource("_lineLayer").setData(lineList);}pointList.features.push({type: "Feature",geometry: {type: "Point",coordinates: lngLat,},});this.map.getSource("_pointLayer").setData(pointList);this.nodeCoordinateList.push(lngLat);}// 鼠标移动事件dynamicAction(e) {const pointList = this.pointFeatureCollection;const lngLat = [e.lngLat.lng, e.lngLat.lat];if (pointList.features.length > 0) {const prev = pointList.features[pointList.features.length - 1];const json = {type: "Feature",geometry: {type: "LineString",coordinates: [prev.geometry.coordinates, lngLat],},};this.map.getSource("_dynamicLineLayer").setData(json);}}
}

使用方法

import { DrawLine } from "./map/index.js"; // 引入// 实例化
const drawVector = new DrawLine(map, (data) => {console.log('绘制完毕后的回调', data);
});// 开始绘制
drawVector.start();// 结束并清除绘制结果
drawVector.clear();

绘制多边形

请添加图片描述

/*** @description: 绘制多边形*/
export class DrawPolygon {map; // 地图对象nodeCoordinateList; // 节点坐标pointFeatureCollection; // 点GeoJSON集合lineFeatureCollection; // 线GeoJSON集合polygonFeatureCollection; // 面GeoJSON集合constructor(map, callback) {this.map = map;this.addPoint = this.addPoint.bind(this);this.end = this.end.bind(this);this.dynamicAction = this.dynamicAction.bind(this);this.callback = callback; // 回调函数}// 初始化图层init() {// 添加面图层this.map.addLayer({id: "_fillLayer",type: "fill",source: {type: "geojson",data: this.lineFeatureCollection,},paint: {"fill-color": "#ff0000","fill-opacity": 0.3,},});// 添加点图层this.map.addLayer({id: "_pointLayer2",type: "circle",source: {type: "geojson",data: this.pointFeatureCollection,},paint: {"circle-color": "#ffffff","circle-radius": 3,"circle-stroke-width": 2,"circle-stroke-color": "#ff0000",},});}// 重置数据reset() {this.nodeCoordinateList = [];this.pointFeatureCollection = {type: "FeatureCollection",features: [],};this.lineFeatureCollection = {type: "FeatureCollection",features: [],};this.polygonFeatureCollection = {type: "FeatureCollection",features: [],};}// 开始绘制start() {this.reset();this.init();this.map.doubleClickZoom.disable(); // 禁止双击缩放this.map.getCanvas().style.cursor = "crosshair"; // 设置鼠标样式this.map.on("click", this.addPoint);this.map.on("dblclick", this.end);this.map.on("mousemove", this.dynamicAction);}// 结束绘制end(e) {this.addPoint(e);this.map.off("click", this.addPoint);this.map.off("dblclick", this.end);this.map.off("mousemove", this.dynamicAction);this.map.getCanvas().style.cursor = ""; // 恢复鼠标样式this.callback && this.callback(this.polygonFeatureCollection);}// 清除绘制clear() {this.map.getCanvas().style.cursor = ""; // 恢复鼠标样式this.map.doubleClickZoom.enable(); // 恢复双击缩放this.map.off("click", this.addPoint);this.map.off("dblclick", this.end);this.map.off("mousemove", this.dynamicAction);if (this.map.getSource("_pointLayer2")) {this.map.removeLayer("_pointLayer2");this.map.removeSource("_pointLayer2");}if (this.map.getSource("_fillLayer")) {this.map.removeLayer("_fillLayer");this.map.removeSource("_fillLayer");}}// 隐藏绘制show(flag) {if (flag) {this.map.setLayoutProperty("_pointLayer2", "visibility", "visible");this.map.setLayoutProperty("_fillLayer", "visibility", "visible");} else {this.map.setLayoutProperty("_pointLayer2", "visibility", "none");this.map.setLayoutProperty("_fillLayer", "visibility", "none");}}// 添加点addPoint(e) {const lngLat = [e.lngLat.lng, e.lngLat.lat];const pointList = this.pointFeatureCollection;pointList.features.push({type: "Feature",geometry: {type: "Point",coordinates: lngLat,},});this.map.getSource("_pointLayer2").setData(pointList);this.nodeCoordinateList.push(lngLat);}// 鼠标移动事件dynamicAction(e) {const pointList = this.pointFeatureCollection;const lngLat = [e.lngLat.lng, e.lngLat.lat];const len = pointList.features.length;if (len > 1) {let pts = this.nodeCoordinateList.concat([lngLat]);pts = pts.concat([this.nodeCoordinateList[0]]);const json = {type: "Feature",geometry: {type: "Polygon",coordinates: [pts],},};this.map.getSource("_fillLayer").setData(json);this.polygonFeatureCollection = {type: "FeatureCollection",features: [json],};}}
}

使用方法

import { DrawPolygon } from "./map/index.js"; // 引入// 实例化
const drawVector = new DrawPolygon(map, (data) => {console.log('绘制完毕后的回调', data);
});// 开始绘制
drawVector.start();// 结束并清除绘制结果
drawVector.clear();

写在最后

当前版本的 Mapbox GL JS 的绘制功能真是不如 OpenLayers 的,OpenLayers 已经封装有一整套方法了

这边还有徒手画线的实现参考:【WebGIS实例】(19)MapboxGL 实现徒手画线(Freehand Drawing)

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/58127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Django+python的酒店客房入侵检测系统设计与实现

项目运行 需要先安装Python的相关依赖:pymysql,Django3.2.8,pillow 使用pip install 安装 第一步:创建数据库 第二步:执行SQL语句,.sql文件,运行该文件中的SQL语句 第三步:修改源…

HTTPS讲解

前瞻 HTTP与HTTPS的关系 HTTPS也是一个在应用层的协议,是在HTTP协议基础上的一个加密解密层 明文 密文 秘钥 明文->秘钥 加密 秘钥->明文 解密 例如:明文为7 秘钥为2 7^21015; 5就是密文例子: 因为http的内容是明文传输的,明文…

危险物品图像分割系统:一键训练

危险物品图像分割系统源码&数据集分享 [yolov8-seg-GFPN&yolov8-seg-CSwinTransformer等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global…

LabVIEW共享变量通信故障

问题概述: 在LabVIEW项目中,使用IO服务器创建共享变量,并通过LabVIEW作为从站进行数据通信。通讯在最初运行时正常,但在经过一段时间或几个小时后,VI前面板出现错误输出,导致数据传输失败。虽然“分布式系统…

折扣影票接口对接渠道如何选择?

选择折扣影票接口对接渠道需要综合多方面因素考虑,以下是一些建议: 1.合法性和合规性: 确认供应商资质:优先选择具有相关票务经营资质的渠道。比如一些大型的在线票务平台,它们通常经过官方认证和监管,在…

[JAVAEE] 多线程的案例(二) - 阻塞队列 生产者消费者模型

目录 一. 什么是阻塞队列 二. java中的阻塞队列 三. 生产者消费者模型 3.1 生产者消费者模型与阻塞队列密不可分的关系 3.2 阻塞队列在生产者消费者模型的作用 a. 解耦合 b. 削峰填谷 四. 模拟实现阻塞队列 4.1 实现put方法 4.2 实现take方法 4.3 生产者消费者模型​…

了解C# 程序结构

本节我们将学习 C# 编程语言的结构,为了让大家能够对 C# 程序结构有个更好的理解,我们会先演示一个最小的、最简单的 C# 程序结构,以便作为接下来的章节的参考。 C# Hello World 实例 一个 C# 程序主要包括以下部分: 命名空间声明…

08 实战:色彩空间展示(本程序以视频为主)

程序效果如下: 我在这里讲解RGB和YCbCr的原理: 一、RGB颜色空间 1.1 基本概念 RGB颜色空间是一种最基础和常用的颜色表示方式,它基于人眼感知色彩的三原色原理。RGB分别代表: R(Red):红色G(Green):绿色B(Blue):蓝色通过这三种基本颜色的不同组合,可以产生人眼…

Promise、async、await 、异步生成器的错误处理方案

1、Promise.all 的错误处理 Promise.all 方法接受一个 Promise 数组,并返回所有解析 Promise 的结果数组: const promise1 Promise.resolve("one"); const promise2 Promise.resolve("two");Promise.all([promise1, promise2]).…

基于人体姿势博文文章

MATLAB运动目标检测系统应用背景 运动目标的定位跟踪,检测识别,运动分析在图像压缩、运动分析、交通检测,智能监控等方面有主要的应用。 首先,在图像压缩中,运动目标检测技术可以在背景区域中将前景区域提取分割出来…

91.【C语言】数据结构之单向链表的查找,中间插入和删除,销毁

目录 1.链表的查找函数 2.链表的修改函数 3.链表的中间插入函数 1.在pos之前插入:SLTInsertBefore函数 1.借助头指针pphead 示意图 代码示例(写入SList.c) 头文件添加SLTInsertbefore的声明 main.c的部分代码改为 1.测试中间插入 2.测试头部插入 3.测试pos为NULL的…

机器视觉:9点标定的原理与实现

一、什么是标定 标定就是将机器视觉处理得到的像素坐标转换成实际项目中使用到的毫米坐标。简单说即使看看实际单位距离内有几个像素,如下图所示,10mm的距离内有222个像素,那像素坐标和实际的毫米坐标就有个比例关系了。 二、九点标定 9点标…

API网关的作用--为什么微服务需要一个API网关?

微服务网关核心作用就是协议转换、安全隔离和流量控制 微服务架构中,API网关作为系统的入口点,可以统一处理所有客户端请求。 1)协议转换:它能够支持多种通信协议(如HTTP、gRPC等)之间的相互转换&#xff…

如何初始化一个线上的GitHub仓库,在本地已有的仓库中上传到线上

如何初始化一个线上的GitHub仓库,在本地已有的仓库中上传到线上, 首先,先创建一个线上的仓库 本地有一个曾经的仓库,或者本地git init创建一个本地仓库 根据线上仓库的主页给的提示代码进行上传 代码如下: …or cr…

gateway 整合 spring security oauth2

微服务分布式认证授权方案 在分布式授权系统中,授权服务要独立成一个模块做统一授权,无论客户端是浏览器,app或者第三方,都会在授权服务中获取权限,并通过网关访问资源 OAuth2的四种授权模式 授权码模式 授权服务器将授…

(三)行为模式:11、模板模式(Template Pattern)(C++示例)

目录 1、模板模式含义 2、模板模式的UML图学习 3、模板模式的应用场景 4、模板模式的优缺点 5、C实现的实例 1、模板模式含义 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法骨架,将某些步骤…

故障诊断 | CNN-ResNets滚动轴承故障诊断实例代码

故障诊断 | CNN-ResNets滚动轴承故障诊断实例代码 目录 故障诊断 | CNN-ResNets滚动轴承故障诊断实例代码效果一览基本介绍程序设计参考资料 效果一览 基本介绍 CNN-ResNets(卷积神经网络-残差网络)在滚动轴承故障诊断中是一种常用的方法。这种方法利用…

Docker 实践与应用举例教程:从入门到精通

Docker 实践与应用举例教程:从入门到精通 引言 在现代软件开发中,Docker 已成为一种不可或缺的工具。它通过容器化技术简化了应用的部署、管理和扩展,极大地提高了开发和运维的效率。本文将详细介绍 Docker 的基本概念、安装步骤、常用命令…

arm ubuntu22.04 安装es7.16.2

1、更新软件包 sudo apt update && sudo apt upgrade -y 2、安装jdk11 sudo apt install openjdk-11-jdk -y 安装查看版本 java -version 输出应该是这样的 openjdk version "11.0.11" 2021-04-20 OpenJDK Runtime Environment (build 11.0.119-Ub…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-22目录1. PoisonedRAG: Knowledge corruption attacks to retrieval-augmented generation of large language models摘要创新点…