基于MapBox的方法封装及调用
目录
1、初始化地图
2、单独添加瓦片
3、开启绘制方法
4、移除绘制数据
5、拾取经纬度
6、加点
7、加线
8、加面
9、更改图层顺序
10、更改实体样式
11、移除实体或图层
12、定位某个点
13、定位数组
14、锁定实体跟随视角
15、获取视窗
16、设置俯仰角
17、设置方位角
18、设置地图中心点
19、开启/关闭地图事件监听
20、部分方法调用示例
加点
加线
加面
移除实体或图层
更改图层顺序
开启关闭事件监听
定位某个点
定位数组
开启绘制
移除绘制
锁定实体跟随视角
更改实体样式
设置俯仰角
设置方位角
设置地图中心点
获取视窗
注:官网地址:Map | Mapbox GL JS | Mapbox
mapbox Style规范:整理一份完整的Mapbox Style 规范 - 知乎
1、初始化地图
this.mapboxMap = new mapboxgl.Map({container: "mapBoxMapContainer",//容器zoom: mapOptions.zoom ? mapOptions.zoom : 9,//层级center: mapOptions.centerPoint ? mapOptions.centerPoint : [116.39, 39.91],//中心点//图层(可用mapbox提供的在线图层,举例:mapbox://styles/mapbox/streets-v11)style: mapOptions.mapBoxUrl,//true则多个源的符号会相互碰撞。false则对每个源中的符号分别运行碰撞检测crossSourceCollisions: false
});
2、单独添加瓦片
this.mapboxMap.addLayer({id: 'tilelayer',//取值参考:https://docs.mapbox.com/style-spec/reference/layers/#typetype:"raster",//取值参考:https://docs.mapbox.com/style-spec/reference/sources/source:{"type": "raster","tiles": [mapOptions.mapBoxUrl],}
});
3、开启绘制方法
引入mapbox-gl-draw.js和mapbox-gl-draw.css
//地图加载完成后 初始化插件
this.mapboxMapDraw = new MapboxDraw({displayControlsDefault: false,//不显示默认的控件按钮
});
this.mapboxMap.addControl(this.mapboxMapDraw);/*** @description 绘制方法* type:String 绘制类型 举例'draw_point'* dataId:String 上层界面使用*/
openDraw(drawOption,callback){var that = this;if(drawOption){//取值"draw_point" "draw_line_string" "draw_polygon"that.mapboxMapDraw.changeMode(drawOption?.type);that.mapboxMap.on("draw.create", function (feature) {if(feature?.features.length){that.callbackFunc({code: 1,geometryId: feature.features[0]?.id,point: feature.features[0]?.geometry?.coordinates,dataId: drawOption?.dataId},callback);}else{that.callbackFunc("参数错误");}});that.mapboxMap.on("draw.update", function (feature) {if(feature?.features.length){that.callbackFunc({code: 1,geometryId: feature.features[0]?.id,point: feature.features[0]?.geometry?.coordinates,dataId: drawOption?.dataId},callback);}else{that.callbackFunc("参数错误");}});that.mapboxMap.on("draw.delete", function (feature) {});}else{that.callbackFunc("参数错误");}
},
4、移除绘制数据
/*** @description 删除绘制的点线面 接收格式 String* removeIdArray:Array 唯一标识的集合,在绘制的方法里会返回 必传*/
removeDrawById(removeIdArray,callback){if(removeIdArray?.length){try{removeIdArray.forEach((item,index)=>{if(this.mapboxMapDraw.get(item.geometryId)){this.mapboxMapDraw.delete(item.geometryId);}});}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
5、拾取经纬度
//开启拾取方法 考虑项目是否在pc端打开 分别判断
pickUpLatLng(callback){if(this.getBrowser() == "pc" || this.getBrowser() == "linux"){this.mapboxMap.on('click',(event) =>{this.pickUpLatLngMonitor(event,callback)});}else{this.mapboxMap.on('touchend',(event) => {this.pickUpLatLngMonitor(event,callback)});}
},
//检测设备
getBrowser(){var sUserAgent = navigator.userAgent.toLocaleLowerCase();var isLinux = (String(navigator.platform).indexOf("linux") > -1);var bIsAndroid = sUserAgent.match(/android/i) == "android";var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";var bIsCE = sUserAgent.match(/windows nt/i) == "windows nt";if (isLinux) {return "linux";} else if (bIsIpad || bIsIphoneOs) {return "ios";} else if (bIsWM) {return "wp";} else if (bIsCE) {return "pc";} else if (bIsAndroid) {return "android";}
},
//回调给上层经纬度
pickUpLatLngMonitor(e,callback){this.callbackFunc({code:1,data:e.lngLat,msg:"拾取经纬度信息!"},callback);
},
6、加点
第一种方式:
/*** @description 添加点 接收格式Array* id:String 唯一标识 必传* paintInfo:Object 图标信息 可选* layoutInfo:Object 图标信息 可选* points:Object 点位数据 举例{ lat: 39,lon: 116} 必传*/
addPoint(pointOption,callback) {if (pointOption?.length) {try{let tempStorageInfo = {};//id为key,经纬度是值pointOption.forEach((item, index) => {if (item.id && item.point?.lat && item.point?.lon) {if(!item.layoutInfo){item.layoutInfo = {};}if(!item?.layoutInfo?.hasOwnProperty("icon-image")){item.layoutInfo["icon-image"] = "default";}//icon-image 需要显示的图标的名字 对应assets下img下的名字this.mapboxMap.loadImage(require("../../../assets/img/" + item.layoutInfo["icon-image"] + ".png"),(error, image) => {if (error) throw error;if(!this.mapboxMap.hasImage(item.layoutInfo["icon-image"])){this.mapboxMap.addImage(item.layoutInfo["icon-image"], image);}let sourceObject = {type: 'geojson',data: {type: 'Feature',geometry: {'type': 'Point','coordinates': [item.point.lon, item.point.lat]}}};//pop弹窗if(item?.layoutInfo?.description){sourceObject["data"]["properties"] = {description:item.layoutInfo.description,icon:'theatre'};}//实体已存在则修改const source = this.mapboxMap.getSource(item.id);const layer = this.mapboxMap.getLayer('layer_'+item.id);if(source){source.setData({type: 'Feature',geometry: {'type': 'Point','coordinates':[item.point.lon, item.point.lat]}});if(layer && (item?.layoutInfo || item?.paintInfo)){if(item?.layoutInfo && Object.keys(item.layoutInfo).length){for(let layoutKey in item.layoutInfo){this.mapboxMap.setLayoutProperty('layer_'+item.id, layoutKey, item.layoutInfo[layoutKey]);}}if(item?.paintInfo && Object.keys(item.paintInfo).length){for(let paintKey in item.paintInfo){this.mapboxMap.setPaintProperty('layer_'+item.id, paintKey, item.paintInfo[paintKey]);}}}}else{this.mapboxMap.addSource(item.id, sourceObject);this.mapboxMap.addLayer({id: 'layer_'+item.id,type: 'symbol',source: item.id,layout: {'icon-image': item?.layoutInfo["icon-image"],//大于等于0的可选数字。单位是原始图标大小的因素。默认为1 支持表达式。'icon-size':item?.layoutInfo?.hasOwnProperty("icon-size") ? item?.layoutInfo["icon-size"] : 1,/** 锚点位置 取值center/left/right/top/bottom* /top-left/top-right/bottom-left/bottom-right*/'icon-anchor':item?.layoutInfo?.hasOwnProperty("icon-anchor") ? item?.layoutInfo["icon-anchor"] : "center",/** 图标与其锚的偏移距离。正值表示向右和向下,而负值表示向左和向上。* 每个组件乘以icon-size的值,以获得以像素为单位的最终偏移量。* 当与图标旋转结合使用时,偏移量将像旋转方向一样向上。*/'icon-offset':item?.layoutInfo?.hasOwnProperty("icon-offset") ? item?.layoutInfo["icon-offset"] : [0,0],//绘制图标时的不透明度。 0 ~ 1之间的可选数字// 'icon-ignore-placement':false,//碰撞后可见先加的'icon-allow-overlap':false,//碰撞后可见后加的// "symbol-z-order": "source",//顺时针旋转图标。单位是度。默认为0 支持表达式'icon-rotate':item?.layoutInfo?.hasOwnProperty("icon-rotate") ? item?.layoutInfo["icon-rotate"] : 0,'text-field':item?.layoutInfo?.hasOwnProperty("text-field") ? item?.layoutInfo["text-field"] : "",/** 文本位置 取值center/left/right/top/bottom* /top-left/top-right/bottom-left/bottom-right*/'text-anchor':item?.layoutInfo?.hasOwnProperty("text-anchor") ? item?.layoutInfo["text-anchor"] : "top",'text-offset':item?.layoutInfo?.hasOwnProperty("text-offset") ? item?.layoutInfo["text-offset"] : [0,0],//大于等于0的可选数字 默认16'text-size':item?.layoutInfo?.hasOwnProperty("text-size") ? item?.layoutInfo["text-size"] : 16,//是否可见 visible/none"visibility":item?.layoutInfo?.hasOwnProperty("visibility") ? item?.layoutInfo.visibility : "visible",// "symbol-sort-key":item?.layoutInfo?.hasOwnProperty("symbol-sort-key") ? item?.layoutInfo["symbol-sort-key"] : 2,},paint:{'icon-opacity':item?.paintInfo?.hasOwnProperty("icon-opacity") ? item?.paintInfo["icon-opacity"] : 1,'text-color':item?.paintInfo?.hasOwnProperty("text-color") ? item?.paintInfo["text-color"] : "#ffffff",}});//pop弹窗if(item?.layoutInfo?.description){this.mapboxMap.on('click','layer_'+item.id,(e)=>{const coordinates = e.features[0].geometry.coordinates;const description = e.features[0].properties.description;new mapboxgl.Popup().setLngLat(coordinates).setHTML(description).addTo(this.mapboxMap);})}}tempStorageInfo[item.id] = [item.point.lon, item.point.lat];//如果需要飞行操作 传入fly参数if(item.flyInfo){this.locationPoint(item.flyInfo);}//如果需要跟随操作 传入follow参数if(item.followInfo){this.followLockEntity(item.followInfo);}//如果需要旋转地图操作 传入bearing参数if(item.bearing){this.setBearing(item.bearing);}if(index == pointOption.length-1){this.callbackFunc({code: 1,data:tempStorageInfo,msg: "添加成功!"},callback);}});}});}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
第二种方式:
if (pointOption && pointOption.length) {pointOption.forEach((item, index) => {if (item.id && item.iconName && item.point.lat && item.point.lon) {let imageStr = require("../../../assets/img/" + item.iconName + ".png");var ele = document.createElement("div");var imgEle = document.createElement("img");imgEle.src = imageStr;ele.appendChild(imgEle);const marker = new mapboxgl.Marker(ele).setLngLat([item.point.lon, item.point.lat]).addTo(this.mapboxMap);}})
}
7、加线
/*** @description 添加线 接收格式Array* id:String 唯一标识 必传* paintInfo:Object 线样式设置 可选* layoutInfo:Object 线样式设置 可选* points:二维Array 点位数据 必传*/
addLine(lineOption,callback) {if(lineOption?.length){try{let tempStorageInfo = {};//id为key,经纬度点集是值lineOption.forEach((item, index) => {if(item.id && item.points){//实体已存在则修改const source = this.mapboxMap.getSource(item.id);const layer = this.mapboxMap.getLayer('layer_'+item.id);if(source){if(source._data && source._data.geometry && source._data.geometry.coordinates){if(item.points.length > 0){let tempData = null;if(item.points.length > 1){tempData= item.points;}else {tempData = JSON.parse(JSON.stringify(source._data.geometry.coordinates));tempData.push(item.points[0]);}source.setData({type: "Feature",properties: {},geometry: {type: "LineString",coordinates: tempData},});}if(layer && (item.layoutInfo || item.paintInfo)){if(item?.layoutInfo && Object.keys(item.layoutInfo).length){for(let layoutKey in item.layoutInfo){this.mapboxMap.setLayoutProperty('layer_'+item.id, layoutKey, item.layoutInfo[layoutKey]);}}if(item?.paintInfo && Object.keys(item.paintInfo).length){for(let paintKey in item.paintInfo){this.mapboxMap.setPaintProperty('layer_'+item.id, paintKey, item.paintInfo[paintKey]);}}}}}else{this.mapboxMap.addSource(item.id, {type: "geojson",data: {type: "Feature",properties: {},geometry: {type: "LineString",coordinates: item.points,},},});this.mapboxMap.addLayer({id: 'layer_' + item.id,type: "line",source: item.id,layout: {//线交叉时的显示样式 bevel(方型交点)/round(圆型交点)/miter(尖型交点)"line-join": item?.layoutInfo?.hasOwnProperty("line-join") ? item?.layoutInfo["line-join"] : "round",//线末端的显示样式 butt(方型末端仅端点)/round/(圆型末端)square(方型末端)"line-cap": item?.layoutInfo?.hasOwnProperty("line-cap") ? item?.layoutInfo["line-cap"] : "round",//是否可见 visible/none"visibility": item?.layoutInfo?.hasOwnProperty("visibility") ? item?.layoutInfo["visibility"] : "visible",// "line-sort-key":item?.layoutInfo?.hasOwnProperty("line-sort-key") ? item?.layoutInfo["line-sort-key"] : 1,},paint: {// 线的颜色(可选,默认值为 #000000。如果设置了 line-pattern,则 line-color 将无效)"line-color": item?.paintInfo?.hasOwnProperty("line-color") ? item.paintInfo["line-color"] : '#888',// 线用的图案(可选,这里填写在 sprite 雪碧图中图标名称。为了图案能无缝填充,图标的高宽需要是 2 的倍数)"line-pattern": item?.paintInfo?.hasOwnProperty("line-pattern") ? item.paintInfo["line-pattern"] : "",//大于等于0的可选数字。单位为像素,默认值为 1。"line-width": item?.paintInfo?.hasOwnProperty("line-width") ? item.paintInfo["line-width"] : 3,// 线的模糊度(可选,值 >= 0,默认值为 0,单位:像素)"line-blur": item?.paintInfo?.hasOwnProperty("line-blur") ? item.paintInfo["line-blur"] : 0,// 线的平移(可选,通过平移 [x, y] 达到一定的偏移量。默认值为 [0, 0],单位:像素。)"line-translate": item?.paintInfo?.hasOwnProperty("line-translate") ? item.paintInfo["line-translate"] : [0, 0],// 线的平移锚点,即相对的参考物(可选,可选值为 map、viewport,默认为 map)"line-translate-anchor": item?.paintInfo?.hasOwnProperty("line-translate-anchor") ? item?.paintInfo["line-translate-anchor"] : "map",//绘制线时的不透明度。 0 ~ 1之间的可选数字 默认值为 1"line-opacity": item?.paintInfo?.hasOwnProperty("line-opacity") ? item?.paintInfo["line-opacity"] : 1,},});//如果需要更改图层顺序if(item?.coverId?.length > 0){item?.coverId.forEach((coverItem)=>{if(this.mapboxMap.getLayer('layer_'+coverItem)){this.changeLayerZIndex('layer_' + item.id,'layer_'+coverItem);}})}//点击高亮操作if(this.getBrowser() == "pc" || this.getBrowser() == "linux"){this.mapboxMap.on('click','layer_' + item.id,(e)=>{this.callbackFunc({code: 1,data:'layer_' + item.id,msg: "获取成功!"},callback);})}else{//点击高亮操作this.mapboxMap.on('touchend','layer_' + item.id,(e)=>{this.callbackFunc({code: 1,data:'layer_' + item.id,msg: "获取成功!"},callback);})}}tempStorageInfo[item.id] = item.points;if(index == lineOption.length-1){this.callbackFunc({code: 1,data:tempStorageInfo,msg: "添加成功!"},callback);}}});}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
8、加面
/*** @author yangjie* @time 2023/10/13 11:24:07* @description 添加面 接收格式Array* id:String 唯一标识 必传* polygonInfo:Object 面样式设置 可选* points:二维Array 点位数据 必传*/
addPolygon(polygonOption,callback) {if(polygonOption?.length) {try{let tempStorageIdArr = [];polygonOption.forEach((item, index) => {if (item.id && item.points) {//实体已存在则删除const source = this.mapboxMap.getSource(item.id);const polygonFillLayerObject = this.mapboxMap.getLayer('layer_fill_'+item.id);const polygonOutlineLayerObject = this.mapboxMap.getLayer('layer_outline_'+item.id);//已存在 修改if(source){source.setData({type: 'Feature',geometry: {type: 'Polygon',coordinates: item.points}});if(polygonFillLayerObject){let layoutInfo = item.fill.layoutInfo;let paintInfo = item.fill.paintInfo;if(layoutInfo && Object.keys(layoutInfo).length){for(let layoutKey in layoutInfo){this.mapboxMap.setLayoutProperty('layer_'+item.id, layoutKey, layoutInfo[layoutKey]);}}if(paintInfo && Object.keys(paintInfo).length){for(let paintKey in paintInfo){this.mapboxMap.setPaintProperty('layer_'+item.id, paintKey, paintInfo[paintKey]);}}}if(polygonOutlineLayerObject){let layoutInfo = item.outLine.layoutInfo;let paintInfo = item.outLine.paintInfo;if(layoutInfo && Object.keys(layoutInfo).length){for(let layoutKey in layoutInfo){this.mapboxMap.setLayoutProperty('layer_'+item.id, layoutKey, layoutInfo[layoutKey]);}}if(paintInfo && Object.keys(paintInfo).length){for(let paintKey in paintInfo){this.mapboxMap.setPaintProperty('layer_'+item.id, paintKey, paintInfo[paintKey]);}}}}else{this.mapboxMap.addSource(item.id, {type: 'geojson',data: {type: 'Feature',geometry: {type: 'Polygon',coordinates: item.points}}});this.mapboxMap.addLayer({id: 'layer_fill_' + item.id,type: 'fill',source: item.id,layout: {"visibility": item.fill?.layoutInfo?.hasOwnProperty("visibility") ? item.fill?.layoutInfo["visibility"] : "visible",},paint: {/** 填充部分的颜色。* 可指定为rgba,如果使用的话,该颜色的不透明度不会影响1px描边的不透明度。*/'fill-color': item.fill?.paintInfo?.hasOwnProperty("fill-color") ? item.fill?.paintInfo["fill-color"] : '#83e5af',/** 整个填充层的不透明度。取值0~1* 与填充颜色相反,如果使用了描边,这个值也会影响填充周围1px的描边。*/'fill-opacity': item.fill?.paintInfo?.hasOwnProperty("fill-opacity") ?item.fill?.paintInfo["fill-opacity"] : 0.5,//填充的轮廓颜色。如果未指定,则匹配fill-color的值。'fill-outline-color': item.fill?.paintInfo?.hasOwnProperty("fill-outline-color") ?item.fill?.paintInfo["fill-outline-color"] : "#83e5af",//几何的偏移量。值为[x, y],其中负数分别表示向左和向上。'fill-translate': item.fill?.paintInfo?.hasOwnProperty("fill-translate") ?item.fill?.paintInfo["fill-translate"] : [0, 0],//平移的参考对象。取值 map(相对于地图)/viewport(相对于视窗)'fill-translate-anchor': item.fill?.paintInfo?.hasOwnProperty("fill-translate-anchor") ?item.fill?.paintInfo["fill-translate-anchor"] : "map",}});this.mapboxMap.addLayer({id: 'layer_outline_' + item.id,type: 'line',source: item.id,layout: {//是否可见 visible/none"visibility": item.outLine?.layoutInfo?.hasOwnProperty("visibility") ? item.outLine?.layoutInfo["visibility"] : "visible",},paint: {'line-color': item.outLine?.paintInfo?.hasOwnProperty("line-color") ?item.outLine?.paintInfo["line-color"] : '#83e5af','line-width': item.outLine?.paintInfo?.hasOwnProperty("line-width") ?item.outLine?.paintInfo["line-width"] : 3,//绘制线时的不透明度。 0 ~ 1之间的可选数字 默认值为 1"line-opacity": item.outLine?.paintInfo?.hasOwnProperty("line-opacity") ?item.outLine?.paintInfo["line-opacity"] : 1,}});}tempStorageIdArr.push(item.id);if(index == polygonOption.length-1){this.callbackFunc({code: 1,data:tempStorageIdArr,msg: "添加成功!"},callback);}}});}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
9、更改图层顺序
/*** topLayer:String 顶部图层的图层id 必传* bottomLayer:String 底部图层的图层id 必传*/
changeLayerZIndex(bottomLayer,topLayer){this.mapboxMap.moveLayer(bottomLayer,topLayer);
},
10、更改实体样式
/*** @description 更改layer/paint属性* type String 取值layout/paint* id:String layer图层的唯一标识 点线在id前面拼接layer_* 如果修改面的填充属性拼接layer_fill_* 如果修改面的边线属性拼接layer_outline_ 必传* stats:String 属性名 例如'icon-rotate' 必传* value:String 属性值 必传*/
updateLayoutOrPaint(updateOption,callback){try{if(updateOption?.type == "layout"){this.mapboxMap.setLayoutProperty(updateOption?.id, updateOption?.stats, updateOption?.value);}else if(updateOption?.type == "paint"){this.mapboxMap.setPaintProperty(updateOption?.id, updateOption?.stats, updateOption?.value);}this.callbackFunc({code: 1,msg: "更新成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
11、移除实体或图层
/*** @description 移除Source元素和Layer元素 参数接收格式:Array* removeIdArray:Array 举例['polygon'] 需要删除的id集合 必传*/
removeSourceAndLayer(removeIdArray,callback){if(removeIdArray?.length){try{removeIdArray.forEach((item,index)=>{const sourceObject = this.mapboxMap.getSource(item);const layerObject = this.mapboxMap.getLayer('layer_'+item);const polygonFillLayerObject = this.mapboxMap.getLayer('layer_fill_'+item);const polygonOutlineLayerObject = this.mapboxMap.getLayer('layer_outline_'+item);if(layerObject) this.mapboxMap.removeLayer('layer_'+item);if(polygonFillLayerObject) this.mapboxMap.removeLayer('layer_fill_'+item);if(polygonOutlineLayerObject) this.mapboxMap.removeLayer('layer_outline_'+item);if(sourceObject) this.mapboxMap.removeSource(item);if(index == removeIdArray.length-1){this.callbackFunc({code: 1,data:removeIdArray,msg: "删除成功!"},callback);}});}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
12、定位某个点
/*** @description 定位 接收格式Object* center:Array 中心点 举例:[116,39] 必传* zoom:Number 地图层级 可选,默认值9* duration:Number 飞行总时长,单位ms 可选,默认值800*/
locationPoint(locationOption,callback) {if(locationOption?.center){try{this.mapboxMap.flyTo({center: locationOption.center,zoom: locationOption?.zoom ? locationOption?.zoom : 9,duration: locationOption?.duration ? locationOption?.duration : 800});this.callbackFunc({code: 1,msg: "定位成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
13、定位数组
注:多点,用于定位某条线或某个区域
/*** @description 定位数组 接收格式Array* pointArray:二维Array 举例[[-79, 43], [-73, 45]] 必传*/
locationArray(pointArray,callback){if(pointArray){try{this.mapboxMap.fitBounds(pointArray, {padding: {top: 10, bottom:25, left: 15, right: 5}});this.callbackFunc({code: 1,msg: "定位成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}}else{this.callbackFunc("参数错误");}
},
14、锁定实体跟随视角
注:用于导航或者需要锁定某个实体
/*** @description 锁定实体,跟随视角* followInfo Object* latlngArr:Array 举例[116,39] 跟随的经纬度* altitude:Number 高度 跟随视角的高度*/
followLockEntity(followInfo,callback){try{const camera = this.mapboxMap.getFreeCameraOptions();const position = followInfo?.latlngArr ? followInfo.latlngArr : [116,39];const altitude = followInfo?.altitude ? followInfo.altitude : 3000;camera.position = mapboxgl.MercatorCoordinate.fromLngLat(position, altitude);camera.lookAtPoint(position);this.mapboxMap.setFreeCameraOptions(camera);this.callbackFunc({code: 1,msg: "跟随成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
15、获取视窗
/*** @description 获取视窗* @return*/
getBounds(callback){try{const bounds = this.mapboxMap.getBounds();this.callbackFunc({code: 1,data:bounds,msg: "获取成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
16、设置俯仰角
/*** @description 设置俯仰角* degree:Number 度数0-60 必填*/
setPitch(degree,callback){try{this.mapboxMap.setPitch(degree, {duration: 2000});this.callbackFunc({code: 1,msg: "设置成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
17、设置方位角
/*** @description 设置方位角* degree:Number 相机的方位是地图的视觉旋转,从北方逆时针方向测量,范围在0°到360°之间。* 0°的方位使地图定向,使北方“向上”,90°的方位使地图定向,使东方“向上”,以此类推。 必传*/
setBearing(degree,callback){try{this.mapboxMap.setBearing(degree);this.callbackFunc({code: 1,msg: "设置成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
18、设置地图中心点
/*** @description 设置地图中心点 接收格式Array* pointArray:Array 举例[116, 39] 必传*/
setCenter(pointArray,callback){try{this.mapboxMap.setCenter(pointArray);this.callbackFunc({code: 1,msg: "设置成功!"},callback);}catch(err){this.callbackFunc("未知错误");throw err;}
},
19、开启/关闭地图事件监听
注:mapbox中关闭监听事件时,必须与开启监听事件的回调函数一致才能成功取消监听
//开启监听地图拖拽(mapbox不支持开启禁止拖拽和禁止平移事件,监听鼠标拖拽后回到原始位置从而实现禁止拖拽的效果)
openListenMapDrag(){mapCenter = this.mapboxMap.getCenter();this.mapboxMap.on('dragend',this.dragBack);
},
//关闭监听地图拖拽
closeListenMapDrag(){this.mapboxMap.off('dragend',this.dragBack);
},
dragBack(){this.setCenter([mapCenter.lng,mapCenter.lat]);
},
20、部分方法调用示例
-
加点
let option = [{id: "ljgh-qd",paintInfo:{'icon-opcity':1,'text-color':"red",},layoutInfo:{'icon-image':"路径规划-引导点",'icon-size':0.4,'icon-anchor':"center",'icon-offset':[0,0],'icon-rotate':0,'text-field':"0",'text-anchor':"top",'text-offset':[0,0],'text-size':18,'description':"<div><div style='font-size: 18px'>我是你好的标题</div><div>我是你好的内容</div></div>",'visibility':"visible",},point: {lat: 39,lon: 116},flyInfo:{center: [116,39],zoom: 11,duration: 800},followInfo:{latlngArr:[116,39],altitude:1000},bearing:90
},{id: "ljgh-qd1",point: {lat: 39,lon: 118},
}];
this.$refs.htMap.MapOption('addPoint', option);
-
加线
let coordinates = [[116.483696, 39.833818],[116.483482, 39.833174],[116.483396, 39.8327]
];
let coordinates1 = [[90.4861, 41.828802],[111.486958, 37.82931],
];
let option = [{id:"nav_route",paintInfo:{"line-color":"black","line-pattern":"","line-width": 3,"line-blur": 0,"line-translate":[0, 0],"line-translate-anchor":"map","line-opacity":1},layoutInfo:{"line-join":"round","line-cap":"round","visibility":"visible",},points:coordinates,coverId:["ljgh-qd"]
},{id:"nav_route1",points:coordinates1
}];
this.$refs.htMap.MapOption('addLine', option);
-
加面
let coordinates = [[[117.13734, 40.13745],[120.03252, 40.13745],[121.03252, 37.5],[120.03252, 37.98],[117.13734, 37.98],]
];
let coordinates1 = [[[116.13734, 40.13745],[98.03252, 40.13745],[98.03252, 37.98],[116.13734, 37.98],]
];
let option = [{id:"polygon",fill:{layoutInfo:{"visibility":"visible",},paintInfo:{'fill-color': "red",'fill-opacity': 0.5,'fill-outline-color': "yellow",'fill-translate': [0,0],'fill-translate-anchor': "map",}},outLine:{layoutInfo:{"visibility":"visible",},paintInfo:{'line-color': "black",'line-width': 6,"line-opacity":0.5}},points:coordinates
},{id:"polygon1",points:coordinates1
}];
this.$refs.htMap.MapOption('addPolygon', option);
-
移除实体或图层
this.$refs.htMap.MapOption('removeSourceAndLayer',["ljgh-qd","ljgh-qd1"]);
-
更改图层顺序
this.$refs.htMap.MapOption('changeLayerZIndex',"layer_1" ,"layer_2");
-
开启关闭事件监听
this.$refs.htMap.MapOption('openListenMapDrag');
this.$refs.htMap.MapOption('closeListenMapDrag');
-
定位某个点
this.$refs.htMap.MapOption('locationPoint', {'center':[116,39],'zoom':5
});
-
定位数组
this.$refs.htMap.MapOption('locationArray', [[90.4861, 41.828802],[111.486958, 37.82931]]);
-
开启绘制
let data = this.$refs.htMap.MapOption('openDraw',{dataId:1,type:'draw_point'
},(res) => {this.delId = res.geometryId;
});
-
移除绘制
//需要取到回调的ID传入
this.$refs.htMap.MapOption('removeDrawById', [{dataId:null,geometryId:null,
}]);
-
锁定实体跟随视角
this.$refs.htMap.MapOption('followLockEntity', {latlngArr:[138.73036, 35.36197],altitude:3000
});
-
更改实体样式
this.$refs.htMap.MapOption('updateLayoutOrPaint', {type:"layout",id:"layer_ljgh-qd",stats:'icon-rotate',value:90
});
-
设置俯仰角
this.$refs.htMap.MapOption('setPitch',80);
-
设置方位角
this.$refs.htMap.MapOption('setBearing',90);
-
设置地图中心点
this.$refs.htMap.MapOption('setCenter',[118,32]);
-
获取视窗
this.$refs.htMap.MapOption('getBounds');
相关文章:
基于MapBox的方法封装及调用
目录 1、初始化地图 2、单独添加瓦片 3、开启绘制方法 4、移除绘制数据 5、拾取经纬度 6、加点 7、加线 8、加面 9、更改图层顺序 10、更改实体样式 11、移除实体或图层 12、定位某个点 13、定位数组 14、锁定实体跟随视角 15、获取视窗 16、设置俯仰角 17、设…...
华为OD机试真题-虚拟游戏理财-2023年OD统一考试(C卷)
题目描述: 在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家Bank,它提供有若干理财产品m,风险及投资回报不同,你有N(元)进行投资,能接受的总风险值为X。 你要在可接受范围内选择最优的投资方式获得最大回报。 说明: 在虚拟游戏中…...
解决 video.js ios 播放一会行一会不行
最近用video 进行m3u8视频文件播放,但是途中遇到了 安卓和电脑端都能打开,ios有时可以播放有时播放不了 出现问题原因: ios拿到视频流前需要预加载视频,如果当前视频流还没有打开过,ios拿不到视频流的缓存,…...

排序分析(Ordination analysis)及R实现
在生态学、统计学和生物学等领域,排序分析是一种用于探索和展示数据结构的多元统计技术。这种分析方法通过将多维数据集中的样本或变量映射到低维空间,以便更容易理解和可视化数据之间的关系。排序分析常用于研究物种组成、生态系统结构等生态学和生物学…...

Tomcat主配置文件(server.xml)详解
前言 Tomcat主配置文件(server.xml)是Tomcat服务器的主要配置文件,文件位置在conf目录下,它包含了Tomcat的全局配置信息,包括监听端口、虚拟主机、安全配置、连接器等。 目录 1 server.xml组件类别 2 组件介绍 3 se…...

Python实现简单的区块链,实现共识算法、Merkle Tree(默克尔树)、冲突解决、添加交易等功能
Python实现简单的区块链 记录自己假期所学相关内容 文章中的内容,开源代码地址见文末。 文章目录 Python实现简单的区块链1、分模块实现简单的单节点区块链1.1 Transaction类1.2 DaDaMessage类1.3 Block类1.4 Dada_BlockCoin类1.5 主函数BlockChainApp类1.6 主函数…...

深入理解 Java 虚拟机(JVM)从入门到精通
目录 一、JVM内存结构1、堆(Heap)(1)特点(2)堆内存分配(3)晋升到老年代的方式(4)堆内存检验方式2、虚拟机栈(VM Stack)(1&…...

哔哩哔哩自动评论软件,其成果展示与开发流程和代码分享
先来看实操成果,↑↑需要的同学可看我名字↖↖↖↖↖,或评论888无偿分享 一、背景介绍 随着互联网的发展,哔哩哔哩作为国内最大的弹幕视频网站之一,吸引了越来越多的用户。为了更好地推广自己的作品,许多UP主希望能够通…...

Qt OpenCV 学习(一):环境搭建
对应版本 Qt 5.15.2OpenCV 3.4.9MinGW 8.1.0 32-bit 1. OpenCV 下载 确保安装 Qt 时勾选了 MinGW 编译器 本文使用 MinGW 编译好的 OpenCV 库,无需自行编译 确保下载的 MinGW 和上述安装 Qt 时勾选的 MinGW 编译器位数一致,此处均为 x86/32-bit下载地址…...

Redis——某马点评day02——商铺缓存
什么是缓存 添加Redis缓存 添加商铺缓存 Controller层中 /*** 根据id查询商铺信息* param id 商铺id* return 商铺详情数据*/GetMapping("/{id}")public Result queryShopById(PathVariable("id") Long id) {return shopService.queryById(id);} Service…...

prometheus|云原生|轻型日志收集系统loki+promtail的部署说明
一, 日志聚合的概念说明 日志------ 每一个程序,服务都应该有保留日志,日志的作用第一是记录程序运行的情况,在出错的时候能够记录错误情况,简单来说就是审计工作,例如nginx服务的日志,kuber…...

MySQL 临时数据空间不足导致SQL被killed 的问题与扩展
开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系 liuaustin3 ,(共1730人左右 1 2 3 4 5࿰…...

文心一言大模型应用开发入门
本文重点介绍百度智能云平台、文心一言、千帆大模型平台的基本使用与接入流程及其详细步骤。 注册文心一言 请登录文心一言官方网站 https://yiyan.baidu.com/welcome 点击登录;图示如下: 请注册文心一言账号并点击登录,图示如下࿱…...

C++新经典模板与泛型编程:SFINAE替换失败并不是一个错误
替换失败并不是一个错误(SFINAE) SFINAE是一个英文简称,全称为Substitution Failure is not an Error,翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则,…...

基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…...

递归-极其优雅的问题解决方法(Java)
递归的定义 大名鼎鼎的递归,相信你即使没接触过也或多或少听过,例如汉诺塔问题就是运用了递归的思想,对于一些学过c语言的同学来说,它可能就是噩梦,因为我当时就是这么认为的(不接受反驳doge) …...

VSCode搭建STM32开发环境
1、下载安装文件 链接:https://pan.baidu.com/s/1WnpDTgYBobiZaXh80pn5FQ 2、安装VSCodeUserSetup-x64-1.78.2.exe软件 3、 在VSCode中安装必要的插件 3、配置Keil Assistant插件 4、在环境变量中部署mingw64编译环境...

解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“
centos系统下,用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法 unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1 上面这个命令在shell 终端能执行成功,…...

软件测试外包干了2个月,技术进步2年。。。
先说一下自己的情况,本科生,18年通过校招进入北京某软件公司,干了接近2年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...
Linux-网络服务和端口
域名:便于人们记忆和使用的标识符 www.baidu.com域名解析:将域名转换为与之对应的 IP 地址的过程 nameserver 8.8.8.8ip地址:网络设备的唯一数字标识符 域名ip地址localhost127.0.0.1 网络服务和端口 网络服务端口ftp21ssh22http80https…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...