Skip to main content

Public Transit Stops

Last updated: September 14, 2026 | 18 minutes read

This API provides access to public transport data including agencies, routes, stops, trips, service alerts, and live vehicle crowding. Fetch and explore real-time public transportation information from selected positions on the map.

Tip

The public transport data structure follows the General Transit Feed Specification (GTFS) and offers access to a subset of GTFS fields and entities.

Key features:

  • Query public transport overlays by screen position
  • Retrieve information about transport agencies, stops, routes, and trips
  • Access real-time data including delays and cancellations
  • View GTFS-RT service alerts (disruptions, detours, closures) scoped to stops and trips
  • Access live vehicle crowding and occupancy data for trips and routes
  • View metadata about accessibility, bike allowances, and platform details
  • Filter trips by route type, route short name, or agency
  • Narrow the requested departures server-side with a schedule filter
  • Retrieve and draw the geometry of the routes serving a stop

How it works:

  • Set a position on the map using setCursorScreenPosition
  • Query for public transport overlays with cursorSelectionOverlayItemsByType
  • Retrieve stop information using getPTStopInfo() on each overlay item, optionally passing a PTStopScheduleFilter
  • Use the returned PTStopInfo object to explore agencies, stops, trips, and route shapes

Query Public Transit Stops​

In order to query public transit stops, register a long-press listener on the map controller. When the user long-presses on the map, set the cursor position to that location and retrieve the public transit overlay items at that position.

controller.registerOnLongPress((pos) async {
// set cursor position on the screen
await controller.setCursorScreenPosition(pos);

// get the public transit overlay items at that position
final items = controller
.cursorSelectionOverlayItemsByType(CommonOverlayId.publicTransport);

// for each overlay item at that position
for (final OverlayItem item in items) {
// get the stop information
final ptStopInfo = await item.getPTStopInfo();
if (ptStopInfo != null) {
// information about agencies
final agencies = ptStopInfo.agencies;

// information about stops and generic routes
// (routes that don't have `heading` set)
final stops = ptStopInfo.stops;

// information about trips (together with
// route, agency, stop times, real-time info, etc.)
final trips = ptStopInfo.trips;

// How to use stops
for (final stop in stops) {
print('Stop id: ${stop.stopId}');
print('Stop name: ${stop.stopName}');

print('Routes:');
for (final route in stop.routes) {
print(' Route id: ${route.routeId}');
print(' Route short name: ${route.routeShortName}');
print(' Route long name: ${route.routeLongName}');
}
}
}
}});
Tip

You can also obtain PTStopInfo instances by performing an overlay search using CommonOverlayId.publicTransport. Retrieve the corresponding OverlayItems and use their getPTStopInfo method to access stop information.

See the Search on overlays guide for details.

danger

All returned times are local times represented as DateTime values in UTC (timezone offset 0). Use the TimezoneService to convert them to other time zones.

danger

Two types of public transit stops exist on the map:

  • OverlayItem stops selected via cursorSelectionOverlayItemsByType - provide extensive PTStopInfo details and display with a blue icon (default style)
  • Landmark stops selected via cursorSelectionLandmarks - provide limited details and display with a gray icon (default style)

Narrow the Request​

getPTStopInfo accepts an optional PTStopScheduleFilter that narrows the request before it is sent, so the server returns only the departures of interest instead of the full schedule.

final ptStopInfo = await item.getPTStopInfo(
filter: PTStopScheduleFilter(
lineNames: ['32', '100X'],
headings: ['Gare du Nord'],
maxRows: 20,
window: Duration(hours: 2),
),
);
PropertyTypeDescription
routeIdsList<int>Keep departures whose route id is in this set. Pass PTRouteInfo.routeId values through unmodified.
lineNamesList<String>Keep departures whose routeShortName is in this set. Empty string entries are invalid.
headingsList<String>Optional direction restriction for lineNames matches. Invalid when non-empty while lineNames is empty.
maxRowsintDepartures to return. 0 uses the server default.
windowDuration?Forward search horizon from time. null uses the server default. Serialized with second resolution; sub-second precision is ignored.
timeDateTime?Absolute time to search forward from. null means now.
shapesboolRequest the route shapes. See Route Shapes.

