/**
* 设计想法:
* 1、封装基本单位对象:单独封装较小单位对象(point、icon)
* 2、返回基本对象:创建较大目标时,构造一个信息对象作为返回
* 2.1 缓存
* 2.2 可用于二次操作(单标记多图层...),以及更多个性化操作
* 3、不限制于局部map对象,可用于外部map
* 4、set* 与 add* 区别
* 前者需要较少参数,且可自行增加额外更多操作(对象类型单一,需手动挂载图层等)
* 后者需要较多参数,但避免较少额外操作(参数:坐标,样式对象)
*/
PS. 由于我是通过SDK的方式引入地图。所以地图的相关构造方法均在Window对象中。可自行打印window查看
故获取Map对象可以通过以下方式获取:
window.BMap // 不同的地图SDK可能不同名称,例如:BMap,BMAPGL
// mixins.data
data() {
return {
baiduMap: null, // 地图对象
// BMAP / BMAPGL
rootMap: "BMap", // Map对象对应key值
}
}
/**
* 创建坐标对象
* lng 经度
* lat 纬度
*/
setPoint(lng, lat) {
return new window[this.rootMap].Point(
parseFloat(lng),
parseFloat(lat)
);
},
/**
* 创建图表对象
* path 图标路径
* width 图标宽度
* height 图标高度
*/
setIcon(path, width, height) {
return new window[this.rootMap].Icon(
path,
new window[this.rootMap].Size(width, height),
// anchor 图标的定位点相对于图标左上角的偏移值,设置为图标的底部中心点
{ anchor: new window[this.rootMap].Size(parseInt(width / 2), height) }
);
},
/**
* 创建标记对象
* pointOrLng 坐标对象或经度
* latOrIcon 纬度或图标对象
*/
setMarker(pointOrLng,latOrIcon=null) {
// 用typeof 、instanceof 会规范
if(latOrIcon && typeof(latOrIcon) != "object" ) {
return new window[this.rootMap].Marker(this.setPoint(pointOrLng,latOrIcon));
}else if(latOrIcon) {
return new window[this.rootMap].Marker(pointOrLng,{ icon: latOrIcon });
}
return new window[this.rootMap].Marker(pointOrLng);
},
/**
* 创建文本标注对象
* point
* obj 基本设置
*/
setWindowInfo(obj = null) {
try {
let keySet = Object.keys(obj);
if (!keySet.length) {
throw new Error("obj must be not null!")
}
let opts = {
width: obj.width ? obj.width : 300,
height: obj.height ? obj.height : 150,
title: obj.title ? obj.title : "信息",
enableMessage: true, //设置允许信息窗发送短息
...obj
}
// InfoWindow( message[窗口内容,可以为html ],style[窗口样式] )
let info = new window[this.rootMap].InfoWindow(obj.message, opts);
return info;
} catch (e) {
console.log("setWindowInfo error: ",e);
}
},
/**
* 创建文本标注对象
* message 标注信息
* lngOrPoint 经度或坐标对象
* lat 纬度
*/
setLabel(message,lngOrPoint,lat=null) {
// 设置默认偏移量
let opts = {
offset: new window[this.rootMap].Size(-100,23),
}
let point = lngOrPoint;
if(lat && !isNaN(lngOrPoint) ) {
point = this.setPoint(lngOrPoint,lat);
}
return new window[this.rootMap].Label(
message,
{position:point,...opts}
);
},
单独封装图形(基于set方法)
/**
* point 坐标对象
* mapComponent 目标的实例对象
* type 目标类型
* style 其他内容
*/
returnConstructor(point, mapComponent, type,style = {}) {
return { point, mapComponent, type, ...style }
},
// 增加定点标记
addIcon(iconPath, lng, lat, width = 50, height = 50) {
let point = new window[this.rootMap].Point(lng, lat)
let icon = this.setIcon(iconPath,width,height);
let marker = new window[this.rootMap].Marker(point, { icon })
this.baiduMap.addOverlay(marker);
return this.returnConstructor(point, marker,"marker");
}
// 线条
addLine(pointArr) {
let item = [];
if (pointArr[0] instanceof Array) {
// pointArr 为数组
item = pointArr.map(v => { return { lng: v[0], lat: v[1] } })
} else {
// pointArr 为对象
item = [...pointArr]
}
if (!new BMapGLLib.TrackAnimation) {
console.error("the BMapGLLib.TrackAnimation is not exist!");
return ;
}
let pointList = [];
item.forEach(ele => {
pointList.push(this.setPoint(ele.lng, ele.lat));
})
// 创建线条对象
let polyLine = new window[this.rootMap].Polyline(pointList);
// 可增加线条绘制动画 (需要查看当前地图是否带有 BMapGLLib.TrackAnimation)
// let trackAni = new BMapGLLib.TrackAnimation(
// this.baiduMap,
// polyLine,
// { overallView: true, tilt: 30, duration: 10000, delay: 200, }
// )
// trackAni.start();
return this.returnConstructor(pointList, polyLine,"polyLine");
}
// 添加圆
addCircle(lng, lat, radius = 100, style = {}) {
let point = this.setPoint(lng, lat);
let circle = new window[this.rootMap].Circle(
point,
radius,
{
strokeColor: "#c0c0c0", // 边线颜色
strokeWeight: 1, // 边线宽度
// strokeStyle: 'solid', // 边线的样式,solid或dashed
fillColor: "blue", // 填充颜色。当参数为空时,圆形将没有填充效果。
fillOpacity: 0.12, // 填充的透明度,取值范围0 - 1。
// strokeOpacity: 0.8, // 边线透明度,取值范围0 - 1。
...style
}
);
this.baiduMap.addOverlay(circle);
return this.returnConstructor(point, circle,"circle");
},
// 添加多边形
addPolygons(pointsArr, style = {}) {
if (!pointsArr) throw new Error("pointsArr is null");
let obj = [];
if (pointsArr[0] instanceof Array) {
obj = pointsArr.map(v => {
return { lng: v[0], lat: v[1] }
})
} else if (pointsArr[0] instanceof Object) {
obj = [...pointsArr];
}
// 参数与圆形类似,详细说明看 2.2.4
let polyStyle = {
strokeWeight: 1,
strokeColor: "#c0c0c0",
fillColor: "#ccc",
fillOpacity: 0.12,
...style
}
let points = obj.map(item => this.setPoint(item.lng, item.lat));
let polygon = new window[this.rootMap].Polygon(points, polyStyle);
this.baiduMap.addOverlay(polygon);
return this.returnConstructor(points, polygon,"polygon");
}
// 添加信息窗口
addWindowsInfo(obj = {}, opts={}) {
let point = this.setPoint(obj.longitude, obj.latitude);
let marker = this.setMarker(point);
// 是否创建文本标注
if(obj.showLabel) {
marker.setLabel(this.setLabel(point,obj.site_name));
}
let info = this.setWindowInfo(obj);
this.addWindowsInfoListener(marker, bMap, info, point, "click");
this.getMap(bMap).addOverlay(marker);
return this.returnConstructor(point, marker,"windowInfo");
},
/**
* 创建信息窗口事件
* tar 绑定事件的目标对象
* info 信息窗口对象
* point 坐标对象
* type 事件类型
*/
addWindowsInfoListener(tar, info, point, type = "click") {
tar.addEventListener(type, function () {
try {
tar.getMap(this.baiduMap).openInfoWindow(info, point);
} catch (e) {
console.log("addWindowsInfoListener error: ", e.message);
}
})
},
addLabel(lng, lat, message) {
let point = this.setPoint(lng, lat);
let label = this.setLabel(point, message);
this.baiduMap.addOverlay(label);
return this.returnConstructor(point, label, "label");
},
官方文档中,清除标记有两种方式:
1、clearOverlays():清除地图上所有的覆盖物,可以用过触发标记对象的enableMassClear/disableMassClear方法允许/禁止被清除。
2、removeOverlay( overlay: Overlay ):从地图中移除覆盖物。如果覆盖物从未被添加到地图中,则不起任何作用添加覆盖物api:
3、addOverlay(overlay: Overlay ):
clearOverlays: function() {
this.dispatchEvent(new BaseEvent("onclearoverlays"))
},
removeOverlay: function(t) {
t && isFunction(t.remove) && (t.remove(),
this.dispatchEvent(new BaseEvent("onremoveoverlay",t)))
},
// 清除单个覆盖物
// 1. 调用map实例对象的removeOverlay 清除某个overlay
removeOverlay(overlay) {
if(overlay.mapComponent) {
this.baiduMap.removeOverlay(overlay.mapComponent);
}else {
this.baiduMap.removeOverlay(overlay);
}
},
// 2. 调用overlay 的remove方法来清除自己
// overlay.mapComponent.remove()
// 清除所有覆盖物
clearOverlays() {
this.baiduMap.clearOverlays();
},
panTo(pointsOrLng,lat=null) {
let pointObj = {};
if (pointsOrLng instanceof Array) {
pointObj.lng = pointsOrLng[0];
pointObj.lat = pointsOrLng[1];
} else if (pointsOrLng instanceof Object) {
pointObj = { ...pointsOrLng };
}
if(!isNaN(lat)) {
this.baiduMap.panTo(this.setPoint(pointsOrLng, lat));
}
this.baiduMap.panTo(this.setPoint(pointObj.lng, pointObj.lat));
},
// this.baiduMap.zoomTo(Index)