从POI点找到边界

工作中有这样的一个需求,通过历史订单的经纬度点,进行一个聚类,聚之后我们需要找到它的边界点存储

聚类的操作有基于Kmeans的和DBSCAN的密度聚类,只是这里需要注意,经纬度点的聚类需要用到距离的计算,不能简单的作为欧式距离或者曼哈顿距离。因为地球是一个球面,在根据经纬度点计算距离的时候,需要先把点投放到平面上,才能保证计算的距离是有意义的,因此,需要根据两个经纬度点计算距离的时候,如下的计算是没问题的,这是用C++实现DBSCAN过程中的一步:(得到的距离是按米来计算的)

//计算角半径
double rad(double d)
{
    return d * M_PI / 180.0;
}

double cal_dist(double lng1, double lat1, double lng2, double lat2) {
   
    float ra = 6378.140;
    float rb = 6356.755;
    float flatten = (ra - rb) / ra;
    double lng1_rad = angle_to_radian(lng1);
    double lat1_rad = angle_to_radian(lat1);
    double lng2_rad = angle_to_radian(lng2);
    double lat2_rad = angle_to_radian(lat2);
    double pA = atan(rb / ra * tan(lat1_rad));
    double pB = atan(rb / ra * tan(lat2_rad));
    
    double xx = acos(sin(pA) * sin(pB) + cos(pA) * cos(pB) * cos(lng1_rad - lng2_rad));
    double c1 = (sin(xx) - xx) * pow((sin(pA) + sin(pB)), 2) / pow(cos(xx / 2),
                                                                   2);
    double c2 = (sin(xx) + xx) * pow((sin(pA) - sin(pB)), 2) / pow(sin(xx / 2),
                                                                   2);
    double dr = flatten / 8 * (c1 - c2);
    double distance = ra * (xx + dr) * 1000;
//    cout<<distance<<endl;
    return distance;
}

以上是一个小插曲,那么如何通过聚类之后的点,找到一个聚类的边界点?

譬如已经得到了一堆点,效果如下图所示:

那么通过找到边界之后的点,效果是这样:

由于项目仓促,我就直接用Python来完成的:

from scipy.spatial import ConvexHull
cv = ConvexHull(cluster1) #cluster1 是只有两列的lng,lat,经度纬度值
hull_points = cv.vertices

edge_point = cluster1.values[hull_points,0:2]
plt.scatter(edge_point[:,0],edge_point[:,1])

以上就是解决问题的过程。有更好的方法,可以留言告诉我,其中这还是很值得学习的,如何通过一堆点找到准确的边界?大概了解了一下,里面用到一些几何学理论,凸包理论,所以聚集出来的点总是凸的形状。如果想要把效果做的更好,还要对噪音点进行删除操作,接着再进行找边界,当然完成这一步在数据量比较大的时候,复杂度还是比较高的。相当于每个聚类之后的一堆点执行N方的操作。

如果有做相关工作的同学,可以留言啊。一起搞定它!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想做个自由的人

随缘吧打赏与否还是会坚持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值