Compare commits
2 Commits
d2ab990bfe
...
cb0442d760
Author | SHA1 | Date | |
---|---|---|---|
cb0442d760 | |||
0e70c72562 |
259
OsmXmlToRegionConverter/ByteConverter.cs
Normal file
259
OsmXmlToRegionConverter/ByteConverter.cs
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static T[] SubArray<T>(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<object> GetObjectsFromBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
HashSet<object> ret = new HashSet<object>();
|
||||||
|
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<byte[]> tagBytesSet = new HashSet<byte[]>();
|
||||||
|
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<byte[]> wayBytesSet = new HashSet<byte[]>();
|
||||||
|
int totalBytes = 0;
|
||||||
|
foreach (KeyValuePair<ulong, HashSet<Tag>> way in t.wayTags)
|
||||||
|
{
|
||||||
|
HashSet<byte[]> tagBytesSet = new HashSet<byte[]>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
OsmXmlToRegionConverter/Coordinates.cs
Normal file
71
OsmXmlToRegionConverter/Coordinates.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
OsmXmlToRegionConverter/Edge.cs
Normal file
36
OsmXmlToRegionConverter/Edge.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
228
OsmXmlToRegionConverter/Manager.cs
Normal file
228
OsmXmlToRegionConverter/Manager.cs
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
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<ulong> nodeIdsToImport = GetHighwayNodeIds(XmlReader.Create(xmlFileStream, readerSettings));
|
||||||
|
xmlFileStream.Position = 0;
|
||||||
|
|
||||||
|
Console.WriteLine("Converting Nodes...");
|
||||||
|
Dictionary<ulong, ulong> 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<ulong> 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<ulong> GetHighwayNodeIds(XmlReader xmlReader)
|
||||||
|
{
|
||||||
|
HashSet<ulong> retSet = new();
|
||||||
|
bool isHighway;
|
||||||
|
HashSet<ulong> 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<ulong, ulong> ImportNodesToRegionsTmp(XmlReader xmlReader, HashSet<ulong> nodeIdsToImport, string outputFolderPath)
|
||||||
|
{
|
||||||
|
Dictionary<ulong, FileStream> regionWriters = new Dictionary<ulong, FileStream>();
|
||||||
|
Dictionary<ulong, ulong> nodeRegions = new Dictionary<ulong, ulong>();
|
||||||
|
|
||||||
|
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<ulong, ulong> nodeRegions, string outputFolderPath)
|
||||||
|
{
|
||||||
|
Dictionary<ulong, FileStream> regionWriters = new Dictionary<ulong, FileStream>();
|
||||||
|
bool isHighway = false;
|
||||||
|
HashSet<ulong> currentIds = new();
|
||||||
|
while (xmlReader.ReadToFollowing("way"))
|
||||||
|
{
|
||||||
|
HashSet<Tag> tagsSet = new HashSet<Tag>();
|
||||||
|
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<ulong> regionsToWrite = new HashSet<ulong>();
|
||||||
|
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<ulong> 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<ulong, Node> nodes = new Dictionary<ulong, Node>();
|
||||||
|
|
||||||
|
byte[] nodeBytes = File.ReadAllBytes(nodesFilePath);
|
||||||
|
HashSet<object> 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<object> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
48
OsmXmlToRegionConverter/Node.cs
Normal file
48
OsmXmlToRegionConverter/Node.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public class Node
|
||||||
|
{
|
||||||
|
public ulong id { get; }
|
||||||
|
public Coordinates coordinates { get; }
|
||||||
|
public HashSet<Edge> edges { get; }
|
||||||
|
|
||||||
|
public Node(ulong id, float latitude, float longitude)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
coordinates = new Coordinates(latitude, longitude);
|
||||||
|
edges = new HashSet<Edge>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(ulong id, Coordinates coordinates)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.coordinates = coordinates;
|
||||||
|
edges = new HashSet<Edge>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj
Normal file
9
OsmXmlToRegionConverter/OsmXmlToRegionConverter.csproj
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
47
OsmXmlToRegionConverter/Region.cs
Normal file
47
OsmXmlToRegionConverter/Region.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public class Region
|
||||||
|
{
|
||||||
|
private HashSet<Node> nodes;
|
||||||
|
public ulong regionHash { get; }
|
||||||
|
|
||||||
|
private TagManager tagManager { get; }
|
||||||
|
|
||||||
|
public Region(ulong regionHash)
|
||||||
|
{
|
||||||
|
this.regionHash = regionHash;
|
||||||
|
nodes = new HashSet<Node>();
|
||||||
|
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<object> nodesSet =
|
||||||
|
ByteConverter.GetObjectsFromBytes(bytes.SubArray(ByteSizeEmpty, bytes.Length - ByteSizeEmpty));
|
||||||
|
foreach(object node in nodesSet)
|
||||||
|
retRegion.AddNode((Node)node);
|
||||||
|
return retRegion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
149
OsmXmlToRegionConverter/Tag.cs
Normal file
149
OsmXmlToRegionConverter/Tag.cs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public class Tag
|
||||||
|
{
|
||||||
|
public TagType key { get; }
|
||||||
|
public dynamic value { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public Tag(TagType key, dynamic value)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tag FromBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
TagType type = (TagType)bytes[0];
|
||||||
|
dynamic value = false;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case TagType.highway:
|
||||||
|
case TagType.oneway:
|
||||||
|
case TagType.forward:
|
||||||
|
value = BitConverter.ToBoolean(bytes, 1);
|
||||||
|
break;
|
||||||
|
case TagType.maxspeed:
|
||||||
|
value = bytes[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tag(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tag ConvertToTag(string key, string value)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case "highway":
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new Tag(Tag.TagType.highway, (Tag.WayType)Enum.Parse(typeof(Tag.WayType), value, true));
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
return new Tag(Tag.TagType.highway, Tag.WayType.unclassified);
|
||||||
|
}
|
||||||
|
case "maxspeed":
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte speed = Convert.ToByte(value);
|
||||||
|
if (speed == 255)
|
||||||
|
return new Tag(Tag.TagType.highway, false);
|
||||||
|
else
|
||||||
|
return new Tag(Tag.TagType.maxspeed, speed);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(e);
|
||||||
|
//Console.WriteLine("Continuing...");
|
||||||
|
return new Tag(Tag.TagType.maxspeed, byte.MaxValue);
|
||||||
|
}
|
||||||
|
case "oneway":
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case "yes":
|
||||||
|
return new Tag(Tag.TagType.oneway, true);
|
||||||
|
case "-1":
|
||||||
|
return new Tag(Tag.TagType.forward, false);
|
||||||
|
case "no":
|
||||||
|
return new Tag(Tag.TagType.oneway, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new Tag(Tag.TagType.EMPTY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TagType : byte
|
||||||
|
{
|
||||||
|
highway, oneway, footway, sidewalk, cycleway, busway, forward, maxspeed, name, surface, lanes, access, tracktype, id, EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Dictionary<WayType, byte> 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 }
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly Dictionary<WayType, byte> 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 }
|
||||||
|
}
|
70
OsmXmlToRegionConverter/TagManager.cs
Normal file
70
OsmXmlToRegionConverter/TagManager.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public class TagManager
|
||||||
|
{
|
||||||
|
public readonly Dictionary<ulong, HashSet<Tag>> 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<Tag>());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
OsmXmlToRegionConverter/TmpNode.cs
Normal file
35
OsmXmlToRegionConverter/TmpNode.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
OsmXmlToRegionConverter/TmpWay.cs
Normal file
31
OsmXmlToRegionConverter/TmpWay.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
namespace OsmXmlToRegionConverter;
|
||||||
|
|
||||||
|
public class TmpWay
|
||||||
|
{
|
||||||
|
public ulong id { get; }
|
||||||
|
public ulong[] wayNodeIds { get; }
|
||||||
|
public HashSet<Tag> tags { get; }
|
||||||
|
|
||||||
|
public TmpWay(ulong id, ulong[] wayNodeIds, HashSet<Tag> 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);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\OsmXmlToRegionConverter\OsmXmlToRegionConverter.csproj" />
|
||||||
<ProjectReference Include="..\Pathfinding\Pathfinding.csproj" />
|
<ProjectReference Include="..\Pathfinding\Pathfinding.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user