1

是否有任何已知的 Java 库允许我将 WGS 84 线转换为 OSGB36,或者是否有一个好的公式可以使用?我目前正在使用这个,但它不是很准确,所以我想知道是否有更好的我可以使用。

private static double[] Wgs84ToBNG(double inLat, double inLon) {

    double lat = inLat * Math.PI / 180.0;
    double lon = inLon * Math.PI / 180.0;
    double a = 6377563.396; // Airy 1830 major & minor semi-axes
    double b = 6356256.910;
    double F0 = 0.9996012717; // NatGrid scale factor on central meridian
    double lat0 = 49 * Math.PI / 180.0; // NatGrid true origin
    double lon0 = -2 * Math.PI / 180.0;
    double N0 = -100000; // northing & easting of true origin, metres
    double E0 = 400000;
    double e2 = 1 - (b * b) / (a * a); // eccentricity squared
    double n = (a - b) / (a + b), n2 = n * n, n3 = n * n * n;
    double cosLat = Math.cos(lat), sinLat = Math.sin(lat);
    double nu = a * F0 / Math.sqrt(1 - e2 * sinLat * sinLat); // transverse
                                                                // radius of
                                                                // curvature
    double rho = a * F0 * (1 - e2)
            / Math.pow(1 - e2 * sinLat * sinLat, 1.5); // meridional radius
                                                        // of curvature
    double eta2 = nu / rho - 1;
    double Ma = (1 + n + (5 / 4) * n2 + (5 / 4) * n3) * (lat - lat0);
    double Mb = (3 * n + 3 * n * n + (21 / 8) * n3) * Math.sin(lat - lat0)
            * Math.cos(lat + lat0);
    double Mc = ((15 / 8) * n2 + (15 / 8) * n3)
            * Math.sin(2 * (lat - lat0)) * Math.cos(2 * (lat + lat0));
    double Md = (35 / 24) * n3 * Math.sin(3 * (lat - lat0))
            * Math.cos(3 * (lat + lat0));
    double M = b * F0 * (Ma - Mb + Mc - Md); // meridional arc
    double cos3lat = cosLat * cosLat * cosLat;
    double cos5lat = cos3lat * cosLat * cosLat;
    double tan2lat = Math.tan(lat) * Math.tan(lat);
    double tan4lat = tan2lat * tan2lat;
    double I = M + N0;
    double II = (nu / 2) * sinLat * cosLat;
    double III = (nu / 24) * sinLat * cos3lat * (5 - tan2lat + 9 * eta2);
    double IIIA = (nu / 720) * sinLat * cos5lat
            * (61 - 58 * tan2lat + tan4lat);
    double IV = nu * cosLat;
    double V = (nu / 6) * cos3lat * (nu / rho - tan2lat);
    double VI = (nu / 120)
            * cos5lat
            * (5 - 18 * tan2lat + tan4lat + 14 * eta2 - 58 * tan2lat * eta2);
    double dLon = lon - lon0;
    double dLon2 = dLon * dLon;
    double dLon3 = dLon2 * dLon;
    double dLon4 = dLon3 * dLon;
    double dLon5 = dLon4 * dLon;
    double dLon6 = dLon5 * dLon;
    double N = I + II * dLon2 + III * dLon4 + IIIA * dLon6;
    double E = E0 + IV * dLon + V * dLon3 + VI * dLon5;
    double[] returnValue = { E, N };
    return returnValue;
} 
4

4 回答 4

2

看看这个页面

在“程序/源代码”部分中,您将找到标题为“WGS84 Lat/Long <=> OSGB36 Grid References”的小节。在本小节中,有几个指向提供此功能的实用程序的链接。

在另一篇文章中,您可以找到此类任务的源代码以及解释。

于 2011-12-18T10:24:59.827 回答
1

如果您不确定其他库的正确性,我会将结果与 PROJ.4 进行比较。如果您不想使用本机库,那么还有一个用于 PROJ.4 的纯 Java 端口。

将 PROJ.4 用于 WGS84 Lat/Long <=> OSGB36 已在此处讨论:
PROJ.4 library and OSGB36

使用 cs2cs:
http
: //trac.osgeo.org/proj/wiki/man_cs2cs OSGB36 字符串:
http
://spatialreference.org/ref/epsg/27700/proj4/ WGS84 字符串:
http ://spatialreference.org/ref/ epsg/4326/proj4/

Java 端口:http:
//sourceforge.net/projects/jmapprojlib/

于 2011-12-18T14:48:40.260 回答
1

我在这方面做了一些工作,并使用了大不列颠坐标系统指南,它告诉你如果你仔细阅读它需要知道的一切。从公式中使用的变量名称来看,您很可能已经研究过同一个文档。我认为整个文档中与坐标系之间转换有关的最重要的段落是这个(从第 30 页的底部开始)

总结:对于简单的经纬度坐标从基准A到基准B的基准变化,首先转换为笛卡尔坐标(公式见附件B),所有椭球高度为零,并使用基准A的椭球参数;然后使用等式 (3) 应用从基准 A 到基准 B 的 Helmert 变换;最后使用基准 B 的椭球参数(附件 C 中的公式)转换回纬度和经度,丢弃基准 B 椭球高度。

它描述了您必须采取的 3 个步骤。您引用的公式会将纬度/经度转换为 同一基准中的东/北。这不是转型

从您的方法的命名中,您传递 WGS84 纬度/经度,因此您应该:

1) 将网格参考系统(以及相关的真实起源等)的所有想法都抛诸脑后,直到您将纬度/经度从一个基准转换为另一个基准

2) 使用操作系统指南中的公式 B1 到 B5 将 WGS84 纬度/经度转换为 WGS84 基准的 3D 笛卡尔坐标(即 x、y 和 z)。确保使用 WGS84 基准的参数(长轴/短轴)

3) 使用提到的 Helmert 变换,将您刚刚计算的笛卡尔坐标转换为相对于 Airy 1830 椭球的笛卡尔坐标。您将在 6.6 节中找到获取新笛卡尔所需的 7 个参数

新坐标 xGB、yGB、zGB 为:

double xGB = tx + (x * (1 + s)) + (-rz * y) + (ry * z);
double yGB = ty + (rz * x) + (y * (1 + s)) + (-rx * z);
double zGB = tz + (-ry * x) + (rx * y) + (z * (1 + s));

他们实际上并没有把它拼出来,他们只是假设你记得你的矩阵数学

4) 现在使用公式 B6 到 B8 将那些新的笛卡尔坐标(相对于 OSGB36 基准面)转换为相对于 OSGB36 基准面的纬度/经度

从这里您可以继续使用您引用的公式计算网格东移和北移

于 2011-12-18T15:27:34.590 回答
0

我用过jcoord。非常有用且易于实现。

于 2013-01-23T12:23:07.973 回答