uniapp中map組件標(biāo)記點(diǎn)合并分裂(續(xù)上一篇優(yōu)化)

在上一篇說(shuō)到10000個(gè)數(shù)據(jù)用時(shí)300ms左右,這里可以舉報(bào)作者謊報(bào)數(shù)據(jù)了,為什么呢,各位看官你細(xì)聽分說(shuō),因?yàn)楫?dāng)時(shí)測(cè)試的是生成兩個(gè)標(biāo)記圖片的10000個(gè)數(shù)據(jù),所以耗時(shí)大概300ms就說(shuō)的過(guò)去了,經(jīng)過(guò)檢查300ms主要有這幾個(gè)部分產(chǎn)生消耗,分別是:①刪除臨時(shí)存儲(chǔ)圖片時(shí)會(huì)產(chǎn)生大概50-100ms,看圖片多少因?yàn)槲业牟僮魇侵苯觿h除所有圖片;②canvas畫圖每張圖片會(huì)產(chǎn)生55ms左右;③init_calculation方法處理10000個(gè)數(shù)據(jù)時(shí)產(chǎn)生消耗。那么我也就是在這三個(gè)方面對(duì)代碼進(jìn)行了優(yōu)化。

因?yàn)閏anvas畫的圖片是一個(gè)臨時(shí)路徑所以沒(méi)辦法必須得進(jìn)行存儲(chǔ),當(dāng)然圖片大小基本是2000字節(jié)左右存儲(chǔ)的時(shí)間大概5ms可以忽略不計(jì),然后有的朋友會(huì)說(shuō)萬(wàn)一很多圖片呢,那也會(huì)是很大的消耗,確實(shí),但是別急處理之后就不會(huì)有那么多圖片了。

優(yōu)化處理一:初次加載的時(shí)候是直接精準(zhǔn)定位到一個(gè)標(biāo)記點(diǎn),這個(gè)時(shí)候我只需要處理這一個(gè)標(biāo)記點(diǎn)和其他標(biāo)記之間是否存在合并的情況, 沒(méi)有的話就根本不用進(jìn)行畫圖存儲(chǔ)的操作,有的話也就只需要處理一張圖片。

調(diào)用以及渲染標(biāo)記點(diǎn)的優(yōu)化
mapdata=this.canvas_map.init_mapdata(JSON.stringify(this.Variable.data),this.on_id,this.scale)
this.equipMentname=mapdata.equipMentdata.markers.name
this.latitude= mapdata.equipMentdata.markers.latitude
this.longitude= mapdata.equipMentdata.markers.longitude
  if(mapdata.markers.quantity>1){
     buffer_obj={}
     buffer_obj.key_id=mapdata.markers.id
     buffer_obj.quantity=mapdata.markers.quantity
    this.markers_id.push(buffer_obj)
    await this.draw(mapdata.markers.quantity,mapdata.markers.id).then(res=>{
        if(res){
             mapdata.markers.iconPath=res
             }
        }) 
      }
初始化處理的優(yōu)化
Canvasmap.prototype.init_calculation = function(data,markers,scale){
    this.markers=null
    var distance=this.regionchange_scale(scale)
    var res 
    this.markers=markers
    this.BufferArray=[]
    for(let i=0;i<data.length;i++){
        res=this.Calculate_distance(this.markers.longitude,this.markers.latitude,data[i].markers.longitude,data[i].markers.latitude)
        if(res<distance){ 
            console.log(data[i]) 
            this.markers.quantity++
        }
    } 
};

優(yōu)化處理二:前面說(shuō)到存儲(chǔ)圖片和畫圖消耗比較大,于是這邊處理是每畫一次圖片會(huì)按標(biāo)記點(diǎn)的特有id,對(duì)應(yīng)標(biāo)記數(shù)記錄quantity和存儲(chǔ)路徑進(jìn)行存儲(chǔ)到數(shù)組里面,那么在下一次遇到這個(gè)id時(shí)會(huì)先去數(shù)組里面查找如果已經(jīng)存在但是quantity有改變那么我們進(jìn)行畫圖更新這時(shí)我們只刪除一張圖片而不是之前刪除所有存儲(chǔ)的圖片;不存在這個(gè)id那就從頭畫圖和存儲(chǔ)并記錄到數(shù)組;如果各個(gè)單位都沒(méi)有改變那么我們就直接復(fù)用,因?yàn)檫@個(gè)時(shí)候圖片還是存在內(nèi)存里面直接根據(jù)id拿路徑顯示就可以了,就和vue中diff算法處理虛擬dom有點(diǎn)類似。

