X、Y、H高程数据转换为经纬度应用到地图中

339 阅读4分钟

X、Y、H高程数据转换为经纬度应用到地图中

  • 高程数据以及预期结果
 高程数据接口返回数据 : [
     {
        x:  4093557.815,
        y:378743.188,
        h: 44543.111
    }
    ...
]
预期结果最终转换为:
[
    [109.66799517575076, 36.90031988239641],
    ...
    [经度, 纬度]
    ...
]

1. 高斯投影坐标转换正反算系统-Transf

const Transf = function (CentralMeridian, EastOffset, TuoqiuCanshu) {
    /* '说明: 用于初始化转换参数
    'TuoqiuCanshu  枚举类型,提供北京54、西安80和WGS84三个椭球参数
    'CentralMeridian 中央经线
    OriginLatitude 原点纬度,如果是标准的分幅,则该参数是0
    'EastOffset东偏移
    NorthOffset 北偏移
    */
    ///'基本变量定义
    let a;//'椭球体长半轴
    let b;// '椭球体短半轴
    let f; //'扁率
    let e;// '第一偏心率
    let e1; //'第二偏心率

    let FE;//'东偏移
    let FN;//'北偏移
    let L0;//'中央经度
    let W0;//'原点纬线
    let k0;//'比例因子

    let PI = 3.14159265358979;
    /*
     *  Canshu
     *  Beijing54 = 0
        Xian80 = 1
        WGS84 = 2
        CGCS2000 = 3
     *
    */
    if (TuoqiuCanshu == 0)//北京五四
    {
        a = 6378245;
        b = 6356863.0188;
    }
    if (TuoqiuCanshu == 1)// '西安八零
    {
        a = 6378140;
        b = 6356755.2882;
    }
    if (TuoqiuCanshu == 2)//'WGS84
    {
        a = 6378137;
        b = 6356752.3142;
    }
    if (TuoqiuCanshu == 3)//'CGCS2000
    {
        a = 6378137;
        b = 6356752.31414;
    }

    f = (a - b) / a;//扁率
    e = Math.sqrt(2 * f - Math.pow(f, 2));//'第一偏心率
    e1 = e / Math.sqrt(1 - Math.pow(e, 2));//'第二偏心率

    L0 = CentralMeridian;//中央经
    W0 = 0;//原点纬线
    k0 = 1;//'比例因子
    FE = EastOffset;//东偏移
    FN = 0;//北偏移
    /*
     * 输入参数分别是:经度、纬度
     */
    const JWgetGK = function (J, W) {
        //'给出经纬度坐标,转换为高克投影坐标

        let BR = (W - W0) * PI / 180;//纬度弧长
        let lo = (J - L0) * PI / 180; //经差弧度
        let N = a / Math.sqrt(1 - Math.pow((e * Math.sin(BR)), 2)) //卯酉圈曲率半径

        //求解参数s
        let B0;
        let B2;
        let B4;
        let B6;
        let B8;
        let C = Math.pow(a, 2) / b;
        B0 = 1 - 3 * Math.pow(e1, 2) / 4 + 45 * Math.pow(e1, 4) / 64 - 175 * Math.pow(e1, 6) / 256 + 11025 * Math.pow(e1, 8) / 16384;
        B2 = B0 - 1
        B4 = 15 / 32 * Math.pow(e1, 4) - 175 / 384 * Math.pow(e1, 6) + 3675 / 8192 * Math.pow(e1, 8);
        B6 = 0 - 35 / 96 * Math.pow(e1, 6) + 735 / 2048 * Math.pow(e1, 8);
        B8 = 315 / 1024 * Math.pow(e1, 8);
        let s = C * (B0 * BR + Math.sin(BR) * (B2 * Math.cos(BR) + B4 * Math.pow((Math.cos(BR)), 3) + B6 * Math.pow((Math.cos(BR)), 5) + B8 * Math.pow((Math.cos(BR)), 7)))

        let t = Math.tan(BR);
        let g = e1 * Math.cos(BR);

        let XR = s + Math.pow(lo, 2) / 2 * N * Math.sin(BR) * Math.cos(BR) + Math.pow(lo, 4) * N * Math.sin(BR) * Math.pow((Math.cos(BR)), 3) / 24 * (5 - Math.pow(t, 2) + 9 * Math.pow(g, 2) + 4 * Math.pow(g, 4)) + Math.pow(lo, 6) * N * Math.sin(BR) * Math.pow((Math.cos(BR)), 5) * (61 - 58 * Math.pow(t, 2) + Math.pow(t, 4)) / 720;
        let YR = lo * N * Math.cos(BR) + Math.pow(lo, 3) * N / 6 * Math.pow((Math.cos(BR)), 3) * (1 - Math.pow(t, 2) + Math.pow(g, 2)) + Math.pow(lo, 5) * N / 120 * Math.pow((Math.cos(BR)), 5) * (5 - 18 * Math.pow(t, 2) + Math.pow(t, 4) + 14 * Math.pow(g, 2) - 58 * Math.pow(g, 2) * Math.pow(t, 2));

        let resultx = YR + FE;
        let resulty = XR + FN;

        let GKresult = {
            'X': resultx,
            'Y': resulty,
        }
        return GKresult
    }
    /*
     * 输入参数分别为:X、Y
     */
    const GKgetJW = function (X, Y) {
        //'给出高克投影坐标,转换为经纬度坐标
        let El1 = (1 - Math.sqrt(1 - Math.pow(e, 2))) / (1 + Math.sqrt(1 - Math.pow(e, 2)));
        let Mf = (Y - FN) / k0;//真实坐标值
        let Q = Mf / (a * (1 - Math.pow(e, 2) / 4 - 3 * Math.pow(e, 4) / 64 - 5 * Math.pow(e, 6) / 256));//角度

        let Bf = Q + (3 * El1 / 2 - 27 * Math.pow(El1, 3) / 32) * Math.sin(2 * Q) + (21 * Math.pow(El1, 2) / 16 - 55 * Math.pow(El1, 4) / 32) * Math.sin(4 * Q) + (151 * Math.pow(El1, 3) / 96) * Math.sin(6 * Q) + 1097 / 512 * Math.pow(El1, 4) * Math.sin(8 * Q);
        let Rf = a * (1 - Math.pow(e, 2)) / Math.sqrt(Math.pow((1 - Math.pow((e * Math.sin(Bf)), 2)), 3));
        let Nf = a / Math.sqrt(1 - Math.pow((e * Math.sin(Bf)), 2));//卯酉圈曲率半径
        let Tf = Math.pow((Math.tan(Bf)), 2);
        let D = (X - FE) / (k0 * Nf);
        let Cf = Math.pow(e1, 2) * Math.pow((Math.cos(Bf)), 2);

        let B = Bf - Nf * Math.tan(Bf) / Rf * (Math.pow(D, 2) / 2 - (5 + 3 * Tf + 10 * Cf - 9 * Tf * Cf - 4 * Math.pow(Cf, 2) - 9 * Math.pow(e1, 2)) * Math.pow(D, 4) / 24 + (61 + 90 * Tf + 45 * Math.pow(Tf, 2) - 256 * Math.pow(e1, 2) - 3 * Math.pow(Cf, 2)) * Math.pow(D, 6) / 720);
        let L = CentralMeridian * PI / 180 + 1 / Math.cos(Bf) * (D - (1 + 2 * Tf + Cf) * Math.pow(D, 3) / 6 + (5 - 2 * Cf + 28 * Tf - 3 * Math.pow(Cf, 2) + 8 * Math.pow(e1, 2) + 24 * Math.pow(Tf, 2)) * Math.pow(D, 5) / 120);

        let Bangle = B * 180 / PI;
        let Langle = L * 180 / PI;

        let resultx = Langle;//RW * 180 / PI;
        let resulty = Bangle + W0;//RJ * 180 / PI;
        let JWresult = {
            'lon': resultx,
            'lat': resulty,
        }

        return JWresult
    }
    ///<summary>将度转换成为度分秒</summary>
    const formatDegree = function (value) {
        value = Math.abs(value);
        let v1 = Math.floor(value);//度
        let v2 = Math.floor((value - v1) * 60);//分
        let v3 = ((value - v1) * 3600 % 60).toFixed(3);//秒
        return v1 + '°' + v2 + '\′' + v3 + '″';
    };
    //度分秒转换成为度
    const DegreeConvertBack = function (value) {
        let du = parseFloat(value.split("°")[0]);
        let fen = parseFloat(value.split("°")[1].split(/′|'/)[0]);
        let miao = parseFloat(value.split("°")[1].split(/′|'/)[1].split(/″|"/)[0]);
        // 根据度数的正负情况进行计算
        let result = du + fen / 60 + miao / 3600;
        if (du < 0) {
            result = -result;
        }
        return result;
    };

    return {
        JWgetGK,
        GKgetJW,
        formatDegree,
        DegreeConvertBack
    }

}

export  default  Transf;

2. 使用示例

            const CentralMeridian = 111 // 中央经线-东经111度
            const EastOffset = 500000 // 东偏移量
            const TuoqiuCanshu = 3
            const {
                JWgetGK,
                GKgetJW,
                formatDegree,
                DegreeConvertBack
            } = Transf(CentralMeridian, EastOffset, TuoqiuCanshu);

           let JWpoint = GKgetJW(378743.188, 4093557.815 )
            
      
           console.log("高斯投影坐标转换正反算系统结果", JWpoint);

转换正反算系统结果: [[经度, 纬度],...] 拿到这些经纬度我们就可以应用到高德地图里,可以画线,标记点都可以使用这里给出的经纬度数据

3. 计算方法:

当地的经度除以3,求得的结果四舍五入。然后再乘以3就是当地的中央子午线。

4. 我国中央子午线

c50edcb47cf0ba37881bd2c73e26e480.png