uniapp实现地图点聚合功能

前言

在工作中接到的一个任务,在app端实现如下功能:

  • 地图点聚合
  • 地图页面支持tab切换(设备、劳务、人员)
  • 支持人员搜索显示分布

但是uniapp原有的map标签不支持点聚合功能(最新的版本支持了点聚合功能),所以采取了hybrid 原生html文件开发的方式

最新的版本map已支持,如下:
在这里插入图片描述

效果图

在这里插入图片描述

生成页面

pages.json中定义distribution.vue页面

{
    
    
    "path": "pages/distribution/distribution",
    "style": {
    
    
        "navigationBarTitleText": "人机分布",
        "navigationBarTextStyle": "black"
    }
},

页面结构主要分为三个部分:顶部标题tab切换地图画布

顶部标题

顶部标题就不用讲了,一般打开微信小程序页面或者app页面,都是左—返回,中—标题,右—其他。存在默认设置,但这里的话存在web-view(web 浏览器组件,可以用来承载网页的容器),很有可能将顶部标题覆盖掉,所以使用自定义标题,具体实现如下:

<view class="tab">
  <!-- :isBack="true" -->
  <tab-left bgColor="bg-gradual-white" :isBack="true" :url="gobackurl">
    <block slot="backText">返回</block>
    <block slot="content">人机分布</block>
  </tab-left>
</view>

tab-left组件

<template>
	<view>
		<view class="cu-custom" :style="[{height:CustomBar + 'px'}]">
			<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
				<view class="action" @tap="BackPage" v-if="isBack">
					<text class="cuIcon-back"></text>
					<slot name="backText"></slot>
				</view>
				<view class="content" :style="[{top:StatusBar + 'px'}]">
					<slot name="content"></slot>
				</view>
				<view  style="margin-right:30upx;">
					<slot name="right"></slot>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
    
    
		data() {
    
    
			return {
    
    
				StatusBar: this.StatusBar,
				CustomBar: this.CustomBar
			};
		},
		name: 'cu-custom',
		computed: {
    
    
			style() {
    
    
				var StatusBar= this.StatusBar;
				var CustomBar= this.CustomBar;
				var bgImage = this.bgImage;
				var style = `height:${
      
      CustomBar}px;padding-top:${
      
      StatusBar}px;`;
				if (this.bgImage) {
    
    
					style = `${
      
      style}background-image:url(${
      
      bgImage});`;
				}
				return style
			}
		},
		props: {
    
    
			bgColor: {
    
    
				type: String,
				default: ''
			},
			isBack: {
    
    
				type: [Boolean, String],
				default: false
			},
			bgImage: {
    
    
				type: String,
				default: ''
			},
			url:{
    
    
				type:String,
				default:''
			}
		},
		methods: {
    
    
			BackPage() {
    
    
				uni.redirectTo({
    
    
					url:this.url
				})
				// uni.navigateBack({
    
    
				// 	delta: 1
				// });
			}
		}
	}
</script>

tab切换

主要实现设备/劳务/人员的tab切换,固定在app内容顶部,难点在于tab切换时,需要实现页面和html页面通信,改变地图内容,主要需要做以下几个功能:

  1. 调用接口(getNavInfo)获取maplists信息
// 获取导航栏数值
getNav(){
    
    
	let params={
    
    
		ProjectId:this.projectId,
		OrgCode:this.orgcode
	}
	Api.getNavInfo(params).then(res=>{
    
    
		console.log('嘻嘻',res)
		if(res.data.length>0){
    
    
			res.data.forEach((item,index)=>{
    
    
				this.maplists[index].number=item
			})
		}else{
    
    
			uni.showToast({
    
    
				title:'获取导航栏数值失败',
				icon:'none'
			})
		}
	})
},

2.切换tab时,实现与页面和html的通信

swichNav(item) {
    
    
    // this.reportisChoose = parseInt(e.currentTarget.id - 1);
    // this.url += encodeURIComponent(JSON.stringify([{'s':1111}]));
    item.check=!item.check
    if(item.check){
    
    
        this.maker.push(item.id)
    }else{
    
    
        let index=0
        this.maker.forEach((x,i)=>{
    
    
            if(x===item.id){
    
    
                index=i
            }
        })
        this.maker.splice(index,1)
    }
    console.log('this.makerxxx',this.maker)
    this.url ='../../hybrid/html/map.html?'+ "access_token="+this.token+"&maker="+JSON.stringify(this.maker)+"&baseUrl="+this.baseUrl+"&projectId=" + this.projectId+"&OrgCode="+this.orgcode
},

地图画布

