///<summary> ///For given region, target precision and extension size, ///returns region boundary that gives available ranges of latitude/longitude ///for regions of target precision, overlapping with extension of given region /// </summary> /// <param name="region">Source <see cref="Region"/></param> /// <param name="extension">Size of region extension (in precision-aligned steps)</param> /// <param name="precision"> Target precision parameter. Any integer value.</param> /// <returns>Region boundary rb. Every region with Lat/Lon of corresponding RegionBoundary's min /// belonging to rb overlaps with extension of given region <see cref="Region"/> objects</returns> public static RegionBoundary GetConnectedRegionsRange(Region region, int extension, int precision) { RegionBoundary rb = RegionHelper.GetRegionBoundary(region); double step = PrecisionHelper.GetStep(precision); rb.Min.Latitude -= extension * step; rb.Min.Longitude -= extension * step; rb.Max.Latitude += (extension - 1) * step; rb.Max.Latitude += (extension - 1) * step; return rb; }
/// <summary> /// Enumerates all regions of given precisions range connected with given <see cref="Region"/>/> /// Being connected means either intersects with the region extended by overlap amount of precision-aligned grids /// </summary> /// <param name="region">Source <see cref="Region"/></param> /// <param name="extension">Size of region extension (in precision-aligned steps)</param> /// <param name="precisionStart"> Start precision parameter. Any integer value.</param> /// <param name="precisionCount"> Count of precision parameters to include. Any non-negative integer value.</param> /// <returns>Collection of connected <see cref="Region"/> objects</returns> public static IEnumerable<Region> GetConnectedRegions(Region region, int extension, int precisionStart, int precisionCount = 1) { RegionBoundary rb = GetRegionBoundary(region); for (int precision = precisionStart; precision < precisionStart + precisionCount; ++precision) { double step = PrecisionHelper.GetStep(precision); for (double lat = rb.Min.Latitude - extension * step; lat < rb.Max.Latitude + extension * step; lat += step) { for (double lon = rb.Min.Longitude - extension * step; lon < rb.Max.Longitude + extension * step; lon += step) { yield return new Region { LatitudePrefix = lat, LongitudePrefix = lon, Precision = precision }; } } } }
private static IEnumerable <Region> GetRegionCoveragePositive(Coordinates location, float radiusMeters, int precision) { int latMax = (int)Coordinates.MAX_LATITUDE; int lonMax = (int)Coordinates.MAX_LONGITUDE; int step = PrecisionHelper.GetStep(precision); int latCurrent = PrecisionHelper.Round(location.Latitude, precision); int latNext = Math.Min(latCurrent + step, latMax); int lonCurrent = PrecisionHelper.Round(location.Longitude, precision); int lonNext = Math.Min(lonCurrent + step, lonMax); //region itself yield return(new Region(latCurrent, lonCurrent, precision)); if (precision > 0) { if (latCurrent > 0) { // South-West if (lonCurrent > 0 && GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latCurrent, Longitude = (float)lonCurrent }) < radiusMeters) { yield return(new Region(latCurrent - step, lonCurrent - step, precision)); } // South if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latCurrent, Longitude = location.Longitude }) < radiusMeters) { yield return(new Region(latCurrent - step, lonCurrent, precision)); } // South-East if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latCurrent, Longitude = (float)lonNext }) < radiusMeters) { yield return(new Region(latCurrent - step, lonNext == lonMax ? -lonCurrent : lonNext, precision)); } } if (lonCurrent > 0) { // West if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = location.Latitude, Longitude = (float)lonCurrent }) < radiusMeters) { yield return(new Region(latCurrent, lonCurrent - step, precision)); } //North-West if (latNext < latMax && GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latNext, Longitude = (float)lonCurrent }) < radiusMeters) { yield return(new Region(latNext, lonCurrent - step, precision)); } } if (latNext < latMax) { //North if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latNext, Longitude = location.Longitude }) < radiusMeters) { yield return(new Region(latNext, lonCurrent, precision)); } //North-East if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = (float)latNext, Longitude = (float)lonNext }) < radiusMeters) { yield return(new Region(latNext, lonNext == lonMax ? -lonCurrent : lonNext, precision)); } } //East if (GeoHelper.DistanceMeters(location, new Coordinates { Latitude = location.Latitude, Longitude = (float)lonNext }) < radiusMeters) { if (lonNext < lonMax) { yield return(new Region(latCurrent, lonNext, precision)); } else if (lonCurrent > 0) { yield return(new Region(latCurrent, -lonCurrent, precision)); } } } }