Import and Export of Regions

This commit is contained in:
C9Glax 2023-02-03 00:02:04 +01:00
parent 9ce3bc4a9d
commit f31b1b577b
6 changed files with 165 additions and 29 deletions

View File

@ -6,7 +6,7 @@ namespace OSMImporter
private readonly Dictionary<tagType, object> _tags = new Dictionary<tagType, object>();
public enum tagType
public enum tagType : byte
{
highway, oneway, footway, sidewalk, cycleway, busway, forward, maxspeed, unknown
}
@ -37,16 +37,16 @@ namespace OSMImporter
case "oneway":
if (value.Equals("yes", StringComparison.CurrentCultureIgnoreCase))
{
this._tags.Add(tagType.oneway, true);
this._tags.Add(tagType.oneway, (byte)1);
}
else if (value.Equals("no", StringComparison.CurrentCultureIgnoreCase))
{
this._tags.Add(tagType.oneway, false);
this._tags.Add(tagType.oneway, (byte)0);
}
else if (value.Equals("reversible", StringComparison.CurrentCultureIgnoreCase))
{
this._tags.Add(tagType.oneway, true);
this._tags.Add(tagType.forward, false);
this._tags.Add(tagType.oneway, (byte)1);
this._tags.Add(tagType.forward, (byte)0);
}
break;
case "sidewalk":
@ -65,7 +65,35 @@ namespace OSMImporter
this._tags.Add(tagType.maxspeed, Convert.ToByte(value));
break;
default:
this._tags.Add(tagType.unknown, value);
Console.WriteLine("Unknown Tag: {0} Value: {1}", key, value);
break;
}
}
public void AddTag(byte tag, byte value)
{
switch ((tagType)tag)
{
case tagType.highway:
this._tags.Add(tagType.highway, (highwayType)value);
break;
case tagType.footway:
this._tags.Add(tagType.footway, (footwayType)value);
break;
case tagType.oneway:
this._tags.Add(tagType.oneway, value);
break;
case tagType.sidewalk:
this._tags.Add(tagType.sidewalk, (sidewalkSide)value);
break;
case tagType.cycleway:
this._tags.Add(tagType.cycleway, (cyclewayType)value);
break;
case tagType.busway:
this._tags.Add(tagType.busway, (buswayType)value);
break;
case tagType.maxspeed:
this._tags.Add(tagType.maxspeed, value);
break;
}
}
@ -89,12 +117,28 @@ namespace OSMImporter
return null;
}
}
public byte[] ToByte() //TODO Current Size sizeof(ulong)
/*
* Value 1: endId (4bytes)
* Value 2: tagsCount (1byte)
* Value x: tag + value (2bytes)
*/
public byte[] ToByte()
{
//TODO Tags
byte[] ret = new byte[sizeof(ulong)];
Buffer.BlockCopy(new []{ this.endNodeId }, 0, ret, 0, ret.Length );
byte[] ret = new byte[sizeof(ulong) + 1 + this._tags.Count * 2];
int offset = 0;
Buffer.BlockCopy(new []{ this.endNodeId }, 0, ret, offset, sizeof(ulong) );
offset += sizeof(ulong);
byte tagsAmount = Convert.ToByte(this._tags.Count);
Buffer.SetByte(ret, offset++, tagsAmount);
foreach (KeyValuePair<tagType, object> tag in this._tags)
{
Buffer.BlockCopy(new byte[]{(byte)tag.Key, (byte)tag.Value}, 0, ret,offset, 2);
offset += 2;
}
return ret;
}
}

View File

