/// <summary> /// Since the way was extended - adjust that intersection to show that the tip of the 'extendedWay' is actually the /// new concatenated way. /// </summary> /// <param name="newIntersectNode"></param> /// <param name="extendingWay"></param> /// <param name="way"></param> private void ChangeIntersectingWay(OSMNode newIntersectNode, OSMWay extendingWay, OSMWay way) { var wayList = endNodeWayList[newIntersectNode.ID]; wayList.Remove(extendingWay); wayList.Add(way); }
private void PrependTo(OSMWay way, OSMWay extendingWay, int direction, int start) { int index = start; for (int i = 0; i < extendingWay.NodeList.Count; i++) { way.NodeList.Insert(0, extendingWay.NodeList[index]); index += direction; } }
/// <summary> /// Remove duplicate node from extending way /// </summary> /// <param name="way"></param> private void DropDuplicateNodes(OSMWay way) { var lastNode = way.NodeList[0]; for (int i = 1; i < way.NodeList.Count; i++) { var node = way.NodeList[i]; if (node.ID == lastNode.ID) { way.NodeList.RemoveAt(i); // Found a duplicate (normally only 1) break; } lastNode = node; } }
private void AddEndNode(OSMNode osmNode, OSMWay way) { var id = osmNode.ID; if (!endNodeWayList.ContainsKey(id)) { var newWayList = new List <OSMWay>(); endNodeWayList.Add(id, newWayList); } var wayList = endNodeWayList[id]; if (!wayList.Contains(way)) { wayList.Add(way); } }
/// <summary> /// Extend way by concatenating 'extendingWay' onto 'way' at the intersection node /// </summary> /// <param name="way"></param> /// <param name="intersectionNode"></param> /// <param name="extendingWay"></param> private void ExtendWay(OSMWay way, OSMNode intersectionNode, OSMWay extendingWay) { int direction = 1; int start = 0; OSMNode newIntersectNode = null; if (extendingWay.NodeList[0] == intersectionNode) { // Sequence Logic already set above newIntersectNode = extendingWay.NodeList[extendingWay.NodeList.Count - 1]; // Last node } else if (extendingWay.NodeList[extendingWay.NodeList.Count - 1] == intersectionNode) { // Attach from end of this way direction = -1; start = extendingWay.NodeList.Count - 1; newIntersectNode = extendingWay.NodeList[0]; // First node } if (way.NodeList[0] == intersectionNode) { // Attach before first node PrependTo(way, extendingWay, direction, start); } else if (way.NodeList[way.NodeList.Count - 1] == intersectionNode) { // Attach after last node AppendTo(way, extendingWay, direction, start); } else { // 3-way intersection at same node? Console.WriteLine("Logic error during glom."); } if (newIntersectNode.ID != intersectionNode.ID) { ChangeIntersectingWay(newIntersectNode, extendingWay, way); } DropDuplicateNodes(way); }
/// <summary> /// Check if 2 ways have identical tags /// </summary> /// <param name="way"></param> /// <param name="testWay"></param> /// <returns>true if identical</returns> private bool IdenticalTags(OSMWay way, OSMWay testWay) { bool isSame = false; if (way.Tags.Count == testWay.Tags.Count) { foreach (string tagName in way.Tags.Keys) { string tagValue = way.Tags[tagName]; if (!testWay.Tags.ContainsKey(tagName) || !testWay.Tags[tagName].Equals(tagValue)) { return(false); } } isSame = true; } return(isSame); }
public static void SetBboxFor(OSMWay osmWay) { foreach (var osmNode in osmWay.NodeList) { if (osmNode.Lat < osmWay.Bbox.MinLat) { osmWay.Bbox.MinLat = osmNode.Lat; } if (osmNode.Lat > osmWay.Bbox.MaxLat) { osmWay.Bbox.MaxLat = osmNode.Lat; } if (osmNode.Lon < osmWay.Bbox.MinLon) { osmWay.Bbox.MinLon = osmNode.Lon; } if (osmNode.Lon > osmWay.Bbox.MaxLon) { osmWay.Bbox.MaxLon = osmNode.Lon; } } }
//<way id = "4526699" version="9" timestamp="2016-09-15T08:28:48Z" uid="1745400" user="******" changeset="42167009"> // <nd ref="28099395"/> // <nd ref="1583440533"/> // <nd ref="299356652"/> // <nd ref="28099387"/> // <nd ref="1583440406"/> // <nd ref="28099388"/> // <nd ref="28099389"/> // <nd ref="28099390"/> // <tag k = "highway" v="primary_link"/> // <tag k = "oneway" v="yes"/> //</way> private void HandleWayRead(XmlReader reader) { var osmWay = new OSMWay(); osmWay.ID = Convert.ToInt64(reader.GetAttribute("id")); var doc = new System.Xml.XmlDocument(); XmlNode node = doc.ReadNode(reader); foreach (XmlAttribute attr in node.Attributes) { osmWay.InnerAttributes.Add(attr.Name, attr.Value); } if (node.HasChildNodes) { var nodeRefs = node.SelectNodes("nd"); foreach (XmlNode osmNode in nodeRefs) { var id = Convert.ToInt64(osmNode.Attributes["ref"].Value); if (osmNodes.ContainsKey(id)) { osmWay.NodeList.Add(osmNodes[id]); } } var tags = node.SelectNodes("tag"); foreach (XmlNode tag in tags) { var key = tag.Attributes["k"].Value; var val = tag.Attributes["v"].Value; osmWay.Tags.Add(key, val); } } SpatialUtilities.SetBboxFor(osmWay); osmWay.SetCenter(); osmWays.Add(osmWay.ID, osmWay); }
private void PerformGlom() { removeWay = new List <OSMWay>(); foreach (var id in endNodeWayList.Keys) { var wayList = endNodeWayList[id]; foreach (var way in wayList) { if (way.IsUsed) { continue; // Someone already glommed this way } OSMWay extendingWay = FindMatchingTags(way, wayList); if (extendingWay != null) { var intersectionNode = osmData.osmNodes[id]; ExtendWay(way, intersectionNode, extendingWay); extendingWay.IsUsed = true; // Mark as used since it was attached to 'way' removeWay.Add(extendingWay); } } } }
/// <summary> /// Search for a way with identical tags /// </summary> /// <param name="way"></param> /// <param name="wayList"></param> /// <returns></returns> private OSMWay FindMatchingTags(OSMWay way, List <OSMWay> wayList) { int foundCount = 0; OSMWay foundWay = null; foreach (var testWay in wayList) { if (testWay.ID != way.ID && !testWay.IsUsed) { if (IdenticalTags(way, testWay)) { foundCount++; foundWay = testWay; } } } if (foundCount == 1) { return(foundWay); } // Found 0 or 2+ matching ways return(null); }