let CoordinateTranslate = (function () {
|
var _ = function () {
|
this.PI = 3.141592653589793238
|
this.a = 6378137.0
|
this.b = 6356752.3142
|
this.f = (this.a - this.b) / this.a
|
this.e_sq = this.f * (2.0 - this.f)
|
this.ee = 0.00669437999013
|
this.WGSF = 1 / 298.257223563
|
this.WGSe2 = this.WGSF * (2 - this.WGSF)
|
this.WGSa = 6378137.00000
|
this.EPSILON = 1.0e-12
|
}
|
_.prototype.CalculateCoordinates = function (point, azimuth, elevation, distance) {
|
var vertical_height = distance * Math.sin(2 * this.PI / 360 * elevation)//垂直高度
|
var horizontal_distance = distance * Math.cos(2 * this.PI / 360 * elevation)//水平距离
|
if (azimuth > 360) azimuth = azimuth % 360
|
if (azimuth < 0) azimuth = 360 + (azimuth % 360)
|
|
var point1 = this.lonLat2WebMercator(point)
|
var lnglat = null
|
|
var x_length, y_length
|
if (azimuth <= 90) {//第四象限
|
x_length = horizontal_distance * Math.cos(2 * this.PI / 360 * azimuth)
|
y_length = horizontal_distance * Math.sin(2 * this.PI / 360 * azimuth)
|
lnglat = {
|
x: point1.x + x_length,
|
y: point1.y - y_length
|
}
|
} else if (azimuth > 90 && azimuth <= 180) {//第三象限
|
x_length = horizontal_distance * Math.sin(2 * this.PI / 360 * (azimuth - 90))
|
y_length = horizontal_distance * Math.cos(2 * this.PI / 360 * (azimuth - 90))
|
lnglat = {
|
x: point1.x - x_length,
|
y: point1.y - y_length
|
}
|
} else if (azimuth > 180 && azimuth <= 270) {//第二象限
|
x_length = horizontal_distance * Math.cos(2 * this.PI / 360 * (azimuth - 180))
|
y_length = horizontal_distance * Math.sin(2 * this.PI / 360 * (azimuth - 180))
|
lnglat = {
|
x: point1.x - x_length,
|
y: point1.y + y_length
|
}
|
} else {//第一象限
|
x_length = horizontal_distance * Math.sin(2 * this.PI / 360 * (azimuth - 270))
|
y_length = horizontal_distance * Math.cos(2 * this.PI / 360 * (azimuth - 270))
|
lnglat = {
|
x: point1.x + x_length,
|
y: point1.y + y_length
|
}
|
}
|
lnglat = this.webMercator2LonLat(lnglat)
|
return {
|
lng: lnglat.x,
|
lat: lnglat.y,
|
height: vertical_height
|
}
|
}
|
/*
|
*经纬度转Web墨卡托
|
*@lonLat 经纬度
|
*/
|
_.prototype.lonLat2WebMercator = function (lonLat) {
|
let x = lonLat.x * this.a / 180
|
let y = Math.log(Math.tan((90 + lonLat.y) * this.PI / 360)) / (this.PI / 180)
|
y = y * this.a / 180
|
return {
|
x: x,
|
y: y
|
}
|
}
|
|
/*
|
*Web墨卡托转经纬度
|
*@mercator 平面坐标
|
*/
|
_.prototype.webMercator2LonLat = function (mercator) {
|
let x = mercator.x / this.a * 180
|
let y = mercator.y / this.a * 180
|
y = 180 / this.PI * (2 * (Math.exp(y * this.PI / 180)) - this.PI / 2)
|
return {
|
x: x,
|
y: y
|
}
|
}
|
|
_.prototype.get_atan = function (z, y) {
|
let x
|
if (z == 0) {
|
x = this.PI / 2
|
} else {
|
if (y == 0) {
|
x = this.PI
|
} else {
|
x = Math.atan(Math.abs(y / z))
|
if ((y > 0) && (z < 0)) {
|
x = this.PI - x
|
} else if ((y < 0) && (z < 0)) {
|
x = this.PI + x
|
} else if ((y < 0) && (z > 0)) {
|
x = 2 * this.M_PI - x
|
}
|
}
|
}
|
return x
|
}
|
//WGS84转ECEF坐标系
|
_.prototype.ConvertLLAToXYZ = function (LLACoor) {
|
let lon = this.PI / 180 * LLACoor.longitude
|
let lat = this.PI / 180 * LLACoor.latitude
|
let H = LLACoor.altitude
|
let N0 = this.a / Math.sqrt(1.0 - this.ee * Math.sin(lat) * Math.sin(lat))
|
let x = (N0 + H) * Math.cos(lat) * Math.cos(lon)
|
let y = (N0 + H) * Math.cos(lat) * Math.sin(lon)
|
let z = (N0 * (1.0 - this.ee) + H) * Math.sin(lat)
|
return {
|
x: x,
|
y: y,
|
z: z
|
}
|
}
|
|
//ECEF坐标系转WGS84
|
_.prototype.ConvertXYZToLLA = function (XYZCoor) {
|
let longitude = this.get_atan(XYZCoor.x, XYZCoor.y)
|
if (longitude < 0) {
|
longitude = longitude + this.PI
|
}
|
let latitude = this.get_atan(Math.sqrt(XYZCoor.x * XYZCoor.x + XYZCoor.y * XYZCoor.y), XYZCoor.z)
|
|
let W = Math.sqrt(1 - this.WGSe2 * Math.sin(latitude) * Math.sin(latitude))
|
let N = this.WGSa / W
|
let B1
|
do {
|
B1 = latitude
|
W = Math.sqrt(1 - this.WGSe2 * Math.sin(B1) * Math.sin(B1))
|
N = this.WGSa / W
|
latitude = this.get_atan(Math.sqrt(XYZCoor.x * XYZCoor.x + XYZCoor.y * XYZCoor.y), (XYZCoor.z + N * this.WGSe2 * Math.sin(B1)))
|
}
|
while (Math.abs(latitude - B1) > this.EPSILON)
|
|
var altitude = Math.sqrt(XYZCoor.x * XYZCoor.x + XYZCoor.y * XYZCoor.y) / Math.cos(latitude) - this.WGSa / Math.sqrt(1 - this.WGSe2 * Math.sin(latitude) * Math.sin(latitude))
|
|
return {
|
longitude: longitude * 180 / this.PI,
|
latitude: latitude * 180 / this.PI,
|
altitude: altitude
|
}
|
}
|
/*北东天坐标系转WGS84
|
@ a A点坐标
|
@ p 相对参数,距离、方位角、仰角
|
*/
|
// 俯视角pitch -elevation
|
//航向角heading(yaw) -azimuth
|
_.prototype.enu_to_ecef = function (a, p) {
|
//距离
|
let distance = p.distance
|
//方位角
|
let azimuth = p.azimuth
|
//仰角
|
let elevation = p.elevation
|
|
let zUp = elevation >= 0 ? distance * Math.sin(this.PI / 180 * elevation) : (-1) * distance * Math.sin(this.PI / 180 * Math.abs(elevation))
|
|
let d = distance * Math.cos(this.PI / 180 * Math.abs(elevation))
|
let xEast
|
let yNorth
|
if (azimuth <= 90) {
|
xEast = d * Math.sin(this.PI / 180 * azimuth)
|
yNorth = d * Math.cos(this.PI / 180 * azimuth)
|
} else if (azimuth > 90 && azimuth < 180) {
|
xEast = d * Math.cos(this.PI / 180 * (azimuth - 90))
|
yNorth = (-1) * d * Math.sin(this.PI / 180 * (azimuth - 90))
|
} else if (azimuth > 180 && azimuth < 270) {
|
xEast = (-1) * d * Math.sin(this.PI / 180 * (azimuth - 180))
|
yNorth = (-1) * d * Math.cos(this.PI / 180 * (azimuth - 180))
|
} else {
|
xEast = (-1) * d * Math.sin(this.PI / 180 * (360 - azimuth))
|
yNorth = d * Math.cos(this.PI / 180 * (360 - azimuth))
|
}
|
|
let lamb = this.radians(a.latitude)
|
let phi = this.radians(a.longitude)
|
let h0 = a.altitude
|
|
let s = Math.sin(lamb)
|
let N = this.a / Math.sqrt(1.0 - this.e_sq * s * s)
|
|
let sin_lambda = Math.sin(lamb)
|
let cos_lambda = Math.cos(lamb)
|
|
let sin_phi = Math.sin(phi)
|
let cos_phi = Math.cos(phi)
|
|
let x0 = (h0 + N) * cos_lambda * cos_phi
|
let y0 = (h0 + N) * cos_lambda * sin_phi
|
let z0 = (h0 + (1 - this.e_sq) * N) * sin_lambda
|
|
let t = cos_lambda * zUp - sin_lambda * yNorth
|
|
let zd = sin_lambda * zUp + cos_lambda * yNorth
|
let xd = cos_phi * t - sin_phi * xEast
|
let yd = sin_phi * t + cos_phi * xEast
|
|
return this.ConvertXYZToLLA({
|
x: xd + x0,
|
y: yd + y0,
|
z: zd + z0
|
})
|
}
|
_.prototype.radians = function (degree) {
|
return this.PI / 180 * degree
|
}
|
return _
|
})()
|
|
window.ECEF = CoordinateTranslate
|