如何将东方赤道坐标和北方赤道坐标转换为纬度和经度?

4
我需要使用Go将OSGB36坐标中的东距和北距转换为纬度和经度坐标。因此,我想知道是否有任何可以完成这一任务的包。从头开始编写似乎并不容易。由于我在受限制的虚拟机中运行代码,所以代码必须是纯Go。
输入:
- Northing - 相对于国家网格原点向北的距离(以米为单位)。 - Easting - 相对于国家网格原点向东的距离(以米为单位)。
示例:
 348356,862582

输出(十进制度 -DDD):

  • 纬度
  • 经度

示例:

41.40338, 2.17403

1
你有什么类型的坐标,想要什么类型的坐标 - 你需要更具体一些,因为有数十种不同类型的坐标在使用中。最好提供一个例子。 - Nick Craig-Wood
我已经更新了问题。希望现在可以理解。 - themihai
@JeremyBanks 我正在尝试使用"go"。由于问题似乎不太清楚,我提供了PHP的等效代码。然而,这似乎导致了混淆,所以现在我已经删除了PHP示例。 - themihai
你可以尝试查看这个项目 - Dmitri Goldring
@dommage 看起来不起作用。我只有北坐标和东坐标。 - themihai
3个回答

3

1
并不是真正的选项,因为我正在沙盒化的虚拟机中运行该应用程序,所以没有C语言。 - themihai

2
下面的代码是从javascript(©2005-2014Chris Veness)在链接Nick Craig-Wood提供的非常天真地移植过来的。我只移植了OsGridToLatLong()函数,但其他函数也不应该太难。此外,这将所有值都视为float64。您可能希望将northingeasting视为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)
}

产生:

纬度:52.833026N
经度:4.871525E

这些是OSGB-36坐标

来自Chris Veness的原始帖子:

“Ordnance Survey使用'OSGB-36',基于一个椭圆形地球表面模型,这个模型非常适合英国。GPS系统通常使用全球性的'WGS-84',基于一个椭圆形模型,这是对整个地球的最佳近似。在格林威治,它们相差约126米(它们在大西洋的某个地方重合;维基百科上有更多信息)”

我不确定这个 Northing: 348356, Easting: 862582 的 OSGB-36 坐标是否应该在这里,但是上面的代码和 JavaScript 代码 (JSFiddle) 把它放在了荷兰北部的某个地方。(尽管地图上显示的坐标是 WGS-84,而不是 OSGB-36。有关 OSGB-36 和 WGS-84 之间的转换,请参见 这里。)

Probably completely wrong

这段代码尚未经过充分测试(它产生的输出与原始JavaScript代码相同,但这并不能保证其正确性),可能存在可怕的错误,但它应该能指出正确的方向(无意双关)。

游乐场


1

你好,我遇到了同样的问题。我们正在将代码库从Python移植过来。我们使用了Tobias Bieniek的这个库-(UTM python version),它在Github上是公开的。

我没有找到什么好的轻量级库。我只是将这个库移植到了golang-UTM golang library。它是纯go的,只包含两种方法。您可以在存储库中找到指向godoc的徽章链接。我在生产中使用它。

为了提高速度,请使用:

go get github.com/im7mortal/UTM


这个库采用 GPL 许可证,这让我无法使用它。这是一个采用 MIT 许可证的库:https://github.com/icholy/utm - Ilia Choly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接