vue使用高德地图后坐标偏移问题

前言:
因为项目有多个版本,有app端及H5端,app端定位地理信息是用手机GPS获取,而H5端定位地理信息是用高德地图获取,但是发现高德地图获取的坐标系有偏移~

一、使用高德地图:

            // 获取当前定位
			AMap.plugin('AMap.Geolocation', function() {
					const geolocation = new AMap.Geolocation({
						enableHighAccuracy: true, //是否使用高精度定位,默认:true
						timeout: 10000, //超过10秒后停止定位,默认:无穷大
					})
					geolocation.getCurrentPosition()
					AMap.event.addListener(geolocation, 'complete', onComplete)
					AMap.event.addListener(geolocation, 'error', onError)
					function onComplete(data) {
					    console.log('高德地图定位成功', data)
					}
					function onError(data) {
						console.log('高德地图定位失败', data)
					}
				})

发现定位返回的地理有偏差,查阅资料后,发现

因为在我国,出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局指定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标,我们在业内将前者称为地球坐标,后者称为火星坐标系(GCJ-02)

而高德地图就是GCJ-02坐标,获取正确的坐标需要转为WGS84坐标

WGS-84坐标系是目前最通用的标准地理坐标系,平实我们常说的经纬度、从GPS设备、智能手机中取出的数据的坐标系、国际地图提供商使用的坐标系都是WGS84坐标系。

二、解决方法

思路:
1、把GCJ-02坐标系转为WGS84坐标系
2、WGS84坐标系使用逆向地理解码(通过经纬度获得地理信息)

1、GCJ-02坐标系 => WGS84坐标系
src目录下新建一个工具类文件(utils),新建gcj02towgs84.js

// 定义一些常量
const x_PI = 3.14159265358979324 * 3000.0 / 180.0
const PI = 3.1415926535897932384626
const a = 6378245.0 // 卫星椭球坐标投影到平面地图坐标系的投影因子
const ee = 0.00669342162296594323  // 椭球的偏心率

/**
 * GCJ02(火星坐标系) 转换为 WGS84 / 即谷歌高德转WGS84
 * @param { Number } lng
 * @param { Number } lat
 */
export function gcj02towgs84(lng, lat) {
    if (outOfChina(lng, lat)) {
        return [lng, lat]
    } else {
        var dlat = transformlat(lng - 105.0, lat - 35.0)
        var dlng = transformlng(lng - 105.0, lat - 35.0)
        var radlat = lat / 180.0 * PI
        var magic = Math.sin(radlat)
        magic = 1 - ee * magic * magic
        var sqrtmagic = Math.sqrt(magic)
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
        const mglat = lat + dlat
        const mglng = lng + dlng
        return [lng * 2 - mglng, lat * 2 - mglat]
    }
}

/**
 * 经度转换
 * @param { Number } lng
 * @param { Number } lat
 */
function transformlat(lng, lat) {
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
    return ret
}

/**
 * 纬度转换
 * @param { Number } lng
 * @param { Number } lat
 */
function transformlng(lng, lat) {
    var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
    return ret
}

/**
 * 判断是否在国内,不在国内则不做偏移
 * @param {*} lng
 * @param {*} lat
 */
function outOfChina(lng, lat) {
    return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
}

在页面中使用

引入:

import { gcj02towgs84 } from '../../../../utils/gcj02towgs84'

使用:

gcj02towgs84(data.position.lng, data.position.lat)

2、逆向地理解码

// 逆向地理解码
const geocoder = new AMap.Geocoder({})
const lnglat = gcj02towgs84(data.position.lng, data.position.lat) // GCJ02 转成 WGS84
geocoder.getAddress(lnglat,function (status, result) {
		if (status === 'complete' && result.info === 'OK') {
				console.log('逆向地理解码', result)
		}
)

完整代码:

				// 获取当前位置
				AMap.plugin('AMap.Geolocation', function() {
					const geolocation = new AMap.Geolocation({
						enableHighAccuracy: true, //是否使用高精度定位,默认:true
						timeout: 10000, //超过10秒后停止定位,默认:无穷大
					})
					geolocation.getCurrentPosition()
					AMap.event.addListener(geolocation, 'complete', onComplete)
					AMap.event.addListener(geolocation, 'error', onError)
					function onComplete(data) {
						// 逆向地理解码
						const geocoder = new AMap.Geocoder({})
						const lnglat = gcj02towgs84(data.position.lng, data.position.lat) // GCJ02 转成 WGS84
						geocoder.getAddress(lnglat,function (status, result) {
							if (status === 'complete' && result.info === 'OK') {
								console.log('逆向地理解码', result)
							}
						})
					}
					function onError(data) {
						console.log('高德地图定位失败', data)
					}
				})

最后:

以为圆满解决了这个问题,然后发现偏差更严重了
在这里插入图片描述
之前偏差1公里,转后偏差了近2公里…

在这里插入图片描述
最最后:

去了一些论坛找答案。

在这里插入图片描述

所以,有办法解决可以告知一下我哦,不挣扎了~

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
要在Vue2中使用高德地图对地图添加GPS定位,可以按照以下步骤进行: 1. 首先,在Vue项目中引入高德地图JavaScript API的SDK,并在页面中添加地图容器。 2. 在Vue组件中使用AMap对象的定位插件AMap.Geolocation获取用户的位置信息,并将地图中心移动到用户当前位置。 以下是示例代码: ``` <template> <div id="map-container"></div> </template> <script> export default { mounted() { // 初始化地图对象 const map = new AMap.Map('map-container', { zoom: 14 }); // 使用定位插件获取用户位置信息 map.plugin('AMap.Geolocation', function() { const 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, 60), // 定位按钮距离容器底部/右侧的像素距离,默认:Pixel(10, 20) showMarker: true, // 定位成功后在定位到的位置显示点标记,默认:true showCircle: true, // 定位成功后用圆圈表示定位精度范围,默认:true panToLocation: true, // 定位成功后将定位到的位置作为地图中心点,默认:true zoomToAccuracy: true // 定位成功后自动调整地图缩放级别以适应定位精度范围,默认:true }); map.addControl(geolocation); geolocation.getCurrentPosition(function(status, result) { if (status === 'complete') { // 定位成功,将地图中心移动到用户当前位置 map.setCenter([result.position.lng, result.position.lat]); } else { // 定位失败 console.log('定位失败'); } }); }); } } </script> ``` 在上面的示例代码中,我们首先初始化了一个地图对象,然后在组件的mounted生命周期函数中使用AMap.Geolocation插件获取用户位置信息,并将地图中心移动到用户当前位置。注意,需要在组件中引入高德地图JavaScript API SDK,并在页面中添加地图容器。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值