Go 如何将东-北坐标转换为经纬度?

Go 如何将东-北坐标转换为经纬度?,go,gis,Go,Gis,我需要使用Go将Eastings和NorthingsOSGB36坐标转换为纬度和经度坐标。因此,我想知道是否有这样的软件包。从零开始写一篇文章似乎并不琐碎。我正在沙盒虚拟机中运行代码,因此代码必须是纯Go 输入: 北距-国家电网原点以北的距离(米) 东距-国家电网原点以东的距离(米) 例如: 348356,862582 输出(十进制度数-DDD): 纬度 经度 例如: 41.40338, 2.17403 你可以试试这个库,它是一个综合性的包装器 我也没有试过,但看起来应该可以 或者

我需要使用Go将
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这是一个麻省理工学院授权的图书馆