[8516] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.IO;
|
---|
| 4 | using System.Xml;
|
---|
[8520] | 5 | using HeuristicLab.Problems.RoutePlanning.Data.Core;
|
---|
| 6 | using HeuristicLab.Problems.RoutePlanning.Data.Osm.Core;
|
---|
[8516] | 7 | using HeuristicLab.Problems.RoutePlanning.Interfaces;
|
---|
| 8 | using HeuristicLab.Problems.RoutePlanning.RoutingGraph;
|
---|
| 9 |
|
---|
| 10 | namespace HeuristicLab.Problems.RoutePlanning.Data.Osm {
|
---|
| 11 | public class OsmDataSource : IDataSource {
|
---|
| 12 | private FileInfo file;
|
---|
[8520] | 13 | private ICostCalculator costCalculator;
|
---|
| 14 | private IGraph graph;
|
---|
[8516] | 15 | private Dictionary<long, Vertex> vertices;
|
---|
| 16 |
|
---|
[8520] | 17 | public OsmDataSource(string filename)
|
---|
| 18 | : this(filename, new TravelTimeCostCalculator()) {
|
---|
| 19 | }
|
---|
| 20 |
|
---|
| 21 | public OsmDataSource(string filename, ICostCalculator costCalc) {
|
---|
[8516] | 22 | file = new FileInfo(filename);
|
---|
[8520] | 23 | costCalculator = costCalc;
|
---|
[8516] | 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 |
|
---|
[8520] | 36 | public IGraph GetRoutingGraph(VehicleType vehicle) {
|
---|
| 37 | throw new NotImplementedException();
|
---|
| 38 | }
|
---|
| 39 |
|
---|
[8516] | 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);
|
---|
[8520] | 116 | //short vertexCategory = (short)category;
|
---|
| 117 | float weight = costCalculator.CalculateCosts(v1, v2, category);
|
---|
[8516] | 118 | if (oneWayRoad) {
|
---|
[8520] | 119 | Edge<Vertex> edge = new Edge<Vertex>(v1, v2, weight);
|
---|
[8516] | 120 | graph.AddEdge(edge);
|
---|
| 121 | } else {
|
---|
[8520] | 122 | Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2, weight);
|
---|
[8516] | 123 | graph.AddEdge(edgeForward);
|
---|
| 124 |
|
---|
[8520] | 125 | Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1, weight);
|
---|
[8516] | 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);
|
---|
[8520] | 215 | //short vertexCategory = (short)category;
|
---|
| 216 | float weight = costCalculator.CalculateCosts(v1, v2, category);
|
---|
[8516] | 217 | if (oneWayRoad) {
|
---|
[8520] | 218 | Edge<Vertex> edge = new Edge<Vertex>(v1, v2, weight);
|
---|
[8516] | 219 | graph.AddEdge(edge);
|
---|
| 220 | } else {
|
---|
[8520] | 221 | Edge<Vertex> edgeForward = new Edge<Vertex>(v1, v2, weight);
|
---|
[8516] | 222 | graph.AddEdge(edgeForward);
|
---|
| 223 |
|
---|
[8520] | 224 | Edge<Vertex> edgeBackward = new Edge<Vertex>(v2, v1, weight);
|
---|
[8516] | 225 | graph.AddEdge(edgeBackward);
|
---|
| 226 | }
|
---|
| 227 | }
|
---|
| 228 | reader.Read();
|
---|
| 229 | }
|
---|
| 230 | reader.Close();
|
---|
| 231 | }
|
---|
| 232 | }
|
---|
[8520] | 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 | //}
|
---|
[8516] | 246 | }
|
---|
| 247 | }
|
---|