A departure is kept when its route id is in routeIds, or when its short name is in lineNames and (if headings is non-empty) its heading is in headings. routeIds and lineNames are OR'd, so both can be used in a single request. headings only refines lineNames matches; it never selects on its own and does not affect routeIds matches. String matching is exact and case-sensitive.

info

The filter narrows only the trips (departures) section. The line catalogue on PTStop.routes is always returned complete, so a filtered request still describes every line serving the stop.

info

maxRows and window are best-effort hints. The server clamps both to its configured caps. The search is forward-only, so departures before time are never returned.

warning

An inconsistent filter is rejected on the device, before any network request is sent. A filter is inconsistent when time is before the Unix epoch, when maxRows or window is negative, when lineNames or headings contains an empty string, or when headings is non-empty while lineNames is empty.

The rejection surfaces as GemError.invalidInput only through getPreviewExtendedData, which reports the error code. getPTStopInfo does not expose it: a rejected filter simply makes it complete with null, the same as any other failure.

An empty filter, or no filter at all, produces exactly the unfiltered request. Check PTStopScheduleFilter.isEmpty to detect that case.

Filter Trips​

Filter trips by route short name, route type, or agency using these PTStopInfo methods:

List<PTTrip> tripsByRouteShortName(String name)
List<PTTrip> tripsByRouteType(PTRouteType type)
List<PTTrip> tripsByAgency(PTAgency agency)

Example:

final trips = ptStopInfo.tripsByRouteType(PTRouteType.bus);

Agencies​

The PTAgency class represents a public transport agency.

PropertyTypeDescription
idintAgency ID
nameStringFull name of the transit agency.
urlString?Optional URL of the transit agency.

Public Transport Routes​

The PTRouteInfo class represents a public transport route.

PropertyTypeDescription
routeIdintRoute ID
routeShortNameString?Short name of a route. Often a short, abstract identifier (e.g., "32", "100X") that riders use to identify a route. May be null.
routeLongNameString?Full name of a route. This name is generally more descriptive than the short name and often includes the route's destination or stop.
routeTypePTRouteTypeType of route.
routeColorColor?Route color designation that matches public-facing material. May be used to color the route on the map or to be shown on UI elements.
routeTextColorColor?Legible color to use for text drawn against a background of routeColor.
headingString?Optional heading information.
liveCrowdingPTCrowdingInfo?Live crowding summary over the route's fresh vehicle positions. Null when the route has no fresh vehicle positions. See Live Crowding.
shapePTShape?Drawable geometry of the route. Null unless shapes were requested and the route has a drawable shape. See Route Shapes.
danger

PTRouteInfo provides information about public transit routes available at a specific stop. PTRoute represents a computed public transit route between multiple waypoints with detailed instructions.

See Compute Public Transit Routes for computing routes using PTRoute.

Route Types​

The PTRouteType enum represents the type of public transport route:

Enum CaseDescription
busBus, Trolleybus. Used for short and long-distance bus routes.
undergroundSubway, Metro. Any underground rail system within a metropolitan area.
railwayRail. Used for intercity or long-distance travel.
tramTram, Streetcar, Light rail. Any light rail or street level system within a metropolitan area.
waterTransportWater transport. Used for ferries and other water-based transit.
miscMiscellaneous. Includes other types of public transport not covered by the other categories.

Stops​

The PTStop class represents a public transport stop.

PropertyTypeDescription
stopIdintIdentifies a location: stop/platform, station, entrance/exit, node or boarding area
stopNameStringName of the location. Matches the agency's rider-facing name for the location as printed on a timetable, published online, or represented on signage.
isStationbool?Whether this location is a station or not. A station is considered a physical structure or area that contains one or more platforms.
routesList<PTRouteInfo>Associated routes for the stop. Contains all routes serving this stop, whether active at the given time or not.
alertsList<PTAlertInfo>GTFS-RT service alerts scoped to this stop (e.g., station closure, elevator outage). Empty when none apply. See Service Alerts.

