地理定位插件

上个任务是个手机端编辑个人信息页面,需要选址得到地理定位信息(经纬度)。设计说这个功能可以参考盒马生鲜APP中选择收货地址的功能。后面功能是实现了,美观不足,O(∩_∩)O哈哈~,毕竟我是一个审美观有点欠缺的前端啊!

地理定位插件_第1张图片
229418621.jpg

我把这个插件的功能分成了两个部分:搜索选址和拖拽地图选址。

初始化

  • 首先去百度地图API注册登录,获取密钥,引用百度地图API文件。

  • 初始化地图
const map = new BMap.Map('map') 
  • 设置地图初始位置
    • 如果知道经纬度,直接创建地理坐标点,设置地图位置和地图级别
    • 如果没有经纬度数据,先请求获取当前位置再设置
    • 请求当前位置是需要授权确认的,如果授权取消,就拿不到当前位置信息了。退而求其次请求当前城市位置,得到的地理坐标点再设置。像上海市就是定位到市政府大楼。
  if (lng && lat) {
    const newPoint = new BMap.Point(lng, lat)
    map.centerAndZoom(newPoint, 18)
  } else {
    const geolocation = new BMap.Geolocation()
    geolocation.enableSDKLocation()
    geolocation.getCurrentPosition((result) => {
      if (geolocation.getStatus() === BMAP_STATUS_SUCCESS) {
        map.centerAndZoom(result.point, 18)
      } else {
        new BMap.LocalCity().get((result) => {
          map.centerAndZoom(result.center, 18)
        })
      }
    })
  }
  • 添加地图组件
    在这里我加入了定位组件和地图缩放组件,没有加参数,感觉保持他们的默认状态就还算能用了。定位组件我赋值给了一个变量,为稍后给它加入事件提供方便。
  map.addControl(new BMap.NavigationControl())
  const geolocationControl = new BMap.GeolocationControl()
  map.addControl(geolocationControl)

地图的的部分就显示出来了,现在它就只是一个地图,接下来要给它加入可以选址的功能

搜索选址

搜索选址使用关键字提示输入,输入关键字后在输入框下方会有相应地址列表提供选择,选中其中一项可以拿到对应位置信息。

  • 建立一个自动完成的对象

const ac = new BMap.Autocomplete({ 'input': 'suggestId', 'location': map })
  • 加入点击列表项事件
    事件对象处理一下得到地址字符串,可惜不能直接拿到坐标点,需要通过逆地址解析后获得。
  ac.addEventListener('onconfirm', (e) => {
    const value = e.item.value
    vm.value.address = value.province + value.city + value.district + value.street + value.business
    geoc.getPoint(vm.value.address, (point) => {
      vm.value.point = point
    })
  })

地图选址

  • 地图中心固定大头针
    拖动地图,刷新地图中心点附近地址列表,这就需要在中心点处固定一个参考物。本来是想用地图的标注实现的,但是标注是固定在地图一个坐标点上的,移动地图时标注的位置也会发生改变,如果边移动地图边改变标注位置,标注移动时候看起来很卡,不太适用。后面问设计抠了一个有透明背景的大头针图片来,用CSS固定在了地图中心点。
  • 获取地图中心点附近地址列表
    在地图对象绑定的dragend事件中触发getSurroundingPois方法,得到列表数据,在地址列表中显示每一项的titleaddress
const geoc = new BMap.Geocoder()

const getSurroundingPois = (vm) => {
  geoc.getLocation(map.getCenter(), (result) => {
    vm.result = result
  })
}
  • 给列表项加入点击事件,点击时直接可以索引到vm.result中的一项数据,就ok了

注意点

  • 除了地图拖动结束,地图初始化位置,点击定位组件定位成功(locationSuccess事件),也需要获取或者刷新地图中心点附近地址列表
  • 搜索输入框,地图和地图中心附近地址列表是用flex纵向排列的,地图和附近地址列表的高度是可变动的,地图高度变化后地图中心点坐标也变化了,我感觉这样不太好,所以监听了地图resize事件,把地图中心点设置成地图大小变化之前的中心点。
  map.addEventListener('resize', () => {
    map.setCenter(vm.result.point)
  })

还有一些细节就不说了,总之,磕磕盼盼完成之后,心里有种不写点东西出来纪念下,就憋得慌的感觉。这算是我的第一篇技术分享了。不喜勿喷,欢迎提意见!

你可能感兴趣的:(地理定位插件)