diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-12-29 00:41:52 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-12-29 00:41:52 +0100 |
| commit | a304c24b32c0327436bbd8c2853e60668e161b42 (patch) | |
| tree | 08f65c05daca134cf4d2e4f779bd15d98fd66370 /src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs | |
| parent | 120a3c6bddd0fb8d9fa05df4763596956554c025 (diff) | |
Rename a lot of stuff, add Santiago real time
Diffstat (limited to 'src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs')
14 files changed, 411 insertions, 0 deletions
diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs new file mode 100644 index 0000000..6a41d1a --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs @@ -0,0 +1,7 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum DirectionId +{ + Outbound = 0, + Inbound = 1 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs new file mode 100644 index 0000000..02ab612 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs @@ -0,0 +1,7 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum ExceptionType +{ + Added = 1, + Removed = 2 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/RouteType.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/RouteType.cs new file mode 100644 index 0000000..e487c32 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/RouteType.cs @@ -0,0 +1,15 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum RouteType +{ + Tram = 0, + Subway = 1, + Rail = 2, + Bus = 3, + Ferry = 4, + CableTram = 5, + AerialLift = 6, + Funicular = 7, + Trolleybus = 11, + Monorail = 12 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs new file mode 100644 index 0000000..346b93a --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs @@ -0,0 +1,8 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum TripBikesAllowed +{ + Empty = 0, + CanAccommodate = 1, + NotAllowed = 2 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs new file mode 100644 index 0000000..6bcdb22 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs @@ -0,0 +1,8 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum TripWheelchairAccessible +{ + Empty = 0, + CanAccommodate = 1, + NotAccessible = 2 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs new file mode 100644 index 0000000..d62f60e --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs @@ -0,0 +1,8 @@ +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; + +public enum WheelchairBoarding +{ + Unknown = 0, + SomeVehicles = 1, + NotPossible = 2 +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Feed.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Feed.cs new file mode 100644 index 0000000..db9b283 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/Feed.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("feeds")] +public class Feed +{ + /// <summary> + /// Auto-incrementing ID value for each feed, to identify it and its version + /// </summary> + [Key] + public int Id { get; set; } + + [MaxLength(32)] public string ShortName { get; set; } + [MaxLength(32)] public string LongName { get; set; } + [MaxLength(255)] public string DownloadUrl { get; set; } + [MaxLength(32)] public string Etag { get; set; } + + public DateTime InsertedAt { get; set; } +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsAgency.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsAgency.cs new file mode 100644 index 0000000..8ce129c --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsAgency.cs @@ -0,0 +1,46 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_agencies")] +[PrimaryKey(nameof(Id), nameof(FeedId))] +public class GtfsAgency +{ + [Key] + [Column("agency_id")] + [MaxLength(255)] + public required string Id { get; set; } + + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("agency_name")] + [MaxLength(255)] + public string Name { get; set; } = string.Empty; + + [Column("agency_url")] + [MaxLength(255)] + public string Url { get; set; } = string.Empty; + + [Column("agency_timezone")] + [MaxLength(50)] + public string Timezone { get; set; } = string.Empty; + + [Column("agency_lang")] + [MaxLength(5)] + public string Language { get; set; } = string.Empty; + + [Column("agency_phone")] + [MaxLength(30)] + public string? Phone { get; set; } = string.Empty; + + [Column("agency_email")] + [MaxLength(255)] + public string? Email { get; set; } = string.Empty; + + [Column("agency_fare_url")] + [MaxLength(255)] + public string? FareUrl { get; set; } = string.Empty; +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendar.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendar.cs new file mode 100644 index 0000000..bcc7c39 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendar.cs @@ -0,0 +1,45 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_calendar")] +[PrimaryKey(nameof(ServiceId), nameof(FeedId))] +public class GtfsCalendar +{ + [Key] + [Column("service_id")] + [MaxLength(32)] + public string ServiceId { get; set; } = null!; + + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("monday")] + public bool Monday { get; set; } + + [Column("tuesday")] + public bool Tuesday { get; set; } + + [Column("wednesday")] + public bool Wednesday { get; set; } + + [Column("thursday")] + public bool Thursday { get; set; } + + [Column("friday")] + public bool Friday { get; set; } + + [Column("saturday")] + public bool Saturday { get; set; } + + [Column("sunday")] + public bool Sunday { get; set; } + + [Column("start_date")] + public DateOnly StartDate { get; set; } + + [Column("end_date")] + public DateOnly EndDate { get; set; } +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs new file mode 100644 index 0000000..e9b5a92 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_calendar_dates")] +[PrimaryKey(nameof(ServiceId), nameof(Date), nameof(FeedId))] +public class GtfsCalendarDate +{ + [Column("service_id")] + [MaxLength(32)] + public required string ServiceId { get; set; } + + [Column("date")] + public required DateTime Date { get; set; } + + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("exception_type")] + public required ExceptionType ExceptionType { get; set; } +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsRoute.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsRoute.cs new file mode 100644 index 0000000..80ef38a --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsRoute.cs @@ -0,0 +1,70 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_routes")] +[PrimaryKey(nameof(Id), nameof(FeedId))] +public class GtfsRoute +{ + [Column("route_id")] + [MaxLength(255)] + public required string Id { get; set; } + + public string SafeId => Id.Replace(" ", "_").Replace("-", "_"); + + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("agency_id")] + [ForeignKey(nameof(Agency))] + [MaxLength(255)] + public required string AgencyId { get; set; } + + [ForeignKey(nameof(AgencyId))] + public GtfsAgency Agency { get; set; } = null!; + + /// <summary> + /// Short name of a route. Often a short, abstract identifier (e.g., "32", "100X", "Green") + /// that riders use to identify a route. Both route_short_name and route_long_name may be defined. + /// </summary> + [Column("route_short_name")] + [MaxLength(32)] + public string ShortName { get; set; } = string.Empty; + + /// <summary> + /// Full name of a route. This name is generally more descriptive than the route_short_name and often + /// includes the route's destination or stop. Both route_short_name and route_long_name may be defined. + /// </summary> + [Column("route_long_name")] + [MaxLength(255)] + public string LongName { get; set; } = string.Empty; + + [Column("route_desc")] + [MaxLength(255)] + public string? Description { get; set; } = string.Empty; + + [Column("route_type")] + public RouteType Type { get; set; } = RouteType.Bus; + + [Column("route_url")] + [MaxLength(255)] + public string? Url { get; set; } = string.Empty; + + [Column("route_color")] + [MaxLength(7)] + public string? Color { get; set; } = string.Empty; + + [Column("route_text_color")] + [MaxLength(7)] + public string? TextColor { get; set; } = string.Empty; + + /// <summary> + /// Orders the routes in a way which is ideal for presentation to customers. + /// Routes with smaller route_sort_order values should be displayed first. + /// </summary> + [Column("route_sort_order")] + public int SortOrder { get; set; } = 1; +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStop.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStop.cs new file mode 100644 index 0000000..6198ffa --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStop.cs @@ -0,0 +1,51 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; +using NetTopologySuite.Geometries; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_stops")] +[PrimaryKey(nameof(Id), nameof(FeedId))] +public class GtfsStop +{ + [Column("stop_id")] + [MaxLength(32)] + public required string Id { get; set; } + + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("stop_code")] + [MaxLength(32)] + public string Code { get; set; } = string.Empty; + + [Column("stop_name")] + [MaxLength(255)] + public string Name { get; set; } = string.Empty; + + [Column("stop_desc")] + [MaxLength(255)] + public string? Description { get; set; } + + [Column("stop_pos")] + public Point? Position { get; set; } + + [Column("stop_url")] + [MaxLength(255)] + public string? Url { get; set; } + + [Column("stop_timezone")] + [MaxLength(50)] + public string? Timezone { get; set; } + + [Column("wheelchair_boarding")] + public WheelchairBoarding WheelchairBoarding { get; set; } = WheelchairBoarding.Unknown; + + // [Column("location_type")] + // public int LocationType { get; set; } + // + // [Column("parent_station")] + // public int? ParentStationId { get; set; } +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStopTime.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStopTime.cs new file mode 100644 index 0000000..2bed623 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsStopTime.cs @@ -0,0 +1,44 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Enmarcha.Experimental.ServiceViewer.Data.Extensions; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_stop_times")] +[PrimaryKey(nameof(TripId), nameof(StopSequence), nameof(FeedId))] +public class GtfsStopTime +{ + [Column("trip_id")] + [ForeignKey("TripId")] + [MaxLength(32)] + public string TripId { get; set; } = null!; + + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [ForeignKey(nameof(TripId))] public GtfsTrip GtfsTrip { get; set; } = null!; + + [Column("arrival_time")] public string Arrival { get; set; } + public TimeSpan ArrivalTime => TimeSpan.FromGtfsTime(Arrival); + + [Column("departure_time")] public string Departure { get; set; } + public TimeSpan DepartureTime => TimeSpan.FromGtfsTime(Departure); + + [Column("stop_id")] + [ForeignKey(nameof(GtfsStop))] + [MaxLength(32)] + public required string StopId { get; set; } + + [ForeignKey(nameof(StopId))] public GtfsStop GtfsStop { get; set; } = null!; + + [Column("stop_sequence")] public int StopSequence { get; set; } = 0; + + // [Column("pickup_type")] + // public int? PickupType { get; set; } + // + // [Column("drop_off_type")] + // public int? DropOffType { get; set; } + + [Column("shape_dist_traveled")] public double? ShapeDistTraveled { get; set; } = null!; +} diff --git a/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsTrip.cs b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsTrip.cs new file mode 100644 index 0000000..8dd5271 --- /dev/null +++ b/src/Enmarcha.Experimental.ServiceViewer/Data/Gtfs/GtfsTrip.cs @@ -0,0 +1,57 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Enmarcha.Experimental.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; + +namespace Enmarcha.Experimental.ServiceViewer.Data.Gtfs; + +[Table("gtfs_trips")] +[PrimaryKey(nameof(Id), nameof(FeedId))] +public class GtfsTrip +{ + [Column("trip_id")] [MaxLength(32)] public string Id { get; set; } = null!; + + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + + [Column("route_id")] + [MaxLength(32)] + [ForeignKey(nameof(Route))] + public string RouteId { get; set; } = null!; + + [ForeignKey(nameof(RouteId))] public GtfsRoute Route { get; set; } = null!; + + [Column("service_id")] [MaxLength(32)] public string ServiceId { get; set; } = null!; + + [Column("trip_headsign")] + [MaxLength(255)] + public string? TripHeadsign { get; set; } + + [Column("trip_short_name")] + [MaxLength(255)] + public string? TripShortName { get; set; } + + [Column("direction_id")] public DirectionId DirectionId { get; set; } = DirectionId.Outbound; + + /// <summary> + /// Identifies the block to which the trip belongs. A block consists of a single trip or many + /// sequential trips made using the same vehicle, defined by shared service days and block_id. + /// A block_id may have trips with different service days, making distinct blocks. + /// </summary> + [Column("block_id")] + [MaxLength(32)] + public string? BlockId { get; set; } + + /// <summary> + /// Identifies a geospatial shape describing the vehicle travel path for a trip. + /// </summary> + /// <remarks>To be implemented: will be stored as a GeoJSON file instead of database records.</remarks> + [Column("shape_id")] + [MaxLength(32)] + public string? ShapeId { get; set; } + + [Column("trip_wheelchair_accessible")] + public TripWheelchairAccessible TripWheelchairAccessible { get; set; } = TripWheelchairAccessible.Empty; + + [Column("trip_bikes_allowed")] public TripBikesAllowed TripBikesAllowed { get; set; } = TripBikesAllowed.Empty; +} |
