GIS - 常用web坐標(biāo)轉(zhuǎn)換(百度 國測 WGS84)

提供了百度坐標(biāo)(BD09)速和、國測局坐標(biāo)(火星坐標(biāo)崔列,GCJ02)腊满、和WGS84坐標(biāo)系之間的轉(zhuǎn)換

坐標(biāo)系說明

目前國內(nèi)主要有以下三種坐標(biāo)系:

  1. WGS84:為一種大地坐標(biāo)系钢拧,也是目前廣泛使用的GPS全球衛(wèi)星定位系統(tǒng)使用的坐標(biāo)系雄妥;
  2. GCJ02:表示經(jīng)過國測局加密的坐標(biāo)最蕾;
  3. BD09:為百度坐標(biāo)系,其中bd09ll表示百度經(jīng)緯度坐標(biāo)老厌,bd09mc表示百度墨卡托米制坐標(biāo)瘟则;

當(dāng)前互聯(lián)網(wǎng)地圖的坐標(biāo)系現(xiàn)狀

地球坐標(biāo) (WGS84)
  • 國際標(biāo)準(zhǔn),從專業(yè)GPS 設(shè)備中取出的數(shù)據(jù)的坐標(biāo)系
  • 國際地圖提供商使用的坐標(biāo)系
火星坐標(biāo) (GCJ-02)也叫國測局坐標(biāo)系
  • 中國標(biāo)準(zhǔn)枝秤,從國行移動(dòng)設(shè)備中定位獲取的坐標(biāo)數(shù)據(jù)使用這個(gè)坐標(biāo)系
  • 國家規(guī)定: 國內(nèi)出版的各種地圖系統(tǒng)(包括電子形式)醋拧,必須至少采用GCJ-02對地理位置進(jìn)行首次加密。
百度坐標(biāo) (BD-09)
  • 百度標(biāo)準(zhǔn)淀弹,百度 SDK趁仙,百度地圖,Geocoding 使用(本來就亂了垦页,百度又在火星坐標(biāo)上來個(gè)二次加密)
開發(fā)過程需要注意的事

從設(shè)備獲取經(jīng)緯度(GPS)坐標(biāo)

如果使用的是百度sdk那么可以獲得百度坐標(biāo)(bd09)或者火星坐標(biāo)(GCJ02),默認(rèn)是bd09    
如果使用的是ios的原生定位庫雀费,那么獲得的坐標(biāo)是WGS84
如果使用的是高德sdk,那么獲取的坐標(biāo)是GCJ02
互聯(lián)網(wǎng)在線地圖使用的坐標(biāo)系
火星坐標(biāo)系:
        iOS 地圖(其實(shí)是高德)
        Gogole地圖
        搜搜、阿里云盏袄、高德地圖
百度坐標(biāo)系:
        當(dāng)然只有百度地圖
WGS84坐標(biāo)系:
        國際標(biāo)準(zhǔn),谷歌國外地圖薄啥、osm地圖等國外的地圖一般都是這個(gè)
舉個(gè)栗子

筆者所在的公司app使用的是百度的sdk,需要對定位坐標(biāo)做web可視化效果,百度地圖提供的js api滿足不了需求垄惧,選用leaflet來做可視化,這里要說到百度地圖了到逊,它使用的坐標(biāo)系和切圖的原點(diǎn)都不一致,并且其加偏還是非線性的觉壶,因此無法利用常用的加載方法去加載脑题,放棄使用它的底圖铜靶,選用了符合標(biāo)準(zhǔn)的高德底圖,高德底圖使用的是國測局坐標(biāo)也就是GCJ02坐標(biāo)系,如果簡單的將app獲取的經(jīng)緯度疊加上去已艰,就有可能你本來在百度大廈的位置就顯示在西二旗地鐵站了甚至更遠(yuǎn),因此需要將bd09轉(zhuǎn)成gcj02坐標(biāo)系哩掺,這個(gè)時(shí)候這個(gè)庫就有了用武之地,對點(diǎn)批量轉(zhuǎn)換再加載到底圖上疮丛,就可以讓點(diǎn)顯示在本應(yīng)該出現(xiàn)的位置幔嫂。

另外如果你拿到了一些WGS84的坐標(biāo),想加載到各種底圖上就可以根據(jù)這個(gè)庫在底圖坐標(biāo)系和你的數(shù)據(jù)坐標(biāo)系之間進(jìn)行轉(zhuǎn)換誊薄。希望對大家有用吧履恩。

coordtransform 坐標(biāo)轉(zhuǎn)換

