/Core/OsmSharp.Routing/Graph/DynamicGraph/Memory/MemoryDynamicGraph.cs

https://bitbucket.org/tscheinpflug/osmsharp · C# · 277 lines · 159 code · 19 blank · 99 comment · 25 complexity · bc0f35ee63caae616f5d7a27fafda200 MD5 · raw file

  1. // OsmSharp - OpenStreetMap tools & library.
  2. // Copyright (C) 2013 Abelshausen Ben
  3. //
  4. // This file is part of OsmSharp.
  5. //
  6. // OsmSharp is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 2 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // OsmSharp is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with OsmSharp. If not, see <http://www.gnu.org/licenses/>.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Text;
  22. using OsmSharp.Tools.Math.Geo.Simple;
  23. namespace OsmSharp.Routing.Graph.DynamicGraph.Memory
  24. {
  25. /// <summary>
  26. /// An implementation of an in-memory dynamic graph.
  27. /// </summary>
  28. public class MemoryDynamicGraph<EdgeData> : IDynamicGraph<EdgeData>
  29. where EdgeData : IDynamicGraphEdgeData
  30. {
  31. /// <summary>
  32. /// Holds the next id.
  33. /// </summary>
  34. private uint _next_id;
  35. /// <summary>
  36. /// Holds all graph data.
  37. /// </summary>
  38. private KeyValuePair<uint, EdgeData>[][] _vertices;
  39. /// <summary>
  40. /// Holds the coordinates of the vertices.
  41. /// </summary>
  42. private GeoCoordinateSimple[] _coordinates;
  43. /// <summary>
  44. /// Creates a new in-memory graph.
  45. /// </summary>
  46. public MemoryDynamicGraph()
  47. {
  48. _next_id = 1;
  49. _vertices = new KeyValuePair<uint, EdgeData>[1000][];
  50. _coordinates = new GeoCoordinateSimple[1000];
  51. }
  52. /// <summary>
  53. /// Increases the memory allocation for this dynamic graph.
  54. /// </summary>
  55. private void IncreaseSize()
  56. {
  57. Array.Resize<GeoCoordinateSimple>(ref _coordinates, _coordinates.Length + 1000);
  58. Array.Resize<KeyValuePair<uint, EdgeData>[]>(ref _vertices, _vertices.Length + 1000);
  59. }
  60. /// <summary>
  61. /// Adds a new vertex to this graph.
  62. /// </summary>
  63. /// <param name="latitude"></param>
  64. /// <param name="longitude"></param>
  65. /// <param name="neighbours_estimate"></param>
  66. /// <returns></returns>
  67. public uint AddVertex(float latitude, float longitude, byte neighbours_estimate)
  68. {
  69. return this.AddVertex(latitude, longitude);
  70. }
  71. /// <summary>
  72. /// Adds a new vertex.
  73. /// </summary>
  74. /// <param name="latitude"></param>
  75. /// <param name="longitude"></param>
  76. /// <returns></returns>
  77. public uint AddVertex(float latitude, float longitude)
  78. {
  79. // make sure vertices array is large enough.
  80. if (_next_id >= _vertices.Length)
  81. {
  82. this.IncreaseSize();
  83. }
  84. // create vertex.
  85. uint new_id = _next_id;
  86. _vertices[new_id] = null;
  87. _coordinates[new_id] = new GeoCoordinateSimple()
  88. {
  89. Latitude = latitude,
  90. Longitude = longitude
  91. };
  92. _next_id++; // increase for next vertex.
  93. return new_id;
  94. }
  95. /// <summary>
  96. /// Returns the information in the current vertex.
  97. /// </summary>
  98. /// <param name="id"></param>
  99. /// <param name="latitude"></param>
  100. /// <param name="longitude"></param>
  101. /// <returns></returns>
  102. public bool GetVertex(uint id, out float latitude, out float longitude)
  103. {
  104. if (_vertices.Length > id)
  105. {
  106. latitude = _coordinates[id].Latitude;
  107. longitude = _coordinates[id].Longitude;
  108. return true;
  109. }
  110. latitude = float.MaxValue;
  111. longitude = float.MaxValue;
  112. return false;
  113. }
  114. /// <summary>
  115. /// Returns an enumerable of all vertices.
  116. /// </summary>
  117. /// <returns></returns>
  118. public IEnumerable<uint> GetVertices()
  119. {
  120. if (_next_id > 1)
  121. {
  122. return OsmSharp.Tools.Range.UInt32(1, (uint)_next_id - 1, 1U);
  123. }
  124. return new List<uint>();
  125. }
  126. /// <summary>
  127. /// Adds and arc to an existing vertex.
  128. /// </summary>
  129. /// <param name="from"></param>
  130. /// <param name="to"></param>
  131. /// <param name="data"></param>
  132. /// <param name="comparer"></param>
  133. public void AddArc(uint from, uint to, EdgeData data, IDynamicGraphEdgeComparer<EdgeData> comparer)
  134. {
  135. if (_vertices.Length > from)
  136. {
  137. KeyValuePair<uint, EdgeData>[] arcs =
  138. _vertices[from];
  139. int idx = -1;
  140. if (arcs != null)
  141. { // check for an existing edge first.
  142. for (int arc_idx = 0; arc_idx < arcs.Length; arc_idx++)
  143. {
  144. if (arcs[arc_idx].Key == to &&
  145. arcs[arc_idx].Value.Weight > data.Weight &&
  146. (comparer != null && comparer.Overlaps(arcs[arc_idx].Value, data)))
  147. { // an arc was found that represents the same directional information.
  148. arcs[arc_idx] = new KeyValuePair<uint, EdgeData>(
  149. to, data);
  150. return;
  151. }
  152. }
  153. // if here: there did not exist an edge yet!
  154. idx = arcs.Length;
  155. Array.Resize<KeyValuePair<uint, EdgeData>>(ref arcs, arcs.Length + 1);
  156. _vertices[from] = arcs;
  157. }
  158. else
  159. { // create an arcs array.
  160. arcs = new KeyValuePair<uint, EdgeData>[1];
  161. idx = 0;
  162. _vertices[from] = arcs;
  163. }
  164. // set the arc.
  165. arcs[idx] = new KeyValuePair<uint, EdgeData>(
  166. to, data);
  167. return;
  168. }
  169. throw new ArgumentOutOfRangeException("from");
  170. }
  171. /// <summary>
  172. /// Removes all arcs starting at from ending at to.
  173. /// </summary>
  174. /// <param name="from"></param>
  175. /// <param name="to"></param>
  176. public void DeleteArc(uint from, uint to)
  177. {
  178. if (_vertices.Length > from)
  179. {
  180. KeyValuePair<uint, EdgeData>[] arcs =
  181. _vertices[from];
  182. if (arcs != null && arcs.Length > 0)
  183. {
  184. List<KeyValuePair<uint, EdgeData>> arcs_list =
  185. new List<KeyValuePair<uint, EdgeData>>(arcs);
  186. foreach (KeyValuePair<uint, EdgeData> arc in arcs)
  187. {
  188. if (arc.Key == to)
  189. {
  190. arcs_list.Remove(arc);
  191. }
  192. }
  193. _vertices[from] = arcs_list.ToArray();
  194. }
  195. return;
  196. }
  197. throw new ArgumentOutOfRangeException("from");
  198. }
  199. /// <summary>
  200. /// Returns all arcs starting at the given vertex.
  201. /// </summary>
  202. /// <param name="vertex"></param>
  203. /// <returns></returns>
  204. public KeyValuePair<uint, EdgeData>[] GetArcs(uint vertex)
  205. {
  206. if (_vertices.Length > vertex)
  207. {
  208. if (_vertices[vertex] == null)
  209. {
  210. return new KeyValuePair<uint, EdgeData>[0];
  211. }
  212. return _vertices[vertex];
  213. }
  214. return new KeyValuePair<uint, EdgeData>[0]; // return empty data if the vertex does not exist!
  215. }
  216. /// <summary>
  217. /// Returns true if the given vertex has neighbour as a neighbour.
  218. /// </summary>
  219. /// <param name="vertex"></param>
  220. /// <param name="neighbour"></param>
  221. /// <returns></returns>
  222. public bool HasNeighbour(uint vertex, uint neighbour)
  223. {
  224. if (_vertices.Length > vertex)
  225. {
  226. if (_vertices[vertex] == null)
  227. {
  228. return false;
  229. }
  230. foreach(KeyValuePair<uint, EdgeData> arc in _vertices[vertex])
  231. {
  232. if (arc.Key == neighbour)
  233. {
  234. return true;
  235. }
  236. }
  237. }
  238. return false;
  239. }
  240. ///// <summary>
  241. ///// Represents a simple vertex.
  242. ///// </summary>
  243. //private struct Vertex
  244. //{
  245. // /// <summary>
  246. // /// Holds an array of edges starting at this vertex.
  247. // /// </summary>
  248. // public KeyValuePair<uint, EdgeData>[] Arcs { get; set; }
  249. //}
  250. /// <summary>
  251. /// Returns the number of vertices in this graph.
  252. /// </summary>
  253. public uint VertexCount
  254. {
  255. get { return _next_id - 1; }
  256. }
  257. }
  258. }