Пример #1
0
        public IEnumerable <GeoIndex> Enumerate(GeoPoint point, Distance distance)
        {
            if (distance < Distance.FromMetres(0))
            {
                return(Enumerable.Empty <GeoIndex>());
            }

            var center = indexes.GetIndex(point);

            if (!indexes.IsIndexValid(center))
            {
                throw new ArgumentOutOfRangeException(nameof(point), $"Geo map data does not cover location {point}");
            }

            var length = Math.Max((int)Math.Floor(distance / resolution) - 1, 0);
            var right  = center.X + length;

            while (indexes.GetGeoPoint(new GeoIndex(right + 1, center.Y)).GetDistance(point) <= distance)
            {
                right++;
            }

            var left = center.X - length;

            while (indexes.GetGeoPoint(new GeoIndex(left - 1, center.Y)).GetDistance(point) <= distance)
            {
                left--;
            }

            left  = indexes.ClampX(left);
            right = indexes.ClampX(right);

            return(Enumerate(Enumerable.Range(center.X, right - center.X + 1).Reverse(), center.Y, point, distance)
                   .Concat(Enumerate(Enumerable.Range(left, center.X - left), center.Y, point, distance)));
        }
Пример #2
0
        private IEnumerable <GeoIndex> NaiveNearestIndexes(GeoPoint point, Distance distance)
        {
            var center = indexes.GetIndex(point);
            var length = (int)Math.Ceiling(distance / resolution) * 2;

            if (length == 0)
            {
                var index = new GeoIndex(center.X, center.Y);
                if (indexes.IsIndexValid(index))
                {
                    yield return(index);
                }
                yield break;
            }

            for (var x = center.X - length; x <= center.X + length; x++)
            {
                for (var y = center.Y - length; y <= center.Y + length; y++)
                {
                    var index = new GeoIndex(x, y);
                    if (indexes.IsIndexValid(index) && indexes.GetGeoPoint(index).GetDistance(point) <= distance)
                    {
                        yield return(index);
                    }
                }
            }
        }
Пример #3
0
        public GeoMapData Dump()
        {
#if DEBUG
            var uncoveredSuburbs = new Dictionary <Suburb, GeoPoint>();
#endif
            var dumpSuburbs = new Dictionary <Suburb, List <GeoIndex> >();
            for (var i = 0; i < indexes.LatitudeIntervalCount; i++)
            {
                for (var j = 0; j < indexes.LongitudeIntervalCount; j++)
                {
                    if (suburbs[i][j] == null)
                    {
                        continue;
                    }

                    foreach (var suburb in suburbs[i][j])
                    {
                        if (string.IsNullOrEmpty(suburb.Postcode))
                        {
#if DEBUG
                            uncoveredSuburbs[suburb] = indexes.GetGeoPoint(new GeoIndex(i, j));
#endif
                            continue;
                        }

                        if (!dumpSuburbs.ContainsKey(suburb))
                        {
                            dumpSuburbs[suburb] = new List <GeoIndex>();
                        }
                        dumpSuburbs[suburb].Add(new GeoIndex(i, j));
                    }
                }
            }

#if DEBUG
            using var sw = new StreamWriter("uncovered-suburbs.txt");
            foreach (var(key, value) in uncoveredSuburbs)
            {
                sw.WriteLine($"{key}\t{value}");
            }
#endif

            return(new GeoMapData
            {
                GeoIndexes = indexes.Dump(),
                ResolutionInMetres = resolution.AsMetres,
                Suburbs = dumpSuburbs.Select(kv => new SuburbGeoIndexes
                {
                    Suburb = kv.Key,
                    IndexRanges = ToRanges(kv.Value).Select(x => x.ToArray()).ToList()
                }).ToList()
            });
        }