1. 程式人生 > >墨卡托坐標與LBS應用

墨卡托坐標與LBS應用

詳細 就是 最小 ron clear earth 效率 展開 return

今天了解到這邊的LBS應用,一般用的是墨卡托坐標。

也就是商品庫的商品入庫的時候,會根據輸入,使用百度地圖提供的一個API,來轉換成一個墨卡托坐標。

然後用戶流量過來的時候,會帶來歷史坐標,和當前坐標,這個時候,就可以和商品庫裏面的坐標來匹配,在某一個範圍內的匹配命中。

具體的墨卡托坐標的解釋,可以看這裏:

http://blog.csdn.net/mr_jianrong/article/details/72625811

墨卡托坐標以及 墨卡托坐標轉經緯度

Google Maps、Virtual Earth等網絡地理所使用的地圖投影,常被稱作Web Mercator或Spherical Mercator,它與常規墨卡托投影的主要區別就是把地球模擬為球體而非橢球體。建議先對地圖投影知識做一個基本的了解,《地圖投影為什麽》。
什麽是墨卡托投影? 墨卡托(Mercator)投影,又名“等角正軸圓柱投影”,荷蘭地圖學家墨卡托(Mercator)在1569年擬定,假設地球被圍在一個中空的圓柱裏,其赤道與圓柱相接觸,然後再假想地球中心有一盞燈,把球面上的圖形投影到圓柱體上,再把圓柱體展開,這就是一幅標準緯線為零度(即赤道)的“墨卡托投影”繪制出的世界地圖。從球到平面,有個轉換公式,這裏就不再羅列。 Google們為什麽選擇墨卡托投影? 墨卡托投影的“等角”特性,保證了對象的形狀的不變行,正方形的物體投影後不會變為長方形。“等角”也保證了方向和相互位置的正確性,因此在航海和航空中常常應用,而Google們在計算人們查詢地物的方向時不會出錯。 墨卡托投影的“圓柱”特性,保證了南北(緯線)和東西(經線)都是平行直線,並且相互垂直。而且經線間隔是相同的,緯線間隔從標準緯線(此處是赤道,也可能是其他緯線)向兩級逐漸增大。 但是,“等角”不可避免的帶來的面積的巨大變形,特別是兩極地區,明顯的如格陵蘭島比實際面積擴大了N倍。不過要是去兩極地區探險或科考的同誌們,一般有更詳細的資料,不會來查看網絡地圖的,這個不要緊。 為什麽是圓形球體,而非橢球體? 這說來簡單,僅僅是由於實現的方便,和計算上的簡單,精度理論上差別0.33%之內,特別是比例尺越大,地物更詳細的時候,差別基本可以忽略。

Web墨卡托投影坐標系:

  以整個世界範圍,赤道作為標準緯線,本初子午線作為中央經線,兩者交點為坐標原點,向東向北為正,向西向南為負。

  X軸:由於赤道半徑為6378137米,則赤道周長為2*PI*r = 20037508.3427892,因此X軸的取值範圍:[-20037508.3427892,20037508.3427892]。

  Y軸:由墨卡托投影的公式可知,同時上圖也有示意,當緯度φ接近兩極,即90°時,y值趨向於無窮。這是那些"懶惰的工程師"就把Y軸的取值範圍也限定在[-20037508.3427892,20037508.3427892]之間,搞個正方形。

  懶人的好處,眾所周知,事先切好靜態圖片,提高訪問效率雲雲。俺只是告訴你為什麽會是這樣子。因此在投影坐標系(米)下的範圍是:最小(-20037508.3427892, -20037508.3427892 )到最大 (20037508.3427892, 20037508.3427892)。

  對應的地理坐標系:

  按道理,先講地理坐標系才是,比如球體還是橢球體是地理坐標系的事情,和墨卡托投影本關聯不大。簡單來說,投影坐標系(PROJCS)是平面坐標系,以米為單位;而地理坐標系(GEOGCS)是橢球面坐標系,以經緯度為單位。具體可參考《坐標系、坐標參照系、坐標變換、投影變換》。

經度:這邊沒問題,可取全球範圍:[-180,180]。 緯度:上面已知,緯度不可能到達90°,懶人們為了正方形而取的-20037508.3427892,經過反計算,可得到緯度85.05112877980659。因此緯度取值範圍是[-85.05112877980659,85.05112877980659]。其余的地區怎麽辦?沒事,企鵝們不在乎。 因此,地理坐標系(經緯度)對應的範圍是:最小(-180,-85.05112877980659),最大(180, 85.05112877980659)。至於其中的Datum、坐標轉換等就不再多言。 如果想知道坐標怎麽計算的,請看全解析第2季《相關坐標計算》;更深入的和GIS相關的第3季《WKT形式表示》 墨卡托坐標轉經緯度 //經緯度轉墨卡托
public Vector2D lonLat2Mercator(Vector2D lonLat)
{
Vector2D mercator = new Vector2D();
double x = lonLat.X * 20037508.34 / 180;
double y = Math.Log(Math.Tan((90 + lonLat.Y) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.34 / 180;
mercator.X = x;
mercator.Y = y;
return mercator;
}
//墨卡托轉經緯度
public Vector2D Mercator2lonLat(Vector2D mercator)
{
Vector2D lonLat = new Vector2D();
double x = mercator.X / 20037508.34 * 180;
double y = mercator.Y / 20037508.34 * 180;
y = 180 / Math.PI * (2 * Math.Atan(Math.Exp(y * Math.PI / 180)) - Math.PI / 2);
lonLat.X = x;
lonLat.Y = y;
return lonLat;
}

墨卡托坐標與LBS應用