空間坐標(biāo)公式:
上述四個方程式中待測點坐標(biāo)x、 y两曼、 z 和Vto為未知參數(shù)皂甘,其中di=c△ti (i=1、2悼凑、3偿枕、4)。
di (i=1佛析、2益老、3、4) 分別為衛(wèi)星1寸莫、衛(wèi)星2捺萌、衛(wèi)星3、衛(wèi)星4到接收機(jī)之間的距離膘茎。
△ti (i=1桃纯、2、3披坏、4) 分別為衛(wèi)星1态坦、衛(wèi)星2、衛(wèi)星3棒拂、衛(wèi)星4的信號到達(dá)接收機(jī)所經(jīng)歷的時間伞梯。
c為GPS信號的傳播速度(即光速)。
四個方程式中各個參數(shù)意義如下:
x帚屉、y谜诫、z 為待測點坐標(biāo)的空間直角坐標(biāo)。
xi 攻旦、yi 喻旷、zi (i=1、2牢屋、3且预、4) 分別為衛(wèi)星1槽袄、衛(wèi)星2、衛(wèi)星3锋谐、衛(wèi)星4在t時刻的空間直角坐標(biāo)遍尺,可由衛(wèi)星導(dǎo)航電文求得。
Vt i (i=1怀估、2狮鸭、3、4) 分別為衛(wèi)星1多搀、衛(wèi)星2歧蕉、衛(wèi)星3、衛(wèi)星4的衛(wèi)星鐘的鐘差康铭,由衛(wèi)星星歷提供惯退。
Vto為接收機(jī)的鐘差。
由以上四個方程即可解算出待測點的坐標(biāo)x从藤、y催跪、z 和接收機(jī)的鐘差Vto 。
GPS的基本定位原理是:衛(wèi)星不間斷地發(fā)送自身的星歷參數(shù)和時間信息夷野,用戶接收到這些信息后懊蒸,經(jīng)過計算求出接收機(jī)的三維位置,三維方向以及運動速度和時間信息悯搔。
引言
在將終端定位到的GPS點顯示到百度地圖上后骑丸,位置有很大偏差,故了解到百度對坐標(biāo)系做了加密
百度地圖api中采用兩種坐標(biāo)體系妒貌,經(jīng)緯度坐標(biāo)系和墨卡托投影坐標(biāo)系通危。前者單位是度,后者單位是米灌曙,具體定義可以參見百科詞條解釋: http://baike.baidu.com/view/61394.htm和http://baike.baidu.com/view/301981.htm菊碟。
坐標(biāo)系轉(zhuǎn)化
查到兩種方式,一種使用百度提供的轉(zhuǎn)換接口在刺,另一種為本地轉(zhuǎn)換
使用百度地圖函數(shù)轉(zhuǎn)換
這里只列舉JS示例:
參考http://www.cnblogs.com/zhaohuionly/archive/2013/06/18/3142623.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}
#l-map{height:100%;width:78%;float:left;border-right:2px solid #bcbcbc;}
#r-result{height:100%;width:20%;float:left;}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.5&ak=9fb983ecd9b505f8fedcc9ab07c65e3e"></script>
<script type="text/javascript" src="http://developer.baidu.com/map/jsdemo/demo/convertor.js"></script>
<title>GPS轉(zhuǎn)百度</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
//GPS坐標(biāo)
var xx = 117.126575995835;
var yy = 36.6702207308909;
var gpsPoint = new BMap.Point(xx,yy);
//地圖初始化
var bm = new BMap.Map("allmap");
bm.centerAndZoom(gpsPoint, 15);
bm.addControl(new BMap.NavigationControl());
//添加谷歌marker和label
var markergps = new BMap.Marker(gpsPoint);
bm.addOverlay(markergps); //添加GPS標(biāo)注
var labelgps = new BMap.Label("我是GPS標(biāo)注哦",{offset:new BMap.Size(20,-10)});
markergps.setLabel(labelgps); //添加GPS標(biāo)注
//坐標(biāo)轉(zhuǎn)換完之后的回調(diào)函數(shù)
translateCallback = function (point){
var marker = new BMap.Marker(point);
bm.addOverlay(marker);
var label = new BMap.Label("我是百度標(biāo)注哦",{offset:new BMap.Size(20,-10)});
marker.setLabel(label); //添加百度label
bm.setCenter(point);
alert("轉(zhuǎn)化為百度坐標(biāo)為:"+point.lng + "," + point.lat);
}
setTimeout(function(){
BMap.Convertor.translate(gpsPoint,0,translateCallback); //真實經(jīng)緯度轉(zhuǎn)成百度坐標(biāo)
}, 2000);
</script>
本地對坐標(biāo)轉(zhuǎn)換
還是使用JS演示逆害,包含html和js,顯示頁面baidu.html如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 95%;overflow: hidden;margin:0;}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.5&ak=9fb983ecd9b505f8fedcc9ab07c65e3e"></script>
<script type="text/javascript" src="http://developer.baidu.com/map/jsdemo/demo/convertor.js"></script>
<script type="text/javascript" src="correction.js"></script>
<script type="text/javascript" src="points-test-data.js"></script>
<script type="text/javascript" src="DistanceTool.js"></script>
<title>GPS坐標(biāo)轉(zhuǎn)百度</title>
</head>
<body>
<div id="allmap"></div>
<div id="control">
<input type="button" value="開啟測距" align="right" onclick="myDis.open()" />
<input type="button" value="關(guān)閉測距" align="right" onclick="myDis.close()" />
</div>
<script type="text/javascript">
//GPS坐標(biāo)
var xx = 117.126575995835;
var yy = 36.6702207308909;
var gpsPoint = new BMap.Point(xx,yy);
//地圖初始化
var bm = new BMap.Map("allmap");
bm.centerAndZoom(gpsPoint, 15);
bm.enableScrollWheelZoom(); //開啟鼠標(biāo)滾輪控制縮放
bm.addControl(new BMap.NavigationControl()); //地圖平移縮放控件
bm.addControl(new BMap.ScaleControl()); //比例尺控件
bm.addControl(new BMap.OverviewMapControl()); //縮略地圖控件
bm.addControl(new BMap.MapTypeControl()); //地圖類型控件
var myDis = new BMapLib.DistanceTool(bm);
//添加谷歌marker和label
for (var i = 0; i < data.data.length; ) {
_point = wgs2bd(data.data[i][1], data.data[i][0])
point = new BMap.Point(_point[1], _point[0]);
var marker = new BMap.Marker(point);
bm.addOverlay(marker);
//var label = new BMap.Label("B",{offset:new BMap.Size(20,-10)});
//marker.setLabel(label); //添加百度label
bm.setCenter(point);
i+= 3;//隔3個點
}
</script>
</body>
</html>
加密函數(shù)使用的算法沒深研究,都是三角變換蚣驼,關(guān)鍵函數(shù)wgs2bd在correct.js中:
/*
pi: 圓周率忍燥。
a: 衛(wèi)星橢球坐標(biāo)投影到平面地圖坐標(biāo)系的投影因子。
ee: 橢球的偏心率隙姿。
x_pi: 圓周率轉(zhuǎn)換量。
transformLat(lat, lon): 轉(zhuǎn)換方法厂捞,比較復(fù)雜输玷,不必深究了队丝。輸入:橫縱坐標(biāo),輸出:轉(zhuǎn)換后的橫坐標(biāo)欲鹏。
transformLon(lat, lon): 轉(zhuǎn)換方法机久,同樣復(fù)雜,自行腦補(bǔ)吧赔嚎。輸入:橫縱坐標(biāo)膘盖,輸出:轉(zhuǎn)換后的縱坐標(biāo)。
wgs2gcj(lat, lon): WGS坐標(biāo)轉(zhuǎn)換為GCJ坐標(biāo)尤误。
gcj2bd(lat, lon): GCJ坐標(biāo)轉(zhuǎn)換為百度坐標(biāo)侠畔。
*/
var pi = 3.14159265358979324;
var a = 6378245.0;
var ee = 0.00669342162296594323;
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
function wgs2bd(lat, lon) {
_wgs2gcj = wgs2gcj(lat, lon);
_gcj2bd = gcj2bd(_wgs2gcj[0], _wgs2gcj[1]);
return _gcj2bd;
}
function gcj2bd(lat, lon) {
x = lon, y = lat;
z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
bd_lon = z * Math.cos(theta) + 0.0065;
bd_lat = z * Math.sin(theta) + 0.006;
return [ bd_lat, bd_lon ];
}
function bd2gcj(lat, lon) {
x = lon - 0.0065, y = lat - 0.006;
z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
gg_lon = z * Math.cos(theta);
gg_lat = z * Math.sin(theta);
return [ gg_lat, gg_lon ];
}
function wgs2gcj(lat, lon) {
dLat = transformLat(lon - 105.0, lat - 35.0);
dLon = transformLon(lon - 105.0, lat - 35.0);
radLat = lat / 180.0 * pi;
magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
mgLat = lat + dLat;
mgLon = lon + dLon;
return [ mgLat, mgLon ];
}
function transformLat(lat, lon) {
ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.sqrt(Math.abs(lat));
ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lon * pi) + 40.0 * Math.sin(lon / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lon / 12.0 * pi) + 320 * Math.sin(lon * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
function transformLon(lat, lon) {
ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.sqrt(Math.abs(lat));
ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * 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 += (150.0 * Math.sin(lat / 12.0 * pi) + 300.0 * Math.sin(lat / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
最終定位點顯示到地圖上基本正確,通過與百度地圖函數(shù)返回的精度對比损晤,本地轉(zhuǎn)換函數(shù)經(jīng)緯度誤差也在千分之一以下
定位效果截圖:
![Uploading image_743578.png . . .]