From f7edc288c1349da85a1bb12589feaa8964396aa2 Mon Sep 17 00:00:00 2001
From: C9Glax <13404778+C9Glax@users.noreply.github.com>
Date: Thu, 2 Feb 2023 19:03:00 +0100
Subject: [PATCH] Initial commit
---
.gitignore | 5 +
.idea/.idea.OSMServer/.idea/.gitignore | 13 ++
.idea/.idea.OSMServer/.idea/indexLayout.xml | 8 ++
.idea/.idea.OSMServer/.idea/vcs.xml | 6 +
Importer/Connection.cs | 42 ++++++
Importer/Coordinates.cs | 27 ++++
Importer/Importer.cs | 138 ++++++++++++++++++++
Importer/Importer.csproj | 14 ++
Importer/Node.cs | 21 +++
Importer/Region.cs | 33 +++++
Importer/RegionManager.cs | 28 ++++
OSMServer.sln | 16 +++
OSMServer.sln.DotSettings.user | 2 +
Server/Server.cs | 9 ++
Server/Server.csproj | 10 ++
15 files changed, 372 insertions(+)
create mode 100644 .gitignore
create mode 100644 .idea/.idea.OSMServer/.idea/.gitignore
create mode 100644 .idea/.idea.OSMServer/.idea/indexLayout.xml
create mode 100644 .idea/.idea.OSMServer/.idea/vcs.xml
create mode 100644 Importer/Connection.cs
create mode 100644 Importer/Coordinates.cs
create mode 100644 Importer/Importer.cs
create mode 100644 Importer/Importer.csproj
create mode 100644 Importer/Node.cs
create mode 100644 Importer/Region.cs
create mode 100644 Importer/RegionManager.cs
create mode 100644 OSMServer.sln
create mode 100644 OSMServer.sln.DotSettings.user
create mode 100644 Server/Server.cs
create mode 100644 Server/Server.csproj
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..add57be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+bin/
+obj/
+/packages/
+riderModule.iml
+/_ReSharper.Caches/
\ No newline at end of file
diff --git a/.idea/.idea.OSMServer/.idea/.gitignore b/.idea/.idea.OSMServer/.idea/.gitignore
new file mode 100644
index 0000000..775c767
--- /dev/null
+++ b/.idea/.idea.OSMServer/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/projectSettingsUpdater.xml
+/contentModel.xml
+/modules.xml
+/.idea.OSMServer.iml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.OSMServer/.idea/indexLayout.xml b/.idea/.idea.OSMServer/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.OSMServer/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.OSMServer/.idea/vcs.xml b/.idea/.idea.OSMServer/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/.idea.OSMServer/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Importer/Connection.cs b/Importer/Connection.cs
new file mode 100644
index 0000000..3f1ed01
--- /dev/null
+++ b/Importer/Connection.cs
@@ -0,0 +1,42 @@
+namespace OSMServer;
+
+public class Connection
+{
+ public Coordinates end { get; }
+
+ private Dictionary tags;
+
+
+ public Connection(Coordinates end)
+ {
+ this.end = end;
+ this.tags = new Dictionary();
+ }
+
+ public Connection(Coordinates end, Dictionary tags)
+ {
+ this.end = end;
+ this.tags = tags;
+ }
+
+ public bool AddTag(string key, string value)
+ {
+ return this.tags.TryAdd(key, value);
+ }
+
+ public string? TryGetTagValue(string key)
+ {
+ return this.tags.ContainsKey(key) ? this.tags[key] : null;
+ }
+
+ public bool ContainsTag(string key)
+ {
+ return this.tags.ContainsKey(key);
+ }
+
+ public void UpdateTag(string key, string value)
+ {
+ if(!this.AddTag(key, value))
+ this.tags[key] = value;
+ }
+}
\ No newline at end of file
diff --git a/Importer/Coordinates.cs b/Importer/Coordinates.cs
new file mode 100644
index 0000000..e752f55
--- /dev/null
+++ b/Importer/Coordinates.cs
@@ -0,0 +1,27 @@
+using System.Diagnostics;
+
+namespace OSMServer;
+
+public class Coordinates
+{
+ public float lat { get; }
+ public float lon { get; }
+
+ public Coordinates(float lat, float lon)
+ {
+ this.lat = lat;
+ this.lon = lon;
+ }
+
+ public uint GetHash()
+ {
+ return Convert.ToUInt32((this.lat * 10000f + this.lon) * 10000f);
+ }
+
+ public uint GetRegionHash()
+ {
+ float latRegion = this.lat % Importer.regionSize;
+ float lonRegion = this.lon % Importer.regionSize;
+ return new Coordinates(latRegion, lonRegion).GetHash();
+ }
+}
\ No newline at end of file
diff --git a/Importer/Importer.cs b/Importer/Importer.cs
new file mode 100644
index 0000000..4060797
--- /dev/null
+++ b/Importer/Importer.cs
@@ -0,0 +1,138 @@
+using System.Xml;
+using Newtonsoft.Json;
+
+namespace OSMServer;
+
+public class Importer
+{
+
+ public const float regionSize = 0.01f;
+
+ public static void Split(string xmlFilePath, string outputFolderPath)
+ {
+ if (!File.Exists(xmlFilePath))
+ throw new FileNotFoundException();
+ FileStream xmlFileStream = File.OpenRead(xmlFilePath);
+ HashSet nodesToImport = ReturnGraphNodes(XmlReader.Create(xmlFileStream));
+
+ xmlFileStream.Position = 0;
+ XmlReader xmlReader = XmlReader.Create(xmlFileStream);
+ Dictionary nodes = new Dictionary();
+ RegionManager regionManager = new RegionManager();
+
+ while (xmlReader.ReadToFollowing("node"))
+ {
+ ulong id = Convert.ToUInt64(xmlReader.GetAttribute("id"));
+ if (nodesToImport.Contains(id))
+ {
+ float lat = Convert.ToSingle(xmlReader.GetAttribute("lat")!.Replace('.', ','));
+ float lon = Convert.ToSingle(xmlReader.GetAttribute("lon")!.Replace('.', ','));
+ Node newNode = new Node(lat, lon);
+ nodes.Add(id, newNode);
+ regionManager.GetRegion(newNode).AddNode(id, newNode);
+ }
+ }
+
+ xmlReader.Close();
+ xmlFileStream.Position = 0;
+ xmlReader = XmlReader.Create(xmlFileStream);
+
+ while (xmlReader.ReadToFollowing("way"))
+ {
+ XmlReader wayReader = xmlReader.ReadSubtree();
+ HashSet nodesInWay = new HashSet();
+ Dictionary tags = new Dictionary();
+ while (wayReader.Read())
+ {
+ if (wayReader.IsStartElement() && wayReader.Name.Equals("nd"))
+ {
+ nodesInWay.Add(Convert.ToUInt64(wayReader.GetAttribute("ref")));
+ }
+ else if (wayReader.IsStartElement() && wayReader.Name.Equals("tag"))
+ {
+ tags.Add(wayReader.GetAttribute("k")!, wayReader.GetAttribute("v")!);
+ }
+ }
+ if (tags.ContainsKey("highway"))
+ {
+ AddConnections(nodes, nodesInWay.ToArray(), tags);
+ }
+ }
+
+ foreach(Region region in regionManager.GetAllRegions())
+ WriteRegion(region, outputFolderPath);
+ }
+
+ private static HashSet ReturnGraphNodes(XmlReader xmlReader)
+ {
+ HashSet retSet = new HashSet();
+ while (xmlReader.ReadToFollowing("way"))
+ {
+ XmlReader wayReader = xmlReader.ReadSubtree();
+ HashSet tmpList = new HashSet();
+ bool addNodes = false;
+ while (wayReader.Read())
+ {
+ if (wayReader.IsStartElement())
+ {
+ if (wayReader.Name.Equals("nd"))
+ {
+ tmpList.Add(Convert.ToUInt64(wayReader.GetAttribute("ref")));
+ }
+ else if (wayReader.Name.Equals("tag"))
+ {
+ if (wayReader.GetAttribute("v")!.Equals("highway"))
+ addNodes = true;
+ }
+ }
+ }
+ if(addNodes)
+ retSet.UnionWith(tmpList);
+ }
+
+ return retSet;
+ }
+
+ private static void AddConnections(Dictionary nodes, ulong[] nodeIds,
+ Dictionary tags)
+ {
+ string oneWayString = tags.ContainsKey("oneway") ? tags["oneway"] : "no";
+ bool oneWay = false;
+ bool forward = true;
+ switch (oneWayString)
+ {
+ case "yes":
+ oneWay = true;
+ break;
+ case "-1":
+ forward = false;
+ break;
+ }
+
+ for (int i = 0; i < nodeIds.Length - 1; i++)
+ {
+ if (oneWay)
+ {
+ nodes[nodeIds[i]].AddConnection(new Connection(nodes[nodeIds[i + 1]], tags));
+ nodes[nodeIds[i + 1]].AddConnection(new Connection(nodes[nodeIds[i]], tags));
+ }
+ else if (forward)
+ {
+ nodes[nodeIds[i]].AddConnection(new Connection(nodes[nodeIds[i + 1]], tags));
+ }
+ else
+ {
+ nodes[nodeIds[i + 1]].AddConnection(new Connection(nodes[nodeIds[i]], tags));
+ }
+ }
+ }
+
+ private static void WriteRegion(Region region, string outputFolderPath)
+ {
+ if (!Directory.Exists(outputFolderPath))
+ Directory.CreateDirectory(outputFolderPath);
+ string jsonString = JsonConvert.SerializeObject(region);
+ string fileName = region.regionHash.ToString();
+ File.WriteAllText(Path.Combine(outputFolderPath, fileName), jsonString);
+ }
+}
\ No newline at end of file
diff --git a/Importer/Importer.csproj b/Importer/Importer.csproj
new file mode 100644
index 0000000..7a4eeea
--- /dev/null
+++ b/Importer/Importer.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net7.0
+ enable
+ enable
+ OSMServer
+
+
+
+
+
+
+
diff --git a/Importer/Node.cs b/Importer/Node.cs
new file mode 100644
index 0000000..9a91eed
--- /dev/null
+++ b/Importer/Node.cs
@@ -0,0 +1,21 @@
+namespace OSMServer;
+
+public class Node : Coordinates
+{
+ private HashSet connections = new HashSet();
+
+ public Node(float lat, float lon) : base(lat, lon)
+ {
+
+ }
+
+ public void AddConnection(Connection connection)
+ {
+ this.connections.Add(connection);
+ }
+
+ public Connection[] GetConnections()
+ {
+ return this.connections.ToArray();
+ }
+}
\ No newline at end of file
diff --git a/Importer/Region.cs b/Importer/Region.cs
new file mode 100644
index 0000000..baaf5fc
--- /dev/null
+++ b/Importer/Region.cs
@@ -0,0 +1,33 @@
+namespace OSMServer;
+
+public class Region
+{
+ private Dictionary nodesInRegion = new Dictionary();
+ public uint regionHash;
+
+ public Region(uint regionHash)
+ {
+ this.regionHash = this.regionHash;
+ }
+
+ public Region(Coordinates regionCoordinates)
+ {
+ this.regionHash = regionCoordinates.GetRegionHash();
+ }
+
+ public Region(ulong nodeId, Node firstNode)
+ {
+ this.regionHash = firstNode.GetRegionHash();
+ this.nodesInRegion.Add(nodeId, firstNode);
+ }
+
+ public void AddNode(ulong nodeId, Node node)
+ {
+ this.nodesInRegion.Add(nodeId, node);
+ }
+
+ public Node[] GetNodes()
+ {
+ return this.nodesInRegion.Values.ToArray();
+ }
+}
\ No newline at end of file
diff --git a/Importer/RegionManager.cs b/Importer/RegionManager.cs
new file mode 100644
index 0000000..9af454d
--- /dev/null
+++ b/Importer/RegionManager.cs
@@ -0,0 +1,28 @@
+namespace OSMServer;
+
+public class RegionManager
+{
+ private Dictionary regions;
+
+ public RegionManager()
+ {
+ this.regions = new Dictionary();
+ }
+
+ public Region GetRegion(Coordinates coordinates)
+ {
+ if(this.regions.ContainsKey(coordinates.GetRegionHash()))
+ return this.regions[coordinates.GetRegionHash()];
+ else
+ {
+ Region newRegion = new Region(coordinates.GetRegionHash());
+ this.regions.Add(newRegion.regionHash, newRegion);
+ return newRegion;
+ }
+ }
+
+ public Region[] GetAllRegions()
+ {
+ return this.regions.Values.ToArray();
+ }
+}
\ No newline at end of file
diff --git a/OSMServer.sln b/OSMServer.sln
new file mode 100644
index 0000000..7393a17
--- /dev/null
+++ b/OSMServer.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSMServer", "OSMServer\OSMServer.csproj", "{BE5C111D-AD61-433A-AE7E-F02B78551347}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BE5C111D-AD61-433A-AE7E-F02B78551347}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE5C111D-AD61-433A-AE7E-F02B78551347}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE5C111D-AD61-433A-AE7E-F02B78551347}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE5C111D-AD61-433A-AE7E-F02B78551347}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/OSMServer.sln.DotSettings.user b/OSMServer.sln.DotSettings.user
new file mode 100644
index 0000000..8cf0f80
--- /dev/null
+++ b/OSMServer.sln.DotSettings.user
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/Server/Server.cs b/Server/Server.cs
new file mode 100644
index 0000000..f657f4d
--- /dev/null
+++ b/Server/Server.cs
@@ -0,0 +1,9 @@
+namespace OSMServer;
+
+public class Server
+{
+ public Server()
+ {
+ Importer.Split("/home/glax/Downloads/bayern-latest.osm.bz2", "/home/glax/Downloads/split");
+ }
+}
\ No newline at end of file
diff --git a/Server/Server.csproj b/Server/Server.csproj
new file mode 100644
index 0000000..2b14c81
--- /dev/null
+++ b/Server/Server.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+