关于 mapboxgl 的常用方法及效果

news2024/11/30 18:50:20

给地图标记点

实现效果
在这里插入图片描述

 /**
  * 在地图上添加标记点
  * point: [lng, lat]
  * color: '#83f7a0'
  */
 addMarkerOnMap(point, color = '#83f7a0') {
   const marker = new mapboxgl.Marker({
     draggable: false,
     color: color,
   }).setLngLat(point).addTo(this.map);
   this.markersList.push(marker);
 },

给地图添加气泡展示地点详情

实现效果:
在这里插入图片描述

 /**
  * 在地图上添加气泡展示
  * point: [lng, lat]
  */
 addPopupOnMap(point) {
   // 将所选点设置为地图中心
   this.map.setCenter(point);
   // Zoom to the zoom level 8 with an animated transition
   this.map.zoomTo(16, {
     duration: 2000
   });
   // 自行赋值
   const html = `<div class="dt-popup">
     <i class="ivu-icon ivu-icon-md-close" id="closePop"></i>
     <ul>
       <li><span class="label">事件名称:</span>${eventName}</li>
       <li><span class="label">经度:</span>${longitude}</li>
       <li><span class="label">纬度:</span>${latitude}</li>
     </ul>
   </div>`
   const popup = new mapboxgl.Popup({ closeOnClick: false }).setLngLat(point).setHTML(html).addTo(this.map);
   // this.popup = popup
   Popup = popup
 },

给地图划线

实现效果
在这里插入图片描述
我的写法估计是有点问题,每条小线段都增加了一个资源和图层,但是还是实现了此功能

map.addSource(`route${routesI}`, {
  type: 'geojson',
   data: {
     type: 'Feature',
     properties: {},
     geometry: {
       type: 'LineString',
       coordinates: routesNew,
     },
   },
 });
 map.addLayer({
   id: `route${routesI}`,
   type: 'line',
   source: `route${routesI}`,
   layout: {
     'line-join': 'round',
     'line-cap': 'round',
   },
   paint: {
     'line-color': '#24C1FF',
     'line-width': 10,
   },
 });

给地图添加缓冲区画圆

实现效果:(颜色自行修改)
在这里插入图片描述

参考地址:https://blog.csdn.net/qq_33950912/article/details/127428093

思路:画圆,其实就是连接n个近似于圆的点位。

经过验证,上述文章中选取了方法三,自定义去切割圆。方法一未曾实现。方法二可能有问题,没有尝试。

/**
  * 计算以中心点、半径 缓冲区
  * center: [lng, lat]
  * radiusInKm 
  */
 createGeoJSONCircle(center, radiusInM, points = 64) {
   var coords = {
     latitude: center[1],
     longitude: center[0]
   };

   var miles = radiusInM;
   var ret = [];
   var distanceX = miles/1000/(111.320*Math.cos(coords.latitude*Math.PI/180));
   var distanceY = miles/1000/110.574;

   var theta, x, y;
   for(var i=0; i<points; i++) {
     theta = (i/points)*(2*Math.PI);
     x = distanceX*Math.cos(theta);
     y = distanceY*Math.sin(theta);

     ret.push([coords.longitude+x, coords.latitude+y]);
   }
   ret.push(ret[0]);

   return {
     "type": "geojson",
     "data": {
       "type": "FeatureCollection",
       "features": [{
         "type": "Feature",
         "geometry": {
           "type": "Polygon",
           "coordinates": [ret]
         }
       }]
     }
   };
 },

/**
	调用 - 请自行赋值
*/
map.addSource("polygon", createGeoJSONCircle([-93.6248586, 41.58527859], 0.5));
map.addLayer({
    "id": "polygon",
    "type": "fill",
    "source": "polygon",
    "layout": {},
    "paint": {
        "fill-color": "blue",
        "fill-opacity": 0.6
    }
});

给地图添加其他图片资源

实现效果
请添加图片描述
添加卡车图片资源:

 /**
 * 引入图片
  * img obj : src, name
  */
 addImage = function(img) {
   map.loadImage(img.src, (error, image) => {
     if (error) throw error;
     if (!map.hasImage(img.name)) map.addImage(img.name, image, {
       sdf: img.sdf || false
     });
   })
 }
 