地图画布主要是嵌入map.html,这里主要是用到了web-view,需要注意以下两个地方:

  1. web-view:一般是占满全屏的,优先级最高,所以会覆盖tab部分,故要设定高度或者top值,

主要实现如下:

// 获取设备信息
getEqData() {
    
    
    let _this=this
    console.log('进来来');
    let projectId = this.$store.state.user.projectId;
    Api.getEqlocation(projectId).then(res => {
    
    
        if (res.data.success) {
    
    
            this.eqData = res.data.data;
            console.log('结果是', this.eqData);
            this.eqData.forEach(item=>{
    
    
                item['x']=this.longitude+Math.random(0,1000)
                item['y']=this.latitude+Math.random(0,1000)
                item['text']='设备信息'
                item['path']='../../static/01.png'
            })

        }
    })
},
// 获取屏幕高度
getwh() {
    
    
    const {
    
     windowWidth, windowHeight } = uni.getSystemInfoSync();
    console.log('windowWidth, windowHeight', windowWidth, windowHeight);
    this.height = windowHeight;
    this.width = windowWidth;
    let _this = this;
    this.$nextTick(function() {
    
    
        this.computeHeight();
        this.setWebHeight()
    });
},
// 设置web-view样式
setWebHeight(){
    
    
    let _this=this
    console.log('height',this.$scope)
    // #ifdef APP-PLUS
    var currentWebview = this.$scope.$getAppWebview(); //获取当前web-view
    setTimeout(function(){
    
    
        var wv = currentWebview.children()[0];
        console.log('wv',wv);
        wv.setStyle({
    
    
            //设置web-view距离顶部的距离以及自己的高度,单位为px
            top: _this.top,
            height: _this.height,
            // 双指缩放
            scalable:true
        });
    },1000)
    // #endif
},
// 计算导航栏和顶部高度
computeHeight() {
    
    
    let _this = this;
    let info = uni.createSelectorQuery().select('.map-top-tab');
    info.boundingClientRect(function(data) {
    
    
        console.log('计算出来什么高度', data);
        _this.top = data.height;
    }).exec();
    let info2=uni.createSelectorQuery().select('.tab')
    info2.boundingClientRect(function(data) {
    
    
        console.log('计算出来什么高度222', data);
        _this.top += data.height;
        _this.height = _this.height-_this.top;
    }).exec();
    console.log('sssssssssssssssss',this.height,this.top)
}
  1. web-view嵌入本地网页,主要放在…/…/hybrid/html 文件下,这个官网给出了建议和结构图,如下:
    在这里插入图片描述
┌─components
├─hybrid
│  └─html
│     ├─css
│     │  └─test.css
│     ├─img
│     │  └─icon.png
│     ├─js
│     │  └─test.js
│     └─local.html
├─pages
│  └─index
│     └─index.vue
├─static
├─main.js
├─App.vue
├─manifest.json
└─pages.json

html页面设置

虽然是个html页面,但主要是实现**地图点聚合(主要使用百度地图api实现)**的功能,所以主要要引入以下几个依赖:

<link rel="stylesheet" href="https//api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" />
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=Ps5KaIdB9sSNUbDwECgTtBL7xluVv91s"></script>
<script src="//libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script type="text/javascript" src="https://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="js/MakerClusterer.js"></script>
<script src="js/vue.min.js"></script>
<script src="js/axios.js"></script>

实现页面通信,分解url参数

created() {
    
    
    axios.defaults.headers.post['Content-Type'] = 'application/json';
    let _this = this
    this.baseUrl = this.getQueryString('baseUrl')
    this.projectId = this.getQueryString('projectId');
    this.access_token_app = this.getQueryString('access_token');
    this.OrgCode = this.getQueryString('OrgCode')
    // console.log('传过来的数据', this.baseUrl, this.projectId, this.access_token_app, this.OrgCode)

    localStorage.setItem('baseUrl', this.baseUrl)
    localStorage.setItem('access_token_app', this.access_token_app)
    axios.defaults.headers.common['Authorization'] = "Bearer " + localStorage.getItem('access_token_app')

    this.maker = this.getQueryString('maker')
    // console.log('this.maker111', this.maker)
    this.maker = JSON.parse(this.maker)
    // console.log('this.maker', this.maker)
    if (this.maker !== null) {
    
    
        // 1--设备,2--劳务,3--人员
        this.maker.forEach(y => {
    
    
            // 1--设备,2--劳务,3--人员
            switch (y) {
    
    
                case 1:
                    console.log('进入设备区域了')
                    _this.getEqData()
                    break
                case 2:
                    console.log('进入劳务区域了')
                    _this.getServiceData()
                    break
                case 3:
                    console.log('进入人员区域了')
                    _this.getUserData()
                    break
            }
        })
    }

    this.$nextTick(function() {
    
    
        _this.initMap()
    })
},
mounted() {
    
    
    document.addEventListener('UniAppJSBridgeReady', function() {
    
    
        uni.getEnv(function(res) {
    
    
            console.log('当前环境:' + JSON.stringify(res));
        });
    });
},
methods:{
    
    
	//取url中的参数值
	getQueryString(name) {
    
    
	    // 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)
	    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
	    let r = window.location.search.substr(1).match(reg);
	    if (r != null) {
    
    
	        // 对参数值进行解码
	        return r[2]
	    }
	    return null;
	},
}

