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就是当地的中央子午线。