Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Problems.RoutePlanning/3.3/Data.Osm/OsmDataSource.cs @ 14536

Last change on this file since 14536 was 8520, checked in by spimming, 12 years ago

#1894:

  • extended datasource interface to get routing graph for a specific vehicle type
  • use ICostCalculator to calculate edge weights
  • moved common enums in own file
  • removed method to estimate cost from graph; use ICostCalculator
File size: 8.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Xml;
5using HeuristicLab.Problems.RoutePlanning.Data.Core;
6using HeuristicLab.Problems.RoutePlanning.Data.Osm.Core;
7using HeuristicLab.Problems.RoutePlanning.Interfaces;
8using HeuristicLab.Problems.RoutePlanning.RoutingGraph;
9
10namespace HeuristicLab.Problems.RoutePlanning.Data.Osm {
11  public class OsmDataSource : IDataSource {
12    private FileInfo file;
13    private ICostCalculator costCalculator;
14    private IGraph graph;
15    private Dictionary<long, Vertex> vertices;
16
17    public OsmDataSource(string filename)
18      : this(filename, new TravelTimeCostCalculator()) {
19    }
20
21    public OsmDataSource(string filename, ICostCalculator costCalc) {
22      file = new FileInfo(filename);
23      costCalculator = costCalc;
24      graph = new Graph();
25      vertices = new Dictionary<long, Vertex>();
26
27      ReadData();
28    }
29
30    #region IDataSource Members
31
32    public IGraph GetRoutingGraph() {
33      return graph;
34    }
35
36    public IGraph GetRoutingGraph(VehicleType vehicle) {
37      throw new NotImplementedException();
38    }
39
40    #endregion
41
42    private Vertex GetVertex(long Id) {
43      Vertex v;
44      if (vertices.TryGetValue(Id, out v)) {
45        return v;
46      } else {
47        return null;
48      }
49    }
50
51    private void ReadData() {
52      XmlReaderSettings settings = new XmlReaderSettings();
53      settings.IgnoreComments = true;
54      settings.IgnoreWhitespace = true;
55
56      using (XmlReader reader = XmlReader.Create(file.FullName, settings)) {
57        reader.ReadStartElement("osm");
58        //reader.ReadStartElement("bounds");
59        reader.Read();
60        while (reader.LocalName.Equals("node")) {
61          double lat = XmlConvert.ToDouble(reader.GetAttribute("lat"));
62          double lon = XmlConvert.ToDouble(reader.GetAttribute("lon"));
63          long id = XmlConvert.ToInt64(reader.GetAttribute("id"));
64
65          Vertex v = new Vertex(id, lon, lat);
66          vertices.Add(v.Id, v);
67
68          reader.Read();
69          if (reader.LocalName.Equals("tag")) {
70            reader.ReadToFollowing("node");
71          }
72        }
73        while (reader.LocalName.Equals("way")) {
74          List<Vertex> way = new List<Vertex>();
75          bool missingNodes = false;
76          HighwayType category = HighwayType.null_type;
77          bool oneWayRoad = false;
78
79          reader.Read();
80          while (reader.LocalName.Equals("nd") || reader.LocalName.Equals("tag")) {
81            if (reader.LocalName.Equals("nd")) {
82              long refNodeId = XmlConvert.ToInt64(reader.GetAttribute("ref"));
83              Vertex vertex = GetVertex(refNodeId);
84              if (vertex != null) {
85                way.Add(vertex);
86              } else {
87                missingNodes = true;
88              }
89
90            } else if (reader.LocalName.Equals("tag")) {
91              string key = reader.GetAttribute("k");
92              string value = reader.GetAttribute("v");
93
94              if (key == TagConstants.HighwayTagKey) {
95                if (Enum.IsDefined(typeof(HighwayType), value)) {
96                  HighwayType ht = (HighwayType)Enum.Parse(typeof(HighwayType), value, true);
97                  category = ht;
98                } else {
99                  category = HighwayType.null_type;
100                }
101              } else if (key == TagConstants.OneWayTag) {
102                oneWayRoad = value.Equals(TagConstants.YesValue);
103              }
104            }
105            reader.Read();
106          }
107          if (missingNodes) {
108            // TODO: Error/Trace output
109            // if Way xxx has incomplete nodes. At least one node was missing in the data.
110          }
111          for (int i = 0; i < way.Count - 1; i++) {
112            Vertex v1 = way[i];
113            graph.AddVertex(v1);
114            Vertex v2 = way[i + 1];
115            graph.AddVertex(v2);
116            //short vertexCategory = (short)category;
117            float weight = costCalculator.CalculateCosts(v1, v2, category);
118            if (oneWayRoad) {
119              Edge<Vertex> edge = new Edge<Vertex>(v1, v2, weight);
120              graph.AddEdge(edge);
121            } else {
122              Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2, weight);
123              graph.AddEdge(edgeForward);
124
125              Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1, weight);
126              graph.AddEdge(edgeBackward);
127            }
128          }
129          reader.Read();
130        }
131        reader.Close();
132      }
133    }
134
135    private void ReadDataV2() {
136      XmlReaderSettings settings = new XmlReaderSettings();
137      settings.IgnoreComments = true;
138      settings.IgnoreWhitespace = true;
139      NameTable nt = new NameTable();
140      string osmName = nt.Add("osm");
141      object nodeName = nt.Add("node");
142      object tagName = nt.Add("tag");
143      object wayName = nt.Add("way");
144      string latName = nt.Add("lat");
145      string lonName = nt.Add("lon");
146      string idName = nt.Add("id");
147      object ndName = nt.Add("nd");
148      string refName = nt.Add("ref");
149      string kName = nt.Add("k");
150      string vName = nt.Add("v");
151      settings.NameTable = nt;
152      string ns = "";
153
154      using (XmlReader reader = XmlReader.Create(file.FullName, settings)) {
155        reader.ReadStartElement(osmName, ns);
156        reader.Read();
157        while (reader.LocalName.Equals(nodeName)) {
158          double lat = XmlConvert.ToDouble(reader.GetAttribute(latName, ns));
159          double lon = XmlConvert.ToDouble(reader.GetAttribute(lonName, ns));
160          long id = XmlConvert.ToInt64(reader.GetAttribute(idName, ns));
161
162          Vertex v = new Vertex(id, lon, lat);
163          vertices.Add(v.Id, v);
164
165          reader.Read();
166          //if (reader.LocalName.Equals(tagName)) {
167          if (ReferenceEquals(tagName, reader.LocalName)) {
168            reader.ReadToFollowing((string)nodeName, ns);
169          }
170        }
171        //while (reader.LocalName.Equals(wayName)) {
172        while (ReferenceEquals(wayName, reader.LocalName)) {
173          List<Vertex> way = new List<Vertex>();
174          bool missingNodes = false;
175          HighwayType category = HighwayType.null_type;
176          bool oneWayRoad = false;
177
178          reader.Read();
179          while (ReferenceEquals(ndName, reader.LocalName) || ReferenceEquals(tagName, reader.LocalName)) {
180            if (reader.LocalName.Equals(ndName)) {
181              long refNodeId = XmlConvert.ToInt64(reader.GetAttribute(refName, ns));
182              Vertex vertex = GetVertex(refNodeId);
183              if (vertex != null) {
184                way.Add(vertex);
185              } else {
186                missingNodes = true;
187              }
188
189            } else if (reader.LocalName.Equals(tagName)) {
190              string key = reader.GetAttribute(kName, ns);
191              string value = reader.GetAttribute(vName, ns);
192
193              if (key == TagConstants.HighwayTagKey) {
194                if (Enum.IsDefined(typeof(HighwayType), value)) {
195                  HighwayType ht = (HighwayType)Enum.Parse(typeof(HighwayType), value, true);
196                  category = ht;
197                } else {
198                  category = HighwayType.null_type;
199                }
200              } else if (key == TagConstants.OneWayTag) {
201                oneWayRoad = value.Equals(TagConstants.YesValue);
202              }
203            }
204            reader.Read();
205          }
206          if (missingNodes) {
207            // TODO: Error/Trace output
208            // if Way xxx has incomplete nodes. At least one node was missing in the data.
209          }
210          for (int i = 0; i < way.Count - 1; i++) {
211            Vertex v1 = way[i];
212            graph.AddVertex(v1);
213            Vertex v2 = way[i + 1];
214            graph.AddVertex(v2);
215            //short vertexCategory = (short)category;
216            float weight = costCalculator.CalculateCosts(v1, v2, category);
217            if (oneWayRoad) {
218              Edge<Vertex> edge = new Edge<Vertex>(v1, v2, weight);
219              graph.AddEdge(edge);
220            } else {
221              Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2, weight);
222              graph.AddEdge(edgeForward);
223
224              Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1, weight);
225              graph.AddEdge(edgeBackward);
226            }
227          }
228          reader.Read();
229        }
230        reader.Close();
231      }
232    }
233
234    //private float CalculateWeight(Vertex s, Vertex t, HighwayType ht) {
235    //  double distanceKms = Utils.LocationDistance(s.Logitude, s.Latitude, t.Logitude, t.Latitude);
236    //  double weight = distanceKms;
237    //  return (float)weight;
238    //}
239
240    //private float CalculateWeight(Vertex s, Vertex t, HighwayType ht) {
241    //  double distanceKms = Utils.LocationDistance(s.Logitude, s.Latitude, t.Logitude, t.Latitude);
242    //  int speedKmH = GetMaxSpeed(ht);
243    //  double weight = (distanceKms / speedKmH) * 60;
244    //  return (float)weight;
245    //}
246  }
247}
Note: See TracBrowser for help on using the repository browser.