使用Boost几何图形从点到线的垂直地理距离

时间:2018-11-03 12:21:48

标签: boost geometry gis boost-geometry

我想获得从点(t)到线段(p, q)的垂直距离。垂直线不能与线[p, q]相交。在那种情况下,我想假设地延伸线(p, q),然后画垂直线以获得距离。 p,q,t均为gps坐标。我正在使用升压几何。

typedef boost::geometry::model::point<
    double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
> geo_point;
typedef boost::geometry::model::segment<geo_point> geo_segment;

geo_point p(88.41253929999999, 22.560206299999997);
geo_point q(88.36928063300775, 22.620867969497795);
geo_point t(88.29580956367181, 22.71558662052875);

我已在map上绘制了这三个位置 enter image description here

我测量两个距离qt和从tpq的距离

double dist_qt = boost::geometry::distance(q, t);
std::cout << dist_qt*earth_radius << std::endl;

geo_segment line(p, q);
double perp_dist = boost::geometry::distance(t, line);
std::cout << perp_dist*earth_radius << std::endl;

这两个距离相同。这意味着它不计算垂直距离。相反,它计算了从点到shortest内的直线的bounds距离。

我如何以这种方式计算垂直距离,以便无论边界如何都必须垂直?

cpp.sh中的工作示例

2 个答案:

答案 0 :(得分:2)

此答案可以进行所有计算,无需提高


考虑半径为R = 1的球体。

enter image description here

点A,B在great circle上。这个大圆gcAB也穿过球体的中心点 O (大圆是必需的)。点 A B O 定义了平面PL1

P 也位于一个很大的圆圈中。

P 到大圆gcAB的最小距离(沿着大圆弧而不是3D直线测量)是圆弧的长度 PC 。 大圆圈gcPC
平面 PL2 PL1 平面垂直。

我们想要点 C ,它位于线 OC 中,该线是上述两个平面的交点。


平面 PL1 由其垂直向量pp1定义。此向量是通过向量OAOB叉积获得的。

由于平面 PL2 与平面 PL1 垂直,因此它必须包含向量pp1。因此,可以通过pp2OP的叉积获得与平面 PL2 垂直的向量pp1

通过ppiOC的叉积获得两个平面的线pp1相交的向量pp2

如果我们对向量ppi进行归一化并将其分量乘以地球的半径R,我们将获得点 C 的坐标。
交叉产品不是可交换的。这意味着,如果我们交换点A,B,我们将在球体中得到相反的点 C'。我们可以测试距离PCPC'并获取它们的最小值。


要计算两个点 A B 大圆距离 Wikipedia link,它取决于角度{{ aOA之间的1}}。
为了获得所有角度的最佳精度,我们使用OB,其中使用半径1,a = atan2(y, x)y= sin(a)x= cos(a)sin(a)可以分别由叉积(OA,OB)和点积(OA,OB)计算。

总的来说,我们有以下C ++代码:

cos(a)

给出距离 对于给定的三个点,AP = 21024.4 BP = 12952.1,PC = 499.493。

运行代码here

答案 1 :(得分:0)

似乎您可以使用project_point策略:

Live On Coliru

#include <string>
#include <iostream>
#include <boost/geometry.hpp>

namespace bg = boost::geometry;

int main(){
    double const earth_radius = 6371.0; // Km

    typedef bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree>> geo_point;
    typedef bg::model::segment<geo_point> geo_segment;

    geo_point p(88.41253929999999, 22.560206299999997);
    geo_point q(88.36928063300775, 22.620867969497795);
    geo_point t(88.29580956367181, 22.71558662052875);

    double dist_qt = bg::distance(q, t);
    std::cout << dist_qt*earth_radius << std::endl;

    geo_segment line(p, q);
    double perp_dist = distance(t, line, bg::strategy::distance::projected_point<>{});
    std::cout << perp_dist*earth_radius << std::endl;
}

打印

12.9521
763.713

我没有检查结果(在那张照片中,perp_dist这么大似乎有点令人惊讶),但是也许我错过了一些东西。

万一您需要做一些特殊的事情(除了坐标系之外)来获得“ haversine”(对不起,我对此不太了解),您可能需要将第二个模板参数传递给projected_point策略:“ 基础点对点距离策略”。