Skip to content

Commit

Permalink
Handle vehicle GTFS entities
Browse files Browse the repository at this point in the history
  • Loading branch information
cedarbaum committed Aug 5, 2023
1 parent e5588db commit be91e30
Show file tree
Hide file tree
Showing 39 changed files with 5,008 additions and 1,207 deletions.
6 changes: 6 additions & 0 deletions api/admin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ message GtfsRealtimeOptions {
// This should not be used for systems where a trip can call at the same
// stop multiple times.
bool reassign_stop_sequences = 4;

// If true, only process entities in a feed if the message contains
// the full entity. This is useful for cases where there are multiple
// feeds for the same system, and some feeds contain only partial
// information about entities.
bool only_process_full_entities = 5;
}

// Description of the configuration for a collection of service maps.
Expand Down
157 changes: 157 additions & 0 deletions api/public.proto
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,28 @@ service Public {
};
}

// List vehicles
//
// `GET /systems/<system_id>/vehicles`
//
// List all feeds for a system.
rpc ListVehicles(ListVehiclesRequest) returns (ListVehiclesReply) {
option (google.api.http) = {
get: "/systems/{system_id}/vehicles"
};
}

// Get vehicle
//
// `GET /systems/<system_id>/vehicles/<vehicle_id>`
//
// Get a vehicle in a system by its ID.
rpc GetVehicle(GetVehicleRequest) returns (Vehicle) {
option (google.api.http) = {
get: "/systems/{system_id}/vehicles/{vehicle_id}"
};
}

}

// Request payload for the entrypoint endpoint.
Expand Down Expand Up @@ -566,6 +588,67 @@ message ListTransfersReply {
repeated Transfer transfers = 1;
}

message ListVehiclesRequest {
// ID of the system for which to list vehicles.
string system_id = 1;

enum SearchMode {
// Return a paginated list of vehicles sorted by vehicle ID.
ID = 0;
// Return all vehicles within max_distance of (latitude, longitude), sorted by the distance.
DISTANCE = 1;
}
// The type of search to perform when listing vehicles.
optional SearchMode search_mode = 2;

// If true, only return vehicles whose IDs are specified in the repeated `id` field.
// Only supported when the search mode is ID.
bool only_return_specified_ids = 3;

// IDs to return if `only_return_specified_ids` is set to true. It is an error to
// populate this field if `only_return_specified_ids` is false.
// Only supported when the search mode is ID.
repeated string id = 4;

// ID of the first vehicle to return. If not set, the vehicle with the smallest ID will be first.
// Only supported when the search mode is ID.
optional string first_id = 5;

// Maximum number of vehicles to return.
// This is supported in all search modes.
// For performance reasons, if it is larger than 100 it is rounded down to 100.
optional int32 limit = 6;

// The maximum distance in kilometers that a vehicle must be from
// latitude, longitude to be listed when using DISTANCE search mode.
optional double max_distance = 7;

// The latitude relative to the returned vehicles when using DISTANCE search mode.
optional double latitude = 8;

// The longitude relative to the returned vehicles when using DISTANCE search mode.
optional double longitude = 9;
}

message ListVehiclesReply {
// List of vehicles.
repeated Vehicle vehicles = 1;

// ID of the next vehicle to return, if there are more results.
optional string next_id = 2;
}

message GetVehicleRequest {
// ID of the system the vehicle is in.
//
// This is a URL parameter in the HTTP API.
string system_id = 1;
// ID of the vehicle.
//
// This is a URL parameter in the HTTP API.
string vehicle_id = 2;
}

// The System resource.
message System {
// ID of the system as specified in the install request.
Expand Down Expand Up @@ -794,10 +877,84 @@ message Trip {
}
}

