Skip to content

Instantly share code, notes, and snippets.

@danzuep
Last active October 18, 2023 07:47
Show Gist options
  • Save danzuep/2007c6faa6e09a98337e4f4f84920410 to your computer and use it in GitHub Desktop.
Save danzuep/2007c6faa6e09a98337e4f4f84920410 to your computer and use it in GitHub Desktop.
public static class LocationExtensions
{
private const double RadianHalfPiToDegrees = 90.0;
private const double RadianPiToDegrees = 180.0;
private const double RadianTwoPiToDegrees = 360.0;
private static readonly Location _center = new Location(latitude: 0, longitude: 0);
private static readonly Location _northeast = new Location(latitude: RadianHalfPiToDegrees, longitude: RadianPiToDegrees);
private static readonly Location _southwest = new Location(latitude: -RadianHalfPiToDegrees, longitude: -RadianPiToDegrees);
private static Location GetValidLocation(double latitude, double longitude)
{
// Adjust latitude if out of bounds
while (latitude > RadianHalfPiToDegrees)
latitude -= RadianPiToDegrees;
while (latitude < -RadianHalfPiToDegrees)
latitude += RadianPiToDegrees;
// Adjust longitude if out of bounds
while (longitude > RadianPiToDegrees)
longitude -= RadianTwoPiToDegrees;
while (longitude < -RadianPiToDegrees)
longitude += RadianTwoPiToDegrees;
var location = new Location(latitude, longitude);
return location;
}
public static Location NextRandom(this Location center, double radiusDegrees, Random? random = null)
{
if (radiusDegrees > RadianHalfPiToDegrees) throw new ArgumentOutOfRangeException(nameof(radiusDegrees));
random ??= new Random();
center ??= _center;
var diameter = radiusDegrees * 2;
// Generate random latitude and longitude within the specified radius, with the center offset applied
var latitude = (random.NextDouble() * diameter) - radiusDegrees + center.Latitude;
var longitude = (random.NextDouble() * diameter) - radiusDegrees + center.Longitude;
var location = GetValidLocation(latitude, longitude);
return location;
}
public static Location NextLocation(this Random random, Location? northeast = null, Location? southwest = null)
{
random ??= new Random();
northeast ??= _northeast;
southwest ??= _southwest;
var latDiff = Math.Abs(northeast.Latitude - southwest.Latitude);
var latMax = Math.Max(northeast.Latitude, southwest.Latitude);
var latitude = random.NextDouble() * -latDiff + latMax;
var lonDiff = Math.Abs(northeast.Longitude - southwest.Longitude);
var lonMax = Math.Max(northeast.Longitude, southwest.Longitude);
var longitude = random.NextDouble() * -lonDiff + lonMax;
var location = GetValidLocation(latitude, longitude);
return location;
}
public static IEnumerable<Location> NextLocations(this Random random, int count)
{
if (random == null) throw new ArgumentNullException(nameof(random));
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
return Enumerable.Range(0, count).Select(i => random.NextLocation());
}
public static IList<Location> NextLocationsList(this Random random, int count)
{
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
random ??= new Random();
var locations = new List<Location>();
for (int i = 0; i < count; i++)
{
var location = random.NextLocation();
locations.Add(location);
}
return locations;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment