Go 如何将东-北坐标转换为经纬度?
我需要使用Go将Go 如何将东-北坐标转换为经纬度?,go,gis,Go,Gis,我需要使用Go将Eastings和NorthingsOSGB36坐标转换为纬度和经度坐标。因此,我想知道是否有这样的软件包。从零开始写一篇文章似乎并不琐碎。我正在沙盒虚拟机中运行代码,因此代码必须是纯Go 输入: 北距-国家电网原点以北的距离(米) 东距-国家电网原点以东的距离(米) 例如: 348356,862582 输出(十进制度数-DDD): 纬度 经度 例如: 41.40338, 2.17403 你可以试试这个库,它是一个综合性的包装器 我也没有试过,但看起来应该可以 或者
Eastings
和Northings
OSGB36坐标转换为纬度和经度坐标。因此,我想知道是否有这样的软件包。从零开始写一篇文章似乎并不琐碎。我正在沙盒虚拟机中运行代码,因此代码必须是纯Go
输入:
- 北距-国家电网原点以北的距离(米)
- 东距-国家电网原点以东的距离(米)
348356,862582
输出(十进制度数-DDD):
- 纬度
- 经度
41.40338, 2.17403
你可以试试这个库,它是一个综合性的包装器
我也没有试过,但看起来应该可以
或者您可以移植代码下面的代码是从提供的javascript(©2005-2014)中非常简单地移植的。我只移植了OsGridToLatLong()
函数,但其他函数应该不会太难。此外,这会将所有值视为float64
。您可能希望将北距
和东距
视为int
package main
import (
"fmt"
"math"
)
const (
radToDeg = 180 / math.Pi
degToRad = math.Pi / 180
a = 6377563.396
b = 6356256.909 // Airy 1830 major & minor semi-axes
f0 = 0.9996012717 // NatGrid scale factor on central meridian
lat0 = 49 * degToRad
lon0 = -2 * degToRad // NatGrid true origin
n0 = -100000.0
e0 = 400000.0 // northing & easting of true origin, metres
e2 = 1 - (b*b)/(a*a) // eccentricity squared
n = (a - b) / (a + b)
n2 = n * n
n3 = n * n * n
)
func OsGridToLatLong(northing, easting float64) (float64, float64) {
lat := lat0
m := 0.0
for northing-n0-m >= 1e-5 { // until < 0.01mm
lat = (northing-n0-m)/(a*f0) + lat
ma := (1 + n + (5/4)*n2 + (5/4)*n3) * (lat - lat0)
mb := (3*n + 3*n*n + (21/8)*n3) * math.Sin(lat-lat0) * math.Cos(lat+lat0)
mc := ((15/8)*n2 + (15/8)*n3) * math.Sin(2*(lat-lat0)) * math.Cos(2*(lat+lat0))
md := (35 / 24) * n3 * math.Sin(3*(lat-lat0)) * math.Cos(3*(lat+lat0))
m = b * f0 * (ma - mb + mc - md) // meridional arc
}
cosLat := math.Cos(lat)
sinLat := math.Sin(lat)
nu := a * f0 / math.Sqrt(1-e2*sinLat*sinLat) // transverse radius of curvature
rho := a * f0 * (1 - e2) / math.Pow(1-e2*sinLat*sinLat, 1.5) // meridional radius of curvature
eta2 := nu/rho - 1
tanLat := math.Tan(lat)
tan2lat := tanLat * tanLat
tan4lat := tan2lat * tan2lat
tan6lat := tan4lat * tan2lat
secLat := 1 / cosLat
nu3 := nu * nu * nu
nu5 := nu3 * nu * nu
nu7 := nu5 * nu * nu
vii := tanLat / (2 * rho * nu)
viii := tanLat / (24 * rho * nu3) * (5 + 3*tan2lat + eta2 - 9*tan2lat*eta2)
ix := tanLat / (720 * rho * nu5) * (61 + 90*tan2lat + 45*tan4lat)
x := secLat / nu
xi := secLat / (6 * nu3) * (nu/rho + 2*tan2lat)
xii := secLat / (120 * nu5) * (5 + 28*tan2lat + 24*tan4lat)
xiia := secLat / (5040 * nu7) * (61 + 662*tan2lat + 1320*tan4lat + 720*tan6lat)
de := easting - e0
de2 := de * de
de3 := de2 * de
de4 := de2 * de2
de5 := de3 * de2
de6 := de4 * de2
de7 := de5 * de2
lat = lat - vii*de2 + viii*de4 - ix*de6
lon := lon0 + x*de - xi*de3 + xii*de5 - xiia*de7
return lat * radToDeg, lon * radToDeg
}
func main() {
lat, lon := OsGridToLatLong(348356.0, 862582.0)
fmt.Printf("Latitude: %fN\nLongitude: %fE\n", lat, lon)
}
主程序包
进口(
“fmt”
“数学”
)
常数(
radToDeg=180/数学π
degToRad=数学Pi/180
a=6377563.396
b=6356256.909//Airy 1830长轴和短半轴
f0=0.9996012717//NatGrid中央子午线比例因子
lat0=49*degToRad
lon0=-2*degToRad//NatGrid真实原点
n0=-100000.0
e0=400000.0//真实原点的北距和东距,米
e2=1-(b*b)/(a*a)//偏心率平方
n=(a-b)/(a+b)
n2=n*n
n3=n*n*n
)
func OsGridToLatLong(北行、东行浮动64)(浮动64、浮动64){
lat:=lat0
m:=0.0
对于北距-n0-m>=1e-5{//,直到<0.01mm
纬度=(北纬-n0-m)/(a*f0)+纬度
ma:=(1+n+(5/4)*n2+(5/4)*n3)*(纬度-纬度0)
mb:=(3*n+3*n*n+(21/8)*n3)*数学正弦(lat-lat0)*数学科斯(lat+lat0)
mc:=((15/8)*n2+(15/8)*n3)*数学Sin(2*(lat-lat0))*数学Cos(2*(lat+lat0))
md:=(35/24)*n3*数学Sin(3*(lat-lat0))*数学Cos(3*(lat+lat0))
m=b*f0*(ma-mb+mc-md)//子午弧
}
cosLat:=math.Cos(lat)
sinLat:=math.Sin(lat)
nu:=a*f0/math.Sqrt(1-e2*sinLat*sinLat)//横向曲率半径
rho:=a*f0*(1-e2)/math.Pow(1-e2*sinLat*sinLat,1.5)//子午曲率半径
eta2:=nu/rho-1
tanLat:=数学Tan(lat)
tan2lat:=tanLat*tanLat
tan4lat:=tan2lat*tan2lat
tan6lat:=tan4lat*tan2lat
secLat:=1/cosLat
nu3:=nu*nu*nu
nu5:=nu3*nu*nu
nu7:=nu5*nu*nu
vii:=tanLat/(2*rho*nu)
viii:=tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2)
ix:=tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat)
x:=秒/nu
席:= SECLAT /(6×NU3)*(NU/RHO + 2×TAN2LAT)
xii:=秒/(120*nu5)*(5+28*tan2lat+24*tan4lat)
xiia:=secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat)
de:=东距-e0
de2:=de*de
de3:=de2*de
de4:=de2*de2
de5:=de3*de2
de6:=de4*de2
de7:=de5*de2
lat=lat-vii*de2+viii*de4-ix*de6
lon:=lon0+x*de-xi*de3+xii*de5-xiia*de7
返回横向*纵向,纵向*纵向
}
func main(){
lat,lon:=OsGridToLatLong(348356.0862582.0)
fmt.Printf(“纬度:%fN\n长度:%fE\n”,纬度,经度)
}
产生:
纬度:52.833026N经度:4.871525E 这些是 原职: “军械测量局使用“OSGB-36”,基于地球表面的椭圆模型,这非常适合英国。GPS系统通常使用全球范围的“WGS-84”,基于椭圆模型,这是对整个地球的最佳近似。在格林威治,这两个模型相差约126米(它们在大西洋的某个地方重合;维基百科上有更多) 我不知道这是否是北距:348356,东距:862582的OSGB-36坐标的位置,但是上面的代码和,放在上面。(虽然地图上显示的坐标是WGS-84,而不是OSGB-36。更多细节请参阅。) 这段代码没有经过适当的测试(它产生与原始javascript代码相同的输出,但不能保证正确性),可能有可怕的错误,但它应该为您指出正确的方向(没有双关语)
嗨,我也有同样的问题。 我从python移植了我们的代码库。我们使用了Tobias Bieniek的库-()。它在github上是公开的 我没有找到好的、轻量级的东西。我只是在golang-上移植了这个库。它是纯go,只包含两种方法。你可以在存储库中找到指向godoc的badge链接。我在生产中使用它 对于速度使用: 获取github.com/im7mortal/UTM
你有什么样的坐标?你想要什么?你需要更具体一点,因为有几十种不同类型的坐标在使用。举个例子就好了。我已经更新了这个问题。希望它现在有意义。@JeremyBanks我正在尝试使用“go”。由于问题不清楚,我提供了PHP中的等效项。但是这似乎会导致混淆,所以现在我只是删除了PHP示例。您可以试着看一看。@dommage它似乎不起作用。我只有北向、东向坐标,实际上不是一个选项,因为我在沙盒虚拟机中运行应用程序,所以没有CTL此库是GPL这是一个麻省理工学院授权的图书馆