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))); }
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); } } } }
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() }); }