2017-08-08 2 views
3

OSMnx bietet Lösung, um den kürzesten Weg zwischen zwei Knoten zu berechnen, aber ich möchte mit den gleichen Punkten auf Straßen (Ich habe GPS-Koordinaten von Fahrzeugen aufgezeichnet). Ich weiß, dass es auch eine Methode gibt, den nächsten Knoten zu bekommen, aber ich habe zwei Fragen zu meinem Problem.Kann man in OSMnx eine Koordinate an eine Straße anpassen?

i) Wenn der nächstgelegene Knoten berechnet wird, ist die Straße, in der der Punkt berücksichtigt wird? (Ich nehme an, nicht) ii) Wenn ich so etwas implementieren möchte, möchte ich wissen, wie eine Straße (Kante) als eine Kurve dargestellt wird (Bézier-Kurve vielleicht?). Ist es möglich, die Kurve (oder die Gleichung der Kurve) einer Kante zu erhalten?

Ich habe diese Frage hier gestellt, weil die Richtlinien für den Beitrag von OSMnx gefragt haben.

Antwort

2

Straßen und Knoten in OSMnx sind shapely.geometry.LineString und shapely.geometry.Point Objekte, so gibt es keine Kurve, nur Sequenz von Koordinaten. Der technische Ausdruck für das, was Sie beschrieben haben, ist Map Matching. Es gibt verschiedene Arten des Kartenabgleichs. Der einfachste ist der geometrische Kartenabgleich, bei dem Sie die nächstgelegene Geometrie (Knoten oder Kante) zum GPS-Punkt finden. point to point Kartenabgleich kann leicht mit eingebauter Osmnx-Funktion ox.get_nearest_node() erreicht werden. Wenn Sie einen Luxus von dichten GPS-Tracks haben, könnte dieser Ansatz einigermaßen gut funktionieren. Für point to line Kartenabgleich müssen Sie formschöne Funktionen verwenden. Das Problem bei diesem Ansatz ist, dass es sehr langsam ist. Sie können den Algorithmus mit dem räumlichen Index beschleunigen, aber für die meisten Zwecke ist es nicht schnell genug. Beachten Sie, dass die geometrische Kartenanpassung unter allen Ansätzen am wenigsten genau ist. Ich habe vor einigen Wochen eine Funktion geschrieben, die einen einfachen Punkt-zu-Zeile-Kartenabgleich mit der Kante GeoDataFrame und dem Knoten GeoDataFrame durchführt, die Sie von OSMnx erhalten können. Ich habe diese Idee aufgegeben und arbeite jetzt an einem neuen Algorithmus (hoffentlich viel schneller), den ich nach Fertigstellung auf GitHub veröffentlichen werde. In der Zwischenzeit kann dies für Sie oder jemand anderen hilfreich sein, also poste ich es hier. Dies ist eine frühe Version des aufgegebenen Codes, nicht ausreichend getestet und nicht optimiert. Probieren Sie es aus und lassen Sie mich wissen, ob es für Sie funktioniert.

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

Wir freuen uns darauf, Ihren neuen Algorithmus zu sehen, wenn Sie ihn auf GitHub schieben. – gboeing

+0

Ich werde Sie wissen lassen, sobald ich etwas vorzeigbar habe. –

Verwandte Themen