Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1894:

  • fixed problem with edge category in XmlDataSource
  • initial version for new DIMACS data source
File size: 7.9 KB
Line 
1
2using System.Collections.Generic;
3using System.IO;
4using System.Xml;
5using HeuristicLab.Problems.RoutePlanning.Graph;
6namespace HeuristicLab.Problems.RoutePlanning.Osm.Data {
7  public class XmlDataSource : IDataSource {
8    private FileInfo file;
9
10    private IDictionary<long, Node> nodes;
11    private IDictionary<long, Way> ways;
12    private IDictionary<long, Relation> relations;
13
14    private IDictionary<long, List<long>> nodeWays;
15
16
17    #region Properties
18
19    public bool IsReadOnly {
20      get {
21        if (file.Exists && file.IsReadOnly) {
22          return true;
23        }
24        return false;
25      }
26    }
27
28    public string Name {
29      get { return file.Name; }
30    }
31
32    #endregion
33
34    #region Constructors
35
36    public XmlDataSource(string filename) {
37      file = new FileInfo(filename);
38
39      nodes = new Dictionary<long, Node>();
40      ways = new Dictionary<long, Way>();
41      relations = new Dictionary<long, Relation>();
42
43      nodeWays = new Dictionary<long, List<long>>();
44
45      ReadData();
46    }
47
48    #endregion
49
50    #region Public Methods
51
52    public Node GetNode(long nodeId) {
53      if (nodes.ContainsKey(nodeId)) {
54        return nodes[nodeId];
55      }
56      return null;
57    }
58
59    public Way GetWay(long wayId) {
60      if (ways.ContainsKey(wayId)) {
61        return ways[wayId];
62      }
63      return null;
64    }
65
66    public List<Way> GetWays(Node node) {
67      if (nodeWays.ContainsKey(node.Id)) {
68        List<long> wayIds = nodeWays[node.Id];
69        List<Way> result = new List<Way>(wayIds.Count);
70        for (int i = 0; i < wayIds.Count; i++) {
71          result.Add(GetWay(wayIds[i]));
72        }
73        return result;
74      }
75      return null;
76    }
77
78    public Relation GetRelation(long relationId) {
79      if (relations.ContainsKey(relationId)) {
80        return relations[relationId];
81      }
82      return null;
83    }
84
85    public IGraph GetRoutingGraph() {
86      IGraph graph = new Graph.Graph();
87      foreach (Way way in ways.Values) {
88        List<Node> nodes = way.Nodes;
89        for (int i = 0; i < way.Nodes.Count - 1; i++) {
90          Vertex v1 = new Vertex(nodes[i].Id, nodes[i].Longitude, nodes[i].Latitude);
91          graph.AddVertex(v1);
92          Vertex v2 = new Vertex(nodes[i + 1].Id, nodes[i + 1].Longitude, nodes[i + 1].Latitude);
93
94          // ---------------------------------------
95          //long id = 314973778;
96          //if (v1.Id == id || v2.Id == id) {
97          //  Console.WriteLine();
98          //}
99          // ---------------------------------------
100          graph.AddVertex(v2);
101          short category = (short)way.HighwayTag;
102          if (way.OneWay) {
103            Edge<Vertex> edge = new Edge<Vertex>(v1, v2, category);
104            graph.AddEdge(edge);
105          } else {
106            Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2, category);
107            graph.AddEdge(edgeForward);
108
109            Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1, category);
110            graph.AddEdge(edgeBackward);
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.