GISer梳理的我國常用的坐標系及相關知識

參考鏈接:聊聊GIS中那些坐標系百度坐標(BD09)、國測局坐標(火星坐標,GCJ02)、和WGS84坐標系互轉

前言:GIS跟幾何關系十分密切,能有豐富的空間想象能力,將有助你更好的理解接下來的知識~

一、經緯度和地理坐標系(GCS)

1、地球

  • 為了能讓地球出現在數學家的公式里,我們曾經走過了2個階段:用平靜的海面描述地球——用虛擬的旋轉橢球面描述地球表面。
  • “假設地球表面都是水,當海平面風平浪靜沒有波瀾起伏時,這個面就是大地水準面。”
  • 注意區分橢球面和旋轉橢球面這兩個數學概念,在GCS中都是旋轉橢球面
  • 旋轉橢球面的標準方程:(x2+y2)/a2+z2/b2=1
  • 由此我們可以下定義,GIS坐標系中的橢球,如果加上高程系,在其內涵上就是GCS(地理坐標系統)。其度量單位就是度分秒。

2、參心坐標系、地心坐標系

  • 物體均有其質心,處處密度相等的物體的質心在其幾何中心
  • 由地球的唯一性和客觀存在,以地球質心為旋轉橢球面的中心的坐標系,叫地心坐標系(協議地球坐標系)
  • GPS中的坐標系叫瞬時地球坐標系
  • 人為的把地球的質心“移走”,將局部的表面“貼到”該國的國土,使之高程誤差盡量減小到最小。就出現了所謂的“參心坐標系”。即橢球中心不在地球質心的坐標系。
  • 我國常用的參心系及對應橢球

北京54坐標系:克拉索夫斯基橢球體
西安80坐標系:IAG75橢球體

  • 我國常用的地心系及對應橢球:

WGS84坐標系:WGS84橢球體(GPS星歷的坐標系,全球統一使用,最新版于2002年修正)
CGCS2000坐標系:CGCS2000橢球體(事實上,CGCS2000橢球和WGS84橢球極為相似,偏差僅有0.11mm,完全可以兼容使用)

3、我國常見GCS

此處不介紹具體來歷,需要了解的童鞋自行百度,Google

3.1北京54坐標系(參心)
  • 橢球體:Krasovsky橢球(克拉索夫斯基橢球)
  • 極半徑b=6 356 863.0187730473 m
  • 赤道半徑a=6 378 245m
  • 扁率=1/298.3
  • 高程系:56黃海系
3.2西安80坐標系(參心)
  • 橢球體:IAG橢球
  • 極半徑b=6 356 755m
  • 赤道半徑a=6 378 140m
  • 扁率=1/298.25722101
  • 高程系:85黃海系
  • 大地原點設在我國中部的陜西省涇陽縣永樂鎮
3.3WGS84坐標系(地心)
  • 解決GPS定位而產生的全球統一的一個坐標系
  • 橢球體:WGS84橢球
  • 極半徑b=6 356 752.314 245 179 5m
  • 赤道半徑a=6 378 137 m
  • 扁率=1/298.257223563
  • 高程系:根據國家需求定
3.4CGCS2000坐標系(地心)
  • 全球地心坐標系在我國的具體體現
  • 橢球體:CGCS2000坐標系
  • 極半徑b=6 356 752.314 140 355 8m
  • 赤道半徑a=6 378 137m
  • 扁率=1/298.257222101
  • 高程系:85黃海系

【注】CGCS2000的定義與WGS84實質一樣。采用的參考橢球非常接近。扁率差異引起橢球面上的緯度和高度變化最大達0.1mm。當前測量精度范圍內,可以忽略這點差異。可以說兩者相容至cm級水平

總結表(最后一行即EPSG).png

EPSG對世界的每一個地方都制定了地圖,但是由于座標系不同,所以地圖也各不相同。
所有的EPSG均可查到的神奇網站~~https://epsg.io/

二、平面坐標和投影坐標系(PCS)

1、提出問題

  • 如何用經緯度表達一塊地的面積?
  • 如何建立一個新的坐標系使得地圖分析、空間分析得以定量計算?

2、什么是投影

  • 光線打到物體上,使得物體產生的陰影形狀,就叫它的投影
  • 地圖:把投影的平面改為曲面,產生了不同的投影,比如投射到一個圓錐面上,一個圓柱面上,一個平面上...等等
  • PCS是基于存在的GCS的。即:PCS=GCS+投影方式

3、我國常用的投影方式

  • 高斯克呂格(Gauss Kruger)投影=橫軸墨卡托(Transverse Mercator)投影
  • 墨卡托(Mercator)投影
  • 通用橫軸墨卡托(UTM)投影
  • Lambert投影
  • Albers投影
  • Web Mercator(網絡墨卡托)投影
3.1高斯克呂格投影/橫軸墨卡托投影
  • 投影面是橢圓柱面
  • 假設橢圓柱躺著,和地軸垂直,而且投影面與之相切,就是橫軸墨卡托了
  • 等角/橫/切橢圓柱/投影
  • 投影合適用于導航
  • 適用比例尺:1:2.5萬--1:100萬等使用6度分帶法;1:5000--1:10000使用3度分帶法
高斯克呂格投影/橫軸墨卡托投影.png

a、中央那條黑線就是投影中心線,與橢圓柱面相切
b、這條線逢360°的因數就可以取,一般多用3度帶(120個)、6度帶(60個)

c、Y方向(赤道方向)前需要加投影帶號

3.2墨卡托投影
  • 正軸等角切/割圓柱投影
  • 高斯克呂格的圓柱面豎起來
