vue项目融合高德地图和百度地图的公共组件

  1 <template>
  2     <div class="mapView">
  3         <!-- 切换按钮 -->
  4         <div v-if="typeButtonBol" class="btnView" >
  5             <el-radio-group v-model="mapType" fill="#28d4c1" size="small">
  6                 <el-radio-button border label="gd">高德地图</el-radio-button>
  7                 <el-radio-button border label="bd">百度地图</el-radio-button>
  8             </el-radio-group>
  9         </div>
 10         <template>
 11             <div v-if="(bdMarkers && bdMarkers.length) || (gdMarkers && gdMarkers.length)" class="mapContent">
 12                 <!-- 百度地图 -->
 13                 <template  v-if="bdMarkers && bdMarkers.length">
 14                     <baidu-map v-if=" mapType == 'bd'" class="map" 
 15                         :scroll-wheel-zoom="true" 
 16                         @ready="map_handler"
 17                         :key="bdMapKey"
 18                         >
 19                         <!-- 缩放控件 -->
 20                         <bm-navigation anchor="BMAP_ANCHOR_TOP_LEFT"></bm-navigation>
 21                         <!-- maker -->
 22                         <template v-if="bdMarkers && bdMarkers.length">
 23                             <bm-marker
 24                                 v-for="(marker, index) in bdMarkers"
 25                                 :position="{ lng: marker.lng, lat: marker.lat }"
 26                                 :icon="marker.icon"
 27                                 :key="index"
 28                                 @click="lookDetail(marker)"
 29                                 :auto-viewport='true' 
 30                             ></bm-marker>
 31                          </template>
 32                          <!-- 弹窗信息 -->
 33                          <bm-info-window
 34                             width="210"
 35                             :position="{ lng: bdTipInfo.lng, lat: bdTipInfo.lat }"
 36                             :show="bdTipShow"
 37                             @close="infoWindowClose"
 38                             @open="infoWindowOpen"
 39                          >
 40                                 <p v-show="bdTipInfo.mac">
 41                                     设备Mac:{{bdTipInfo.mac}}
 42                                 </p>
 43                                 <p>参考地址:{{bdTipInfo.address || '无'}}</p>
 44                                 <p>
 45                                     与门店距离:{{bdTipInfo.distance}}
 46                                 </p>
 47                          </bm-info-window>
 48                     </baidu-map>
 49                 </template>
 50                 <!-- 高德地图 -->
 51                 <template v-if="gdMarkers && gdMarkers.length">
 52                     <div v-if=" mapType == 'gd'" class="amap-wrapper">
 53                         <el-amap 
 54                         ref="map"
 55                         class="amap-box" 
 56                         :amap-manager="amapManager"
 57                         :vid="'amap-vue'"
 58                         :plugin="plugin"
 59                         :events='events'>
 60                             <!-- 高德的marker -->
 61                             <template v-if="gdMarkers && gdMarkers.length">
 62                                 <el-amap-marker 
 63                                     v-for="(marker, index) in gdMarkers" 
 64                                     :key="index"
 65                                     :position="marker.position"
 66                                     :index="marker.index"
 67                                     :extData="marker"
 68                                     :icon="marker.iconUrl"
 69                                     :events="marker.events"
 70                                     >
 71                                 </el-amap-marker>
 72                             </template> 
 73                              <!-- 高德的信息提示窗 -->
 74                             <template v-if="window">
 75                                 <el-amap-info-window
 76                                     :position="window.position"
 77                                     :visible="window.visible"
 78                                     :offset="[3, -30]"
 79                                     :events="windowEvent"
 80                                     :close-when-click-map="false"
 81                                     >
 82                                     <p v-show="window.mac" class="p">
 83                                         设备Mac:{{window.mac}}
 84                                     </p>
 85                                     <p class="p">参考地址:{{window.address || "无"}}</p>
 86                                     <p class="p">
 87                                         与门店距离:{{window.distance}}
 88                                     </p>
 89                                 </el-amap-info-window>
 90                             </template>
 91                         </el-amap>
 92                     </div>
 93                 </template>
 94             </div>
 95         </template>
 96         <template v-if="tipBol">
 97             <div class="iconWrap">
 98                 <template v-for="(item , index) in checkoutIcon()">
 99                     <div class="dis-line"  :key="index">
