2017-10-04 33 views
0

かなり複雑ですが、長いストーリーは短いです。私はOSMNxのようないくつかのライブラリを使って、都市のいくつかのスポットの間のルートを描きました。今私はそれを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 

ここで印刷(旅)の結果は、ループの終わりです:

私はこのように、forループで、各ノードのカップル(1つのスタート、1つの到着)の座標を連結するタプルを作りました
[(6.15815, 48.6996136), (6.1629696, 48.7007431), (6.1629696, 48.7007431), [...], (6.1994411, 48.6768434), (6.1994411, 48.6768434), (6.1995322, 48.6767583)] 

各タプルは正しく表示されます。しかし、私は...のすっきりラインストリングで旅を変換したいそして、それはこの返すとき:

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でそれを変換することはできません。

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

を私はタプルが緯度と経度の間にカンマなしで変換される理由を理解していません。さらに、いくつかの重複があります(3行目の2番目の座標は4行目の最初の座標などです)、将来のshpのエラーの原因になる可能性があります。

ありがとうございます!

+0

'print(final_journey)'はあなたの行の[よく知られているテキスト](https://en.wikipedia.org/wiki/Well-known_text)表現です。これには何も問題はありません(カンマなしのタプルなど)。インタプリタ内のジオメトリをどのように整然と表示するかです。 – mgc

答えて

1

私はノードの座標を取得し、それらを一緒に接続するとあなたができることはないと思います。通りが真っ直ぐでないならどうしますか? OSMnxはストリートの正確な形状を提供します。ノードの幾何学的形状を抽出するために、より良い解はhereと説明されています。しかし、ストリートの幾何学が必要です。 2つのノード間に複数のエッジが存在する可能性があるため、これは必ずしも簡単ではありません。私は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

あなたはその後、シェープファイルに保存することができます:

output_edges.to_file() 

一つの重要な発言を:私はすでに言ったように、2つのノード間に複数のエッジが存在することができます。つまり、uv(エッジの開始と終了)は十分ではありません。また、keyが必要です。これはOSMnxによって自動的に追加され、すべてのエッジに対してグラフとgdf_edgesの両方で検索されます。したがって、上記のコードを使用する場合は、ノード間に(複数の場合は)allのエッジがあることに注意してください。クイックチェックはlen(np.nonzero(output_edges['key'])[0])です。平行なエッジがない場合、これは必ずゼロになります。そうでない場合は、平行なエッジがあることを意味します。

UPDATE

OSMnxが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

関連する問題