Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1894:
Dijkstra: get node with a specific rank
graph interface extended: get vertices
fixed bug in ReadData method
methods to perform routing algorithm benchmark added to test program

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