pszufe / OpenStreetMapX.jl

OpenStreetMap (*.osm) support for Julia 1.0 and up
MIT License
123 stars 24 forks source link

should all weights equal the distance between the corresponding nodes? #34

Closed kramsretlow closed 4 years ago

kramsretlow commented 4 years ago

This possible issue was observed while checking the fix for #32 .

Let md be an object of type MapData. Suppose that a certain edge in md.g connects vertices i and j, which correspond to nodes nodeA and nodeB in the map, respectively.

It is my impression that md.w[i,j] should hold the Euclidean distance between nodeA and nodeB, and that the same distance should be obtained by using distance(nodeA, nodeB). I tried to check this with code like the following:

count = 0
for (nodeA, nodeB) in md.e
    i, j = (md.v[nodeA], md.v[nodeB])
    thisweight = md.w[i, j]
    thisdist = distance(md.nodes[nodeA], md.nodes[nodeB])
    if thisweight ā‰ˆ thisdist
        count += 1
    end
end
count/length(md.e)

Which, for my map of Shanghai, returned 0.527: 53% of the weights agreed with the distance calculation (while 47 percent did not). I spent some time trying to figure out why some would agree and others not, but I couldn't get to the bottom of it.

Are they supposed to be the same in the first place? Am I missing something?

Thanks!

pszufe commented 4 years ago

This is indeed very good question!

The get_map_data has a parameter only_intersections by default set to true. This parameter causes a truncation of the road system to only nodes that are intersections while leaving out those nodes that are present in OSM data to present road curvature (an OSM Way is a just set of straight lines attached to nodes so in order to present road curvature additional nodes are needed).

When this node compression occurs, still the actual distances between intersections are preserved. In result the matrix w in MapData contains correct distances between intersections when traveling by car.

If you want those two pieces of data to match just turn off the graph compression:

m = get_map_data(map_file_path, use_cache=false, only_intersections=false);

Now running:

all([distance(m.nodes[m.n[e.src]],m.nodes[m.n[e.dst]]) == m.w[e.src,e.dst] for e in edges(m.g)])

should yield true.

kramsretlow commented 4 years ago

Ah, I see, thanks! I had toggled a couple of other options to gt_map_data but didn't try only_intersections.

Also, somehow I had missed the existence of the n field in MapData, it's useful šŸ‘