100                         <img class="img" :src="item.url" alt=""><span class="text">{{item.text}}</span>
101                     </div>
102                 </template>
103             </div>
104         </template>
105     </div>
106 </template>
107 <script>
108 const amapManager= new AMapManager();
109 import { AMapManager,lazyAMapApiLoaderInstance } from 'vue-amap';
110 import {point_transform} from "pack/common/js/mapTool";
111 export default {
112     props:{
113         typeButtonBol:{
114             type: Boolean,
115             default:true,
116         },//是否展示地图类型按钮
117         tipBol:{
118             type: Boolean,
119             default:true,
120         },//是否展示底部提示
121         mapType:{
122             type: String,
123             default:'gd',
124         },//地图类型
125         markers:{
126             type:Array,
127             default:[],
128         },//标记点的坐标
129     },
130     watch:{
131         // mapType:{
132         //     handler(newValue, oldValue) {
133         //         if(newValue == 'bd'){
134         //             this.refreshMapHandle();
135         //         } 
136         //     },
137         //     deep: false,
138         //     immediate: false
139         // },
140         markers:{
141             handler(newValue, oldValue) {
142                 this.$nextTick(()=>{
143                     this.setGDmarkers();
144                     this.setBDmarkers();
145                 })
146             },
147             deep: false,
148             immediate: false
149         }
150 
151     },
152     data(){
153         return{
154             amapManager,
155             events:{
156                 complete: () => {
157                     this.$nextTick(()=>{
158                         this.setGDview()//缩放高德地图视野
159                     })
160                 },
161             },
162             iconList:[{
163                 url:require('./img/md.png'),
164                 text:'门店位置',
165                 type:0,
166                 size:{
167                     width:21,
168                     height:36
169                 }
170             },{
171                 url:require('./img/shebei.png'),
172                 text:'设备位置',
173                 type:1,
174                 size:{
175                     width:26,
176                     height:26
177                 }
178             },{
179                 url:require('./img/gjmac.png'),
180                 text:'拍摄柜机位置',
181                 type:2,
182                 size:{
183                     width:26,
184                     height:26
185                 }
186             },{
187                 url:require('./img/mdh.png'),
188                 text:'门店位置',
189                 type:3,
190                 size:{
191                     width:21,
192                     height:36
193                 }
194             }],
195             bdMarkers:[],//百度的markers
196             bdTipShow:false,//百度的信息展示bol
197             bdTipInfo:{},//百度的信息对象
198             bdMapKey:'',//重置百度的key
199             gdMarkers:[],//高德的markers
200             gdTipShow:false,//高德的展示信息b
201             window:'',//高德的信息对象
202             plugin:['Geocoder','ToolBar'],//高德地图初始化的插件
203             windowEvent:{
204                 close:()=>{
205                     console.log(this.window.visible)
206                     this.$nextTick(()=>{
207                         this.window.visible = false
208                     })
209                     
210                 }
211             }//高德信息窗体关闭事件监听
212         }
213     },
214     beforeMount(){},
215     mounted(){
216         lazyAMapApiLoaderInstance.load().then(()=>{
217             this.plugin = ['Geocoder','ToolBar']
218         })
219         this.setGDmarkers();
220         this.setBDmarkers();
221     },
222     methods:{
223         //匹配对应的图标
224         matchIcon(obj){
225             return this.iconList.find((val,i)=>{
226                 return obj.type == val.type;
227             })
228         },
229         //筛选图标
230         checkoutIcon(){
231             let arr = [];
232             this.markers.forEach((v,i)=>{
233                 this.iconList.forEach((item,index)=>{
234                     if(item.type == v.type){
235                         arr.push(item)
236                     }
237                 })
238             })
239             return arr;
240         },
241         //百度地图初始化好了之后做的事情
242         map_handler({ BMap, map }) {
243             this.$nextTick(() => {
244                 var view = map.getViewport(this.bdMarkers);
245                 map.centerAndZoom(view.center, view.zoom);
246             })
247         },
248         //百度marker点击
249         lookDetail(info){
250             console.log("bdmaker==>",info)
251             if(info.type ==  0 || info.type ==  3){
252                 return
253             }
254             this.bdTipInfo = info;
255             this.getPointAddress();
256             this.$set(this.bdTipInfo,'distance',this.getPoiDistance(this.getBDmdlnglat(),this.bdTipInfo))
257         },
258         //百度marker点击
259         infoWindowClose() {
260             this.bdTipShow = false;
261         },
262         //百度marker点击
263         infoWindowOpen() {
264             this.bdTipShow = true;
265         },
266         //重置百度地图
267         refreshMapHandle() {
268             this.bdMapKey = Math.random().toString(36).substr(2);
269         },
270         //百度根据经纬度获取地址的方法
271         getPointAddress() {
272             let devicePoint = new BMap.Point(
273                 this.bdTipInfo.lng,
274                 this.bdTipInfo.lat
275             );
276             let geo = new BMap.Geocoder();
277             geo.getLocation(devicePoint, (rs) => {
278                 this.bdTipInfo.address = rs.address;
279                 this.bdTipShow = true;
280             });
281         },
282         //百度地图根据两个点计算距离
283         getPoiDistance(shop,device) {
284             let map = new BMap.Map();
285             let shopPoint = new BMap.Point(shop.lng, shop.lat);
286             let devicePoint = new BMap.Point(
287                 device.lng,
288                 device.lat
289             );
290             let disPoint = Math.round(
291                 (map.getDistance(shopPoint, devicePoint) * 10) / 10
292             );
293             return disPoint > 1000
294                 ? `${(disPoint / 1000).toFixed(1)}km`
295                 : `${disPoint}m`;
296         },
297         //获取高德门店位置坐标
298         getBDmdlnglat(){
299             return this.bdMarkers.find((v,i)=>{
300                 return v.type == 0;
301             }) 
302         },
303         //初始化百度的markers数组
304         setBDmarkers(){
305             let arr = [];
306             point_transform(3,5,this.markers,data=>{
307                 console.log("this.markers==>",this.markers)
308                 console.log("转化后的data==>",data)
309                 if(data.length){
310                     data.map((v,i)=>{
311                         arr.push({
312                             lng:v.lng,
313                             lat:v.lat,
314                             icon:{
315                                 url: this.matchIcon(this.markers[i]).url,
316                                 size: this.matchIcon(this.markers[i]).size,
317                             },
318                             type:this.markers[i].type,
319                             mac:this.markers[i].mac,
320                         })
321                     })
322                 } 
323                 this.bdMarkers = arr;
324                 this.$nextTick(()=>{
325                     this.refreshMapHandle();
326                 })
327             })
328         },
329         //增加百度marker
330         addBDmarker(msg){
331             point_transform(3,5,[{lng:msg.longitude,lat:msg.latitude}],data=>{
332                 console.log("data==>",data)
333                 this.bdMarkers.push({
334                     lng:data[0].lng,
335                     lat:data[0].lat,
336                     icon:{
337                         url: this.matchIcon(msg).url,
338                         size: this.matchIcon(msg).size,
339                     },
340                     type:msg.type,
341                     mac:msg.mac,
342                 })
343                 this.$nextTick(()=>{
344                     this.refreshMapHandle();
345                 })
346             })
347         },
348         //高德地图根据经纬度获取地址
349         getAmapAddress(res){
350             return new Promise(resolve=>{
351                 let geocoder = new AMap.Geocoder({
352                     radius: 1000,
353                     extensions: "all"
354                 });
355                 console.log('dianzuobiao==>',res)
356                 geocoder.getAddress(res, (status,result)=>{
357                     resolve(result)
358                 });
359             })
360         },
361         //高德地图计算两点之间的距离
362         getAmapDistance(lng,lat,poi){
363             let lnglat = new AMap.LngLat(lng, lat);
364             let distance = lnglat.distance(poi);//这里测量距离
365                 return distance > 1000
366                 ? `${(distance / 1000).toFixed(1)}km`
367                 : `${distance}m`;
368         },
369         //初始化高德的markers数组
370         setGDmarkers(){
371             let arr = [];
372             if(this.markers.length){
373                 this.markers.map((res,i)=>{
374                     arr.push({
375                         position:[res.lng,res.lat],
376                         iconUrl:new AMap.Icon({
377                             image:this.matchIcon(res).url,
378                             size: new AMap.Size(this.matchIcon(res).size.width, this.matchIcon(res).size.height),
379                             imageSize: new AMap.Size(this.matchIcon(res).size.width, this.matchIcon(res).size.height)
380                         }),
381                         type:res.type,
382                         mac:res.mac,
383                         index:i,
384                         events:{
385                             click: (ev) => {
386                                 this.$nextTick(()=>{
387                                     // 这里通过高德 SDK 完成。
388                                     this.getAmapAddress(this.gdMarkers[ev.target.getExtData().index].position).then(res=>{
389                                         let result = res.info?res.regeocode.formattedAddress:'';
390                                         let distance = this.getAmapDistance(
391                                             this.getDGmdlnglat().position[0],
392                                             this.getDGmdlnglat().position[1],
393                                             this.gdMarkers[ev.target.getExtData().index].position
394                                             );
395                                         this.initGDwindow(this.gdMarkers,ev.target.getExtData().index,result,distance);
396                                     })
397                                     
398                                 })
399                             },
400                         }
401                     })
402                 })
403             }
404             this.gdMarkers = arr;
405         },
406         //初始化高德marker的点击事件
407         initGDwindow(arr,index,address,distance){
408             let windows = [];
409             console.log("arr==>",arr)
410             if(arr.length){
411                 arr.map((v,i)=>{
412                     windows.push({
413                         position: v.position,
414                         visible: false,
415                         type:v.type,
416                         mac: v.mac ? v.mac:''
417                     }) 
418                 })
419             }
420             this.window = windows[index];
421             this.window.address = address;
422             this.window.distance = distance;
423             if(this.window.type == 0 || this.window.type ==  3){
424                 return
425             }
426             this.$nextTick(() => {
427                 this.window.visible = true;
428             });
429         },
430         //增加高德marker
431         addGDmarker(msg){
432             this.gdMarkers.push({
433                 position:[msg.longitude,msg.latitude],
434                 iconUrl:new AMap.Icon({
435                     image:this.matchIcon(msg).url,
436                     size: new AMap.Size(this.matchIcon(msg).size.width, this.matchIcon(msg).size.height),
437                     imageSize: new AMap.Size(this.matchIcon(msg).size.width, this.matchIcon(msg).size.height)
438                 }),
439                 type:msg.type,
440                 mac:msg.mac,
441                 index:this.gdMarkers.length,
442                 events:{
443                     click: (ev) => {
444                         this.$nextTick(()=>{
445                             this.getAmapAddress(this.gdMarkers[ev.target.getExtData().index].position).then(res=>{
446                                 let result = res.info?res.regeocode.formattedAddress:'';
447                                 let distance = this.getAmapDistance(
448                                     this.getDGmdlnglat().position[0],
449                                     this.getDGmdlnglat().position[1],
450                                     this.gdMarkers[ev.target.getExtData().index].position
451                                     );
452                                 this.initGDwindow(this.gdMarkers,ev.target.getExtData().index,result,distance);
453                             })
454                         })
455                         
456                     },
457                 }
458             })
459             this.setGDview()
460         },
461         //获取高德门店位置坐标
462         getDGmdlnglat(){
463             return this.gdMarkers.find((v,i)=>{
464                 return v.type == 0;
465             })  
466         },
467         //接受父级组件
468         reciveParentMsg(msg){
469             this.addGDmarker(msg);
470             this.addBDmarker(msg);
471         },
472         //重新缩放高德地图视野
473         setGDview(){
474             console.log(this.$refs.map)
475             this.$refs.map.$$getInstance().setFitView()     
476         }
477     }
478 }
479 </script>
480 <style lang="scss" scoped>
481 .mapView{
482     overflow: hidden;
483     position: relative;
484     height: 100%;
485     display: flex;
486     flex-direction: column;
487     .btnView{
488         position: absolute;
489         right:10px;
490         top: 10px;
491         z-index: 1000;  
492     }
493     .mapContent{
494         flex: 12;
495         border-radius: 10px;
496         .map{
497             height: 100%
498         }
499         .amap-wrapper {
500             width: 100%;
501             height: 100%;
502         }
503     }
504     .iconWrap{
505         flex: 1;
506         .dis-line{
507             margin-top: 20px;
508             display: inline-block;
509             margin-left: 40px;
510             .img{
511                 width: 20px;
512                 vertical-align: middle;
513             }
514             .text{
515                 margin-left: 10px;
516             }
517         }
518     }
519     .p{
520         margin: 10px;
521     }
522 }
523 /deep/ {
524     .el-radio-button__inner{
525         &:hover {
526             border-color: #28d4c1 !important;    
527         }  
528     }
529 }
530 
531 </style>
View Code