Stop Times​

The PTStopTime class provides details about stop time in a PTTrip.

PropertyTypeDescription
stopNameStringThe name of the serviced stop.
coordinatesCoordinatesWGS latitude and longitude for the stop.
hasRealtimeboolWhether data is provided in real-time or not.
delayintDelay in seconds. Not available if hasRealtime is false.
departureTimeDateTime?Optional departure time in the local timezone.
isBeforeboolWhether the stop time is before the current time.
isWheelchairFriendlyboolWhether the stop is wheelchair accessible.

Trips​

The PTTrip class represents a public transport trip.

PropertyTypeDescription
routePTRouteInfoAssociated route
agencyPTAgencyAssociated agency
tripIndexintTrip index
tripDateDateTime?The date of the trip
departureTimeDateTime?Departure time of the trip from the first stop
hasRealtimeboolWhether real-time data is available
isCancelledbool?Whether the trip is cancelled
delayMinutesint?Delay in minutes. Not available if hasRealtime is false.
stopTimesList<PTStopTime>Details of stop times in the trip
stopIndexintStop index
stopPlatformCodeString?Platform code for the stop. May be null.
isWheelchairAccessibleboolWhether the trip is wheelchair accessible.
isBikeAllowedboolWhether bikes are allowed on the trip.
alertsList<PTAlertInfo>GTFS-RT service alerts applicable to this trip. Empty when none apply. See Service Alerts.
vehiclePTCrowdingInfo?Live crowding of the vehicle running this trip. Present when a fresh vehicle position reports exactly this trip instance, usually only the currently running vehicle. May be null.
departureOccupancyStatusPTOccupancyStatus?Predicted occupancy after departing this stop. May be null.
Tip

When both vehicle and departureOccupancyStatus are present, vehicle.occupancyStatus is the measured (live) value and departureOccupancyStatus is predicted. Prefer the live value for the currently running vehicle and the predicted value for upcoming departures.

danger

A PTAlertEffect.noService alert overlaps with isCancelled. The isCancelled flag remains the authoritative cancellation indicator; the alert supplies the user-facing reason.

danger

PTRouteInfo represents the public-facing service riders recognize (e.g., "Bus 42"). PTTrip is a single scheduled journey along that route at a specific time with its own stop times and sequence. The route is the line identity; trips are individual vehicle runs throughout the day.

Service Alerts​

The PTAlertInfo class represents a GTFS-RT service alert, such as a strike, detour, or station closure. Alerts are provided deduplicated in PTStopInfo.alerts and referenced by the trips (PTTrip.alerts) and stops (PTStop.alerts) they apply to. Those lists share the same PTAlertInfo instances.

PropertyTypeDescription
causePTAlertCauseThe cause of the alert.
effectPTAlertEffectThe effect of the alert.
activePeriodsList<PTAlertActivePeriod>Periods when the alert is active. An empty list means the alert is active for as long as the feed carries it.
urlsList<PTAlertTranslation>URL translations pointing to additional information. May be empty.
headerTextsList<PTAlertTranslation>Header text translations summarizing the alert. May be empty.
descriptionTextsList<PTAlertTranslation>Description text translations detailing the alert. May be empty.
severityLevelPTAlertSeverityLevel?The severity of the alert. Null when the feed supplies none.
causeDetailsList<PTAlertTranslation>Agency-specific cause wording translations. May be empty.
effectDetailsList<PTAlertTranslation>Agency-specific effect wording translations. May be empty.

To read a localized text field, use the per-field helpers, which return the text for a given language tag (e.g. en) or null when the corresponding list is empty:

String? urlFor(String language)
String? headerTextFor(String language)
String? descriptionTextFor(String language)
String? causeDetailFor(String language)
String? effectDetailFor(String language)

These delegate to PTAlertInfo.selectTranslation, which returns the first translation matching the language tag, or the first entry as a fallback.

