Closed seisman closed 3 years ago
平面距离=墨卡托投影里的纸面距离 测地线距离=球体地球的球面距离 大圆路径距离是什么?
平面距离=墨卡托投影里的纸面距离 测地线距离=球体地球的球面距离 大圆路径距离是什么?
我知道大圆路径是什么,只是说如果测地线距离=球体地球的球面距离,测地线距离!=大圆路径距离,那大圆路径距离是什么?
平面距离=墨卡托投影里的纸面距离 测地线距离=球体地球的球面距离 大圆路径距离是什么?
我知道大圆路径是什么,只是说如果测地线距离=球体地球的球面距离,测地线距离!=大圆路径距离,那大圆路径距离是什么?
@ZMAlt 的建议是三种距离方式翻译为“平面距离”,“大圆路径距离”和“大地线长度”。根据 ArcGIS 的一篇博文(https://pro.arcgis.com/zh-cn/pro-app/latest/tool-reference/spatial-analyst/geodesic-versus-planar-distance.htm ),似乎测地线距离也是很常用的翻译。
我个人更倾向于将三者翻译为“平面距离”,“大圆路径距离”,和“测地线距离”。@ZMAlt 你的意见如何?
我搜了下,维基也有同样的描述 https://zh.wikipedia.org/wiki/%E6%B5%8B%E5%9C%B0%E7%BA%BF 我觉得可以
平面距离=墨卡托投影里的纸面距离 测地线距离=球体地球的球面距离 大圆路径距离是什么?
平面距离不一定是墨卡托投影,可以是其他投影,只要投影到平面 测地线/大地线 是椭球上两点的距离 大圆路径 可以认为是球面距离
平面距离=墨卡托投影里的纸面距离 测地线距离=球体地球的球面距离 大圆路径距离是什么?
平面距离不一定是墨卡托投影,可以有很多投影,只要投影到平面 测地线/大地线 是椭球上两点的距离 大圆路径 可以认为是球面距离
如果大圆距离是球面距离,那gmt的计算结果里,经度相同而纬度不相同的点的距离就该是纬度直接相减,昨天的实验不是
如果大圆距离是球面距离,那gmt的计算结果里,经度相同而纬度不相同的点的距离就该是纬度直接相减,昨天的实验不是
我觉得角度为单位的结果就有问题,不同纬度的角度对应的实际距离也在变化
如果大圆距离是球面距离,那gmt的计算结果里,经度相同而纬度不相同的点的距离就该是纬度直接相减,昨天的实验不是
我觉得角度为单位的结果就有问题,不同纬度的角度对应的实际距离也在变化
球面不存在这个问题。我意思是,gmt里的大圆距离和测地线距离可能都是在椭球地球里算的,但是默认情况下用的一个简化公式
球面不存在这个问题。我意思是,gmt里的大圆距离和测地线距离可能都是在椭球地球里算的,但是默认情况下用的一个简化公式
我看了下源码: 大圆距离用的确实是球面距离的公式 https://zh.wikipedia.org/wiki/%E5%A4%A7%E5%9C%86%E8%B7%9D%E7%A6%BB 公式的结果为度, 如果单位设置为 m/km 的话,就乘以一个 scale
对于大地线长度, 如果设置单位是 m/km... 的话,默认用的是 vincenty 公式,结果单位是 m 如果设置单位为 度... 的话,用的不是 vincenty 公式(因为 vincenty 公式的结果就是 m/km),而是把椭球坐标转换为球坐标,然后计算(详细计算过程我没看)
所以,我认为,结论如下:
The issue was fixed by 0d215103.
gmt计算大圆距离有三种计算方法,但是只有个两种“地球”,球体和椭球体,所以为什么gmt有三种计算方式,我的疑问还是没解决
来自 @wangliang1989 https://github.com/gmt-china/GMT_docs/pull/766#issuecomment-962908611
Flat earth 一定是用了投影的,把地理坐标投影到平面,然后计算。 Sphere earth 我猜是用的球面距离公式,但是球的定义可能有点门道,我还没细看过
来自 @ZMAlt https://github.com/gmt-china/GMT_docs/pull/766#issuecomment-959148084
这里我又看了下 flat earth 的源码,我关于 Flat earth的表述有点问题,我原本以为是分别对地理坐标投影,然后分带计算平面距离。但其实不是,flat earth 用的不是投影到平面计算以 m/km 为单位的距离,而是非常简单的经纬度差值的 hypot 计算,然后乘以一个投影地区整体的 scale。这样看来,精度就更加低了。 也就是说 flat earth 是直接用的地理坐标的经纬度差值和投影地区的 scale 计算的。这种情况下,精度已经非常差了,基本到不了考虑是球还是椭球的地步了。
看了下面源码结合当前的中文文档基本就明白了。
源码
GMT_LOCAL double gmtmap_flatearth_dist_degree (struct GMT_CTRL *GMT, double x0, double y0, double x1, double y1) {
/* Calculates the approximate flat earth distance in degrees.
If difference in longitudes exceeds 180 we pick the other
offset (360 - offset)
*/
double dlon;
gmt_M_unused(GMT);
gmt_M_set_delta_lon (x0, x1, dlon);
return (hypot ( dlon * cosd (0.5 * (y1 + y0)), (y1 - y0)));
}
/*! . */
GMT_LOCAL double gmtmap_flatearth_dist_meter (struct GMT_CTRL *GMT, double x0, double y0, double x1, double y1) {
/* Calculates the approximate flat earth distance in km.
If difference in longitudes exceeds 180 we pick the other
offset (360 - offset)
*/
return (gmtmap_flatearth_dist_degree (GMT, x0, y0, x1, y1) * GMT->current.proj.DIST_M_PR_DEG);
}
GMT_LOCAL double gmtmap_haversine (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) {
/* Haversine formula for great circle distance. Intermediate function that returns sin^2 (half_angle).
* This avoids problems with short distances where cos(c) is close to 1 and acos is inaccurate.
*/
double sx, sy, sin_half_squared;
if (lat1 == lat2 && lon1 == lon2) return (0.0);
if (GMT->current.setting.proj_aux_latitude != GMT_LATSWAP_NONE) { /* Use selected auxiliary latitude */
lat1 = gmt_lat_swap (GMT, lat1, GMT->current.setting.proj_aux_latitude);
lat2 = gmt_lat_swap (GMT, lat2, GMT->current.setting.proj_aux_latitude);
}
sy = sind (0.5 * (lat2 - lat1));
sx = sind (0.5 * (lon2 - lon1)); /* If there is a 360 wrap here then the sign of sx is wrong but we only use sx^2 */
sin_half_squared = sy * sy + cosd (lat2) * cosd (lat1) * sx * sx;
return (sin_half_squared);
}
double gmtlib_great_circle_dist_degree (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) {
/* Great circle distance on a sphere in degrees */
double sin_half_squared = gmtmap_haversine (GMT, lon1, lat1, lon2, lat2);
return (2.0 * d_asind (d_sqrt (sin_half_squared)));
}
/*! . */
double gmt_great_circle_dist_meter (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) {
/* Calculates the great circle distance in meter */
return (gmtlib_great_circle_dist_degree (GMT, lon1, lat1, lon2, lat2) * GMT->current.proj.DIST_M_PR_DEG);
}
GMT_LOCAL double gmtmap_geodesic_dist_degree (struct GMT_CTRL *GMT, double lonS, double latS, double lonE, double latE) {
/* Compute the great circle arc length in degrees on an ellipsoidal
* Earth. We do this by converting to geocentric coordinates.
*/
...
GMT_LOCAL double gmtmap_vincenty_dist_meter (struct GMT_CTRL *GMT, double lonS, double latS, double lonE, double latE) {
/* Translation of NGS FORTRAN code for determination of true distance
** and respective forward and back azimuths between two points on the
** ellipsoid. Good for any pair of points that are not antipodal.
**
** INPUT
** latS, lonS -- latitude and longitude of first point in radians.
** latE, lonE -- latitude and longitude of second point in radians.
**
** OUTPUT
** s -- distance between points in meters.
** Modified by P.W. from: http://article.gmane.org/gmane.comp.gis.proj-4.devel/3478
*/
...
所以基本结论还是不变,追求精度就用大地线,不追求就用大圆和平面,单位是 km/m 比较靠谱。
gmt计算大圆距离有三种计算方法,但是只有个两种“地球”,球体和椭球体,所以为什么gmt有三种计算方式,我的疑问还是没解决
来自 @wangliang1989 #766 (comment)
Flat earth 一定是用了投影的,把地理坐标投影到平面,然后计算。 Sphere earth 我猜是用的球面距离公式,但是球的定义可能有点门道,我还没细看过
来自 @ZMAlt #766 (comment)
这里我又看了下 flat earth 的源码,我关于 Flat earth的表述有点问题,我原本以为是分别对地理坐标投影,然后分带计算平面距离。但其实不是,flat earth 用的不是投影到平面计算以 m/km 为单位的距离,而是非常简单的经纬度差值的 hypot 计算,然后乘以一个投影地区整体的 scale。这样看来,精度就更加低了。 也就是说 flat earth 是直接用的地理坐标的经纬度差值和投影地区的 scale 计算的。这种情况下,精度已经非常差了,基本到不了考虑是球还是椭球的地步了。
看了下面源码结合当前的中文文档基本就明白了。
flat earth
源码
GMT_LOCAL double gmtmap_flatearth_dist_degree (struct GMT_CTRL *GMT, double x0, double y0, double x1, double y1) { /* Calculates the approximate flat earth distance in degrees. If difference in longitudes exceeds 180 we pick the other offset (360 - offset) */ double dlon; gmt_M_unused(GMT); gmt_M_set_delta_lon (x0, x1, dlon); return (hypot ( dlon * cosd (0.5 * (y1 + y0)), (y1 - y0))); } /*! . */ GMT_LOCAL double gmtmap_flatearth_dist_meter (struct GMT_CTRL *GMT, double x0, double y0, double x1, double y1) { /* Calculates the approximate flat earth distance in km. If difference in longitudes exceeds 180 we pick the other offset (360 - offset) */ return (gmtmap_flatearth_dist_degree (GMT, x0, y0, x1, y1) * GMT->current.proj.DIST_M_PR_DEG); }
Sphere earth
GMT_LOCAL double gmtmap_haversine (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) { /* Haversine formula for great circle distance. Intermediate function that returns sin^2 (half_angle). * This avoids problems with short distances where cos(c) is close to 1 and acos is inaccurate. */ double sx, sy, sin_half_squared; if (lat1 == lat2 && lon1 == lon2) return (0.0); if (GMT->current.setting.proj_aux_latitude != GMT_LATSWAP_NONE) { /* Use selected auxiliary latitude */ lat1 = gmt_lat_swap (GMT, lat1, GMT->current.setting.proj_aux_latitude); lat2 = gmt_lat_swap (GMT, lat2, GMT->current.setting.proj_aux_latitude); } sy = sind (0.5 * (lat2 - lat1)); sx = sind (0.5 * (lon2 - lon1)); /* If there is a 360 wrap here then the sign of sx is wrong but we only use sx^2 */ sin_half_squared = sy * sy + cosd (lat2) * cosd (lat1) * sx * sx; return (sin_half_squared); } double gmtlib_great_circle_dist_degree (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) { /* Great circle distance on a sphere in degrees */ double sin_half_squared = gmtmap_haversine (GMT, lon1, lat1, lon2, lat2); return (2.0 * d_asind (d_sqrt (sin_half_squared))); } /*! . */ double gmt_great_circle_dist_meter (struct GMT_CTRL *GMT, double lon1, double lat1, double lon2, double lat2) { /* Calculates the great circle distance in meter */ return (gmtlib_great_circle_dist_degree (GMT, lon1, lat1, lon2, lat2) * GMT->current.proj.DIST_M_PR_DEG); }
Geodesic earth
GMT_LOCAL double gmtmap_geodesic_dist_degree (struct GMT_CTRL *GMT, double lonS, double latS, double lonE, double latE) { /* Compute the great circle arc length in degrees on an ellipsoidal * Earth. We do this by converting to geocentric coordinates. */ ...
GMT_LOCAL double gmtmap_vincenty_dist_meter (struct GMT_CTRL *GMT, double lonS, double latS, double lonE, double latE) { /* Translation of NGS FORTRAN code for determination of true distance ** and respective forward and back azimuths between two points on the ** ellipsoid. Good for any pair of points that are not antipodal. ** ** INPUT ** latS, lonS -- latitude and longitude of first point in radians. ** latE, lonE -- latitude and longitude of second point in radians. ** ** OUTPUT ** s -- distance between points in meters. ** Modified by P.W. from: http://article.gmane.org/gmane.comp.gis.proj-4.devel/3478 */ ...
所以基本结论还是不变,追求精度就用大地线,不追求就用大圆和平面,单位是 km/m 比较靠谱。
这段论述的信息应该加到手册里,我这么认为
这段论述的信息应该加到手册里,我这么认为
用 GMT 算距离人很少,大多数人并不会关心的。学测量的人,需要的话大多数都已经手写了这些公式了,也搞的比较清楚。中文手册现在基本上已经够了,后面我找时间简单修一下。
所以三种计算距离的方式的准确名称是:大地线长距离,大圆路径距离和平面距离?
_Originally posted by @seisman in https://github.com/gmt-china/GMT_docs/issues/766#issuecomment-959295701_
根据 @ZMAlt 的反馈,中文手册中目前对 flat earth distance 和 geodesic distance 的翻译并不准确。
@ZMAlt 的建议是三种距离方式翻译为“平面距离”,“大圆路径距离”和“大地线长度”。根据 ArcGIS 的一篇博文(https://pro.arcgis.com/zh-cn/pro-app/latest/tool-reference/spatial-analyst/geodesic-versus-planar-distance.htm ),似乎测地线距离也是很常用的翻译。
我个人更倾向于将三者翻译为“平面距离”,“大圆路径距离”,和“测地线距离”。@ZMAlt 你的意见如何?