百度地图引入(第一个script是引入百度地图,后2个是用到了自定义信息窗口才需要,第3个infobox.js官方文档上有)
<script src="http://api.map.baidu.com/api?v=3.0&ak=放自己的AK" type="text/javascript"></script>
<!--百度地图自定义信息窗口-->
<script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=放自己的AK" type="text/javascript"></script>
<script src="static/InfoBox.js" type="text/javascript"></script>
Dom部分很简单,有个容器就行了,如下
<div class="map-box" ref="mapContainer">
</div>
Data定义部分(主要是map实例,其他的非必需)
data () {
return {
map: null, // 地图实例
projectIconList: [
{id: 0, src: require('../../images/project-icon-blue.png')},
{id: 1, src: require('../../images/project-icon-green.jpg')},
{id: 2, src: require('../../images/project-icon-grey.jpg')},
{id: 3, src: require('../../images/project-icon-orange.jpg')},
],
projectIcon: null, // 项目icon
airportIcon: require('../../images/airport-icon.png'), // 机场icon
myProjectIcon: null, // 项目标注icon
myAirportIcon: null, // 机场标注icon
lastInfoBox: null, // 信息窗口
markerList: [], // 所有覆盖物数组(便于清空)
zoomNum: null, // 地图缩放级别
};
},
地图初始化的方法(此处增加了一些地图控件,不用可以去掉)
/*
* 地图初始化
* */
mapInit () {
this.map = new BMap.Map(this.$refs.mapContainer); // 创建地图实例
this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 8); // 初始化地图,用经纬度设置地图中心点,同时设置地图展示级别
this.map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
this.map.addControl(new BMap.NavigationControl({ anchor: BMAP_ANCHOR_TOP_RIGHT })); // 添加平移缩放控件
this.map.addControl(new BMap.ScaleControl({ offset: new BMap.Size(10, 5) })); // 添加比例尺控件
// this.map.addControl(new BMap.OverviewMapControl()); // 添加缩略图控件
this.map.addControl(new BMap.MapTypeControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(30, 20) })); // 添加地图类型控件(地图,卫星,混合)
this.map.setCurrentCity('北京'); // 仅当设置城市信息时,MapTypeControl的切换功能才能可用
百度坐标转换方法(这里是wgs-84坐标转百度)
/**
* 百度坐标转换方法
* @param x 需转换的坐标经度
* @param y 需转换的坐标维度
* @param translateCallback 转换方法的回调函数
* 坐标常量说明:
* COORDINATES_WGS84 = 1, WGS84坐标
* COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
* COORDINATES_GCJ02 = 3,GCJ02坐标
* COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
* COORDINATES_BD09 = 5, 百度bd09经纬度坐标
* COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
* COORDINATES_MAPBAR = 7,mapbar地图坐标
* COORDINATES_51 = 8,51地图坐标
*/
transformCoordinate (x, y, translateCallback) {
let originalPoint = new BMapGL.Point(x, y);
let convertor = new BMapGL.Convertor();
let pointArr = [];
pointArr.push(originalPoint);
convertor.translate(pointArr, COORDINATES_WGS84, COORDINATES_BD09, translateCallback);
},
算了,直接贴原码吧,不然也还是看不懂
<!--
* @Author : XuXing
* @Date : 2021/04/16
* @Version : 1.0
* @Content : 项目列表页地图
-->
<template>
<div class="map-box" ref="mapContainer">
</div>
</template>
<script>
import airportLocation from '../../../static/airportLocation';
export default {
name: 'projectList',
components: {},
props: ['dataList', 'clickedProject'],
data () {
return {
map: null, // 地图实例
projectIconList: [
{id: 0, src: require('../../images/project-icon-blue.png')},
{id: 1, src: require('../../images/project-icon-green.jpg')},
{id: 2, src: require('../../images/project-icon-grey.jpg')},
{id: 3, src: require('../../images/project-icon-orange.jpg')},
],
projectIcon: null, // 项目icon
airportIcon: require('../../images/airport-icon.png'), // 机场icon
myProjectIcon: null, // 项目标注icon
myAirportIcon: null, // 机场标注icon
lastInfoBox: null, // 信息窗口
markerList: [], // 所有覆盖物数组(便于清空)
zoomNum: null, // 地图缩放级别
};
},
created () {
window.goDetail = this.goDetail;// 解决字符串模板@click无效的问题
// this.$set(this.dataList);
},
mounted () {
this.mapInit();
},
computed: {
formatStatus () {
return (value) => {
return value === 0 ? '待开始' : value === 1 ? '进行中' : value === 2 ? '已完成' : '已延期';
};
}
},
watch: {
dataList: {
handler (newValue, oldValue) {
// console.log('mapnewValue:', newValue);
if (this.dataList.length > 0 && this.zoomNum >= 9) {
this.createProjectMarker();
}
},
immediate: true,
deep: true
}
},
methods: {
/*
* 地图初始化
* */
mapInit () {
this.map = new BMap.Map(this.$refs.mapContainer); // 创建地图实例
this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 8); // 初始化地图,用经纬度设置地图中心点,同时设置地图展示级别
this.map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
this.map.addControl(new BMap.NavigationControl({ anchor: BMAP_ANCHOR_TOP_RIGHT })); // 添加平移缩放控件
this.map.addControl(new BMap.ScaleControl({ offset: new BMap.Size(10, 5) })); // 添加比例尺控件
// this.map.addControl(new BMap.OverviewMapControl()); // 添加缩略图控件
this.map.addControl(new BMap.MapTypeControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(30, 20) })); // 添加地图类型控件(地图,卫星,混合)
this.map.setCurrentCity('北京'); // 仅当设置城市信息时,MapTypeControl的切换功能才能可用
this.myAirportIcon = new BMap.Icon(this.airportIcon, new BMap.Size(34, 40)); // 机场标注icon
this.createProjectMarker();
// 监听地图缩放级别
this.map.addEventListener('zoomend', e => {
this.zoomNum = this.map.getZoom();
// console.log('ZoomNum:', this.zoomNum);
if (this.zoomNum < 5) { // 缩放级别小于5时,不展示
this.remove(this.markerList);
this.markerList = [];
} else {
this.createProjectMarker();
}
});
},
/**
* 百度坐标转换方法
* @param x 需转换的坐标经度
* @param y 需转换的坐标维度
* @param translateCallback 转换方法的回调函数
* 坐标常量说明:
* COORDINATES_WGS84 = 1, WGS84坐标
* COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
* COORDINATES_GCJ02 = 3,GCJ02坐标
* COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
* COORDINATES_BD09 = 5, 百度bd09经纬度坐标
* COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
* COORDINATES_MAPBAR = 7,mapbar地图坐标
* COORDINATES_51 = 8,51地图坐标
*/
transformCoordinate (x, y, translateCallback) {
let originalPoint = new BMapGL.Point(x, y);
let convertor = new BMapGL.Convertor();
let pointArr = [];
pointArr.push(originalPoint);
convertor.translate(pointArr, COORDINATES_WGS84, COORDINATES_BD09, translateCallback);
},
/**
* 标识项目
*/
createProjectMarker () {
this.remove(this.markerList);
this.markerList = [];
this.dataList.forEach(item => {
let translateCallback = (data) => {
if (data.status === 0) {
this.createMarker(data.points[0], item);
}
};
// 数据原因,这里centerLatitude=>经度,centerLongitude=>纬度
this.transformCoordinate(item.defaultPosition.centerLatitude, item.defaultPosition.centerLongitude, translateCallback);
});
},
/**
* 项目打点及创建覆盖物
* @param point 百度bd09经纬度坐标
* @param projectInfo 项目信息
*/
createMarker (point, projectInfo) {
// console.log(projectInfo);
let pt = new BMap.Point(point.lng, point.lat);
this.projectIcon = this.projectIconList.find(icon => icon.id === projectInfo.status).src;
this.myProjectIcon = new BMap.Icon(this.projectIcon, new BMap.Size(34, 40)); // 项目标注icon
let marker = new BMap.Marker(pt, { icon: this.myProjectIcon });
this.markerList.push(marker);
this.map.addOverlay(marker);
let opts = {
position: point, // 指定文本标注所在的地理位置
offset: new BMap.Size(-10, -20) // 设置文本偏移量
};
let label = new BMap.Label(projectInfo.project_name, opts); // 创建文本标注对象
label.setStyle({ // label样式
color: '#333333',
fontSize: '16px',
lineHeight: '20px',
border: 'none',
background: '#ffffff',
textStrokeWidth: '2px', // 不生效
textStrokeColor: '#FFFFFF', // 不生效
textShadow: '2px 2px 2px #FFFFFF;' // 不生效
});
marker.setLabel(label); // 设置项目名称,设置覆盖物的文字标签
let projectStatus = this.formatStatus(projectInfo.status);
let arr = [projectInfo.id,projectInfo.project_name,projectInfo.tempId]; // 解决onClick无法传对象
// 点击标注,打开自定义信息窗口
marker.addEventListener('click', () => {
let html = `<div style="cursor: default">
<div style="display: flex;justify-content: space-between">
<span style="font-size: 18px;font-family: Source Han Sans CN;color: #333333;line-height: 30px;cursor: pointer" onClick="goDetail('${arr}')">${ projectInfo.project_name }</span>
<div style="background: #367BF1;border-radius: 4px;padding: 6px 12px;text-align: center;color: #ffffff;font-size: 14px;cursor: pointer">数据总览</div>
</div>
<div style="margin-top: 12px">
<p style="font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #666666;">项目类型:${ projectInfo.templateTypeName }</p>
<p style="font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #666666;">项目状态:${ projectStatus }</p>
</div>
</div>`;
let infoBox = new BMapLib.InfoBox(this.map, html, {
boxStyle: {
background: '#FFFFFF',
width: '300px',
height: '120px',
borderRadius: '4px',
boxShadow: '0 2px 4px 0 rgba(0, 0, 0, 0.2)',
padding: '17px 11px',
zIndex: 999
},
enableAutoPan: false, // 是否启动自动平移功能
align: INFOBOX_AT_TOP, // 基于哪个位置进行定位
offset: new BMap.Size(0, 30)
});
if (this.lastInfoBox) {
//判断上一个窗体是否存在,若存在则执行close
this.lastInfoBox.close();
this.lastInfoBox = null;
} else {
infoBox.open(marker); // 开启信息窗口
this.lastInfoBox = infoBox;
}
});
},
/**
* 根据选择的项目改变地图中心
*/
changeCenter () {
// 转换方法的回调函数
let translateCallback = (data) => {
if (data.status === 0) {
let pt = new BMap.Point(data.points[0].lng, data.points[0].lat);
this.map.centerAndZoom(pt, 9); // 把点击的点设置为地图中心点,同时设置地图展示级别
}
};
this.$nextTick(() => {
// 数据原因,这里centerLatitude=>经度,centerLongitude=>纬度
this.transformCoordinate(this.clickedProject.defaultPosition.centerLatitude, this.clickedProject.defaultPosition.centerLongitude, translateCallback);
});
},
/**
* 清空覆盖物
* @param list 覆盖物数组
*/
remove (list) {
if (list && list.length > 0) {
[...list].every(x => (!this.map.removeOverlay(x)));
}
},
/**
* 标识机场
*/
createAirportMarker () {
this.remove(this.markerList);
this.markerList = [];
airportLocation.forEach(item => {
// 转换方法的回调函数
let translateCallback = (data) => {
if (data.status === 0) {
let pt = new BMap.Point(data.points[0].lng, data.points[0].lat);
let marker = new BMap.Marker(pt, { icon: this.myAirportIcon });
this.markerList.push(marker);
this.map.addOverlay(marker);
let opts = {
position: data.points[0], // 指定文本标注所在的地理位置
offset: new BMap.Size(-33, -20) // 设置文本偏移量
};
let label = new BMap.Label(item.name, opts); // 创建文本标注对象
label.setStyle({ // label样式
color: '#333333',
fontSize: '16px',
lineHeight: '20px',
border: 'none',
background: '#ffffff',
});
marker.setLabel(label); // 设置项目名称,设置覆盖物的文字标签
}
};
this.transformCoordinate(item.longitude, item.latitude, translateCallback);
});
},
/**
* 跳转项目详情
*/
goDetail(project) {
setTimeout(() => {
this.$router.push({
path: "projectEdit",
query: {
pid: project.split(',')[0],
pname: project.split(',')[1],
tempid: project.split(',')[2]
}
});
}, 100);
},
}
};
</script>
<style lang="less" scoped>
@deep: ~'>>>';
@import "../../styles/common";
.map-box {
width: 100%;
height: 100%;
}
/*下面两段是去掉百度地图水印的css*/
@{deep}.BMap_cpyCtrl {
display: none !important;
}
@{deep}.anchorBL {
a {
display: none !important;
}
}
/*隐藏地图类型控件的三维地图按钮(百度已废弃三维)*/
@{deep}.anchorBR {
div:nth-child(3) {
display: none !important;
}
}
</style>