【问题标题】:Plotting unsorted way/area's node reference from .osm file从 .osm 文件中绘制未排序的方式/区域的节点引用
【发布时间】:2018-06-14 08:00:35
【问题描述】:

所以我试图从 .osm 节点引用中定义建筑物的确切形状(外层),因为我需要根据一些假设在其中创建更多细节结构(房间、墙壁)。

到目前为止,我已经使用 pyosmium 从其“building:part”的引用中提取了节点的坐标,将节点的坐标存储到元组列表中,使用来自 shapely 的 Polygon 函数对其进行重建,并使用 mplleaflet 对其进行绘制。但不知何故,参考中的节点没有排序,当我尝试绘制它时,显示了很多交叉点。

我目前解决这个排序问题的方法如下:

def distance(current_data, x_point):
        # find the shortest distance between x_point and all points in current data
        # check if it's perpendicular to the line built before
        return current_data[x] # which perpendicular and has shortest distance to x_point

def sort_nodes(nodes):
        temp = []
        for node in nodes:
               if len(temp) < 2: # adding first 2 points as a starting line 
                     temp.append(node)
               else:
                     n = distance(temp, node)
                     # find index of current_data[x] in temp
                     return temp.insert(min_index, node)

仅按距离(最短)对坐标元组进行排序仍然不能解决问题。甚至根据其度数对其进行排序也可能导致另一个问题,即并非所有建筑物都是矩形的。

这就是我到目前为止通过基于距离排序的方式。plotted image

有没有更好的方法来做到这一点?还是我做错了?我已经连续尝试了 2 天。如果这很简单,我很抱歉,但我对编码真的很陌生,需要完成这项工作。感谢您的帮助。

编辑:对 sai 的回答

这是我提取节点的以下方法:

import osmium as osm
def way_filter():
    class WayFilter(osm.SimpleHandler):

        def __init__(self):
            super(WayFilter, self).__init__()
            self.nodes = []

        def way(self, w):
            if 'building:part' in w.tags and w.tags['building:part'] == 'hospital':
                temp = []
                for n in w.nodes:
                    temp.append(n.ref)
                self.nodes.append(temp)

     ways = WayFilter()
     ways.apply_file(map)
     return ways.nodes

def get_node(ref_node):
   class ObjectCounterHandler(osm.SimpleHandler):
       def __init__(self):
           osm.SimpleHandler.__init__(self)
           self.location = []
           self.ref = ref_node

       def write_object(self, lon, lat):
           self.location.append([lon, lat])

       def node(self, n):
            try:
               if any(n.id in sublist for sublist in self.ref):
                   self.write_object(n.location.lon, n.location.lat)
            except TypeError:
               if n.id in self.ref:
                   self.write_object(n.location.lon, n.location.lat)

   h = ObjectCounterHandler()
   h.apply_file(map)
   return h.location

主程序

a = way_filter()
for ref in a:

    b = get_node(ref)
    c = next(colors)
    loc = []

    for x in b:
        loc.append(tuple(x))

    # plot the points
    polygons = Polygon(loc)
    x,y = polygons.exterior.xy
    plt.plot(x,y, zorder=1) 
mplleaflet.show()

这是没有排序的结果。 plot image without sort

【问题讨论】:

    标签: python openstreetmap shapely osmium


    【解决方案1】:

    节点以正确的顺序通过方式引用,即它们彼此相邻。您无需执行任何手动排序如果您正确阅读了引用的节点 ID 列表。只有关系元素才需要手动排序。

    很遗憾,我对 pyosmium 不熟悉,所以我无法告诉您您的代码有什么问题。

    【讨论】:

    • 我在问题中添加了更多代码。不知何故,我得到了彼此相交的线。
    • 你是对的。我从参考中获取节点的部分错误。我应该删除问题吗?因为它是糟糕编码的一部分?谢谢!!
    • 不,不要删除它。也许其他人偶然发现了同样的问题。在此处添加评论(或新答案)并解释代码的哪一部分错误以及您如何修复它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 2020-03-06
    • 2018-06-02
    • 2019-05-08
    相关资源
    最近更新 更多