初始化地图

// 初始化地图
initMap() {
    
    
    // 百度地图API功能
    this.map = new BMap.Map("allmap");
    // 初始化地图,创建中心坐标和地图实例
    this.map.centerAndZoom(new BMap.Point(116.331398, 39.897445), 10);
    // this.map.addEventListener("tilesloaded",function(){alert("地图加载完毕");})
    // 启用拖拽
    // this.map.enableInertialDragging()
    // this.map.enableScrollWheelZoom();
    // 启用双指缩放
    // this.map.enablePinchToZoom()
    // this.map.addControl(new BMap.NavigationControl());
    this.map.addControl(new BMap.ScaleControl());
    this.map.addControl(new BMap.OverviewMapControl());
    let temMap = this.map
    // 添加带有定位的导航控件,放大,缩小
    var navigationControl = new BMap.NavigationControl({
    
    
        // 靠左上角位置
        anchor: BMAP_ANCHOR_TOP_RIGHT,
        // 偏移值
        offset: new BMap.Size(5, 50),
        // LARGE类型
        type: BMAP_NAVIGATION_CONTROL_LARGE,
        // 是否显示级别
        showZoomInfo: true,
        // 启用显示定位
        enableGeolocation: true
    });
    this.map.addControl(navigationControl);
    // 添加定位控件
    var geolocationControl = new BMap.GeolocationControl();
    geolocationControl.addEventListener("locationSuccess", function(e) {
    
    
        // 定位成功事件
        var address = '';
        address += e.addressComponent.province;
        address += e.addressComponent.city;
        address += e.addressComponent.district;
        address += e.addressComponent.street;
        address += e.addressComponent.streetNumber;
    });
    geolocationControl.addEventListener("locationError", function(e) {
    
    
        // 定位失败事件
        alert(e.message);
    });
    this.map.addControl(geolocationControl);
},

点聚合功能实现

主要起作用的是MarkerClusterer

watch: {
    
    
    markerArr(val) {
    
    
        if (val != null) {
    
    
            console.log('ccccc', val)
            if (this.markerClusterer) {
    
    
                this.markerClusterer.clearMarkers()
            }
            this.markerClusterer = new BMapLib.MarkerClusterer(this.map, {
    
    
                markers: val
            });
						// 所有标记显示在地图内
            this.map.setViewport(this.pointArray)
            console.log('当前地图级别', this.map.getZoom())
        }
    },
}

搜索功能实现

// 根据名称搜索项目
searchByName() {
    
    
    console.log('运动少杀杀杀', this.arrAll)
    let markerByName = this.arrAll.filter(item => item.name.indexOf(this.keyword) !== -1)
    console.log('过滤后的照片', markerByName)
    if (markerByName.length === 0) {
    
    
        alert('搜索内容无定位信息,请重新搜索')
        this.keyword = ''
        return
    }
    // 设置最大级别数
    // this.map.setMaxZoom(10)
    this.markerArr = []
    this.createDefineMarker(markerByName)
    this.map.setViewport(this.pointArray)
    console.log('当前地图级别', this.map.getZoom())
},

全部代码

<template>
	<view>
		<view class="tab">
			<!-- :isBack="true" -->
			<tab-left bgColor="bg-gradual-white" :isBack="true"  :url="gobackurl">
				<block slot="backText">返回</block>
				<block slot="content">人机分布</block>
			</tab-left>
		</view>
		<view class="map-top-tab">
			<block v-for="(maplist, index) in maplists" :key="index">
				<view class="tab-item" :class="{ 'tab-active': maplist.check }" :id="maplist.id" :data-current="index" @click="swichNav(maplist)">
					<text>{
    
    {
    
     maplist.number }}</text>
					<view>{
    
    {
    
     maplist.title }}</view>
				</view>
			</block>
		</view>
		<view class="box" :style="{ top: top + 'px' }"><web-view :src="url"></web-view></view>
	</view>
