基于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…...
Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)读书笔记 目录
完结状态:未完结 文章目录 前言第1章 Kubernetes入门 11.1 了解Kubernetes 2 附录A Kubernetes核心服务配置详解 915总结 前言 提示:这里可以添加本文要记录的大概内容: Kubernetes权威指南:从Docker到Kubernetes实践全接触&…...
阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来
前言 Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类…...
Redis中持久化策略RDB与AOF优缺点对比
Redis持久化策略对比 RDBAOF持久化方式定时对整个内存做快照记录每一次执行的命令数据完整性不完整,两次备份之间存在丢失相对完整,取决于刷盘策略文件大小会有压缩,文件体积小记录命令,文件体积较大宕机恢复速度很快慢数据恢复优先级低,数据完整性不如AOF高,记录了执行命令数据…...
通用plantuml 时序图(Sequence Diagram)模板头
通用plantuml文件 startuml participant Admin order 0 #87CEFA // 参与者、顺序、颜色 participant Student order 1 #87CEFA participant Teacher order 2 #87CEFA participant TestPlayer order 3 #87CEFA participant Class order 4 #87CEFA participant Subject order …...
Domino多Web站点托管
大家好,才是真的好。 看到一篇文档,大概讲述的是他在家里架了一台Domino服务器,上面跑了好几个Internet的Web网站(使用Internet站点)。再租了一台云服务器,上面安装Nginx做了反向代理,代理访问…...
防火墙补充NAT
目录 1.iptables保存规则 2.自定义链 3.NAT NAT的实现分为下面类型: SNAT实验操作 DNAT实验操作 1.iptables保存规则 永久保存方法一: iptables -save > /data/iptables_rule //输出重定向备份 iptables -restore < /data/iptables_r…...
配置和管理VLAN
VLAN技术是交换技术的重要组成部分,也是交换机配置的基础。用于把物理上直接相连的网络从逻辑上划分为多个子网。 每一个VLAN 对应一个广播域,处于不同VLAN 上的主机不能通信。 不同VLAN 之间通信需要引入三层交换技术。 对性能局域网的配置和管理主要…...
dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)
1 数据 第一个维度是sequence的index,每一行是多个元素(表示这一时刻的record) from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…...
2 文本分类入门:TextCNN
论文链接:https://arxiv.org/pdf/1408.5882.pdf TextCNN 是一种用于文本分类的卷积神经网络模型。它在卷积神经网络的基础上进行了一些修改,以适应文本数据的特点。 TextCNN 的主要思想是使用一维卷积层来提取文本中的局部特征,并通过池化操…...
算法初阶双指针+C语言期末考试之编程题加强训练
双指针 常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。 对撞指针:⼀般⽤于顺序结构中,也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼…...
【Spark基础】-- 宽窄依赖
目录 1、前言 2、宽窄依赖 2.1 窄依赖 2.2 宽依赖 3、宽窄转换的算子 1、前言 要理解宽窄依赖,首先我们需要了解 Transform...
Spatial Data Analysis(六):空间优化问题
Spatial Data Analysis(六):空间优化问题 使用pulp库解决空间优化问题: pulp是一个用于优化问题的Python库。它包含了多种优化算法和工具,可以用于线性规划、混合整数线性规划、非线性规划等问题。Pulp提供了一个简单…...
PHP短信接口防刷防轰炸多重解决方案三(可正式使用)
短信接口盗刷轰炸:指的是黑客利用非法手段获取短信接口的访问权限,然后使用该接口发送大量垃圾短信给目标用户 短信验证码轰炸解决方案一(验证码类解决)-CSDN博客 短信验证码轰炸解决方案二(防止海外ip、限制ip、限制手机号次数解决)-CSDN博客 PHP短信…...
C#大型LIS检验信息系统项目源码
LIS系统,一套医院检验科信息系统。它是以数据库为核心,将实验仪器与电脑连接成网,基础功能包括病人样本登录、实验数据存取、报告审核、打印分发等。除基础功能外,实验数据统计分析、质量控制管理、人员权限管理、试剂出入库等功能…...
【C语言】数据在内存中的存储
目录 练笔 整型数据的存储: char 型数据——最简单的整型 整型提升: 推广到其他整形: 大小端: 浮点型数据的存储: 存储格式: 本篇详细介绍 整型数据,浮点型数据 在计算机中是如何储存的。…...
Java聊天程序(一对一)简单版
我们首先要完成服务端,不然出错,运行也要先运行服务端,如果不先连接服务端,就不监听,那客户端不知道连接谁 服务端 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.Actio…...
Linux下超轻量级Rust开发环境搭建:一、安装Rust
Rust语言在国内逐步开始流行,但开发环境的不成熟依然困扰不少小伙伴。 结合我个人的使用体验,推荐一种超轻量级的开发环境:Rust Helix Editor。运行环境需求很低,可以直接在Linux终端里进行代码开发。对于工程不是太过庞大的Rus…...
定义一个学生类,其中有3个私有数据成员学号、姓名、成绩,以及若于成员。 函数实现对学生数据的赋值和输出。
#include <stdio.h> // 定义学生类 typedef struct Student { int stuNum; // 学号 char name[20]; // 姓名,假设最长为20个字符 float score; // 成绩 } Student; // 初始化学生信息 void initializeStudent(Student *student, int num, const…...
1.2 C语言简介
一、为什么要讲C语言 C语言是编程界的长青藤,可以查看语言排名发现,虽然现在语言很多,但是C语言一直占有一定地址 来源网站:https://www.tiobe.com/tiobe-index/ 在系统、嵌入式、底层驱动等领域存在一定的唯一性(C语…...
小白学Java之数组问题——第三关黄金挑战
内容1.数组中出现次数超过一般的数字2.数组中出现一次的数字3.颜色分类问题 1.数组中出现次数超过一半的数字 这是剑指offer中的一道题目,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如:输入如下所示的一个长度为9…...
各大期刊网址
1.NeurIPS,全称Annual Conference on Neural Information Processing Systems, 是机器学习领域的顶级会议,与ICML,ICLR并称为机器学习领域难度最大,水平最高,影响力最强的会议! NeurIPS是CCF 推…...
使用autodl服务器,在A40显卡上运行, Yi-34B-Chat-int4模型,并使用vllm优化加速,显存占用42G,速度18 words/s
1,演示视频 https://www.bilibili.com/video/BV1gu4y1c7KL/ 使用autodl服务器,在A40显卡上运行, Yi-34B-Chat-int4模型,并使用vllm优化加速,显存占用42G,速度18 words/s 2,关于A40显卡…...
unity 2d 入门 飞翔小鸟 下坠功能且碰到地面要停止 刚体 胶囊碰撞器 (四)
1、实现对象要受重力 在对应的图层添加刚体 改成持续 2、设置胶囊碰撞器并设置水平方向 3、地面添加盒状碰撞器 运行则能看到小鸟下坠并落到地面上...
速达软件任意文件上传漏洞复现
简介 速达软件专注中小企业管理软件,产品涵盖进销存软件,财务软件,ERP软件,CRM系统,项目管理软件,OA系统,仓库管理软件等,是中小企业管理市场的佼佼者,提供产品、技术、服务等信息,百万企业共同选择。速达软件全系产品存在任意文件上传漏洞,未经身份认证得攻击者可以通过此漏…...
Name or service not knownstname
Name or service not knownstname Hadoop 或 Spark 集群启动时 报错 Name or service not knownstname 原因时因为 workers 文件在windows 使用图形化工具打开过 操作系统类型不对引发的 在Linux系统上删除 workers 文件 使用 vim 重新编辑后分发即可...
[Geek Challenge 2023] web题解
文章目录 EzHttpunsignn00b_Uploadeasy_phpEzRceezpythonezrfi EzHttp 按照提示POST传参 发现密码错误 F12找到hint,提示./robots.txt 访问一下,得到密码 然后就是http请求的基础知识 抓包修改 最后就是 我们直接添加请求头O2TAKUXX: GiveMeFlag 得到…...
【recrutment / Hiring / Job / Application】
Interviewee I), objected/targeted job/position1.1) Azure 平台运维工程师(comms&social)1.1.1), comms communication and social, for talk, content1.1.2) Cloud computing1.1.3) 拥有ITI/MCSE/RHCE相关认证或Azure认证(如Az204/Az304 have/own…...
二极管:ESD静电保护二极管
一、什么是ESD二极管 ESD二极管与 TVS二极管原理是一样的,也是为了保护电,但ESD二极管的主要功能是防止静电。 静电防护的前提条件就要求其电容值要足够地低,一般在1PF-3.5PF之间最好,主要应用于板级保护。 二、什么是静电 静…...
【根据数组元素生成随机颜色函数】
const colorOptions ["#f50","#2db7f5","#87d068","#108ee9",];const getRandomColor () > {const randomIndex Math.floor(Math.random() * colorOptions.length);return colorOptions[randomIndex];}; 时小记,终有…...
鸿蒙一出,android开发处境再受重创
华为宣布其自研操作系统鸿蒙HarmonyOSNEXT开发者预览版将不再兼容安卓系统,这一消息引起了广泛关注和热议。这一决策标志着华为正式告别安卓,摆脱了外部的制约,开始着手打造一个全新的生态系统。 鸿蒙系统4发布一个月,截至目前&a…...