for (final alert in ptStopInfo.alerts) {
print('Cause: ${alert.cause}');
print('Effect: ${alert.effect}');
print('Severity: ${alert.severityLevel}');
print('Header: ${alert.headerTextFor('en')}');
print('Description: ${alert.descriptionTextFor('en')}');
}

// Alerts scoped to a specific trip or stop
final tripAlerts = trip.alerts;
final stopAlerts = stop.alerts;
danger

The translations (urls, headerTexts, descriptionTexts, causeDetails, effectDetails) are passed through verbatim from the GTFS-RT feed. The language tags may be inaccurate, since some feeds tag the same untranslated text under multiple languages. Treat them as hints and rely on the fallback behavior of selectTranslation.

danger

PTAlertInfo provides alerts for public transport data associated with stops. Do not confuse it with PTAlert, which represents an alert of a computed public transport route segment.

Alert Cause​

The PTAlertCause enum classifies the cause of an alert (GTFS-RT Cause). Values outside the GTFS-RT enum map to unknownCause.

Enum CaseDescription
unknownCauseUnknown cause.
otherCauseOther cause not represented by any other value.
technicalProblemTechnical problem.
strikeStrike.
demonstrationDemonstration.
accidentAccident.
holidayHoliday.
weatherWeather.
maintenanceMaintenance.
constructionConstruction.
policeActivityPolice activity.
medicalEmergencyMedical emergency.

Alert Effect​

The PTAlertEffect enum classifies the effect of an alert (GTFS-RT Effect). Values outside the GTFS-RT enum map to unknownEffect.

Enum CaseDescription
noServiceNo service. Overlaps with PTTrip.isCancelled; the trip flag remains the authoritative cancellation indicator.
reducedServiceReduced service.
significantDelaysSignificant delays.
detourDetour.
additionalServiceAdditional service.
modifiedServiceModified service.
otherEffectOther effect not represented by any other value.
unknownEffectUnknown effect.
stopMovedStop moved.
noEffectNo effect.
accessibilityIssueAccessibility issue.

Alert Severity​

The PTAlertSeverityLevel enum describes the severity of an alert (GTFS-RT SeverityLevel). Values outside the GTFS-RT enum map to unknown.

Enum CaseDescription
unknownUnknown severity.
infoInformation.
warningWarning.
severeSevere.

Active Period​

The PTAlertActivePeriod class represents a period when an alert is active. Both bounds are optional.

PropertyTypeDescription
startDateTime?UTC start of the period. Null means active since forever.
endDateTime?UTC end of the period. Null means open-ended.

Translation​

The PTAlertTranslation class represents a single translation of an alert text field.

PropertyTypeDescription
languageStringLanguage tag, verbatim from the feed. May be inaccurate.
textStringTranslation text.

Live Crowding​

The PTCrowdingInfo class exposes live vehicle crowding data derived from GTFS-RT vehicle positions. It appears in two places:

  • PTTrip.vehicle — the measured values reported by the vehicle running exactly that trip instance. vehicles is always null here.
  • PTRouteInfo.liveCrowding — a summary over all the route's fresh vehicle positions. vehicles counts them and the other fields carry the worst value over those vehicles.
PropertyTypeDescription
vehiclesint?Number of fresh vehicle positions on the route. Only provided by PTRouteInfo.liveCrowding; always null for PTTrip.vehicle.
congestionLevelPTCongestionLevel?Congestion level of the traffic the vehicle(s) travel in. May be null.
occupancyStatusPTOccupancyStatus?Occupancy status of the vehicle(s). May be null.
occupancyPercentageint?Occupancy as a percentage of the vehicle capacity. May exceed 100 per the GTFS-RT specification. May be null.
// Live crowding of the vehicle running a trip
final vehicle = trip.vehicle;
if (vehicle != null) {
print('Occupancy: ${vehicle.occupancyStatus}');
print('Occupancy %: ${vehicle.occupancyPercentage}');
print('Congestion: ${vehicle.congestionLevel}');
}

