diff --git a/OSMDatastructure/Region.cs b/OSMDatastructure/Region.cs index 55e83f6..1c2f0b9 100644 --- a/OSMDatastructure/Region.cs +++ b/OSMDatastructure/Region.cs @@ -1,3 +1,4 @@ +using System.Runtime.Serialization.Formatters.Binary; using OSMDatastructure.Graph; namespace OSMDatastructure; @@ -7,7 +8,6 @@ public class Region { [NonSerialized]public const float RegionSize = 0.1f; public readonly HashSet nodes = new(); - public readonly HashSet ways = new(); public ulong regionHash { get; } public TagManager tagManager { get; } @@ -23,11 +23,43 @@ public class Region tagManager = new TagManager(); } - public OsmNode? GetNodeWithCoordinates(Coordinates coordinates) + public bool ContainsNode(ulong id) { - foreach(OsmNode node in this.nodes) - if (node.coordinates.Equals(coordinates)) - return node; - return null; + return nodes.Any(node => node.nodeId == id); + } + + public bool ContainsNode(Coordinates coordinates) + { + return nodes.Any(node => node.coordinates.Equals(coordinates)); + } + + public OsmNode? GetNode(ulong id) + { + if (ContainsNode(id)) + return nodes.First(node => node.nodeId == id); + else return null; + } + + public OsmNode? GetNode(Coordinates coordinates) + { + if (ContainsNode(coordinates)) + return nodes.First(node => node.coordinates.Equals(coordinates)); + else return null; + } + + public static Region? FromFile(string filePath) + { + BinaryFormatter bFormatter = new BinaryFormatter(); +#pragma warning disable SYSLIB0011 + if (File.Exists(filePath)) + return (Region)bFormatter.Deserialize(new FileStream(filePath, FileMode.Open)); +#pragma warning restore SYSLIB0011 + else return null; + } + + public static Region? FromId(string path, ulong regionId) + { + string filePath = Path.Join(path, $"{regionId}.region"); + return FromFile(filePath); } } \ No newline at end of file diff --git a/Pathfinding/RegionManager.cs b/Pathfinding/RegionManager.cs index e4d0ec2..23f3aee 100644 --- a/Pathfinding/RegionManager.cs +++ b/Pathfinding/RegionManager.cs @@ -50,7 +50,7 @@ namespace OSMImporter public OsmNode? GetNode(Coordinates coordinates) { Region regionWithNode = GetRegion(coordinates); - return regionWithNode.GetNodeWithCoordinates(coordinates); + return regionWithNode.GetNode(coordinates); } } } \ No newline at end of file diff --git a/Server/RegionConverter.cs b/Server/RegionConverter.cs index 3b4ebcc..bd61438 100644 --- a/Server/RegionConverter.cs +++ b/Server/RegionConverter.cs @@ -1,6 +1,7 @@ using System.Globalization; using System.Runtime.Serialization.Formatters.Binary; using System.Xml; +using OSMDatastructure; using OSMDatastructure.Graph; namespace Server; @@ -19,7 +20,8 @@ public class RegionConverter public const string NodesFileName = "region.nodes"; public const string WaysFileName = "region.ways"; - public const string tagsFileName = "region.tags"; + public const string TagsFileName = "region.tags"; + public const string RegionsFileName = ".region"; public static void ConvertXMLToRegions(string filePath, string outputPath) { @@ -35,6 +37,11 @@ public class RegionConverter Console.WriteLine("Converting Ways..."); ImportWays(XmlReader.Create(xmlFileStream, ReaderSettings), nodeIdRegionDict, outputPath); + xmlFileStream.Dispose(); + + Console.WriteLine("Combining tmpFiles into region"); + CombineTmpFiles(outputPath, nodeIdRegionDict.Values.ToHashSet()); + } private static Dictionary GetNodesAndRegions(XmlReader xmlReader, string outputPath) @@ -198,7 +205,7 @@ public class RegionConverter BinaryFormatter bFormatter = new BinaryFormatter(); if (!regionTagsFileStreams.ContainsKey(regionHash)) { - string tagsRegionPath = Path.Combine(outputPath, regionHash.ToString(), tagsFileName); + string tagsRegionPath = Path.Combine(outputPath, regionHash.ToString(), TagsFileName); regionTagsFileStreams.Add(regionHash, new FileStream(tagsRegionPath, FileMode.OpenOrCreate)); } @@ -211,4 +218,69 @@ public class RegionConverter bFormatter.Serialize(regionTagsFileStreams[regionHash], tm); #pragma warning restore SYSLIB0011 } + + private static void CombineTmpFiles(string folderPath, HashSet regionHashes) + { + BinaryFormatter bFormatter = new BinaryFormatter(); + foreach (ulong regionId in regionHashes) + { + ValueTuple> tmpRegion = LoadRegion(folderPath, regionId); + foreach (OsmEdge edge in tmpRegion.Item2) + { + OsmNode? startNode = tmpRegion.Item1.GetNode(edge.startId); + if (startNode is not null) + { + startNode.edges.Add(edge); + } + } + FileStream tmpRegionFileStream = new FileStream(Path.Join(folderPath, $"{regionId}{RegionsFileName}"), FileMode.Create); +#pragma warning disable SYSLIB0011 + bFormatter.Serialize(tmpRegionFileStream, tmpRegion.Item1); +#pragma warning restore SYSLIB0011 + tmpRegionFileStream.Dispose(); + Directory.Delete(Path.Join(folderPath, regionId.ToString()), true); + } + } + + private static ValueTuple> LoadRegion(string folderPath, ulong regionHash) + { + Region newRegion = new Region(regionHash); + HashSet ways = new(); + BinaryFormatter bFormatter = new BinaryFormatter(); + if (!Directory.Exists(Path.Join(folderPath, regionHash.ToString()))) + throw new FileNotFoundException("Region does not exist"); + +#pragma warning disable SYSLIB0011 + using (FileStream wayFileStream = new FileStream(Path.Join(folderPath, regionHash.ToString(), RegionConverter.WaysFileName), FileMode.Open)) + { + while (wayFileStream.Position < wayFileStream.Length) + { + OsmEdge deserializedEdge = (OsmEdge)bFormatter.Deserialize(wayFileStream); + ways.Add(deserializedEdge); + } + } + + using (FileStream nodeFileStream = new FileStream(Path.Join(folderPath, regionHash.ToString(), RegionConverter.NodesFileName), FileMode.Open)) + { + while (nodeFileStream.Position < nodeFileStream.Length) + { + OsmNode deserializedNode = (OsmNode)bFormatter.Deserialize(nodeFileStream); + newRegion.nodes.Add(deserializedNode); + } + } + + using (FileStream tagsFileStream = new FileStream(Path.Join(folderPath, regionHash.ToString(), RegionConverter.TagsFileName), FileMode.Open)) + { + while (tagsFileStream.Position < tagsFileStream.Length) + { + TagManager tm = (TagManager)bFormatter.Deserialize(tagsFileStream); + ulong id = (ulong)tm.wayTagSets.First()!.Value.First(tag => tag.key == Tag.TagType.id)!.value; + foreach(Tag tag in tm.wayTagSets.First()!.Value) + newRegion.tagManager.AddTag(id, tag); + } + } +#pragma warning restore SYSLIB0011 + + return new ValueTuple>(newRegion, ways); + } } \ No newline at end of file diff --git a/Server/RegionLoader.cs b/Server/RegionLoader.cs deleted file mode 100644 index 8f0d741..0000000 --- a/Server/RegionLoader.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Runtime.Serialization.Formatters.Binary; -using OSMDatastructure; -using OSMDatastructure.Graph; - -namespace Server; - -public class RegionLoader -{ - private string path { get; } - private Dictionary regionIdsDict; - public RegionLoader(string path) - { - this.path = path; - this.regionIdsDict = new(); - } - - public HashSet GetNodes(ulong regionHash) - { - Region r = GetRegion(regionHash); - return r.nodes; - } - - public HashSet GetWays(ulong regionHash) - { - Region r = GetRegion(regionHash); - return r.ways; - } - - public TagManager GetTags(ulong regionHash) - { - Region r = GetRegion(regionHash); - return r.tagManager; - } - - public HashSet? GetTagsForWay(ulong regionHash, ulong wayId) - { - Region r = GetRegion(regionHash); - return r.tagManager.GetTagsForWayId(wayId); - } - - public Region GetRegion(ulong regionHash) - { - if (regionIdsDict.ContainsKey(regionHash)) - return regionIdsDict[regionHash]; - else return LoadRegion(regionHash); - } - - private Region LoadRegion(ulong regionHash) - { - Region newRegion = new Region(regionHash); - BinaryFormatter bFormatter = new BinaryFormatter(); - if (regionIdsDict.ContainsKey(regionHash)) - throw new Exception("Region already loaded"); - if (!Directory.Exists(Path.Join(path, regionHash.ToString()))) - throw new FileNotFoundException("Region does not exist"); - -#pragma warning disable SYSLIB0011 - using (FileStream wayFileStream = new FileStream(Path.Join(path, regionHash.ToString(), RegionConverter.WaysFileName), FileMode.Open)) - { - while (wayFileStream.Position < wayFileStream.Length) - { - OsmEdge deserializedEdge = (OsmEdge)bFormatter.Deserialize(wayFileStream); - newRegion.ways.Add(deserializedEdge); - } - } - - using (FileStream nodeFileStream = new FileStream(Path.Join(path, regionHash.ToString(), RegionConverter.NodesFileName), FileMode.Open)) - { - while (nodeFileStream.Position < nodeFileStream.Length) - { - OsmNode deserializedNode = (OsmNode)bFormatter.Deserialize(nodeFileStream); - newRegion.nodes.Add(deserializedNode); - } - } - - using (FileStream tagsFileStream = new FileStream(Path.Join(path, regionHash.ToString(), RegionConverter.tagsFileName), FileMode.Open)) - { - while (tagsFileStream.Position < tagsFileStream.Length) - { - TagManager tm = (TagManager)bFormatter.Deserialize(tagsFileStream); - ulong id = (ulong)tm.wayTagSets.First()!.Value.First(tag => tag.key == Tag.TagType.id)!.value; - foreach(Tag tag in tm.wayTagSets.First()!.Value) - newRegion.tagManager.AddTag(id, tag); - } - } -#pragma warning restore SYSLIB0011 - - regionIdsDict.Add(regionHash, newRegion); - return newRegion; - } -} \ No newline at end of file