目录
一、简介
最近在项目中,有需要使用到获取用户当前地理位置信息的功能,获取当前用户位置保存到数据库中的场景,并且需要支持多种地图定位方式,我这里采用系统参数配置的方式,暂时实现了高德地图和腾讯地图两种方式,下面我们就分别对两种地图的实现方式做一个总结。
二、高德地图
【a】注册高德地图开发者账号获取开发者Key
高德开放平台地址:https://console.amap.com/dev/key/app
选择:Web端(JS API)服务平台
【b】页面引入相关JS
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=这里填写上一步申请成功的应用key"></script>
【c】获取当前位置代码
//初始化高德地图定位
initGdMap = () => {
let mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function() {
let geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 是否使用高精度定位,默认:true
timeout: 10000, // 超过10秒后停止定位,默认:无穷大
maximumAge: 0, // 定位结果缓存0毫秒,默认:0
convert: true, // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, // 显示定位按钮,默认:true
buttonPosition: 'LB', // 定位按钮停靠位置,默认:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, // 定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, // 定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, // 定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: true, // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
});
mapObj.addControl(geolocation);
geolocation.getCurrentPosition((status, result) => {
if (status === 'complete') {
//缩减地址 result.formattedAddress为详细地址(省市县)
// let currentAddress = result.addressComponent.building;
console.log(result);
} else {
Toast.fail('定位失败', 1, () => {
props.dispatch({
type: 'studentWorkStudy/changeCurrentAddress',
currentAddress: '定位失败',
});
});
}
});
});
};
【d】调用结果
注意事项:移动端包括手机,pad和其它带有GPS定位芯片的智能设备(如手表、音箱等),移动端的系统包括iOS和Android。成功完成定位需要达成以下前提条件:
- 系统GPS打开;
- 所使用的App或浏览器已获取定位权限;
- 对打开的页面允许使用定位;
- 对于iOS10以上系统和Android的一些版本已禁止在非HTTPS协议的域名下定位,请尽快将站点升级到HTTPS;
注意,以上只是定位成功的前提条件,满足这些并不一定等于可以成功定位,定位还与当前位置(室内会影响GPS信息)、手机信号和定位权限等因素影响。如果您在使用过程中定位失败,可以参考FAQ:Geolocation的定位流程以及定位失败的原因 。
更多高德地图相关API功能可以参考:https://lbs.amap.com/api/javascript-api/summary进行学习。
三、腾讯地图
说实话,腾讯地图没有那么准,如果有开通HTTPS域名访问的网站,建议使用高德地图来进行定位,不然获取的位置可能会有1至2公里的误差都有可能。
【a】注册腾讯地图开发者账号获取开发者Key
腾讯地图开发者平台地址:https://lbs.qq.com/dev/console/key/manage
【b】页面引入相关JS
<script type="text/javascript" src="https://map.qq.com/api/js?v=2.exp&key=这里填写上一个步骤申请的key"></script>
【c】获取当前位置代码
由于考虑到腾讯地图不是特别准,所以我的做法是:先获取到当前位置的经纬度信息,然后稍稍做一些微调,然后通过腾讯地图相关WebService API接口进行经纬度逆解析地理位置信息。
逆地址解析(坐标位置描述)参考文档:https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder
注意:下面的mapSecret其实就是刚刚第一步申请的腾讯地图Key.
//初始化腾讯地图定位
initTencentMap = (mapSecret = '') => {
if (!mapSecret) {
Toast.fail('请到系统管理设置地图秘钥');
return;
}
let props = this.props;
//初始化腾讯地图定位
let geolocation = new qq.maps.Geolocation(mapSecret, 'ly-sm-mobile-ui');
let options = { timeout: 8000 };
geolocation.getLocation((position) => {
//稍微修正腾讯地图的经纬度偏差
let latitude = position.lat + 0.00134;
let longitude = position.lng + 0.01191;
props.dispatch({
type: 'studentWorkStudy/getAddressList',
params: {
location: `${latitude},${longitude}`,
},
callback: data => {
if (data) {
let dataMap = JSON.parse(data);
console.log(dataMap.result);
//地址描述
// let address = dataMap.result.address || '';
// 经过腾讯地图优化过的描述方式
let recommendAddress = dataMap.result.formatted_addresses.recommend || '';
//更多参数可参考:https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder
props.dispatch({
type: 'studentWorkStudy/changeCurrentAddress',
currentAddress: recommendAddress,
});
}
},
});
}, () => {
Toast.fail('定位失败', 1, () => {
props.dispatch({
type: 'studentWorkStudy/changeCurrentAddress',
currentAddress: '定位失败',
});
});
}, options);
};
通过逆地址解析需要后端服务配合去发起WebService请求,其实就是发起一个http请求,请求URL就如下面那样,只是URL上面的经纬度信息是获取的当前位置的经纬度。
调用示例: GET请求示例,注意参数值要进行URL编码
https://apis.map.qq.com/ws/geocoder/v1/?location=39.984154,116.307490&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&get_poi=1
请求参数说明:
参数 | 必填 | 说明 | 示例 |
---|---|---|---|
location | 是 | 位置坐标,格式: location=lat<纬度>,lng<经度> | location= 39.984154,116.307490 |
get_poi | 否 | 是否返回周边POI列表: 1.返回;0不返回(默认) | get_poi=1 |
poi_options | 否 | 用于控制POI列表: 1 poi_options=address_format=short 返回短地址,缺省时返回长地址 2 poi_options=radius=5000 半径,取值范围 1-5000(米) 3 poi_options=page_size=20 每页条数,取值范围 1-20 4 poi_options=page_index=1 页码,取值范围 1-20 注:分页时page_size与page_index参数需要同时使用 5 poi_options=policy=1/2/3/4/5 控制返回场景, policy=1[默认] 以地标+主要的路+近距离POI为主,着力描述当前位置; policy=2 到家场景:筛选合适收货的POI,并会细化收货地址,精确到楼栋; policy=3 出行场景:过滤掉车辆不易到达的POI(如一些景区内POI),增加道路出入口、交叉口、大区域出入口类POI,排序会根据真实API大用户的用户点击自动优化。 policy=4 社交签到场景,针对用户签到的热门 地点进行优先排序。 policy=5 位置共享场景,用户经常用于发送位置、位置分享等场景的热门地点优先排序 6 poi_options=category=分类词1,分类词2, 指定分类,多关键词英文逗号分隔; (支持类别参见:附录) | 【单个参数写法示例】: poi_options=address_format=short 【多个参数英文分号间隔,写法示例】: poi_options=address_format=short;radius=5000; page_size=20;page_index=1;policy=2 |
key | 是 | 开发密钥(Key) | key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77 |
output | 否 | 返回格式:支持JSON/JSONP,默认JSON | output=json |
callback | 否 | JSONP方式回调函数 | callback=function1 |
返回结果示例:
{
"status": 0,
"message": "query ok",
"request_id": "c165b6de-b9d9-11ea-8207-5254004df5fd",
"result": {
"location": {
"lat": 39.984154,
"lng": 116.30749
},
"address": "北京市海淀区北四环西路66号",
"formatted_addresses": {
"recommend": "海淀区中关村中国技术交易大厦(彩和坊路)",
"rough": "海淀区中关村中国技术交易大厦(彩和坊路)"
},
"address_component": {
"nation": "中国",
"province": "北京市",
"city": "北京市",
"district": "海淀区",
"street": "北四环西路",
"street_number": "北四环西路66号"
},
"ad_info": {
"nation_code": "156",
"adcode": "110108",
"city_code": "156110000",
"name": "中国,北京市,北京市,海淀区",
"location": {
"lat": 40.045132,
"lng": 116.375
},
"nation": "中国",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"address_reference": {
"business_area": {
"id": "14178584199053362783",
"title": "中关村",
"location": {
"lat": 39.980598,
"lng": 116.310997
},
"_distance": 0,
"_dir_desc": "内"
},
"famous_area": {
"id": "14178584199053362783",
"title": "中关村",
"location": {
"lat": 39.980598,
"lng": 116.310997
},
"_distance": 0,
"_dir_desc": "内"
},
"crossroad": {
"id": "529979",
"title": "海淀大街/彩和坊路(路口)",
"location": {
"lat": 39.982498,
"lng": 116.30809
},
"_distance": 185.8,
"_dir_desc": "北"
},
"town": {
"id": "110108012",
"title": "海淀街道",
"location": {
"lat": 39.974819,
"lng": 116.284409
},
"_distance": 0,
"_dir_desc": "内"
},
"street_number": {
"id": "595672509379194165901290",
"title": "北四环西路66号",
"location": {
"lat": 39.984089,
"lng": 116.308037
},
"_distance": 45.8,
"_dir_desc": ""
},
"street": {
"id": "9217092216709107946",
"title": "彩和坊路",
"location": {
"lat": 39.97921,
"lng": 116.308411
},
"_distance": 46.6,
"_dir_desc": "西"
},
"landmark_l2": {
"id": "3629720141162880123",
"title": "中国技术交易大厦",
"location": {
"lat": 39.984104,
"lng": 116.307503
},
"_distance": 0,
"_dir_desc": "内"
}
},
"poi_count": 10,
"pois": [
{
"id": "3629720141162880123",
"title": "中国技术交易大厦",
"address": "北京市海淀区北四环西路66号",
"category": "房产小区:商务楼宇",
"location": {
"lat": 39.984104,
"lng": 116.307503
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 0,
"_dir_desc": "内"
},
{
"id": "9969038414753335812",
"title": "腾讯科技(北京)有限公司(中国技术交易大厦)",
"address": "北京市海淀区北四环西路66号中国技术交易大厦第三极大厦5-11层",
"category": "公司企业:公司企业",
"location": {
"lat": 39.984131,
"lng": 116.307503
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 0,
"_dir_desc": "内"
},
{
"id": "2845372667492951071",
"title": "中国技术交易大厦A座",
"address": "北京市海淀区北四环西路66号",
"category": "房产小区:商务楼宇",
"location": {
"lat": 39.984329,
"lng": 116.307419
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 20.4,
"_dir_desc": ""
},
{
"id": "3724888736111897241",
"title": "万学教育集团",
"address": "北京市海淀区北四环西路66号中国技术交易大厦",
"category": "公司企业:公司企业",
"location": {
"lat": 39.984085,
"lng": 116.307426
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 9.2,
"_dir_desc": ""
},
{
"id": "13477589832396847863",
"title": "品·咖啡",
"address": "北京市海淀区北四环西路66号中国技术交易大厦1楼大厅内",
"category": "娱乐休闲:咖啡厅",
"location": {
"lat": 39.984192,
"lng": 116.30735
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 12.5,
"_dir_desc": ""
},
{
"id": "3187032738687555052",
"title": "中关村创业大街",
"address": "北京市海淀区海淀西大街",
"category": "购物:商业步行街",
"location": {
"lat": 39.983013,
"lng": 116.306732
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 36.3,
"_dir_desc": "东北"
},
{
"id": "7246616758286733108",
"title": "基督教堂(彩和坊路)",
"address": "北京市海淀区彩和坊路9号",
"category": "旅游景点:教堂",
"location": {
"lat": 39.983135,
"lng": 116.30764
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 69.5,
"_dir_desc": "北"
},
{
"id": "12925244666643621769",
"title": "中国技术交易大厦B座",
"address": "北京市海淀区北四环西路66号",
"category": "房产小区:商务楼宇",
"location": {
"lat": 39.983906,
"lng": 116.307556
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 28.2,
"_dir_desc": ""
},
{
"id": "12689244359326172642",
"title": "车库咖啡",
"address": "北京市海淀区中关村创业大街6号楼2层",
"category": "娱乐休闲:咖啡厅",
"location": {
"lat": 39.983898,
"lng": 116.306908
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 57.1,
"_dir_desc": "东北"
},
{
"id": "2926578115367138813",
"title": "武胜猪肝面",
"address": "北京市海淀区北四环西路66号",
"category": "美食:小吃快餐",
"location": {
"lat": 39.984184,
"lng": 116.307503
},
"ad_info": {
"adcode": "110108",
"province": "北京市",
"city": "北京市",
"district": "海淀区"
},
"_distance": 3.6,
"_dir_desc": ""
}
]
}
}
通过逆地址解析,还可以获取当前位置的附近点位置集合信息,这在某些业务场景下还有很有用的。
【d】定位结果
更多腾讯地图相关API可以参考:https://lbs.qq.com/webApi/javascriptGL/glGuide/glOverview进行学习。
四、总结
以上就是关于高德地图和腾讯地图获取用户当前位置的功能,简单来说,基本上都是按照官方文档进行的,这里只是做一个总结,方面后面用到的时候可以翻出来看看,还有很多更骚的操作可以参考对应的官方文档进行学习。