【问题标题】:Shapely : tuples without commas with LineString匀称:带 LineString 的不带逗号的元组
【发布时间】:2017-10-04 08:51:06
【问题描述】:

这很复杂,但长话短说:我使用了几个库,如 OSMNx,在城市的几个地点之间绘制了一条路线。现在我将其转换为 shp 文件。

路由是一个包含节点 ID 的列表。然后这些id用于提取每个节点的纬度和经度。我制作了元组,将每个节点的坐标(一个开始,一个到达)与一个 for 循环连接起来,如下所示:

journey = [] 
# previous list will contain tuples with coordinates of each node

for node1, node2 in zip(route[:-1], route[1:]):
    parcours.append(tuple((G.node[noeud1]['x'], G.node[noeud1]['y']))) # we create a tuple with coordinates of start's node
    parcours.append(tuple((G.node[noeud2]['x'], G.node[noeud2]['y']))) # then we make the same for the arrival node

这是循环结束时 print(journey) 的结果:

[(6.15815, 48.6996136), (6.1629696, 48.7007431), (6.1629696, 48.7007431), [...], (6.1994411, 48.6768434), (6.1994411, 48.6768434), (6.1995322, 48.6767583)]

每个元组都正确显示。但是当我想在一个匀称的 LineString 中转换旅程时......它会返回这个:

from shapely.geometry import LineString
final_journey = LineString(journey)
print(final_journey)
LINESTRING (6.15815 48.6996136, 6.1629696 48.7007431, 6.1629696 48.7007431, 6.1630717 48.7002871, [...], 6.1991794 48.677085, 6.1994411 48.6768434, 6.1994411 48.6768434, 6.1995322 48.6767583)

因此,我无法使用 fiona 将其转换为 shp:

import fiona
schema = {
    'geometry': 'Polygon',
    "properties": {'id': 123}
}

with fiona.open('test.shp', 'w', 'ESRI Shapefile', schema) as c:
    c.write({
        'geometry': mapping(trace)
    })

----------------------------------- ---------------------------- TypeError Traceback(最近一次调用 最后)在() 4 } 5 ----> 6 with fiona.open('test.shp', 'w', 'ESRI Shapefile', schema) as c: 7 c.写({ 8 '几何':映射(轨迹)

/usr/local/lib/python3.5/dist-packages/fiona/init.py in open(path, 模式、驱动程序、模式、crs、编码、层、vfs、启用驱动程序、 crs_wkt) 第173章 174 编码=编码,层=层,vsi=vsi,存档=存档, --> 175 启用驱动程序=启用驱动程序,crs_wkt=crs_wkt) 176 其他: 第177章

/usr/local/lib/python3.5/dist-packages/fiona/collection.py 在 init(自我、路径、模式、驱动程序、架构、crs、编码、层、vsi、存档、启用驱动程序、crs_wkt、**kwargs) 154 elif self.mode in ('a', 'w'): 第155章 --> 156 self.session.start(self, **kwargs) 157 除了 IOError: 158 self.session = 无

fiona/ogrext.pyx in fiona.ogrext.WritingSession.start (fiona/ogrex2.c:16207)()

TypeError: 'int' 类型的参数不可迭代

我不明白为什么在纬度和经度之间没有逗号的情况下转换元组。此外,还有几个重复(第三行的第二个坐标是第四行的第一个坐标等),可能会成为未来shp的错误来源。

提前致谢!

【问题讨论】:

  • 当您执行print(final_journey) 时看到的是您的行的Well Known Text 表示。这没有什么问题(例如“不带逗号的元组”),它只是在解释器中显示几何图形的方式。

标签: python shapefile shapely


【解决方案1】:

我不认为获取节点的坐标然后将它们连接在一起是你能做的最好的事情。如果街道不直怎么办? OSMnx 为您提供街道的精确几何形状。要提取节点的几何形状,here 解释了更好的解决方案。但是你需要街道的几何形状。由于两个节点之间可能有不止一条边,所以这并不总是那么简单。我相信ox.get_route_edge_attributes() 应该能够做到这一点,如果您要求另一个属性(例如highway),它确实很有效,但不适用于提取边缘的geometry。原因(我猜)是不是G 中的所有边都有geometry,但是如果你得到网络的gdf_edges,那么你总是有每条边的几何形状。以下是我发现的解决方法:

gdf_nodes, gdf_edges = ox.graph_to_gdfs(G)
path = nx.shortest_path(G, G.nodes()[0], G.nodes()[1])

获取路径中节点的GeoDataFrame:

output_points = gdf_nodes.loc[path]
output_points.plot(color='red')

要获得边的几何形状,首先将 u,v 值的元组设置为 gdf_edges 的索引,然后 loc 选择路径的 GeoDataFrame:

gdf_edges.index = gdf_edges.apply(lambda row: (row.u, row.v), axis=1)
output_lines = gdf_edges.loc[list(zip(path[:-1], path[1:]))]
output_lines.plot(color='red')

然后您可以将其保存到 shapefile:

output_edges.to_file()

一个重要的评论:正如我已经说过的,两个节点之间可以有多个边。这意味着要唯一标识一条边,uv(边缘的开始和结束)还不够,你还需要key,它是由OSMnx自动添加的,你可以在每个边缘的graph和gdf_edges中找到它。因此,如果您使用上面的代码,请注意它会给您all 节点之间的边(如果有多个边)。快速检查是:len(np.nonzero(output_edges['key'])[0])。如果没有平行边,这肯定是零。如果不是,则说明有平行边。

更新

OSMnx 具有从 GeoDataFrame 保存 shapefile 的功能:

p = '/path/to/destination/'
ox.save_gdf_shapefile(output_lines, 'output', p)

将架构添加到 to_file() 似乎也可以:

sch = {'geometry': 'LineString',
       'properties': {'key': 'int',
                        'u': 'int',
                        'v': 'int'}}

test = gpd.GeoDataFrame(output_lines[['u', 'v', 'key']], 
                        geometry=output_lines['geometry'], crs='+init=EPSG:3740')

test.to_file('/path/to/destination/test.shp', schema=sch)

【讨论】:

  • 嗨 Alireza !刚刚测试了您的解决方案,它工作正常,直到 output_edges.to_file() 步骤(我不确定这是一个好的变量,我认为使用 output_lines 会更好)。我必须提交一个类似于我的问题中的模式吗?提前致谢!
  • 太好了,我验证了你的答案!再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 2019-09-12
  • 2022-01-10
相关资源
最近更新 更多