// 加载 truck 
 let truck_img = {
   src: 'img/truck_mapboxgl.png',
   name: 'truck_img'
 }
 addImage(truck_img)
 

给地图添加图上gif中 1-2-3标记点并且实现鼠标滑过显示popup效果

实现效果:同上图

/**
 * 添加坐标点及鼠标以上效果
 */
addPoints = function (featuresList) {
  map.addSource('places', {
    'type': 'geojson',
    'data': {
      'type': 'FeatureCollection',
      'features': featuresList
    }
  })

  // 加载 circle 定位圆
  let img = {
    src: 'img/circle.png',
    name: 'circle_img',
    sdf: true
  }
  addImage(img)

  map.addLayer({
    'id': 'places',
    'type': 'symbol',
    'source': 'places',
    'layout': {
      'icon-image': img.name, // 图标ID
      'icon-size': 0.15, // 图标的大小
      'icon-anchor': 'center', // 图标的位置
      'text-field': ['get', 'num'],
    },
    'paint': {
      'text-color': '#fff',
      'icon-color': ['get', 'color']
    },
  });

  // Create a popup, but don't add it to the map yet.
  const popup = new mapboxgl.Popup({
    closeButton: false,
    closeOnClick: false
  });

  map.on('mouseenter', 'places', (e) => {
    // Change the cursor style as a UI indicator.
    map.getCanvas().style.cursor = 'pointer';

    // Copy coordinates array.
    const coordinates = e.features[0].geometry.coordinates.slice();
    const description = e.features[0].properties.description;

    // Ensure that if the map is zoomed out such that multiple
    // copies of the feature are visible, the popup appears
    // over the copy being pointed to.
    while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
      coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
    }

    // Populate the popup and set its coordinates
    // based on the feature found.
    popup.setLngLat(coordinates).setHTML(description).addTo(map);

  });

  map.on('mouseleave', 'places', () => {
    map.getCanvas().style.cursor = '';
    popup.remove();
  });
}

在地图中图标动态移动

实现效果:如上图

此方法用于卡车图标动态移动

/**
 * 添加路径 - 卡车图标动态效果
 */
addTruckRoutes = function (coordinatesList) {
  // 起点
  const origin = coordinatesList[0]

  const route = {
    'type': 'FeatureCollection',
    'features': [{
      'type': 'Feature',
      'geometry': {
        'type': 'LineString',
        'coordinates': coordinatesList
      }
    }]
  };

  const point = {
    'type': 'FeatureCollection',
    'features': [{
      'type': 'Feature',
      'properties': {},
      'geometry': {
        'type': 'Point',
        'coordinates': origin
      }
    }]
  }

  const lineDistance = turf.length(route.features[0]);
  const arc = [];
  const steps = 200;
  for (let i = 0; i < lineDistance; i += lineDistance / steps) {
    const segment = turf.along(route.features[0], i);
    arc.push(segment.geometry.coordinates);
  }
  route.features[0].geometry.coordinates = arc;
  let counter = 0;

  map.addSource('route', {
    'type': 'geojson',
    'data': route
  });

  map.addSource('point', {
    'type': 'geojson',
    'data': point
  });

  map.addLayer({
    'id': `route`,
    'source': 'route',
    'type': 'line',
    'paint': {
      'line-width': 20,
      'line-color': '#2d8cf0',
      'line-opacity': 0.4
    }
  })
  
  // 加载 truck 定位圆
  let truck_img = {
    src: 'img/truck_mapboxgl.png',
    name: 'truck_img'
  }
  addImage(truck_img)

  map.addLayer({
    'id': `point`,
    'source': 'point',
    'type': 'symbol',
    'layout': {
      'icon-image': truck_img.name,
      'icon-size': 0.2,
      'icon-rotate': ['get', 'bearing'],
      'icon-rotation-alignment': 'map',
      'icon-allow-overlap': true,
      'icon-ignore-placement': true
    }
  });

  animate = function () {
    running = true;
    const start =
      route.features[0].geometry.coordinates[
        counter >= steps ? counter - 1 : counter
      ];
    const end =
      route.features[0].geometry.coordinates[
        counter >= steps ? counter : counter + 1
      ];
    point.features[0].geometry.coordinates =
      route.features[0].geometry.coordinates[counter];
    point.features[0].properties.bearing = turf.bearing(
      turf.point(start),
      turf.point(end)
    )+90; // 此处控制图标的头部指向问题,可以加减角度,使卡车头部一直朝着目的地

    // Update the source with this new data
    map.getSource('point').setData(point);

    // Request the next frame of animation as long as the end has not been reached
    if (counter < steps) {
      requestAnimationFrame(animate);
      counter = counter + 1;
    } else {
      counter = 0
      animate()
    }      
  }

  animate(counter);
}

