aboutsummaryrefslogtreecommitdiff
path: root/.idea/gtfs-book
diff options
context:
space:
mode:
Diffstat (limited to '.idea/gtfs-book')
-rw-r--r--.idea/gtfs-book/ch-00-definitive-guide-to-gtfs.md55
-rw-r--r--.idea/gtfs-book/ch-01-introduction.md45
-rw-r--r--.idea/gtfs-book/ch-02-agencies.md47
-rw-r--r--.idea/gtfs-book/ch-03-stops.md117
-rw-r--r--.idea/gtfs-book/ch-04-routes.md82
-rw-r--r--.idea/gtfs-book/ch-05-trips.md222
-rw-r--r--.idea/gtfs-book/ch-06-stop-times.md160
-rw-r--r--.idea/gtfs-book/ch-07-calendar.md138
-rw-r--r--.idea/gtfs-book/ch-08-fares.md115
-rw-r--r--.idea/gtfs-book/ch-09-shapes.md76
-rw-r--r--.idea/gtfs-book/ch-10-frequencies.md98
-rw-r--r--.idea/gtfs-book/ch-11-stop-transfers.md65
-rw-r--r--.idea/gtfs-book/ch-12-feed-information.md36
-rw-r--r--.idea/gtfs-book/ch-13-importing-to-sql.md125
-rw-r--r--.idea/gtfs-book/ch-14-switching-to-integer-ids.md111
-rw-r--r--.idea/gtfs-book/ch-15-optimizing-shapes.md158
-rw-r--r--.idea/gtfs-book/ch-16-deleting-unused-data.md106
-rw-r--r--.idea/gtfs-book/ch-17-searching-for-trips.md346
-rw-r--r--.idea/gtfs-book/ch-18-working-with-trip-blocks.md109
-rw-r--r--.idea/gtfs-book/ch-19-calculating-fares.md296
-rw-r--r--.idea/gtfs-book/ch-20-trip-patterns.md141
-rw-r--r--.idea/gtfs-book/ch-21-conclusion.md23
-rw-r--r--.idea/gtfs-book/images/agency-google-maps.pngbin348035 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/block-01.pngbin20153 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/block-02.pngbin19817 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/block-03.pngbin19154 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/block-04.pngbin20673 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/orthogonal-distance.jpegbin23287 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/shape-original.jpegbin402743 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/shape-reduced.jpegbin401253 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/stop-times.pngbin454610 -> 0 bytes
-rw-r--r--.idea/gtfs-book/images/stops-sample.pngbin129647 -> 0 bytes
32 files changed, 0 insertions, 2671 deletions
diff --git a/.idea/gtfs-book/ch-00-definitive-guide-to-gtfs.md b/.idea/gtfs-book/ch-00-definitive-guide-to-gtfs.md
deleted file mode 100644
index 2c32c67..0000000
--- a/.idea/gtfs-book/ch-00-definitive-guide-to-gtfs.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# The Definitive Guide to GTFS
-
-*Consuming open public transportation data with the General Transit Feed
-Specification*
-
-Originally written by Quentin Zervaas.
-
-## About This Book
-
-This book is a comprehensive guide to GTFS -- the General Transit Feed
-Specification. It is comprised of two main sections.
-
-The first section describes what GTFS is and provides details about the
-specification itself. In addition to this it also provides various
-discussion points and things to consider for each of the files in the
-specification.
-
-The second section covers a number of topics that relate to actually
-using GTFS feeds, such as how to calculate fares, how to search for
-trips, how to optimize feed data and more.
-
-This book is written for developers that are using transit data for web
-sites, mobile applications and more. It aims to be as language-agnostic
-as possible, but uses SQL to demonstrate concepts of extracting data
-from a GTFS feed.
-
-### About The Author
-
-Quentin Zervaas is a software developer from Adelaide, Australia.
-
-Quentin was the founder of TransitFeeds (now <OpenMobilityData.org>), a web
-site that provides a comprehensive listing of public transportation data
-available around the world. This site is referenced various times
-throughout this book.
-
-### Credits
-
-First Edition. Published in February 2014.
-
-**Technical Reviewer**
-
-Rupert Hanson
-
-**Copy Editor**
-
-Miranda Little
-
-**Disclaimer**
-
-The information in this book is distributed on an "as is" basis, without
-warranty. Although every precaution has been taken in the preparation of
-this work, the author shall not be liable to any person or entity with
-respect to any loss or damage caused or alleged to be caused directly or
-indirectly by the information contained in this book.
-
diff --git a/.idea/gtfs-book/ch-01-introduction.md b/.idea/gtfs-book/ch-01-introduction.md
deleted file mode 100644
index 3b3765c..0000000
--- a/.idea/gtfs-book/ch-01-introduction.md
+++ /dev/null
@@ -1,45 +0,0 @@
-## 1. Introduction to GTFS
-
-GTFS (General Transit Feed Specification) is a data standard developed
-by Google used to describe a public transportation system. Its primary
-purpose was to enable public transit agencies to upload their schedules
-to Google Transit so that users of Google Maps could easily figure out
-which bus, train, ferry or otherwise to catch.
-
-> **A GTFS feed is a ZIP file that contains a series of CSV files that
-list routes, stops and trips in a public transportation system.**
-
-This book examines GTFS in detail, including which data from a public
-transportation system can be represented, how to extract data, and
-explores some more advanced techniques for optimizing and querying data.
-
-The official GTFS specification has been referenced a number of times in
-this book. It is strongly recommended you are familiar with it. You can
-view at the following URL:
-
-<https://developers.google.com/transit/gtfs/reference>
-
-### Structure of a GTFS Feed
-
-A GTFS feed is a series of CSV files, which means that it is trivial to
-include additional files in a feed. Additionally, files required as part
-of the specification can also include additional columns. For this
-reason, feeds from different agencies generally include different levels
-of detail.
-
-***Note:** The files in a GTFS feed are CSV files, but use a file
-extension of `.txt`.*
-
-A GTFS feed can be described as follows:
-
-> **A GTFS feed has one or more routes. Each route (`routes.txt`) has one or
-more trips (`trips.txt`). Each trip visits a series of stops (`stops.txt`)
-at specified times (`stop_times.txt`). Trips and stop times only contain
-time of day information; the calendar is used to determine on which days
-a given trip runs (`calendar.txt` and `calendar_dates.txt`).**
-
-The following chapters cover the main files that are included in all
-GTFS feeds. For each file, the main columns are covered, as well as
-optional columns that can be included. This book also covers some of the
-unofficial columns that some agencies choose to include.
-
diff --git a/.idea/gtfs-book/ch-02-agencies.md b/.idea/gtfs-book/ch-02-agencies.md
deleted file mode 100644
index cb837ae..0000000
--- a/.idea/gtfs-book/ch-02-agencies.md
+++ /dev/null
@@ -1,47 +0,0 @@
-## 2. Agencies (agency.txt)
-
-*This file is ***required*** to be included in GTFS feeds.*
-
-The `agency.txt` file is used to represent the agencies that provide
-data for this feed. While its presence is optional, if there are routes
-from multiple agencies included, then records in `routes.txt` make
-reference to agencies in this file.
-
-| Field | Required? | Description |
-| :----------------------------------------------------- | :--------: | :-------- |
-| `agency_id` | Optional | An ID that uniquely identifies a single transit agency in the feed. If a feed only contains routes for a single agency then this value is optional. |
-| `agency_name` | Required | The full name of the transit agency. |
-| `agency_url` | Required | The URL of the transit agency. Must be a complete URL only, beginning with `http://` or `https://`. |
-| `agency_timezone` | Required | Time zone of agency. All times in `stop_times.txt` use this time zone, unless overridden by its corresponding stop. All agencies in a single feed must use the same time zone. Example: **America/New_York** (See <http://en.wikipedia.org/wiki/List_of_tz_database_time_zones> for more examples) |
-| `agency_lang` | Required | Contains a two-letter ISO-639-1 code (such as `en` or `EN` for English) for the language used in this feed. |
-| `agency_phone` | Optional | A single voice telephone number for the agency that users can dial if required. |
-| `agency_fare_url` | Optional | A URL that describes fare information for the agency. Must be a complete URL only, beginning with `http://` or `https://`. |
-
-### Sample Data
-
-The following extract is taken from the GTFS feed of TriMet (Portland,
-USA), located at <https://openmobilitydata.org/p/trimet>.
-
-| `agency_name` | `agency_url` | `agency_timezone` | `agency_lang` | `agency_phone` |
-| :------------ | :------------------------------------------- | :-------------------- | :------------ | :--------------- |
-| `TriMet` | `[https://trimets.org](https://trimet.org/)` | `America/Los_Angeles` | `en` | `(503) 238-7433` |
-
-In this example, the `agency_id` column is included, but as there is
-only a single entry the value can be empty. This means the `agency_id`
-column in `routes.txt` also is not required.
-
-### Discussion
-
-The data in this file is typically used to provide additional
-information to users of your app or web site in case schedules derived
-from the rest of this feed are not sufficient (or in the case of
-`agency_fare_url`, an easy way to provide a reference point to users
-if the fare information in the feed is not being used).
-
-If you refer to the following screenshot, taken from Google Maps, you
-can see the information from `agency.txt` represented in the
-lower-left corner as an example of how it can be used.
-
-![GTFS agency](images/agency-google-maps.png)
-
-
diff --git a/.idea/gtfs-book/ch-03-stops.md b/.idea/gtfs-book/ch-03-stops.md
deleted file mode 100644
index cd8dedb..0000000
--- a/.idea/gtfs-book/ch-03-stops.md
+++ /dev/null
@@ -1,117 +0,0 @@
-## 3. Stops & Stations (stops.txt)
-
-*This file is ***required*** to be included in GTFS feeds.*
-
-The individual locations where vehicles pick up or drop off passengers
-are represented by `stops.txt`. Records in this file are referenced in
-`stop_times.txt`. A record in this file can be either a stop or a
-station. A station has one or more child stops, as indicated using the
-`parent_station` value. Entries that are marked as stations may not
-appear in `stop_times.txt`.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `stop_id` | Required | An ID to uniquely identify a stop or station. |
-| `stop_code` | Optional | A number or short string used to identify a stop to passengers. This is typically displayed at the physical stop or on printed schedules. |
-| `stop_name` | Required | The name of the stop as passengers know it by. |
-| `stop_desc` | Optional | A description of the stop. If provided, this should provide additional information to the `stop_name` value. |
-| `stop_lat` | Required | The latitude of the stop (a number in the range of `-90` to `90`). |
-| `stop_lon` | Required | The longitude of the stop (a number in the range of `-180` to `180`). |
-| `zone_id` | Optional | This is an identifier used to calculate fares. A single zone ID may appear in multiple stops, but is ignored if the stop is marked as a station. |
-| `stop_url` | Optional | A URL that provides information about this stop. It should be specific to this stop and not simply link to the agency's web site. |
-| `location_type` | Optional | Indicates if a record is a stop or station. `0` or blank means a stop, `1` means a station. |
-| `parent_station` | Optional | If a record is marked as a stop and has a parent station, this contains the ID of the parent (the parent must have a `location_type` of `1`). |
-| `stop_timezone` | Optional | If a stop is located in a different time zone to the one specified in `agency.txt`, then it can be overridden here. |
-| `wheelchair_boarding` | Optional | A value of `1` indicates it is possible for passengers in wheelchairs to board or alight. A value of `2` means the stop is not wheelchair accessible, while `0` or an empty value means no information is available. If the stop has a parent station, then 0 or an empty value means to inherit from its parent. |
-
-### Sample Data
-
-The following extract is taken from the TriMet GTFS feed
-(<https://openmobilitydata.org/p/trimet>).
-
-| `stop_id` | `stop_code` | `stop_name` | `stop_lat` | `stop_lon` | `stop_url` |
-| :-------- | :----------- | :------------------ | :---------- | :------------ | :---------------------------------------------------|
-| `2` | `2` | `A Ave & Chandler` | `45.420595` | `-122.675676` |` <http://trimet.org/arrivals/tracker?locationID=2>` |
-| `3` | `3` | `A Ave & Second St` | `45.419386` | `-122.665341` |` <http://trimet.org/arrivals/tracker?locationID=3>` |
-| `4` | `4` | `A Ave & 10th St` | `45.420703` | `-122.675152` |` <http://trimet.org/arrivals/tracker?locationID=4>` |
-| `6` | `6` | `A Ave & 8th St` | `45.420217` | `-122.67307` |` <http://trimet.org/arrivals/tracker?locationID=6>` |
-
-The following diagram shows how these points look if you plot them onto
-a map.
-
-![Stops](images/stops-sample.png)
-
-In this extract, TriMet use the same value for stop IDs and stop codes.
-This is useful, because it means the stop IDs are stable (that is, they
-do not change between feed versions). This means that if you want to
-save a particular stop (for instance, if a user wants to save a
-"favorite stop") you can trust that saving the ID will get the job done.
-
-**Note:** This is not always the case though, which means you may have
-to save additional information if you want to save a stop. For instance,
-you may need to save the coordinates or the list of routes a stop serves
-so you can find it again if the stop ID has changed in a future version
-of the feed.
-
-### Stops & Stations
-
-Specifying an entry in this file as a *station* is typically used when
-there are many stops located within a single physical entity, such as a
-train station or bus depot. While many feeds do not offer this
-information, some large train stations may have up to 20 or 30
-platforms.
-
-Knowing the platform for a specific trip is extremely useful, but if a
-passenger wants to select a starting point for their trip, showing them
-a list of platforms may be confusing.
-
-Passenger:
-
-**"I want to travel from *Central Station* to *Airport Station*."**
-
-Web site / App:
-
-**"Board at *Central Station platform 5*, disembark at *Airport Station platform 1*."**
-
-In this example, the passenger selects the parent station, but they are
-presented with the specific stop so they know exactly where within the
-station they need to embark or disembark.
-
-### Wheelchair Accessibility
-
-If you are showing wheelchair accessibility information, it is important
-to differentiate between "no access" and "no information", as knowing a
-stop is not accessible is as important as knowing it is.
-
-If a stop is marked as being wheelchair accessible, you must check that
-trips that visit the stop are also accessible (using the
-`wheelchair_accessible` field in `trips.txt`). If the value in
-`trips.txt` is blank, `0` or `1` then it is safe to assume the
-trip can be accessed. If the stop is accessible and the trip is not,
-then passengers in wheelchairs cannot use the trip.
-
-### Stop Features
-
-One of the proposed changes to GTFS is the addition of a file called
-`stop_features.txt`. This is used to define characteristics about
-stops. The great thing about this file is that it allows you to indicate
-to users when a stop has a ticket machine, bike storage, lighting, or an
-electronic display with real-time information.
-
-TriMet is one of the few agencies including this file. The following is
-a sample of this file.
-
-| `stop_id` | `feature_type` |
-| :-------- | :------------- |
-| `61` | `4110` |
-| `61` | `2310` |
-| `61` | `5200` |
-
-This data indicate that stop `61` (NE Alberta & 24th) has a *Printed
-Schedule Display* (`4110`), a *Bike Rack* (`2310`) and a *Street
-Light* (`5200`).
-
-For more information about this proposal and a list of values and their
-meanings, refer to
-<https://sites.google.com/site/gtfschanges/proposals/stop-amenity>.
-
diff --git a/.idea/gtfs-book/ch-04-routes.md b/.idea/gtfs-book/ch-04-routes.md
deleted file mode 100644
index 2e9716e..0000000
--- a/.idea/gtfs-book/ch-04-routes.md
+++ /dev/null
@@ -1,82 +0,0 @@
-## 4. Routes (routes.txt)
-
-*This file is ***required*** to be included in GTFS feeds.*
-
-A route is a group of trips that are displayed to riders as a single
-service.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `route_id` | Required | An ID that uniquely identifies the route. |
-| `agency_id` | Optional | The ID of the agency a route belongs to, as it appears in `agency.txt`. Only required if there are multiple agencies in the feed. |
-| `route_short_name` | Required | A nickname or code to represent this service. If this is left empty then the `route_long_name` must be included. |
-| `route_long_name` | Required | The route full name. If this is left empty then the `route_short_name` must be included. |
-| `route_desc` | Optional | A description of the route, such as where and when the route operates. |
-| `route_type` | Required | The type of transportation used on a route (such as bus, train or ferry). See below for more information. |
-| `route_url` | Optional | A URL of a web page that describes this particular route. |
-| `route_color` | Optional | If applicable, a route can have a color assigned to it. This is useful for systems that use colors to identify routes. This value is a six-character hexadecimal number (for example, `FF0000` is red). |
-| `route_text_color` | Optional | For routes that specify the `route_color`, a corresponding text color should also be specified. |
-
-### Sample Data
-
-The following extract is taken from the TriMet GTFS feed
-(<https://openmobilitydata.org/p/trimet>).
-
-| `route_id` | `route_short_name` | `route_long_name` | `route_type` |
-| :--------- | :----------------- | :--------------------------- | :----------- |
-| `1` | `1` | `Vermont` | `3` |
-| `4` | `4` | `Division / Fessenden` | `3` |
-| `6` | `6` | `Martin Luther King Jr Blvd` | `3` |
-
-This sample shows three different bus routes for the greater Portland
-area. The `route_type` value of `3` indicates they are buses. See
-the next section for more information about route types in GTFS.
-
-There is no agency ID value in this feed, as TriMet is the only agency
-represented in the feed.
-
-The other thing to note about this data is that TriMet use the same
-value for both `route_id` and `route_short_name`. This is very
-useful, because it means if you have a user that wants to save
-information about a particular route you can trust the `route_id`
-value. Unfortunately, this is not the case in all GTFS feeds. Sometimes,
-the `route_id` value may change with every version of a feed (or at
-least, semi-frequently). Additionally, some feeds may also have multiple
-routes with the same `route_short_name`. This can present challenges
-when trying to save user data.
-
-### Route Types
-
-To indicate a route's mode of transport, the `route_type` column is
-used.
-
-| Value | Description |
-| :---- | :---------------- |
-| `0` | Tram / Light Rail |
-| `1` | Subway / Metro |
-| `2` | Rail |
-| `3` | Bus |
-| `4` | Ferry |
-| `5` | Cable Car |
-| `6` | Gondola |
-| `7` | Funicular |
-
-Agencies may interpret the meaning of these route types differently. For
-instance, some agencies specify their subway service as rail (value of
-`2` instead of `1`), while some specify their trains as light rail
-(`0` instead of `2`).
-
-These differences between agencies occur mainly because of the vague
-descriptions for each of these route types. If you use Google Transit to
-find directions, you may notice route types referenced that are
-different to those listed above. This is because Google Transit also
-supports additional route types. You can read more about these
-additional route types at
-<https://support.google.com/transitpartners/answer/3520902?hl=en>.
-
-Very few GTFS feeds made available to third-party developers actually
-make use of these values, but it is useful to know in case you come
-across one that does. For instance, Sydney Buses include their school
-buses with a route type of `712`, while other buses in the feed have
-route type `700`.
-
diff --git a/.idea/gtfs-book/ch-05-trips.md b/.idea/gtfs-book/ch-05-trips.md
deleted file mode 100644
index ee2b814..0000000
--- a/.idea/gtfs-book/ch-05-trips.md
+++ /dev/null
@@ -1,222 +0,0 @@
-## 5. Trips (trips.txt)
-
-*This file is ***required*** to be included in GTFS feeds.*
-
-The `trips.txt` file contains trips for each route. The specific stop
-times are specified in `stop_times.txt`, and the days each trip runs
-on are specified in `calendar.txt` and `calendar_dates.txt`.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `route_id` | Required | The ID of the route a trip belongs to as it appears in `routes.txt`. |
-| `service_id` | Required | The ID of the service as it appears in `calendar.txt` or `calendar_dates.txt`, which identifies the dates on which a trip runs. |
-| `trip_id` | Required | A unique identifier for a trip in this file. This value is referenced in `stop_times.txt` when specifying individual stop times. |
-| `trip_headsign` | Optional | The text that appears to passengers as the destination or description of the trip. Mid-trip changes to the headsign can be specified in `stop_times.txt`. |
-| `trip_short_name` | Optional | A short name or code to identify the particular trip, different to the route's short name. This may identify a particular train number or a route variation. |
-| `direction_id` | Optional | Indicates the direction of travel for a trip, such as to differentiate between an inbound and an outbound trip. |
-| `block_id` | Optional | A block is a series of trips conducted by the same vehicle. This ID is used to group 2 or more trips together. |
-| `shape_id` | Optional | This value references a value from `shapes.txt` to define a shape for a trip. |
-| `wheelchair_accessible` | Optional | `0` or blank indicates unknown, while `1` indicates the vehicle can accommodate at least one wheelchair passenger. A value of `2` indicates no wheelchairs can be accommodated. |
-
-### Sample Data
-
-Consider the following extract, taken from the `trips.txt` file of the
-TriMet GTFS feed (<https://openmobilitydata.org/p/trimet>).
-
-| `route_id` | `service_id` | `trip_id` | `direction_id` | `block_id` | `shape_id` |
-| ---------- | ------------ | ----------- | -------------- | ---------- | ---------- |
-| 1 | W.378 | 4282257 | 0 | 103 | 185327 |
-| 1 | W.378 | 4282256 | 0 | 101 | 185327 |
-| 1 | W.378 | 4282255 | 0 | 102 | 185327 |
-| 1 | W.378 | 4282254 | 0 | 103 | 185327 |
-
-This data describes four individual trips for the "Vermont" bus route
-(this was determined by looking up the `route_id` value in
-`routes.txt`). While the values for `trip_id`, `block_id` and
-`shape_id` are all integers in this particular instance, this is not a
-requirement. Just like `service_id`, there may be non-numeric
-characters.
-
-As each of these trips is for the same route and runs in the same
-direction (based on `direction_id`) they can all be represented by the
-same shape. Note however that this is not always be the case as some
-agencies may start or finish trips for a single route at different
-locations depending on the time of the day. If this were the case, then
-the trip's shape would differ slightly (and therefore have a different
-shape to represent it in `shapes.txt`).
-
-Although this example does not include `trip_headsign`, many feeds do
-include this value. This is useful for indicating to a passenger where
-the trip is headed. When the trip headsign is not provided in the feed,
-you can determine the destination by using the final stop in a trip.
-
-**Tip:** If you are determining the destination based on the final stop,
-you can either present the stop name to the user, or you can
-reverse-geocode the stop's coordinates to determine the its locality.
-
-### Blocks
-
-In the preceding example, each trip has a value for `block_id`. The
-first and the last trips here both have a `block_id` value of `103`.
-This indicates that the same physical vehicle completes both of these
-trips. As each of these trips go in the same direction, it is likely
-that they start at the same location.
-
-This means there is probably another trip in the feed for the same block
-that exists between the trips listed here. It would likely travel from
-the finishing point of the first trip (`4282257`) to the starting
-point of the other trip (`4282254`). If you dig a little deeper in the
-feed you will find the trip shown in the following table.
-
-| `route_id` | `service_id` | `trip_id` | `direction_id` | `block_id` | `shape_id` |
-| :--------- | :----------- | :-------- | :------------- | :--------- | :--------- |
-| 1 | W.378 | 4282270 | 1 | 103 | 185330 |
-
-This is a trip traveling in the opposite direction for the same block.
-It has a different shape ID because it is traveling in the opposite
-direction; a shape's points must advance in the same direction a trip's
-stop times do.
-
-***Note:** You should perform some validation when grouping trips
-together using block IDs. For instance, if trips share a block_id value
-then they should also have the same service_id value. You should also
-check that the times do not overlap; otherwise the same vehicle would be
-unable to service both trips.*
-
-If you dig even further in this feed, there are actually seven different
-trips all using block `103` for the **W.378** service period. This
-roughly represents a full day's work for a single vehicle.
-
-For more discussion on blocks and how to utilize them effectively, refer
-to *Working With Trip Blocks*.
-
-### Wheelchair Accessibility
-
-Similar to `stops.txt`, you can specify the wheelchair accessibility
-of a specific trip using the `wheelchair_accessible` field. While many
-feeds do not provide this information (often because vehicles in a fleet
-can be changed at the last minute, so agencies do not want to guarantee
-this information), your wheelchair-bound users will love you if you can
-provide this information.
-
-As mentioned in the section on `stops.txt`, it is equally important to
-tell a user that a specific vehicle cannot accommodate wheelchairs as to
-when it can. Additionally, if the stops in a feed also have wheelchair
-information, then both the stop and trip must be wheelchair accessible
-for a passenger to be able to access a trip at the given stop.
-
-### Trip Direction
-
-One of the optional fields in `trips.txt` is `direction_id`, which
-is used to indicate the general direction a vehicle is traveling. At
-present the only possible values are `0` to represent "inbound" and
-`1` to represent "outbound". There are no specific guidelines as to
-what each value means, but the intention is that an inbound trip on a
-particular route should be traveling in the opposite direction to an
-outbound trip.
-
-Many GTFS feeds do not provide this information. In fact, there are a
-handful of feeds that include two entries in `routes.txt` for each
-route (one for each direction).
-
-One of the drawbacks of `direction_id` is that there are many routes
-for which "inbound" or "outbound" do not actually mean anything. Many
-cities have loop services that start and finish each trip at the same
-location. Some cities have one or more loops that travel in both
-directions (generally indicated by "clockwise loop" and
-"counter-clockwise loop", or words to that effect). In these instances,
-the `direction_id` can be used to determine which direction the route
-is traveling.
-
-### Trip Short Name
-
-The `trip_short_name` field that appears in `trips.txt` is used to
-provide a vehicle-specific code to a particular trip on a route. Based
-on GTFS feeds that are currently in publication, it appears there are
-two primary use-cases for this field:
-
-* Specifying a particular train number for all trains on a route
-* Specifying a route "sub-code" for a route variant.
-
-### Specifying a Train Number
-
-For certain commuter rail systems, such as SEPTA in Philadelphia or MBTA
-in Boston, each train has a specific number associated with it. This
-number is particularly meaningful to passengers as trains on the same
-route may have different stopping patterns or even different features
-(for instance, only a certain train may have air-conditioning or
-wheelchair access).
-
-Consider the following extract from SEPTA's rail feed
-(<https://openmobilitydata.org/p/septa>).
-
-| `route_id` | `service_id` | `trip_id` | `trip_headsign` | `block_id` | `trip_short_name` |
-| ---------- | ------------ | ------------ | ------------------------ | ---------- | ----------------- |
-| AIR | S5 | AIR_1404_V25 | Center City Philadelphia | 1404 | 1404 |
-| AIR | S1 | AIR_402_V5 | Center City Philadelphia | 402 | 402 |
-| AIR | S1 | AIR_404_V5 | Center City Philadelphia | 404 | 404 |
-| AIR | S5 | AIR_406_V25 | Center City Philadelphia | 406 | 406 |
-
-In this data, there are four different trains all heading to the same
-destination. The `trip_short_name` is a value that can safely be
-presented to users as it has meaning to them. In this case, you could
-present the first trip to passengers as:
-
-**"Train 1404 on the Airport line heading to Center City
-Philadelphia."**
-
-In this particular feed, SEPTA use the same value for
-`trip_short_name` and for `block_id`, because the train number
-belongs to a specific train. This means after it completes the trip to
-Center City Philadelphia it continues on. In this particular feed, the
-following trip also exists:
-
-**"Train 1404 on the Warminster line heading to Glenside."**
-
-You can therefore think of the `trip_short_name` value as a
-"user-facing" version of `block_id`.
-
-### Specifying a Route Sub-Code
-
-The other use-case for `trip_short_name` is for specifying a route
-sub-code. For instance, consider an agency that has a route with short
-name `100` that travels from stop `S1` to stop `S2`. At night the
-agency only has a limited number of routes running, so they extend this
-route to also visit stop `S3` (so it travels from `S1` to `S2`
-then to `S3`). As it is a minor variation of the main path, the agency
-calls this trip `100A`.
-
-The agency could either create a completely separate entry in
-`routes.txt` (so they would have `100` and `100A`), or they can
-override the handful of trips in the evening by setting the
-`trip_short_name` to `100A`. The following table shows how this
-example might be represented.
-
-| `route_id` | `trip_id` | `service_id` | `trip_short_name` |
-| ---------- | --------- | ------------ | ----------------- |
-| 100 | T1 | C1 | |
-| 100 | T2 | C1 | |
-| 100 | T3 | C1 | |
-| 100 | T4 | C1 | 100A |
-
-In this example the `trip_short_name` does not need to be set for the
-first three trips as they use the `route_short_name` value from
-`routes.txt`.
-
-### Specifying Bicycle Permissions
-
-A common field that appears in many GTFS fields is
-`trip_bikes_allowed`, which is used to indicate whether or not
-passengers are allowed to take bicycles on board. This is useful for
-automated trip planning when bicycle options can be included in the
-results.
-
-The way this field works is similar to the wheelchair information; `0`
-or empty means no information provided; `1` means no bikes allowed;
-while `2` means at least one bike can be accommodated.
-
-**Note:** Unfortunately, this value is backwards when you compare it to
-wheelchair accessibility fields. For more discussion on this matter,
-refer to the topic on the Google Group for GTFS Changes
-(<https://groups.google.com/d/topic/gtfs-changes/rEiSeKNc4cs/discussion>).
-
diff --git a/.idea/gtfs-book/ch-06-stop-times.md b/.idea/gtfs-book/ch-06-stop-times.md
deleted file mode 100644
index 9eb0f93..0000000
--- a/.idea/gtfs-book/ch-06-stop-times.md
+++ /dev/null
@@ -1,160 +0,0 @@
-## 6. Stop Times (stop_times.txt)
-
-*This file is ***required*** to be included in GTFS feeds.*
-
-The `stop_times.txt` file specifies individual stop arrivals and
-departures for each trip. This file is typically the largest in a GTFS
-feed as it contains many records that correspond to each entry in
-`trips.txt`.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `trip_id` | Required | References a trip from `trips.txt`. This ID is referenced for every stop in a trip. |
-| `arrival_time` | Required | The arrival time in `HH:MM:SS` format. Can be left blank, except for at least the first and last stop time in a trip. This value is typically be the same as `departure_time`. |
-| `departure_time` | Required | The departure time in `HH:MM:SS` format. Can be left blank, except for at least the first and last stop time in a trip. This value is typically be the same as `arrival_time`. |
-| `stop_id` | Required | References a single stop from `stops.txt`. |
-| `stop_sequence` | Required | A unique number for a given trip to indicate the stopping order. Typically these values appear in order and increment by 1 for each stop time, but this is not always the case. |
-| `stop_headsign` | Optional | This is text that appears to passengers at this stop to identify the trip's destination. It should only be used to override the `trip_headsign` value from `trips.txt`. |
-| `pickup_type` | Optional | Indicates if passengers can be picked up at this stop. Sometimes a stop is drop-off only. |
-| `drop_off_type` | Optional | Indicates if passengers can be dropped off at this stop. Sometimes a stop is pick-up only. |
-| `shape_dist_traveled` | Optional | If a trip has an associated shape, this value indicates how far along that shape the vehicle has traveled when at this stop. Values in this file and `shapes.txt` must use the same unit. |
-
-### Sample Data
-
-Consider the following extract, taken from stop_times.txt in the TriMet
-GTFS feed (<https://openmobilitydata.org/p/trimet>). This represents the
-first ten stops of a trip for bus route `1` ("Vermont") in Portland, as
-covered in Sample Data for `trips.txt`.
-
-| `trip_id` | `arrival_time` | `departure_time` | `stop_id` | `stop_sequence` | `shape_dist_traveled` |
-| :-------- | :------------- | :--------------- | :-------- | :-------------- | :-------------------- |
-| 4282247 | 06:47:00 | 06:47:00 | 13170 | 1 | 0.0 |
-| 4282247 | 06:48:18 | 06:48:18 | 7631 | 2 | 867.5 |
-| 4282247 | 06:50:13 | 06:50:13 | 7625 | 3 | 2154.9 |
-| 4282247 | 06:52:07 | 06:52:07 | 7612 | 4 | 3425.5 |
-| 4282247 | 06:53:42 | 06:53:42 | 7616 | 5 | 4491.1 |
-| 4282247 | 06:55:16 | 06:55:16 | 10491 | 6 | 5536.2 |
-| 4282247 | 06:57:06 | 06:57:06 | 7588 | 7 | 6767.1 |
-| 4282247 | 06:58:00 | 06:58:00 | 7591 | 8 | 7364.4 |
-| 4282247 | 06:58:32 | 06:58:32 | 175 | 9 | 8618.7 |
-| 4282247 | 06:58:50 | 06:58:50 | 198 | 10 | 9283.8 |
-
-If you were to plot the full trip on a map (including using its shape
-file, as specified in `shapes.txt` and referenced in `trips.txt`),
-it would look like the following diagram. The first stop is selected.
-
-![Stop Times](images/stop-times.png)
-
-### Arrival Time vs. Departure Time
-
-The first thing to notice about this data is that the values in
-`arrival_time` and `departure_time` are the same. In reality, most
-of the time these values are the same. The situation where these values
-differ is typically when a vehicle is required to wait for a period of
-time before departing. For instance:
-
-**"The train departs the domestic airport at 6:30am, arrives at the
-international terminal at 6:35am. It waits for 10 minutes for passengers
-who have just landed to board, then departs for the city at 6:45am."**
-
-While this is not typically something you need to worry about, be aware
-that some feeds differ and the holdover time could be large. A person
-rushing to a train wants to know the time it departs, while a husband
-waiting at a stop to meet his wife wants to know what time it arrives.
-
-**Note:** In a situation where the difference between the arrival time
-and departure is small, you may be better off always displaying the
-earlier time to the user. The driver may view a one or two minute
-holdover as an opportunity to keep on time, whereas a ten or fifteen
-minute holdover is unlikely to be ignored as doing so would
-significantly alter the schedule.
-
-### Scheduling Past Midnight
-
-One of the most important concepts to understand about
-`stop_times.txt` is that times later than midnight can be specified.
-For example, if a trip starts at 11:45 PM and takes an hour to complete,
-its finishing time is 12:45 AM the next day.
-
-The `departure_time` value for the first stop is be `23:45:00`,
-while the `arrival_time` value for the final stop is `24:45:00`.
-If you were to specify the final arrival time as `00:45:00`, it
-would be referencing 12:45 AM prior to the trip's starting time.
-
-While you could use the `stop_sequence` to determine which day the
-trip fell on, it would be impossible to do a quick search purely based
-on the given final stop.
-
-A trip may start and finish after midnight without being considered as
-part of the next day's service. Many transit systems shut down
-overnight, but may have a few services that run after midnight until
-about 1 AM or 2 AM. It is logical to group them all together with the
-same service as earlier trips, which this functionality allows you to
-do.
-
-However, this has implications when searching for trips. For instance,
-if you want to find all trips between 12:00 AM and 1:00 AM on 30 January
-2014, then you need to search:
-
-* Between `00:00:00` and `01:00:00` for trips with service on `20140130`
-* Between `24:00:00` and `25:00:00` for trips with service on` 20140129`
-
-In *Searching for Trips* you can see how to apply this to your
-trip searches.
-
-### Time Points
-
-Most GTFS feeds provide arrival/departure times for every single stop.
-In reality, most agencies do not have known times (or at least, they do
-not publish times) for many of their stops.
-
-Typically, for routes that describe trains, subways or ferries that make
-relatively few stops in a trip, all stops have a specified time.
-However, often for bus routes that may make many stops in a single trip,
-generally only the main stops have times shown on printed schedules.
-
-Typically, the bus drivers are required to meet these time points; if
-they are ahead of schedule they might wait at a time point until the
-scheduled time; if they are running late they might try to catch up in
-order to adhere to the specified time point.
-
-This means that the intermediate points are likely estimates that have
-been interpolated based on the amount of time between time points. If
-there are multiple stops in-between the time points then the distance
-between stops may also be used to calculate the estimate.
-
-In actual fact, GTFS feeds do not have to specify times for all stops.
-The data in the following table is perfectly valid for a trip.
-
-| `trip_id` | `arrival_time` | `stop_id` | `stop_sequence` | `shape_dist_traveled` |
-| :-------- | :------------- | :-------- | :-------------- | :-------------------- |
-| T1 | 10:00:00 | S1 | 1 | 0 |
-| T1 | | S2 | 2 | 1500 |
-| T1 | | S3 | 3 | 3000 |
-| T1 | 10:12:00 | S4 | 4 | 6000 |
-
-Based on this data, without taking into account the distance traveled,
-you may estimate that the second stop arrives at 10:04 AM while the
-third stop arrives at 10:08.
-
-If you consider the distance traveled, you might conclude the second
-stop arrives at 10:03 AM while the third stop arrives at 10:06 AM.
-
-Some agencies include an additional column in `stop_times.txt` called
-`timepoint`. This is used when they specify the times for all stops
-but also want to indicate if only certain stops are guaranteed times.
-
-The following table shows how this would look using the previous data as
-its basis.
-
-| `trip_id` | `arrival_time` | `stop_id` | `stop_sequence` | `shape_dist_traveled` | `timepoint` |
-| :--------- | :------------- | :-------- | :-------------- | :-------------------- | :---------- |
-| T1 | 10:00:00 | S1 | 1 | 0 | 1 |
-| T1 | 10:03:00 | S2 | 2 | 1500 | 0 |
-| T1 | 10:06:00 | S3 | 3 | 3000 | 0 |
-| T1 | 10:12:00 | S4 | 4 | 6000 | 1 |
-
-This can be especially useful if you want to highlight these time points
-so as to represent the printed schedules accurately, or even if you are
-a transit agency just using the data for internal reporting.
-
diff --git a/.idea/gtfs-book/ch-07-calendar.md b/.idea/gtfs-book/ch-07-calendar.md
deleted file mode 100644
index aebf131..0000000
--- a/.idea/gtfs-book/ch-07-calendar.md
+++ /dev/null
@@ -1,138 +0,0 @@
-## 7. Trip Schedules (calendar.txt & calendar_dates.txt)
-
-*Each of these files are ***optional*** in a GTFS feed, but at least one
-of them is ***required***.*
-
-The `calendar.txt` file is used to indicate the range of dates on
-which trips are running. It works by including a start date and a finish
-date (typically a range of 3-6 months), then a marker for each day of
-the week on which it operates. If there are single-day scheduling
-changes that occur during this period, then the `calendar_dates.txt`
-file can be used to override the schedule for each of these days.
-
-The following table shows the specification for `calendar.txt`.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `service_id` | Required | A unique ID for a single service. This value is referenced by trips in `trips.txt`. |
-| `start_date` | Required | This indicates the start date for a given service, in `YYYYMMDD` format. |
-| `end_date` | Required | This indicates the end date for a given service, in `YYYYMMDD` format. |
-| `monday` | Required | Contains `1` if trips run on Mondays between the start and end dates, `0` or empty if not. |
-| `tuesday` | Required | Contains `1` if trips run on Tuesdays between the start and end dates, `0` or empty if not. |
-| `wednesday` | Required | Contains `1` if trips run on Wednesdays between the start and end dates, `0` or empty if not. |
-| `thursday` | Required | Contains `1` if trips run on Thursdays between the start and end dates, `0` or empty if not. |
-| `friday` | Required | Contains `1` if trips run on Fridays between the start and end dates, `0` or empty if not. |
-| `saturday` | Required | Contains `1` if trips run on Saturdays between the start and end dates, `0` or empty if not. |
-| `sunday` | Required | Contains `1` if trips run on Sundays between the start and end dates, `0` or empty if not. |
-
-As mentioned above, the `calendar_dates.txt` file is used to define
-exceptions to entries in `calendar.txt`. For instance, if a 3-month
-service is specified in `calendar.txt` and a holiday lies on a Monday
-during this period, then you can use calendar_dates.txt to override this
-single date.
-
-If the weekend schedule were used for a holiday, then you would add a
-record to remove the regular schedule for the holiday date, and another
-record to add the weekend schedule for the holiday date.
-
-Some feeds choose only to include `calendar_dates.txt` and not
-`calendar.txt`, in which case there is an "add service" record for
-every service and every date in this file.
-
-The following table shows the specification for `calendar_dates.txt`.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `service_id` | Required | The service ID that an exception is being defined for. This is referenced in both `calendar.txt` and in `trips.txt`. Unlike `calendar.txt`, it is possible for a `service_id` value to appear multiple times in this file. |
-| `date` | Required | The date for which the exception is occurring, in `YYYYMMDD` format. |
-| `exception_type` | Required | This indicates whether the exception is denoting an added service (`1`) or a removed service (`2`). |
-
-### Sample Data
-
-The following is an extract from the `calendar.txt` file in Adelaide
-Metro's GTFS feed (<https://openmobilitydata.org/p/adelaide-metro>). This
-extract includes schedules from the start of 2014 until the end of March
-2014.
-
-| `service_id` | `monday` | `tuesday` | `wednesday` | `thursday` | `friday` | `saturday` | `sunday` | `start_date` | `end_date` |
-| :----------- | :------- | :-------- | :---------- | :--------- | :------- | :--------- | :------- | :----------- | :--------- |
-| 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 20140102 | 20140331 |
-| 11 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 20140102 | 20140331 |
-| 12 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 20140102 | 20140331 |
-
-Any trip in the corresponding `trips.txt` file with a `service_id`
-value of `1` runs from Monday to Friday. Trips with a `service_id`
-of `11` run only on Saturday, while those with `12` run only on
-Sunday.
-
-Now consider an extract from `calendar_dates.txt` from the same feed,
-as shown in the following table.
-
-| `service_id` | `date` | `exception_type` |
-| ------------ | -------- | ---------------- |
-| 1 | 20140127 | 2 |
-| 1 | 20140310 | 2 |
-| 12 | 20140127 | 1 |
-| 12 | 20140310 | 1 |
-
-The first two rows mean that on January 27 and March 10 trips with
-`service_id` of `1` are not running. The final two rows mean that on
-those same dates trips with `service_id` of `12` are running. This
-has the following meaning:
-
-**"On 27 January and 10 March, use the Sunday timetable instead of the
-Monday-Friday timetable."**
-
-In Adelaide, these two dates are holidays (Australia Day and Labour
-Day). It is Adelaide Metro's policy to run their Sunday timetable on
-public holidays, which is reflected by the above records in their
-`calendar_dates.txt` file.
-
-### Structuring Services
-
-The case described above is the ideal case for specifying services in a
-GTFS feed (dates primarily specified in `calendar.txt` with a handful
-of exceptions in `calendar_dates.txt`).
-
-Be aware that there are two other major ways that services are specified
-in feeds.
-
-1. Using only `calendar_dates.txt` and expressly including every
- single date within the service range. Each of these is included as
- "service added" (an `exception_type` value of `1`). The
- following table shows how this might look.
-
-| `service_id` | `date` | `exception_type` |
-| :----------- | :------- | :--------------- |
-| 1 | 20140102 | 1 |
-| 1 | 20140103 | 1 |
-| 11 | 20140104 | 1 |
-| 12 | 20140105 | 1 |
-
-2. Not using `calendar_dates.txt`, but creating many records in
- `calendar.txt` instead to span various dates. The following table
- shows how you can represent Monday-Friday from the sample data in
- this fashion.
-
-| `service_id` | `monday` | `tuesday` | `wednesday` | `thursday` | `friday` | `saturday` | `sunday` | `start_date` | `end_date` |
-| :----------- | :------- | :-------- | :---------- | :--------- | :------- | :--------- | :------- | :----------- | :--------- |
-| 1a | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 20140102 | 20140126 |
-| holiday1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 20140127 | 20140127 |
-| 1b | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 20140128 | 20140309 |
-| holiday2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 20140310 | 20140310 |
-| 1c | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 20140311 | 20140331 |
-
-In this example, each holiday has its own row in `calendar.txt` that
-runs for a single day only.
-
-Refer to *Finding Service IDs* to see how to determine
-services that are running for a given day.
-
-### Service Name
-
-There are a number of feeds that specify a column in `calendar.txt`
-called `service_name`. This is used to give a descriptive name to each
-service. For example, the Sedona Roadrunner in Arizona
-(<https://openmobilitydata.org/p/sedona-roadrunner>) has services called
-"Weekday Service", "Weekend Service" and "New Year's Eve Service".
-
diff --git a/.idea/gtfs-book/ch-08-fares.md b/.idea/gtfs-book/ch-08-fares.md
deleted file mode 100644
index 88bcbea..0000000
--- a/.idea/gtfs-book/ch-08-fares.md
+++ /dev/null
@@ -1,115 +0,0 @@
-## 8. Fare Definitions (fare_attributes.txt & fare_rules.txt)
-
-*These files are ***optional*** in a GTFS feed, but any rules specified
-must reference a fare attributes record.*
-
-These two files define the types of fares that exist in a system,
-including their price and transfer information. The attributes of a
-particular fare exist in `fare_attributes.txt`, which has the
-following columns.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `fare_id` | Required | A value that uniquely identifies a fare listed in this file. It must only appear once in this file. |
-| `price` | Required | This field specifies the cost of the fare. For instance, if a trip costs $2 USD, then this value should be either `2.00` or `2`, and the `currency_type` should be `USD`. |
-| `currency_type` | Required | This is the currency code that `price` is specified in, such as USD for United States Dollar. |
-| `payment_method` | Required | This indicates when the fare is to be paid. `0` means it can be paid on board, while `1` means it must be paid before boarding. |
-| `transfers` | Required | The number of transfers that may occur. This must either be empty (unlimited) transfers, or the number of transfers. |
-| `transfer_duration` | Optional | This is the number of seconds a transfer is valid for. |
-
-The following table shows the specification for `fare_rules.txt`,
-which defines the rules used to apply a fare to a particular trip.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `fare_id` | Required | This is the ID of the fare that a rule applies to as it appears in `fare_attributes.txt`. |
-| `route_id` | Optional | The ID of a route as it appears in `routes.txt` for which this rule applies. If there are several routes with the same fare attributes, there may be a row in `fare_rules.txt` for each route. |
-| `origin_id` | Optional | This value corresponds to a `zone_id` value from `stops.txt`. If specified, this means a trip must begin in the given zone in order to qualify for this fare. |
-| `destination_id` | Optional | This value corresponds to a `zone_id` value from `stops.txt`. If specified, this means a trip must begin in the given zone in order to qualify for this fare. |
-| `contains_id` | Optional | This value corresponds to a `zone_id` value from `stops.txt`. If specified, this means a trip must pass through every `contains_id` zone for the given fare (in other words, several rules may need to be checked). |
-
-Note that aside from `fare_id`, all fields are optional in this file.
-This means some very complex rules can be made (especially when
-transfers come into the calculation). The following URL has discussion
-about different rules and some complex fare examples:
-
-<https://code.google.com/p/googletransitdatafeed/wiki/FareExamples>
-
-Refer to *Calculating Fares* for discussion about the
-algorithm for calculating fares for trips both with and without
-transfers.
-
-### Sample Data
-
-The following data is taken from the TriMet GTFS feed
-(<https://openmobilitydata.org/p/trimet>). Firstly, the data from the
-`fare_attributes.txt` file.
-
-| `fare_id` | `price` | `currency` | `payment_method` | `transfers` | `transfer_duration` |
-| :-------- | :------ | :--------- | :--------------- | :---------- | :-------------------|
-| B | 2.5 | USD | 0 | | 7200 |
-| R | 2.5 | USD | 1 | | 7200 |
-| BR | 2.5 | USD | 0 | | 7200 |
-| RB | 2.5 | USD | 1 | | 7200 |
-| SC | 1 | USD | 1 | 0 | |
-| AT | 4 | USD | 1 | 0 | |
-| VT | 0 | USD | 1 | 0 | |
-
-The data from the `fare_rules.txt` file is shown in the following
-table.
-
-| `fare_id` | `route_id` | `origin_id` | `destination_id` | `contains_id` |
-| :-------- | :--------- | :---------- | :--------------- | :------------ |
-| B | | B | | B |
-| R | | R | | R |
-| BR | | B | | B |
-| BR | | B | | R |
-| RB | | R | | B |
-| RB | | R | | R |
-| SC | 193 | | | |
-| SC | 194 | | | |
-| AT | 208 | | | |
-| VT | 250 | | | |
-
-In this sample data, TriMet have named some of their fares the same as
-the zones specified in `stops.txt`. In this particular feed, bus stops
-have a `zone_id` of `B`, while rail stops have `R`.
-
-The fares in this file are as follows:
-
-* Fare `B`. If you start at a bus stop (`zone_id` value of `B`),
- you can buy your ticket on board (`payment_method` of `0`). You
- may transfer an unlimited number (empty transfers value) for 2 hours
- (`transfer_duration` of `7200`). The cost is $2.50 USD.
-* Fare `R`. If you start at a rail stop, you must pre-purchase your
- ticket. You may transfer an unlimited number of times to other rail
- services for up to 2 hours. The cost is $2.50 USD.
-
-The `BR` fare describes a trip that begins on a bus then transfers to
-a rail service (while `RB` is the opposite). This fare is not be
-matched if the passenger does not travel on both, as all `contains_id`
-values must be matched in order to apply a fare.
-
-The other fares (`SC`, `AT` and `VT`) all apply to their
-respective `route_id` values, regardless of start and finish stops.
-Tickets must be pre-purchased, and transfers are not allowed. The `VT`
-fare (which corresponds to TriMet's Vintage Trolley) is free to ride
-since it has a price of `0`.
-
-### Assigning Fares to Agencies
-
-One of the extensions available to `fare_attributes.txt` is to include
-an `agency_id` column. This is to limit a specific fare to only routes
-from the specified agency, in the case where a feed has multiple
-agencies.
-
-This is useful because there may be two agencies in a feed that define
-fares with no specific rules (in other words, the fare applies to all
-trips). If the price differs, then GTFS dictates that the cheapest fare
-is always applied. Using `agency_id` means these fares can be
-differentiated accordingly.
-
-For more information about this extension, refer to the Google Transit
-GTFS Extensions page at
-<https://support.google.com/transitpartners/answer/2450962>.
-
diff --git a/.idea/gtfs-book/ch-09-shapes.md b/.idea/gtfs-book/ch-09-shapes.md
deleted file mode 100644
index bc05636..0000000
--- a/.idea/gtfs-book/ch-09-shapes.md
+++ /dev/null
@@ -1,76 +0,0 @@
-## 9. Trip Shapes (shapes.txt)
-
-*This file is ***optional*** in a GTFS feed.*
-
-Each trip in `trips.txt` can have a shape associated with it. The
-shapes.txt file defines the points that make up an individual shape in
-order to plot a trip on a map. Two or more records in `shapes.txt`
-with the same `shape_id` value define a shape.
-
-The amount of data stored in this file can be quite large. In
-*Optimizing Shapes* there are some strategies to efficiently
-reduce the amount of shape data.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `shape_id` | Required | An ID to uniquely identify a shape. Every point for a shape contains the same value. |
-| `shape_pt_lat` | Required | The latitude for a given point in the range of `-90` to `90`. |
-| `shape_pt_lon` | Required | The longitude for a given point in the range of `-180` to `180`. |
-| `shape_pt_sequence` | Required | A non-negative number that defines the ordering for points in a shape. A value must not be repeated within a single shape. |
-| `shape_dist_traveled` | Optional | This value represents how far along a shape a particular point exists. This is a distance in a unit such as feet or kilometers. This unit must be the same as that used in `stop_times.txt`. |
-
-### Sample Data
-
-The following table shows a portion of a shape from the TriMet GTFS
-feed. It is a portion of the shape that corresponds to the sample data
-in the `stop_times.txt` section.
-
-| `shape_id` | `shape_pt_lat` | `shape_pt_lon` | `shape_pt_sequence` | `shape_dist_traveled` |
-| :--------- | :------------- | :------------- | :------------------ | :-------------------- |
-| 185328 | 45.52291 | -122.677372 | 1 | 0.0 |
-| 185328 | 45.522921 | -122.67737 | 2 | 3.7 |
-| 185328 | 45.522991 | -122.677432 | 3 | 34.0 |
-| 185328 | 45.522992 | -122.677246 | 4 | 81.5 |
-| 185328 | 45.523002 | -122.676567 | 5 | 255.7 |
-| 185328 | 45.523004 | -122.676486 | 6 | 276.4 |
-| 185328 | 45.523007 | -122.676386 | 7 | 302.0 |
-| 185328 | 45.523024 | -122.675386 | 8 | 558.4 |
-| 185328 | 45.522962 | -122.67538 | 9 | 581.0 |
-
-In this sample data, the `shape_dist_traveled` is listed in feet.
-There is no way to specify in a GTFS feed which units are used for this
-column -- it could be feet, miles, meters, kilometers. In actual fact,
-it does not really matter, just as long as the units are the same as in
-`stop_times.txt`.
-
-If you need to present a distance to your users (such as how far you
-need to travel on a bus), you can calculate it instead by adding up the
-distance between each point and formatting it based on the user's
-locale settings.
-
-### Point Sequences
-
-In most GTFS feeds the `shape_pt_sequence` value starts at 1 and
-increments by 1 for every subsequent point. Additionally, points are
-typically listed in order of their sequence.
-
-You should not rely on these two statements though, as this is not a
-requirement of GTFS. Many transit agencies have automated systems that
-export their GTFS from a separate system, which can sometimes result in
-an unpredictable output format.
-
-For instance, a trip that has stop times listed with the sequences `1`, `2`,
-`9`, `18`, `7`, `3` is perfectly valid.
-
-### Distance Travelled
-
-The `shape_dist_traveled` column is used so you can programmatically
-determine how much of a shape to draw when showing a map to users of
-your web site or app. If you use techniques in *Optimizing Shapes*
-to reduce the file size of shape data, then it becomes difficult to
-use this value.
-
-Alternatively, you can calculate portions of shapes by determining which
-point in a shape travels closest to the start and finish points of a
-trip.
-
diff --git a/.idea/gtfs-book/ch-10-frequencies.md b/.idea/gtfs-book/ch-10-frequencies.md
deleted file mode 100644
index 45021ab..0000000
--- a/.idea/gtfs-book/ch-10-frequencies.md
+++ /dev/null
@@ -1,98 +0,0 @@
-## 10. Repeating Trips (frequencies.txt)
-
-*This file is ***optional*** in a GTFS feed.*
-
-In some cases a route may repeat a particular stopping pattern every few
-minutes (picture a subway line that runs every 5 minutes). Rather than
-including entries in `trips.txt` and `stop_times.txt` for every
-single occurrence, you can include the trip once then define rules for
-it to repeat for a period of time.
-
-Having a trip repeat only works in the case where the timing between
-stops remains consistent for all stops. Using `frequencies.txt`, you
-use the relative times between stops alongside a calculated starting
-time for the trip in order to determine the specific stop times.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `trip_id` | Required | The ID of the trip as it appears in `trips.txt` that is being repeated. A single trip can appear multiple times for different time ranges. |
-| `start_time` | Required | The time at which a given trip starts repeating, in `HH:MM:SS` format. |
-| `end_time` | Required | The time at which a given trip stops repeating, in `HH:MM:SS` format. |
-| `headway_secs` | Required | The time in seconds between departures from a given stop during the time range. |
-| `exact_times` | Optional | Whether or not repeating trips should be exactly scheduled. See below for discussion. |
-
-### Sample Data
-
-The following sample data is taken from Société de transport de Montréal
-(STM) in Montreal
-(<https://openmobilitydata.org/p/societe-de-transport-de-montreal>).
-
-| `trip_id` | `start_time` | `end_time` | `headway_secs` |
-| :----------------------- | :----------- | :--------- | :------------- |
-| 13S_13S_F1_1_2_0.26528 | 05:30:00 | 07:25:30 | 630 |
-| 13S_13S_F1_1_6_0.34167 | 07:25:30 | 08:40:10 | 560 |
-| 13S_13S_F1_1_10_0.42500 | 08:40:10 | 12:19:00 | 505 |
-| 13S_13S_F1_1_7_0.58750 | 12:19:00 | 15:00:00 | 460 |
-| 13S_13S_F1_1_11_0.66875 | 15:00:00 | 18:23:00 | 420 |
-| 13S_13S_F1_1_5_0.78889 | 18:23:00 | 21:36:35 | 505 |
-
-Each of the trips listed here have corresponding entries in
-`trips.txt` and `stop_times.txt` (more on that shortly). This data
-can be interpreted as follows.
-
-* The first trip runs every 10m 30s from 5:30am until 7:25am.
-* The second trip runs every 9m 20s from 7:25am until 8:40am, and so on.
-
-The following table shows some of the stop times for the first trip
-(`departure_time` is omitted here for brevity, since it is identical
-to `arrival_time`).
-
-| `trip_id` | `stop_id` | `arrival_time` | `stop_sequence` |
-| :---------------------- | :-------- | :------------- | :-------------- |
-| 13S_13S_F1_1_2_0.26528 | 18 | 06:22:00 | 1 |
-| 13S_13S_F1_1_2_0.26528 | 19 | 06:22:59 | 2 |
-| 13S_13S_F1_1_2_0.26528 | 20 | 06:24:00 | 3 |
-| 13S_13S_F1_1_2_0.26528 | 21 | 06:26:00 | 4 |
-
-As this trip runs to the specified frequency, the specific times do not
-matter. Instead, the differences are used. For the above stop times,
-there is a 59 second gap between the first and second time, a 61 second
-gap between the second and third, and a 120 second gap between the third
-and fourth.
-
-The stop times for the first frequency record (10.5 minutes apart) can
-be calculated as follows.
-
-* `05:30:00`, `05:30:59`, `05:32:00`, `05:34:00`
-* `05:40:30`, `05:41:29`, `05:42:30`, `05:44:30`
-* `05:51:00`, `05:51:59`, `05:53:00`, `05:55:00`
-* ...
-* `07:25:30`, `07:26:29`, `07:27:30`, `07:29:30`
-
-### Specifying Exact Times
-
-In the file definition at the beginning of this chapter there is an
-optional field called `exact_times`. It may not be immediately clear
-what this field means, so to explain it better, consider the frequency
-definitions in the following table.
-
-| `trip_id` | `start_time` | `end_time` | `headway_secs` | `exact_times` |
-| :-------- | :----------- | :--------- | :------------- | :------------ |
-| T1 | 09:00:00 | 10:00:00 | 300 | 0 |
-| T2 | 09:00:00 | 10:00:00 | 300 | 1 |
-
-These two frequencies are the same, with only the `exact_times` value
-different. The first (`T1`) should be presented in a manner such as:
-
-**"Between 9 AM and 10 AM this trip departs every 5 minutes."**
-
-The second trip (`T2`) should be presented as follows:
-
-**"This trip departs at 9 AM, 9:05 AM, 9:10 AM, ..."**
-
-While ultimately the meaning is the same, this difference is used in
-order to allow agencies to represent their schedules more accurately.
-Often, schedules that convey to passengers that they will not have to
-wait more than five minutes do so without having to explicitly list
-every departure time.
-
diff --git a/.idea/gtfs-book/ch-11-stop-transfers.md b/.idea/gtfs-book/ch-11-stop-transfers.md
deleted file mode 100644
index 6a43674..0000000
--- a/.idea/gtfs-book/ch-11-stop-transfers.md
+++ /dev/null
@@ -1,65 +0,0 @@
-## 11. Stop Transfers (transfers.txt)
-
-*This file is ***optional*** in a GTFS feed.*
-
-To define how passengers can transfer between routes at specific stops
-feed providers can include `transfers.txt`. This does not mean
-passengers cannot transfer elsewhere, but it does indicate if a transfer
-is not possible between certain stops, or a minimum time required if
-transfer is possible.
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `from_stop_id` | Required | The ID of stop as it appears in `stops.txt` where the connection begins. If this references a station, then this rule applies to all stops within the station. |
-| `to_stop_id` | Required | The ID of the stop as it appears in `stops.txt` where the connection between trips ends. If this references a station, then this rule applies to all stops within the station. |
-| `transfer_type` | Required | `0` or blank means the recommended transfer point, `1` means the secondary vehicle will wait for the first, `2` means a minimum amount of time is required, `3` means transfer is not possible. |
-| `min_transfer_time` | Optional | If the `transfer_type` value is `2` then this value must be specified. It indicates the number of seconds required to transfer between the given stops. |
-
-It is also possible that records in this file are specified for
-ticketing reasons. For instance, some train stations are set up so that
-passengers can transfer between routes without needing to validate their
-ticket again or buy a transfer. Other stations that are shared between
-those same routes might not have this open transfer area, thereby
-requiring you to exit one route fully before buying another ticket to
-access the second.
-
-### Sample Data
-
-The following table shows some sample transfer rules from TriMet in
-Portland's GTFS feed (<https://openmobilitydata.org/p/trimet>).
-
-| `from_stop_id` | `to_stop_id` | `transfer_type` | `min_transfer_time` |
-| :------------- | :----------- | :-------------- | :------------------ |
-| 7807 | 5020 | 0 | |
-| 7807 | 7634 | 0 | |
-| 7807 | 7640 | 0 | |
-
-These rules indicate that if you are transferring from a route that
-visits stop `7807` to any route that visits the other stops (`5020`,
-`7634` or `7640`), then this is the ideal place to do it.
-
-In other words, if there are other locations along the first route where
-you could transfer to the second route, then those stops should not be
-used. These rules say this is the best place to transfer.
-
-Consider the transfer rule in the following table, taken from the New
-York City Subway GTFS feed (<https://openmobilitydata.org/p/mta/79>).
-
-| `from_stop_id` | `to_stop_id` | `transfer_type` | `min_transfer_time` |
-| :------------- | :----------- | :-------------- | :------------------ |
-| 121 | 121 | 2 | 180 |
-
-In this data, the MTA specifies how long it takes to transfer to
-different platforms within the same station. The stop with ID 121 refers
-to the 86th St station (as specified in `stops.txt`). It has a
-`location_type` of `1` and two stops within it (`121N` and
-`121S`). The above transfer rule says that if you need to transfer
-from `121N` to `121S` (or vice-versa) then a minimum time of 3
-minutes (180 seconds) must be allocated.
-
-If you were to calculate the time taken to transfer using the
-coordinates of each of these platforms, it would only take a few seconds
-as they are physically close to each other. In reality though, you must
-exit one platform then walk around and enter the other platform (often
-having to use stairs).
-
diff --git a/.idea/gtfs-book/ch-12-feed-information.md b/.idea/gtfs-book/ch-12-feed-information.md
deleted file mode 100644
index ffad2ab..0000000
--- a/.idea/gtfs-book/ch-12-feed-information.md
+++ /dev/null
@@ -1,36 +0,0 @@
-## 12. Feed Information (feed_info.txt)
-
-*This file is ***optional*** in a GTFS feed.*
-
-Feed providers can include additional information about a feed using
-`feed_info.txt`. It should only ever have a single row (other than the
-CSV header row).
-
-| Field | Required? | Description |
-| :----- | :-------- | :---------- |
-| `feed_publisher_name` | Required | The name of the organization that publishes the feed. This may or may not be the same as any agency in `agency.txt`. |
-| `feed_publisher_url` | Required | The URL of the feed publisher's web site. |
-| `feed_lang` | Required | This specifies the language used in the feed. If an agency also has a language specified, then the agency's value should override this value. |
-| `feed_start_date` | Optional | This value is a date in `YYYYMMDD` format that asserts the data in this feed is valid from this date. If specified, it typically matches up with the earliest date in `calendar.txt` or `calendar_dates.txt`, but if it is earlier, this is explicitly saying there are no services running between this date and the earliest service date. |
-| `feed_end_date` | Optional | This value is a date in `YYYYMMDD` format that asserts the data in this feed is valid until this date. If specified, it typically matches up with the latest date in `calendar.txt` or `calendar_dates.txt`, but if it is earlier, this is explicitly saying there are no services running between the latest service date and this date. |
-| `feed_version` | Optional | A string that indicates the version of this feed. This can be useful to let feed publishers know whether the latest version of their feed has been incorporated. |
-
-### Sample Data
-
-The following sample data is taken from the GTFS feed of TriMet in
-Portland (<https://openmobilitydata.org/p/trimet>).
-
-| `feed_publisher_name` | `feed_publisher_url` | `feed_lang` | `feed_start_date` | `feed_end_date` | `feed_version` |
-| :-------------------- | :-------------------------------------- | :---------- | :---------------- | :-------------- | :---------------- |
-| TriMet | [http://trimet.org](http://trimet.org/) | en | | | 20140121-20140421 |
-
-In this example, TriMet do not include the start or end dates, meaning
-you should derive the dates this feed is active for by the dates in
-`calendar_dates.txt` (this particular feed does not have a
-`calendar.txt` file).
-
-TriMet use date stamps to indicate the feed version. This feed was
-published on 21 January 2014 and includes data up until 21 April 2014,
-so it appears they use the first/last dates as a way to specify their
-version. Each agency has its own method.
-
diff --git a/.idea/gtfs-book/ch-13-importing-to-sql.md b/.idea/gtfs-book/ch-13-importing-to-sql.md
deleted file mode 100644
index e96517c..0000000
--- a/.idea/gtfs-book/ch-13-importing-to-sql.md
+++ /dev/null
@@ -1,125 +0,0 @@
-## 13. Importing a GTFS Feed to SQL
-
-One of the great things about GTFS is that it is already in a format
-conducive to being used in an SQL database. The presence of various IDs
-in each of the different files makes it easy to join the tables in order
-to extract the data you require.
-
-To try this yourself, download `GtfsToSql`
-(<https://github.com/OpenMobilityData/GtfsToSql>). This is a Java
-command-line application that imports a GTFS feed to an SQLite database.
-This application also supports PostgreSQL, but the examples used here
-are for SQLite.
-
-The pre-compiled `GtfsToSql` Java archive can be downloaded from its
-GitHub repository at
-<https://github.com/OpenMobilityData/GtfsToSql/tree/master/dist>.
-
-To use `GtfsToSql`, all you need is an extracted GTFS feed. The
-following instructions demonstrate how you to import the TriMet feed
-that has been referenced throughout this book.
-
-Firstly, download and extract the feed. The following commands use curl
-to download the file, then unzip to extract the file to a sub-directory
-called `trimet`.
-
-```
-$ curl http://developer.trimet.org/schedule/gtfs.zip > gtfs.zip
-
-$ unzip gtfs.zip -d trimet/
-```
-
-To create an SQLite database from this feed, the following command can
-be used.
-
-```
-$ java -jar GtfsToSql.jar -s jdbc:sqlite:./db.sqlite -g ./trimet
-```
-
-This may take a minute or two to complete (you will see progress as it
-imports the feed and then creates indexes), and at the end you will have
-a GTFS database in a file called `db.sqlite`. You can then query this
-database with the command-line `sqlite3` tool, as shown in the
-following example.
-
-```
-$ sqlite3 db.sqlite
-sqlite> SELECT * FROM agency;
-|TriMet|http://trimet.org|America/Los_Angeles|en|503-238-7433
-
-sqlite> SELECT * FROM routes WHERE route_type = 0;
-90|||MAX Red Line||0|http://trimet.org/schedules/r090.htm||
-100|||MAX Blue Line||0|http://trimet.org/schedules/r100.htm||
-190|||MAX Yellow Line||0|http://trimet.org/schedules/r190.htm||
-193||Portland Streetcar|NS Line||0|http://trimet.org/schedules/r193.htm||
-194||Portland Streetcar|CL Line||0|http://trimet.org/schedules/r194.htm||
-200|||MAX Green Line||0|http://trimet.org/schedules/r200.htm||
-250|||Vintage Trolley||0|http://trimet.org/schedules/r250.htm||
-```
-
-The first query above finds all agencies stored in the database, while
-the second finds all routes marked as Light Rail (`route_type` of
-`0`).
-
-**Note: In the following chapters there are more SQL examples. All of
-these examples are geared towards running on an SQLite database that has
-been created in this manner.**
-
-All tables in this database match up with the corresponding GTFS
-filename (so for `agency.txt`, the table name is `agency`, while for
-`stop_times.txt` the table name is `stop_times`). The columns in SQL
-have the same name as the value in the corresponding GTFS file.
-
-***Note:** All data imported using this tool is stored as text in the
-database. This means you may need to be careful when querying integer
-data. For example, ordering stop times by stop_sequence may not produce
-expected results (for instance, 29 as a string comes before 3). Although
-it is a performance hit, you can change this behavior by casting the
-value to integer, such as: ORDER BY stop_sequence + 0. The reason
-`GtfsToSql` works in this way is because it is intended as a lightweight
-tool to be able to quickly query GTFS data. I recommend rolling your own
-importer to treat data exactly as you need it, especially in conjunction
-with some of the optimization techniques recommended later in this book.*
-
-### File Encodings
-
-The GTFS specification does not indicate whether files should be encoded
-using UTF-8, ISO-8859-1 or otherwise. Since a GTFS feed is not
-necessarily in English, you must be willing to handle an extended
-character set.
-
-The GtfsToSql tool introduced above automatically detects the encoding
-of each file using the juniversalchardet Java library
-(<https://code.google.com/p/juniversalchardet/>).
-
-I recommend you take some time looking at the source code of GtfsToSql
-to further understand this so you are aware of handling encodings
-correctly if you write your own parser.
-
-### Optimizing GTFS Feeds
-
-If you are creating a database that is to be distributed onto a mobile
-device such as an iPhone or Android phone, then disk space and
-computational power is at a premium. Even if you are setting up a
-database to be queried on a server only, then making the database
-perform as quickly as possible is still important.
-
-In the following chapters are techniques for optimizing GTFS feeds.
-There are many techniques that can be applied to improve the performance
-of GTFS, such as:
-
-* Using integer identifiers rather than string identifiers (for route
- IDs, trip IDs, stop IDs, etc.) and creating appropriate indexes
-* Removing redundant shape points and encoding shapes
-* Deleting unused data
-* Reusing repeating trip patterns.
-
-Changing the data to use integer IDs makes the greatest improvement to
-performance, but the other techniques also help significantly.
-
-Depending on your needs, there are other optimizations that can be made
-to reduce file size and speed up querying of the data, but the ease of
-implementing them may depend on your database storage system and the
-programming language used to query the data. The above list is a good
-starting point.
-
diff --git a/.idea/gtfs-book/ch-14-switching-to-integer-ids.md b/.idea/gtfs-book/ch-14-switching-to-integer-ids.md
deleted file mode 100644
index 4d3914a..0000000
--- a/.idea/gtfs-book/ch-14-switching-to-integer-ids.md
+++ /dev/null
@@ -1,111 +0,0 @@
-## 14. Switching to Integer IDs
-
-There are a number of instances in a GTFS feed where IDs are used, such
-as to identify routes, trips, stops and shapes. There are no specific
-guidelines in GTFS as to the type of data or length an ID can be. As
-such, IDs in some GTFS feeds maybe anywhere up to 30 or 40 characters
-long.
-
-Using long strings as IDs is extremely inefficient as they make the size
-of a database much larger than it needs to be, as well as making
-querying the data much slower.
-
-To demonstrate, consider a GTFS feed where trip IDs are 30 characters
-long. If there are 10,000 trips, each with an average of 30 stops in
-`stop_times.txt`, then the IDs alone take up 9.3 MB of storage.
-Realistically speaking, you need to index the `trip_id` field in order
-to look up a trip's stop times quickly, which uses even more space.
-
-The following SQL statements show how you might represent GTFS without
-optimizing the identifiers. For brevity, not all fields from the GTFS
-feed are included here.
-
-```sql
-CREATE TABLE trips (
- trip_id TEXT,
- route_id TEXT,
- service_id TEXT
-);
-
-CREATE INDEX trips_trip_id ON trips (trip_id);
-
-CREATE INDEX trips_route_id ON trips (route_id);
-
-CREATE INDEX trips_service_id ON trips (service_id);
-
-CREATE TABLE stop_times (
- trip_id TEXT,
- stop_id TEXT,
- stop_sequence INTEGER
-);
-
-CREATE INDEX stop_times_trip_id ON stop_times (trip_id);
-
-CREATE INDEX stop_times_stop_id on stop_times (stop_id);
-```
-
-If you were to add an integer column to `trips` called, say,
-`trip_index`, then you can reference that value from `stop_times`
-instead of `trip_id`. The following SQL statements show this.
-
-```sql
-CREATE TABLE trips (
- trip_id TEXT,
- trip_index INTEGER,
- route_id TEXT,
- service_id TEXT
-);
-
-CREATE INDEX trips_trip_id ON trips (trip_id);
-CREATE INDEX trips_trip_index ON trips (trip_index);
-CREATE INDEX trips_route_id ON trips (route_id);
-CREATE INDEX trips_service_id ON trips (service_id);
-
-CREATE TABLE stop_times (
- trip_index INTEGER,
- stop_id TEXT,
- stop_sequence INTEGER
-);
-
-CREATE INDEX stop_times_trip_index ON stop_times (trip_index);
-
-CREATE INDEX stop_times_stop_id on stop_times (stop_id);
-```
-
-This results in a significant space saving (when you consider how large
-`stop_times` can be), as well as being far quicker to look up stop
-times based on a trip ID. Note that the original `trip_id` value is
-retained so it can be referenced if required.
-
-Without adding `trip_index`, you would use the following query to find
-stop times given a trip ID.
-
-```sql
-SELECT * FROM stop_times
- WHERE trip_id = 'SOME_LONG_TRIP_ID'
- ORDER BY stop_sequence;
-```
-
-With the addition of `trip_index`, you need to first find the record
-in `trips`. This can be achieved using the following query. This is a
-small sacrifice compared to performing string comparison on all stop
-times.
-
-```sql
-SELECT * FROM stop_times
- WHERE trip_index = (
- SELECT trip_index FROM trips WHERE trip_id = 'SOME_LONG_TRIP_ID'
- )
- ORDER BY stop_sequence;
-```
-
-You can make the same change for the other IDs in the feed, such as
-`route_id` and `stop_id`. For these columns you still keep (and
-index) the original values in `routes` and `stops` respectively,
-since you may still need to look up records based on these values.
-
-***Note:** Even though this book recommends optimizing feeds in this
-manner, the remainder of examples in this book only use their original
-IDs, in order to simplify the examples and to ensure compatibility with
-the `GtfsToSql` tool introduced previously.*
-
diff --git a/.idea/gtfs-book/ch-15-optimizing-shapes.md b/.idea/gtfs-book/ch-15-optimizing-shapes.md
deleted file mode 100644
index fbb1125..0000000
--- a/.idea/gtfs-book/ch-15-optimizing-shapes.md
+++ /dev/null
@@ -1,158 +0,0 @@
-## 15. Optimizing Shapes
-
-Shape data in a GTFS feed (that is, the records from `shapes.txt`)
-represents a large amount of data. There are a number of ways to reduce
-this data, which can help to:
-
-* Speed up data retrieval
-* Reduce the amount of data to transmit to app / web site users
-* Speed up rendering of the shape onto a map (such as a native mobile
- map or a JavaScript map).
-
-Two ways to reduce shape data are as follows:
-
-* **Reducing the number of points in a shape.** The shapes included in
- GTFS are often very precise and include a number of redundant
- points. Many of these can be removed without a noticeable loss of
- shape quality using the *Douglas-Peucker Algorithm*.
-* **Encoding all points in a shape into a single value.** The *Encoded
- Polyline Algorithm* used in the Google Maps JavaScript API can also
- be used with GTFS shapes. This reduces the amount of storage
- required and also makes looking up all points in a shape far
- quicker.
-
-### Reducing Points in a Shape
-
-Many of the shapes you find in GTFS feeds are extremely detailed. They
-often follow the exact curvature of the road and may consist of hundreds
-or thousands of points for a trip that might have only 30 or 40 stops.
-
-While this level of detail is useful, the sheer amount of data required
-to be rendered on a map can be a massive performance hit from the
-perspective of retrieving the data as well as rendering on a map.
-Realistically, shapes do not need this much detail in order to convey
-their message to your users.
-
-Consider the following shape from Portland that has been rendered using
-Google Maps. The total shape consists of 1913 points.
-
-![Original Shape](images/shape-original.jpg)
-
-Compare this now to the same shape that has had redundant points
-removed. The total number of points in this shape is 175, which
-represents about a 90% reduction.
-
-![Reduced Shape](images/shape-reduced.jpg)
-
-If you look closely, you can see some minor loss of detail, but for the
-most part, the shapes are almost identical.
-
-This reduction in points can be achieved using the Douglas-Peucker
-Algorithm. It does so by discarding points that do not deviate
-significantly between its surrounding points.
-
-The Douglas-Peucker Algorithm works as follows:
-
-* Begin with the first and last points in the path (A and B). These
- are always kept.
-* Find the point between the first and last that is furthest away from
- the line joining the first and last line (the orthogonal distance --
- see the figure below).
-* If this point is greater than the allowed distance (the tolerance
- level), the point is kept (call it X).
-* Repeat this algorithm twice: once using A as the first point and X
- as the last point, then again using X as the first point and B as
- the last point.
-
-This algorithm is recursive, and continues until all points have been
-checked.
-
-***Note:** The tolerance level determines how aggressively points are
-removed. A higher tolerance value is less aggressive and discards less
-data, while a lower tolerance discards more data.*
-
-The following diagram shows what orthogonal distance means.
-
-![Orthogonal Distance](images/orthogonal-distance.jpg)
-
-The following resources provide more information about the
-Douglas-Peucker Algorithm and describe how to implement it in your own
-systems:
-
-* <http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm>
-* <http://www.loughrigg.org/rdp/>
-* <http://stackoverflow.com/questions/2573997/reduce-number-of-points-in-line>.
-
-You can often discard about 80-90% of all shape data before seeing a
-significant loss of line detail.
-
-### Encoding Shape Points
-
-A single entry in `shapes.txt` corresponds to a single point in a
-single shape. Each entry includes a shape ID, a latitude and longitude.
-
-***Note:** The `shape_dist_traveled` field is also included, but you do not
-strictly need to use this field (nor the corresponding field in
-stop_times.txt). The technique described in this section will not work
-if you intend to use `shape_dist_traveled`.*
-
-This means if you want to look up a shape by its ID, you may need to
-retrieve several hundreds of rows from a database. Using the Encoded
-Polyline Algorithm you can change your GTFS database so each shape is
-represented by a single row in a database. This means the shape can be
-found much more quickly and much less data needs to be processed to
-determine the shape.
-
-Consider the following data, taken from TriMet's `shapes.txt` file.
-This data represents the first five points of a shape.
-
-| `shape_id` | `shape_pt_lat` | `shape_pt_lon` | `shape_pt_sequence` | `shape_dist_traveled` |
-| :--------- | :------------- | :------------- | :------------------- | :--------------------- |
-| `185328` | `45.52291 ` | `-122.677372` | `1` | `0.0` |
-| `185328` | `45.522921` | `-122.67737` | `2` | `3.7` |
-| `185328` | `45.522991` | `-122.677432` | `3` | `34.0` |
-| `185328` | `45.522992` | `-122.677246` | `4` | `81.5` |
-| `185328` | `45.523002` | `-122.676567` | `5` | `255.7` |
-
-If you apply the Encoded Polyline Algorithm to this data, the
-coordinates can be represented using the following string.
-
-```
-eeztGrlwkVAAML?e@AgC
-```
-
-To learn how to arrive at this value, you can read up on the Encoded
-Polyline Algorithm at
-<https://developers.google.com/maps/documentation/utilities/polylinealgorithm>.
-
-Instead of having every single shape point in a single table, you can
-create a table that has one record per shape. The following SQL
-statement is a way you could achieve this.
-
-```sql
-CREATE TABLE shapes (
- shape_id TEXT,
- encoded_shape TEXT
-);
-```
-
-The following table shows how this data could be represented in a
-database.
-
-| `shape_id` | `encoded_shape` |
-| :--------- | :--------------------- |
-| `185328` | `eeztGrlwkVAAML?e@AgC` |
-
-Storing the shape in this manner means you can retrieve an entire shape
-by looking up only one database row and running it through your decoder.
-
-To further demonstrate how both the encoding and decoding works, try out
-the polyline utility at
-<https://developers.google.com/maps/documentation/utilities/polylineutility>.
-
-You can find implementations for encoding and decoding points for
-various languages at the following locations:
-
-* <http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/>
-* <https://github.com/emcconville/google-map-polyline-encoding-tool>
-
diff --git a/.idea/gtfs-book/ch-16-deleting-unused-data.md b/.idea/gtfs-book/ch-16-deleting-unused-data.md
deleted file mode 100644
index f2a2fc0..0000000
--- a/.idea/gtfs-book/ch-16-deleting-unused-data.md
+++ /dev/null
@@ -1,106 +0,0 @@
-## 16. Deleting Unused Data**
-
-Once you have imported a GTFS feed into a database, it is possible for
-there to be a lot of redundant data. This can ultimately slow down any
-querying of that data as well as bloating the size of the database. If
-you are making an app where the GTFS database is queried on the device
-then disk space and computational time are at a premium, so you must do
-what you can to reduce resource usage.
-
-The first thing to check for is expired services. You can do this by
-searching `calendar.txt` for entries that expire before today's date.
-Be aware though, you also need to ensure there are no
-`calendar_dates.txt` entries overriding these services (a service
-could have an `end_date` of, say, `20140110`, but also have a
-`calendar_dates.txt` entry for `20140131`).
-
-Firstly, find service IDs in `calendar_dates.txt` that are still
-active using the following query.
-
-```sql
-SELECT service_id FROM calendar_dates WHERE date >= '20140110';
-```
-
-***Note:** In order to improve performance of searching for dates, you
-should import the date field in `calendar_dates.txt` as an integer, as
-well as `start_date` and `end_date` in `calendar.txt`.*
-
-Any services matched in this query should not be removed. You can then
-find service IDs in `calendar.txt` with the following SQL query.
-
-```sql
-SELECT * FROM calendar WHERE end_date < '20140110'
- AND service_id NOT IN (
- SELECT service_id FROM calendar_dates WHERE date >= '20140110'
- );
-```
-
-Before deleting these services, corresponding trips and stop times must
-be removed since you need to know the service ID in order to delete a
-trip. Likewise, stop times must be deleted before trips since you need
-to know the trip IDs to be removed.
-
-```sql
-DELETE FROM stop_times WHERE trip_id IN (
- SELECT trip_id FROM trips WHERE service_id IN (
- SELECT service_id FROM calendar WHERE end_date < '20140110'
- AND service_id NOT IN (
- SELECT service_id FROM calendar_dates WHERE date >= '20140110'
- )
- )
- );
-```
-
-Now there may be a series of trips with no stop times. Rather than
-repeating the above sub-queries, a more thorough way of removing trips
-is to remove trips with no stop times.
-
-```sql
-DELETE FROM trips WHERE trip_id NOT IN (
- SELECT DISTINCT trip_id FROM stop_times
-);
-```
-
-With all `service_id` references removed, you can remove the expired
-rows from `calendar.txt` using the following SQL query.
-
-```sql
-DELETE FROM calendar WHERE end_date < '20140110'
- AND service_id NOT IN (
- SELECT DISTINCT service_id FROM calendar_dates WHERE date >= '20140110'
- );
-```
-
-The expired rows in `calendar_dates.txt` can also be removed, which
-can be achieved using the following query.
-
-```sql
-DELETE FROM calendar_dates WHERE date < '20140110';
-```
-
-There may now be some stops that are not used by any trips. These can be
-removed using the following query.
-
-```sql
-DELETE FROM stops WHERE stop_id NOT IN (
- SELECT DISTINCT stop_id FROM stop_times
-);
-```
-
-Additionally, you can remove unused shapes and routes using the
-following queries.
-
-```sql
-DELETE FROM shapes WHERE shape_id NOT IN (
- SELECT DISTINCT shape_id FROM trips
-);
-
-DELETE FROM routes WHERE route_id NOT IN (
- SELECT DISTINCT route_id FROM trips
-);
-```
-
-There are other potential rows that can be removed (such as records in
-`transfers.txt` that reference non-existent stops), but hopefully you
-get the idea from the previous queries.
-
diff --git a/.idea/gtfs-book/ch-17-searching-for-trips.md b/.idea/gtfs-book/ch-17-searching-for-trips.md
deleted file mode 100644
index dd0a901..0000000
--- a/.idea/gtfs-book/ch-17-searching-for-trips.md
+++ /dev/null
@@ -1,346 +0,0 @@
-## 17. Searching for Trips**
-
-This section shows you how to search for trips in a GTFS feed based on
-specified times and stops.
-
-The three scenarios covered are:
-
-* Finding all stops departing from a given stop after a certain time
-* Finding all stops arriving at a given stop before a certain time
-* Finding all trips between two stops after a given time
-
-The first and second scenarios are the simplest, because they only rely
-on a single end of each trip. The third scenario is more complex because
-you have to ensure that each trip returned visits both the start and
-finish stops.
-
-When searching for trips, the first thing you need to know is which
-services are running for the given search time.
-
-### Finding Service IDs
-
-The first step in searching for trips is to determine which services are
-running. To begin with, you need to find service IDs for a given date.
-You then need to handle exceptions accordingly. That is, you need to add
-service IDs and remove service IDs based on the rules in
-`calendar_dates.txt`.
-
-***Note:** In *Scheduling Past Midnight*, you were shown how
-GTFS works with times past midnight. The key takeaway from this is that
-you have to search for trips for two sets of service IDs. This is
-covered as this chapter progresses.*
-
-In Australia, 27 January 2014 (Monday) was the holiday for Australia
-Day. This is used as an example to demonstrate how to retrieve service
-IDs.
-
-Firstly, you need the main set of service IDs for the day. The following
-SQL query achieves this.
-
-```sql
-SELECT service_id FROM calendar
- WHERE start_date <= '20140127' AND end_date >= '20140127'
- AND monday = 1;
-
-# Result: 1, 2, 6, 9, 18, 871, 7501
-```
-
-Next you need to find service IDs that are to be excluded, as achieved
-by the following SQL query.
-
-```sql
-SELECT service_id FROM calendar_dates
- WHERE date = '20140127' AND exception_type = 2;
-
-# Result: 1, 2, 6, 9, 18, 871, 7501
-```
-
-Finally, you need to find service IDs that are to be added. This query
-is identical to the previous query, except for the different
-`exception_type` value.
-
-```sql
-SELECT service_id FROM calendar_dates
- WHERE date = '20140127' AND exception_type = 1;
-
-# Result: 12, 874, 4303, 7003
-```
-
-You can combine these three queries all into a single query in SQLite
-using `EXCEPT` and `UNION`, as shown in the following SQL query.
-
-```sql
-SELECT service_id FROM calendar
- WHERE start_date <= '20140127' AND end_date >= '20140127'
- AND monday = 1
-
-UNION
-
-SELECT service_id FROM calendar_dates
- WHERE date = '20140127' AND exception_type = 1
-
-EXCEPT
-
-SELECT service_id FROM calendar_dates
- WHERE date = '20140127' AND exception_type = 2;
-
-# Result: 12, 874, 4304, 7003
-```
-
-Now when you search for trips, only trips that have a matching
-`service_id` value are included.
-
-### Finding Trips Departing a Given Stop
-
-In order to determine the list of services above, a base timestamp on
-which to search is needed. For the purposes of this example, assume that
-timestamp is 27 January 2014 at 1 PM (`13:00:00` when using GTFS).
-
-This example searches for all services departing from Adelaide Railway
-Station, which has stop ID `6665` in the Adelaide Metro GTFS feed. To
-find all matching stop times, the following query can be performed.
-
-```sql
-SELECT * FROM stop_times
- WHERE stop_id = '6665'
- AND departure_time >= '13:00:00'
- AND pickup_type = 0
- ORDER BY departure_time;
-```
-
-This returns a series of stop times that match the given criteria. The
-only problem is it does not yet take into account valid service IDs.
-
-***Note:** This query may also return stop times that are the final stop
-on a trip, which is not useful for somebody trying to find departures.
-You may want to modify your database importer to override the final stop
-time of each trip so its `pickup_type` has a value of `1` (no pick-up) and
-its first stop time so it has a `drop_off_type` of `1` (no drop-off).*
-
-To make sure only the correct trips are returned, join `stop_times`
-with `trips` using `trip_id`, and then include the list of service
-IDs. For the purposes of this example the service IDs, stop ID and
-departure time are being hard-coded. You can either embed a sub-query,
-or include the service IDs via code.
-
-```sql
-SELECT t.*, st.* FROM stop_times st, trips t
- WHERE st.stop_id = '6665'
- AND st.trip_id = t.trip_id
- AND t.service_id IN ('12', '874', '4304', '7003')
- AND st.departure_time >= '13:00:00'
- AND st.pickup_type = 0
- ORDER BY st.departure_time;
-```
-
-This gives you the final list of stop times matching the desired
-criteria. You can then decide specifically which data you need to
-retrieve; you now have the `trip_id`, meaning you can find all stop
-times for a given trip if required.
-
-If you need to restrict the results to only those that occur after the
-starting stop, you can retrieve stop times with only a `stop_sequence`
-larger than that of the stop time returned in the above query.
-
-### Finding Trips Arriving at a Given Stop
-
-In order to find the trips arriving at a given stop before a specified
-time, it is just a matter of making slight modifications to the above
-query. Firstly, check the `arrival_time` instead of
-`departure_time`. Also, check the `drop_off_type` value instead of
-`pickup_type`.
-
-```sql
-SELECT t.*, st.* FROM stop_times st, trips t
- WHERE st.stop_id = '6665'
- AND st.trip_id = t.trip_id
- AND t.service_id IN ('12', '874', '4304', '7003')
- AND st.arrival_time <= '13:00:00'
- AND st.drop_off_type = 0
- ORDER BY st.arrival_time DESC;
-```
-
-For this particular data set, there are trips from four different routes
-returned. If you want to restrict this to a particular route, you can
-filter on the `t.route_id` value.
-
-```sql
-SELECT t.*, st.* FROM stop_times st, trips t
- WHERE st.stop_id = '6665'
- AND st.trip_id = t.trip_id
- AND t.service_id IN ('12', '874', '4304', '7003')
- AND t.route_id = 'BEL'
- AND st.arrival_time <= '13:00:00'
- AND st.drop_off_type = 0
- ORDER BY st.arrival_time DESC;
-```
-
-### Performance of Searching Text-Based Times
-
-These examples search using text-based arrival/departure times (such as
-`13:00:00`). This works because the GTFS specification mandates that
-all times are `HH:MM:SS` format (although `H:MM:SS` is allowed for times
-earlier than 10 AM).
-
-Doing this kind of comparison (especially if you are scanning millions
-of rows) is quite slow and expensive. It is more efficient to convert
-all times stored in the database to integers that represent the number
-of seconds since midnight.
-
-***Note:** The GTFS specification states that arrival and departure times
-are "noon minus 12 hours" in order to account for daylight savings time.
-This is effectively midnight, except for the days that daylight savings
-starts or finishes.*
-
-In order to achieve this, you can convert the text-based time to an
-integer with `H * 3600 + M * 60 + S`. For example, `13:35:21` can
-be converted using the following steps.
-
-```
- (13 * 3600) + (35 * 60) + (21)
-= 46800 + 2100 + 21
-= 48921
-```
-
-You can then convert back to hours, minutes and seconds in order to
-generate timestamps in your application as shown in the following
-algorithm.
-
-```
-H = floor( 48921 / 3600 )
- = floor( 13.59 )
- = 13
-
-M = floor( 48921 / 60 ) % 60
- = floor( 815.35 ) % 60
- = 815 % 60
- = 35
-
-S = 48921 % 60
- = 21
-```
-
-### Finding Trips Between Two Stops
-
-Now that you know how to look up a trip from or to a given stop, the
-previous query can be expanded so both the start and finish stop are
-specified. The following example finds trips that depart after 1 PM. The
-search only returns trips departing from *Adelaide Railway Station*
-(stop ID `6665`) are shown. Additionally, only trips that then visit
-*Blackwood Railway Station* (stop IDs `6670` and `101484`) are
-included.
-
-In order to achieve this, the following changes must be made to the
-previous examples.
-
-* **Join against stop_times twice.** Once for the departure stop time
- and once for the arrival stop time.
-* **Allow for multiple stop IDs at one end.** The destination in this
- example has two platforms, so you need to check both of them.
-* **Ensure the departure time is earlier than the arrival time.
- **Otherwise trips heading in the opposite direction may also be
- returned.
-
-The following query demonstrates how this is achieved.
-
-```sql
-SELECT t.*, st1.*, st2.*
- FROM trips t, stop_times st1, stop_times st2
- WHERE st1.trip_id = t.trip_id
- AND st2.trip_id = t.trip_id
- AND st1.stop_id = '6665'
- AND st2.stop_id IN ('6670', '101484')
- AND t.service_id IN ('12', '874', '4304', '7003')
- AND st1.departure_time >= '13:00:00'
- AND st1.pickup_type = 0
- AND st2.drop_off_type = 0
- AND st1.departure_time < st2.arrival_time
- ORDER BY st1.departure_time;
-```
-
-In this example, the table alias `st1` is used for the departure stop
-time. Once again, the stop ID must match, as well as the departure time
-and pick-up type.
-
-For the arrival stop time the alias `st2` is used. This table also
-joins the `trips` table using `trip_id`. Since the destination has
-multiple stop IDs, the SQL `IN` construct is used. The arrival time is
-not important in this example, so only the departure is checked.
-
-The final thing to check is that the departure occurs before the
-arrival. If you do not perform this step, then trips traveling in the
-opposite direction may also be returned.
-
-***Note:** Technically, there may be multiple results returned for the
-same trip. For some transit agencies, a single trip may visit the a stop
-more than once. If this is the case, you should also check the trip
-duration (arrival time minus departure time) and use the shortest trip
-when the same trip is returned multiple times.*
-
-### Accounting for Midnight
-
-As discussed previously, GTFS has the ability for the trips to depart or
-arrive after midnight for a given service day without having to specify
-it as part of the next service day. Consequently, while the queries
-above are correct, they do not necessarily paint the full picture.
-
-In reality, when performing a trip search, you need to take into account
-trips that have wrapped times (for instance, where 12:30 AM is specified
-as `24:30:00`). If you want to find trips that depart after 12:30 AM
-on a given day, you need to check for trips departing after
-`00:30:00` on that day, as well as for trips departing at
-`24:30:00` on the previous day.
-
-This means that for each trip search you are left with two sets of
-trips, which you must then merge and present as appropriate.
-
-***Note:** In reality, agencies generally do not have trips that overlap
-from multiple service days, so technically you often only need one query
-(for example, a train service might end on 12:30 AM then restart on the
-next service day at 4:30 AM). If your app / web site only uses a single
-feed where you can tune your queries manually based on how the agency
-operates, then you can get away with only querying a single service day.
-On the other hand, if you are building a scalable system that works with
-data from many agencies, then you need to check both days.*
-
-To demonstrate how this works in practice, the following example
-searches for all trips that depart after 12:30:00 AM on 14 March 2014.
-The examples earlier in this chapter showed how to find the service IDs
-for a given date. To account for midnight, service IDs for both March 14
-(the "main" service date) and March 13 (the overlapping date) need to be
-determined.
-
-Assume that March 13 has a service ID of `C1` and March 14 has a
-service ID of `C2`. First you need to find the departures for March
-14, as shown in the following query.
-
-```sql
-SELECT t.*, st.* FROM stop_times st, trips t
- WHERE st.stop_id = 'S1'
- AND st.trip_id = t.trip_id
- AND t.service_id IN ('C1')
- AND st.departure_time >= '00:30:00'
- AND st.pickup_type = 0
- ORDER BY st.departure_time;
-```
-
-The resultant list needs to be combined with the trips that depart after
-midnight from the March 13 service. To check this, it is just a matter
-of swapping in the right service IDs, then adding 24 hours to the search
-time.
-
-```sql
-SELECT t.*, st.* FROM stop_times st, trips t
- WHERE st.stop_id = 'S1'
- AND st.trip_id = t.trip_id
- AND t.service_id IN ('C2')
- AND st.departure_time >= '24:30:00'
- AND st.pickup_type = 0
- ORDER BY st.departure_time;
-```
-
-In order to get your final list of trips you must combine the results
-from both of these queries. If you are generating complete timestamps in
-order to present the options to your users, just remember to account for
-the results from the second query being 24 hours later.
-
diff --git a/.idea/gtfs-book/ch-18-working-with-trip-blocks.md b/.idea/gtfs-book/ch-18-working-with-trip-blocks.md
deleted file mode 100644
index d59b2c4..0000000
--- a/.idea/gtfs-book/ch-18-working-with-trip-blocks.md
+++ /dev/null
@@ -1,109 +0,0 @@
-## 18. Working With Trip Blocks**
-
-One of the more complex aspects of GTFS is how to properly use the
-`block_id` field in `trips.txt`. The concept is simple, but
-incorporating this information in a manner that is simple to understand
-for a passenger can be more difficult.
-
-A single vehicle (such as a bus or train) completes multiple trips in a
-single service day. For instance, once a bus completes its trip (Trip X)
-from Location A to Location B, it then begins another trip (Trip Y) from
-Location B to Location C. It then completes a final trip (Trip Z) from
-Location C back to Location A.
-
-If a passenger boards in the middle of Trip X and is allowed to stay on
-the bus until the end of the Trip Y, then this should be represented in
-GTFS by giving Trips X, Y, Z the same `block_id` value.
-
-The following diagram shows a vehicle that performs two trips,
-completing opposite directions of the same route. Often a single vehicle
-will do many more than just two trips in a day.
-
-![Block](images/block-01.png)
-
-***Note:** When trips in a block are represented in stop_times.txt, the
-final stop of a trip and the first stop of the subsequent trip must both
-be included, even though they are typically at the same stop (and often
-the same arrival & departure time). The final stop of the first trip is
-drop-off only, while the first stop of the next trip is pick-up only.*
-
-In the following diagram, the vehicle completes three trips, each for
-separate routes. As in the previous diagram, the vehicle will likely
-complete more trips over a single day.
-
-![Block](images/block-02.png)
-
-These two diagrams show the difficulties that can arise when trying to
-calculate trips across multiple blocks. The first diagram is repeated
-below, this time with stops marked so trips between two locations can be
-found.
-
-![Block](images/block-03.png)
-
-Consider the scenario where you want to retrieve all trip times from
-Stop S2 to Stop S1. Since the vehicle gets to Stop S3 then turns around
-and heads back to S1, the trip search returns two options:
-
-1. Board at S2 on the upper trip, travel via S3, then get to S1.
-2. Board at S2 on the lower trip, travel directly to S1.
-
-The second option is a subset of the first option, which means it is a
-far shorter trip (plus it avoids the passenger getting annoyed from
-passing their starting point again). To determine which option to use,
-you can use the trip duration.
-
-Now consider the other type of block formation, where a vehicle
-completes subsequent trips from different routes.
-
-![Block](images/block-04.png)
-
-If a passenger wants to travel from Stop S2 to S4, you will not get the
-situation where the vehicle travels past the same location twice.
-However, it is also possible for a passenger to travel from Stop S2 to
-Stop S6 without ever having to change vehicles.
-
-Referring back to the previous chapter about performing trip searches,
-it is relatively straightforward to account for blocks in these
-searches. Using the query to find trips between two stops as a
-reference, the following changes need to be made:
-
-* Instead of joining both occurrences of `stop_times` to the
- `trips` table, you now need two occurrences of `trips`.
-* Each `stop_times` table occurrence is joined to a separate
- `trips` table occurrence.
-* The two occurrences of `trips` are joined on the `block_id`
- value (if it is available).
-
-The following query shows how to find trips that start at stop `S2`
-and finish at stop `S4`, departing after 1 PM on the day with service
-ID `C1`.
-
-```sql
-SELECT t1.*, t2.*, st1.*, st2.*
- FROM trips t1, trips t2, stop_times st1, stop_times st2
- WHERE st1.trip_id = t1.trip_id
- AND st2.trip_id = t2.trip_id
- AND st1.stop_id = 'S2'
- AND st2.stop_id = 'S4'
- AND t1.service_id = 'C1'
- AND (
- t1.trip_id = t2.trip_id
- OR (
- LENGTH(t1.block_id) > 0 AND t1.block_id = t2.block_id
- )
- )
- AND st1.departure_time >= '13:00:00'
- AND st1.pickup_type = 0
- AND st2.drop_off_type = 0
- AND st1.departure_time < st2.arrival_time
- ORDER BY st1.departure_time;
-```
-
-Since `block_id` may be unpopulated, the query joins on both the
-`trip_id` and the `block_id`.
-
-***Note:** An alternative is to guarantee every single trip has a
-`block_id` value when importing -- even if some blocks only consist of
-a single trip. If you can guarantee this condition, then you can
-simplify this query by using `t1.block_id = t2.block_id`.*
-
diff --git a/.idea/gtfs-book/ch-19-calculating-fares.md b/.idea/gtfs-book/ch-19-calculating-fares.md
deleted file mode 100644
index df24dd4..0000000
--- a/.idea/gtfs-book/ch-19-calculating-fares.md
+++ /dev/null
@@ -1,296 +0,0 @@
-## 19. Calculating Fares**
-
-In order to calculate a fare for a trip in GTFS, you must use data from
-`fare_attributes.txt` and `fare_rules.txt`. It is relatively
-straightforward to calculate the cost of a single trip (that is,
-boarding a vehicle, traveling for a number of stops, then disembarking),
-but it becomes much more complicated when you need to take into account
-multiple trip segments (that is, one or more transfers).
-
-***Note:** As it stands, many feed providers do not include fare
-information. This is because many systems have a unique set of rules
-that cannot be modelled with the current structure of fares in GTFS.
-Additionally, it is not possible to determine different classes of
-pricing (such as having a separate price for adults and children). For
-the purposes of this chapter, these limitations are ignored.*
-
-For more discussion on how fares work in GTFS, refer to *Fare
-Definitions (`fare_attributes.txt` & `fare_rules.txt`)*.
-
-This chapter first shows you how to calculate fares for a single trip,
-then how to account for transfers and for multiple trips.
-
-### Calculating a Single Trip Fare
-
-Much of the logic used when calculating fares requires knowledge of the
-zones used in a trip.
-
-***Note:** A zone is a physical area within a transit system that
-contains a series of stops. They are used to group trip pricing into key
-areas in a system. Some transit systems do not work like this (for
-instance, they may measure the physical distance travelled rather than
-specific stops), which is one reason why the GTFS fares model does not
-work in all cases.*
-
-A zone is defined in GTFS by the `zone_id` column in `stops.txt`. A
-single stop can only belong to one zone.
-
-Fares are matched to a trip using a combination of any of the following:
-
-* The route of the trip
-* The zone of the stop the passenger boards from
-* The zone of the stop the passenger disembarks
-* The zone(s) of any stops on the trip that are passed while the
- passenger is on board.
-
-Consider the following simplified data set that may appear in
-`stops.txt` and `stop_times.txt`. Assume for this example that the
-trip `T1` belongs to a route with an ID of `R1`.
-
-```
-stop_id,zone_id
-S1,Z1
-S2,Z1
-S3,Z2
-S4,Z3
-
-trip_id,stop_id,stop_sequence
-T1,S1,1
-T1,S2,2
-T1,S3,3
-T1,S4,4
-```
-
-If a passenger travels from stop S1 to stop S4, then their starting zone
-is Z1, their finishing zone is Z3, and the zones they pass through are
-Z1, Z2 and Z3.
-
-***Note:** When calculating fares, the start and finish zones are also
-included in the zones passed through, so in this example you Z3 is also
-considered as a zone that the trip passes through.*
-
-Using this data, you can now calculate matching fares. To do so, you
-need to find all fares that match either of the following:
-
-* Fares that have no associated rules.
-* Fares that have rules that match the specified trip. If a fare
- defines multiple zones that must be passed through (using
- `contains_id`), then all zones must be matched.
-
-If multiple fares qualify for a trip, then the cheapest fare is the one
-to use.
-
-### Finding Fares With No Rules
-
-This is the simplest use-case for fares. You can find all matching fares
-with the following SQL.
-
-```sql
-SELECT * FROM fare_attributes WHERE fare_id NOT IN (
- SELECT DISTINCT fare_id FROM fare_rules
-);
-```
-
-If a feed only has `fare_attributes.txt` records with no rules, then
-the difference between the fares is in the transfer rules. This section
-only covers calculating fares for a single trip with no transfers, so
-for now you can just select the cheapest fare using the following SQL.
-
-```sql
-SELECT * FROM fare_attributes WHERE fare_id NOT IN (
- SELECT DISTINCT fare_id FROM fare_rules
- )
- ORDER BY price + 0 LIMIT 1;
-```
-
-***Note:** You still need to check for fares with one or more rules in
-order to find the cheapest price. Also, `0` is added in this query in
-order to cast a string to a number. When you roll your own importer you
-should instead import this as a numerical value.*
-
-### Finding Fares With Matched Rules
-
-Next you must check against specific rules for a fare. In order to do
-this, you need the starting zone, finishing zone, and all zones passed
-through (including the start and finish zones).
-
-Referring back to the previous example, if a trip starts at `Z1`,
-passes through `Z2` and finishes at `Z3`, you can find fare
-candidates (that is, trips that *may* match), using the following SQL
-query.
-
-```sql
-SELECT * FROM fare_attributes WHERE fare_id IN (
- SELECT fare_id FROM fare_rules
- WHERE (LENGTH(route_id) = 0 OR route_id = 'R1')
- AND (LENGTH(origin_id) = 0 OR origin_id = 'Z1')
- AND (LENGTH(destination_id) = 0 OR destination_id = 'Z3')
- AND (LENGTH(contains_id) = 0 OR contains_id IN ('Z1', 'Z2', 'Z3')
- )
- );
-```
-
-This returns a list of fares that may qualify for the given trip. As
-some fares have multiple rules, all must be checked. The algorithm to
-represent this is as follows.
-
-```
-fares = [ result from above query ]
-
-qualifyingFares = [ ]
-
-for (fare in fares) {
- if (qualifies(fare))
- qualifyingFares.add(fare)
-}
-
-allFares = qualifyFares + faresWithNoRules
-
-passengerFare = cheapest(allFares)
-```
-
-As shown on the final two lines, once you have the list of qualifying
-fares, you can combine these with fares that have no rules (from the
-previous section) and then determine the cheapest fare.
-
-First though, you must determine if a fare with rules qualifies for the
-given trip. If a fare specifies zones that must be passed through, then
-all rules must be matched.
-
-***Note:** If a particular rule specifies a different route, start, or
-finish than the one you are checking, you do not need to ensure the
-`contains_id` matches, since this rule no longer applies. You still need
-to check the other rules for this fare.*
-
-The algorithm needs to build up a list of zone IDs from the fare rules
-in order to check against the trip. Once this has been done, you need to
-check that every zone ID collected from the rules is contained in the
-trip's list of zones.
-
-```
-qualifies(fare, routeId, originId, destinationId, containsIds) {
-
- fareContains = [ ]
-
- for (rule in fare.rules) {
- if (rule.contains.length == 0)
- continue
-
- if (rule.route.length > 0 AND rule.route != routeId)
- continue
-
- if (rule.origin.length > 0 AND rule.origin != originId)
- continue
-
- if (rule.desination.length > 0 AND rule.destination != destinationId)
- continue
-
- fareContains.add(rule.containsId);
- }
-
- if (fareContains.size == 0)
- return YES
-
- if (containIds HAS EVERY ELEMENT IN fareContains)
- return YES
- else
- return NO
-}
-```
-
-This algorithm achieves the following:
-
-* Only rules that have a value for `contains_id` are relevant. Rules
- that do not have this value fall through and should be considered as
- qualified.
-* If the route is specified but not equal to the one being checked, it
- is safe to ignore the rule's `contains_id`. If the route is empty
- or equal, the loop iteration can continue.
-* Check for the `origin_id` and `destination_id` in the same
- manner as `route_id`.
-* If the route, origin and destination all qualify then store the
- `contains_id` so it can be checked after the loop.
-
-The algorithm returns *yes* if the fare qualifies, meaning you can save
-it as a qualifying fare. You can then return the cheapest qualifying
-fare to the user.
-
-### Calculating Trips With Transfers
-
-Once you introduce transfers, fare calculation becomes more complicated.
-A "trip with a transfer" is considered to be a trip where the passenger
-boards a vehicle, disembarks, and then gets on another vehicle. For
-example:
-
-* Travel on trip T1 from Stop S1 to Stop S2
-* Walk from Stop S2 to Stop S3
-* Travel on trip T2 from Stop S3 to Stop S4.
-
-In order to calculate the total fare for a trip with transfers, the
-following algorithm is used:
-
-1. Retrieve list of qualifying fares for each trip individually
-2. Create a list of every fare combination possible
-3. Loop over all combinations and find the total cost
-4. Return the lowest cost from Step 3.
-
-Step 1 was covered in *Calculating a Single Trip Fare*, but
-you must skip the final step of finding the cheapest fare. This is
-because the cheapest fare may change depending on subsequent transfers.
-Instead, this step is performed once the cheapest *combination* is
-determined.
-
-To demonstrate Step 2, consider the following example:
-
-* The trip on T1 from S1 to S2 yields the following qualifying fares:
- F1, F2.
-* The subsequent trip on T2 from S3 to S4 yields the following
- qualifying fares: F3, F4.
-
-Generating every combination of these fares yields the following
-possibilities:
-
-* F1 + F3
-* F1 + F4
-* F2 + F3
-* F2 + F4.
-
-Step 3 can now be performed, which involves finding the total cost for
-each combinations. As you need to take into account the possibility of
-timed transfers (according to the data stored in
-`fare_attributes.txt`), you also need to know about the times of these
-trips.
-
-The following algorithm can be used to calculate the total cost using
-transfer rules. In this example, you would call this function once for
-each fare combination.
-
-```
-function totalCost(fares) {
- total = 0
-
- for (fare in fares) {
- freeTransfer = NO
-
- if (previousFare ALLOWS TRANSFERS) {
- if (HAS ENOUGH TRANSFERS REMAINING) {
- if (TRANSFER NOT EXPIRED) {
- freeTransfer = YES
- }
- }
- }
-
- if (!freeTransfer)
- total = total + fare.price;
-
- previousFare = fare;
- }
-
- return total;
-}
-```
-
-Once all combinations have called the `totalCost` algorithm, you will
-have a price for each trip. You can then return the lowest price as the
-final price for the trip.
-
diff --git a/.idea/gtfs-book/ch-20-trip-patterns.md b/.idea/gtfs-book/ch-20-trip-patterns.md
deleted file mode 100644
index 4b0cf73..0000000
--- a/.idea/gtfs-book/ch-20-trip-patterns.md
+++ /dev/null
@@ -1,141 +0,0 @@
-## 20. Trip Patterns**
-
-In a GTFS feed, a route typically has multiple trips that start and
-finish at the same stops. If you are looking to reduce the size of the
-data stored, then converting data from `stop_times.txt` into a series
-of reusable patterns is an excellent way to do so.
-
-For two trips to share a common pattern, the following must hold true:
-
-* The stops visited and the order in which they are visited must be the same
-* The time differences between each stop must be the same.
-
-The following table shows some fictional trips to demonstrate this.
-
-| **Stop** | **Trip 1** | **Trip 2** | **Trip 3** |
-| :------- | :--------- | :--------- | :--------- |
-| S1 | 10:00:00 | 10:10:00 | 10:20:00 |
-| S2 | 10:02:00 | 10:13:00 | 10:22:00 |
-| S3 | 10:05:00 | 10:15:00 | 10:25:00 |
-| S4 | 10:06:00 | 10:18:00 | 10:26:00 |
-| S5 | 10:10:00 | 10:21:00 | 10:30:00 |
-
-In a GTFS feed, this would correspond to 15 records in
-`stop_times.txt`. If you look more closely though, you can see the
-trips are very similar. The following table shows the differences
-between each stop time, instead of the actual time.
-
-| **Stop** | **Trip 1** | **Trip 2** | **Trip 3** |
-| :------- | :-------------- | :-------------- | :-------------- |
-| S1 | 00:00:00 | 00:00:00 | 00:00:00 |
-| S2 | 00:02:00 (+2m) | 00:03:00 (+3m) | 00:02:00 (+2m) |
-| S3 | 00:05:00 (+5m) | 00:05:00 (+5m) | 00:05:00 (+5m) |
-| S4 | 00:06:00 (+6m) | 00:08:00 (+8m) | 00:06:00 (+6m) |
-| S5 | 00:10:00 (+10m) | 00:11:00 (+11m) | 00:10:00 (+10m) |
-
-You can see from this table that the first and third trip, although they
-start at different times, have the same offsets between stops (as well
-as stopping at identical stops).
-
-Instead of using a table to store stop times, you can store patterns. By
-storing the ID of the pattern with each trip, you can reduce the list of
-stop times in this example from 15 to 10. As only time offsets are
-stored for each patterns, the trip starting time also needs to be saved
-with each trip.
-
-You could use SQL such as the following to model this.
-
-```sql
-CREATE TABLE trips (
- trip_id TEXT,
- pattern_id INTEGER,
- start_time TEXT,
- start_time_secs INTEGER
-);
-
-CREATE TABLE patterns (
- pattern_id INTEGER,
- stop_id TEXT,
- time_offset INTEGER,
- stop_sequence INTEGER
-);
-```
-
-The data you would store for trips in this example is shown in the
-following table.
-
-| `trip_id` | `pattern_id` | `start_time` | `start_time_secs` |
-| :-------- | :----------- | :----------- | :---------------- |
-| T1 | 1 | 10:00:00 | 36000 |
-| T2 | 2 | 10:10:00 | 36600 |
-| T3 | 1 | 10:20:00 | 37200 |
-
-***Note:** The above table includes start_time_secs, which is an integer
-value representing the number of seconds since the day started. Using
-the hour, minutes and seconds in start_time, this value is `H * 3600 + M * 60 + S`.*
-
-In the `patterns` table, you would store data as in the following
-table.
-
-| `pattern_id` | `stop_id` | `time_offset` | `stop_sequence` |
-| :----------- | :-------- | :------------ | :-------------- |
-| 1 | S1 | 0 | 1 |
-| 1 | S2 | 120 | 2 |
-| 1 | S3 | 300 | 3 |
-| 1 | S4 | 360 | 4 |
-| 1 | S5 | 600 | 5 |
-| 2 | S1 | 0 | 1 |
-| 2 | S2 | 180 | 2 |
-| 2 | S4 | 300 | 3 |
-| 2 | S5 | 480 | 4 |
-| 2 | S6 | 660 | 5 |
-
-As you can see, this represents an easy way to significantly reduce the
-amount of data stored. You could have tens or hundreds of trips each
-sharing the same pattern. When you scale this to the entire feed, this
-could reduce, say, 3 million records to about 200,000.
-
-***Note:** This is a somewhat simplified example, as there is other data
-available in `stop_times.txt` (such as separate arrival/departure times,
-drop-off type and pick-up type). You should take all of this data into
-account when determining how to allocate patterns.*
-
-### Updating Trip Searches
-
-Changing your model to reuse patterns instead of storing every stop time
-means your data lookup routines must also be changed.
-
-For example, to find all stop times for a given trip, you must now find
-the pattern using the following SQL query.
-
-```sql
-SELECT * FROM patterns
- WHERE pattern_id = (SELECT pattern_id FROM trips WHERE trip_id = 'YOUR_TRIP_ID')
- ORDER BY stop_sequence;
-```
-
-If you want to determine the arrival/departure time, you must add the
-offset stored for the pattern record to the starting time stored with
-the trip. This involves joining the tables and adding `time_offset` to
-`start_time_secs`, as shown in the following query.
-
-```sql
-SELECT t.start_time_secs + p.time_offset, p.stop_id
- FROM patterns p, trips t
- WHERE p.pattern_id = t.pattern_id
- AND t.trip_id = 'YOUR_TRIP_ID'
- ORDER BY p.stop_sequence;
-```
-
-### Other Data Reduction Methods
-
-There are other ways you can reduce the amount of data, such as only
-using patterns to store the stops (and not timing offsets), and then
-storing the timings with each trip record. A technique such as this
-further reduces the size of the database, but the trade-off is that
-querying the data becomes slightly more complex.
-
-Hopefully you can see that by using the method described in this chapter
-there are a number of ways to be creative with GTFS data, and that you
-must make decisions when it comes to speed, size, and ease of querying
-data.
diff --git a/.idea/gtfs-book/ch-21-conclusion.md b/.idea/gtfs-book/ch-21-conclusion.md
deleted file mode 100644
index 0bdc2e0..0000000
--- a/.idea/gtfs-book/ch-21-conclusion.md
+++ /dev/null
@@ -1,23 +0,0 @@
-## Conclusion
-
-Thanks for reading *The Definitive Guide to GTFS*. While there are many
-techniques that may take some time to comprehend in this book, the
-content should bring you up to speed with GTFS quickly.
-
-At first glance, GTFS appears to be very simple, but there are a number
-of "gotchas" which are not immediately apparent until you have spent
-significant time working with a range of feeds.
-
-The key takeaways from this book are:
-
-* How GTFS feeds are structured
-* How to import a GTFS feed to SQL and perform queries
-* How to search for trips, handle blocks and calculate fares
-* How to optimize an SQL database to minimize resource usage on mobile
- devices.
-
-If you have enjoyed this book, please share it or feel free to contribution improvements or changes as necessary.
-
-*Quentin Zervaas*
-February, 2014
-
diff --git a/.idea/gtfs-book/images/agency-google-maps.png b/.idea/gtfs-book/images/agency-google-maps.png
deleted file mode 100644
index b9e7c2a..0000000
--- a/.idea/gtfs-book/images/agency-google-maps.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/block-01.png b/.idea/gtfs-book/images/block-01.png
deleted file mode 100644
index 9408632..0000000
--- a/.idea/gtfs-book/images/block-01.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/block-02.png b/.idea/gtfs-book/images/block-02.png
deleted file mode 100644
index 162e5ea..0000000
--- a/.idea/gtfs-book/images/block-02.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/block-03.png b/.idea/gtfs-book/images/block-03.png
deleted file mode 100644
index 345cd72..0000000
--- a/.idea/gtfs-book/images/block-03.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/block-04.png b/.idea/gtfs-book/images/block-04.png
deleted file mode 100644
index ec384b5..0000000
--- a/.idea/gtfs-book/images/block-04.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/orthogonal-distance.jpeg b/.idea/gtfs-book/images/orthogonal-distance.jpeg
deleted file mode 100644
index 9c88323..0000000
--- a/.idea/gtfs-book/images/orthogonal-distance.jpeg
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/shape-original.jpeg b/.idea/gtfs-book/images/shape-original.jpeg
deleted file mode 100644
index 5d72050..0000000
--- a/.idea/gtfs-book/images/shape-original.jpeg
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/shape-reduced.jpeg b/.idea/gtfs-book/images/shape-reduced.jpeg
deleted file mode 100644
index cf6f7cd..0000000
--- a/.idea/gtfs-book/images/shape-reduced.jpeg
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/stop-times.png b/.idea/gtfs-book/images/stop-times.png
deleted file mode 100644
index cdce53d..0000000
--- a/.idea/gtfs-book/images/stop-times.png
+++ /dev/null
Binary files differ
diff --git a/.idea/gtfs-book/images/stops-sample.png b/.idea/gtfs-book/images/stops-sample.png
deleted file mode 100644
index ec0e5c7..0000000
--- a/.idea/gtfs-book/images/stops-sample.png
+++ /dev/null
Binary files differ