示例#1
0
        private IEnumerable <ThreadInfo> GetPartitionPaths(ThreadManager TM, Stack <PartitionPass> partitions, Dictionary <int, SortedSet <Node> > goalNodes)
        {
            var currentThread = TM.CurrentThread;

            var currentNode = partitions.Peek().Target;
            var paths       = new List <List <PartitionPass> >();

            // Travel to other partitions, and get the paths through them
            yield return(TM.Await(currentThread, GetNodePartitions(TM, currentNode, "spGetNodePartitions")));

            var nodePartitions = TM.GetResult <SortedSet <int> >(currentThread).Except(partitions.Select((PartitionPass pp) => pp.Partition));

            foreach (int partition in nodePartitions)
            {
                // See if any goal nodes are in this partition
                if (goalNodes.ContainsKey(partition))
                {
                    foreach (var goalNode in goalNodes[partition])
                    {
                        partitions.Push(new PartitionPass(partition, goalNode, _settings.WeightedDist(currentNode, goalNode)));
                        var path = partitions.Reverse().Skip(1).ToList();
                        paths.Add(path);
                        partitions.Pop();
                    }
                }

                // Go to all the boundaries of this partition
                yield return(TM.Await(currentThread, GetPartitionBoundaries(TM, partition)));

                var targetNodes = TM.GetResult <SortedSet <Node> >(currentThread);
                if (goalNodes.ContainsKey(partition))
                {
                    targetNodes.ExceptWith(goalNodes[partition]);
                }
                targetNodes.Remove(currentNode);
                foreach (var targetNode in targetNodes)
                {
                    partitions.Push(new PartitionPass(partition, targetNode, _settings.WeightedDist(currentNode, targetNode)));
                    yield return(TM.Await(currentThread, GetPartitionPaths(TM, partitions, goalNodes)));

                    paths.AddRange(TM.GetResult <List <List <PartitionPass> > >(currentThread));
                    partitions.Pop();
                }
            }

            yield return(TM.Return(currentThread, paths));
        }
示例#2
0
        public IEnumerable <ThreadInfo> GetDirections(ThreadManager TM, int to, Dictionary <string, string> query)
        {
            var currentThread = TM.CurrentThread;

            _settings = new DirectionsSettings(query);

            yield return(TM.Await(currentThread, GetShortestPath(TM, to)));

            _pathFindingDone = 1;

            yield return(TM.Await(currentThread, GetDirectionMessages(TM)));

            _messageFindingDone = 1;
            yield return(TM.Sleep(currentThread, 60000));

            _directions.Remove(_id);

            yield return(TM.Return(currentThread));
        }
示例#3
0
        public IEnumerable <ThreadInfo> HandlePath(ThreadManager TM, IEnumerable <string> path, Dictionary <string, string> query, object state)
        {
            var currentThread = TM.CurrentThread;

            if (path.Any())
            {
                if (Redirects.ContainsKey(path.First()))
                {
                    yield return(TM.Await(currentThread, Redirects[path.First()].HandlePath(TM, path.Skip(1), query, state)));
                }
                else
                {
                    int intValue;
                    if (Int32.TryParse(path.First(), out intValue))
                    {
                        yield return(TM.Await(currentThread, HandleIntPath(TM, intValue, state)));

                        if (!(TM.GetResultNoException(currentThread) is JsonResponse))
                        {
                            yield return(TM.Await(currentThread, IntRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread))));
                        }
                    }
                    else
                    {
                        double floatValue;
                        if (Double.TryParse(path.First(), out floatValue))
                        {
                            yield return(TM.Await(currentThread, HandleFloatPath(TM, floatValue, state)));

                            if (!(TM.GetResultNoException(currentThread) is JsonResponse))
                            {
                                yield return(TM.Await(currentThread, FloatRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread))));
                            }
                        }
                        else
                        {
                            yield return(TM.Await(currentThread, HandleUnknownPath(TM, path.First(), state)));

                            if (!(TM.GetResultNoException(currentThread) is JsonResponse))
                            {
                                yield return(TM.Await(currentThread, UnknownRedirect.HandlePath(TM, path.Skip(1), query, TM.GetResult(currentThread))));
                            }
                        }
                    }
                }
            }
            else
            {
                yield return(TM.Await(currentThread, HandleNoPath(TM, query, state)));
            }

            yield return(TM.Return(currentThread));
        }
示例#4
0
        private static IEnumerable <ThreadInfo> HandleRequest(ThreadManager TM, HttpListenerContext context)
        {
            var currentThread = TM.CurrentThread;

            JsonResponse result = null;

            var path = Uri.UnescapeDataString(context.Request.Url.LocalPath).Split('/').SkipWhile(String.IsNullOrEmpty).TakeWhile(s => !String.IsNullOrEmpty(s));
            Dictionary <string, string> query = new Dictionary <string, string>();

            if (!String.IsNullOrEmpty(context.Request.Url.Query))
            {
                var querySplit = Uri.UnescapeDataString(context.Request.Url.Query).Split('?', '&', ';').Skip(1);
                foreach (string field in querySplit)
                {
                    int equalsPos = field.IndexOf('=');
                    if (equalsPos == -1 || equalsPos == 0 || equalsPos == field.Length - 1)
                    {
                        result = new JsonResponse(HttpStatusCode.BadRequest);
                        break;
                    }
                    query.Add(field.Substring(0, equalsPos), field.Substring(equalsPos + 1, field.Length - equalsPos - 1));
                }
            }

            if (result == null)
            {
                yield return(TM.Await(currentThread, _handler.HandlePath(TM, path, query, new object())));

                try
                {
                    result = TM.GetResult <JsonResponse>(currentThread);
                }
                catch (Exception)
                {
                    result = new JsonResponse(HttpStatusCode.InternalServerError);
                }
            }

            var encoding = new ASCIIEncoding();

            byte[] b;
            if (result.Json != null)
            {
                b = encoding.GetBytes(result.Json.Serialize());
            }
            else
            {
                b = encoding.GetBytes(result.Message);
            }
            context.Response.OutputStream.Write(b, 0, b.Length);
            context.Response.StatusCode = (int)result.StatusCode;
            context.Response.Close();
            yield return(TM.Return(currentThread, null));
        }
