예제 #1
0
파일: OsmFile.cs 프로젝트: Levrum/Levrum
        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);
                    }
                }
            }
        }
예제 #2
0
파일: OsmFile.cs 프로젝트: Levrum/Levrum
        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;
                }
            }
        }
예제 #3
0
파일: OsmFile.cs 프로젝트: Levrum/Levrum
        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);
                    }
                }
            }
        }