uniapp實(shí)現(xiàn)地圖點(diǎn)聚合功能的詳細(xì)教程
任務(wù)
在工作中接到的一個(gè)任務(wù),在app端實(shí)現(xiàn)如下功能:
- 地圖點(diǎn)聚合
- 地圖頁(yè)面支持tab切換(設(shè)備、勞務(wù)、人員)
- 支持人員搜索顯示分布
但是uniapp原有的map標(biāo)簽不支持點(diǎn)聚合功能(最新的版本支持了點(diǎn)聚合功能),所以采取了hybrid
原生html文件開(kāi)發(fā)的方式
最新的版本map已支持,如下:
效果圖
h5的效果圖,與真機(jī)有點(diǎn)偏差
生成頁(yè)面
在pages.json
中定義distribution.vue
頁(yè)面
{ "path": "pages/distribution/distribution", "style": { "navigationBarTitleText": "人機(jī)分布", "navigationBarTextStyle": "black" } },
頁(yè)面結(jié)構(gòu)主要分為三個(gè)部分:頂部標(biāo)題,tab切換,地圖畫(huà)布
頂部標(biāo)題
頂部標(biāo)題就不用講了,一般打開(kāi)微信小程序頁(yè)面或者app頁(yè)面,都是左—返回,中—標(biāo)題,右—其他。存在默認(rèn)設(shè)置,但這里的話存在web-view(web 瀏覽器組件,可以用來(lái)承載網(wǎng)頁(yè)的容器),很有可能將頂部標(biāo)題覆蓋掉,所以使用自定義標(biāo)題,具體實(shí)現(xiàn)如下:
<view class="tab"> <!-- :isBack="true" --> <tab-left bgColor="bg-gradual-white" :isBack="true" :url="gobackurl"> <block slot="backText">返回</block> <block slot="content">人機(jī)分布</block> </tab-left> </view>
tab切換
主要實(shí)現(xiàn)設(shè)備/勞務(wù)/人員的tab切換,固定在app內(nèi)容頂部,難點(diǎn)在于tab切換時(shí),需要實(shí)現(xiàn)頁(yè)面和html頁(yè)面通信,改變地圖內(nèi)容,主要需要做以下幾個(gè)功能:
- 調(diào)用接口(getNavInfo)獲取maplists信息
// 獲取導(dǎo)航欄數(shù)值 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:'獲取導(dǎo)航欄數(shù)值失敗', icon:'none' }) } }) },
- 切換tab時(shí),實(shí)現(xiàn)與頁(yè)面和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 },
地圖畫(huà)布
地圖畫(huà)布主要是嵌入map.html
,這里主要是用到了web-view
,需要注意以下兩個(gè)地方:
web-view
:一般是占滿全屏的,優(yōu)先級(jí)最高,所以會(huì)覆蓋tab部分,故要設(shè)定高度或者top值,
主要實(shí)現(xiàn)如下:
// 獲取設(shè)備信息 getEqData() { let _this=this console.log('進(jìn)來(lái)來(lái)'); let projectId = this.$store.state.user.projectId; Api.getEqlocation(projectId).then(res => { if (res.data.success) { this.eqData = res.data.data; console.log('結(jié)果是', this.eqData); this.eqData.forEach(item=>{ item['x']=this.longitude+Math.random(0,1000) item['y']=this.latitude+Math.random(0,1000) item['text']='設(shè)備信息' 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() }); }, // 設(shè)置web-view樣式 setWebHeight(){ let _this=this console.log('height',this.$scope) // #ifdef APP-PLUS var currentWebview = this.$scope.$getAppWebview(); //獲取當(dāng)前web-view setTimeout(function(){ var wv = currentWebview.children()[0]; console.log('wv',wv); wv.setStyle({ //設(shè)置web-view距離頂部的距離以及自己的高度,單位為px top: _this.top, height: _this.height, // 雙指縮放 scalable:true }); },1000) // #endif }, // 計(jì)算導(dǎo)航欄和頂部高度 computeHeight() { let _this = this; let info = uni.createSelectorQuery().select('.map-top-tab'); info.boundingClientRect(function(data) { console.log('計(jì)算出來(lái)什么高度', data); _this.top = data.height; }).exec(); let info2=uni.createSelectorQuery().select('.tab') info2.boundingClientRect(function(data) { console.log('計(jì)算出來(lái)什么高度222', data); _this.top += data.height; _this.height = _this.height-_this.top; }).exec(); console.log('sssssssssssssssss',this.height,this.top) }
- web-view嵌入本地網(wǎng)頁(yè),主要放在
../../hybrid/html
文件下,這個(gè)官網(wǎng)給出了建議和結(jié)構(gòu)圖,如下:
┌─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頁(yè)面設(shè)置
雖然是個(gè)html頁(yè)面,但主要是實(shí)現(xiàn)地圖點(diǎn)聚合(主要使用百度地圖api實(shí)現(xiàn)) 的功能,所以主要要引入以下幾個(gè)依賴:
<link rel="stylesheet" href="https//api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" rel="external nofollow" /> <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=Ps5KaIdB9sSNUbDwECgTtBL7xluVv91s"></script> <script src="http://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>
實(shí)現(xiàn)頁(yè)面通信,分解url參數(shù)
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('傳過(guò)來(lái)的數(shù)據(jù)', 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--設(shè)備,2--勞務(wù),3--人員 this.maker.forEach(y => { // 1--設(shè)備,2--勞務(wù),3--人員 switch (y) { case 1: console.log('進(jìn)入設(shè)備區(qū)域了') _this.getEqData() break case 2: console.log('進(jìn)入勞務(wù)區(qū)域了') _this.getServiceData() break case 3: console.log('進(jìn)入人員區(qū)域了') _this.getUserData() break } }) } this.$nextTick(function() { _this.initMap() }) }, mounted() { document.addEventListener('UniAppJSBridgeReady', function() { uni.getEnv(function(res) { console.log('當(dāng)前環(huán)境:' + JSON.stringify(res)); }); }); }, methods:{ //取url中的參數(shù)值 getQueryString(name) { // 正則:[找尋'&' + 'url參數(shù)名字' = '值' + '&']('&'可以不存在) var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); let r = window.location.search.substr(1).match(reg); if (r != null) { // 對(duì)參數(shù)值進(jìn)行解碼 return r[2] } return null; }, }
初始化地圖
// 初始化地圖 initMap() { // 百度地圖API功能 this.map = new BMap.Map("allmap"); // 初始化地圖,創(chuàng)建中心坐標(biāo)和地圖實(shí)例 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 // 添加帶有定位的導(dǎo)航控件,放大,縮小 var navigationControl = new BMap.NavigationControl({ // 靠左上角位置 anchor: BMAP_ANCHOR_TOP_RIGHT, // 偏移值 offset: new BMap.Size(5, 50), // LARGE類型 type: BMAP_NAVIGATION_CONTROL_LARGE, // 是否顯示級(jí)別 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); },
點(diǎn)聚合功能實(shí)現(xiàn)
主要起作用的是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 }); // 所有標(biāo)記顯示在地圖內(nèi) this.map.setViewport(this.pointArray) console.log('當(dāng)前地圖級(jí)別', this.map.getZoom()) } }, }
搜索功能實(shí)現(xiàn)
// 根據(jù)名稱搜索項(xiàng)目 searchByName() { console.log('運(yùn)動(dòng)少殺殺殺', this.arrAll) let markerByName = this.arrAll.filter(item => item.name.indexOf(this.keyword) !== -1) console.log('過(guò)濾后的照片', markerByName) if (markerByName.length === 0) { alert('搜索內(nèi)容無(wú)定位信息,請(qǐng)重新搜索') this.keyword = '' return } // 設(shè)置最大級(jí)別數(shù) // this.map.setMaxZoom(10) this.markerArr = [] this.createDefineMarker(markerByName) this.map.setViewport(this.pointArray) console.log('當(dāng)前地圖級(jí)別', this.map.getZoom()) },
總結(jié)
到此這篇關(guān)于uniapp實(shí)現(xiàn)地圖點(diǎn)聚合功能的文章就介紹到這了,更多相關(guān)uniapp地圖點(diǎn)聚合功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
- 該播放器類似框架式的~設(shè)置在頁(yè)面底部 即使查看網(wǎng)頁(yè)的另一個(gè)頁(yè)面,歌曲也不會(huì)因?yàn)樗⑿露V共⒅匦虏シ?/div> 2006-10-10
mint-ui的search組件在鍵盤顯示搜索按鈕的實(shí)現(xiàn)方法
這篇文章主要介紹了mint-ui的search組件在鍵盤顯示搜索按鈕的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-10-10JS中setInterval、setTimeout不能傳遞帶參數(shù)的函數(shù)的解決方案
在JS中無(wú)論是setTimeout還是setInterval,在使用函數(shù)名作為調(diào)用句柄時(shí)都不能帶參數(shù),而在許多場(chǎng)合必須要帶參數(shù),接下來(lái)為大家介紹具體的解決方法2013-04-04如何實(shí)現(xiàn)小程序tab欄下劃線動(dòng)畫(huà)效果
這篇文章主要介紹了如何實(shí)現(xiàn)小程序tab欄下劃線動(dòng)畫(huà)效果,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁(yè)內(nèi)容
這篇文章主要介紹了javascript實(shí)現(xiàn)禁止復(fù)制網(wǎng)頁(yè)內(nèi)容,需要的朋友可以參考下2014-12-12利用window.name實(shí)現(xiàn)windowStorage代碼分享
本文主要介紹了利用window.name實(shí)現(xiàn)windowStorage的功能分享,大家參考使用吧2014-01-01uni-app跨端自定義指令實(shí)現(xiàn)按鈕權(quán)限操作
實(shí)現(xiàn)uni-app自定義指令按鈕權(quán)限需要涉及到對(duì)于vue.config.js新增loader配置,基礎(chǔ)正則知識(shí),webpack的loader開(kāi)發(fā)和調(diào)試,以及npm本地調(diào)試和發(fā)布,接下來(lái)就從了解這些前置知識(shí)開(kāi)始,需要的朋友可以參考下2023-01-01js中常見(jiàn)的4種創(chuàng)建對(duì)象方式與優(yōu)缺點(diǎn)
不管是哪門語(yǔ)言,千變?nèi)f化不離其宗,深入理解其本質(zhì),方能應(yīng)用自如,下面這篇文章主要給大家介紹了關(guān)于js中常見(jiàn)的4種創(chuàng)建對(duì)象方式與優(yōu)缺點(diǎn),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01最新評(píng)論