cyang-kth / fmm

Fast map matching, an open source framework in C++
https://fmm-wiki.github.io/
Apache License 2.0
892 stars 215 forks source link

Question about reconstructing the ‘spdist’ by using ‘offset’ and ‘road length’ #204

Closed Dreamzz5 closed 3 years ago

Dreamzz5 commented 3 years ago
idx=2 #print opath
print(gdf.iloc[idx]['opath'])
array([14695, 14715, 14675, 14675, 14675,  8718]))

print(gdf.iloc[idx]['cpath']) #print cpath
array([14695,  7036, 14715, 14717,  8859, 14675,  8718])

print(gdf.iloc[idx]['tpath'].split('|')) #print tpath
['14695,7036,14715', '14715,14717,8859,14675', '14675', '14675', '14675,8718']

print(gdf.iloc[idx]['offset'])#print offset
array([  0.        ,  16.53772351, 154.8306739 , 154.8306739 ,154.8306739 ,  63.57969753])

print(gdf.iloc[idx]['spdist'])#print spdist
array([256.097439  , 462.1053789 ,   0.        ,   0.        ,63.57969753])

print(gdf.iloc[idx]['road_length'])#print road_length
[124.762, 106.248, 50.242, 142.199, 107.313, 143.378, 199.241]

So when I want to use the offset and road length to reconstruct the spdist. For example, tpath 1 '14695,7036,14715'

road1 length - offset1+ road2 length + offset2=
124.762-0+16.53772351+106.248=247.54772351 != 256.097439
cyang-kth commented 3 years ago

It seems the road length you obtained is not correct. How did you get it?

Dreamzz5 commented 3 years ago

The original Shapefile was downloaded from OSM for map matching.

cyang-kth commented 3 years ago

From your example, the edge 14675 has a length of 143.378 but its offset is 154.8306739, which is longer than the length. I think the length field you are reporting here is not correct.

Dreamzz5 commented 3 years ago

OK, I will check it now.

Dreamzz5 commented 3 years ago

Yes, it weirds. I plot the road network and trajectory together and demonstrate that the road id is correct.

fig,ax=plt.subplots(dpi=100)
road_network[road_network.id.isin(eval(gdf.iloc[idx]['cpath']))].plot(ax=ax,edgecolor='b',label='road',alpha=0.8)
gpd.GeoDataFrame(gdf.iloc[idx:idx+1]).set_geometry('pgeom').plot(ax=ax,edgecolor='r',label='trajectory',alpha=0.8)
ax.legend()
ax.axis('off')

image

Dreamzz5 commented 3 years ago

The road network is image

cyang-kth commented 3 years ago

If you directly calculate the length from the geometry, what is your result?

Dreamzz5 commented 3 years ago

What means about ‘directly calculate’?

cyang-kth commented 3 years ago

The length is calculated from the geometry of the linestring in fmm rather than using the cost information. You could also export the length field of the matching result to check the length inside the program. It may be different from the current one you are using, which comes from the cost field of the shapefile.

Dreamzz5 commented 3 years ago
print(gdf.iloc[idx].pgeom.length*111.11*1000) # meter
760.639211613965
print(gdf.iloc[idx]['spdist'].sum()*111.11*1000) # meter
781.78251543
cyang-kth commented 3 years ago

I mean the length of each edge, not the spdist, or pgeom. Pgeom is just a line connecting each matched point, its length is not the same as the spdist.

Dreamzz5 commented 3 years ago

OK, I will check it now.

Dreamzz5 commented 3 years ago

Yes, you are right. When I transfer the cost to 'linestring', the 'spdist' is matched.

print(road_network[road_network.id.isin(eval(gdf.iloc[idx]['cpath']))].cost.values)
[106.248, 199.241, 107.313, 143.378, 124.762,  50.242, 142.199]

print(road_network[road_network.id.isin(eval(gdf.iloc[idx]['cpath']))].geometry.length.values*111.11*1000)
[109.70259929, 217.65652669, 114.3454652 , 154.83075841,129.85755404,  58.28126324, 151.18537477]

print(road_length2[14695],road_length2[7036],road_length2[14715])
(129.8575540363128, 109.7025992889302, 58.28126324202719)

129.8575540363128-0+109.7025992889302+16.53772351=256.09787683524297, which is almost equal to ‘spdist’(256.097439).

thanks a lot.