From ac1ac62a00284fe770caa3639ab839b6b6e39083 Mon Sep 17 00:00:00 2001 From: glax Date: Thu, 30 Mar 2023 18:24:57 +0200 Subject: [PATCH] Combining Datastructures and Serialization //TODO --- OSMDatastructure/ByteConverter.cs | 272 ------------------ OSMDatastructure/Coordinates.cs | 30 +- OSMDatastructure/OSMEdge.cs | 226 +-------------- OSMDatastructure/OsmNode.cs | 20 +- OSMDatastructure/Region.cs | 10 +- .../Tag.cs | 3 +- OSMDatastructure/TagManager.cs | 45 +++ OsmXmlToRegionConverter/ByteConverter.cs | 259 ----------------- OsmXmlToRegionConverter/Coordinates.cs | 71 ----- OsmXmlToRegionConverter/Edge.cs | 36 --- OsmXmlToRegionConverter/Manager.cs | 228 --------------- OsmXmlToRegionConverter/Node.cs | 48 ---- .../OsmXmlToRegionConverter.csproj | 9 - OsmXmlToRegionConverter/Region.cs | 47 --- OsmXmlToRegionConverter/TagManager.cs | 70 ----- OsmXmlToRegionConverter/TmpNode.cs | 35 --- OsmXmlToRegionConverter/TmpWay.cs | 31 -- 17 files changed, 90 insertions(+), 1350 deletions(-) delete mode 100644 OSMDatastructure/ByteConverter.cs rename {OsmXmlToRegionConverter => OSMDatastructure}/Tag.cs (99%) create mode 100644 OSMDatastructure/TagManager.cs delete mode 100644 OsmXmlToRegionConverter/ByteConverter.cs delete mode 100644 OsmXmlToRegionConverter/Coordinates.cs delete mode 100644 OsmXmlToRegionConverter/Edge.cs delete mode 100644 OsmXmlToRegionConverter/Manager.cs delete mode 100644 OsmXmlToRegionConverter/Node.cs delete mode 100644 OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj delete mode 100644 OsmXmlToRegionConverter/Region.cs delete mode 100644 OsmXmlToRegionConverter/TagManager.cs delete mode 100644 OsmXmlToRegionConverter/TmpNode.cs delete mode 100644 OsmXmlToRegionConverter/TmpWay.cs diff --git a/OSMDatastructure/ByteConverter.cs b/OSMDatastructure/ByteConverter.cs deleted file mode 100644 index a74d30c..0000000 --- a/OSMDatastructure/ByteConverter.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System.Text; -using OSMDatastructure.Graph; - -namespace OSMDatastructure; - -public static class ByteConverter -{ - #region Region - /* - * | regionHash | Nodes | - * |---------------+---------------+ - * | 4 bytes | - * | int | - */ - public static byte[] GetBytes(Region region) - { - int totalNodeBytes = 0; - HashSet nodes = new(); - foreach (OsmNode node in region.nodes) - { - byte[] nodeBytes = GetBytes(node); - totalNodeBytes += nodeBytes.Length; - nodes.Add(nodeBytes); - } - - byte[] retBytes = new byte[sizeof(int) + totalNodeBytes]; - Array.Copy(BitConverter.GetBytes(region.regionHash), 0, retBytes, 0, sizeof(int)); - int offset = sizeof(int); - foreach (byte[] node in nodes) - { - Array.Copy(node, 0, retBytes, offset, node.Length); - offset += node.Length; - } - - return retBytes; - } - - public static Region ToRegion(byte[] bytes) - { - Region retRegion = new Region(BitConverter.ToInt32(bytes, 0)); - int offset = sizeof(int); - while (offset < bytes.Length) - { - int size = BitConverter.ToInt32(bytes, offset); - byte[] nodeBytes = new byte[size]; - Array.Copy(bytes, offset, nodeBytes, 0, size); - offset += size; - retRegion.nodes.Add(ToNode(nodeBytes)); - } - - return retRegion; - } - - #endregion - - #region Coordinates - - /* - * | Latitude | Longitude | - * |---------------+---------------+ - * | 4 bytes | 4 bytes | - * | float | float | - */ - - public static byte[] GetBytes(Coordinates coordinates) - { - byte[] retBytes = new byte[8]; - Array.Copy(BitConverter.GetBytes(coordinates.latitude), 0, retBytes, 0, sizeof(float)); - Array.Copy(BitConverter.GetBytes(coordinates.longitude), 0, retBytes, sizeof(float), sizeof(float)); - return retBytes; - } - - public static Coordinates ToCoordinates(byte[] bytes) - { - if (bytes.Length != 8) - throw new ArgumentException("Needs exactly 8 bytes", nameof(bytes)); - float latitude = BitConverter.ToSingle(bytes, 0); - float longitude = BitConverter.ToSingle(bytes, sizeof(float)); - return new Coordinates(latitude, longitude); - } - - #endregion - - #region OsmNode - - /* - * | Size | Coordinates | Edges - * |---------------+---------------+---------------+ - * | 4 bytes | 8 bytes | - * | int | byte[] | - */ - - public static byte[] GetBytes(OsmNode node) - { - int totalBytes = sizeof(int) + 8; //size + Coordinates - HashSet edges = new(); - foreach (OsmEdge edge in node.edges) - { - byte[] edgeBytes = GetBytes(edge); - edges.Add(edgeBytes); - totalBytes += edgeBytes.Length; - } - - byte[] retBytes = new byte[totalBytes]; - Array.Copy(BitConverter.GetBytes(totalBytes), retBytes, 4); - Array.Copy(GetBytes(node.coordinates), 0, retBytes, 4, 8); - int offset = 4 + 8; - foreach (byte[] edgeBytes in edges) - { - Array.Copy(edgeBytes, 0, retBytes, offset, edgeBytes.Length); - offset += edgeBytes.Length; - } - - return retBytes; - } - - public static OsmNode ToNode(byte[] bytes) - { - byte[] coordinateBytes = new byte[8]; - Array.Copy(bytes, 4, coordinateBytes, 0, 8); - Coordinates coordinates = ToCoordinates(coordinateBytes); - - OsmNode retNode = new OsmNode(coordinates); - - int offset = sizeof(int) + 8; - while (offset < bytes.Length) - { - int tagsSize = BitConverter.ToInt32(bytes, offset); - byte[] edgeBytes = new byte[sizeof(int) + 8 + tagsSize]; - Array.Copy(bytes, offset, edgeBytes, 0, edgeBytes.Length); - offset += edgeBytes.Length; - retNode.edges.Add(ToEdge(edgeBytes)); - } - - return retNode; - } - - #endregion - - #region OsmEdge - - /* Edge: - * | tagsSize | neighborCoord | tags - * |---------------+---------------+-------------- - * | 4 bytes | 8 bytes | - * | int | byte[] | - * - */ - - public static byte[] GetBytes(OsmEdge edge) - { - int totalBytes = sizeof(int) + 8; //size + Coordinates - int offset = totalBytes; - - int tagsSize = 0; - HashSet tags = new(); - foreach (KeyValuePair kv in edge.tags) - { - byte[] tagBytes = GetBytes(kv); - tags.Add(tagBytes); - tagsSize += tagBytes.Length; - } - - totalBytes += tagsSize; - byte[] retBytes = new byte[totalBytes]; - Array.Copy(BitConverter.GetBytes(tagsSize), retBytes, 4); - Array.Copy(GetBytes(edge.neighborCoordinates), 0, retBytes, sizeof(int), 8); - - foreach (byte[] tag in tags) - { - Array.Copy(tag, 0, retBytes, offset, tag.Length); - offset += tag.Length; - } - - return retBytes; - } - - public static OsmEdge ToEdge(byte[] bytes) - { - byte[] coordinateBytes = new byte[8]; - Array.Copy(bytes, 4, coordinateBytes, 0, 8); - Coordinates coordinates = ToCoordinates(coordinateBytes); - - OsmEdge retEdge = new OsmEdge(coordinates); - - int offset = sizeof(int) + 8; - while (offset < bytes.Length) - { - int tagContentSize = BitConverter.ToInt32(bytes, offset); - byte[] tagBytes = new byte[sizeof(int) + 1 + tagContentSize]; - Array.Copy(bytes, offset, tagBytes, 0, tagBytes.Length); - offset += tagBytes.Length; - KeyValuePair tag = ToTag(tagBytes); - retEdge.tags.Add(tag.Key, tag.Value); - } - - return retEdge; - } - - #endregion - - #region OsmEdge.Tag - /* - * Tag: - * | contentSize | tagType | tagContent - * |---------------+---------------+--------------- - * | 4 bytes | 1 byte | - * | int | byte | - */ - - public static byte[] GetBytes(KeyValuePair tag) - { - byte[] objectBytes; - Type objectType = tag.Value.GetType(); - if (objectType == Type.GetType("System.String")) - { - objectBytes = Encoding.ASCII.GetBytes((string)tag.Value); - } - else if (objectType == Type.GetType("System.Boolean")) - { - objectBytes = BitConverter.GetBytes((bool)tag.Value); - } - else if (objectType == Type.GetType("System.Int32")) - { - objectBytes = BitConverter.GetBytes((int)tag.Value); - } - else if (objectType == Type.GetType("System.UInt64")) - { - objectBytes = BitConverter.GetBytes((ulong)tag.Value); - } - else if (objectType == Type.GetType("System.Byte") || objectType.Name == "wayType") - { - objectBytes = new[] { (byte)tag.Value }; - } - else - { - throw new Exception(string.Format("Tag-Bytes object-Type: {0}", tag.Value.GetType())); - } - - byte[] retBytes = new byte[sizeof(int) + 1 + objectBytes.Length]; - Array.Copy(BitConverter.GetBytes(objectBytes.Length), 0, retBytes, 0, sizeof(int)); - retBytes[sizeof(int)] = (byte)tag.Key; - Array.Copy(objectBytes, 0, retBytes, sizeof(int) + 1, objectBytes.Length); - return retBytes; - } - - public static KeyValuePair ToTag(byte[] bytes) - { - OsmEdge.tagType tagType = (OsmEdge.tagType)bytes[sizeof(int)]; - int contentSize = BitConverter.ToInt32(bytes, 0); - byte[] content = new byte[contentSize]; - Array.Copy(bytes, sizeof(int) + 1, content, 0, contentSize); - - switch (tagType) - { - case OsmEdge.tagType.highway: - return new KeyValuePair(tagType, (OsmEdge.wayType)content[0]); - case OsmEdge.tagType.maxspeed: - return new KeyValuePair(tagType, content[0]); - case OsmEdge.tagType.oneway: - return new KeyValuePair(tagType, BitConverter.ToBoolean(content)); - case OsmEdge.tagType.forward: - return new KeyValuePair(tagType, BitConverter.ToBoolean(content)); - case OsmEdge.tagType.id: - return new KeyValuePair(tagType, BitConverter.ToUInt64(content)); - default: - return new KeyValuePair(tagType, content); - } - } - #endregion -} - diff --git a/OSMDatastructure/Coordinates.cs b/OSMDatastructure/Coordinates.cs index ec48f9b..2aa1bb5 100644 --- a/OSMDatastructure/Coordinates.cs +++ b/OSMDatastructure/Coordinates.cs @@ -1,5 +1,8 @@ +using System.Globalization; + namespace OSMDatastructure.Graph; +[Serializable] public class Coordinates { public float latitude { get; } @@ -20,37 +23,32 @@ public class Coordinates return convObj.latitude == this.latitude && convObj.longitude == this.longitude; } - private const float decimalCoordsSave = 10000; - private const ulong offset = 10000000; - //Latitude maxChars = 7 - //Longitude maxChars = 8 - - public override int GetHashCode() - { - return GetHashCode(latitude, longitude); - } - - public static int GetRegionHashCode(float latitude, float longitude) + public static ulong GetRegionHashCode(float latitude, float longitude) { float latRegion = latitude - latitude % Region.RegionSize; float lonRegion = longitude - longitude % Region.RegionSize; return GetHashCode(latRegion, lonRegion); } - public static int GetRegionHashCode(Coordinates coordinates) + public static ulong GetRegionHashCode(Coordinates coordinates) { float latRegion = coordinates.latitude - coordinates.latitude % Region.RegionSize; float lonRegion = coordinates.longitude - coordinates.longitude % Region.RegionSize; return GetHashCode(latRegion, lonRegion); } - - public static int GetHashCode(float latitude, float longitude) + + private const float decimalCoordsSave = 10000; //Latitude maxChars = 7 + private const ulong offset = 10000000; //Longitude maxChars = 8 + public static ulong GetHashCode(float latitude, float longitude) { - return HashCode.Combine(latitude, longitude); + ulong latHash = Convert.ToUInt64((latitude + 90) * decimalCoordsSave); + ulong lonHash = Convert.ToUInt64((longitude + 180) * decimalCoordsSave); + return latHash * offset + lonHash; } public override string ToString() { - return string.Format("COORDINATES Lat: {0} Lon: {1}", this.latitude, this.longitude); + return + $"COORDINATES Lat: {this.latitude.ToString(NumberFormatInfo.InvariantInfo)} Lon: {this.longitude.ToString(CultureInfo.InvariantCulture)}"; } } \ No newline at end of file diff --git a/OSMDatastructure/OSMEdge.cs b/OSMDatastructure/OSMEdge.cs index a6a9c2b..c1aec95 100644 --- a/OSMDatastructure/OSMEdge.cs +++ b/OSMDatastructure/OSMEdge.cs @@ -1,228 +1,22 @@ namespace OSMDatastructure.Graph; +[Serializable] public class OsmEdge { - public Coordinates neighborCoordinates { get; } - public readonly Dictionary tags = new(); - - public OsmEdge(float lat, float lon) - { - this.neighborCoordinates = new Coordinates(lat, lon); - this.tags = new(); - } + public ulong wayId { get; } + public ulong neighborId { get; } + public ulong neighborRegion { get; } - public OsmEdge(Coordinates neighborCoordinates) + + public OsmEdge(ulong wayID, ulong neighborID, ulong neighborRegion) { - this.neighborCoordinates = neighborCoordinates; - this.tags = new(); - } - - public OsmEdge(float lat, float lon, Dictionary tags) - { - this.neighborCoordinates = new Coordinates(lat, lon); - //To prevent "EMPTY" tags - foreach (KeyValuePair tag in tags) - { - if(tag.Key != tagType.EMPTY) - this.tags.Add(tag.Key, tag.Value); - } - } - - public OsmEdge(Coordinates neighborCoordinates, Dictionary tags) - { - this.neighborCoordinates = neighborCoordinates; - //To prevent "EMPTY" tags - foreach (KeyValuePair tag in tags) - { - if(tag.Key != tagType.EMPTY) - this.tags.Add(tag.Key, tag.Value); - } - } - - public enum tagType : byte - { - highway, oneway, footway, sidewalk, cycleway, busway, forward, maxspeed, name, surface, lanes, access, tracktype, id, EMPTY - } - - private static readonly Dictionary defaultSpeedCar = new() { - { wayType.NONE, 0 }, - { wayType.motorway, 110 }, - { wayType.trunk, 100 }, - { wayType.primary, 80 }, - { wayType.secondary, 80 }, - { wayType.tertiary, 70 }, - { wayType.unclassified, 20 }, - { wayType.residential, 10 }, - { wayType.motorway_link, 50 }, - { wayType.trunk_link, 50 }, - { wayType.primary_link, 30 }, - { wayType.secondary_link, 25 }, - { wayType.tertiary_link, 25 }, - { wayType.living_street, 10 }, - { wayType.service, 0 }, - { wayType.pedestrian, 0 }, - { wayType.track, 0 }, - { wayType.bus_guideway, 0 }, - { wayType.escape, 0 }, - { wayType.raceway, 0 }, - { wayType.road, 25 }, - { wayType.busway, 0 }, - { wayType.footway, 0 }, - { wayType.bridleway, 0 }, - { wayType.steps, 0 }, - { wayType.corridor, 0 }, - { wayType.path, 0 }, - { wayType.cycleway, 0 }, - { wayType.construction, 0 } - }; - - private static readonly Dictionary defaultSpeedPedestrian = new() { - { wayType.NONE, 0 }, - { wayType.motorway, 0 }, - { wayType.trunk, 0 }, - { wayType.primary, 0 }, - { wayType.secondary, 0 }, - { wayType.tertiary, 0 }, - { wayType.unclassified, 1 }, - { wayType.residential, 3 }, - { wayType.motorway_link, 0 }, - { wayType.trunk_link, 0 }, - { wayType.primary_link, 0 }, - { wayType.secondary_link, 0 }, - { wayType.tertiary_link, 0 }, - { wayType.living_street, 5 }, - { wayType.service, 2 }, - { wayType.pedestrian, 5 }, - { wayType.track, 0 }, - { wayType.bus_guideway, 0 }, - { wayType.escape, 0 }, - { wayType.raceway, 0 }, - { wayType.road, 3 }, - { wayType.busway, 0 }, - { wayType.footway, 4 }, - { wayType.bridleway, 1 }, - { wayType.steps, 2 }, - { wayType.corridor, 3 }, - { wayType.path, 4 }, - { wayType.cycleway, 2 }, - { wayType.construction, 0 } - }; - public enum wayType : byte { NONE, motorway, trunk, primary, secondary, tertiary, unclassified, residential, motorway_link, trunk_link, primary_link, secondary_link, tertiary_link, living_street, service, pedestrian, track, bus_guideway, escape, raceway, road, busway, footway, bridleway, steps, corridor, path, cycleway, construction } - - public enum speedType { pedestrian, car, road } - - public void AddTag(string key, string value) - { - KeyValuePair tag = ConvertToTag(key, value); - if(tag.Key != tagType.EMPTY) - tags.Add(tag.Key, tag.Value); - } - - public static KeyValuePair ConvertToTag(string key, string value) - { - switch (key) - { - case "highway": - try - { - return new KeyValuePair(tagType.highway, (wayType)Enum.Parse(typeof(wayType), value, true)); - } - catch (ArgumentException) - { - return new KeyValuePair(tagType.highway, wayType.unclassified); - } - case "maxspeed": - try - { - byte speed = Convert.ToByte(value); - if(speed == 255) - return new KeyValuePair(tagType.EMPTY, 0); - else - return new KeyValuePair(tagType.maxspeed, speed); - } - catch (Exception) - { - //Console.WriteLine(e); - //Console.WriteLine("Continuing..."); - return new KeyValuePair(tagType.maxspeed, byte.MaxValue); - } - case "oneway": - switch (value) - { - case "yes": - return new KeyValuePair(tagType.oneway, true); - case "-1": - return new KeyValuePair(tagType.forward, false); - case "no": - return new KeyValuePair(tagType.oneway, false); - } - break; - case "id": - return new KeyValuePair(tagType.id, Convert.ToUInt64(value)); - } - return new KeyValuePair(tagType.EMPTY, 0); - } - - public ulong GetId() - { - return tags.ContainsKey(tagType.id) ? (ulong)tags[tagType.id] : 0; - } - - public wayType GetHighwayType() - { - if (!tags.ContainsKey(tagType.highway)) - throw new Exception("Not a road?"); - return (wayType)tags[tagType.highway]; - } - - public bool IsOneWay() - { - return tags.ContainsKey(tagType.oneway) && (bool)tags[tagType.oneway]; - } - - public byte GetMaxSpeed(speedType type) - { - switch (type) - { - case speedType.road: - return tags.ContainsKey(tagType.maxspeed) ? (byte)tags[tagType.maxspeed] : (byte)0; - case speedType.car: - return tags.ContainsKey(tagType.maxspeed) ? (byte)tags[tagType.maxspeed] : defaultSpeedCar[GetHighwayType()]; - case speedType.pedestrian: - return defaultSpeedPedestrian[GetHighwayType()]; - default: - return 0; - } - } - - public bool IsForward() - { - return this.tags.ContainsKey(tagType.forward) && (bool)this.tags[tagType.forward]; - } - - public double GetWeight(OsmNode parentNode, speedType vehicle) - { - double distance = Utils.DistanceBetween(parentNode, neighborCoordinates); - byte speedByte = GetMaxSpeed(vehicle); - if (speedByte > 0) - { - double speed = Convert.ToDouble(speedByte); - return distance / speed; - } - else - { - return double.MaxValue; - } + this.wayId = wayID; + this.neighborId = neighborID; + this.neighborRegion = neighborRegion; } public override string ToString() { - string tagsString = ""; - foreach (KeyValuePair tag in tags) - { - tagsString += string.Format("\n\t{0}: {1}", tag.Key, tag.Value); - } - - return string.Format("EDGE neighborCoordinates: {0} {1}", neighborCoordinates.ToString(), tagsString); + return $"EDGE WayID: {wayId} NeighborID: {neighborId} {neighborRegion}"; } } \ No newline at end of file diff --git a/OSMDatastructure/OsmNode.cs b/OSMDatastructure/OsmNode.cs index 79b7667..507aa2f 100644 --- a/OSMDatastructure/OsmNode.cs +++ b/OSMDatastructure/OsmNode.cs @@ -1,23 +1,27 @@ namespace OSMDatastructure.Graph; +[Serializable] public class OsmNode { + public ulong nodeId { get; } public HashSet edges { get; } public Coordinates coordinates { get; } - public OsmNode? previousPathNode = null; - public double currentPathWeight = double.MaxValue; - public double currentPathLength = double.MaxValue; - public double directDistanceToGoal = double.MaxValue; + [NonSerialized]public OsmNode? previousPathNode = null; + [NonSerialized]public double currentPathWeight = double.MaxValue; + [NonSerialized]public double currentPathLength = double.MaxValue; + [NonSerialized]public double directDistanceToGoal = double.MaxValue; - public OsmNode(float lat, float lon) + public OsmNode(ulong nodeId, float lat, float lon) { + this.nodeId = nodeId; this.edges = new(); this.coordinates = new Coordinates(lat, lon); } - public OsmNode(Coordinates coordinates) + public OsmNode(ulong nodeId, Coordinates coordinates) { + this.nodeId = nodeId; this.edges = new(); this.coordinates = coordinates; } @@ -25,14 +29,14 @@ public class OsmNode public OsmEdge? GetEdgeToNode(OsmNode n) { foreach (OsmEdge e in this.edges) - if (e.neighborCoordinates.Equals(n.coordinates)) + if (e.neighborId == n.nodeId) return e; return null; } public override bool Equals(object? obj) { - return obj != null && obj.GetType() == this.GetType() && ((OsmNode)obj).coordinates.Equals(this.coordinates); + return obj != null && obj.GetType() == this.GetType() && ((OsmNode)obj).nodeId == this.nodeId; } public override int GetHashCode() diff --git a/OSMDatastructure/Region.cs b/OSMDatastructure/Region.cs index c9902c1..eaf8897 100644 --- a/OSMDatastructure/Region.cs +++ b/OSMDatastructure/Region.cs @@ -2,20 +2,24 @@ using OSMDatastructure.Graph; namespace OSMDatastructure; +[Serializable] public class Region { - public const float RegionSize = 0.01f; + [NonSerialized]public const float RegionSize = 0.01f; public readonly HashSet nodes = new(); - public int regionHash { get; } + public ulong regionHash { get; } + public TagManager tagManager { get; } - public Region(int regionHash) + public Region(ulong regionHash) { this.regionHash = regionHash; + tagManager = new TagManager(); } public Region(Coordinates coordinates) { regionHash = Coordinates.GetRegionHashCode(coordinates); + tagManager = new TagManager(); } public OsmNode? GetNodeWithCoordinates(Coordinates coordinates) diff --git a/OsmXmlToRegionConverter/Tag.cs b/OSMDatastructure/Tag.cs similarity index 99% rename from OsmXmlToRegionConverter/Tag.cs rename to OSMDatastructure/Tag.cs index 3f4ead0..cd26bde 100644 --- a/OsmXmlToRegionConverter/Tag.cs +++ b/OSMDatastructure/Tag.cs @@ -1,5 +1,6 @@ -namespace OsmXmlToRegionConverter; +namespace OSMDatastructure.Graph; +[Serializable] public class Tag { public TagType key { get; } diff --git a/OSMDatastructure/TagManager.cs b/OSMDatastructure/TagManager.cs new file mode 100644 index 0000000..0c10132 --- /dev/null +++ b/OSMDatastructure/TagManager.cs @@ -0,0 +1,45 @@ +using System.Runtime.CompilerServices; + +namespace OSMDatastructure.Graph; + +[Serializable] +public class TagManager +{ + public readonly Dictionary> wayTags = new(); + + public bool ContainsKey(ulong wayId, Tag.TagType key) + { + return wayTags.ContainsKey(wayId) && wayTags[wayId].Any(tag => tag.key == key); + } + + public object? GetTag(ulong wayId, Tag.TagType key) + { + return ContainsKey(wayId, key) ? wayTags[wayId].First(tag => tag.key == key) : null; + } + + public void AddTag(ulong wayId, string key, string value) + { + Tag tag = Tag.ConvertToTag(key, value); + AddTag(wayId, tag); + } + + public void AddTag(ulong wayId, Tag tag) + { + if (tag.key != Tag.TagType.EMPTY) + { + if(!wayTags.ContainsKey(wayId)) + wayTags.Add(wayId, new HashSet()); + wayTags[wayId].Add(tag); + } + } + + public HashSet? GetTagsForWayId(ulong wayId) + { + return wayTags.TryGetValue(wayId, out HashSet? value) ? value : null; + } + + public bool ContainsWay(ulong wayId) + { + return wayTags.ContainsKey(wayId); + } +} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/ByteConverter.cs b/OsmXmlToRegionConverter/ByteConverter.cs deleted file mode 100644 index 6482ba6..0000000 --- a/OsmXmlToRegionConverter/ByteConverter.cs +++ /dev/null @@ -1,259 +0,0 @@ -using System.Text; - -namespace OsmXmlToRegionConverter; - -public static class Extensions -{ - public static T[] SubArray(this T[] array, int offset, int length) - { - T[] result = new T[length]; - Buffer.BlockCopy(array, offset, result, 0, length); - return result; - } -} - -public class ByteConverter -{ - - private enum ContentType : byte - { - Node = 0, - Coordinates = 1, - Edge = 2, - TmpNode = 3, - TmpWay = 4, - Region = 5, - TagManager = 6 - } - - public static HashSet GetObjectsFromBytes(byte[] bytes) - { - HashSet ret = new HashSet(); - while (bytes.Length > 0) - { - ContentType contentType = (ContentType)bytes[0]; - switch (contentType) - { - case ContentType.Node: - int edgeCount = BitConverter.ToInt32(bytes, 1); - int byteSizeNode = Node.ByteSizeEmpty + 1 + edgeCount * Edge.ByteSize; //+1 for contenttype of coordinates - ret.Add(Node.FromBytes(bytes.SubArray(1, byteSizeNode))); - bytes = bytes.SubArray(1 + byteSizeNode, bytes.Length - 1 - byteSizeNode); //-1 for overflow - break; - case ContentType.Coordinates: - ret.Add(Coordinates.FromBytes(bytes.SubArray(1, Coordinates.ByteSize))); - bytes = bytes.SubArray(1 + Coordinates.ByteSize, bytes.Length - 1 - Coordinates.ByteSize); - break; - case ContentType.Edge: - ret.Add(Edge.FromBytes(bytes.SubArray(1, Edge.ByteSize))); - bytes = bytes.SubArray(1 + Edge.ByteSize, bytes.Length - 1 - Edge.ByteSize); - break; - case ContentType.TmpNode: - ret.Add(TmpNode.FromBytes(bytes.SubArray(1, TmpNode.ByteSize + 1))); //+1 for contenttype of coordinates - bytes = bytes.SubArray(1 + TmpNode.ByteSize + 1, bytes.Length - 1 - (TmpNode.ByteSize + 1)); - break; - case ContentType.TmpWay: - int byteSizeTmpWay = BitConverter.ToInt32(bytes, 1); - ret.Add(TmpWay.FromBytes(bytes.SubArray(1, byteSizeTmpWay))); - bytes = bytes.SubArray(1 + byteSizeTmpWay, bytes.Length - 1 - byteSizeTmpWay); - break; - case ContentType.TagManager: - int totalBytesTagManager = BitConverter.ToInt32(bytes, 1); - ret.Add(TagManager.FromBytes(bytes.SubArray(1 + sizeof(int), totalBytesTagManager))); - bytes = bytes.SubArray(1 + sizeof(int) + totalBytesTagManager, bytes.Length - 1 - sizeof(int) - totalBytesTagManager); - break; - default: - throw new Exception("Unknown Type"); - } - } - - return ret; - } - - public static byte[] GetBytes(Node n) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.Node); - b.Write(n.edges.Count); - b.Write((byte)ContentType.Node); - b.Write(n.id); - b.Write(GetBytes(n.coordinates)); - foreach(Edge e in n.edges) - b.Write(GetBytes(e)); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(Coordinates c) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.Coordinates); - b.Write(c.latitude); - b.Write(c.longitude); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(Edge e) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.Edge); - b.Write(e.wayId); - b.Write(e.neighborId); - b.Write(e.neighborRegion); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(TmpNode tn) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.TmpNode); - b.Write(tn.id); - b.Write(GetBytes(tn.coordinates)); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(TmpWay tw) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.TmpWay); - HashSet tagBytesSet = new HashSet(); - int totalTagBytes = 0; - foreach (Tag tag in tw.tags) - { - byte[] tagBytes = GetBytes(tag); - totalTagBytes += tagBytes.Length; - tagBytesSet.Add(tagBytes); - } - - b.Write(sizeof(ulong) + sizeof(int) + tw.wayNodeIds.Length * sizeof(ulong) + totalTagBytes); - b.Write(tw.id); - b.Write(tw.wayNodeIds.Length); - foreach (ulong wayNodeId in tw.wayNodeIds) - b.Write(wayNodeId); - foreach (byte[] tagBytes in tagBytesSet) - b.Write(tagBytes); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(Region r) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - b.Write((byte)ContentType.Region); - b.Write(r.GetNodes().Length); - b.Write(r.regionHash); - foreach (Node n in r.GetNodes()) - b.Write(GetBytes(n)); - } - - return m.ToArray(); - } - } - - public static byte[] GetBytes(Tag tag) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - byte[] valueBytes; - if (tag.value is ulong valueUlong) - { - valueBytes = BitConverter.GetBytes(valueUlong); - }else if (tag.value is byte valueByte) - { - valueBytes = new[] { valueByte }; - }else if (tag.value is bool valueBool) - { - valueBytes = BitConverter.GetBytes(valueBool); - }else if (tag.value is string valueString) - { - valueBytes = Encoding.ASCII.GetBytes(valueString); - }else if (tag.value is int valueInt) - { - valueBytes = BitConverter.GetBytes(valueInt); - } - else - { - throw new ArgumentException($"Unknown type {tag.value.GetType()}"); - } - b.Write(sizeof(byte) + valueBytes.Length); - b.Write((byte)tag.key); - b.Write(valueBytes); - } - return m.ToArray(); - } - } - - public static byte[] GetBytes(TagManager t) - { - using (MemoryStream m = new MemoryStream()) - { - using (BinaryWriter b = new BinaryWriter(m)) - { - HashSet wayBytesSet = new HashSet(); - int totalBytes = 0; - foreach (KeyValuePair> way in t.wayTags) - { - HashSet tagBytesSet = new HashSet(); - tagBytesSet.Add(BitConverter.GetBytes(way.Key)); - int totalWayBytes = sizeof(ulong); - - foreach (Tag tag in way.Value) - { - byte[] tagBytes = GetBytes(tag); - totalWayBytes += tagBytes.Length; - tagBytesSet.Add(tagBytes); - } - - wayBytesSet.Add(BitConverter.GetBytes(totalWayBytes)); - foreach (byte[] bytes in tagBytesSet) - { - wayBytesSet.Add(bytes); - } - - totalBytes += sizeof(int) + totalWayBytes; - } - - b.Write(totalBytes); - foreach (byte[] bytes in wayBytesSet) - { - b.Write(bytes); - } - } - - return m.ToArray(); - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/Coordinates.cs b/OsmXmlToRegionConverter/Coordinates.cs deleted file mode 100644 index 6ff0352..0000000 --- a/OsmXmlToRegionConverter/Coordinates.cs +++ /dev/null @@ -1,71 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class Coordinates -{ - public const float RegionSize = 0.01f; - public float latitude { get; } - public float longitude { get; } - - public Coordinates(float latitude, float longitude) - { - this.latitude = latitude; - this.longitude = longitude; - } - - public override bool Equals(object? obj) - { - if (obj == null || obj.GetType() != this.GetType()) - return false; - Coordinates convObj = (Coordinates)obj; - // ReSharper disable twice CompareOfFloatsByEqualityOperator static values - return convObj.latitude == this.latitude && convObj.longitude == this.longitude; - } - - public new ulong GetHashCode() - { - return GetHashCode(latitude, longitude); - } - - public static ulong GetRegionHashCode(float latitude, float longitude) - { - float latRegion = latitude - latitude % RegionSize; - float lonRegion = longitude - longitude % RegionSize; - return GetHashCode(latRegion, lonRegion); - } - - public static ulong GetRegionHashCode(Coordinates coordinates) - { - float latRegion = coordinates.latitude - coordinates.latitude % RegionSize; - float lonRegion = coordinates.longitude - coordinates.longitude % RegionSize; - return GetHashCode(latRegion, lonRegion); - } - - private const float decimalCoordsSave = 10000; - private const ulong offset = 10000000; - //Latitude maxChars = 7 - //Longitude maxChars = 8 - public static ulong GetHashCode(float latitude, float longitude) - { - ulong latHash = Convert.ToUInt64((latitude + 90) * decimalCoordsSave); - ulong lonHash = Convert.ToUInt64((longitude + 180) * decimalCoordsSave); - return latHash * offset + lonHash; - } - - public override string ToString() - { - return string.Format("COORDINATES Lat: {0} Lon: {1}", this.latitude, this.longitude); - } - - public const int ByteSize = sizeof(float) * 2; - public static Coordinates FromBytes(byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - float latitude = r.ReadSingle(); - float longitude = r.ReadSingle(); - return new Coordinates(latitude, longitude); - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/Edge.cs b/OsmXmlToRegionConverter/Edge.cs deleted file mode 100644 index 17d458a..0000000 --- a/OsmXmlToRegionConverter/Edge.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class Edge -{ - public ulong wayId { get; } - public ulong neighborId { get; } - public ulong neighborRegion { get; } - - public Edge(ulong wayId, ulong neighborId, ulong neighborRegion) - { - this.wayId = wayId; - this.neighborId = neighborId; - this.neighborRegion = neighborRegion; - } - - public Edge(ulong wayId, Node neighborNode) - { - this.wayId = wayId; - this.neighborId = neighborNode.id; - this.neighborRegion = Coordinates.GetRegionHashCode(neighborNode.coordinates); - } - - public const int ByteSize = sizeof(ulong) * 3; - public static Edge FromBytes(byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - ulong wayId = r.ReadUInt64(); - ulong neighborId = r.ReadUInt64(); - ulong neighborRegion = r.ReadUInt64(); - return new Edge(wayId, neighborId, neighborRegion); - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/Manager.cs b/OsmXmlToRegionConverter/Manager.cs deleted file mode 100644 index ae562cd..0000000 --- a/OsmXmlToRegionConverter/Manager.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System.Globalization; -using System.Xml; - -namespace OsmXmlToRegionConverter; - -public class Manager -{ - private static readonly XmlReaderSettings readerSettings = new() - { - IgnoreWhitespace = true, - IgnoreComments = true - }; - - private static readonly NumberFormatInfo decimalInfo = new() - { - NumberDecimalSeparator = "." - }; - - private const string NodesTmpFilename = "nodes.tmp"; - private const string WaysTmpFilename = "ways.tmp"; - private const string TagsFilename = "tags"; - - public static void XmlToByteConverter(string inputFilePath, string outputFolderPath) - { - if (!File.Exists(inputFilePath)) - throw new FileNotFoundException(inputFilePath); - Directory.CreateDirectory(outputFolderPath); - - Console.WriteLine("Getting highwayNodeIDs..."); - FileStream xmlFileStream = new FileStream(inputFilePath, FileMode.Open); - HashSet nodeIdsToImport = GetHighwayNodeIds(XmlReader.Create(xmlFileStream, readerSettings)); - xmlFileStream.Position = 0; - - Console.WriteLine("Converting Nodes..."); - Dictionary nodeRegions = ImportNodesToRegionsTmp(XmlReader.Create(xmlFileStream, readerSettings), nodeIdsToImport, outputFolderPath); - nodeIdsToImport.Clear(); //memory management - xmlFileStream.Position = 0; - - Console.WriteLine("Converting Ways..."); - ImportWaysToRegionTmp(XmlReader.Create(xmlFileStream, readerSettings), nodeRegions, outputFolderPath); - HashSet regionHashes = nodeRegions.Values.ToHashSet(); - nodeRegions.Clear(); //memory management - - Console.WriteLine("Converting Nodes and Ways to Nodes and Edges in regionfile..."); - ConvertNodesAndWaysToRegion(outputFolderPath, regionHashes); - } - - private static HashSet GetHighwayNodeIds(XmlReader xmlReader) - { - HashSet retSet = new(); - bool isHighway; - HashSet currentIds = new(); - while (xmlReader.ReadToFollowing("way")) - { - isHighway = false; - currentIds.Clear(); - XmlReader wayReader = xmlReader.ReadSubtree(); - while (wayReader.Read()) - { - if (xmlReader.Name == "tag" && xmlReader.GetAttribute("k")!.Equals("highway")) - { - isHighway = true; - } - else if (xmlReader.Name == "nd") - { - try - { - currentIds.Add(Convert.ToUInt64(xmlReader.GetAttribute("ref"))); - } - catch (FormatException) { }; - } - } - if (isHighway) - { - retSet.UnionWith(currentIds); - } - wayReader.Close(); - } - xmlReader.Close(); - - return retSet; - } - - private static Dictionary ImportNodesToRegionsTmp(XmlReader xmlReader, HashSet nodeIdsToImport, string outputFolderPath) - { - Dictionary regionWriters = new Dictionary(); - Dictionary nodeRegions = new Dictionary(); - - while (xmlReader.ReadToFollowing("node")) - { - ulong currentNodeId = Convert.ToUInt64(xmlReader.GetAttribute("id")); - if (nodeIdsToImport.Contains(currentNodeId)) - { - float lat = Convert.ToSingle(xmlReader.GetAttribute("lat")!, decimalInfo); - float lon = Convert.ToSingle(xmlReader.GetAttribute("lon")!, decimalInfo); - TmpNode newTmpNode = new TmpNode(currentNodeId, lat, lon); - ulong regionHash = Coordinates.GetRegionHashCode(newTmpNode.coordinates); - - if (!regionWriters.ContainsKey(regionHash)) - { - Directory.CreateDirectory(Path.Combine(outputFolderPath, regionHash.ToString())); - regionWriters.Add(regionHash, new FileStream(Path.Combine(outputFolderPath, regionHash.ToString(), NodesTmpFilename), FileMode.Append)); - } - regionWriters[regionHash].Write( ByteConverter.GetBytes(newTmpNode)); - nodeRegions.Add(currentNodeId, regionHash); - } - } - foreach(FileStream regionWriter in regionWriters.Values) - regionWriter.Close(); - xmlReader.Close(); - return nodeRegions; - } - - private static void ImportWaysToRegionTmp(XmlReader xmlReader, Dictionary nodeRegions, string outputFolderPath) - { - Dictionary regionWriters = new Dictionary(); - bool isHighway = false; - HashSet currentIds = new(); - while (xmlReader.ReadToFollowing("way")) - { - HashSet tagsSet = new HashSet(); - isHighway = false; - currentIds.Clear(); - ulong wayId = Convert.ToUInt64(xmlReader.GetAttribute("id")); - XmlReader wayReader = xmlReader.ReadSubtree(); - while (wayReader.Read()) - { - if (xmlReader.Name == "tag" && xmlReader.GetAttribute("k")!.Equals("highway")) - { - isHighway = true; - } - else if (xmlReader.Name == "nd") - { - try - { - currentIds.Add(Convert.ToUInt64(xmlReader.GetAttribute("ref"))); - } - catch (FormatException) { }; - }else if (xmlReader.Name == "tag") - { - tagsSet.Add(Tag.ConvertToTag(xmlReader.GetAttribute("k")!, xmlReader.GetAttribute("v")!)); - } - } - if (isHighway) - { - TmpWay newTmpWay = new TmpWay(wayId, currentIds.ToArray(), tagsSet); - HashSet regionsToWrite = new HashSet(); - foreach (ulong nodeId in currentIds) - { - if (nodeRegions.ContainsKey(nodeId)) - { - regionsToWrite.Add(nodeRegions[nodeId]); - } - } - - - foreach (ulong regionHash in regionsToWrite) - { - if (!regionWriters.ContainsKey(regionHash)) - { - regionWriters.Add(regionHash, new FileStream(Path.Combine(outputFolderPath, regionHash.ToString(), WaysTmpFilename), FileMode.Append)); - } - regionWriters[regionHash].Write(ByteConverter.GetBytes(newTmpWay)); - } - } - wayReader.Close(); - } - foreach(FileStream regionWriter in regionWriters.Values) - regionWriter.Close(); - xmlReader.Close(); - } - - private static void ConvertNodesAndWaysToRegion(string outputFolderPath, HashSet regionHashes) - { - foreach (ulong regionHash in regionHashes) - { - Console.WriteLine($"Converting Region {regionHash}"); - string regionFilePath = Path.Combine(outputFolderPath, $"{regionHash.ToString()}.region"); - string regionFolderPath = Path.Combine(outputFolderPath, regionHash.ToString()); - string nodesFilePath = Path.Combine(regionFolderPath, NodesTmpFilename); - string waysFilePath = Path.Combine(regionFolderPath, WaysTmpFilename); - - Region newRegion = new Region(regionHash); - Dictionary nodes = new Dictionary(); - - byte[] nodeBytes = File.ReadAllBytes(nodesFilePath); - HashSet nodeObjects = ByteConverter.GetObjectsFromBytes(nodeBytes); - foreach (object obj in nodeObjects) - { - if (obj.GetType() == typeof(TmpNode)) - { - TmpNode tmpNode = (TmpNode)obj; - Node newNode = new Node(tmpNode.id, tmpNode.coordinates); - newRegion.AddNode(newNode); - nodes.TryAdd(newNode.id, newNode); - } - else - throw new Exception("Unexpected object."); - } - - byte[] wayBytes = File.ReadAllBytes(waysFilePath); - HashSet ways = ByteConverter.GetObjectsFromBytes(wayBytes); - foreach (object obj in ways) - { - if (obj.GetType() == typeof(TmpWay)) - { - TmpWay way = (TmpWay)obj; - for (int nodeIdi = 0; nodeIdi < way.wayNodeIds.Length - 1; nodeIdi++) //TODO directional - { - if (nodes.ContainsKey(way.wayNodeIds[nodeIdi]) && - nodes.ContainsKey(way.wayNodeIds[nodeIdi + 1])) - { - Node n1 = nodes[way.wayNodeIds[nodeIdi]]; - Node n2 = nodes[way.wayNodeIds[nodeIdi + 1]]; - n1.edges.Add(new Edge(way.id, n2)); - n2.edges.Add(new Edge(way.id, n1)); - } - } - } - else throw new Exception("Unexpected object."); - } - - File.WriteAllBytes(regionFilePath, ByteConverter.GetBytes(newRegion)); - Directory.Delete(regionFolderPath, true); - } - - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/Node.cs b/OsmXmlToRegionConverter/Node.cs deleted file mode 100644 index 1a60c87..0000000 --- a/OsmXmlToRegionConverter/Node.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class Node -{ - public ulong id { get; } - public Coordinates coordinates { get; } - public HashSet edges { get; } - - public Node(ulong id, float latitude, float longitude) - { - this.id = id; - coordinates = new Coordinates(latitude, longitude); - edges = new HashSet(); - } - - public Node(ulong id, Coordinates coordinates) - { - this.id = id; - this.coordinates = coordinates; - edges = new HashSet(); - } - - public void AddEdge(Edge edge) - { - edges.Add(edge); - } - - public const int ByteSizeEmpty = sizeof(int) + sizeof(ulong) + Coordinates.ByteSize; - public static Node FromBytes(byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - int edgeCount = r.ReadInt32(); - ulong id = r.ReadUInt64(); - byte[] coordinateBytes = r.ReadBytes(sizeof(float) * 2); - Coordinates coordinates = Coordinates.FromBytes(coordinateBytes); - - Node ret = new Node(id, coordinates); - - for (int i = 0; i < edgeCount; i++) - ret.AddEdge(Edge.FromBytes(r.ReadBytes(Edge.ByteSize))); - - return ret; - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj b/OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj deleted file mode 100644 index 6836c68..0000000 --- a/OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net7.0 - enable - enable - - - diff --git a/OsmXmlToRegionConverter/Region.cs b/OsmXmlToRegionConverter/Region.cs deleted file mode 100644 index e883b50..0000000 --- a/OsmXmlToRegionConverter/Region.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class Region -{ - private HashSet nodes; - public ulong regionHash { get; } - - private TagManager tagManager { get; } - - public Region(ulong regionHash) - { - this.regionHash = regionHash; - nodes = new HashSet(); - tagManager = new TagManager(); - } - - public void AddNode(Node nodeToAdd) - { - if (nodes.Contains(nodeToAdd)) - throw new Exception("Node already in region"); - else - nodes.Add(nodeToAdd); - } - - public Node[] GetNodes() - { - return this.nodes.ToArray(); - } - - public const int ByteSizeEmpty = sizeof(int) + sizeof(ulong); - public static Region FromBytes(byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - int nodesInRegionCount = r.ReadInt32(); - ulong regionHash = r.ReadUInt64(); - Region retRegion = new Region(regionHash); - HashSet nodesSet = - ByteConverter.GetObjectsFromBytes(bytes.SubArray(ByteSizeEmpty, bytes.Length - ByteSizeEmpty)); - foreach(object node in nodesSet) - retRegion.AddNode((Node)node); - return retRegion; - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/TagManager.cs b/OsmXmlToRegionConverter/TagManager.cs deleted file mode 100644 index 9368e6b..0000000 --- a/OsmXmlToRegionConverter/TagManager.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace OsmXmlToRegionConverter; - -public class TagManager -{ - public readonly Dictionary> wayTags = new(); - - public bool ContainsKey(ulong wayId, Tag.TagType key) - { - return wayTags.ContainsKey(wayId) && wayTags[wayId].Any(tag => tag.key == key); - } - - public object? GetTag(ulong wayId, Tag.TagType key) - { - return ContainsKey(wayId, key) ? wayTags[wayId].First(tag => tag.key == key) : null; - } - - public void AddTag(ulong wayId, string key, string value) - { - Tag tag = Tag.ConvertToTag(key, value); - AddTag(wayId, tag); - } - - private void AddTag(ulong wayId, Tag tag) - { - if (tag.key != Tag.TagType.EMPTY) - { - if(!wayTags.ContainsKey(wayId)) - wayTags.Add(wayId, new HashSet()); - wayTags[wayId].Add(tag); - } - } - - public static TagManager FromBytes(byte[] bytes) - { - TagManager newTagManager = new TagManager(); - - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - while (r.BaseStream.Position < bytes.Length) - { - int wayByteSize = r.ReadInt32(); - byte[] wayBytes = r.ReadBytes(wayByteSize); - AddWayFromBytes(ref newTagManager, wayBytes); - } - } - } - - return newTagManager; - } - - private static void AddWayFromBytes(ref TagManager tagManager, byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - ulong wayId = r.ReadUInt64(); - while (r.BaseStream.Position < bytes.Length) - { - int tagsByteSize = r.ReadInt32(); - byte[] tagBytes = r.ReadBytes(tagsByteSize); - Tag tag = Tag.FromBytes(tagBytes); - tagManager.AddTag(wayId, tag); - } - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/TmpNode.cs b/OsmXmlToRegionConverter/TmpNode.cs deleted file mode 100644 index b17970d..0000000 --- a/OsmXmlToRegionConverter/TmpNode.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class TmpNode -{ - public ulong id { get; } - - public Coordinates coordinates { get; } - - public TmpNode(ulong id, float latitude, float longitude) - { - this.id = id; - this.coordinates = new Coordinates(latitude, longitude); - } - - public TmpNode(ulong id, Coordinates coordinates) - { - this.id = id; - this.coordinates = coordinates; - } - - public const int ByteSize = sizeof(ulong) + Coordinates.ByteSize; - public static TmpNode FromBytes(byte[] bytes) - { - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - ulong id = r.ReadUInt64(); - byte coordinatesType = r.ReadByte(); - byte[] coordinateBytes = r.ReadBytes(sizeof(float) * 2); - Coordinates coordinates = Coordinates.FromBytes(coordinateBytes); - return new TmpNode(id, coordinates); - } - } - } -} \ No newline at end of file diff --git a/OsmXmlToRegionConverter/TmpWay.cs b/OsmXmlToRegionConverter/TmpWay.cs deleted file mode 100644 index 4a1b7e0..0000000 --- a/OsmXmlToRegionConverter/TmpWay.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace OsmXmlToRegionConverter; - -public class TmpWay -{ - public ulong id { get; } - public ulong[] wayNodeIds { get; } - public HashSet tags { get; } - - public TmpWay(ulong id, ulong[] wayNodeIds, HashSet tags) - { - this.id = id; - this.wayNodeIds = wayNodeIds; - this.tags = tags; - } - - public static TmpWay FromBytes(byte[] bytes) - { - throw new NotImplementedException();/* - using (MemoryStream m = new MemoryStream(bytes)) { - using (BinaryReader r = new BinaryReader(m)) - { - int wayNodeIdsLength = r.ReadInt32(); - ulong id = r.ReadUInt64(); - ulong[] wayNodeIds = new ulong[wayNodeIdsLength]; - for (int i = 0; i < wayNodeIds.Length; i++) - wayNodeIds[i] = r.ReadUInt64(); - return new TmpWay(id, wayNodeIds); - } - }*/ - } -} \ No newline at end of file