</template>
<script>
import config from '../../config'
import Api from '../../api/distribution/distribution';
import ApiDict from '../../api/hidden-danger/hidden-danger';
import tabLeft from '@/components/colorui/components/tab-leftDefined.vue'
export default {
    
    
	data() {
    
    
		return {
    
    
			gobackurl:'/pages/more/more',
			maker:[1],
			token:this.$store.state.user.token,
			projectId:this.$store.state.user.projectId,
			orgcode:this.$store.state.user.orgCode,
			baseUrl:config.baseUrl,
			height: 0,
			width: 0,
			top: 0,
			url: '../../hybrid/html/map.html?',
			reportisChoose: 0,
			marker:[],
			eqData:[],
			maplists: [
				{
    
    
					number: '3/4',
					title: '设备',
					id: 1,
					check:true
				},
				{
    
    
					number: '2/3',
					title: '劳务',
					id: 2,
					check:false
				},
				{
    
    
					number: '3/4',
					title: '人员',
					id: 3,
					check:false
				}
			]
		};
	},
	components:{
    
    
		tabLeft
	},
	created() {
    
    
		// this.getEqData()
		this.getNav()
	},
	mounted() {
    
    
		console.log('this.$store.state.user',this.$store.state.user)
	},
	onLoad() {
    
    
		this.getwh();
	},
	onShow() {
    
    
		this.url ='../../hybrid/html/map.html?'+ "access_token="+this.token+"&maker="+JSON.stringify(this.maker)+"&baseUrl="+this.baseUrl+"&projectId=" + this.projectId+"&OrgCode="+this.orgcode
	},
	methods: {
    
    
		goback(){
    
    
			console.log('进入到这里来了')
			uni.redirectTo({
    
    
				url:'/pages/more/more'
			})
		},
		swichNav(item) {
    
    
			// this.reportisChoose = parseInt(e.currentTarget.id - 1);
			// this.url += encodeURIComponent(JSON.stringify([{'s':1111}]));
			item.check=!item.check
			if(item.check){
    
    
				this.maker.push(item.id)
			}else{
    
    
				let index=0
				this.maker.forEach((x,i)=>{
    
    
					if(x===item.id){
    
    
						index=i
					}
				})
				this.maker.splice(index,1)
			}
			console.log('this.makerxxx',this.maker)
			this.url ='../../hybrid/html/map.html?'+ "access_token="+this.token+"&maker="+JSON.stringify(this.maker)+"&baseUrl="+this.baseUrl+"&projectId=" + this.projectId+"&OrgCode="+this.orgcode
		},
		// 获取导航栏数值
		getNav(){
    
    
			let params={
    
    
				ProjectId:this.projectId,
				OrgCode:this.orgcode
			}
			Api.getNavInfo(params).then(res=>{
    
    
				console.log('嘻嘻',res)
				if(res.data.length>0){
    
    
					res.data.forEach((item,index)=>{
    
    
						this.maplists[index].number=item
					})
				}else{
    
    
					uni.showToast({
    
    
						title:'获取导航栏数值失败',
						icon:'none'
					})
				}
			})
		},
		// 获取设备信息
		getEqData() {
    
    
			let _this=this
			console.log('进来来');
			let projectId = this.$store.state.user.projectId;
			Api.getEqlocation(projectId).then(res => {
    
    
				if (res.data.success) {
    
    
					this.eqData = res.data.data;
					console.log('结果是', this.eqData);
					this.eqData.forEach(item=>{
    
    
						item['x']=this.longitude+Math.random(0,1000)
						item['y']=this.latitude+Math.random(0,1000)
						item['text']='设备信息'
						item['path']='../../static/01.png'
					})

				}
			})
		},
		// 获取屏幕高度
		getwh() {
    
    
			const {
    
     windowWidth, windowHeight } = uni.getSystemInfoSync();
			console.log('windowWidth, windowHeight', windowWidth, windowHeight);
			this.height = windowHeight;
			this.width = windowWidth;
			let _this = this;
			this.$nextTick(function() {
    
    
				this.computeHeight();
				this.setWebHeight()
			});
		},
		// 设置web-view样式
		setWebHeight(){
    
    
			let _this=this
			console.log('height',this.$scope)
			// #ifdef APP-PLUS
			var currentWebview = this.$scope.$getAppWebview(); //获取当前web-view
			setTimeout(function(){
    
    
				var wv = currentWebview.children()[0];
				console.log('wv',wv);
				wv.setStyle({
    
    
					//设置web-view距离顶部的距离以及自己的高度,单位为px
					top: _this.top,
					height: _this.height,
					// 双指缩放
					scalable:true
				});
			},1000)
			// #endif
		},
		// 计算导航栏和顶部高度
		computeHeight() {
    
    
			let _this = this;
			let info = uni.createSelectorQuery().select('.map-top-tab');
			info.boundingClientRect(function(data) {
    
    
				console.log('计算出来什么高度', data);
				_this.top = data.height;
			}).exec();
			let info2=uni.createSelectorQuery().select('.tab')
			info2.boundingClientRect(function(data) {
    
    
				console.log('计算出来什么高度222', data);
				_this.top += data.height;
				_this.height = _this.height-_this.top;
			}).exec();
			console.log('sssssssssssssssss',this.height,this.top)
		}
	}
};
</script>
<style scoped>
.box {
    
    
	height: 100upx !important;
	overflow: hidden;
}
.tab-item {
    
    
	-webkit-flex: 1;
	flex: 1;
	text-align: center;
	color: #fff;
	padding: 15upx;
}
.map-top-tab {
    
    
	z-index: 9999;
	display: flex;
	background: #3380bb;
	position: relative;
}
.tab-active {
    
    
	background: #0060aa;
}

