cosbidev / PyTrack

a Map-Matching-based Python Toolbox for Vehicle Trajectory Reconstruction
https://pytrack-lib.readthedocs.io/en/latest/#
BSD 3-Clause Clear License
62 stars 9 forks source link

Issues with draw_path function: Lines not aligned with roads #12

Closed bodong66 closed 12 months ago

bodong66 commented 1 year ago

Description:

I've been using the PyTrack package for map matching and encountered an issue when visualizing the results using the draw_path function. Some of the plotted lines are not aligned with the roads, leading to a visually inaccurate representation.

Expected behavior:

The plotted path should align accurately with the roads on the map, reflecting the correct map-matched result.

Actual behavior:

Some lines are plotted off the roads, suggesting an issue with either the map matching or the visualization.

Screenshots:

image

I hope this can be addressed soon, and I'd appreciate any guidance or workarounds in the meantime. Thank you for your hard work on this package!

mtortora-ai commented 1 year ago

This is strange behaviour. I think it is because the points are very spread out. Is it possible to get the simulation data to reproduce the error? See you soon

bodong66 commented 12 months ago

Hello,

I apologize for the delay in responding; I have been quite busy and, unfortunately, overlooked the GitHub issues. Attached, please find the files necessary for reproduction.

Thank you for your patience. code snippet:

import pandas as pd
import numpy as np
from pytrack.graph import graph, distance
from pytrack.analytics import visualization
from pytrack.matching import candidate, mpmatching_utils, mpmatching
import matplotlib.pyplot as plt

df = pd.read_csv("reproduce.csv")

# Extract latitude and longitude directly as a list of tuples
points = [(lat, lon) for lat, lon in zip(df["latitude"], df["longitude"])]

# Calculate the bounding box using numpy functions
north, east = np.max(points, axis=0)
south, west = np.min(points, axis=0)

# Extract road network graph
G = graph.graph_from_bbox(*distance.enlarge_bbox(north, south, west, east, 500), simplify=False, network_type='drive')

# Visualize the extracted graph on a map centered around the mean location
maps = visualization.Map(location=(np.mean(df["latitude"]), np.mean(df["longitude"])))
maps.add_graph(G, plot_nodes=False)

# Extract and plot candidates
G_interp, candidates = candidate.get_candidates(G, points, interp_dist=5, closest=True, radius=30)
maps.draw_candidates(candidates, 30)

# Extract trellis DAG graph
trellis = mpmatching_utils.create_trellis(candidates)
trellis_draw = visualization.draw_trellis(trellis, figsize=(15, 100), dpi=100)
plt.show()

# Perform the map-matching process
path_prob, predecessor = mpmatching.viterbi_search(G_interp, trellis, "start", "target")

# Plot map-matching results
maps.draw_path(G_interp, trellis, predecessor)

maps.save("reproduce.html")

reproduce.csv

mtortora-ai commented 12 months ago

Try changing the parameters of graph.graph_from_bbox and candidate.get_candidates as follows:

import pandas as pd
import numpy as np
from pytrack.graph import graph, distance
from pytrack.analytics import visualization
from pytrack.matching import candidate, mpmatching_utils, mpmatching
import matplotlib.pyplot as plt

df = pd.read_csv("reproduce.csv")

# Extract latitude and longitude directly as a list of tuples
points = [(lat, lon) for lat, lon in zip(df["latitude"], df["longitude"])]

# Calculate the bounding box using Numpy functions
north, east = np.max(points, axis=0)
south, west = np.min(points, axis=0)

# Extract road network graph
G = graph.graph_from_bbox(*distance.enlarge_bbox(north, south, west, east, 500), simplify=True, network_type='drive')

# Visualize the extracted graph on a map centered around the mean location
maps = visualization.Map(location=(np.mean(df["latitude"]), np.mean(df["longitude"])))
maps.add_graph(G, plot_nodes=False)

# Extract and plot candidates
G_interp, candidates = candidate.get_candidates(G, points, interp_dist=20, closest=True, radius=30)
maps.draw_candidates(candidates, 30)

# Extract trellis DAG graph
trellis = mpmatching_utils.create_trellis(candidates)
trellis_draw = visualization.draw_trellis(trellis, figsize=(15, 100), dpi=100)
plt.show()

# Perform the map-matching process
path_prob, predecessor = mpmatching.viterbi_search(G_interp, trellis, "start", "target", beta=3, sigma=5))

# Plot map-matching results
maps.draw_path(G_interp, trellis, predecessor)

maps.save("reproduce.html")

In this way, I obtain the following results:

github_issue

If it is no problem, remember to leave a star for the repository.