地图路线持续闪动特效

实现效果
请添加图片描述
此方法官网有示例

代码如下:

/**
 * 添加路径 - 路径虚线变化效果
 */
addDashedRoutes = function (coordinatesList) {
  map.addSource('route', {
    'type': 'geojson',
    'data': {
      'type': 'Feature',
      'properties': {},
      'geometry': {
        'type': 'LineString',
        'coordinates': coordinatesList
      }
    }
  });
  map.addLayer({
    'id': 'route',
    'type': 'line',
    'source': 'route',
    'layout': {
      'line-join': 'round',
      'line-cap': 'round'
    },
    'paint': {
      // 'line-color': '#2b85e4',
      // 'line-width': 10
      'line-color': '#2d8cf0',
      'line-width': 8,
      'line-opacity': 0.4
    }
  });
  map.addLayer({
    id: 'line-dashed',
    type: 'line',
    source: 'route',
    paint: {
      'line-color': '#2db7f5',
      'line-width': 8,
      'line-dasharray': [0, 4, 3]
    }
  });   

  /**
   * 动态展示路径 - 路径虚线变化效果
   */
  const dashArraySequence = [
    [0, 4, 3],
    [0.5, 4, 2.5],
    [1, 4, 2],
    [1.5, 4, 1.5],
    [2, 4, 1],
    [2.5, 4, 0.5],
    [3, 4, 0],
    [0, 0.5, 3, 3.5],
    [0, 1, 3, 3],
    [0, 1.5, 3, 2.5],
    [0, 2, 3, 2],
    [0, 2.5, 3, 1.5],
    [0, 3, 3, 1],
    [0, 3.5, 3, 0.5]
  ];
  let step = 0;
  animateDashArray = function (timestamp) {
    const newStep = parseInt(
      (timestamp / 50) % dashArraySequence.length
    );

    if (newStep !== step) {
      map.setPaintProperty(
        'line-dashed',
        'line-dasharray',
        dashArraySequence[step]
      );
      step = newStep;
    }

    // Request the next frame of the animation.
    requestAnimationFrame(animateDashArray);
  }

  // start the animation
  animateDashArray(0);
}  

地图正向反向地址匹配

官网有示例,可自行查阅

/**
 * 正向地址匹配
 * address: '孵化大厦'
 */
addressMatchPoint(address) {
  // 正向匹配参数
  var geoCodeParam = new SuperMap.GeoCodingParameter({
    address: address, // 地址
    fromIndex:0, // 设置返回对象的起始索引值
    toIndex:10, // 设置返回对象的结束索引值。
    // prjCoordSys:{epsgcode26}, // 坐标设置
    maxReturn:5 // 最大返回结果数
  });
  //创建地址匹配服务
  var addressUrl = MAP_SERVICE + "***************"
  var addressMatchService = new mapboxgl.supermap.AddressMatchService(addressUrl);
  // 向服务端发送请求进行正向地址匹配,并获取返回的结果
  return addressMatchService.code(geoCodeParam, function(obj){});
},

/**
 * 反向地址匹配
 * point: [lng, lat]
 */
pointMatchAddress(point) {
  // 反向匹配参数
  var geoDecodeParam = new SuperMap.GeoDecodingParameter({
    x: point[0], // 横坐标
    y: point[1], // 纵坐标
    fromIndex: 0, // 设置返回对象的起始索引值。
    toIndex: 10, // 设置返回对象的结束索引值。
    // filters: "", // 过滤字段
    // prjCoordSys: {epsgcode26}, // 坐标设置
    maxReturn: 3, // 最大结果数
    geoDecodingRadius: -1 // 查询半径
  });
  // 创建地址匹配服务
  var addressUrl = MAP_SERVICE +  "***************"
  var addressMatchService = new mapboxgl.supermap.AddressMatchService(addressUrl);
  // 向服务端发送请求进行反向地址匹配,并获取返回的结果
  return addressMatchService.decode(geoDecodeParam, function(obj){});
},

