fmm icon indicating copy to clipboard operation
fmm copied to clipboard

FMM trajectories do not match start and end points

Open seffylmz opened this issue 2 years ago • 3 comments

FMM fits quite well except for the start and end points of the trajectories. As seen on the picture, the map matched trajectory (red) starts at the nearest node instead of the starting point of the original trajectory (black). Any suggestion on that?

MM

I am using a script similar to the provided example:

from fmm import Network,NetworkGraph,FastMapMatch,FastMapMatchConfig,UBODT
from fmm import GPSConfig,ResultConfig
from fmm import UBODTGenAlgorithm

# Load network data and graph
network = Network("network-new/edges.shp", "fid", "u", "v")
print "Nodes {} edges {}".format(network.get_node_count(),network.get_edge_count())
graph = NetworkGraph(network)

#Precompute an UBODT file
ubodt_gen = UBODTGenAlgorithm(network,graph)
status = ubodt_gen.generate_ubodt("ubodt.txt", 0.003, binary=False, use_omp=True)
print status

#Load UBODT data
ubodt = UBODT.read_ubodt_csv("ubodt.txt")

#Create FMM model
model = FastMapMatch(network,graph,ubodt)

#Define FMM configuration
k = 12
radius = 200
gps_error = 100
fmm_config = FastMapMatchConfig(k,radius,gps_error)

#Match trajectories in GPS file
input_config = GPSConfig()
input_config.file = 'gps/traj_0.csv'
input_config.id = 'id'

print input_config.to_string()

result_config = ResultConfig()
result_config.file = 'gps/mr_0_n.txt'
result_config.output_config.write_opath = True
print result_config.to_string()

status = model.match_gps_file(input_config, result_config, fmm_config)
print status

seffylmz avatar Mar 31 '22 09:03 seffylmz

If your data is in unit of degrees, the current configuration is too large. Try to reduce radius and GPS error by a factor of 1e-5(1 degree=1e5 meters, 1 meter = 1e-5 degree)。

Keep all units in degrees if you do not want to project your GPS and network data into meters.

cyang-kth avatar Mar 31 '22 09:03 cyang-kth

Thanks for the quick response. I also tried reduced parameters and various others (also for delta and vmax) but always facing the same issue.

It seems to me that the trajectory points are only located at nodes and break points of edges. Thus, points in the middle of an edge are not matched. Can it be related to the network files?

I have generated the network files by using this snippet:

def save_graph_shapefile_directional(G, filepath=None, encoding="utf-8"):
    # default filepath if none was provided
    if filepath is None:
        filepath = os.path.join(ox.settings.data_folder, "graph_shapefile")

    # if save folder does not already exist, create it (shapefiles
    # get saved as set of files)
    if not filepath == "" and not os.path.exists(filepath):
        os.makedirs(filepath)
    filepath_nodes = os.path.join(filepath, "nodes.shp")
    filepath_edges = os.path.join(filepath, "edges.shp")

    # convert undirected graph to gdfs and stringify non-numeric columns
    gdf_nodes, gdf_edges = ox.utils_graph.graph_to_gdfs(G)
    gdf_nodes = ox.io._stringify_nonnumeric_cols(gdf_nodes)
    gdf_edges = ox.io._stringify_nonnumeric_cols(gdf_edges)
    # We need an unique ID for each edge
    gdf_edges["fid"] = np.arange(0, gdf_edges.shape[0], dtype='int')
    # save the nodes and edges as separate ESRI shapefiles
    gdf_nodes.to_file(filepath_nodes, encoding=encoding)
    gdf_edges.to_file(filepath_edges, encoding=encoding)

print("osmnx version",ox.__version__)

# Download by a bounding box
boundary_polygon = Polygon(coordinates)
G = ox.graph_from_polygon(boundary_polygon, network_type='drive')
start_time = time.time()
save_graph_shapefile_directional(G, filepath='./network-new')
print("--- %s seconds ---" % (time.time() - start_time))

seffylmz avatar Mar 31 '22 10:03 seffylmz

You could try other search radius and gps error, also check the direction of each edge to assure the direction of edge is consistent with the GPS movement.

cyang-kth avatar Apr 01 '22 02:04 cyang-kth