示例#5
0
        protected virtual IEnumerable <ThreadInfo> HandleIntPath(ThreadManager TM, int value, object state)
        {
            var currentThread = TM.CurrentThread;

            if (IntRedirect != null)
            {
                yield return(TM.Return(currentThread, value));
            }
            else
            {
                yield return(TM.Await(currentThread, HandleFloatPath(TM, value, state)));

                yield return(TM.Return(currentThread));
            }
        }
示例#6
0
        private IEnumerable <ThreadInfo> GetShortestPath(ThreadManager TM, int to)
        {
            var currentThread = TM.CurrentThread;

            // See if the start node is already in the goal location
            yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationNodes", new SqlParameter("@location", to)));

            using (var table = TM.GetResult <DataTable>(currentThread)) {
                if (table.Rows.Count == 0)
                {
                    // Error - no nodes in goal location
                    yield return(TM.Return(currentThread));
                }

                foreach (DataRow row in table.Rows)
                {
                    if (new Node(row).Id == _start.Id)
                    {
                        // Already at goal
                        yield return(TM.Return(currentThread));
                    }
                }
            }

            // Get the nodes on the boundary of the goal location
            var goalNodes = new Dictionary <int, SortedSet <Node> >();

            yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationBoundaryNodes", new SqlParameter("@location", to)));

            using (var table = TM.GetResult <DataTable>(currentThread)) {
                if (table.Rows.Count == 0)
                {
                    // Error - no nodes on goal location's boundary
                    yield return(TM.Return(currentThread));
                }

                foreach (DataRow row in table.Rows)
                {
                    var node = new Node(row);
                    if (!goalNodes.ContainsKey(node.Partition.Value))
                    {
                        goalNodes[node.Partition.Value] = new SortedSet <Node>(new NodeComparer());
                    }
                    goalNodes[node.Partition.Value].Add(node);
                }
            }

            // Get the possible partition paths
            Stack <PartitionPass> partitions = new Stack <PartitionPass>();

            partitions.Push(new PartitionPass(-1, _start, 0));
            yield return(TM.Await(currentThread, GetPartitionPaths(TM, partitions, goalNodes)));

            var passes = TM.GetResult <List <List <PartitionPass> > >(currentThread);

            SortedSet <TargetPath>         queue         = new SortedSet <TargetPath>(new TargetPathComparer());
            Dictionary <int, ShortestPath> shortestPaths = new Dictionary <int, ShortestPath>();

            shortestPaths[_start.Id] = new ShortestPath();
            foreach (var pass in passes)
            {
                queue.Add(new TargetPath(_start, 0, pass, queue, _settings));
            }

            while (true)
            {
                var currentPath = queue.First();

                _pathFindingDone = Math.Max(_pathFindingDone, currentPath.DistSoFar * currentPath.DistSoFar / (currentPath.BestDist * currentPath.BestDist));

                if (goalNodes.Any(kvp => kvp.Value.Contains(currentPath.CurrentNode)))
                {
                    var currentNode = currentPath.CurrentNode;
                    var prevNode    = shortestPaths[currentNode.Id].PrevNode;
                    _paths.Add(new DirectionPath(currentNode.Lat, currentNode.Lon, null, true, null, currentNode.Altitude, currentNode.Location, currentNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward));
                    while (currentNode.Id != _start.Id)
                    {
                        _paths.Insert(0, new DirectionPath(prevNode.Lat, prevNode.Lon, null, false, null, prevNode.Altitude, prevNode.Location, prevNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward));
                        currentNode = prevNode;
                        prevNode    = shortestPaths[currentNode.Id].PrevNode;
                    }
                    _paths.First().Flag = true;
                    yield return(TM.Return(currentThread));
                }

                yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetPathsFromNode",
                                           new SqlParameter("@node", currentPath.CurrentNode.Id),
                                           new SqlParameter("@part", currentPath.PartitionsLeft.First().Partition)));

                using (var table = TM.GetResult <DataTable>(currentThread)) {
                    foreach (DataRow row in table.Rows)
                    {
                        var    path     = new PathToNode(row, currentPath.CurrentNode.Id, currentPath.PartitionsLeft.First().Partition);
                        double pathDist = _settings.WeightedDist(currentPath.CurrentNode, path.Node);

                        if (shortestPaths.ContainsKey(path.Node.Id))
                        {
                            if (shortestPaths[path.Node.Id].TotalDist > currentPath.DistSoFar + pathDist)
                            {
                                shortestPaths[path.Node.Id].SetPrevNode(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths);
                            }
                            else if (shortestPaths[path.Node.Id].TotalDist < currentPath.DistSoFar + pathDist)
                            {
                                continue;
                            }
                            // TODO
                        }
                        else
                        {
                            shortestPaths[path.Node.Id] = new ShortestPath(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths);
                            // TODO
                        }

                        if (path.Node.Id == currentPath.PartitionsLeft.First().Target.Id)
                        {
                            queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft.Skip(1).ToList(), queue, _settings));
                        }
                        else
                        {
                            queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft, queue, _settings));
                        }
                    }
                }

                queue.Remove(currentPath);
            }
        }