两点之间路径规划

参照官网示例

let serviceUrl = MAP_SERVICE + '******';
let findPathService = new mapboxgl.supermap.NetworkAnalystService(serviceUrl);
//向服务器发送请求,并对返回的结果进行分析处理,展示在客户端上
const result = findPathService.findPath(findPathParams, function(serviceResult) {})
// ...不完整代码

遇到问题

  1. 在vue组件中,添加上了maker或者popup,使用data中定义变量会造成地图空白问题,暂时没有解决,后面改用在全局声明marker或者popup,layer好像也存在类似问题,可以参考解决。
    在这里插入图片描述
  2. 调用以上方法包裹在 map.on('load', () => { }) 的方法中。
  3. 以上代码均为不完整代码,有些在vue中使用,有些在原生中使用,请仔细阅读,以免出错。

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

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

相关文章

微信小程序 -- ios 底部小黑条样式问题

问题&#xff1a; 如图&#xff0c;ios有的机型底部伪home键会显示在按钮之上&#xff0c;导致点击按钮的时候误触 解决&#xff1a; App.vue <script>export default {wx.getSystemInfo({success: res > {let bottomHeight res.screenHeight - res.safeArea.bott…

react 学习笔记 李立超老师 | (学习中~)

文章目录 react学习笔记01入门概述React 基础案例HelloWorld三个API介绍 JSXJSX 解构数组 创建react项目(手动)创建React项目(自动) | create-react-app事件处理React中的CSS样式内联样式 | 内联样式中使用state (不建议使用)外部样式表 | CSS Module React组件函数式组件和类组…

GUI的简单概述和基本使用

GUI的概念 1&#xff0c;到目前为止&#xff0c;我们编写的都是控制输入的程序&#xff0c;操作使用非常不直观&#xff0c;采取一直方式让效果呈现在窗口上。 2&#xff0c;GUI及图形界面指采用图像方式显示的用户界面&#xff0c;与早期计算机的命令行界面相比&#xff0c;…

CSS——选择器、PxCook软件、盒子模型

1、选择器 1.1 结构伪类选择器 作用&#xff1a;根据元素的结构关系查找元素。 1.1.1 :nth-child&#xff08;公式&#xff09; 作用&#xff1a;根据元素的结构关系查找多个元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"…

SimplePIR——目前最快单服务器匿踪查询方案

一、介绍 这篇论文旨在实现高效的单服务器隐私信息检索&#xff08;PIR&#xff09;方案&#xff0c;以解决在保护用户隐私的同时快速检索数据库的问题。为了实现这一目标&#xff0c;论文提出了两种新的PIR方案&#xff1a;SimplePIR和DoublePIR。这两种方案的实现基于学习与错…

【桑基图】绘制桑基图

绘制桑基图 一、绘制桑基图&#xff08;1&#xff09;方法一&#xff1a;去在线网站直接绘制&#xff08;2&#xff09;方法二&#xff1a;写html之后在vscode上运行 二、遇到的问题&#xff08;1&#xff09;当导入一些excel的时候&#xff0c;无法绘制出桑基图 一、绘制桑基图…

B 站基于 StarRocks 构建大数据元仓

作者&#xff1a;bilibili 大数据高级开发工程师 杨洋 B站大数据元仓是一款用来观测大数据引擎运行情况、推动大作业治理的系统诊断产品。经过调研和性能测试&#xff0c;大数据元仓最终以 StarRocks 为技术底座&#xff0c;从实际的应用效果来看&#xff0c;大部分查询都能在几…

准确!!!在 CentOS 8 上配置 PostgreSQL 14 的主从复制

在 CentOS 8 上配置 PostgreSQL 14 的主从复制&#xff0c;并设置 WAL 归档到特定路径 /home/postgres/archive 的步骤如下&#xff1a; 主服务器配置&#xff08;主机&#xff09; 配置 PostgreSQL&#xff1a; 编辑 postgresql.conf 文件&#xff1a; vim /data/postgres/p…

