Пример #1
0
        /// <summary>
        /// Searches for the closest stop.
        /// </summary>
        /// <returns></returns>
        public static uint SearchClosest(this StopsDb.Enumerator stopsDbEnumerator, float latitude, float longitude,
                                         float offset)
        {
            // search for all nearby stops.
            var stops = Hilbert.Search(stopsDbEnumerator, latitude, longitude, offset);

            var bestDistance = double.MaxValue;
            var bestVertex   = Constants.NoStopId;

            foreach (var stop in stops)
            {
                if (stopsDbEnumerator.MoveTo(stop))
                {
                    var lat      = stopsDbEnumerator.Latitude;
                    var lon      = stopsDbEnumerator.Longitude;
                    var distance = Coordinate.DistanceEstimateInMeter(latitude, longitude, lat, lon);
                    if (distance < bestDistance)
                    { // a new closest vertex found.
                        bestDistance = distance;
                        bestVertex   = stop;
                    }
                }
            }
            return(bestVertex);
        }
Пример #2
0
        /// <summary>
        /// Searches the stops db assuming it has been sorted.
        /// </summary>
        public static HashSet <uint> Search(this StopsDb.Enumerator stopsDbEnumerator, int n, float minLatitude, float minLongitude,
                                            float maxLatitude, float maxLongitude)
        {
            var targets = Itinero.Algorithms.Search.Hilbert.HilbertCurve.HilbertDistances(
                System.Math.Max(minLatitude, -90),
                System.Math.Max(minLongitude, -180),
                System.Math.Min(maxLatitude, 90),
                System.Math.Min(maxLongitude, 180), n);

            targets.Sort();

            var stops     = new HashSet <uint>();
            var targetIdx = 0;
            var stop1     = (uint)0;
            var stop2     = (uint)stopsDbEnumerator.Count - 1;

            while (targetIdx < targets.Count)
            {
                uint stop;
                int  count;
                if (Hilbert.Search(stopsDbEnumerator, targets[targetIdx], n, stop1, stop2, out stop, out count))
                {         // the search was successful.
                    while (count > 0)
                    {     // there have been stops found.
                        if (stopsDbEnumerator.MoveTo((uint)stop + (uint)(count - 1)))
                        { // the stop was found.
                            var vertexLat = stopsDbEnumerator.Latitude;
                            var vertexLon = stopsDbEnumerator.Longitude;
                            if (minLatitude < vertexLat &&
                                minLongitude < vertexLon &&
                                maxLatitude > vertexLat &&
                                maxLongitude > vertexLon)
                            { // within offset.
                                stops.Add((uint)stop + (uint)(count - 1));
                            }
                        }
                        count--;
                    }

                    // update stop1.
                    stop1 = stop;
                }

                // move to next target.
                targetIdx++;
            }
            return(stops);
        }
Пример #3
0
 /// <summary>
 /// Searches the stops db for nearby stops assuming it has been sorted.
 /// </summary>
 public static HashSet <uint> Search(this StopsDb.Enumerator stopsDbEnumerator, float latitude, float longitude,
                                     float offset)
 {
     return(Hilbert.Search(stopsDbEnumerator, Itinero.Algorithms.Search.Hilbert.HilbertExtensions.DefaultHilbertSteps, latitude - offset, longitude - offset,
                           latitude + offset, longitude + offset));
 }
Пример #4
0
        /// <summary>
        /// Searches the stops db assuming it has been sorted.
        /// </summary>
        public static bool Search(this StopsDb.Enumerator stopsDbEnumerator, long hilbert, int n, uint stop1, uint stop2,
                                  out uint vertex, out int count)
        {
            var hilbert1 = Hilbert.Distance(stopsDbEnumerator, n, stop1);
            var hilbert2 = Hilbert.Distance(stopsDbEnumerator, n, stop2);

            while (stop1 <= stop2)
            {
                // check the current hilbert distances.
                if (hilbert1 > hilbert2)
                { // situation is impossible and probably the stops are not sorted.
                    throw new Exception("Stops not sorted: Binary search using hilbert distance not possible.");
                }
                if (hilbert1 == hilbert)
                { // found at hilbert1.
                    var lower = stop1;
                    while (hilbert1 == hilbert)
                    {
                        if (lower == 0)
                        { // stop here, not more vertices lower.
                            break;
                        }
                        lower--;
                        hilbert1 = Hilbert.Distance(stopsDbEnumerator, n, lower);
                    }
                    var upper = stop1;
                    hilbert1 = Hilbert.Distance(stopsDbEnumerator, n, upper);
                    while (hilbert1 == hilbert)
                    {
                        if (upper >= stopsDbEnumerator.Count - 1)
                        { // stop here, no more vertices higher.
                            break;
                        }
                        upper++;
                        hilbert1 = Hilbert.Distance(stopsDbEnumerator, n, upper);
                    }
                    vertex = lower;
                    count  = (int)(upper - lower) + 1;
                    return(true);
                }
                if (hilbert2 == hilbert)
                { // found at hilbert2.
                    var lower = stop2;
                    while (hilbert2 == hilbert)
                    {
                        if (lower == 0)
                        { // stop here, not more vertices lower.
                            break;
                        }
                        lower--;
                        hilbert2 = Hilbert.Distance(stopsDbEnumerator, n, lower);
                    }
                    var upper = stop2;
                    hilbert2 = Hilbert.Distance(stopsDbEnumerator, n, upper);
                    while (hilbert2 == hilbert)
                    {
                        if (upper >= stopsDbEnumerator.Count - 1)
                        { // stop here, no more vertices higher.
                            break;
                        }
                        upper++;
                        hilbert2 = Hilbert.Distance(stopsDbEnumerator, n, upper);
                    }
                    vertex = lower;
                    count  = (int)(upper - lower) + 1;
                    return(true);
                }
                if (hilbert1 == hilbert2 ||
                    stop1 == stop2 ||
                    stop1 == stop2 - 1)
                { // search is finished.
                    vertex = stop1;
                    count  = 0;
                    return(true);
                }

                // Binary search: calculate hilbert distance of the middle.
                var vertexMiddle  = stop1 + (uint)((stop2 - stop1) / 2);
                var hilbertMiddle = Hilbert.Distance(stopsDbEnumerator, n, vertexMiddle);
                if (hilbert <= hilbertMiddle)
                { // target is in first part.
                    stop2    = vertexMiddle;
                    hilbert2 = hilbertMiddle;
                }
                else
                { // target is in the second part.
                    stop1    = vertexMiddle;
                    hilbert1 = hilbertMiddle;
                }
            }
            vertex = stop1;
            count  = 0;
            return(false);
        }