el-cascader异步级联选择器选择省市区,在百度地图上显示坐标

大家好,我是南宫,上上周我去开了个需求评审,里面有几个细节我特别担心,特意花了两天去查资料,查的昏天黑地的。上周我开始写在地图上选择坐标的组件,写完以后想分享一下其中的经验,所以写了这篇博客。

可能不会涉及太多细节,主要是思路的分享。

① 级联选择器选择到的是id,怎么把选择到的id给百度地图API查询经纬度坐标?

我的级联选择器用的是公司内部自己的接口封装的,是异步的级联选择器,选择到的结果是一个数组,值为对应的行政编码。比如["35","3501","350102"]。

效果大概这样:(地图组件的点击定位和搜索框定位是其他同事做的,我拿过来以后补充了头部级联选择器和对应的定位,以及选中的经纬度显示在右上角)

我确认过,用行政编码是无法到百度地图查出经纬度坐标的,但是省市区的名称可以(通过百度地图的地址解析功能可以根据省市区名称获取经纬度,如果传入数字找不到)。

所以核心就是,在选择完,拿到code以后,去获取选择的节点数据,然后拼接完整的省市区名称,然后调用百度地图的api去查询经纬度。

分享一部分的代码。

// 在级联选择器被回填以后,或者发生了change事件后,就去获取勾选的节点,并且通过parent找到所有父节点的数据,就可以拼接节点的名称了
getArea() {
   const nodes = this.$refs.nativeSelect.$refs.nativePlace.getCheckedNodes()
   console.log('nodes, 级联选择器勾选的节点', nodes)
   let name = nodes[0].data.areaName
   let parent = nodes[0].parent
   while (parent) {
     name = parent.data.areaName + ',' + name
     parent = parent.parent
    }
    console.log('name拼接', name)
    this.areaName = name
  },

获取到名称以后,把名称拼接起来,拼接起来以后作为一个地址去调用百度地图地址解析的API

(前面那段修改了areaName的值,下面这段代码是针对areaName的watch)

主要是调用BMapGL.Geocoder实例的getPoint方法,第一个参数是地址字符串,第二个参数是回调函数,第三个参数表示城市,也就是在哪个城市找这个地址,我们这里地址就是省市区,所以不使用第三个参数。

// 获取到完整的行政区域名称后,获取经纬度,设为中心点,并且定位到这里
areaName(val) {
  if (val) {
    var geocoder = new BMapGL.Geocoder()
    geocoder.getPoint(val, (rs) => {
    console.log('结果', rs)
     if (rs) {
       this.$refs.map.setCenter([rs.lng, rs.lat])
       this.mapClick([rs.lng, rs.lat])
       console.log('获取行政区域坐标', rs.lng, rs.lat)
      } else {
         this.$message.warning('行政区域定位失败')
      }
     })
   }
 },

(地图组件的封装和地图组件定位到对应坐标的代码我就不放出来了,反正重点是要获取到选择的省市区的经纬度坐标)

② 特殊情况下查不到经纬度坐标,怎么办?

我的这个需求是可以选择省市区,但是没有要求必须选到区,也可以只选到市级或者省级

我发现如果只选择到省,或者是选择了香港澳门台湾,会直接返回北京的经纬度坐标。应该是getPoint方法的内部逻辑,如果实在找不到就返回北京的坐标。

但是这样的话,虽然不会报错,但是给我造成了困扰。

我提供一个解决思路——先判断是否只选择省,是就拼接省会城市去定位,需要注意自治区的判断。

(因为省是一大块地区,只能用经纬度范围而不是经纬度坐标来定义。但是如果是省级的单位,往往都是设在省会城市的,所以定位到省会没什么不妥。注意自治区也是省级,但是名字又带“区”,不能仅仅用选择到的名字是否带有“省”来判断是否选择了省级)

如果是港澳台,就去定位到特定的坐标,我去百度搜到了一个差不多的经纬度,如果匹配到,直接让地图定位对应的坐标。

provinceToCapital数据是省份和省会的对照索引表,这个数据是AI提供给我的,当然,下面这个代码也是AI写的,我给整合起来用了。

 // 根据行政区域名称获取经纬度,如果选择的是省,就定位到省会城市
 getLocationByAddress(address) {
   var myGeo = new BMapGL.Geocoder() // 预处理地址
   if ((!address.includes('市') && !address.includes('区')) || address.includes('自治区')) 
   {
     // 假设所有省份后面都加上省会城市名
     var capital = provinceToCapital[address]
     if (capital) {
       address += capital
     }
   }
   console.log('获取经纬度的地址', address)
   // 特殊处理特殊的地名
   if (address.includes('香港')) {
     const point = {
       lng: 114.25,
       lat: 22.25,
     }
     console.log(point.lng + ', ' + point.lat)
     this.$refs.map.setCenter([point.lng, point.lat])
     this.mapClick([point.lng, point.lat])
     console.log('获取行政区域坐标', point.lng, point.lat)
   } else if (address.includes('澳门')) {
     const point = {
       lng: 113.55,
       lat: 22.19,
     }
     console.log(point.lng + ', ' + point.lat)
     this.$refs.map.setCenter([point.lng, point.lat])
     this.mapClick([point.lng, point.lat])
     console.log('获取行政区域坐标', point.lng, point.lat)
   } else if (address.includes('台湾')) {
       const point = {
       lng: 121.5,
       lat: 25.05,
     }
     console.log(point.lng + ', ' + point.lat)
     this.$refs.map.setCenter([point.lng, point.lat])
     this.mapClick([point.lng, point.lat])
     console.log('获取行政区域坐标', point.lng, point.lat)
   } else {
       myGeo.getPoint(address, (point) => {
       if (point) {
         console.log(point.lng + ', ' + point.lat)
         this.$refs.map.setCenter([point.lng, point.lat])
         this.mapClick([point.lng, point.lat])
         console.log('获取行政区域坐标', point.lng, point.lat)
       } else {
         console.log('无法解析地址') // 可以选择返回一个预设的经纬度或者提示用户
         this.$message.warning('行政区域定位失败')
       }
     })
   }
 },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值