Пример #1
0
        public static async Task <StopDistanceResult> GetNearestStop(GeoCoordinate center)
        {
            await nearestStopLock.WaitAsync();

            if (nearestStopTime < DateTime.Now - TimeSpan.FromMinutes(1))
            {
                LastNearestStop = await calculateNearestStop(center);

                nearestStopTime = DateTime.Now;
            }
            nearestStopLock.Release();
            return(LastNearestStop);
        }
Пример #2
0
        public static async Task <IEnumerable <StopDistanceResult> > WalkDistances(Stop sourceStop, IEnumerable <Stop> targetStops)
        {
            var    unknownStops = new List <Stop>();
            var    result       = new List <StopDistanceResult>();
            double walkingSpeed = WalkingSpeed();

            var sourceTransfers = sourceStop.Transfers.ToArray();

            foreach (Stop currentStop in targetStops)
            {
                if (currentStop.Coordinate == sourceStop.Coordinate)
                {
                    result.Add(new StopDistanceResult
                    {
                        Stop = currentStop,
                        EstimatedDuration = TimeSpan.Zero,
                        DistanceInMeters  = 0.0
                    });
                }
                else
                {
                    Transfer matchingTransfer = sourceTransfers.FirstOrDefault(t => t.Target.Coordinate == currentStop.Coordinate);
                    if (matchingTransfer != null)
                    {
                        var entry = new StopDistanceResult
                        {
                            Stop = currentStop,
                            EstimatedDuration = TimeSpan.FromSeconds(matchingTransfer.Distance / walkingSpeed),
                            DistanceInMeters  = (double)matchingTransfer.Distance
                        };
                        result.Add(entry);
                        AddToCache(sourceStop.Coordinate, currentStop.Coordinate, new Direction {
                            EstimatedDuration = entry.EstimatedDuration, DistanceInMeters = entry.DistanceInMeters
                        });
                    }
                    else
                    {
                        unknownStops.Add(currentStop);
                    }
                }
            }
            result.AddRange(await WalkDistances(sourceStop.Coordinate, unknownStops));
            return(result);
        }
Пример #3
0
        private static async Task <StopDistanceResult> calculateNearestStop(GeoCoordinate center)
        {
            StopDistanceResult result = null;

            if (center != null)
            {
                var stops = TransitBaseComponent.Current.Stops
                            .Where(s => s.StraightLineDistanceTo(center.Latitude, center.Longitude) < 2000)
                            .Select(s => new { Stop = s, Distance = s.StraightLineDistanceTo(center.Latitude, center.Longitude) })
                            .OrderBy(x => x.Distance)
                            .ToList();
                StopDistanceResult prevResult = new StopDistanceResult {
                    DistanceInMeters = double.MaxValue
                };
                while (stops.Count > 0)
                {
                    var minDistance = stops.First().Distance;
                    var nextStops   = stops.TakeWhile(s => s.Distance < minDistance + 200.0).ToList();
                    stops.RemoveRange(0, nextStops.Count);

                    var results = await WalkDistances(center, nextStops.Select(x => x.Stop));

                    var minResult = results.Concat(new StopDistanceResult[] { prevResult }).MinBy(r => r.DistanceInMeters);
                    if (stops.Count == 0 || minResult.DistanceInMeters <= stops.First().Distance)
                    {
                        result = minResult;
                        break;
                    }
                    else
                    {
                        prevResult = minResult;
                    }
                }
            }
            return(result);
        }