Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1894:

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