Skip to content

Instantly share code, notes, and snippets.

@rofr
Created August 8, 2015 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rofr/d5fe5f553327dc00a26a to your computer and use it in GitHub Desktop.
Save rofr/d5fe5f553327dc00a26a to your computer and use it in GitHub Desktop.
OrigoDB GeoSpatial and GraphModel using QuickGraph (quickgraph.codeplex.com)
[Serializable]
public class FlightModel : Model
{
[NonSerialized]
private AdjacencyGraph<string, Leg> _airports;
private readonly GeoSpatialIndex<string> _locations
= new GeoSpatialIndex<string>();
[Serializable]
public class Leg : Edge<string>
{
public readonly double TicketPrice;
public Leg(string from, string to, double ticketPrice)
: base(from, to)
{
TicketPrice = ticketPrice;
}
}
public bool IsEmpty
{
get { return _airports.IsVerticesEmpty; }
}
public void Add(string city, GeoPoint location)
{
if (_airports.ContainsVertex(city)) throw new CommandAbortedException("airport already exists");
_airports.AddVertex(city);
_locations[city] = location;
}
public void Connect(string source, string target, double ticketPrice)
{
if (!_airports.ContainsVertex(source)) throw new CommandAbortedException("Unknown source airport");
if (!_airports.ContainsVertex(target)) throw new CommandAbortedException("Unknown target airport");
_airports.AddEdge(new Leg(source, target, ticketPrice));
_airports.AddEdge(new Leg(target, source, ticketPrice));
}
/// <summary>
/// Get path by flying distance
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
/// <returns></returns>
public IEnumerable<Leg> GetShortestPathByDistance(string source, string target)
{
return GetCheapestPath(source, target, e => DistanceInKm(e.Source, e.Target));
}
/// <summary>
/// get path with least number of legs
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public IEnumerable<Leg> GetShortestPathByLegCount(string from, string to)
{
return GetCheapestPath(from, to, e => 1);
}
public IEnumerable<Leg> GetCheapestPathByTicketPrice(string from, string to)
{
return GetCheapestPath(from, to, e => ((Leg) e).TicketPrice);
}
public IEnumerable<Leg> GetCheapestPath(string from, string to, Func<Edge<string>, double> costFunction)
{
var dijkstra = _airports.ShortestPathsDijkstra(costFunction, from);
IEnumerable<Leg> path;
if (dijkstra.Invoke(to, out path)) return path;
throw new Exception(String.Format("No path from {0} to {1}", from, to));
}
/// <summary>
/// Get the five nearest airports
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public KeyValuePair<string,ArcDistance>[] MayDay(GeoPoint point)
{
double radius = 500;
while (true)
{
var result = _locations.WithinRadius(point, radius).ToArray();
if (result.Length >= 5) return result;
radius += 500;
}
}
private double DistanceInKm(string from, string to)
{
return _locations[from].DistanceTo(_locations[to]).ToKilometers();
}
protected override void SnapshotRestored()
{
//hack because AdjacencyGraph is not serializable
_airports = new AdjacencyGraph<string, Leg>();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using OrigoDB.Core;
using OrigoDB.Core.Modeling.Geo;
using QuickGraph;
using QuickGraph.Algorithms;
class Program
{
static void Main(string[] args)
{
var config = new EngineConfiguration();
config.EnsureSafeResults = false;
var engine = Engine.For<FlightModel>(config);
var flightModel = engine.GetProxy();
if (flightModel.IsEmpty)
{
Populate(flightModel);
}
var cheapest = flightModel.GetCheapestPathByTicketPrice("HNL", "ARN");
double price = 0;
foreach (var leg in cheapest)
{
Console.WriteLine(leg + ", price: " + leg.TicketPrice);
price += leg.TicketPrice;
}
Console.WriteLine("Total price: " + price);
//Point near LHR
var airports = flightModel.MayDay(new GeoPoint(52, -1.5));
foreach (var keyValuePair in airports)
{
Console.WriteLine("{0} is {1} km away", keyValuePair.Key, keyValuePair.Value.ToKilometers());
}
Console.ReadLine();
}
static void Populate(FlightModel flightModel)
{
flightModel.Add("LAX", new GeoPoint(33.9428575, -118.404631));
flightModel.Add("PDX", new GeoPoint(45.5897694, -122.5950942));
flightModel.Add("LHR", new GeoPoint(51.4689508, -0.4548784));
flightModel.Add("ARN", new GeoPoint(59.6497622, 17.9237807));
flightModel.Add("CGN", new GeoPoint(50.9572449, 6.9673223));
flightModel.Add("OSL", new GeoPoint(60.1975501, 11.1004153));
flightModel.Add("YVR", new GeoPoint(49.1966913, -123.1815123));
flightModel.Add("CPH", new GeoPoint(55.6180236, 12.6507628));
flightModel.Add("MUC", new GeoPoint(48.3537449, 11.7860028));
flightModel.Add("CAI", new GeoPoint(30.1114621, 31.4153838));
flightModel.Add("LOS", new GeoPoint(6.5818185, 3.3211348));
flightModel.Add("BKK", new GeoPoint(13.682246, 100.746903));
flightModel.Add("SIN", new GeoPoint(1.3550328, 103.987668));
flightModel.Add("HKG", new GeoPoint(22.3087355, 113.915957));
flightModel.Add("HND", new GeoPoint(35.5493932, 139.7798386));
flightModel.Add("SFO", new GeoPoint(37.6213129, -122.3789554));
flightModel.Add("FRA", new GeoPoint(50.0244026, 8.5461304));
flightModel.Add("CDG", new GeoPoint(49.006986, 2.5536005));
flightModel.Add("DXB", new GeoPoint(25.2523059, 55.3703183));
flightModel.Add("HNL", new GeoPoint(21.3212643, -157.9257257));
flightModel.Add("SEA", new GeoPoint(47.4502499, -122.3088165));
flightModel.Connect("HNL", "SEA", 289);
flightModel.Connect("DXB", "SEA", 5173);
flightModel.Connect("CDG", "DXB", 713);
flightModel.Connect("CDG", "SEA", 3736);
flightModel.Connect("FRA", "CDG", 160);
flightModel.Connect("FRA", "DXB", 668);
flightModel.Connect("FRA", "SEA", 648);
flightModel.Connect("SFO", "FRA", 2901);
flightModel.Connect("SFO", "CDG", 2927);
flightModel.Connect("SFO", "DXB", 1218);
flightModel.Connect("SFO", "HNL", 379);
flightModel.Connect("SFO", "SEA", 151);
flightModel.Connect("HND", "SFO", 3724);
flightModel.Connect("HND", "FRA", 2660);
flightModel.Connect("HND", "CDG", 2994);
flightModel.Connect("HND", "DXB", 3391);
flightModel.Connect("HND", "HNL", 1255);
flightModel.Connect("HND", "SEA", 2021);
flightModel.Connect("HKG", "HND", 618);
flightModel.Connect("HKG", "SFO", 1228);
flightModel.Connect("HKG", "FRA", 1415);
flightModel.Connect("HKG", "CDG", 1521);
flightModel.Connect("HKG", "DXB", 1615);
flightModel.Connect("HKG", "SEA", 1190);
flightModel.Connect("SIN", "HKG", 136);
flightModel.Connect("SIN", "HND", 672);
flightModel.Connect("SIN", "FRA", 1197);
flightModel.Connect("SIN", "CDG", 1527);
flightModel.Connect("SIN", "DXB", 531);
flightModel.Connect("BKK", "SIN", 55);
flightModel.Connect("BKK", "HKG", 115);
flightModel.Connect("BKK", "HND", 532);
flightModel.Connect("BKK", "FRA", 1278);
flightModel.Connect("BKK", "CDG", 1367);
flightModel.Connect("LOS", "FRA", 1732);
flightModel.Connect("LOS", "CDG", 1850);
flightModel.Connect("CAI", "LOS", 352);
flightModel.Connect("CAI", "BKK", 773);
flightModel.Connect("CAI", "FRA", 639);
flightModel.Connect("CAI", "CDG", 673);
flightModel.Connect("CAI", "DXB", 538);
flightModel.Connect("MUC", "CAI", 483);
flightModel.Connect("MUC", "BKK", 480);
flightModel.Connect("MUC", "SIN", 1167);
flightModel.Connect("MUC", "HND", 1209);
flightModel.Connect("MUC", "SFO", 3581);
flightModel.Connect("MUC", "FRA", 112);
flightModel.Connect("MUC", "CDG", 248);
flightModel.Connect("MUC", "DXB", 1034);
flightModel.Connect("CPH", "MUC", 184);
flightModel.Connect("CPH", "CAI", 346);
flightModel.Connect("CPH", "BKK", 561);
flightModel.Connect("CPH", "FRA", 169);
flightModel.Connect("CPH", "CDG", 127);
flightModel.Connect("YVR", "MUC", 2379);
flightModel.Connect("YVR", "HKG", 823);
flightModel.Connect("YVR", "HND", 1006);
flightModel.Connect("YVR", "SFO", 179);
flightModel.Connect("YVR", "FRA", 2389);
flightModel.Connect("YVR", "CDG", 1158);
flightModel.Connect("YVR", "HNL", 310);
flightModel.Connect("YVR", "SEA", 161);
flightModel.Connect("OSL", "CPH", 73);
flightModel.Connect("OSL", "MUC", 85);
flightModel.Connect("OSL", "BKK", 502);
flightModel.Connect("OSL", "FRA", 182);
flightModel.Connect("OSL", "CDG", 194);
flightModel.Connect("CGN", "MUC", 98);
flightModel.Connect("ARN", "CGN", 88);
flightModel.Connect("ARN", "OSL", 46);
flightModel.Connect("ARN", "CPH", 52);
flightModel.Connect("ARN", "MUC", 1056);
flightModel.Connect("ARN", "CAI", 0);
flightModel.Connect("ARN", "BKK", 466);
flightModel.Connect("ARN", "FRA", 185);
flightModel.Connect("ARN", "CDG", 246);
flightModel.Connect("ARN", "DXB", 477);
flightModel.Connect("LHR", "ARN", 96);
flightModel.Connect("LHR", "CGN", 110);
flightModel.Connect("LHR", "OSL", 181);
flightModel.Connect("LHR", "YVR", 2346);
flightModel.Connect("LHR", "CPH", 114);
flightModel.Connect("LHR", "MUC", 145);
flightModel.Connect("LHR", "CAI", 525);
flightModel.Connect("LHR", "LOS", 1537);
flightModel.Connect("LHR", "BKK", 580);
flightModel.Connect("LHR", "SIN", 731);
flightModel.Connect("LHR", "HKG", 1205);
flightModel.Connect("LHR", "HND", 1441);
flightModel.Connect("LHR", "SFO", 2091);
flightModel.Connect("LHR", "FRA", 145);
flightModel.Connect("LHR", "CDG", 160);
flightModel.Connect("LHR", "DXB", 696);
flightModel.Connect("LHR", "SEA", 2206);
flightModel.Connect("PDX", "YVR", 183);
flightModel.Connect("PDX", "SFO", 98);
flightModel.Connect("PDX", "HNL", 569);
flightModel.Connect("PDX", "SEA", 106);
flightModel.Connect("LAX", "PDX", 110);
flightModel.Connect("LAX", "LHR", 1287);
flightModel.Connect("LAX", "PDX", 110);
flightModel.Connect("LAX", "YVR", 116);
flightModel.Connect("LAX", "CPH", 952);
flightModel.Connect("LAX", "CAI", 2901);
flightModel.Connect("LAX", "HKG", 756);
flightModel.Connect("LAX", "HND", 998);
flightModel.Connect("LAX", "SFO", 130);
flightModel.Connect("LAX", "FRA", 2901);
flightModel.Connect("LAX", "CDG", 3065);
flightModel.Connect("LAX", "DXB", 1224);
flightModel.Connect("LAX", "HNL", 185);
flightModel.Connect("LAX", "SEA", 107);
}
}
HNL->SEA, price: 289
SEA->FRA, price: 648
FRA->ARN, price: 185
Total price: 1122
LHR is 93,1198818612241 km away
CDG is 439,245229229784 km away
CGN is 597,542955658633 km away
FRA is 735,849817151399 km away
CPH is 1010,409334502 km away
MUC is 1027,68797517073 km away
OSL is 1196,97339698373 km away
ARN is 1473,31477713848 km away
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment