diff options
Diffstat (limited to '.idea/gtfs-realtime-book/ch-06-consuming-service-alerts.md')
-rw-r--r-- | .idea/gtfs-realtime-book/ch-06-consuming-service-alerts.md | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/.idea/gtfs-realtime-book/ch-06-consuming-service-alerts.md b/.idea/gtfs-realtime-book/ch-06-consuming-service-alerts.md new file mode 100644 index 0000000..9869173 --- /dev/null +++ b/.idea/gtfs-realtime-book/ch-06-consuming-service-alerts.md @@ -0,0 +1,305 @@ +## 6. Consuming Service Alerts + +The previous chapter introduced you to Protocol Buffers and showed you +how load a remote GTFS-realtime feed into your Java project. This +chapter will show you how to read the data from each of the three entity +types (service alerts, vehicle positions and trip updates). + +The previous chapter also showed you how to loop over all entities in a +feed using `getEntityList()`. Each entity contains either a service +alert, a vehicle position or a trip update. + +Once you have verified that a `FeedEntity` element contains an alert, +you can retrieve the corresponding `Alert` object using +`getAlert()`. + +```java +for (FeedEntity entity : fm.getEntityList()) { + if (entity.hasAlert()) { + Alert alert = entity.getAlert(); + + processAlert(alert); + } +} +``` + +You can then access the specific properties of a service alert using the +returned object. + +### Cause & Effect + +For example, to retrieve the cause value for the alert, you would first +check for its presence with `hasCause()` then retrieve the value using +`getCause()`. + +```java +public void processAlert(Alert alert) { + if (alert.hasCause()) { + Cause cause = alert.getCause(); + + // ... + } + + // ... +} +``` + +The `Cause` object is an enumerator, meaning it has a finite number of +possible values. To determine which value the object corresponds to, +call `getNumber()` to compare it to the possible values. + +```java +switch (cause.getNumber()) { + case Cause.ACCIDENT_VALUE: + // ... + + case Cause.MEDICAL_EMERGENCY_VALUE: + // ... +} +``` + +Note: There are other possible cause values to include in the switch +statement; these have been omitted here as they are all covered in the +specification earlier in this book. + +The `Effect` field works in the same way. The difference is that the +possible list of values to compare against is different. + +```java +if (alert.hasEffect()) { + Effect effect = alert.getEffect(); + + switch (effect.getNumber()) { + case Effect.DETOUR_VALUE: + // ... + + case Effect.SIGNIFICANT_DELAYS_VALUE: + // ... + } +} +``` + +### Title, Description and URL + +Each of these fields are of type `TranslatedString`. A +`TranslatedString` may contain multiple `Translation` objects, so +when processing these fields you must loop over the available +translations. + +For example, to loop over the available translations for the header text +you iterate over **getTranslationList()**. + +```java +if (alert.hasHeaderText()) { + TranslatedString header = alert.getHeaderText(); + + for (Translation translation : header.getTranslationList()) { + // Process the translation here + + } +} +``` + +***Note:** To access the description you would use `hasDescription()` and +`getDescription()`, while to access the URL you would use `hasUrl()` and +`getUrl()`.* + +Alternatively, you can use `getTranslationCount()` and +`getTranslation()` to retrieve each of the available translations. + +```java +for (int i = 0; i < header.getTranslationCount(); i++) { + Translation translation = header.getTranslation(i); + + // Process the translation here +} +``` + +A `Translation` object is made up of text and optionally, its +associated language. When dealing with the URL field, the text retrieved +from `getText()` contains a full URL. + +```java +if (translation.hasLanguage()) { + String language = translation.getLanguage(); + + if (language.equals("fr")) { + // Do something for French language + } + else { + // All other languages + } +} + +if (translation.hasText()) { + String text = translation.getText(); + + // Do something with the text +} +``` + +***Note:** Most GTFS-realtime feeds only specify text in a single +language, and therefore do not include the language value.* + +### Active Period + +A service alert may contain zero or more time ranges, each of which +specify the dates and times the alert is active for. If none are +specified then the alert is active as long as it exists within the feed. + +You can access each of the `TimeRange` objects using either of the +following methods: + +```java +for (TimeRange timeRange : alert.getActivePeriodList()) { + // ... +} + +for (int i = 0; i < alert.getActivePeriodCount(); i++) { + TimeRange timeRange = alert.getActivePeriod(i); + + // ... +} +``` + +A `TimeRange` can have either a start or finish date, or it may +contain both. In Java, you can turn each of these dates into a +`java.util.Date` object as shown below. + +```java +if (timeRange.hasStart()) { + Date start = new Date(timeRange.getStart() * 1000); + + // ... +} + +if (timeRange.hasEnd()) { + Date end = new Date(timeRange.getEnd() * 1000); + + // ... +} +``` + +***Note:** The date value is multiplied by 1,000 because the date in the +GTFS-realtime is represented by the number of seconds since January 1, +1970, while `java.util.Date` is instantiated using the number of +milliseconds since the same date.* + +### Affected Entities + +A service alert may contain zero or more affected entities, each of +which describes a route, stop, agency, trip or route type. You can +access these entities using either of the following methods: + +``` +for (EntitySelector entity : alert.getInformedEntityList()) { + +} + +for (int i = 0; i < alert.getInformedEntityCount(); i++) { + EntitySelector entity = alert.getInformedEntity(i); + +} +``` + +There are a number of properties available in the `EntitySelector` +object, each of which can be used to match the entity to the +corresponding GTFS feed. + +For example, if the `EntitySelector` object has a route ID value, then +you should be able to locate the route in the corresponding GTFS feed's +`routes.txt` file. + +The properties can be accessed as follows: + +```java +if (entity.hasAgencyId()) { + String agencyId = entity.getAgencyId(); + +} + +if (entity.hasRouteId()) { + String routeId = entity.getRouteId(); + +} + +if (entity.hasRouteType()) { + int routeType = entity.getRouteType(); + +} + +if (entity.hasStopId()) { + String stopId = entity.getStopId(); + +} +``` + +The route type value is an Integer and if present must correspond either +to the standard GTFS route type values, or to the extended route type +values. + +The other entity information that can be contained in `EntitySelector` +is trip information. You can access the trip properties as follows: + +```java +if (entity.hasTrip()) { + TripDescriptor trip = entity.getTrip(); + + if (trip.hasTripId()) { + String tripId = trip.getTripId(); + + } + + if (trip.hasRouteId()) { + String routeId = trip.getRouteId(); + + } + + if (trip.hasStartDate()) { + String startDate = trip.getStartDate(); + + } + + if (trip.hasStartTime()) { + String startTime = trip.getStartTime(); + + } + + if (trip.hasScheduleRelationship()) { + ScheduleRelationship sr = trip.getScheduleRelationship(); + + } +} +``` + +You can test the `ScheduleRelationship` value by comparing the +`getNumber()` value to one of the available constants, as follows. + +```java +if (entity.hasTrip()) { + // ... + + if (trip.hasScheduleRelationship()) { + + ScheduleRelationship sr = trip.getScheduleRelationship(); + + switch (sr.getNumber()) { + case ScheduleRelationship.ADDED_VALUE: + // ... + break; + + case ScheduleRelationship.CANCELED_VALUE: + // ... + break; + + case ScheduleRelationship.SCHEDULED_VALUE: + // ... + break; + + case ScheduleRelationship.UNSCHEDULED_VALUE: + // ... + break; + } + } +} +``` |