/// <summary> /// Builds a transitdb from a GTFS or loads it if it's there already. /// </summary> public static TransitDb RunOrLoad(string gtfsFolder) { TransitDb transitDb = null; var transitDbFile = gtfsFolder + ".transitdb"; if (File.Exists(transitDbFile)) { try { using (var stream = File.OpenRead(transitDbFile)) { transitDb = TransitDb.Deserialize(stream); } Itinero.Logging.Logger.Log("TransitDbBuilder", Itinero.Logging.TraceEventType.Warning, "Existing TransitDb found, not rebuilding, delete file to retest."); } catch { Itinero.Logging.Logger.Log("TransitDbBuilder", Itinero.Logging.TraceEventType.Warning, "Invalid existing TransitDb file, could not load file."); transitDb = null; } } if (transitDb == null) { transitDb = TransitDbBuilder.Run(gtfsFolder); using (var stream = File.Open(transitDbFile, FileMode.Create)) { transitDb.Serialize(stream); } } return(transitDb); }
public void Translate_Journey_CorrectTranslation() { const ulong time = 15761461220ul; const ulong previousTime = 15761454920ul; var tdb = new TransitDb(0); var wr = tdb.GetWriter(); var l = wr.AddOrUpdateStop("Some Station", 4.123, 51.789, null); var rootL = new StopId(1, 140860940, 184354050); // Supposed to be an OSM-location var connection = new Connection(new ConnectionId(0, 1), "testConnection", rootL, l, previousTime, (ushort)(time - previousTime), new TripId(0, 0)); var connId = wr.AddOrUpdateConnection(connection); wr.Close(); var genesis = new Journey <TransferMetric>(rootL, previousTime, TransferMetric.Factory); var j = genesis.ChainSpecial(connId, previousTime, l, new TripId(3, 3)); var op = new Operator("Op", tdb, null, 500, new string[] { }, new string[] { }); var operators = new OperatorSet(new List <Operator> { op }); var translatedSegment = operators.TranslateWalkSegment(j, new CoordinatesCache(new DummyOtherMode(), false)); Assert.Contains("openstreetmap.org", translatedSegment.Departure.Location.Id); Assert.DoesNotContain("openstreetmap.org", translatedSegment.Arrival.Location.Id); }
/// <summary> /// Adds a trip for the given agency. /// </summary> public static uint AddTrip(this TransitDb db, Trip trip, global::GTFS.Entities.Route route, uint agencyId, uint scheduleId) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", trip.Id); attributes.AddNotNullOrWhiteSpace("accessibility_type", trip.AccessibilityType == null ? string.Empty : trip.AccessibilityType.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("block_id", trip.BlockId); attributes.AddNotNullOrWhiteSpace("direction", trip.Direction == null ? string.Empty : trip.Direction.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("headsign", trip.Headsign); attributes.AddNotNullOrWhiteSpace("route_id", trip.RouteId); attributes.AddNotNullOrWhiteSpace("service_id", trip.ServiceId); attributes.AddNotNullOrWhiteSpace("shape_id", trip.ShapeId); attributes.AddNotNullOrWhiteSpace("short_name", trip.ShortName); attributes.AddNotNullOrWhiteSpace("route_color", route.Color.ToHexColorString()); attributes.AddNotNullOrWhiteSpace("route_description", route.Description); attributes.AddNotNullOrWhiteSpace("route_long_name", route.LongName); attributes.AddNotNullOrWhiteSpace("route_short_name", route.ShortName); attributes.AddNotNullOrWhiteSpace("route_text_color", route.TextColor.ToHexColorString()); var metaId = db.TripAttributes.Add(attributes); return(db.AddTrip(scheduleId, agencyId, metaId)); }
public static TransitDb BuildOrLoad() { // load data. TransitDb db = null; if (!File.Exists("data.transitdb")) { var profile = Belgium.Sncb(); // create a stops db and connections db. db = new TransitDb(); // load connections for the current day. var w = db.GetWriter(); profile.AddAllLocationsTo(w, Serilog.Log.Warning); profile.AddAllConnectionsTo(w, DateTime.Now, DateTime.Now.AddHours(8), Serilog.Log.Warning); w.Close(); // store to disk. using (var stream = File.Open("data.transitdb", FileMode.Create)) { db.Latest.WriteTo(stream); } } else { using (var stream = File.OpenRead("data.transitdb")) { db = TransitDb.ReadFrom(stream); } } return(db); }
public void TestAddTransfersDb() { var db = new TransitDb(); db.AddTransfersDb(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(), new TransfersDb(1024)); Assert.IsTrue(db.HasTransfersDb(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest())); var tranfersDb = db.GetTransfersDb(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest()); Assert.IsNotNull(tranfersDb); Assert.Catch <ArgumentNullException>(() => { db.AddTransfersDb(null, new TransfersDb(1024)); }); Assert.Catch <ArgumentNullException>(() => { db.AddTransfersDb(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(), null); }); Assert.Catch <ArgumentNullException>(() => { db.HasTransfersDb(null); }); Assert.Catch <ArgumentNullException>(() => { db.GetTransfersDb(null); }); }
public void TestSerializeDeserialize() { var transitDb = new TransitDb(); var reader = new GTFSReader <GTFSFeed>(); var feed = reader.Read(GTFS.sample_feed.SampleFeed.BuildSource()); transitDb.LoadFrom(feed); Assert.AreEqual(13, transitDb.TripsCount); Assert.AreEqual(9, transitDb.StopsCount); Assert.AreEqual(22, transitDb.ConnectionsCount); using (var stream = new MemoryStream()) { var size = transitDb.Serialize(stream); stream.Seek(0, SeekOrigin.Begin); transitDb = TransitDb.Deserialize(stream); Assert.AreEqual(13, transitDb.TripsCount); Assert.AreEqual(9, transitDb.StopsCount); Assert.AreEqual(22, transitDb.ConnectionsCount); } }
/// <summary> /// Adds all given calendars in a way as compact as possible. /// </summary> public static uint AddCalendars(this TransitDb db, List <Calendar> calendars) { // merge mergeable calendars. int c = 0; while (c + 1 < calendars.Count) { Calendar mergedCalendar = null; if (calendars[c].TryMerge(calendars[c + 1], out mergedCalendar)) { calendars[c] = mergedCalendar; calendars.RemoveAt(c + 1); } else { c++; } } // add to db. var newScheduleId = db.AddSchedule(); for (var j = 0; j < calendars.Count; j++) { db.AddScheduleEntry(newScheduleId, calendars[j].StartDate, calendars[j].EndDate, calendars[j].Mask); } return(newScheduleId); }
public ClosestStopSearch(Router router, TransitDb transitDb, Profile profile, RouterPoint routerPoint, float max, bool backward = false) { _router = router; _transitDb = transitDb; _max = max; _profile = profile; _routerPoint = routerPoint; _backward = backward; }
public static Result <Route> TryCalculateIntermodal(this Router router, TransitDb db, Profile profile, Coordinate source, Coordinate target) { var sourceResolved = router.Resolve(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(), source.Latitude, source.Longitude); var targetResolved = router.ResolveConnected(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(), target.Latitude, target.Longitude); return(router.TryCalculateIntermodal(db, profile, sourceResolved, targetResolved)); }
/// <summary> /// Extracts a tile of stops. /// </summary> public static Stop[] ExtractPointsForStops(this TransitDb transitDb, ulong tileId, StopLayerConfig config) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (config.Name == null) { throw new ArgumentException("Layer configuration has no name set."); } if (transitDb.StopsCount == 0) { return(new Stop[0]); } var tile = new Tile(tileId); var diffX = (tile.Top - tile.Bottom); var diffY = (tile.Right - tile.Left); var marginX = diffX / 1024; var marginY = diffY / 1024; var tileBox = new LocalGeo.Box(tile.Bottom - marginY, tile.Left - marginX, tile.Top + marginY, tile.Right + marginX); var stopsEnumerator = transitDb.GetStopsEnumerator(); var stopIds = stopsEnumerator.Search( tileBox.MinLat - diffY, tileBox.MinLon - diffX, tileBox.MaxLat + diffY, tileBox.MaxLon + diffX); var stops = new Stop[stopIds.Count]; var i = 0; foreach (var stopId in stopIds) { stopsEnumerator.MoveTo(stopId); if (config != null && config.IncludeStopsFunc != null && !config.IncludeStopsFunc(stopsEnumerator)) { // explicitly excluded this stop. continue; } stops[i] = new Stop() { Latitude = stopsEnumerator.Latitude, Longitude = stopsEnumerator.Longitude, MetaId = stopsEnumerator.MetaId }; i++; } return(stops); }
/// <summary> /// Creates a new instance of the profile search algorithm. /// </summary> public ProfileSearch(TransitDb db, DateTime departureTime, TransfersDb transfersDb, Func <uint, DateTime, bool> isTripPossible) { _db = db; _transfersDb = transfersDb; _sources = new Dictionary <uint, uint>(); _targets = new Dictionary <uint, uint>(); _departureTime = departureTime; _isTripPossible = isTripPossible; }
public Operator(string name, TransitDb tdb, Synchronizer synchronizer, uint maxSearch, IEnumerable <string> altNames, IEnumerable <string> tags) { MaxSearch = maxSearch; Name = name; Tdb = tdb; Synchronizer = synchronizer; AltNames = altNames?.ToHashSet() ?? new HashSet <string>(); Tags = tags?.ToHashSet() ?? new HashSet <string>(); }
public void TestLoadFromSampleFeed() { var transitDb = new TransitDb(); var reader = new GTFSReader <GTFSFeed>(); var feed = reader.Read(sample_feed.SampleFeed.BuildSource()); transitDb.LoadFrom(feed); Assert.AreEqual(13, transitDb.TripsCount); Assert.AreEqual(9, transitDb.StopsCount); Assert.AreEqual(22, transitDb.ConnectionsCount); }
public void TestAddStopLinksDb() { // build a simple network and connections db. var routerDb = new RouterDb(); routerDb.LoadTestNetwork( System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream( "Itinero.Transit.Test.test_data.networks.network1.geojson")); var transitDb = new TransitDb(); var feed = DummyGTFSFeedBuilder.OneConnection( TimeOfDay.FromTotalSeconds(0), TimeOfDay.FromTotalSeconds(3600)); feed.Stops.Get(0).Latitude = 51.22965768754021f; feed.Stops.Get(0).Longitude = 4.460974931716918f; feed.Stops.Get(1).Latitude = 51.229617377118906f; feed.Stops.Get(1).Longitude = 4.463152885437011f; transitDb.LoadFrom(feed); var db = new MultimodalDb(routerDb, transitDb); // add stop links. var profile = VehicleMock.Car().Fastest(); db.AddStopLinksDb(profile); // check result. var stopLinksDb = db.GetStopLinksDb(profile); Assert.IsNotNull(stopLinksDb); var stop0 = db.TransitDb.SearchFirstStopsWithTags((t) => { return(t.Contains("id", "0")); }); var stop1 = db.TransitDb.SearchFirstStopsWithTags((t) => { return(t.Contains("id", "1")); }); var stopLinksDbEnumerator = stopLinksDb.GetEnumerator(); stopLinksDbEnumerator.MoveTo(stop0); Assert.AreEqual(1, stopLinksDbEnumerator.Count); Assert.IsTrue(stopLinksDbEnumerator.MoveNext()); Assert.AreEqual(0, stopLinksDbEnumerator.EdgeId); Assert.AreEqual(0, stopLinksDbEnumerator.Offset); stopLinksDbEnumerator.MoveTo(stop1); Assert.AreEqual(1, stopLinksDbEnumerator.Count); Assert.IsTrue(stopLinksDbEnumerator.MoveNext()); Assert.AreEqual(0, stopLinksDbEnumerator.EdgeId); Assert.AreEqual(ushort.MaxValue, stopLinksDbEnumerator.Offset); }
public void TestLoadFromOneConnection() { var transitDb = new TransitDb(); var feed = DummyGTFSFeedBuilder.OneConnection( TimeOfDay.FromTotalSeconds(0), TimeOfDay.FromTotalSeconds(3600)); transitDb.LoadFrom(feed); Assert.AreEqual(1, transitDb.TripsCount); var tripEnumerator = transitDb.GetTripsEnumerator(); Assert.IsTrue(tripEnumerator.MoveTo(0)); Assert.AreEqual(0, tripEnumerator.Id); Assert.AreEqual(0, tripEnumerator.ScheduleId); var tripMeta = new AttributeCollection(transitDb.TripAttributes.Get(tripEnumerator.MetaId)); Assert.IsTrue(tripMeta.Contains("id", "0")); Assert.IsTrue(tripMeta.Contains("route_id", "0")); Assert.IsTrue(tripMeta.Contains("service_id", "0")); var agencyMeta = new AttributeCollection(transitDb.AgencyAttributes.Get(tripEnumerator.AgencyId)); Assert.IsTrue(agencyMeta.Contains("id", "0")); Assert.AreEqual(2, transitDb.StopsCount); var stopEnumerator = transitDb.GetStopsEnumerator(); Assert.IsTrue(stopEnumerator.MoveTo(0)); Assert.AreEqual(0, stopEnumerator.Id); Assert.AreEqual(0, stopEnumerator.Latitude); Assert.AreEqual(0, stopEnumerator.Longitude); var stopMeta = new AttributeCollection(transitDb.StopAttributes.Get(stopEnumerator.MetaId)); Assert.IsTrue(stopMeta.Contains("id", "0")); Assert.IsTrue(stopEnumerator.MoveTo(1)); Assert.AreEqual(1, stopEnumerator.Id); Assert.AreEqual(1, stopEnumerator.Latitude); Assert.AreEqual(1, stopEnumerator.Longitude); stopMeta = new AttributeCollection(transitDb.StopAttributes.Get(stopEnumerator.MetaId)); Assert.IsTrue(stopMeta.Contains("id", "1")); Assert.AreEqual(1, transitDb.ConnectionsCount); transitDb.SortConnections(DefaultSorting.DepartureTime, null); var connectionEnumerator = transitDb.GetConnectionsEnumerator(DefaultSorting.DepartureTime); Assert.IsTrue(connectionEnumerator.MoveTo(0)); Assert.AreEqual(0, connectionEnumerator.Id); Assert.AreEqual(0, connectionEnumerator.DepartureStop); Assert.AreEqual(0, connectionEnumerator.DepartureTime); Assert.AreEqual(1, connectionEnumerator.ArrivalStop); Assert.AreEqual(3600, connectionEnumerator.ArrivalTime); Assert.AreEqual(0, connectionEnumerator.TripId); }
public void TranslateJourney_SimpleJourney_CorrectTranslation() { var depDate = new DateTime(2019, 06, 19, 10, 00, 00).ToUniversalTime(); var tdb = new TransitDb(0); var writer = tdb.GetWriter(); var stop0 = writer.AddOrUpdateStop("https://example.org/stop0", 0, 0); var stop1 = writer.AddOrUpdateStop("https://example.org/stop1", 1, 1); var stop2 = writer.AddOrUpdateStop("https://example.org/stop2", 2, 2); var trip0 = writer.AddOrUpdateTrip("https://example.org/trip0", new[] { new Attribute("headsign", "Oostende") }); var conn0 = writer.AddOrUpdateConnection(stop0, stop1, "https://example.org/conn1", depDate.AddMinutes(-10), 10 * 60, 0, 0, trip0, 0); writer.Close(); var con = tdb.Latest.ConnectionsDb; var connection = con.Get(conn0); var genesis = new Journey <TransferMetric>(stop0, depDate.ToUnixTime(), TransferMetric.Factory, Journey <TransferMetric> .EarliestArrivalScanJourney); var journey0 = genesis.ChainForward(connection); var journey1 = journey0.ChainSpecial( Journey <TransferMetric> .OTHERMODE, depDate.AddMinutes(15).ToUnixTime(), stop2, new TripId(uint.MaxValue, uint.MaxValue)); var state = new State(new List <Operator> { new Operator("test", tdb, null, 0, null, null) }, null, null, null); var cache = new CoordinatesCache(new CrowsFlightTransferGenerator(), false); var translated = state.Operators.GetFullView().Translate(journey1, cache); Assert.Equal("https://example.org/stop0", translated.Segments[0].Departure.Location.Id); Assert.Equal("https://example.org/stop1", translated.Segments[0].Arrival.Location.Id); Assert.Equal("https://example.org/trip0", translated.Segments[0].Vehicle); Assert.Equal("https://example.org/stop1", translated.Segments[1].Departure.Location.Id); Assert.Equal("https://example.org/stop2", translated.Segments[1].Arrival.Location.Id); Assert.Null(translated.Segments[1].Vehicle); }
/// <summary> /// Tests merge transitdbs. /// </summary> public static Func <TransitDb> GetTestMergeTransitDbs(TransitDb[] transitDbs) { return(() => { var transitDb = new TransitDb(); for (var i = 0; i < transitDbs.Length; i++) { transitDb.CopyFrom(transitDbs[i]); } transitDb.SortConnections(DefaultSorting.DepartureTime, null); transitDb.SortStops(); return transitDb; }); }
/// <summary> /// Adds an agency. /// </summary> public static uint AddAgency(this TransitDb db, Agency agency) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", agency.Id.ToStringEmptyWhenNull()); attributes.AddNotNullOrWhiteSpace("fare_url", agency.FareURL); attributes.AddNotNullOrWhiteSpace("language_code", agency.LanguageCode); attributes.AddNotNullOrWhiteSpace("name", agency.Name); attributes.AddNotNullOrWhiteSpace("phone", agency.Phone); attributes.AddNotNullOrWhiteSpace("timezone", agency.Timezone); attributes.AddNotNullOrWhiteSpace("url", agency.URL); return(db.AgencyAttributes.Add(attributes)); }
/// <summary> /// Tests building a transitdb. /// </summary> public static Func <TransitDb> GetTestBuildTransitDb(string gtfsFolder) { var reader = new GTFSReader <GTFSFeed>(false); return(() => { var feed = reader.Read(new GTFSDirectorySource(gtfsFolder)); var transitDb = new TransitDb(); transitDb.LoadFrom(feed); transitDb.SortConnections(DefaultSorting.DepartureTime, null); transitDb.SortStops(); return transitDb; }); }
public void GetConnections_SimpleTdb_ReturnsOneConnection() { var dt = new DateTime(2019, 09, 07, 10, 00, 00).ToUniversalTime(); var tdb = new TransitDb(0); var wr = tdb.GetWriter(); var stop0 = wr.AddOrUpdateStop("abc", 1.0, 1.0, new List <Attribute> { new Attribute("name", "abc") }); var stop1 = wr.AddOrUpdateStop("def", 1.5, 1.0, new List <Attribute> { new Attribute("name", "def") }); // To early wr.AddOrUpdateConnection(stop0, stop1, "conn3", dt.AddMinutes(-15), 1000, 0, 0, new TripId(0, 0), 0); // This one we are searching for wr.AddOrUpdateConnection(stop0, stop1, "conn0", dt.AddMinutes(5), 1000, 0, 0, new TripId(0, 0), 0); // Wrong departure station wr.AddOrUpdateConnection(stop1, stop0, "conn1", dt.AddMinutes(15), 1000, 0, 0, new TripId(0, 0), 0); // To late: falls out of the window of 1hr wr.AddOrUpdateConnection(stop0, stop1, "conn2", dt.AddMinutes(65), 1000, 0, 0, new TripId(0, 0), 0); wr.Close(); var transitDbs = new List <Operator> { { new Operator("", tdb, null, 0, null, null) } }; State.GlobalState = new State(transitDbs, null, null, null); var lc = new LocationController(); var result = lc.GetConnections("abc", dt); var returnedSegments = result.Value.Segments; Assert.NotNull(returnedSegments); Assert.Single(returnedSegments); Assert.Equal(dt.AddMinutes(5), returnedSegments[0].Departure.Time); }
public void TestAddTransfersDbExtension() { var db = new TransitDb(); var stop1 = db.AddStop(51.10700473650233f, 3.9084237813949585f, 1); var stop2 = db.AddStop(51.10700473650233f, 3.9091318845748897f, 1); db.AddTransfersDbForPedestrians(5 * 60); var profile = Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(); var transfers = db.GetTransfersDb(profile); var transferEnumerator = transfers.GetTransferEnumerator(); Assert.IsTrue(transferEnumerator.MoveTo(stop1)); Assert.IsTrue(transferEnumerator.MoveNext()); Assert.AreEqual(Coordinate.DistanceEstimateInMeter( 51.10700473650233f, 3.9084237813949585f, 51.10700473650233f, 3.9091318845748897f) * profile.Factor(Osm.Data.TransitDbExtensions.DefaultEdgeProfile).Value, transferEnumerator.Seconds, 1); Assert.AreEqual(stop2, transferEnumerator.Stop); }
/// <summary> /// Extracts a tile of stops. /// </summary> public static StopLayer ExtractPointLayerForStops(this TransitDb transitDb, ulong tileId, StopLayerConfig config) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (config.Name == null) { throw new ArgumentException("Layer configuration has no name set."); } return(new StopLayer() { Meta = transitDb.StopAttributes, Name = config.Name, Points = transitDb.ExtractPointsForStops(tileId, config) }); }
/// <summary> /// Adds a stop. /// </summary> /// <returns></returns> public static uint AddStop(this TransitDb db, Stop stop) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", stop.Id); attributes.AddNotNullOrWhiteSpace("code", stop.Code); attributes.AddNotNullOrWhiteSpace("description", stop.Description); attributes.AddNotNullOrWhiteSpace("location_type", stop.LocationType == null ? string.Empty : stop.LocationType.Value.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("name", stop.Name); attributes.AddNotNullOrWhiteSpace("timezone", stop.Timezone); attributes.AddNotNullOrWhiteSpace("url", stop.Url); attributes.AddNotNullOrWhiteSpace("wheelchairboarding", stop.WheelchairBoarding); attributes.AddNotNullOrWhiteSpace("zone", stop.Zone); var metaId = db.StopAttributes.Add(attributes); return(db.AddStop((float)stop.Latitude, (float)stop.Longitude, metaId)); }
/// <summary> /// Extracts a tile of stops. /// </summary> public static VectorTile ExtractTileForStops(this TransitDb transitDb, ulong tileId, StopLayerConfig config) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (config.Name == null) { throw new ArgumentException("Layer configuration has no name set."); } var layers = new List <Layer>(1); layers.Add(transitDb.ExtractPointLayerForStops(tileId, config)); return(new VectorTile() { Layers = layers, TileId = tileId }); }
public void TestOneHopUnsuccessful() { // build dummy db. var db = new TransitDb(); db.AddStop(0, 0, 0); db.AddStop(1, 1, 1); db.AddTrip(0, 0, 0); db.AddConnection(0, 1, 0, 8 * 3600, 8 * 3600 + 10 * 60); db.SortConnections(DefaultSorting.DepartureTime, null); // run algorithm. var algorithm = new ProfileSearch(db, new DateTime(2017, 05, 10, 08, 30, 00), (profileId, day) => true); algorithm.SetSourceStop(0, 08 * 3600 + 30 * 60); algorithm.SetTargetStop(1, 0); algorithm.Run(); // test results. Assert.IsTrue(algorithm.HasRun); Assert.IsFalse(algorithm.HasSucceeded); }
/// <summary> /// Tries to load the transitDB from disk. Gives null if loading failed /// </summary> private static TransitDb TryLoadFromDisk(string path, uint id) { if (!File.Exists(path)) { Log.Information($"TransitDb {path} does not exist. Skipping load"); return(null); } try { Log.Information($"Attempting to read a transitDB from {path}"); var db = TransitDb.ReadFrom(path, id); Log.Information( $"TransitDB loaded. Loaded times are {db.Latest.ConnectionsDb.EarliestDate.FromUnixTime():s} --> {db.Latest.ConnectionsDb.LatestDate.FromUnixTime():s}"); return(db); } catch (Exception e) { Log.Error( $"Could not load transitDB from disk (path is {path}). Will start with an empty transitDB instead.\n{e.Message}"); return(null); } }
/// <summary> /// Adds a transfers db. /// </summary> public static void AddTransfersDb(this TransitDb db, Profiles.Profile profile, float maxTimeInSeconds) { db.AddTransfersDb(profile, TransitDbExtensions.DefaultEdgeProfile, maxTimeInSeconds); }
/// <summary> /// Adds a transfers db for pedestrians. /// </summary> public static void AddTransfersDbForPedestrians(this TransitDb db, float maxTimeInSeconds) { db.AddTransfersDb(Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest(), maxTimeInSeconds); }
public void TestOneHop() { // build dummy db. var db = new TransitDb(); db.AddStop(0, 0, db.StopAttributes.Add(new Attributes.Attribute("name", "stop1"))); db.AddStop(1, 1, db.StopAttributes.Add(new Attributes.Attribute("name", "stop2"))); db.AddTrip(0, 0, db.TripAttributes.Add(new Attributes.Attribute("name", "trip1"))); db.AddConnection(0, 1, 0, 3600, 3600 + 40 * 60); db.SortConnections(DefaultSorting.DepartureTime, null); var router = new TransitRouter(db, Itinero.Osm.Vehicles.Vehicle.Pedestrian.Fastest()); var result = router.TryEarliestArrival(new DateTime(2017, 05, 10, 00, 50, 00), 0, 1, (i) => true); var route = result.Value; Assert.IsNotNull(route); Assert.IsNotNull(route.Shape); Assert.AreEqual(3, route.Shape.Length); Assert.AreEqual(0, route.Shape[0].Latitude); Assert.AreEqual(0, route.Shape[0].Longitude); Assert.AreEqual(0, route.Shape[1].Latitude); Assert.AreEqual(0, route.Shape[1].Longitude); Assert.AreEqual(1, route.Shape[2].Latitude); Assert.AreEqual(1, route.Shape[2].Longitude); Assert.IsNotNull(route.Stops); Assert.AreEqual(3, route.Stops.Length); var stop = route.Stops[0]; Assert.IsNotNull(stop.Attributes); Assert.AreEqual(1, stop.Attributes.Count); Assert.IsTrue(stop.Attributes.Contains("name", "stop1")); Assert.AreEqual(0, stop.Shape); Assert.AreEqual(0, stop.Coordinate.Latitude); Assert.AreEqual(0, stop.Coordinate.Longitude); stop = route.Stops[1]; Assert.IsNotNull(stop.Attributes); Assert.AreEqual(1, stop.Attributes.Count); Assert.IsTrue(stop.Attributes.Contains("name", "stop1")); Assert.AreEqual(1, stop.Shape); Assert.AreEqual(0, stop.Coordinate.Latitude); Assert.AreEqual(0, stop.Coordinate.Longitude); stop = route.Stops[2]; Assert.IsNotNull(stop.Attributes); Assert.AreEqual(1, stop.Attributes.Count); Assert.IsTrue(stop.Attributes.Contains("name", "stop2")); Assert.AreEqual(2, stop.Shape); Assert.AreEqual(1, stop.Coordinate.Latitude); Assert.AreEqual(1, stop.Coordinate.Longitude); Assert.IsNotNull(route.ShapeMeta); Assert.AreEqual(3, route.ShapeMeta.Length); var meta = route.ShapeMeta[0]; Assert.AreEqual(0, meta.Shape); Assert.IsNotNull(meta.Attributes); Assert.IsTrue(meta.Attributes.Contains(Itinero.Transit.Constants.TimeOfDayKey, "3000")); meta = route.ShapeMeta[1]; Assert.AreEqual(1, meta.Shape); Assert.IsNotNull(meta.Attributes); Assert.IsTrue(meta.Attributes.Contains(Itinero.Transit.Constants.TimeOfDayKey, "3600")); Assert.IsTrue(meta.Attributes.Contains("time", "600")); meta = route.ShapeMeta[2]; Assert.AreEqual(2, meta.Shape); Assert.IsNotNull(meta.Attributes); Assert.IsTrue(meta.Attributes.Contains(Itinero.Transit.Constants.TimeOfDayKey, "6000")); Assert.IsTrue(meta.Attributes.Contains("time", "3000")); Assert.AreEqual(3000, route.TotalTime); }
/// <summary> /// Loads data from a gtfs feed. /// </summary> public static void LoadFrom(this TransitDb db, IGTFSFeed feed) { if (db.StopsCount > 0 || db.TripsCount > 0) { // the database is not empty, cannot load this new GTFS-feed. throw new InvalidOperationException("Cannot load a GTFS-feed into a non-empty transit db."); } // load agencies. var agenciesIndex = new Dictionary <string, uint>(); for (var i = 0; i < feed.Agencies.Count; i++) { var agency = feed.Agencies.Get(i); agenciesIndex[agency.Id.ToStringEmptyWhenNull()] = db.AddAgency(agency); } // load schedules. var calendarTag = 1; var schedulesIndex = new Dictionary <string, uint>(); var calendarDates = new List <CalendarDate>(feed.CalendarDates); foreach (var calendar in feed.Calendars) { for (var day = calendar.StartDate; day <= calendar.EndDate; day = day.AddDays(1)) { if (calendar.CoversDate(day)) { calendarDates.Add(new CalendarDate() { Date = day, ExceptionType = global::GTFS.Entities.Enumerations.ExceptionType.Added, ServiceId = calendar.ServiceId, Tag = calendarTag }); } } } calendarDates.Sort((x, y) => { var c = x.ServiceId.CompareTo(y.ServiceId); if (c == 0) { return(x.Date.CompareTo(y.Date)); } return(c); }); // merge/remove dates. for (var i = 0; i < calendarDates.Count - 1; i++) { if (calendarDates[i].ServiceId == calendarDates[i + 1].ServiceId && calendarDates[i].Date == calendarDates[i + 1].Date) { if (calendarDates[i].ExceptionType == calendarDates[i + 1].ExceptionType) { calendarDates.RemoveAt(i + 1); } else if (calendarDates[i].Tag == null && calendarDates[i + 1].Tag != null) { calendarDates.RemoveAt(i + 1); } else if (calendarDates[i].Tag != null && calendarDates[i + 1].Tag == null) { calendarDates.RemoveAt(i); i--; } } } // convert to calendar objects again. var currentServiceId = string.Empty; var currentCalendars = new List <Calendar>(); var scheduleIds = new Dictionary <string, uint>(); for (var i = 0; i < calendarDates.Count; i++) { var current = calendarDates[i]; if (currentServiceId != current.ServiceId) { // start new calendars. if (currentCalendars.Count > 0) { // add previous calendars. currentCalendars[currentCalendars.Count - 1].TrimEndDate(); var newScheduleId = db.AddCalendars(currentCalendars); scheduleIds.Add(currentServiceId, newScheduleId); currentCalendars.Clear(); } // start working on the next one. currentServiceId = current.ServiceId; if (current.ExceptionType == global::GTFS.Entities.Enumerations.ExceptionType.Added) { // ok, use this as the first new date. var calendarForCurrent = current.Date.CreateCalendar( current.ServiceId); calendarForCurrent.ExpandWeek(); calendarForCurrent.TrimStartDate(); currentCalendars.Add(calendarForCurrent); } else { // not Add so don't create a week yet, go for the next one. currentServiceId = string.Empty; } } else { // add to existing calendars. var existing = currentCalendars[currentCalendars.Count - 1]; if (existing.EndDate >= current.Date) { // should be part of the last calendar. existing.Set(current.Date, current.ExceptionType == global::GTFS.Entities.Enumerations.ExceptionType.Added); } else if (current.ExceptionType == global::GTFS.Entities.Enumerations.ExceptionType.Added) { // add new calendar. var calendarForCurrent = current.Date.CreateCalendar( current.ServiceId); calendarForCurrent.ExpandWeek(); calendarForCurrent.TrimStartDate(); currentCalendars.Add(calendarForCurrent); } } } if (currentCalendars.Count > 0) { // add last calendars. currentCalendars[currentCalendars.Count - 1].TrimEndDate(); var newScheduleId = db.AddCalendars(currentCalendars); scheduleIds.Add(currentServiceId, newScheduleId); } // load routes. var routes = new Dictionary <string, global::GTFS.Entities.Route>(); for (var i = 0; i < feed.Routes.Count; i++) { var route = feed.Routes.Get(i); routes[route.Id] = route; } // load trips. var tripsIndex = new Dictionary <string, uint>(); var tripServiceIds = new Dictionary <string, string>(); for (var i = 0; i < feed.Trips.Count; i++) { var trip = feed.Trips.Get(i); tripServiceIds[trip.Id] = trip.ServiceId; var route = feed.Routes.Get(trip.RouteId); uint agencyId, scheduleId; global::GTFS.Entities.Route gtfsRoute; if (agenciesIndex.TryGetValue(route.AgencyId.ToStringEmptyWhenNull(), out agencyId) && scheduleIds.TryGetValue(trip.ServiceId, out scheduleId) && routes.TryGetValue(trip.RouteId, out gtfsRoute)) { tripsIndex[trip.Id] = db.AddTrip(trip, gtfsRoute, agencyId, scheduleId); } } // load stops. var stopsReverseIndex = new Extensions.LinkedListNode <string> [feed.Stops.Count]; var stopsIndex = new Dictionary <string, uint>(); for (var i = 0; i < feed.Stops.Count; i++) { var stop = feed.Stops.Get(i); if (string.IsNullOrWhiteSpace(stop.ParentStation)) { // only add stops that have no parent station. var stopId = db.AddStop(stop); stopsReverseIndex[stopId] = new Extensions.LinkedListNode <string>(stop.Id); stopsIndex[stop.Id] = stopId; } } for (var i = 0; i < feed.Stops.Count; i++) { var stop = feed.Stops.Get(i); if (!string.IsNullOrWhiteSpace(stop.ParentStation)) { // now add the stops that have parent stations. uint stopId; if (!stopsIndex.TryGetValue(stop.ParentStation, out stopId)) { // oeps, parent station not found. throw new Exception("A station was found with a parent station that has a parent station of it's own. Only one level of station hierarchy is supported."); } var node = stopsReverseIndex[stopId]; while (node.Next != null) { node = node.Next; } node.Next = new Extensions.LinkedListNode <string>(stop.Id); } } // sort stops. db.SortStops((i, j) => { var temp = stopsReverseIndex[i]; stopsReverseIndex[i] = stopsReverseIndex[j]; stopsReverseIndex[j] = temp; }); // re-index stops. for (uint i = 0; i < stopsReverseIndex.Length; i++) { var node = stopsReverseIndex[i]; while (node != null) { stopsIndex[node.Value] = i; node = node.Next; } } // index the shapes. var shapeIndex = new Dictionary <string, ShapePoint[]>(); if (feed.Shapes != null) { var originalShapeIndex = new Dictionary <string, List <Shape> >(); List <Shape> shape = null; foreach (var shapePoint in feed.Shapes) { if (!originalShapeIndex.TryGetValue(shapePoint.Id, out shape)) { shape = new List <Shape>(); originalShapeIndex.Add(shapePoint.Id, shape); } shape.Add(shapePoint); } foreach (var pair in originalShapeIndex) { pair.Value.Sort((x, y) => { if (x.Id == y.Id) { return(x.Sequence.CompareTo(y.Sequence)); } return(x.Id.CompareTo(y.Id)); }); var shapePoints = new ShapePoint[pair.Value.Count]; for (var i = 0; i < shapePoints.Length; i++) { float distanceTravelled = 0; if (pair.Value[i].DistanceTravelled.HasValue) { distanceTravelled = (float)pair.Value[i].DistanceTravelled.Value; } else { if (i > 0) { distanceTravelled = Coordinate.DistanceEstimateInMeter( (float)pair.Value[i].Latitude, (float)pair.Value[i].Longitude, shapePoints[i - 1].Latitude, shapePoints[i - 1].Longitude) + shapePoints[i - 1].DistanceTravelled; } } shapePoints[i] = new ShapePoint() { Latitude = (float)pair.Value[i].Latitude, Longitude = (float)pair.Value[i].Longitude, DistanceTravelled = distanceTravelled }; } shapeIndex[pair.Key] = shapePoints; } } // load connections. var stopTimes = new List <StopTime>(feed.StopTimes); stopTimes.Sort((x, y) => { var c = x.TripId.CompareTo(y.TripId); if (c == 0) { return(x.StopSequence.CompareTo(y.StopSequence)); } return(c); }); var currentTripId = string.Empty; var currentShapeId = string.Empty; uint collisionOffset = 1; for (var i = 0; i < stopTimes.Count; i++) { var stopTime = stopTimes[i]; var stopTimeServiceId = string.Empty; uint tripId; if (tripServiceIds.TryGetValue(stopTime.TripId, out stopTimeServiceId) && tripsIndex.TryGetValue(stopTime.TripId, out tripId)) { if (currentTripId != stopTime.TripId) { // start a new sequence. currentTripId = stopTime.TripId; var trip = feed.Trips.Get(currentTripId); currentShapeId = trip.ShapeId; collisionOffset = 1; } else { // the previous stop time has the same id, add them as a connection. var previousStopTime = stopTimes[i - 1]; uint stop1, stop2; if (stopsIndex.TryGetValue(previousStopTime.StopId, out stop1) && stopsIndex.TryGetValue(stopTime.StopId, out stop2)) { if (stopTime.ArrivalTime.TotalSeconds - previousStopTime.DepartureTime.TotalSeconds < collisionOffset) { // make sure arrival and departure time differ at least one second. db.AddConnection(stop1, stop2, tripId, (uint)previousStopTime.DepartureTime.TotalSeconds + (collisionOffset - 1), (uint)stopTime.ArrivalTime.TotalSeconds + collisionOffset); collisionOffset++; } else if (collisionOffset > 1) { // the previous time was offsetted, also offset this departure time. db.AddConnection(stop1, stop2, tripId, (uint)previousStopTime.DepartureTime.TotalSeconds + (collisionOffset - 1), (uint)stopTime.ArrivalTime.TotalSeconds); collisionOffset = 1; } else { // arrival and departure time differ already. db.AddConnection(stop1, stop2, tripId, (uint)previousStopTime.DepartureTime.TotalSeconds, (uint)stopTime.ArrivalTime.TotalSeconds); collisionOffset = 1; } if (previousStopTime.ShapeDistTravelled.HasValue && stopTime.ShapeDistTravelled.HasValue) { var shape = db.ShapesDb.Get(stop1, stop2); if (shape == null) { ShapePoint[] shapePoints = null; if (shapeIndex.TryGetValue(currentShapeId, out shapePoints)) { var shapeBetweenStops = ShapePoint.ExtractShape( shapePoints, (float)previousStopTime.ShapeDistTravelled.Value, (float)stopTime.ShapeDistTravelled.Value); db.ShapesDb.Add(stop1, stop2, new Graphs.Geometric.Shapes.ShapeEnumerable(shapeBetweenStops)); } } } } } } } }