// The Vehicle resource.
//
// This resource corresponds to the [vehicle position type in the GTFS static
// specification](https://developers.google.com/transit/gtfs-realtime/reference#message-vehicleposition).
message Vehicle {
// A unique ID for the vehicle.
string id = 1;

// A reference to the vehicle's trip.
optional Trip.Reference trip = 2;

// The vehicle's current latitude.
optional double latitude = 3;

// The vehicle's current longitude.
optional double longitude = 4;

// The vehicle's current bearing.
optional float bearing = 5;

// The vehicle's current odometer reading.
optional double odometer = 6;

// The vehicle's current speed.
optional float speed = 7;

// The stop sequence index of the vehicle's current stop.
optional int32 stop_sequence = 8;

// A reference to the vehicle's current stop.
optional Stop.Reference stop = 9;

// Corresponds to [VehicleStopStatus](https://developers.google.com/
// transit/gtfs-realtime/reference#enum-vehiclestopstatus).
enum CurrentStatus {
INCOMING_AT = 0;
STOPPED_AT = 1;
IN_TRANSIT_TO = 2;
}
// The vehicle's current status.
optional CurrentStatus current_status = 10;

// The timestamp of the last update to the vehicle's position.
optional int64 updated_at = 11;

// Corresponds to [CongestionLevel](https://developers.google.com/
// transit/gtfs-realtime/reference#enum-congestionlevel).
enum CongestionLevel {
UNKNOWN_CONGESTION_LEVEL = 0;
RUNNING_SMOOTHLY = 1;
STOP_AND_GO = 2;
CONGESTION = 3;
SEVERE_CONGESTION = 4;
}
// The vehicle's current congestion level.
CongestionLevel congestion_level = 12;

// Corresponds to [OccupancyStatus](https://developers.google.com/
// transit/gtfs-realtime/reference#enum-occupancystatus).
enum OccupancyStatus {
EMPTY = 0;
MANY_SEATS_AVAILABLE = 1;
FEW_SEATS_AVAILABLE = 2;
STANDING_ROOM_ONLY = 3;
CRUSHED_STANDING_ROOM_ONLY = 4;
FULL = 5;
NOT_ACCEPTING_PASSENGERS = 6;
}
// The vehicle's current occupancy status.
optional OccupancyStatus occupancy_status = 13;

// The percentage of seats occupied.
optional int32 occupancy_percentage = 14;

// Reference is the reference type for the vehicle resource.
message Reference {
string id = 1;
Resource resource = 2;
}
}

Expand Down
50 changes: 28 additions & 22 deletions db/queries/stop_queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ UPDATE stop SET
code = sqlc.arg(code),
description = sqlc.arg(description),
platform_code = sqlc.arg(platform_code),
timezone = sqlc.arg(timezone),
type = sqlc.arg(type),
timezone = sqlc.arg(timezone),
type = sqlc.arg(type),
wheelchair_boarding = sqlc.arg(wheelchair_boarding),
zone_id = sqlc.arg(zone_id),
parent_stop_pk = NULL
Expand All @@ -35,7 +35,7 @@ WHERE

-- name: DeleteStaleStops :exec
DELETE FROM stop
WHERE
WHERE
stop.feed_pk = sqlc.arg(feed_pk)
AND NOT stop.pk = ANY(sqlc.arg(updated_stop_pks)::bigint[]);

Expand All @@ -52,7 +52,7 @@ LIMIT sqlc.arg(num_stops);

