2017-10-04 98 views
0

這很複雜,但長話短說:我已經使用了幾個類似OSMN的庫來繪製城市的幾個景點之間的路線。現在我將它轉換爲一個shp文件。Shapely:不帶逗號的元組與LineString

該路由是一個充滿節點ID的列表。然後這些id用於提取每個節點的緯度和經度。我做了元組與來連接各個節點對(一個開始,一個到達)的座標循環,這樣的:在循環結束

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 

這裏的打印(旅程)的結果:

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

每個元組都顯示正確。但是,當我想旅途轉換成一個身材勻稱的線段形式...而它返回:

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 (most recent call last) in() 4 } 5 ----> 6 with fiona.open('test.shp', 'w', 'ESRI Shapefile', schema) as c: 7 c.write({ 8 'geometry': mapping(trace)

/usr/local/lib/python3.5/dist-packages/fiona/init.py in open(path, mode, driver, schema, crs, encoding, layer, vfs, enabled_drivers, crs_wkt) 173 c = Collection(path, mode, crs=crs, driver=driver, schema=this_schema, 174 encoding=encoding, layer=layer, vsi=vsi, archive=archive, --> 175 enabled_drivers=enabled_drivers, crs_wkt=crs_wkt) 176 else: 177 raise ValueError(

/usr/local/lib/python3.5/dist-packages/fiona/collection.py in init(self, path, mode, driver, schema, crs, encoding, layer, vsi, archive, enabled_drivers, crs_wkt, **kwargs) 154 elif self.mode in ('a', 'w'): 155 self.session = WritingSession() --> 156 self.session.start(self, **kwargs) 157 except IOError: 158 self.session = None

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

TypeError: argument of type 'int' is not iterable

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) 

因此,我不能使用菲奧娜轉換的軸馬力我不明白爲什麼元組在經緯度之間沒有逗號轉換。此外,還有幾個重複(第三行的第二個座標是第四行的第一個座標,等等),也許它可能是未來shp的錯誤來源。

在此先感謝!

+0

什麼,當你做你所看到的'print(final_journey)'是你的行的[Well Known Text](https://en.wikipedia.org/wiki/Well-known_text)表示。這沒什麼錯(例如'沒有逗號的元組'),它只是在解釋器中幾何地顯示幾何圖形。 – mgc

回答

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') 

enter image description here

,並獲得邊緣的幾何形狀第一組的元組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') 

enter image description here

然後你可以將它保存到shape文件:

output_edges.to_file() 

一個重要的一句話:我已經說了,可以有兩個節點之間的多個邊緣。這意味着爲了唯一標識邊緣,uv(邊緣的開始和結束)是不夠的,您還需要key,它是由OSMnx自動添加的,您可以在圖形和gdf_edges中爲每個邊緣找到它。所以如果你使用上面的代碼,請注意它會給你all節點之間的邊緣(如果有多個)。快速檢查是:len(np.nonzero(output_edges['key'])[0])。如果沒有平行邊緣,這肯定是零。如果不是,則意味着存在平行邊緣。

UPDATE

OSMnx有一個功能,可以節省shape文件從GeoDataFrame:

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) 
+0

嗨Alireza!剛剛測試過你的解決方案,它的工作正常,直到output_edges.to_file()步驟(我不確定這是好變量,我認爲這對output_lines更好)。我必須提交一個像我的問題那樣的模式嗎?提前致謝 ! – Raphadasilva

+0

@Raphadasilva檢查更新。 –

+0

很好,我驗證你的答案!再次感謝 – Raphadasilva