public static OsmStreetSystem FromOsmFile(string file)
        {
            Dictionary <long, Waypoint> wps       = new Dictionary <long, Waypoint>();
            OsmStreetSystem             newSystem = new OsmStreetSystem();

            using (XmlReader rd = XmlReader.Create(file))
            {
                while (rd.Read())
                {
                    if (rd.NodeType == XmlNodeType.Element)
                    {
                        switch (rd.Name)
                        {
                        case "node":
                            var newwp = ParseWaypoint(rd);
                            wps.Add(newwp.Id, newwp);
                            break;

                        case "way":
                            ParseWay(rd, wps, newSystem);
                            break;
                        }
                    }
                }
            }

            return(newSystem);
        }
        public static OsmStreetSystem Build(OsmLoader data)
        {
            OsmStreetSystem newSystem = new OsmStreetSystem();

            var ways = data.Ways.Values.Where(w => Defaults.HighwayWhitelist.Contains(w.GetTag("highway", "-")));

            foreach (var way in ways)
            {
                bool oneWay = (way.GetTag("oneway", "no") == "yes") ||
                              (way.GetTag("junction", "-") == "roundabout");

                Waypoint lastPoint = newSystem.GetWaypointForNode(way.Nodes[0]);

                var conInfo = MakeConnectionInfo(way);

                for (int i = 1; i < way.Nodes.Count; i++)
                {
                    var current = newSystem.GetWaypointForNode(way.Nodes[i]);

                    lastPoint.ConnectTo(current, conInfo);

                    if (!oneWay)
                    {
                        current.ConnectTo(lastPoint, conInfo);
                    }

                    lastPoint = current;
                }
            }

            return(newSystem);
        }
        public static OsmStreetSystem LoadSystem(Stream str)
        {
            OsmStreetSystem newSys = new OsmStreetSystem();

            Dictionary <long, ConnectionInfo> infos = new Dictionary <long, ConnectionInfo>();

            using (var rd = XmlReader.Create(str))
            {
                while (rd.Read())
                {
                    if (rd.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }

                    switch (rd.Name)
                    {
                    case "wp":
                        var wp = ParseWaypoint(rd);
                        newSys.Waypoints.Add(wp.Id, wp);
                        break;

                    case "ci":
                        var id = ReadInfoId(rd);
                        infos.Add(id, ReadInfo(rd));
                        break;

                    case "rel":
                        long start = long.Parse(rd.GetAttribute("start"));
                        long end   = long.Parse(rd.GetAttribute("end"));
                        long ci    = long.Parse(rd.GetAttribute("ci"));

                        newSys.Waypoints[start].ConnectTo(newSys.Waypoints[end], infos[ci]);
                        break;
                    }
                }
            }

            return(newSys);
        }
        private static void ParseWay(XmlReader rd, Dictionary <long, Waypoint> wps, OsmStreetSystem strt)
        {
            if (rd.IsEmptyElement)
            {
                return;
            }

            var wpIds = new ArrayList(2000);
            Dictionary <string, string> tags = new Dictionary <string, string>();

            while (rd.Read() && rd.NodeType != XmlNodeType.EndElement)
            {
                if (rd.NodeType == XmlNodeType.Element)
                {
                    switch (rd.Name)
                    {
                    case "nd":
                        wpIds.Add(long.Parse(rd.GetAttribute("ref")));
                        break;

                    case "tag":
                        tags.Add(
                            rd.GetAttribute("k"),
                            rd.GetAttribute("v")
                            );
                        break;
                    }
                }
            }

            if (!Defaults.HighwayWhitelist.Contains(tags.Get("highway", "-")))
            {
                return;
            }

            bool oneWay = (tags.Get("oneway", "no") == "yes") ||
                          (tags.Get("junction", "-") == "roundabout");

            var info = MakeConnectionInfo(tags);

            Waypoint last = wps[(long)wpIds[0]];

            if (!strt.Waypoints.ContainsKey(last.Id))
            {
                strt.Waypoints.Add(last.Id, last);
            }

            for (int i = 1; i < wpIds.Count; i++)
            {
                Waypoint current = wps[(long)wpIds[i]];
                if (!strt.Waypoints.ContainsKey(current.Id))
                {
                    strt.Waypoints.Add(current.Id, current);
                }

                last.ConnectTo(current, info);

                if (!oneWay)
                {
                    current.ConnectTo(last, info);
                }

                last = current;
            }
        }