czmap
Version:
- 提供统一的API 实现不同的地图(百度、高德、腾讯)应用 丝滑切换 - 主要实现功能 - 基础地图展示 - 路径 - 围栏 #### 相关API使用
259 lines (256 loc) • 9.19 kB
text/typescript
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级
}
}