// Worst-case crowding summary over a route's fresh vehicles
final routeCrowding = route.liveCrowding;
if (routeCrowding != null) {
print('Vehicles: ${routeCrowding.vehicles}');
print('Worst occupancy: ${routeCrowding.occupancyStatus}');
}
danger

Every field of PTCrowdingInfo is optional. Feeds and older realtime producers supply arbitrary subsets, so any combination of fields may be null. Render crowding indicators that degrade gracefully when data is absent.

Congestion Level​

The PTCongestionLevel enum describes the congestion of the traffic a vehicle travels in (GTFS-RT CongestionLevel). Values outside the GTFS-RT enum map to unknown.

Enum CaseDescription
unknownUnknown congestion level.
runningSmoothlyRunning smoothly.
stopAndGoStop and go.
congestionCongestion.
severeCongestionSevere congestion.

Occupancy Status​

The PTOccupancyStatus enum describes vehicle occupancy (GTFS-RT OccupancyStatus). Values above notAcceptingPassengers mean there is no usable crowding data. The scale is not strictly linear, so display the producer's state rather than interpolating.

Enum CaseDescription
emptyEmpty.
manySeatsAvailableMany seats available.
fewSeatsAvailableFew seats available.
standingRoomOnlyStanding room only.
crushedStandingRoomOnlyCrushed standing room only.
fullFull.
notAcceptingPassengersNot accepting passengers.
noDataAvailableNo usable crowding data.
notBoardableNot boardable (no usable crowding data).

Route Shapes​

The PTShape class holds the drawable geometry of a public transport route. Shapes are not returned by default - request them by setting shapes: true on the schedule filter:

final ptStopInfo = await item.getPTStopInfo(
filter: PTStopScheduleFilter(shapes: true),
);
PropertyTypeDescription
pointsList<Coordinates>Shape points, ordered in the travel direction of the referencing route. Empty when the shape failed to decode.
MethodReturn TypeDescription
toMarker()Marker?Converts the shape into a drawable polyline marker, or null when points is empty.

Shapes are returned deduplicated in PTStopInfo.shapes, one entry per distinct geometry and direction, and referenced from PTRouteInfo.shape on the stop catalogue's routes. Both share the same PTShape instances.

Draw the shapes​

Each call to toMarker creates a new marker, so reuse the result instead of converting repeatedly.

Render settings apply per collection, so drawing each line in its own routeColor means one collection per route:

for (final stop in ptStopInfo.stops) {
for (final route in stop.routes) {
final marker = route.shape?.toMarker();
if (marker == null) {
continue;
}

final collection = MarkerCollection(
markerType: MarkerType.polyline,
name: 'pt_shape_${route.routeId}',
);
collection.add(marker);

mapController.preferences.markers.add(
collection,
settings: MarkerCollectionRenderSettings(
polylineInnerColor: route.routeColor ?? Colors.blue,
),
);
}
}

Using the line's own routeColor keeps the map and the departure list consistent.

warning

Shapes are the largest part of the response. Request them only when they will actually be drawn.

danger

PTRouteInfo.shape is always null on PTTrip.route. Shapes are resolved onto the stop catalogue's routes only, so look the route up in PTStop.routes to get its geometry.

info

A null PTRouteInfo.shape is the authoritative "not drawable" signal: a route can be advertised as having a shape while no geometry is actually available. A PTShape with an empty points list failed to decode and is kept only so the positional references of the response stay valid.

Stop Info​

The PTStopInfo class aggregates stop-related data including agencies, stops, trips, service alerts, and route shapes related to a specific public transit overlay item.

PropertyTypeDescription
agenciesList<PTAgency>Agencies serving the selected item
tripsList<PTTrip>Trips in which the selected item is involved
stopsList<PTStop>Stops associated with the trips
alertsList<PTAlertInfo>Deduplicated GTFS-RT service alerts referenced by the trips and stops. Empty when none apply. The order is not meaningful.
shapesList<PTShape>Deduplicated route shapes. Empty unless shapes were requested. See Route Shapes.