代码如上直接复制粘贴可用,但是不要忘记在项目里引用高德和百度的sdk,UI是element-ui哦,

下面代码是里面的那个方法差点忘记贴了。😄

/**
 * 使用百度API转化
 * eg:百度转高德 --- point_transform(5,3,{lng:'', lat: ''})
 * type : 1.GPS 2.GPS-米,sogou 3.谷歌,高德,soso,aliyun,国测局 4.3相关-米 5.百度 6.百度-米 7.mapbar 8.51
 * @param {*} fromType 
 * @param {*} toType
 * @param {*} points  [{lng:0, lat: 0}]
 * points: 官方一次只能转换10个点---ps:所以已添加循环
 */
export function point_transform(fromType, toType, points, cb) {
    let allPoint = [];   //转换后的点数组
    let convertor = new BMap.Convertor();
    let translatePoint = [];    //中转数组
    for (let i = 0; i < points.length; i += 10) {
        translatePoint.push(points.slice(i, i + 10));        //  从已有的数组中返回选定的元素,该方法并不会修改数组,而是返回一个子数组
    }

    for (let i = 0; i < translatePoint.length; i++) {
        convertor.translate(translatePoint[i], fromType, toType, function (data) {
            allPoint.push(...data.points);
            if (i == translatePoint.length - 1) {
                cb(allPoint)
            }
        });
    }

}

  

posted @ 2020-11-25 11:03  lijuntao  阅读(450)  评论(0编辑  收藏  举报
TOP