为什么要用 mapbox ?如题图,mapbox是一个支持真3D地形展示的webGIS框架,与常用的Leaflet、Cesium和Openlayers并称四大框架,本文将介绍mapbox-gl js 在 vue 中的用法。
(资料图)
各位可以自行搜索上面提到的或者其他的webGIS框架或者集成服务商,可以很轻松的比较出mapbox的优势:
支持3D地形、3D模型支持多种坐标系投影mapbox studio 在线编辑地图样式,使用时只需一个链接,更新时链接也无需修改(无可替代)漂亮(谁能反驳?)简单易上手(对比Cesium、Openlayers)地理数据全格式支持(Image、KML、WMS、 WMTS、 GeoJson)功能齐全,mapbox再也不是那个花瓶了,它现在是一个强大的、完整的大型框架注册mapbox账号mapbox禁止中国地区的新用户注册,需要开启全局的魔法,进入 mapbox官网注册
如果要求输入 海外银行卡号,参阅:知乎:mapbox的注册怎么需要填卡号,有银行要求吗,之前看网上说不需要填,具体要怎么操作,求大神指点。?
完成注册后会看到如下画面
左上红框可以在线创建、编辑地图样式。下方红框是公钥,可以用来访问你创建的公开地图。
创建你的个性化地图你可以自行探索各个图层分别是什么,我这里只新增了一个卫星图,图层越多,加载的时候就越慢,用起来就越卡。
点击左上角3D按钮,即可开启3D视图,mapbox会根据全球等高线信息模拟出地形
上图为山东省泰安市。此外还支持:
自定义光源自定义坐标系自定义地形夸张雾气(视野可见范围,适当设置有助于性能优化)在VUE项目中使用mapBox本文使用vue3,选配如下:
routervuexless
安装,通过NPM安装
npm i mapbox-gl
引入
import mapboxgl from "mapbox-gl";import "mapbox-gl/dist/mapbox-gl.css";import MapboxLanguage from "@mapbox/mapbox-gl-language"; //可以将标签改为中文
初始化
mapboxgl.accessToken="pk.eyJ1IjoiemJiZW4iLCJhIjoiACtpemtnOXRoMDRhcDMwbG43aGYxbXhqYyJ9.YOJzSXzubABBJeK7SXg60w"; //这是一个无效的公钥,上面提到了公钥在哪里可以获取到this.map = new mapboxgl.Map({ container: "basicMapbox", style: "mapbox://styles/xxx/ckus1uok22m4117aif4pg9qa6", //这是个假链接,在上面有提到分享按钮,那里有你自己的链接 center: [118, 28], zoom: 3, //zoom你都不懂就别看了 pitch: 0, // 相对于地面3D视角的角度 bearing: 0, // 东西南北 方向,正北方为 0 projection: "globe", // 为 3D 地球 antialias: false, //抗锯齿,通过false关闭提升性能 essential: true, //不知道什么意思,我看人家写我就写了 renderWorldCopies: false, //可理解为loop,在projection: "globe"时无效 skipOnboarding: true,//可选择不等待瓦片加载 });// ### 标签汉化// this.map.addControl(new MapboxLanguage({ defaultLanguage: "zh-Hans" }));// ### 添加导航控制条// this.map.addControl(new mapboxgl.NavigationControl(), "top-left");
监听事件
this.map.on("eventName",()=>{})// 常用事件有:load、moveend、render等,自行探索
常用方法
this.map.setFog({}); //开启宇宙、星空this.map.flyTo({ center: [109.926476, 19.088415], //目标中心点 海南省琼中县湾岭镇 zoom: 11, //目标缩放级别 bearing: 56.50, //目标方位角 pitch: 47.50, //目标倾斜角},duration: 7000,) //飞行let shape = await request.get("some_geoJosn")this.map.addSource("customSourceName"{ type:"geojson" //可选: raster || image || 等 // 每个类型所需的参数不一样,自行探索,这里用geojson举例。 "data": shape}) //添加资源this.map.getSource("customSourceName") && this.map.removeSource("customSourceName") //获取资源、删除资源this.map.addLayer({ id: "measure-lines", type: "line", source: "customSourceName", //使用刚刚添加的资源 layout: { "line-cap": "round", "line-join": "round" }, paint: { "line-color": "#00FFF4", "line-width": 2.5, "line-opacity": 1, "line-gap-width": 0, },}); // 添加图层,如上使用 名为 customSourceName 的资源 添加了一个用线勾勒轮廓的图层。this.map.getLayer("measure-lines") && this.map.removeLayer("measure-lines") // 获取图层、删除图层
插点,以下是一个插点的简单示例,可以用vue组件渲染插点的响应弹窗:
import mapboxPopView from "../mapboxPopView/mapboxPopView.vue"; //弹窗组件需提前引入 async setMaker(makerList) { if (!makerList) { return } // console.log("makerList::: ", makerList); for (let item of makerList) { let dom = document.createElement("img") dom.src = require(`../../../public/static/img/${item.deviceType}.png`) //这里使用了自定义图片来替换默认插点图标 dom.style.width = "52.4px" dom.style.height = "auto" //可以保持比例 dom.id = `marker-${item.deviceId}` dom.classList.add("markerCustom") dom.addEventListener("click", () => { this.setPopContent(item) }) let marker = new mapboxgl.Marker({ element: dom, offset: [0, -50], //图标偏移量 }).setLngLat([item.lon, item.lat]).addTo(this.map); // 添加标记的弹窗事件 var popup = new mapboxgl.Popup({ offset: [0, -100], //弹窗偏移量 }).setHTML(``) // this.setPopContent(item) marker.setPopup(popup); this.markerList.push(marker) // 点击标记时显示弹窗 } this.$store.dispatch("addLayer") }, setPopContent(item) { const MyNewPopup = defineComponent({ extends: mapboxPopView, setup() { const deviceItem = item return { deviceItem } //这里的常量可以直接在组件的this对象中获取 }, }) setTimeout(() => { createApp(MyNewPopup).mount(`#popup-content-${item.deviceId}`) //挂载到刚刚定义的拥有唯一ID的DOM节点上 }, 10); },
插点效果如图:
至此,mapbox的基本功能介绍完毕,另外,mapbox支持自定义图源,下面是一个使用天地图瓦片的例子:
setTiandituLaryer() { this.map.addSource("tianditu", { type: "raster", tiles: [ "你的天地图链接", ], tileSize: 256, }); this.map.addLayer({ id: "tianditu", type: "raster", source: "tianditu", });},
如果使用其他的图源,记得在mapbox studio里关闭或删除无用的图层。
码云:mapbox_demo
旗鼓相当的对手,就是我们磨砺爪子的坚石。