上个任务是个手机端编辑个人信息页面,需要选址得到地理定位信息(经纬度)。设计说这个功能可以参考盒马生鲜APP中选择收货地址的功能。后面功能是实现了,美观不足,O(∩_∩)O哈哈~,毕竟我是一个审美观有点欠缺的前端啊!
229418621.jpg我把这个插件的功能分成了两个部分:搜索选址和拖拽地图选址。
初始化
- 首先去百度地图API注册登录,获取密钥,引用百度地图API文件。
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥"></script>
- 初始化地图
<div id="map"></div>
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)
地图的的部分就显示出来了,现在它就只是一个地图,接下来要给它加入可以选址的功能
搜索选址
搜索选址使用关键字提示输入,输入关键字后在输入框下方会有相应地址列表提供选择,选中其中一项可以拿到对应位置信息。
- 建立一个自动完成的对象
<input id="suggestId">
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
方法,得到列表数据,在地址列表中显示每一项的title
、address
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)
})
还有一些细节就不说了,总之,磕磕盼盼完成之后,心里有种不写点东西出来纪念下,就憋得慌的感觉。这算是我的第一篇技术分享了。不喜勿喷,欢迎提意见!
网友评论