3.3通用橫軸墨卡托投影(UTM投影)
  • 橫軸等角割圓柱投影
  • UTM投影=0.9996高斯投影
  • 高斯克呂格的投影面是與橢球面相切的,這貨與橢球面相割
  • 大地測量和地形測量的投影基礎
  • 我國各種遙感影像的常用投影
3.4Lambert投影(蘭伯特投影)
  • 我國地形圖常用投影,比如1:400萬基礎數據
  • 自定義投影
  • 等角圓錐投影
  • 圓錐的方向和地軸的方向:正軸、橫軸、斜軸
Lambert投影.png
3.5Albers投影(阿伯斯投影)
  • 正軸等積割圓錐投影
  • 我國各省市的投影
  • 與Lambert投影的區別就在前者是等角,后者是等積
3.6Web墨卡托(WebMercator投影)
  • 由Google提出的、為了自家GoogleMap而專門定義的一種投影,屬于墨卡托投影
  • 經常被百度地圖等網絡地圖采用

三、GCS與PCS相互轉化(三參數、七參數)(包含SuperMap iDesktop轉換)

1、GCS轉GCS

  • 進行平移、旋轉、縮放三步,可以無序進行
左為平移,右為旋轉.png

1.1利用SuperMap iDesktop轉換(WGS84轉西安80)

a、打開某數據源,其中具有地理坐標系為WGS84的數據集


具有地理坐標系為WGS84的數據集.png

b、重設坐標系信息


重設坐標系.png

c、重新打開數據集即可查看
西安80坐標系.png

d、相關坐標系參數可在重設彈窗中查看,WGS84轉西安80,是屬于7參數轉換(地心轉參心),在SuperMap iDesktop中是默認的,也可根據數據情況來進行坐標系參數的修改

2、GCS進行投影

  • 重設投影坐標系即可
  • 如果所需投影系沒有自己需要的GCS,就新建一個

3、PCS轉PCS(重投影)

  • 三參數即可

4、根據ArcGIS總結如下(網扒圖。。)

坐標系轉換.png

四、火星坐標系

  • 火星坐標這個東西很常見,出現在互聯網地圖上。例如百度、騰訊、谷歌等地圖。
  • 出于保密等政治因素,地圖的GCS坐標值,會被一種特殊的數學函數加密一次,會偏離真實坐標數百米的距離,但是反饋到用戶端的卻是正確的位置信息(也就是說你拿到GCS坐標也沒用,拿GPS到實地跑跟拿著地圖定位,可能會偏出幾十米甚至一百米的距離)。

1、火星坐標 (GCJ-02)也叫國測局坐標系

  • 中國標準,從國行移動設備中定位獲取的坐標數據使用這個坐標系
  • 國家規定: 國內出版的各種地圖系統(包括電子形式),必須至少采用GCJ-02對地理位置進行首次加密。

2、百度坐標 (BD-09)

  • 百度標準,百度 SDK,百度地圖,Geocoding 使用
  • 百度又在火星坐標上來個二次加密

3、coordtransform 坐標轉換

3.1安裝(install)
npm install coordtransform
3.2示例用法(Example&Usage)

3.2.1 NodeJs用法

//國測局坐標(火星坐標,比如高德地圖在用),百度坐標,wgs84坐標(谷歌國外以及絕大部分國外在線地圖使用的坐標)
var coordtransform=require('coordtransform');
//百度經緯度坐標轉國測局坐標
var bd09togcj02=coordtransform.bd09togcj02(116.404, 39.915);
//國測局坐標轉百度經緯度坐標
var gcj02tobd09=coordtransform.gcj02tobd09(116.404, 39.915);
//wgs84轉國測局坐標
var wgs84togcj02=coordtransform.wgs84togcj02(116.404, 39.915);
//國測局坐標轉wgs84坐標
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 ]

3.2.2 瀏覽器用法
直接引用目錄內的index.js,會有一個coordtransform的全局對象暴露出來,也支持用AMD加載器加載

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>coordTransform</title>
</head>
<body>
<h1>請按F12打開控制臺查看結果</h1>
<script src="index.js"></script>
<script>
    //國測局坐標(火星坐標,比如高德地圖在用),百度坐標,wgs84坐標(谷歌國外以及絕大部分國外在線地圖使用的坐標)
    //百度經緯度坐標轉國測局坐標
    var bd09togcj02 = coordtransform.bd09togcj02(116.404, 39.915);
    //國測局坐標轉百度經緯度坐標
    var gcj02tobd09 = coordtransform.gcj02tobd09(116.404, 39.915);
    //wgs84轉國測局坐標
    var wgs84togcj02 = coordtransform.wgs84togcj02(116.404, 39.915);
    //國測局坐標轉wgs84坐標
    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 ]
</script>
</body>
</html>

五、JavaScript封裝方法轉換坐標

【注】參數設置正常即可

/**
 * Created by Wandergis on 2015/7/8.
 * 提供了百度坐標(BD09)、國測局坐標(火星坐標,GCJ02)、和WGS84坐標系之間的轉換
 */

//定義一些常量
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
var PI = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;

/**
 * 百度坐標系 (BD-09) 與 火星坐標系 (GCJ-02)的轉換
 * 即 百度 轉 谷歌、高德
 * @param bd_lon
 * @param bd_lat
 * @returns {*[]}
 */
function bd09togcj02(bd_lon, bd_lat) {
  var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  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]
}

/**
 * 火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 的轉換
 * 即谷歌、高德 轉 百度
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function gcj02tobd09(lng, lat) {
  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轉GCj02
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function wgs84togcj02(lng, lat) {
  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 轉換為 WGS84
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function gcj02towgs84(lng, lat) {
  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);
    mglat = lat + dlat;
    mglng = lng + dlng;
    return [lng * 2 - mglng, lat * 2 - mglat]
  }
}

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
}

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
 * @returns {boolean}
 */
function out_of_china(lng, lat) {
  return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容