UNPKG

czmap

Version:

- 提供统一的API 实现不同的地图(百度、高德、腾讯)应用 丝滑切换 - 主要实现功能 - 基础地图展示 - 路径 - 围栏 #### 相关API使用

259 lines (256 loc) 9.19 kB
export function initBMap(this: any) { const BMapGL = (window as any).BMapGL || {}, BMapGLLib = (window as any).BMapGLLib || {}, gcoord = (window as any).gcoord || {}; let { id, points = [116.404, 39.915], areaName, poiText = true, //是否显示POI信息 poiIcon = true, //是否显示POI图标信息 zoom = 10, drivingPath = [], enableScrollWheel = false, isScaleCtrl = false, isZoomCtrl = false, navi3DCtrl = false, // 添加3D控件 enclosure = {}, coordType, drivingType } = this.$options const map = new BMapGL.Map(id); // 坐标中心点转换 let centerpoint = points // 坐标转换 function pointsChange(data){ let dishPint = [] data.forEach(item => { const result = gcoordChange([item.lng,item.lat]) dishPint.push({lng:result[0], lat:result[1]}) }) return dishPint } // 坐标走二次转换 function gcoordChange(points){ const result = gcoord.transform( points, // 经纬度坐标 gcoord.GCJ02, // 当前坐标系 gcoord.BD09 // 目标坐标系 ); return result } // 如果使用非百度的BD09坐标系 转换为gcj02 if (!coordType){ // 中心点的转换 centerpoint = gcoordChange(points) // 路径转换 if (drivingPath){ drivingPath = pointsChange(drivingPath) } // 圆心围栏转换 if(enclosure && enclosure.point){ enclosure.point = gcoordChange(enclosure.point) } // 其他围栏转换 if(enclosure && enclosure.points){ enclosure.points = pointsChange(enclosure.points) } } const point = this.$options.points && points.length === 2 ? new BMapGL.Point(centerpoint[0], centerpoint[1]) : null; map.centerAndZoom(point ?? areaName, zoom); map.enableScrollWheelZoom(enableScrollWheel); map.setDisplayOptions({ poiText, poiIcon }) // 添加3D控件 if (navi3DCtrl){ const ctrl3D = new BMapGL.NavigationControl3D(); map.addControl(ctrl3D); } // 添加比例尺控件 if (isScaleCtrl) { const scaleCtrl = new BMapGL.ScaleControl(); map.addControl(scaleCtrl); } // 添加缩放控件 if (isZoomCtrl) { const zoomCtrl = new BMapGL.ZoomControl(); map.addControl(zoomCtrl); } // 轨迹配置 if (drivingPath && drivingPath.length >= 2) { const startPints = [drivingPath[0].lng, drivingPath[0].lat] const endPints = [drivingPath.at(-1).lng, drivingPath.at(-1).lat] // 起始结束点位计算路径 if (drivingType && drivingType === 'path') { const start = new BMapGL.Point(startPints[0], startPints[1]); const end = new BMapGL.Point(endPints[0], endPints[1]); const driving = new BMapGL.DrivingRoute(map, { renderOptions: { map: map, autoViewport: true } }); driving.search(start, end); } else { map.centerAndZoom(new BMapGL.Point(startPints[0], startPints[1])); let point = []; for (let i = 0; i < drivingPath.length; i++) { point.push(new BMapGL.Point(drivingPath[i].lng, drivingPath[i].lat)); } const pl = new BMapGL.Polyline(point, { strokeColor: "#6699FF", strokeWeight: 6, }); const markerST = new BMapGL.Marker(new BMapGL.Point(startPints[0], startPints[1]), { title: '起点' }); const markerEND = new BMapGL.Marker(new BMapGL.Point(endPints[0],endPints[1]), { title: '终点' }); setTimeout(function () { const trackAni = new BMapGLLib.TrackAnimation(map, pl, { overallView: true, // 动画完成后自动调整视野到总览 tilt: 30, // 轨迹播放的角度,默认为55 duration: 4000, // 动画持续时长,默认为10000,单位ms delay: 300 // 动画开始的延迟,默认0,单位ms }); trackAni.start(); map.addOverlay(markerST); map.addOverlay(markerEND); }, 1000); } } // 围栏配置 if (enclosure && enclosure.type === 'circle') { const { fillColor = "#6699FF", fillOpacity = 0.3, strokeColor = "#6699FF", strokeWeight = 2, strokeOpacity = 1, point, radius } = enclosure const circle = new BMapGL.Circle(new BMapGL.Point(point[0],point[1]), radius, { fillColor, fillOpacity, strokeColor, strokeWeight, strokeOpacity, }); setCircleBestViewport(new BMapGL.Point(point[0], point[1]), radius) map.addOverlay(circle); // 添加到地图中 } else if (enclosure && enclosure.type === 'polygon') { const { fillColor = "#6699FF", fillOpacity = 0.3, strokeColor = "#6699FF", strokeWeight = 2, strokeOpacity = 1, points = [] } = enclosure let pl = [] for (let i = 0; i < points.length; i++) { pl.push(new BMapGL.Point(points[i].lng, points[i].lat)) } const polygon = new BMapGL.Polygon(pl, { fillColor, fillOpacity, strokeColor, strokeWeight, strokeOpacity }); setZoom(pl) map.addOverlay(polygon); } else if ((enclosure && enclosure.type === 'district')){ // 行政区域 const { fillColor = "#6699FF", fillOpacity = 0.3, strokeColor = "#6699FF", strokeWeight = 2, strokeOpacity = 1, proname = '北京市', prokind = 1 } = enclosure /************/ //获取行政区域 并调整视野 const bdary = new BMapGL.Boundary(); bdary.get(proname, function(rs) { const points = rs.boundaries[0].split(';') const nPoints = points.map(it => { const item = it.split(',') return {lng: item[0], lat: item[1]} }) setZoom(nPoints) }) // 必须调整完视野才能 添加行政区域覆盖 setTimeout(function(){ const dist = new BMapGL.DistrictLayer({ name: `(${proname})`, fillColor, strokeWeight, strokeColor, fillOpacity }); map.addDistrictLayer(dist); }, 1200) /************/ } else if ( enclosure && enclosure.type === 'polyline'){ // 绘制线 const { strokeColor = "#6699FF", strokeWeight = 4, strokeOpacity = 1, points, offset } = enclosure let point = []; for (let i = 0; i < points.length; i++) { point.push(new BMapGL.Point(points[i].lng, points[i].lat)); } var opts = { position: new BMapGL.Point(points[0].lng, points[0].lat), // 指定文本标注所在的地理位置 offset: new BMapGL.Size(30, -30) // 设置文本偏移量 }; // 创建文本标注对象 var label = new BMapGL.Label(`线性覆盖辐射范围: ${offset} 米`, opts); // 自定义文本标注样式 label.setStyle({ color: '#6699FF', borderRadius: '5px', borderColor: '#ccc', padding: '5px 15px', fontSize: '14px', height: '28px', lineHeight: '30px', fontFamily: '微软雅黑' }); var polyline = new BMapGL.Polyline( point, { strokeColor, strokeWeight, strokeOpacity }); setZoom(points) map.addOverlay(label); map.addOverlay(polyline); } // 多边形视野调整 function setZoom(bPoints) { var view = map.getViewport(bPoints); var mapZoom = view.zoom; var centerPoint = view.center; map.centerAndZoom(centerPoint, mapZoom); } // 圆形的最佳视野范围 function setCircleBestViewport(point, radius) { let zoom = 20; //地图层级数(百度地图默认为19层,这里多加1层使下面通过直径的运算刚好可以得出地图对应的层级) let num = 20; //基数 while (num < radius) { num = num * 2; zoom--; } map.centerAndZoom(point, zoom + 1); //设置中心点和缩放层级,为了优化显示效果此处zoom多加2级 } }