Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Problems.RoutePlanning/3.3/Osm.Data/XmlDataSource.cs @ 8471

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

#1894:

  • calculate distance in kilometers for two locations
  • generate IGraph from a datasource
  • adapted test program
File size: 7.8 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using System.IO;
5using System.Xml;
6using HeuristicLab.Problems.RoutePlanning.Graph;
7namespace HeuristicLab.Problems.RoutePlanning.Osm.Data {
8  public class XmlDataSource : IDataSource {
9    private FileInfo file;
10
11    private IDictionary<long, Node> nodes;
12    private IDictionary<long, Way> ways;
13    private IDictionary<long, Relation> relations;
14
15    private IDictionary<long, List<long>> nodeWays;
16
17
18    #region Properties
19
20    public bool IsReadOnly {
21      get {
22        if (file.Exists && file.IsReadOnly) {
23          return true;
24        }
25        return false;
26      }
27    }
28
29    public string Name {
30      get { return file.Name; }
31    }
32
33    #endregion
34
35    #region Constructors
36
37    public XmlDataSource(string filename) {
38      file = new FileInfo(filename);
39
40      nodes = new Dictionary<long, Node>();
41      ways = new Dictionary<long, Way>();
42      relations = new Dictionary<long, Relation>();
43
44      nodeWays = new Dictionary<long, List<long>>();
45
46      ReadData();
47    }
48
49    #endregion
50
51    #region Public Methods
52
53    public Node GetNode(long nodeId) {
54      if (nodes.ContainsKey(nodeId)) {
55        return nodes[nodeId];
56      }
57      return null;
58    }
59
60    public Way GetWay(long wayId) {
61      if (ways.ContainsKey(wayId)) {
62        return ways[wayId];
63      }
64      return null;
65    }
66
67    public List<Way> GetWays(Node node) {
68      if (nodeWays.ContainsKey(node.Id)) {
69        List<long> wayIds = nodeWays[node.Id];
70        List<Way> result = new List<Way>(wayIds.Count);
71        for (int i = 0; i < wayIds.Count; i++) {
72          result.Add(GetWay(wayIds[i]));
73        }
74        return result;
75      }
76      return null;
77    }
78
79    public Relation GetRelation(long relationId) {
80      if (relations.ContainsKey(relationId)) {
81        return relations[relationId];
82      }
83      return null;
84    }
85
86    public IGraph GetRoutingGraph() {
87      IGraph graph = new Graph.Graph();
88      foreach (Way way in ways.Values) {
89        List<Node> nodes = way.Nodes;
90        for (int i = 0; i < way.Nodes.Count - 1; i++) {
91          Vertex v1 = new Vertex(nodes[i].Id, nodes[i].Longitude, nodes[i].Latitude);
92          graph.AddVertex(v1);
93          Vertex v2 = new Vertex(nodes[i + 1].Id, nodes[i + 1].Longitude, nodes[i + 1].Latitude);
94          if (v1.Id == 370626403) {
95            Console.WriteLine();
96          }
97          graph.AddVertex(v2);
98          if (way.OneWay) {
99            Edge<Vertex> edge = new Edge<Vertex>(v1, v2);
100            edge.Category = (short)way.HighwayTag;
101            graph.AddEdge(edge);
102          } else {
103            Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2);
104            edgeForward.Category = (short)way.HighwayTag;
105            graph.AddEdge(edgeForward);
106
107            Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1);
108            edgeForward.Category = (short)way.HighwayTag;
109            graph.AddEdge(edgeBackward);
110          }
111
112        }
113      }
114      return graph;
115    }
116
117    #endregion
118
119    #region Private Methods
120
121    private void ReadData() {
122      XmlReaderSettings settings = new XmlReaderSettings();
123      settings.IgnoreComments = true;
124      settings.IgnoreWhitespace = true;
125
126      using (XmlReader reader = XmlReader.Create(file.FullName, settings)) {
127        reader.ReadStartElement("osm");
128        //reader.ReadStartElement("bounds");
129        reader.Read();
130        while (reader.LocalName.Equals("node")) {
131          Node node = new Node();
132
133          double lat = XmlConvert.ToDouble(reader.GetAttribute("lat"));
134          double lon = XmlConvert.ToDouble(reader.GetAttribute("lon"));
135
136          GetBaseAttributes(reader, node);
137          node.Latitude = lat;
138          node.Longitude = lon;
139
140          reader.Read();
141          if (reader.LocalName.Equals("tag")) {
142            while (reader.LocalName.Equals("tag")) {
143              string key = reader.GetAttribute("k");
144              string value = reader.GetAttribute("v");
145              node.Tags.Add(key, value);
146              reader.Read();
147            }
148            reader.Read();
149          }
150
151          nodes.Add(node.Id, node);
152        }
153        while (reader.LocalName.Equals("way")) {
154          Way way = new Way();
155          GetBaseAttributes(reader, way);
156          reader.Read();
157          bool missingNodes = false;
158          while (reader.LocalName.Equals("nd") || reader.LocalName.Equals("tag")) {
159            if (reader.LocalName.Equals("nd")) {
160              long refNodeId = XmlConvert.ToInt64(reader.GetAttribute("ref"));
161              Node refNode = GetNode(refNodeId);
162              if (refNode != null) {
163                way.Nodes.Add(refNode);
164              } else {
165                missingNodes = true;
166              }
167
168            } else if (reader.LocalName.Equals("tag")) {
169              string key = reader.GetAttribute("k");
170              string value = reader.GetAttribute("v");
171              way.Tags.Add(key, value);
172            }
173            reader.Read();
174          }
175          if (missingNodes) {
176            // TODO: Error/Trace output
177            // if Way xxx has incomplete nodes. At least one node was missing in the data.
178          }
179          ways.Add(way.Id, way);
180          InsertNodeWayRelation(way);
181
182          reader.Read();
183        }
184        while (reader.LocalName.Equals("relation")) {
185          Relation relation = new Relation();
186          GetBaseAttributes(reader, relation);
187
188          reader.Read();
189          while (reader.LocalName.Equals("member") || reader.LocalName.Equals("tag")) {
190            if (reader.LocalName.Equals("member")) {
191              string type = reader.GetAttribute("type");
192              long refNodeId = XmlConvert.ToInt64(reader.GetAttribute("ref"));
193              string role = reader.GetAttribute("role");
194              RelationMember member = new RelationMember();
195              member.Role = role;
196              if (type == "node") {
197                member.Member = GetNode(refNodeId);
198              } else if (type == "way") {
199                member.Member = GetWay(refNodeId);
200              }
201              relation.Members.Add(member);
202            } else if (reader.LocalName.Equals("tag")) {
203              string key = reader.GetAttribute("k");
204              string value = reader.GetAttribute("v");
205              relation.Tags.Add(key, value);
206            }
207            reader.Read();
208          }
209
210          relations.Add(relation.Id, relation);
211
212          reader.Read();
213        }
214        reader.Close();
215      }
216    }
217
218    private void GetBaseAttributes(XmlReader reader, OsmBase obj) {
219      obj.Id = XmlConvert.ToInt64(reader.GetAttribute("id"));
220      //Console.WriteLine("id:" + obj.Id);
221
222      if (reader.GetAttribute("user") != null) {
223        obj.User = reader.GetAttribute("user");
224      }
225      if (reader.GetAttribute("uid") != null) {
226        obj.UserId = XmlConvert.ToInt32(reader.GetAttribute("uid"));
227      }
228      if (reader.GetAttribute("visible") != null) {
229        obj.Visible = XmlConvert.ToBoolean(reader.GetAttribute("visible"));
230      }
231      if (reader.GetAttribute("version") != null) {
232        obj.Version = XmlConvert.ToInt32(reader.GetAttribute("version"));
233      }
234      if (reader.GetAttribute("changeset") != null) {
235        obj.Changeset = XmlConvert.ToInt64(reader.GetAttribute("changeset"));
236      }
237      if (reader.GetAttribute("timestamp") != null) {
238        obj.Timestamp = XmlConvert.ToDateTime(reader.GetAttribute("timestamp"), XmlDateTimeSerializationMode.Utc);
239      }
240
241    }
242
243    private void InsertNodeWayRelation(Way way) {
244      foreach (Node node in way.Nodes) {
245        if (!nodeWays.ContainsKey(node.Id)) {
246          nodeWays.Add(node.Id, new List<long>());
247        }
248        nodeWays[node.Id].Add(way.Id);
249      }
250    }
251
252    #endregion
253  }
254}
Note: See TracBrowser for help on using the repository browser.