地理坐标(经度,纬度)转换为米(x,y)

3

我正在使用如下的坐标系:

enter image description here

x和y的单位为米。我只对正向的x和y感兴趣。我想要将(x,y)转换成(lat,lon),反之亦然。

我认为这很简单,并且我认为我的解决方案没有问题。但是,我得到的结果并不完全正确。

我的解决方案:

如下图所示,我将纬度和经度作为两个圆的角度考虑:

enter image description here

1. (x,y)转换为(lat,lon)

我对x和y都应用了弧长公式(这里),如下所示:

enter image description here enter image description here

因此,我的函数为:

private static double calculateLat(float x) {
    int earthRadius = 6371000;
    return REF_LOC.getLatitude() + x*360/(2*PI*earthRadius);
}

private static double calculateLong(float y) {
    int earthRadius = 6371000;
    return REF_LOC.getLongitude() + y*360/(2*PI*earthRadius);
}

REF_LOC是参考地理位置,对于它而言(x,y)是(0,0)。它可以是地球上的任何一点。

2. (纬度,经度) 转 (x,y)

我只是简单地使用了以下方法:

int calculateX(double longitude){
        Location.distanceBetween(REF_LOC.getLatitude(), REF_LOC.getLongitude(),
                REF_LOC.getLatitude(), lonDeg, results);
        return results[0];
}

int calculateY(double latitude){
        Location.distanceBetween(REF_LOC.getLatitude(), REF_LOC.getLongitude(),
                latDeg, REF_LOC.getLongitude(), results);
        return results[0];
}

但我得到的结果不一致。首先,我使用方案1将一些值(x,y)转换为(lat,long)。但是,当我使用相同的(lat,long)使用方案2将其还原为(x,y)时,我在x和y方向上大约有2米和10米的差异。请问有谁能帮我确定问题所在吗?


1
我估计差异的原因是你的(1)是建模一个球体,而(2)(使用 Location.distanceBetween)是建模一个椭球体,其中椭球体的轴定义为:double a = 6378137.0; // WGS84 主轴 double b = 6356752.3142; // WGS84 半长轴 - user2711811
1
还可以查看https://gis.stackexchange.com/questions/25494/how-accurate-is-approximating-the-earth-as-a-sphere,了解误差大小的解释。 - user2711811
1个回答

1
提到我对球形和椭圆形计算的评论,另一种比较球形和椭圆形距离计算方法的方式是使用两个可用工具:
// For REF_LOC = (70, 20)

// Compute a lat/lng due east of a REF_LOC and compute distance using both
// available methods.

LatLng P = SphericalUtil.computeOffsetOrigin(REF_LOC, 20000, 90.0);

// And then compute a distance 
d = SphericalUtil.computeDistanceBetween(REF_LOC, P);
Location.distanceBetween(REF_LOC.latitude, REF_LOC.longitude, P.latitude, P.longitude, results);

// d = 20000.000000000036
// results[0] = 20081.818


// and for a REF_LOC = (0, 20)
// d = 20000.000000000127
// results[0] = 20022.377

有趣的是,SphericalUtil.computeOffsetOrigin() 产生了错误,纬度从赤道到极点增加使其不对称。然而,结果距离基本上是准确的。

我建议使用 SphericalUtil.computeOffsetOrigin 来计算 X/Y,并将其分解为您正在执行的纬度和经度偏移量。

最后展示 SphericalUtil 解决方案:

// Start with some arbitrary x/y relative to REF_LOC
double Rx = 125.0;
double Ry = 73.0;

// Compute a lat/lon from REF_LOC to the point
LatLng Rll = new LatLng(SphericalUtil.computeOffsetOrigin(REF_LOC, Ry, 180).latitude,
            SphericalUtil.computeOffsetOrigin(REF_LOC, Rx, 270).longitude);

// And recompute the x/y components of the lat/lon

double Rxx = SphericalUtil.computeDistanceBetween(REF_LOC, new LatLng(REF_LOC.latitude, Rll.longitude));
double Ryy = SphericalUtil.computeDistanceBetween(REF_LOC, new LatLng(Rll.latitude, REF_LOC.longitude));

导致:

结果为:

Rx/Ry   = (125.0, 73.0)
Rxx/Ryy = (125.00000004545973, 73.00000000137051)

可接受的误差,我认为。

那么,分别代表 x/y 的真正含义是什么?

请参考以下两个实用工具的来源获取更多信息:

Location

SphericalUtil


这个可行!但是,如果我在您的解决方案中使用Location.distanceBetween()而不是SphericalUtil.computeDistanceBetween(),它会给出不正确的结果。可能是因为它们使用不同的半径值。好吧,转换是一致的(前后都是),但我还需要在现场测试并查看它是否提供正确的结果。非常感谢! - M. Usman Khan
我刚发现我需要颠倒角度(0度变成180度,90度变成270度)才能使其正常工作。否则该位置会位于负数一侧。 - M. Usman Khan
1
是的,computeOffsetOrigin是“TO”,因此在球面解决方案中,应该按照您指示的航向将点放入第一象限。 代码已更新 - 谢谢。 - user2711811

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