【问题标题】:Geopandas : sort a sample of points like a cycle graphGeopandas:像循环图一样对点样本进行排序
【发布时间】:2017-01-03 21:41:29
【问题描述】:

我正在尝试使用 geopandas 来操作一些点数据。我的最终 GeoDataFrame 代表在那里:

为了使用an other Python module,它用 OSM 数据计算两点之间的最短路径,我必须对我的点 like a tour 进行排序。

如果不是,下一个 Python 模块计算最短道路,但不一定在最近点之间。主要问题是旅游的约束。

如果我的点只是在一条线上,那么每个点的经纬度的基本排序功能就足够了,比如:

df1 = pd.read_csv("file.csv", sep = ",")
df1 = df1.sort_values(['Latitude','Longitude'], ascending = [1,1]) 
# (I'm starting with pandas df before GeoDataFrame conversion)

如果我们在此排序后从上一张图片的“上”点开始,DataFrame 的第二个点将是最近的点,依此类推......直到第五个点,位于图片的右侧(所以不再是最近的了)...

所以我的问题是:有人知道如何实现这种特殊的排序,还是我必须手动更改索引?

【问题讨论】:

  • “像赛道”是什么意思?
  • 抱歉,我不确定这个词...像旅游还是旅行?
  • 你指的是cycle吗?
  • 是的,就是这样...我将编辑我的问题以更清楚!
  • @ResMar 很抱歉打扰您,但还没有人回答,我想知道您是否有实现这一目标的想法...祝您有美好的一天!

标签: python sorting pandas geopandas


【解决方案1】:

如果我正确理解您的问题,您希望重新排列点的顺序,以便它们创建最短的路径。

我也遇到了同样的问题。 这是接受常规数据框的函数(= 每个坐标都有单独的字段。我相信您将能够修改任一函数以接受地理数据框或数据框,以便将几何字段拆分为 x 和 y 字段。

def autoroute_points_df(points_df, x_col="e",y_col="n"):

    '''
    Function, that converts a list of random points into ordered points, searching for the shortest possible distance between the points.
    Author: Marjan Moderc, 2016
    '''
    points_list = points_df[[x_col,y_col]].values.tolist()

    # arrange points in by ascending Y or X
    points_we = sorted(points_list, key=lambda x: x[0])
    points_sn = sorted(points_list, key=lambda x: x[1])

    # Calculate the general direction of points (North-South or West-East) - In order to decide where to start the path!
    westmost_point = points_we[0]
    eastmost_point = points_we[-1]

    deltay = eastmost_point[1] - westmost_point[1]
    deltax = eastmost_point[0] - westmost_point[0]
    alfa = math.degrees(math.atan2(deltay, deltax))
    azimut = (90 - alfa) % 360

    # If main directon is towards east (45°-135°), take westmost point as starting line.
    if (azimut > 45 and azimut < 135):
        points_list = points_we
    elif azimut > 180:
        raise Exception("Error while computing the azimuth! It cant be bigger then 180 since first point is west and second is east.")
    else:
        points_list = points_sn

    # Create output (ordered df) and populate it with the first one already.
    ordered_points_df = pd.DataFrame(columns=points_df.columns)
    ordered_points_df = ordered_points_df.append(points_df.ix[(points_df[x_col]==points_list[0][0]) & (points_df[y_col]==points_list[0][1])])

    for iteration in range(0, len(points_list) - 1):

        already_ordered = ordered_points_df[[x_col,y_col]].values.tolist()

        current_point = already_ordered[-1]  # current point
        possible_candidates = [i for i in points_list if i not in already_ordered]  # list of candidates

        distance = 10000000000000000000000
        best_candidate = None
        for candidate in possible_candidates:
            current_distance = Point(current_point).distance(Point(candidate))
            if current_distance < distance:
                best_candidate = candidate
                distance = current_distance

        ordered_points_df = ordered_points_df.append(points_df.ix[(points_df[x_col]==best_candidate[0]) & (points_df[y_col]==best_candidate[1])])

    return ordered_points_df

希望它能解决你的问题!

【讨论】:

  • 我认为它可以工作。我会尽快测试,我很快就会验证你的答案。最重要的是:非常感谢你:-)
  • 早上好@MarjanModerc!我刚刚用“真实”点的样本​​重新测试了你的算法,但有一个小问题:两点之间最近的路线并不总是绘制全局循环图的最佳方法。我可以向您发送一个与您的算法短路的 GeoDF 吗?也许会更清楚!在此先感谢,祝您有美好的一天
猜你喜欢
  • 1970-01-01
  • 2015-05-03
  • 2012-10-20
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2023-03-28
  • 2012-01-29
相关资源
最近更新 更多