GeographicLib:移动 latLon 坐标并返回创建偏移量
GeographicLib: moving a latLon coordinate and back creates an offset
使用以下代码(使用 GeographicLib)移动坐标并再次返回,创建到原始起点的偏移量。
差异随着移动距离的增加而增加,并取决于方位角。同时使用 GeodesicExact 和 Geodesic 也是如此。
我最终想要实现的是通过移动起始坐标来创建一个 latLon 形状。
是否有 exact/better 方法可以做到这一点,或者我是否遗漏了一些基本知识?
inline double distanceInMeters(const GeoCoords &_c1, const GeoCoords &_c2) {
GeodesicExact geod = geodWGS84(); // GeodesicExact::WGS84()
double meters;
geod.Inverse(_c1.Latitude(), _c1.Longitude(),
_c2.Latitude(), _c2.Longitude(),
meters);
return meters;
}
// move coord _byMeters in direction _azimuth
// inexact with horiz moves !!!
inline GeoCoords move(const GeoCoords &_coords, const double &_azimuth, const double &_byMeters) {
GeodesicExact geod = geodWGS84(); // GeodesicExact::WGS84()
double latOut, lngOut;
geod.Direct(_coords.Latitude(), _coords.Longitude(), _azimuth, _byMeters, latOut, lngOut);
return GeoCoords(latOut, lngOut);
}
inline void testDistanceMove() {
GeoCoords c(12.3456789, 12.3456789);
GeoCoords cc = c;
double dist = 123459998.6789; // meters
bool bHorz = true; // <-- creates some offset???
bool bVert = true; // almost exact
if (bHorz) cc = move(cc, Azimuth::WEST, dist); // 270.
if (bVert) cc = move(cc, Azimuth::SOUTH, dist); // 180
if (bHorz) cc = move(cc, Azimuth::EAST, dist); // 90.
if (bVert) cc = move(cc, Azimuth::NORTH, dist); // 0.
ofLogNotice((__func__)) << "c : " << toString(c);
ofLogNotice((__func__)) << "cc: " << toString(cc);
double diff = distanceInMeters(c, cc);
ofLogNotice((__func__)) << "diff: " << ofToString(diff, 12) << " m";
}
几何平面概念的简单概念不适用于椭圆体上的球体。例如,四边形的内角和大于 360°。如果距离很小(大约 1 公里)并且您不靠近杆子,您将得到近似闭合;然而,您的距离超过地球周长的 3 倍,因此所有赌注均无效。
附录
为了帮助描绘问题,考虑从北极以南 1 米处开始,绘制距离为 1 米的 4 条边(依次为西、南、东和北)。因为1米远小于地球半径,所以这个是一个平面问题。折线看起来像(虚线是子午线)
如果你从南极1米以内开始,这张照片看起来更奇怪。
使用以下代码(使用 GeographicLib)移动坐标并再次返回,创建到原始起点的偏移量。 差异随着移动距离的增加而增加,并取决于方位角。同时使用 GeodesicExact 和 Geodesic 也是如此。 我最终想要实现的是通过移动起始坐标来创建一个 latLon 形状。
是否有 exact/better 方法可以做到这一点,或者我是否遗漏了一些基本知识?
inline double distanceInMeters(const GeoCoords &_c1, const GeoCoords &_c2) {
GeodesicExact geod = geodWGS84(); // GeodesicExact::WGS84()
double meters;
geod.Inverse(_c1.Latitude(), _c1.Longitude(),
_c2.Latitude(), _c2.Longitude(),
meters);
return meters;
}
// move coord _byMeters in direction _azimuth
// inexact with horiz moves !!!
inline GeoCoords move(const GeoCoords &_coords, const double &_azimuth, const double &_byMeters) {
GeodesicExact geod = geodWGS84(); // GeodesicExact::WGS84()
double latOut, lngOut;
geod.Direct(_coords.Latitude(), _coords.Longitude(), _azimuth, _byMeters, latOut, lngOut);
return GeoCoords(latOut, lngOut);
}
inline void testDistanceMove() {
GeoCoords c(12.3456789, 12.3456789);
GeoCoords cc = c;
double dist = 123459998.6789; // meters
bool bHorz = true; // <-- creates some offset???
bool bVert = true; // almost exact
if (bHorz) cc = move(cc, Azimuth::WEST, dist); // 270.
if (bVert) cc = move(cc, Azimuth::SOUTH, dist); // 180
if (bHorz) cc = move(cc, Azimuth::EAST, dist); // 90.
if (bVert) cc = move(cc, Azimuth::NORTH, dist); // 0.
ofLogNotice((__func__)) << "c : " << toString(c);
ofLogNotice((__func__)) << "cc: " << toString(cc);
double diff = distanceInMeters(c, cc);
ofLogNotice((__func__)) << "diff: " << ofToString(diff, 12) << " m";
}
几何平面概念的简单概念不适用于椭圆体上的球体。例如,四边形的内角和大于 360°。如果距离很小(大约 1 公里)并且您不靠近杆子,您将得到近似闭合;然而,您的距离超过地球周长的 3 倍,因此所有赌注均无效。
附录
为了帮助描绘问题,考虑从北极以南 1 米处开始,绘制距离为 1 米的 4 条边(依次为西、南、东和北)。因为1米远小于地球半径,所以这个是一个平面问题。折线看起来像(虚线是子午线)
如果你从南极1米以内开始,这张照片看起来更奇怪。