private void cleanSplitWays() { // This function is a doozy! Hopefully I translated its functionality okay, but if you're running into a problem with intersections it probably lies here. Dictionary <string, string> removedWays = new Dictionary <string, string>(); List <OSMNode> nodes = Nodes; for (int i = 0; i < nodes.Count; i++) { OSMNode node = nodes[i]; List <OSMWay> filteredWaysForNode = new List <OSMWay>(); // Need to create a mega way of the two ways the node is splitting. Otherwise multiple things get screwed up down the line. foreach (string usedInWay in node.WayReferences.ToList()) { string newID = usedInWay; while (removedWays.ContainsKey(newID)) { node.WayReferences.Remove(newID); newID = removedWays[newID]; node.WayReferences.Add(newID); } } foreach (string wayId in node.WayReferences) { OSMWay way; if (WaysById.TryGetValue(wayId, out way)) { if (way.Tags.ContainsKey("highway") && AcceptedRoadTypes.Contains(way.Tags["highway"])) { filteredWaysForNode.Add(way); } } } if (node.References == 2 && filteredWaysForNode.Count == 2) { OSMWay megaWay, dyingWay; bool reversedDyingWay = false; OSMWay way1 = filteredWaysForNode[0]; OSMWay way2 = filteredWaysForNode[1]; bool isLastNodeForWayOne = way1.NodeReferences[way1.NodeReferences.Count - 1] == node.ID; bool isLastNodeForWayTwo = way2.NodeReferences[way2.NodeReferences.Count - 1] == node.ID; if (isLastNodeForWayOne) { megaWay = way1; dyingWay = way2; if (isLastNodeForWayTwo) { // Situation where they are both facing towards the split way node reversedDyingWay = true; } } else if (isLastNodeForWayTwo) { megaWay = way2; dyingWay = way1; } else { // Weird scenario where they are both facing away from the split way node OSMIntersection intersection = new OSMIntersection(); intersection.ID = node.ID; intersection.Location = node.Location; Intersections[node.ID] = intersection; continue; } // This is when one way loops around and connects to the other way more than once bool multipleConnections = false; foreach (string nodeId in dyingWay.NodeReferences) { if (nodeId != node.ID && megaWay.NodeReferences.Contains(nodeId)) { multipleConnections = true; if (!Intersections.ContainsKey(nodeId)) { OSMNode multiNode = NodesById[nodeId]; multiNode.IsIntersection = true; OSMIntersection intersection = new OSMIntersection(); intersection.ID = nodeId; intersection.Location = multiNode.Location; Intersections[nodeId] = intersection; } break; } } if (multipleConnections) { continue; } if (megaWay.ID == dyingWay.ID) { node.References--; node.WayReferences.RemoveAt(1); continue; } if ((megaWay.Oneway || dyingWay.Oneway) ^ (megaWay.Oneway && dyingWay.Oneway)) { //If there is just one one-way street, add an intersection. If they both are, ...way murder time! if (!Intersections.ContainsKey(node.ID)) { OSMIntersection intersection = new OSMIntersection(); intersection.ID = node.ID; intersection.Location = node.Location; Intersections[node.ID] = intersection; } continue; } // Identity theft megaWay.Name = string.IsNullOrWhiteSpace(megaWay.Name) ? dyingWay.Name : megaWay.Name; // Combine max speeds double mwMaxSpeed, dwMaxSpeed; if (double.TryParse(megaWay.MaxSpeed, out mwMaxSpeed) && double.TryParse(dyingWay.MaxSpeed, out dwMaxSpeed)) { megaWay.MaxSpeed = Math.Max(mwMaxSpeed, dwMaxSpeed).ToString(); } else if (string.IsNullOrWhiteSpace(megaWay.MaxSpeed)) { megaWay.MaxSpeed = dyingWay.MaxSpeed; } if (!reversedDyingWay) { foreach (string nodeId in dyingWay.NodeReferences) { if (nodeId != node.ID) { megaWay.NodeReferences.Add(nodeId); } } } else { for (int j = dyingWay.NodeReferences.Count - 1; j >= 0; j--) { if (dyingWay.NodeReferences[j] != node.ID) { megaWay.NodeReferences.Add(dyingWay.NodeReferences[j]); } } } double previousLength = megaWay.NodeDistances[megaWay.NodeDistances.Count - 1]; if (!reversedDyingWay) { for (int h = 0; h < dyingWay.NodeReferences.Count; h++) { string nodeId = dyingWay.NodeReferences[h]; if (nodeId != node.ID) { megaWay.NodeDistances.Add(previousLength + dyingWay.NodeDistances[h]); } } } else { for (int j = dyingWay.NodeReferences.Count - 1; j >= 0; j--) { string nodeId = dyingWay.NodeReferences[j]; if (nodeId != node.ID) { int inverseIndex = dyingWay.NodeReferences.Count - 1 - j; megaWay.NodeDistances.Add(dyingWay.NodeDistances[inverseIndex] + previousLength); } } } //megaWay uses mega drain... WaysById.Remove(dyingWay.ID); node.WayReferences.Remove(dyingWay.ID); node.References--; removedWays[dyingWay.ID] = megaWay.ID; foreach (var murderedWay in removedWays.ToList()) { if (murderedWay.Value == dyingWay.ID) { removedWays[murderedWay.Key] = megaWay.ID; } } //Its super effective! //megaWay regains some HP //dyingWay has fainted! //Levrum used ULTRA BALL! //Gotcha! megaWay was caught! //megaWay's data was added to the POKEDEX //Give a nickname to the captured megaWay? claimOsmObjectAsLevrums(megaWay); } } // Fix any references that may have changed after the last loop foreach (OSMNode node in NodesById.Values.ToList()) { foreach (string usedInWay in node.WayReferences.ToList()) { string newID = usedInWay; while (removedWays.ContainsKey(newID)) { node.WayReferences.Remove(newID); newID = removedWays[newID]; node.WayReferences.Add(newID); } } } }
private void createEndIntersections() { foreach (OSMWay way in Ways) { if (!way.Tags.ContainsKey("highway") || !AcceptedRoadTypes.Contains(way.Tags["highway"]) || way.NodeReferences.Count < 2) { continue; } string firstNodeId = way.NodeReferences[0]; string lastNodeId = way.NodeReferences[way.NodeReferences.Count - 1]; OSMNode firstNode, lastNode; if (NodesById.TryGetValue(firstNodeId, out firstNode) && firstNode.References == 1 && !Intersections.ContainsKey(firstNode.ID)) { OSMIntersection intersection = new OSMIntersection(); intersection.ID = firstNode.ID; intersection.Location = firstNode.Location; Intersections[firstNode.ID] = intersection; } if (NodesById.TryGetValue(lastNodeId, out lastNode) && lastNode.References == 1 && !Intersections.ContainsKey(lastNode.ID)) { OSMIntersection intersection = new OSMIntersection(); intersection.ID = lastNode.ID; intersection.Location = lastNode.Location; Intersections[lastNode.ID] = intersection; } } }
private void generateIntersections() { foreach (OSMWay way in Ways) { List <string> nodeIdsForWay = way.NodeReferences; if (nodeIdsForWay.Count < 2) { continue; } if (!way.Tags.ContainsKey("highway") || !AcceptedRoadTypes.Contains(way.Tags["highway"])) { continue; } string firstNodeId = way.NodeReferences[0]; string lastNodeId = way.NodeReferences[way.NodeReferences.Count - 1]; if (NodesById.ContainsKey(firstNodeId)) { NodesById[firstNodeId].EndNodeFlag = true; } if (NodesById.ContainsKey(lastNodeId)) { NodesById[lastNodeId].EndNodeFlag = true; } foreach (string nodeId in nodeIdsForWay) { OSMNode node; if (!NodesById.TryGetValue(nodeId, out node)) { continue; } node.References++; if (firstNodeId != nodeId && lastNodeId != nodeId) { node.References++; } else { int nodeIndex = nodeIdsForWay.IndexOf(nodeId); if (nodeIndex != 0 && nodeIndex < nodeIdsForWay.Count - 1) // Handles instances where a node appears twice in a way, once in the middle and once at the end { node.References++; } } if (node.References >= 3 && !Intersections.ContainsKey(nodeId)) { OSMIntersection intersection = new OSMIntersection(); intersection.ID = nodeId; intersection.Location = node.Location; Intersections[nodeId] = intersection; } else if (way.Name != null && !node.InternalName.Contains(way.Name)) { node.InternalName = string.IsNullOrWhiteSpace(node.Name) ? way.Name : string.Format("{0} / {1}", node.Name, way.Name); } } } }