-- name: ListStops_Geographic :many
WITH distance AS (
SELECT
SELECT
pk stop_pk,
(6371 * acos(cos(radians(latitude)) * cos(radians(sqlc.arg(latitude)::numeric)) * cos(radians(sqlc.arg(longitude)::numeric) - radians(longitude)) + sin(radians(latitude)) * sin(radians(sqlc.arg(latitude)::numeric)))) val
FROM stop
Expand All @@ -71,7 +71,13 @@ SELECT stop.* FROM stop
AND stop.id = sqlc.arg(stop_id);

-- name: ListTripStopTimesByStops :many
SELECT trip_stop_time.*, trip.*, vehicle.id vehicle_id FROM trip_stop_time
SELECT trip_stop_time.*,
trip.*, vehicle.id vehicle_id,
vehicle.latitude vehicle_latitude,
vehicle.longitude vehicle_longitude,
vehicle.bearing vehicle_bearing,
vehicle.updated_at vehicle_updated_at
FROM trip_stop_time
INNER JOIN trip ON trip_stop_time.trip_pk = trip.pk
LEFT JOIN vehicle ON vehicle.trip_pk = trip.pk
WHERE trip_stop_time.stop_pk = ANY(sqlc.arg(stop_pks)::bigint[])
Expand All @@ -90,29 +96,29 @@ FROM stop
WHERE stop.parent_stop_pk = ANY(sqlc.arg(stop_pks)::bigint[]);

-- name: MapStopIDAndPkToStationPk :many
WITH RECURSIVE
WITH RECURSIVE
ancestor AS (
SELECT
id stop_id,
SELECT
id stop_id,
pk stop_pk,
pk station_pk,
pk station_pk,
parent_stop_pk,
(type = 'STATION') is_station
(type = 'STATION') is_station
FROM stop
WHERE stop.system_pk = sqlc.arg(system_pk)
AND (
NOT sqlc.arg(filter_by_stop_pk)::bool
OR stop.pk = ANY(sqlc.arg(stop_pks)::bigint[])
)
UNION
SELECT
UNION
SELECT
child.stop_id stop_id,
child.stop_pk stop_pk,
parent.pk station_pk,
parent.parent_stop_pk,
(parent.type = 'STATION') is_station
FROM stop parent
INNER JOIN ancestor child
parent.pk station_pk,
parent.parent_stop_pk,
(parent.type = 'STATION') is_station
FROM stop parent
INNER JOIN ancestor child
ON child.parent_stop_pk = parent.pk
AND NOT child.is_station
)
Expand All @@ -123,17 +129,17 @@ SELECT stop_id, stop_pk, station_pk

-- name: MapStopPkToDescendentPks :many
WITH RECURSIVE descendent AS (
SELECT
SELECT
stop.pk root_stop_pk,
stop.pk descendent_stop_pk
FROM stop
WHERE stop.pk = ANY(sqlc.arg(stop_pks)::bigint[])
UNION
SELECT
UNION
SELECT
descendent.root_stop_pk root_stop_pk,
child.pk descendent_stop_pk
FROM stop child
INNER JOIN descendent
FROM stop child
INNER JOIN descendent
ON child.parent_stop_pk = descendent.descendent_stop_pk
)
SELECT root_stop_pk, descendent_stop_pk FROM descendent;
Expand Down
37 changes: 33 additions & 4 deletions db/queries/trip_queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,33 @@ SELECT lss.trip_pk, stop.pk destination_pk
ON trip_stop_time.stop_pk = stop.pk;

-- name: ListTrips :many
SELECT * FROM trip
SELECT trip.*,
vehicle.id as vehicle_id,
vehicle.latitude as vehicle_latitude,
vehicle.longitude as vehicle_longitude,
vehicle.bearing as vehicle_bearing,
vehicle.updated_at as vehicle_updated_at
FROM trip
LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk
WHERE route_pk = ANY(sqlc.arg(route_pks)::bigint[])
ORDER BY route_pk, id;

-- name: ListTripPksInSystem :many
SELECT trip.id, trip.pk
FROM trip
INNER JOIN feed ON trip.feed_pk = feed.pk
WHERE trip.id = ANY(sqlc.arg(trip_ids)::text[])
AND feed.system_pk = sqlc.arg(system_pk);

-- name: GetTrip :one
SELECT * FROM trip
SELECT trip.*,
vehicle.id as vehicle_id,
vehicle.latitude as vehicle_latitude,
vehicle.longitude as vehicle_longitude,
vehicle.bearing as vehicle_bearing,
vehicle.updated_at as vehicle_updated_at
FROM trip
LEFT JOIN vehicle ON trip.pk = vehicle.trip_pk
WHERE trip.id = sqlc.arg(trip_id)
AND trip.route_pk = sqlc.arg(route_pk);

Expand All @@ -38,7 +59,7 @@ VALUES
RETURNING pk;

-- name: UpdateTrip :batchexec
UPDATE trip SET
UPDATE trip SET
feed_pk = sqlc.arg(feed_pk),
direction_id = sqlc.arg(direction_id),
started_at = sqlc.arg(started_at),
Expand Down Expand Up @@ -90,7 +111,15 @@ WHERE pk = ANY(sqlc.arg(pks)::bigint[]);

-- name: DeleteStaleTrips :many
DELETE FROM trip
WHERE
WHERE
trip.feed_pk = sqlc.arg(feed_pk)
AND NOT trip.pk = ANY(sqlc.arg(updated_trip_pks)::bigint[])
RETURNING trip.route_pk;

-- name: MapTripIDToPkInSystem :many
SELECT trip.id, trip.pk
FROM trip
INNER JOIN feed ON trip.feed_pk = feed.pk
WHERE trip.id = ANY(sqlc.arg(trip_ids)::text[])
AND feed.system_pk = sqlc.arg(system_pk)
FOR UPDATE;
Loading

0 comments on commit be91e30

Please sign in to comment.