uniapp实现地图点聚合功能的详细教程
任务
在工作中接到的一个任务,在app端实现如下功能:
- 地图点聚合
- 地图页面支持tab切换(设备、劳务、人员)
- 支持人员搜索显示分布
但是uniapp原有的map标签不支持点聚合功能(最新的版本支持了点聚合功能),所以采取了hybrid
原生html文件开发的方式
最新的版本map已支持,如下:
效果图
h5的效果图,与真机有点偏差
生成页面
在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切换
主要实现设备/劳务/人员的tab切换,固定在app内容顶部,难点在于tab切换时,需要实现页面和html页面通信,改变地图内容,主要需要做以下几个功能:
- 调用接口(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'
})
}
})
},
- 切换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
,需要注意以下两个地方:
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)
}
- 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
map.html页面设置
虽然是个html页面,但主要是实现地图点聚合(主要使用百度地图api实现) 的功能,所以主要要引入以下几个依赖:
<link rel="stylesheet" href="https//api.map.baidu.com/library/SearchInfoWindow/1.5/class="lazy" data-src/SearchInfoWindow_min.css" rel="external nofollow" />
<script type="text/javascript" class="lazy" data-src="https://api.map.baidu.com/api?v=2.0&ak=Ps5KaIdB9sSNUbDwECgTtBL7xluVv91s"></script>
<script class="lazy" data-src="//libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script type="text/javascript" class="lazy" data-src="https://api.map.baidu.com/library/TextIconOverlay/1.2/class="lazy" data-src/TextIconOverlay_min.js"></script>
<script type="text/javascript" class="lazy" data-src="js/MakerClusterer.js"></script>
<script class="lazy" data-src="js/vue.min.js"></script>
<script class="lazy" data-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())
},
总结
到此这篇关于uniapp实现地图点聚合功能的文章就介绍到这了,更多相关uniapp地图点聚合功能内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341