//對(duì)比最新標(biāo)記和存儲(chǔ)的標(biāo)記數(shù)據(jù)進(jìn)行對(duì)比是否為重復(fù)標(biāo)記
let diff_id=this.markers_id.findIndex(item=>item.key_id==mapdata.markers[i].id)
if(mapdata.markers[i].quantity>1){
if(diff_id!=-1&&this.markers_id[diff_id].quantity!=mapdata.markers[i].quantity){                                this.markers_id[diff_id].quantity=mapdata.markers[i].quantity
await this.rmfile(this.markers_id[diff_id].path)
await this.draw(mapdata.markers[i].quantity,this.markers_id[diff_id].key_id).then(res=>{
 if(res){  
mapdata.markers[i].iconPath=res 
}
})
 //如果之前沒(méi)有存在過(guò)這個(gè)標(biāo)記那么直接push新路徑
 }else if(diff_id==-1){  
 this.markers_id.push({
 'key_id':mapdata.markers[i].id,
'quantity':mapdata.markers[i].quantity
 })
await this.draw(mapdata.markers[i].quantity,mapdata.markers[i].id).then(res=>{
 if(res){
mapdata.markers[i].iconPath=res
} 
 })
 //否則直接復(fù)用
 }else{
mapdata.markers[i].iconPath=this.markers_id[diff_id].path
 } 
}else{
mapdata.markers[i].iconPath="/static/img/onselect.png"
 }

優(yōu)化處理三:因?yàn)榈貓D的縮放級(jí)別是不斷在變化的,我們不可能每次都計(jì)算所有的標(biāo)記點(diǎn),看不到的就可以假裝不存在,所以對(duì)標(biāo)記進(jìn)行篩選每次只處理視野范圍內(nèi)的標(biāo)記

//獲取地圖可視經(jīng)緯度范圍,對(duì)不在視野范圍內(nèi)的標(biāo)記去除(提升效率3)
            getRegion(map,list){
                let mapsection_data=[]
                return new Promise((resolve, reject)=>{
                    map.getRegion ({
                        success(res) {
                            let N_longitude=res.northeast.longitude
                            let N_latitude=res.northeast.latitude
                            let S_longitude=res.southwest.longitude
                            let S_latitude=res.southwest.latitude
                            for(let i=0;i<list.length;i++){
                                if(list[i].markers.longitude<N_longitude&&list[i].markers.latitude<N_latitude&&list[i].markers.longitude>S_longitude&&list[i].markers.latitude>S_latitude){
                                    mapsection_data.push(list[i])
                                }
                            }
                            resolve(mapsection_data)
                        }
                    }) 
                })
            },

優(yōu)化處理四:前面還說(shuō)到為什么圖片的數(shù)量會(huì)變的很少,而且是越來(lái)越少,因?yàn)槊看味歼M(jìn)行了記錄,但是當(dāng)縮放級(jí)別越來(lái)越小,這時(shí)候視野越廣要處理的標(biāo)記點(diǎn)會(huì)越來(lái)越多,是有這么個(gè)問(wèn)題,所以考慮之后決定在按地市到省份地理位置進(jìn)行處理,不過(guò)在幾萬(wàn)個(gè)數(shù)據(jù)計(jì)算所有標(biāo)記點(diǎn)的合并情況也是很有壓力的,我的處理方式是在第一次打開當(dāng)前標(biāo)記點(diǎn)時(shí)另外異步一個(gè)方法開始計(jì)算,這樣等地圖到達(dá)級(jí)市,省級(jí)的時(shí)候應(yīng)該已經(jīng)處理完,便可以直接拿數(shù)據(jù)走流程了。

getRegeo(data){
    return new Promise((resolve, reject) => {
    this.myAmapFun = new amapFile.AMapWX({key:'0ac92fa7d5fe9244fa0139b16a3a2c21'});
     this.myAmapFun.getRegeo({
    location:''+data.markers.longitude+','+data.markers.latitude,
    success: (data)=>{
    let province=data[0].regeocodeData.addressComponent
    let province_index=this.province.findIndex(item=>item.markers.name==province.province)
 if(province_index!=-1){
    this.province[province_index].markers.quantity++
    let city_index=this.province[province_index].city.findIndex(item=>item.markers.name==province.city)
    if(city_index>-1){ 
    this.province[province_index].city[city_index].markers.quantity++
    }else{
    this.province[province_index].city.push({
    "markers":{
    "latitude": data[0].latitude,
    "longitude": data[0].longitude,
    "iconPath": "/static/img/onselect.png",
    "width": 32,
    "height":32, 
    "quantity":1, 
    "id": province.adcode,
    "title":province.city+"設(shè)備",
    "name": province.city,
    "address":province.city
     }})
    }
    }
    resolve(this.province)
        }, 
        fail: function(info){ 
         console.log(info) 
                        }
                      })
                });
            },

但是問(wèn)題就在這個(gè),這個(gè)是通過(guò)高德api接口去獲取定位,等他處理完上萬(wàn)個(gè)數(shù)據(jù)黃花菜都涼了,當(dāng)前只是模擬數(shù)據(jù),最終可以和后臺(tái)約定好數(shù)據(jù)結(jié)構(gòu)直接將數(shù)據(jù)返回給你,可以在進(jìn)入頁(yè)面之前就拿到,一頓操作下來(lái)我這邊算是比較流暢了。

另外頁(yè)面上的模糊搜索功能如果要使用還需自行進(jìn)行處理,組件是沒(méi)有問(wèn)題,代碼里面是通過(guò)名字字段name進(jìn)行搜索。

方法可能不是最優(yōu)但是也能夠?qū)⒕?,如有想法可另行修改,代碼已經(jīng)更新到git倉(cāng)庫(kù),可以去上一篇底部鏈接獲取。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容