美文网首页GIS&LBSCesiumSuperMap
GISer梳理的我国常用的坐标系及相关知识

GISer梳理的我国常用的坐标系及相关知识

作者: alanwhy | 来源:发表于2018-08-28 00:04 被阅读72次

参考链接:
https://www.cnblogs.com/onsummer/p/7451128.html
https://cnodejs.org/topic/564c0a27e4766d487f6fe38d

前言: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封装方法转换坐标

【注】参数设置正常即可

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;
        var ee = 0.00669342162296594323;
        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 new TYLngLat(wgsLon, wgsLat);

        var d = this.delta(wgsLat, wgsLon);
        return new TYLngLat(wgsLon + d.lon, wgsLat + d.lat);
    },
    //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 new TYLngLat(gcjLon - d.lon, gcjLat - d.lat);
    },
    //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 new TYLngLat(wgsLon, wgsLat);
    },
    //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 };
    },
    distance: function (latA, logA, latB, logB) {
        var earthR = 6371000;
        var x = Math.cos(latA * Math.PI / 180) * Math.cos(latB * Math.PI / 180) * Math.cos((logA - logB) * Math.PI / 180);
        var y = Math.sin(latA * Math.PI / 180) * Math.sin(latB * Math.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;
    }
};

相关文章

网友评论

    本文标题:GISer梳理的我国常用的坐标系及相关知识

    本文链接:https://www.haomeiwen.com/subject/tzdxwftx.html