GIS&LBSCesiumSuperMap

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

2018-08-28  本文已影响72人  alanwhy

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

前言:GIS跟几何关系十分密切,能有丰富的空间想象能力,将有助你更好的理解接下来的知识~

一、经纬度和地理坐标系(GCS)

1、地球

2、参心坐标系、地心坐标系

北京54坐标系:克拉索夫斯基椭球体
西安80坐标系:IAG75椭球体

WGS84坐标系:WGS84椭球体(GPS星历的坐标系,全球统一使用,最新版于2002年修正)
CGCS2000坐标系:CGCS2000椭球体(事实上,CGCS2000椭球和WGS84椭球极为相似,偏差仅有0.11mm,完全可以兼容使用)

3、我国常见GCS

此处不介绍具体来历,需要了解的童鞋自行百度,Google

3.1北京54坐标系(参心)
3.2西安80坐标系(参心)
3.3WGS84坐标系(地心)
3.4CGCS2000坐标系(地心)

【注】CGCS2000的定义与WGS84实质一样。采用的参考椭球非常接近。扁率差异引起椭球面上的纬度和高度变化最大达0.1mm。当前测量精度范围内,可以忽略这点差异。可以说两者相容至cm级水平

总结表(最后一行即EPSG).png
EPSG对世界的每一个地方都制定了地图,但是由于座标系不同,所以地图也各不相同。
所有的EPSG均可查到的神奇网站~~https://epsg.io/

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

1、提出问题

2、什么是投影

3、我国常用的投影方式

3.1高斯克吕格投影/横轴墨卡托投影
高斯克吕格投影/横轴墨卡托投影.png

a、中央那条黑线就是投影中心线,与椭圆柱面相切
b、这条线逢360°的因数就可以取,一般多用3度带(120个)、6度带(60个)

c、Y方向(赤道方向)前需要加投影带号

3.2墨卡托投影
3.3通用横轴墨卡托投影(UTM投影)
3.4Lambert投影(兰伯特投影)
Lambert投影.png
3.5Albers投影(阿伯斯投影)
3.6Web墨卡托(WebMercator投影)

三、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进行投影

3、PCS转PCS(重投影)

4、根据ArcGIS总结如下(网扒图。。)

坐标系转换.png

四、火星坐标系

1、火星坐标 (GCJ-02)也叫国测局坐标系

2、百度坐标 (BD-09)

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;
    }
};
上一篇 下一篇

猜你喜欢

热点阅读