我在弄一个实验室预约项目,学生到预约的时间后在实验室的电脑上进行签到定位。使用高德地图api进行定位,功能弄好了,可是定位的距离和实际的距离差了几百米。(我在图书馆点击定位,但是在浏览器上定位到了宿舍楼;在宿舍楼点击定位,但是定位到了教学楼)。请问这个怎么解决?谢谢。
(https://segmentfault.com/q/10...,这篇文章我也看过了,跟着弄也不行)
我在弄一个实验室预约项目,学生到预约的时间后在实验室的电脑上进行签到定位。使用高德地图api进行定位,功能弄好了,可是定位的距离和实际的距离差了几百米。(我在图书馆点击定位,但是在浏览器上定位到了宿舍楼;在宿舍楼点击定位,但是定位到了教学楼)。请问这个怎么解决?谢谢。
(https://segmentfault.com/q/10...,这篇文章我也看过了,跟着弄也不行)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<link type="text/css" href="../static/atd/css/common-9baddc8954.css" rel="stylesheet">
<link href="../static/atd/css/layer.css" rel="stylesheet" type="text/css">
<link type="text/css" href="../static/atd/css/stuCourse-06127df797.css" rel="stylesheet">
<%--加载高德地图--%>
<script type="text/javascript"
src="http://webapi.amap.com/maps?v=1.4.3&key=ec3226d69643a423012abef447eb8db1"></script>
<!-- UI组件库 1.0 -->
<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
<script src="../static/atd/js/jquery-3.2.1.min.js"></script> <%--444444444--%>
<style type="text/css">body {
position: relative;
max-width: 520px;
margin: 0 auto;
overflow: hidden;
}
</style>
<base href="<%=basePath%>">
</head>
<body onload="javascript:toolBar.doLocation()">
<div class="page-inner" id="page-getlocation-confirm">
<form action="lab_info/${msg }.do" method="post" id="confirmAttendForm">
<header class="header-item" style="background-color: rgb(0, 117, 142);">
<a href="javascript:history.back(-1)" class="icon-back" data-pjax="">
<img src="static/atd/img/backWhite.png" style="vertical-align: middle;text-align: center;">
</a>
<i class="line"></i>
<h3 class="fs36 text-overflow" id="attencename">确认签到位置</h3>
</header>
<div id="wrapper-getLocation">
<div class="location-map-checkin" style="height:80px;">
<a href="javascript:document:confirmAttendForm.submit();" class="gotocheckin">
<span class="top">定位准确</span>
<span class="bottom">点击签到</span>
</a>
<a href="javascript:void(0)" onclick="location.reload()" class="reloadcation" id="start">
<span class="top">定位有误</span>
<span class="bottom">重新定位</span>
</a>
</div>
<%--显示位置--%>
<div style="padding-bottom: 10px">
<input type="text" id="location" name="LOCATION" class="fs30" readonly="readonly" style="width: 100%;font-size: 15px">
<input type="text" id="position" name="LOCATION" class="fs30" readonly="readonly" style="width: 100%;font-size: 15px">
<input type="text" id="location_type" name="LOCATION" class="fs30" readonly="readonly" style="width: 100%;font-size: 15px">
<input type="hidden" name="LAB_ID" value="${LAB_ID}">
</div>
</div>
<%--显示地图--%>
<div id="container"
style="height:560px;overflow: hidden; position: relative; background-color: rgb(243, 241, 236); color: rgb(0, 0, 0); text-align: left;">
</div>
</form>
</div>
</body>
<%--提示框--%>
<div class="" id="tipWindow">
<div class="gTips"><span style="background-color: #EA3640" id="tip">${tipInfo}</span></div>
</div>
</html>
<script>
setTimeout('$("#tipWindow").addClass("hidden")', 3000);
/**/
//自定义定位标记
var toolBar;
/*offset: new AMap.Pixel(-14, -34),//相对于基点的位置*/
var customMarker = new AMap.Marker({
offset: new AMap.Pixel(-14, -34),//相对于基点的位置
icon: new AMap.Icon({ //复杂图标
size: new AMap.Size(27, 36),//图标大小
image: "http://webapi.amap.com/images/custom_a_j.png", //大图地址
imageOffset: new AMap.Pixel(-28, 0)//相对于大图的取图位置
})
});
//初始化地图对象,加载地图
var map = new AMap.Map('container', {
resizeEnable: true
});
//地图中添加地图操作ToolBar插件
map.plugin(["AMap.ToolBar"], function () {
toolBar = new AMap.ToolBar({locationMarker: customMarker}); //设置地位标记为自定义标记
map.addControl(toolBar);
});
var GPS = {
PI: 3.14159265358979324,
x_pi: 3.14159265358979324 * 3000.0 / 180.0,
delta: function (lat, lon)
{
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
var ee = 0.00669342162296594323; // ee: 椭球的偏心率。
var dLat = this.transformLat(lon - 105.0, lat - 35.0);
var dLon = this.transformLon(lon - 105.0, lat - 35.0);
var radLat = lat / 180.0 * this.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) * this.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
return { 'lat': dLat, 'lon': dLon };
},
//WGS-84 to GCJ-02
gcj_encrypt: function (wgsLat, wgsLon)
{
if (this.outOfChina(wgsLat, wgsLon))
return { 'lat': wgsLat, 'lon': wgsLon };
var d = this.delta(wgsLat, wgsLon);
return { 'lat': wgsLat + d.lat, 'lon': wgsLon + d.lon };
},
//GCJ-02 to WGS-84
gcj_decrypt: function (gcjLat, gcjLon)
{
if (this.outOfChina(gcjLat, gcjLon))
return { 'lat': gcjLat, 'lon': gcjLon };
var d = this.delta(gcjLat, gcjLon);
return { 'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon };
},
//GCJ-02 to WGS-84 exactly
gcj_decrypt_exact: function (gcjLat, gcjLon)
{
var initDelta = 0.01;
var threshold = 0.000000001;
var dLat = initDelta, dLon = initDelta;
var mLat = gcjLat - dLat, mLon = gcjLon - dLon;
var pLat = gcjLat + dLat, pLon = gcjLon + dLon;
var wgsLat, wgsLon, i = 0;
while (1)
{
wgsLat = (mLat + pLat) / 2;
wgsLon = (mLon + pLon) / 2;
var tmp = this.gcj_encrypt(wgsLat, wgsLon)
dLat = tmp.lat - gcjLat;
dLon = tmp.lon - gcjLon;
if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))
break;
if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;
if (dLon > 0) pLon = wgsLon; else mLon = wgsLon;
if (++i > 10000) break;
}
//console.log(i);
return { 'lat': wgsLat, 'lon': wgsLon };
},
//GCJ-02 to BD-09
bd_encrypt: function (gcjLat, gcjLon)
{
var x = gcjLon, y = gcjLat;
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
bdLon = z * Math.cos(theta) + 0.0065;
bdLat = z * Math.sin(theta) + 0.006;
return { 'lat': bdLat, 'lon': bdLon };
},
//BD-09 to GCJ-02
bd_decrypt: function (bdLat, bdLon)
{
var x = bdLon - 0.0065, y = bdLat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
var gcjLon = z * Math.cos(theta);
var gcjLat = z * Math.sin(theta);
return { 'lat': gcjLat, 'lon': gcjLon };
},
//WGS-84 to Web mercator
//mercatorLat -> y mercatorLon -> x
mercator_encrypt: function (wgsLat, wgsLon)
{
var x = wgsLon * 20037508.34 / 180.;
var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);
y = y * 20037508.34 / 180.;
return { 'lat': y, 'lon': x };
/*
if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90))
return null;
var x = 6378137.0 * wgsLon * 0.017453292519943295;
var a = wgsLat * 0.017453292519943295;
var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
return {'lat' : y, 'lon' : x};
//*/
},
// Web mercator to WGS-84
// mercatorLat -> y mercatorLon -> x
mercator_decrypt: function (mercatorLat, mercatorLon)
{
var x = mercatorLon / 20037508.34 * 180.;
var y = mercatorLat / 20037508.34 * 180.;
y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);
return { 'lat': y, 'lon': x };
/*
if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90)
return null;
if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))
return null;
var a = mercatorLon / 6378137.0 * 57.295779513082323;
var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);
var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;
return {'lat' : y, 'lon' : x};
//*/
},
// two point's distance
distance: function (latA, lonA, latB, lonB)
{
var earthR = 6371000.;
var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lonA - lonB) * this.PI / 180);
var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);
var s = x + y;
if (s > 1) s = 1;
if (s < -1) s = -1;
var alpha = Math.acos(s);
var distance = alpha * earthR;
return distance;
},
outOfChina: function (lat, lon)
{
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
},
transformLat: function (x, y)
{
var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
return ret;
},
transformLon: function (x, y)
{
var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
return ret;
}
};
var geolocation;
map.plugin('AMap.Geolocation', function () {
geolocation = new AMap.Geolocation({
enableHighAccuracy: true,//是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:无穷大
buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
buttonPosition: 'RB',
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: true //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
});
map.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位信息
AMap.event.addListener(geolocation, 'error', onError); //返回定位出错信息
});
//解析定位结果
function onComplete(data) {
var str = ["定位成功"];
var location = data.formattedAddress;
var position = data.position;
var location_type=data.location_type;
//gcj-02转换为wgt84
var gpsPoint = GPS.gcj_decrypt_exact(data.position.getLat(), data.position.getLng());
document.getElementById('tip').innerHTML = str;
document.getElementById('location').value = "地址:" + location;
document.getElementById('position').value = "position:" + position;
document.getElementById('location_type').value = "location_type:" + location_type + "===" + gpsPoint.lat + "," + gpsPoint.lon;
}
//解析定位错误信息
function onError(data) {
var error = ['定位失败'];
document.getElementById('tip').innerHTML = error;
document.getElementById('location').value = "错误提示:" + data.info + '--' + data.message;
}
</script>
</script>
问题有点模糊,但根据偏差信息,大约是坐标系的问题。高德默认是GCJ2000的米制坐标,如果你当成wgs48的,偏差大概在500米左右。如果只是定位误差,不考虑gps偏移的情况,误差不会超过10米。所以,我估计是第一种情况。不过你描述的环境并不具体,所以也只能猜
10 回答11.2k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
地图类应用由于政府管制一直是有精度丢失的,但是不会相差这么大!看看你的代码坐标转换有没有问题。