前端常见的定位大致有如下几种方案
geolocation 定位
地理位置 API 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可,只用用户允许定位才能够获取到定位信息。
在使用之前需要对该对象进行判断
1 2 3 if (navigator.geolocation) { // doSomething }
通过 getCurrentPosition() 获取当前定位位置,若用户允许进行定位,则会返回一个集合位置相关信息的对象集合
1 2 3 4 navigator.geolocation.getCurrentPosition(pos => { console.log(pos.coords.latitude) console.log(pos.coords.longitude) })
geolocation API 同时还提供了获取用户移动时的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 // 可以使用 clearWatch 移除事件 function getLocation() { if (navigator.geolocation) { navigator.geolocation.watchPosition(showPosition); } else { console.log("Geolocation is not supported by this browser") } } function showPosition(position) { console.log("Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude) }
第三方地图定位 以腾讯地图为例,使用之前引入依赖https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js
获取精确定位信息
1 2 3 4 5 6 let geolocation = new qq.maps.Geolocation("your key", "myapp") geolocation.getLocation(pos => { // doSomething }, err => { // doSomething })
获取粗糙定位信息
1 2 3 4 5 6 let geolocation = new qq.maps.Geolocation("your key", "myapp") geolocation.getIpLocation(pos => { // doSomething }, err => { // doSomething })
如需使用腾讯地图,可以使用如下方式进行引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function TMap () { return new Promise(function (resolve, reject) { if (window.qq) { resolve(window.qq) return false } window.init = function () { resolve(window.qq) } let script = document.createElement('script') // 如需使用几何运算工具,需要加上参数 &libraries=geometry script.src = `https://map.qq.com/api/js?v=2.exp&callback=init&key=${key}` script.onerror = reject document.head.appendChild(script) }) }
腾讯地图提供了丰富的 API 及组件:
1.初始化地图
1 2 3 4 5 6 7 8 9 10 let center = new qq.maps.LatLng(latitude, longitude) let map = new qq.maps.Map($element, { center: center, zoom: 12, minZoom: 7, zoomControl: true, zoomControlOptions: { position: qq.maps.ControlPosition.BOTTOM_LEFT } })
2.添加覆盖物
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let marker = new qq.maps.Marker({ position: center, map: map }) let size = new qq.maps.Size(120, 180) let origin = new qq.maps.Point(0, 0) let anchor = new qq.maps.Point(15, 20) let scaleSize = new qq.maps.Size(15, 15) let markerIcon = new qq.maps.MarkerImage( redIcon, size, origin, anchor, scaleSize ) marker.setIcon(markerIcon) // 删除覆盖物 marker.setMap(null)
3.添加信息窗及事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let infoWin = new qq.maps.InfoWindow({ map: map }) qq.maps.event.addListener(marker, 'click', () => { infoWin.open() infoWin.setContent(`<div style="text-align:center;white-space:nowrap;margin:10px;">${title}</div>`) infoWin.setPosition(center) }) qq.maps.event.addListener(map, 'bounds_changed', () => { map.setCenter(center) marker.setMap(null) // doSomething })
4.地图选点组件
1 2 3 4 export default (backUrl) => { window.location.href = `https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=${backUrl}&key=${key}&referer=my-app` }
5.添加 label
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let label = new qq.maps.Label({ position: center, map: map, offset: new qq.maps.Size(-40, 10), content: 'label' }) let cssStyle = { color: '#FFFFFF', fontSize: '12px', fontWeight: 'bold' transform: 'translateX(-50%)' } label.setStyle(cssStyle)
6.绘制直线
1 2 3 4 5 6 7 new qq.maps.Polyline({ path: [start, end], strokeColor: '#000', strokeWeight: 5, editable: false, map: map })
7.绘制圆形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 new qq.maps.Circle({ //圆形的中心点坐标。 center: center, //圆形是否可点击。 clickable: true, //是否可以编辑 editable: true, //鼠标在圆形内的光标样式。 cursor: 'pointer', //圆形的填充色,可通过Color对象的alpha属性设置透明度。 // fillColor: "#00f", fillColor: new qq.maps.Color(0,15,255, 0.2), //要显示圆形的地图。 map: this.map, //圆形的半径。 radius: 500, //圆形的边框颜色,可通过Color对象的alpha属性设置透明度。 strokeColor: "#fff", //圆形的边框样式。实线是solid,虚线是dash。 strokeDashStyle: "solid", //圆形的边框线宽。 strokeWeight: 2, //圆形是否可见。 visible: true, //圆形的zIndex值。 zIndex: 1000 })
8.绘制多边形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 new qq.maps.Polygon({ //多边形是否可点击。 clickable: true, //鼠标在多边形内的光标样式。 cursor: 'crosshair', //多边形是否可编辑。 editable: true, //多边形的填充色,可通过Color对象的alpha属性设置透明度。 // fillColor: '#5f9ea0', fillColor: fillColor || new qq.maps.Color(0, 0, 0, 0.2), //要显示多边形的地图。 map: this.map, //多边形的路径,以经纬度坐标数组构成。 path: path, //多边形的线条颜色,可通过Color对象的alpha属性设置透明度。 strokeColor: '#0ad', //多边形的边框样式。实线是solid,虚线是dash。 strokeDashStyle: 'solid', //多边形的边框线宽。 strokeWeight: 3, //多边形是否可见。 visible: true, //多边形的zIndex值。 zIndex: 1000 })
9.计算直线距离
1 qq.maps.geometry.spherical.computeDistanceBetween(path1, path2)
更多 API 移步 腾讯地图 JavaScript API 需要注意的是,使用腾讯地图的一些开放 API 必须进行 Key鉴权:
> Key用途
Key用于识别开发者身份、验证权限,并在某些情况下方便联系到您。不使用Key会导致部分功能无法正常使用。
> Key使用限制
目前Key申请完全免费,基础功能使用免费,且没有调用次数限制。
> Key使用方法
在加载API服务时通过key参数传入您申请的Key。
> Key如何申请
使用QQ账号登录,点击控制台—密钥管理—申请创建密钥,填写应用名及应用描述即可申请。一个账号最多可以申请5个Key
微信 JSSDK 定位 微信提供了 JSSDK 供开发者在微信环境下使用,其中包含获取当前位置的 api,若要使用微信 JSSDK,需要通过 wx.config 进行权限验证,验证通过后使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 wx.config({ debug: false, appId: json.appid, timestamp: json.timestamp, nonceStr: json.nonceStr, signature: json.signature, jsApiList: [ 'getLocation' ] }); wx.error(function (res) { console.log(res.errMsg); options.callback(); }); wx.ready(function () { wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation 用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 console.log('微信定位成功;'); }, fail: function(){ console.log('微信定位失败;'); } }); });
App 定位 对于嵌入在 App 中的 H5 页面,通常会由 App 进行定位,并通过地址栏传参给 H5 页面,在 App 中,优先使用 App 的定位。
参考
腾讯地图 JavaScript API
微信JS-SDK说明文档