一個(gè)提供了百度坐標(biāo)(BD09)、國測局坐標(biāo)(火星坐標(biāo)呢蔫,GCJ02)切心、和WGS84坐標(biāo)系之間的轉(zhuǎn)換的工具模塊(另外還提供了python版本的代碼https://github.com/wandergis/coordTransform_py

支持node、瀏覽器(AMD方式和直接引用方式)
GitHub地址:https://github.com/wandergis/coordtransform
npm地址:https://www.npmjs.com/package/coordtransform
項(xiàng)目主頁:http://wandergis.github.io/coordtransform/

/**
 * Created by Wandergis on 2015/7/8.
 * 提供了百度坐標(biāo)(BD09)片吊、國測局坐標(biāo)(火星坐標(biāo)绽昏,GCJ02)、和WGS84坐標(biāo)系之間的轉(zhuǎn)換
 */
//UMD魔法代碼
// if the module has no dependencies, the above pattern can be simplified to
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.coordtransform = factory();
  }
}(this, function () {
  //定義一些常量
  var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  var PI = 3.1415926535897932384626;
  var a = 6378245.0;
  var ee = 0.00669342162296594323;
  /**
   * 百度坐標(biāo)系 (BD-09) 與 火星坐標(biāo)系 (GCJ-02)的轉(zhuǎn)換
   * 即 百度 轉(zhuǎn) 谷歌俏脊、高德
   * @param bd_lon
   * @param bd_lat
   * @returns {*[]}
   */
  var bd09togcj02 = function bd09togcj02(bd_lon, bd_lat) {
    var bd_lon = +bd_lon;
    var bd_lat = +bd_lat;
    var x = bd_lon - 0.0065;
    var y = bd_lat - 0.006;
    var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
    var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
    var gg_lng = z * Math.cos(theta);
    var gg_lat = z * Math.sin(theta);
    return [gg_lng, gg_lat]
  };

  /**
   * 火星坐標(biāo)系 (GCJ-02) 與百度坐標(biāo)系 (BD-09) 的轉(zhuǎn)換
   * 即谷歌全谤、高德 轉(zhuǎn) 百度
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var gcj02tobd09 = function gcj02tobd09(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
    var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
    var bd_lng = z * Math.cos(theta) + 0.0065;
    var bd_lat = z * Math.sin(theta) + 0.006;
    return [bd_lng, bd_lat]
  };

  /**
   * WGS84轉(zhuǎn)GCj02
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var wgs84togcj02 = function wgs84togcj02(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    if (out_of_china(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);
      var mglat = lat + dlat;
      var mglng = lng + dlng;
      return [mglng, mglat]
    }
  };

  /**
   * GCJ02 轉(zhuǎn)換為 WGS84
   * @param lng
   * @param lat
   * @returns {*[]}
   */
  var gcj02towgs84 = function gcj02towgs84(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    if (out_of_china(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);
      var mglat = lat + dlat;
      var mglng = lng + dlng;
      return [lng * 2 - mglng, lat * 2 - mglat]
    }
  };

  var transformlat = function transformlat(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    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
  };

  var transformlng = function transformlng(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    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
  };

  /**
   * 判斷是否在國內(nèi),不在國內(nèi)則不做偏移
   * @param lng
   * @param lat
   * @returns {boolean}
   */
  var out_of_china = function out_of_china(lng, lat) {
    var lat = +lat;
    var lng = +lng;
    // 緯度3.86~53.55,經(jīng)度73.66~135.05 
    return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
  };

  return {
    bd09togcj02: bd09togcj02,
    gcj02tobd09: gcj02tobd09,
    wgs84togcj02: wgs84togcj02,
    gcj02towgs84: gcj02towgs84
  }
}));
  • Usage
es (22 sloc)  982 Bytes
/**
 * Created by wandergis on 15/11/17.
 */
//國測局坐標(biāo)(火星坐標(biāo),比如高德地圖在用),百度坐標(biāo),wgs84坐標(biāo)(谷歌國外以及絕大部分國外在線地圖使用的坐標(biāo))
var coordtransform = require('../index');
//百度經(jīng)緯度坐標(biāo)轉(zhuǎn)國測局坐標(biāo)
var bd09togcj02 = coordtransform.bd09togcj02(116.404, 39.915);
//國測局坐標(biāo)轉(zhuǎn)百度經(jīng)緯度坐標(biāo)
var gcj02tobd09 = coordtransform.gcj02tobd09(116.404, 39.915);
//wgs84轉(zhuǎn)國測局坐標(biāo)
var wgs84togcj02 = coordtransform.wgs84togcj02(116.404, 39.915);
//國測局坐標(biāo)轉(zhuǎn)wgs84坐標(biāo)
var gcj02towgs84 = coordtransform.gcj02towgs84(116.404, 39.915);
console.log(bd09togcj02);
console.log(gcj02tobd09);
console.log(wgs84togcj02);
console.log(gcj02towgs84);
//result
//bd09togcj02:   [ 116.39762729119315, 39.90865673957631 ]
//gcj02tobd09:   [ 116.41036949371029, 39.92133699351021 ]
//wgs84togcj02:  [ 116.41024449916938, 39.91640428150164 ]
//gcj02towgs84:  [ 116.39775550083061, 39.91359571849836 ]

github上開源的web坐標(biāo)系轉(zhuǎn)換工具可參考gcoord

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爷贫,一起剝皮案震驚了整個(gè)濱河市认然,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漫萄,老刑警劉巖卷员,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腾务,居然都是意外死亡毕骡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門岩瘦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來未巫,“玉大人,你說我怎么就攤上這事担钮〕髟” “怎么了尤仍?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵箫津,是天一觀的道長。 經(jīng)常有香客問我,道長苏遥,這世上最難降的妖魔是什么饼拍? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮田炭,結(jié)果婚禮上师抄,老公的妹妹穿的比我還像新娘。我一直安慰自己叨吮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布茶鉴。 她就那樣靜靜地躺著景用,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伞插。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天舀瓢,我揣著相機(jī)與錄音耗美,去河邊找鬼。 笑死幽歼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的甸私。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诬烹,長吁一口氣:“原來是場噩夢啊……” “哼弃鸦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唬格,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汰聋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烹困,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年拟蜻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枯饿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屈张,死狀恐怖袱巨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愉老,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布嫉入,位于F島的核電站,受9級特大地震影響咒林,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜澎粟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一欢瞪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遣鼓,春花似錦、人聲如沸骑祟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抒巢。三九已至,卻和暖如春蛉谜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背型诚。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留也搓,地道東北人涵紊。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像摸柄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子嗦玖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容