</style>

map.html需要进行的操作

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
		<link rel="stylesheet" href="https//api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" />
		<style type="text/css">
			body,
			html,
			#app {
    
    
				width: 100%;
				height: 100%;
				margin: 0;
			}

			#allmap {
    
    
				width: 100%;
				height: 100%;
			}

			p {
    
    
				margin-left: 5px;
				font-size: 14px;
			}

			.search {
    
    
				position: fixed;
				padding: 10px;
				/* 伪信息 记得改成0 */
				top: 0;
				width: 70%;
				/* background-color: #FFFFFF; */
				display: flex;
				align-items: center;
				/* justify-content: space-around; */
			}

			.search-input,
			.search-btn {
    
    
				height: 30px;
				box-sizing: border-box;
				box-shadow: 1px 1px 1px 1px rgba(221, 221, 221, 0.5);
				border-radius: 5px;
				border: 1px solid #DDDDDD;
			}

			.search-input {
    
    
				padding-left: 6px;
			}

			.search-btn {
    
    
				margin-left: 10px;
				width: 50px;
				background-color: #0A6DFF;
				color: #FFFFFF;
			}

			.search-icon {
    
    
				height: 19px;
				width: 19px;
				margin-left: -25px;
				/* background-color: #A0CFFF; */
			}
		</style>
		<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=Ps5KaIdB9sSNUbDwECgTtBL7xluVv91s"></script>
		<script src="//libs.baidu.com/jquery/1.9.0/jquery.js"></script>
		<script type="text/javascript" src="https://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script>
		<script type="text/javascript" src="js/MakerClusterer.js"></script>
		<!-- <script type="text/javascript" src="https//api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"></script> -->

		<script src="js/vue.min.js"></script>
		<script src="js/axios.js"></script>
		<title>点聚合</title>
	</head>
	<body>
		<div id="app">
			<div id="allmap"></div>
			<div class="search">
				<input type="text" name="" id="" value="" placeholder="请输入搜索名称" class="search-input" v-model="keyword" />
				<img class="search-icon" v-show="keyword!==''" src="img/icon_close.png" mode="aspectFit" @click="resetInput">
				<button type="button" class="search-btn" @click="searchByName">搜索</button>

			</div>
		</div>
	</body>
