public static GeoLocation ToRadianLocation(GeoLocation geoPoint) { double x = WorldUtils.ToRadians(geoPoint.Lon); double y = WorldUtils.ToRadians(geoPoint.Lat); return(new GeoLocation() { Lon = x, Lat = y }); }
public static double CalcBearing(GeoLocation origin, GeoLocation dest) { origin = WorldUtils.ToRadianLocation(origin); dest = WorldUtils.ToRadianLocation(dest); double range = (dest.Lon - origin.Lon); double y = Math.Sin(range) * Math.Cos(dest.Lat); double x = Math.Cos(origin.Lat) * Math.Sin(dest.Lat) - Math.Sin(origin.Lat) * Math.Cos(dest.Lat) * Math.Cos(range); double angle = Math.Atan2(y, x); return(WorldUtils.ToDegreesNormalized(angle)); }
public static double CalcDistance(GeoLocation origin, GeoLocation dest) { origin = WorldUtils.ToRadianLocation(origin); dest = WorldUtils.ToRadianLocation(dest); double sinProd = Math.Sin(origin.Lat) * Math.Sin(dest.Lat); double cosProd = Math.Cos(origin.Lat) * Math.Cos(dest.Lat); double lonDelta = (dest.Lon - origin.Lon); double angle = Math.Acos(sinProd + cosProd * Math.Cos(lonDelta)); double distance = angle * 6371.0; return(distance); }
public static void Init() { Flights = new List <FlightInfo>(); Airports = new List <WorldCity>(); var fullCityList = WorldLocations.GetAll(); var cities = new List <WorldCity>(); var countries = new Dictionary <string, int>(); foreach (var city in fullCityList) { if (countries.ContainsKey(city.Country)) { if (countries[city.Country] < 2) { cities.Add(city); countries[city.Country]++; } } else { cities.Add(city); countries.Add(city.Country, 1); } } fullCityList.Sort(new Comparison <WorldCity>(ComparePopulation)); int count = cities.Count; int flightsCount = 0; double minDistance = 200; double maxDistance = 10000; double flightsLimit = 250; for (int i = 0; i < count; i++) { WorldCity origin = cities[i]; int connectionsCount = 0; double connectionsMax = Math.Min(20, Math.Round(origin.Pop * 4)); for (int j = 0; j < count; j++) { WorldCity dest = cities[j]; GeoLocation originGeo = new GeoLocation() { Lat = origin.Lat, Lon = origin.Lon }; GeoLocation destGeo = new GeoLocation() { Lat = dest.Lat, Lon = dest.Lon }; if (origin.Name != dest.Name) { string route = origin.Name + "-" + dest.Name; bool routeIsValid = !FlightsLookup.ContainsKey(route); double distance = Math.Round(WorldUtils.CalcDistance(originGeo, destGeo)); bool distanceIsValid = distance > minDistance && distance < maxDistance; double pass = Math.Round(rand.NextDouble() * 200) + 150; double time = distance / 800; bool trafficIsValid = origin.Pop > 3 && dest.Pop > 1.0; if (routeIsValid && distanceIsValid && trafficIsValid) { FlightsLookup.Add(route, route); List <List <Point> > paths = WorldUtils.CalcPaths(originGeo, destGeo); flightsCount++; connectionsCount++; string id = origin.Name.Substring(0, 3).ToUpper() + "-" + flightsCount; FlightInfo flight = new FlightInfo() { ID = id, Origin = origin, Dest = dest, Time = time, Passengers = pass, Distance = distance, Points = paths }; Flights.Add(flight); } if (connectionsCount > connectionsMax) { //Console.WriteLine("Count: " + connectionsCount + ", Origin Name: " + origin.Name); break; } if (flightsCount > flightsLimit) { break; } } } } foreach (FlightInfo flight in Flights) { AddAirport(flight.Origin); AddAirport(flight.Dest); } Airports = AirportsLookup.Values.ToList(); Console.WriteLine("Cities= " + cities.Count + " Airports=" + Airports.Count + " Flights=" + Flights.Count); }
public static List <List <Point> > CalcPaths(GeoLocation origin, GeoLocation dest) { int interval = 200; var paths = new List <List <Point> >() { new List <Point>() }; int pathID = 0; double distance = WorldUtils.CalcDistance(origin, dest); if (distance <= interval) { // Console.WriteLine("Distance Less Than Equal To Interval!"); paths[pathID].Add(new Point() { X = dest.Lon, Y = dest.Lat }); } else { // Console.WriteLine("Distance Greater Than Interval!"); GeoLocation current = origin; GeoLocation previous = origin; for (int dist = interval; dist <= distance; dist += interval) { previous = current; paths[pathID].Add(new Point() { X = current.Lon, Y = current.Lat }); double bearing = WorldUtils.CalcBearing(current, dest); current = WorldUtils.CalcDestination(current, bearing, interval); if (previous.Lon > 150 && current.Lon < -150) { paths[pathID].Add(new Point() { X = 180, Y = current.Lat }); paths.Add(new List <Point>()); pathID++; current = new GeoLocation() { Lon = -180, Lat = current.Lat }; } else if (previous.Lon < -150 && current.Lon > 150) { paths[pathID].Add(new Point() { X = -180, Y = current.Lat }); paths.Add(new List <Point>()); pathID++; current = new GeoLocation() { Lon = 180, Lat = current.Lat }; } } paths[pathID].Add(new Point() { X = dest.Lon, Y = dest.Lat }); } return(paths); }