Я пишу свою собственную программу навигации по карте C#. Я использую OpenStreetMaps для данных карты. Это большой XML-файл, содержащий узлы и способы. Я написал конвертер, который удаляет XML-файл из бесполезного мусора (например, timestamp, user и т. Д.), Поэтому файл станет меньше.Усиление сложности анализа XML - C# XML Looping
Теперь, когда я пытаюсь пересечь XML и преобразовывать данные в объект C# Пути и узлы, я столкнулся с проблемой. Мне нужно сделать так много циклов, что время загрузки слишком длинное.
Пример XML (W = путь, п = узла, RF = ссылкой на узел):
<n id="2638006578" l="5.9295547" b="52.5619519" />
<n id="2638006579" l="5.9301973" b="52.5619526" />
<n id="2638006581" l="5.9303625" b="52.5619565" />
<n id="2638006583" l="5.9389539" b="52.5619577" />
<n id="2638006589" l="5.9386643" b="52.5619733" />
<n id="2638006590" l="5.9296231" b="52.5619760" />
<n id="2638006595" l="5.9358987" b="52.5619864" />
<n id="2638006596" l="5.9335913" b="52.5619865" />
<w id="453071384">
<nd rf="2638006581" />
<nd rf="2638006590" />
<nd rf="2638006596" />
<nd rf="2638006583" />
<nd rf="2638006578" />
</w>
<w id="453071385">
<nd rf="2638006596" />
<nd rf="2638006578" />
<nd rf="2638006581" />
<nd rf="2638006583" />
</w>
Путь узлы содержат ссылки на узлы, так что узел может быть существует в несколько путей (узлы соединяют пути).
Узлы содержат долготу и широту (l = lon, b = lat).
Эти файлы XML содержат узлов и путей, поэтому это не просто небольшой файл. Файл XML в приведенном ниже примере кода имеет 500K строк.
Мой код
class Program {
static List<Way> ways = new List<Way>();
static List<Node> nodes = new List<Node>();
static void Main(String[] args) {
read();
}
public static void read() {
String xmlLoc = @"C:\Users\MyName\Desktop\result.xml";
long time = DateTime.Now.Ticks;
Parse(xmlLoc);
long time2 = DateTime.Now.Ticks;
Console.WriteLine("Done: {0} ms", (time2 - time)/10000);
Console.WriteLine(" - Nodes Amount:" + nodes.Count());
Console.WriteLine(" - Ways Amount: " + ways.Count());
}
private static Node GetByRef(long reference) {
return nodes.First(x => x.ID == reference);
}
private static void Parse(string path) {
using (XmlReader reader = XmlReader.Create(path)) {
reader.MoveToContent();
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
XElement element = XElement.ReadFrom(reader) as XElement;
if (element.Name.ToString().Equals("w")) {
Way w = new Way();
var name = element.Attribute("nm");
if (name != null) w.Name = name.Value;
var children = element.Descendants("nd");
foreach (XElement child in children) w.References.Add(long.Parse(child.Attribute("rf").Value));
ways.Add(w);
}else if (element.Name.ToString().Equals("n")) {
Node n = new Node();
n.ID = long.Parse(element.Attribute("id").Value);
n.Lon = double.Parse(element.Attribute("l").Value);
n.Lat = double.Parse(element.Attribute("b").Value);
nodes.Add(n);
}
}
}
}
}
}
class Way {
public List<long> References { get; private set; }
public long ID { get; set; }
public String Name { get; set; }
public bool OneWay { get; set; }
public Way() {
this.References = new List<long>();
}
}
class Node {
public long ID { get; set; }
public double Lat { get; set; }
public double Lon { get; set; }
}
В настоящее время не существует действительное отношение между классом Пути и класса Node. Есть только список с long
значениями. Мне почему-то нужно добавить список с узлами в класс Way, но это потребует от меня работы с другим (два?) Для/while циклов. Это будет означать O (N4), я считаю, что это медленно.
Технически я ищу и решение, и способы построить это лучше, если вы посоветуете, я бы хотел его услышать!
Заранее благодарен!
PS: Если мне нужно обновить/изменить свой вопрос, пожалуйста, скажите мне, а не немедленно.
Рассмотрим встроенный XML десериализации вместо того, чтобы писать собственный анализатор. Первый пример среди многих других: http://stackoverflow.com/questions/364253/how-to-deserialize-xml-document – Tomalak
Действительно ли необходимо циклически перебирать XML-файл более одного раза? Как насчет того, чтобы делать только один проход и * хранить * все необходимое позже? – scai
@Tomalak Я загляну в него, спасибо! – Dubb