AIGC之Image2Video(一)| Animate Anyone:从静态图像生成动态视频,可将任意图像角色动画化

近日&#xff0c;阿里发布了Animate Anyone&#xff0c;只需一张人物照片&#xff0c;结合骨骼动画&#xff0c;就能生成人体动画视频。 项目地址&#xff1a;https://humanaigc.github.io/animate-anyone/ 论文地址&#xff1a;https://arxiv.org/pdf/2311.17117.pdf Github…

632. 最小区间

632. 最小区间 class Solution {public int[] smallestRange(List<List<Integer>> nums) {int size nums.size();Map<Integer, List<Integer>> indices new HashMap<Integer, List<Integer>>();int xMin Integer.MAX_VALUE, xMax Inte…

Docker+jenkins+gitlab实现持续集成

1.安装环境 服务器ip虚拟机版本192.168.5.132centos7.6192.168.5.152centos7.6 2. 安装docker 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2添加软件源信息&#xff0c;要确保centos7能上外网 yum-config-manager --add-repo http:…

HarmonyOS4.0从零开始的开发教程06常用基础组件

HarmonyOS&#xff08;四&#xff09;常用基础组件 1 组件介绍 组件&#xff08;Component&#xff09;是界面搭建与显示的最小单位&#xff0c;HarmonyOS ArkUI声明式开发范式为开发者提供了丰富多样的UI组件&#xff0c;我们可以使用这些组件轻松的编写出更加丰富、漂亮的界…

华为配置风暴控制示例

组网需求 如下图所示&#xff0c;SwitchA作为二层网络到三层路由器的衔接点&#xff0c;需要防止二层网络转发的广播、未知组播或未知单播报文产生广播风 配置思路 用如下的思路配置风暴控制。 通过在GE0/0/1接口视图下配置风暴控制功能&#xff0c;实现防止二层网络转发的…

华为设备使用python配置netconf 功能

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过SSH登陆到设备上配置netconf协议的用户名&#xff0c;密码以及netconf服务&#xff0c;并且通过netconf协议将设备的loopback0接口IP地址配…

Redis应用-缓存

目录 什么是缓存 使用redis作为缓存 缓存的更新策略 通用的淘汰策略 redis内置的淘汰策略 缓存预热 缓存穿透 缓存雪崩 缓存击穿 什么是缓存 缓存(cache)是计算机中一个经典的概念,在很多的场景中都会涉及到. 核心思路就是把一些常用的数据放到触手可及(访问速度更快…

docker安装及配置mysql

docker 安装mysql 下载镜像文件 下载mysql5.7版本 sudo docker pull mysql:5.7检查是否下载成功 sudo docker images2.创建实例并启动 切换到root下避免每次使用sudo 密码&#xff1a;vagrant docker run -p 3306:3306 --name mysql \ -v /mydata/mysql/log:/var/log/my…

ChatGPT能帮助--掌握各种AI绘图工具,随意生成各类型性图像

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

专业130+总分400+云南大学通信847专业基础综考研经验(原专业课827)

今年专业130总分400云南大学通信上岸&#xff0c;整体考研感觉还是比较满意&#xff0c;期间也付出了很多心血&#xff0c;走过弯路&#xff0c;下面分享一下这一年考研得失&#xff0c;希望大家可以从中有所借鉴。 先说明我在考研报名前更换成云南大学的理由&#xff1a;&…

HarmonyOS4.0从零开始的开发教程03初识ArkTS开发语言(中)

HarmonyOS&#xff08;二&#xff09;初识ArkTS开发语言&#xff08;中&#xff09;之TypeScript入门 浅析ArkTS的起源和演进 1 引言 Mozilla创造了JS&#xff0c;Microsoft创建了TS&#xff0c;Huawei进一步推出了ArkTS。 从最初的基础的逻辑交互能力&#xff0c;到具备类…

使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB

本文介绍从AWS DynamoDB到阿里云MongoDB的迁移框架。 它概述了以下步骤&#xff1a; 在阿里云上配置云数据库MongoDB版并应用公网终端节点在 AWS EC2 上安装 Nimoshake将AWS EC2访问阿里云MongoDB版列入白名单配置 Nimoshake 并开始迁移过程验证目标数据库上的增量数据 1. 创…