ExtractMapGraph(string osm_pbf_filename) { var recreationalVechicleRoadTags = new HashSet<string>( new[] { // https://wiki.openstreetmap.org/wiki/Key:highway "motorway", "trunk", "primary", "secondary", "tertiary", "unclassified", "residential", "service", // ramps and other road connectors "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link", } ); var onewayIdentifiers = new HashSet<string>(new [] { "yes", "1", "true" }); var nodes = new Dictionary<long, FindingDirectionsState>(); // TODO: figure out why hashset of OSM edge is fine but IWeightedGraphEdge fails to dedupe var edges = new HashSet<OsmEdge>(); var graphNodes = new HashSet<FindingDirectionsState>(); using(var fileStream = File.OpenRead(osm_pbf_filename)) using(var source = new PBFOsmStreamSource(fileStream)) foreach (var element in source) { switch(element.Type) { case OsmGeoType.Node: if (!element.Id.HasValue) continue; var osm_node = (Node)element; if (!osm_node.Latitude.HasValue || !osm_node.Longitude.HasValue) continue; var graph_node = new FindingDirectionsState( nodeId: (ulong)osm_node.Id.Value, latitude: osm_node.Latitude.Value, longitude: osm_node.Longitude.Value ); nodes[element.Id.Value] = graph_node; break; case OsmGeoType.Way: if (!element.Tags.ContainsKey("highway")) continue; var highwayType = element.Tags.GetValue("highway"); if (!recreationalVechicleRoadTags.Contains(highwayType)) continue; var way = (Way)element; if (way.Nodes.Length < 2) continue; bool isOneWay = element.Tags.ContainsKey("oneway") && onewayIdentifiers.Contains(element.Tags["oneway"]); for(int i = 1; i < way.Nodes.Length; i++) { var a = nodes[way.Nodes[i-1]]; var b = nodes[way.Nodes[i]]; graphNodes.Add(a); graphNodes.Add(b); var distance = DistanceHelper.Haversine(a.Latitude, a.Longitude, b.Latitude, b.Longitude); edges.Add(new OsmEdge(a, b, distance)); if (!isOneWay) edges.Add(new OsmEdge(b, a, distance)); } break; case OsmGeoType.Relation: // don't need these? break; } } var graph = new AdjacencyListWeightedGraph<FindingDirectionsState, double>(edges); return (graph, graphNodes); }
public static Func <FindingDirectionsState, double> MakeStraightLineDistanceHeuristic(FindingDirectionsState goal) { return(from => DistanceHelper.Haversine(from.Latitude, from.Longitude, goal.Latitude, goal.Longitude)); }
public override double DistanceSquaredBetweenPoints(double[] a, double[] b) { double dst = DistanceHelper.Haversine(a[0], a[1], b[0], b[1]); return (float)(dst * dst); }