@ -19,6 +19,68 @@ namespace OSMImporter
NumberDecimalSeparator = "."
};
public static Region ImportRegion(string folderPath, Coordinates coordinates)
{
string fullPath = Path.Combine(folderPath, coordinates.GetRegionHash().ToString());
Console.WriteLine(fullPath);
Region retRegion = new Region(coordinates);
if (!File.Exists(fullPath))
return retRegion;
FileStream fileStream = new FileStream(fullPath, FileMode.Open);
while (fileStream.Position < fileStream.Length)
{
byte[] nodeIdBytes = new byte[sizeof(ulong)];
fileStream.ReadExactly(nodeIdBytes,0,nodeIdBytes.Length);
ulong[] nodeId = new ulong[1];
Buffer.BlockCopy(nodeIdBytes,0,nodeId,0,nodeIdBytes.Length);
byte[] latBytes = new byte[sizeof(float)];
fileStream.ReadExactly(latBytes, 0, latBytes.Length);
byte[] lonBytes = new byte[sizeof(float)];
fileStream.ReadExactly(lonBytes, 0, latBytes.Length);
Node newNode = NodeFromBytes(latBytes, lonBytes);
retRegion.AddNode(nodeId[0], newNode);
byte connectionsAmount = Convert.ToByte(fileStream.ReadByte());
for (byte connectionInt = 0; connectionInt < connectionsAmount; connectionInt++)
{
byte[] endIdBytes = new byte[sizeof(ulong)];
fileStream.ReadExactly(endIdBytes, 0, endIdBytes.Length);
Connection connection = ConnectionFromByte(endIdBytes);
newNode.AddConnection(connection);
byte tagsAmount = Convert.ToByte(fileStream.ReadByte());
for (byte tagInt = 0; tagInt < tagsAmount; tagInt++)
{
byte keyByte = Convert.ToByte(fileStream.ReadByte());
byte valueByte = Convert.ToByte(fileStream.ReadByte());
connection.AddTag(keyByte, valueByte);
}
}
}
fileStream.Close();
return retRegion;
}
private static Node NodeFromBytes(byte[] latByte, byte[] lonByte)
{
float[] lat = new float[1];
float[] lon = new float[1];
Buffer.BlockCopy(latByte, 0, lat, 0, latByte.Length);
Buffer.BlockCopy(lonByte, 0, lon, 0, lonByte.Length);
return new Node(lat[0], lon[0]);
}
private static Connection ConnectionFromByte(byte[] endIdByte)
{
ulong[] endId = new ulong[1];
Buffer.BlockCopy(endIdByte, 0, endId, 0, endIdByte.Length);
return new Connection(endId[0]);
}
public static void Split(string xmlFilePath, string outputFolderPath)
{
if (!File.Exists(xmlFilePath))
@ -168,6 +230,10 @@ namespace OSMImporter
}
}
/*
* Value x: nodeId (4bytes)
* Value x+1: Node (xbytes)
*/
private static void WriteRegion(Region region, string outputFolderPath)
{
if (!Directory.Exists(outputFolderPath))
@ -177,9 +243,14 @@ namespace OSMImporter
if (!File.Exists(fullPath))
File.Create(fullPath).Close();
FileStream fileStream = new FileStream(fullPath, FileMode.Append);
foreach (Node node in region.GetNodes())
foreach (KeyValuePair<ulong, Node> nodeKeyValuePair in region.GetNodes())
{
byte[] nodeByte = node.ToByte();
byte[] nodeByte = nodeKeyValuePair.Value.ToByte();
byte[] nodeIdByte = new byte[sizeof(long)];
ulong[] nodeId = new ulong[]{nodeKeyValuePair.Key};
Buffer.BlockCopy(nodeId,0,nodeIdByte,0,nodeIdByte.Length);
fileStream.Write(nodeIdByte);
fileStream.Write(nodeByte, 0, nodeByte.Length );
}
fileStream.Close();

View File

@ -24,19 +24,37 @@ namespace OSMImporter
* Value 1: Latitude (4bytes)
* Value 2: Longitude (4bytes)
* Value 3: Connections-Count (1 byte)
* Value x: Connection (8bytes) //TODO
* Value x: Connection
*/
public byte[] ToByte()
{
long countBytes = 0;
float[] coords = { this.lat, this.lon };
byte[] ret = new byte[sizeof(float) * coords.Length + 1 + _connections.Count * sizeof(ulong)];
Buffer.BlockCopy(coords, 0, ret, 0, sizeof(float) * coords.Length );
byte countConnections = Convert.ToByte(_connections.Count);
Connection[] conns = this._connections.ToArray();
for (int i = 0; i < conns.Length; i++)
countBytes += sizeof(float) * 2;
HashSet<byte[]> byteConnections = new();
foreach (Connection connection in this._connections)
{
byte[] connection = conns[i].ToByte();
Buffer.BlockCopy(connection, 0, ret, sizeof(float) * coords.Length + 1 + i * connection.Length, connection.Length);
byte[] connectionBytes = connection.ToByte();
byteConnections.Add(connectionBytes);
countBytes += connectionBytes.Length;
}
byte connectionsAmount = Convert.ToByte(byteConnections.Count);
countBytes++;
int offset = 0;
byte[] ret = new byte[countBytes];
Buffer.BlockCopy(coords, 0, ret, offset, sizeof(float) * 2);
offset += sizeof(float) * 2;
Buffer.SetByte(ret, offset, connectionsAmount);
offset++;
foreach (byte[] connection in byteConnections)
{
Buffer.BlockCopy(connection, 0, ret, offset, connection.Length);
offset += connection.Length;
}
return ret;
}

View File

@ -21,9 +21,9 @@ namespace OSMImporter
this._nodesInRegion.Add(nodeId, value: node);
}
public Node[] GetNodes()
public Dictionary<ulong, Node> GetNodes()
{
return this._nodesInRegion.Values.ToArray();
return this._nodesInRegion;
}
}
}

View File

@ -1,6 +1,6 @@
namespace OSMImporter
{
public enum highwayType
public enum highwayType : byte
{
motorway,
trunk,
@ -34,13 +34,13 @@ namespace OSMImporter
construction
}
public enum footwayType
public enum footwayType : byte
{
sidewalk,
crossing
}
public enum cyclewayType
public enum cyclewayType : byte
{
lane,
opposite,
@ -52,7 +52,7 @@ namespace OSMImporter
shared_lane
}
public enum sidewalkSide
public enum sidewalkSide : byte
{
both,
left,
@ -60,7 +60,7 @@ namespace OSMImporter
no
}
public enum buswayType
public enum buswayType : byte
{
lane
}

View File

@ -8,6 +8,9 @@ public class Server
public static void Main(string[] args)
{
Importer.Split("/home/glax/Downloads/oberbayern-latest.osm", "/home/glax/Downloads/split");
Importer.Split("/home/glax/Downloads/bayern-latest.osm", "/home/glax/Downloads/bayern-latest");
Region r = Importer.ImportRegion("/home/glax/Downloads/bayern-latest", new Coordinates(47.890f,12.56f));
foreach(KeyValuePair<ulong, Node> nodes in r.GetNodes())
Console.WriteLine(nodes.Key);
}
}