2017-08-08 9 views
3

OSMnxは2つのノード間の最短経路を計算するソリューションを提供していますが、私は道路上の点(私は車両から記録されたGPS座標を持っています)と同じことを望みます。私は最も近いノードを取得する方法もあることを知っていますが、私はこの問題について2つの質問があります。OSMnxの通りに座標を合わせることは可能ですか?

i)計算された最近接点は、ポイントも考慮される通りですか? (私はそうではないと思う) ii)このようなものを実装したいのであれば、通り(エッジ)がどのように曲線として表現されているか知りたいと思う(ベジエ曲線かもしれない?エッジのカーブ(またはカーブの方程式)を得ることは可能ですか?

私はこの質問をここで尋ねました。なぜなら、OSMnxの寄稿のガイドラインに尋ねたからです。

答えて

2

OSMnxの道路とノードはshapely.geometry.LineStringshapely.geometry.Pointオブジェクトなので、カーブはなく、座標のシーケンスだけです。あなたが記述した技術用語はMap Matchingです。地図マッチングにはさまざまな方法があります。最も単純なものは、GPSポイントに対して最も近いジオメトリ(ノードまたはエッジ)を見つけるジオメトリマップマッチングです。 point to pointマップマッチングは、組み込みのosmnx関数ox.get_nearest_node()を使用すると簡単に実現できます。高密度のGPSトラックがある場合は、このアプローチは合理的にうまくいく可能性があります。 point to line地図マッチングでは、整然とした機能を使用する必要があります。このアプローチの問題は、それが非常に遅いことです。空間インデックスを使用してアルゴリズムの速度を上げることはできますが、ほとんどの場合、十分に高速ではありません。ジオメトリマップマッチングは、すべてのアプローチの中で最も正確ではないことに注意してください。私は数週間前に、OSMnxから得ることができるエッジGeoDataFrameとノードGeoDataFrameを使用した単純なポイント・ツー・ライン・マッチングを行う関数を書いた。私はこのアイデアを放棄しましたが、完成したらGitHubで公開する新しいアルゴリズムに取り組んでいます。一方、これはあなたや他の人のために役立つかもしれないので、私はここに投稿します。これは放棄されたコードの初期バージョンであり、十分にテストされておらず、最適化されていません。試してみて、それがあなたのために働くかどうか私に知らせてください。

def GeoMM(traj, gdfn, gdfe): 
""" 
performs map matching on a given sequence of points 

Parameters 
---------- 

Returns 
------- 
list of tuples each containing timestamp, projected point to the line, the edge to which GPS point has been projected, the geometry of the edge)) 

""" 

traj = pd.DataFrame(traj, columns=['timestamp', 'xy']) 
traj['geom'] = traj.apply(lambda row: Point(row.xy), axis=1) 
traj = gpd.GeoDataFrame(traj, geometry=traj['geom'], crs=EPSG3740) 
traj.drop('geom', axis=1, inplace=True) 

n_sindex = gdfn.sindex 

res = [] 
for gps in traj.itertuples(): 
    tm = gps[1] 
    p = gps[3] 
    circle = p.buffer(150) 
    possible_matches_index = list(n_sindex.intersection(circle.bounds)) 
    possible_matches = gdfn.iloc[possible_matches_index] 
    precise_matches = possible_matches[possible_matches.intersects(circle)] 
    candidate_nodes = list(precise_matches.index) 

    candidate_edges = [] 
    for nid in candidate_nodes: 
     candidate_edges.append(G.in_edges(nid)) 
     candidate_edges.append(G.out_edges(nid)) 

    candidate_edges = [item for sublist in candidate_edges for item in sublist] 
    dist = [] 
    for edge in candidate_edges: 
     # get the geometry 
     ls = gdfe[(gdfe.u == edge[0]) & (gdfe.v == edge[1])].geometry 
     dist.append([ls.distance(p), edge, ls]) 

    dist.sort() 
    true_edge = dist[0][1] 
    true_edge_geom = dist[0][2].item() 
    pp = true_edge_geom.interpolate(true_edge_geom.project(p)) # projected point 
    res.append((tm, pp, true_edge, true_edge_geom)) 


    return res 
+0

GitHubにプッシュすると、新しいアルゴリズムが表示されるのを楽しみにしています。 – gboeing

+0

私は何かがあるとすぐにお知らせします。 –

関連する問題