</html>
<script type="text/javascript">
	let _this = this
	new Vue({
    
    
		el: "#app",
		data: {
    
    
			arrAll: [],
			keyword: '',
			baseUrl: '',
			projectId: '',
			access_token_app: '',
			OrgCode: '',
			maker: '',
			tempPoint: [],
			markerArr: [],
			eqData: [],
			userData: [],
			map: '',
			x: 0,
			y: 0,
			markerClusterer: '',
			pointArray: [],
			service: [],
		},
		created() {
    
    
			axios.defaults.headers.post['Content-Type'] = 'application/json';
			let _this = this
			this.baseUrl = this.getQueryString('baseUrl')
			this.projectId = this.getQueryString('projectId');
			this.access_token_app = this.getQueryString('access_token');
			this.OrgCode = this.getQueryString('OrgCode')
			// console.log('传过来的数据', this.baseUrl, this.projectId, this.access_token_app, this.OrgCode)

			localStorage.setItem('baseUrl', this.baseUrl)
			localStorage.setItem('access_token_app', this.access_token_app)
			axios.defaults.headers.common['Authorization'] = "Bearer " + localStorage.getItem('access_token_app')

			this.maker = this.getQueryString('maker')
			// console.log('this.maker111', this.maker)
			this.maker = JSON.parse(this.maker)
			// console.log('this.maker', this.maker)
			if (this.maker !== null) {
    
    
				// 1--设备,2--劳务,3--人员
				this.maker.forEach(y => {
    
    
					// 1--设备,2--劳务,3--人员
					switch (y) {
    
    
						case 1:
							console.log('进入设备区域了')
							_this.getEqData()
							break
						case 2:
							console.log('进入劳务区域了')
							_this.getServiceData()
							break
						case 3:
							console.log('进入人员区域了')
							_this.getUserData()
							break
					}
				})
			}

			this.$nextTick(function() {
    
    
				_this.initMap()
			})
		},
		mounted() {
    
    
			document.addEventListener('UniAppJSBridgeReady', function() {
    
    
				uni.getEnv(function(res) {
    
    
					console.log('当前环境:' + JSON.stringify(res));
				});
			});
		},
		watch: {
    
    
			markerArr(val) {
    
    
				if (val != null) {
    
    
					console.log('ccccc', val)
					if (this.markerClusterer) {
    
    
						this.markerClusterer.clearMarkers()
					}
					this.markerClusterer = new BMapLib.MarkerClusterer(this.map, {
    
    
						markers: val
					});
					this.map.setViewport(this.pointArray)
					console.log('当前地图级别', this.map.getZoom())
				}
			},
			// keyword(val){
    
    
			// 	if(val!=null){
    
    
			// 		console.log('运动少杀杀杀',this.arrAll)
			// 		let markerByName=this.arrAll.filter(item=>item.name===this.keyword)
			// 		console.log('过滤后的照片',markerByName)
			// 		this.createDefineMarker(markerByName)
			// 	}
			// }
			// tempPoint:{
    
    
			// 	immediate:true,
			// 	deep: true,
			// 	handler:function(val){
    
    
			// 		console.log('导致水水水水',val,this.tempPoint)
			// 		if(val.length>0){
    
    
			// 			console.log('ffffff',val,this.tempPoint)
			// 		}
			// 		// console.log('tempPoint', this.tempPoint)
			// 		// let mk = new BMap.Marker(this.tempPoint);
			// 		// console.log('temMap', this.map)

			// 		// this.map.addOverlay(mk);
			// 		// // 设置文字标记
			// 		// let label = new BMap.Label("我所在的位置", {
    
    
			// 		// 	offset: new BMap.Size(20, -10)
			// 		// });
			// 		// mk.setLabel(label);
			// 		// this.map.panTo(this.tempPoint);
			// 	}
			// }
		},
		computed: {
    
    

		},
		methods: {
    
    
			formatDate(dd) {
    
    
				if (dd != null && dd != '') {
    
    
					var date = new Date(dd);
					var year = date.getFullYear();
					/* 在日期格式中,月份是从0开始的,因此要加0
					 * 使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
					 * */
					var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
					var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
					// 拼接
					return year + '/' + month + '/' + day;
				} else {
    
    
					return '';
				}
			},
			// 根据名称搜索项目
			searchByName() {
    
    
				console.log('运动少杀杀杀', this.arrAll)
				let markerByName = this.arrAll.filter(item => item.name.indexOf(this.keyword) !== -1)
				console.log('过滤后的照片', markerByName)
				if (markerByName.length === 0) {
    
    
					alert('搜索内容无定位信息,请重新搜索')
					this.keyword = ''
					return
				}
				// 设置最大级别数
				// this.map.setMaxZoom(10)
				this.markerArr = []
				this.createDefineMarker(markerByName)
				this.map.setViewport(this.pointArray)
				console.log('当前地图级别', this.map.getZoom())
			},
			resetInput() {
    
    
				this.keyword = ''
				this.searchByName()
			},
			// 初始化地图
			initMap() {
    
    
				// 百度地图API功能
				this.map = new BMap.Map("allmap");
				// 初始化地图,创建中心坐标和地图实例
				this.map.centerAndZoom(new BMap.Point(116.331398, 39.897445), 10);
				// this.map.addEventListener("tilesloaded",function(){alert("地图加载完毕");})
				// 启用拖拽
				// this.map.enableInertialDragging()
				// this.map.enableScrollWheelZoom();
				// 启用双指缩放
				// this.map.enablePinchToZoom()
				// this.map.addControl(new BMap.NavigationControl());
				this.map.addControl(new BMap.ScaleControl());
				this.map.addControl(new BMap.OverviewMapControl());
				let temMap = this.map
				// 添加带有定位的导航控件,放大,缩小
				var navigationControl = new BMap.NavigationControl({
    
    
					// 靠左上角位置
					anchor: BMAP_ANCHOR_TOP_RIGHT,
					// 偏移值
					offset: new BMap.Size(5, 50),
					// LARGE类型
					type: BMAP_NAVIGATION_CONTROL_LARGE,
					// 是否显示级别
					showZoomInfo: true,
					// 启用显示定位
					enableGeolocation: true
				});
				this.map.addControl(navigationControl);
				// 添加定位控件
				var geolocationControl = new BMap.GeolocationControl();
				geolocationControl.addEventListener("locationSuccess", function(e) {
    
    
					// 定位成功事件
					var address = '';
					address += e.addressComponent.province;
					address += e.addressComponent.city;
					address += e.addressComponent.district;
					address += e.addressComponent.street;
					address += e.addressComponent.streetNumber;
				});
				geolocationControl.addEventListener("locationError", function(e) {
    
    
					// 定位失败事件
					alert(e.message);
				});
				this.map.addControl(geolocationControl);
				// let geolocation = new BMap.Geolocation();

				// geolocation.getCurrentPosition(function(r) {
    
    
				// 	console.log('xxxxx', r)
				// 	_this.tempPoint = r.point
				// 	console.log('_this.tempPoint', _this.tempPoint)
				// 	_this.x = r.point.lng
				// 	_this.y = r.point.lat
				// 	console.log('您的位置:' + r.point.lng + ',' + r.point.lat);

				// }, {
    
    
				// 	enableHighAccuracy: true
				// })

				// setTimeout(function() {
    
    
				// 	console.log('tempPoint', _this.tempPoint)
				// 	let mk = new BMap.Marker(_this.tempPoint);
				// 	console.log('temMap', temMap)

				// 	temMap.addOverlay(mk);
				// 	// 设置文字标记
				// 	let label = new BMap.Label("我所在的位置", {
    
    
				// 		offset: new BMap.Size(20, -10)
				// 	});
				// 	mk.setLabel(label);
				// 	temMap.panTo(_this.tempPoint);
				// }, 5000)


				// var MAX = 10;
				// var markers = [];
				// var pt = null;
				// var i = 0;
				// for (; i < MAX; i++) {
    
    
				// 	pt = new BMap.Point(Math.random() * 40 + 85, Math.random() * 30 + 21);
				// 	markers.push(new BMap.Marker(pt));
				// }
				// console.log('坐标点', markers)
				// //最简单的用法,生成一个marker数组,然后调用markerClusterer类即可。
				// var markerClusterer = new BMapLib.MarkerClusterer(this.map, {
    
    
				// 	markers: markers
				// });

				// let dd = [{
    
    
				// 	// 116.331398, 39.897445
				// 	x: 116.331398,
				// 	y: 39.897445
				// }]
				// this.createDefineMarker(dd, 'img/01.png')
				// this.getEqData()

			},
			// 创建自定义标记
			createDefineMarker(data, path) {
    
    
				if (data == null) {
    
    
					return
				}
				// 清除前面已有的地图覆盖物
				this.map.clearOverlays()
				// let pointArray = new Array();
				for (let i = 0; i < data.length; i++) {
    
    
					let marker2 = []
					let pt = new BMap.Point(data[i].x, data[i].y);
					let myIcon = new BMap.Icon(data[i].path, new BMap.Size(100, 100), {
    
    
						imageSize: new BMap.Size(50, 50)
					});

					marker2 = new BMap.Marker(pt, {
    
    
						icon: myIcon,
						title: '这是图标的标题'
					})
					// marker2.addEventListener("click", this.attribute);
					this.addClickHandler(data[i], marker2);
					this.markerArr.push(marker2)
					this.pointArray[i] = new BMap.Point(data[i].x, data[i].y);
					let label = new BMap.Label(data[i].name, {
    
    
						offset: new BMap.Size(20, -10)
					});
					label.setZIndex(9999)
					marker2.setLabel(label);

					this.map.addOverlay(marker2);
				}
				//让所有点在视野范围内
				// this.map.setViewport(this.pointArray);
			},
			//取url中的参数值
			getQueryString(name) {
    
    
				// 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)
				var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
				let r = window.location.search.substr(1).match(reg);
				if (r != null) {
    
    
					// 对参数值进行解码
					return r[2]
				}
				return null;
			},
			// 获取设备信息
			getEqData() {
    
    
				axios.get(this.baseUrl + '/api/Entry/GetEqLocationdata', {
    
    
					params: {
    
    
						'projectId': this.projectId
					}
				}).then(res => {
    
    
					console.log('什么结果', res)
					if (res.data.success) {
    
    
						this.eqData = res.data.data
						let arr = []
						this.eqData.forEach(item => {
    
    
							let str = [0, 0]
							if (item.Location) {
    
    
								str = item.Location.split(',')
								console.log('经纬度有分开嘛嘛嘛', str)
								let obj = {
    
    }
								obj = {
    
    
									icon: '设备',
									x: str[0],
									y: str[1],
									name: item.EquipmentTypeName,
									type: item.SpecificationType,
									producte: item.Manufacturer,
									date: item.EntryDate,
									path: 'img/01.png'
								}
								arr.push(obj)
							}
						})
						this.arrAll = this.arrAll.concat(arr)
						this.createDefineMarker(arr)
					} else {
    
    
						alert(res.data.message || '获取设备信息失败')
					}
				})
			},
			// 获取劳务信息
			getServiceData() {
    
    
				axios.post(this.baseUrl + '/api/Personnel/LoadPersonList/LoadPersonList?proinfoId=' + this.projectId).then(res => {
    
    
					console.log('ssss', res)
					if (res.data.success) {
    
    
						this.service = res.data.data
						let arr = []
						this.service.forEach((item, index) => {
    
    
							let str = []
							// 伪信息,记得注释
							// item.LongLatitude = 116.402144 + Math.random(0.20) + ',' + 39.92959 + Math.random(0, 20)
							if (item.LongLatitude) {
    
    
								str = item.LongLatitude.split(',')
								let obj = {
    
    
									icon: '劳务',
									path: 'img/02.png',
									x: str[0],
									y: str[1],
									name: item.Name,
									lsnumber: item.LSNumber,
									tel: item.CellPhone,
								}
								arr.push(obj)
							}
						})
						this.arrAll = this.arrAll.concat(arr)
						this.createDefineMarker(arr)
					} else {
    
    
						alert(res.data.message || '获取劳务信息失败')
					}
				})
			},
			// 获取人员信息
			getUserData() {
    
    
				axios.post(this.baseUrl + '/api/Entry/GetPersondata?OrgCode=' + this.OrgCode).then(res => {
    
    
					console.log('vvvvv', res)
					if (res.data.success) {
    
    
						this.userData = res.data.data
						let arr = []
						this.userData.forEach(item => {
    
    
							if (item.latitude && item.longitude) {
    
    
								let obj = {
    
    
									icon: '人员',
									x: item.longitude,
									y: item.latitude,
									// 伪信息,记得注释
									// x: 116.402144 + Math.random(0.20),
									// y: 39.92959 + Math.random(0, 20),
									name: item.CnName,
									role: item.Role,
									email: item.Email,
									telephone: item.Telephone,
									addreess: item.Addreess,
									path: 'img/03.png'
								}
								arr.push(obj)
							}
						})
						this.arrAll = this.arrAll.concat(arr)
						this.createDefineMarker(arr)
					} else {
    
    
						alert(res.data.message || '获取人员数据失败')
					}
				})
			},
			addClickHandler(content, marker, $event) {
    
    
				console.log('ssssssncudo', $event)
				let that = this
				marker.addEventListener("click", function(e) {
    
    
					console.log('打破自己哦', e)
					that.attribute(content, marker, e)
				});
			},
			attribute(content, marker, e) {
    
    
				console.log('到添加标记了', content, marker, e)
				let content1 = ''
				if (content.icon === '设备') {
    
    
					content.date = this.formatDate(content.date)
					content1 = '<div style="margin:0;line-height:20px;padding:2px;">' +
						'设备名称:' + content.name + '<br/>设备类型:' + content.type + '<br/>生产厂家:' + content.producte + '<br/>生产时间:' + content
						.date + '</div>';
				} else if (content.icon === '劳务') {
    
    
					content1 = '<div style="margin:0;line-height:20px;padding:2px;">' +
						'姓名:' + content.name + '<br/> 劳务工号:' + content.lsnumber + '<br/>电话:' + content.tel + '</div>';
				} else if (content.icon === '人员') {
    
    
					content1 = '<div style="margin:0;line-height:20px;padding:2px;">' +
						'姓名:' + content.name + '<br/> 角色:' + content.role + '<br/>邮箱:' + content.email + '<br/>电话:' + content.telephone +
						'</div>';
				}
				var p = e.target;
				var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat);
				var infoWindow = new BMap.InfoWindow(content1); // 创建信息窗口对象 
				this.map.openInfoWindow(infoWindow, point); //开启信息窗口
				//图片加载完毕重绘infowindow
				// document.getElementById('imgDemo').onload = function() {
    
    
				// 	infoWindow.redraw(); //防止在网速较慢,图片未加载时,生成的信息框高度比图片的总高度小,导致图片部分被隐藏
				// }
				// var p = e.target;
				// alert("marker的位置是" + p.getPosition().lng + "," + p.getPosition().lat);
			}
		}
	})
</script>

猜你喜欢

转载自blog.csdn.net/weixin_41886421/article/details/129328509