gtfs_reader 1.2.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -15
- data/Rakefile +6 -9
- data/lib/gtfs_reader/bulk_feed_handler.rb +28 -24
- data/lib/gtfs_reader/config/column.rb +16 -16
- data/lib/gtfs_reader/config/defaults/gtfs_feed_definition.rb +50 -46
- data/lib/gtfs_reader/config/feed_definition.rb +19 -19
- data/lib/gtfs_reader/config/file_definition.rb +34 -33
- data/lib/gtfs_reader/config/source.rb +17 -15
- data/lib/gtfs_reader/config/sources.rb +7 -3
- data/lib/gtfs_reader/configuration.rb +8 -9
- data/lib/gtfs_reader/core.rb +14 -15
- data/lib/gtfs_reader/exceptions.rb +0 -1
- data/lib/gtfs_reader/feed_handler.rb +12 -8
- data/lib/gtfs_reader/file_reader.rb +34 -36
- data/lib/gtfs_reader/file_row.rb +40 -32
- data/lib/gtfs_reader/log.rb +37 -23
- data/lib/gtfs_reader/source_updater.rb +40 -43
- data/lib/gtfs_reader/version.rb +29 -28
- metadata +39 -39
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e25dd494cd1cfa6d1e2fef48744b1016644362c6
         | 
| 4 | 
            +
              data.tar.gz: b147c7f108b84ac047b68e50a704bb1aa3d4f6ff
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d9dc292265e217230dac89bf9f92ac5c7bcec17e19e77ef62c9dd34e79660ebf77f1732d96627925d01ced21bace26479b6c4dddff59fcbd43d43ff43a42ecfd
         | 
| 7 | 
            +
              data.tar.gz: dfd918d96505e679e61ac204441df6c7d4976601d7ea5d413ceeb47f4dc7941dd56d04e1492e2afad935c8ebcf19c3b74ce44aff8119ca4af03595e26be0242e
         | 
    
        data/README.md
    CHANGED
    
    | @@ -15,7 +15,7 @@ Feed](https://developers.google.com/transit/gtfs)": | |
| 15 15 | 
             
            > developers to write applications that consume that data in an interoperable
         | 
| 16 16 | 
             
            > way.
         | 
| 17 17 |  | 
| 18 | 
            -
            Essentially, a GTFS feed is a ZIP file containing | 
| 18 | 
            +
            Essentially, a GTFS feed is a ZIP file containing
         | 
| 19 19 | 
             
            [CSV-formatted](https://en.wikipedia.org/wiki/Comma-separated_values) .txt
         | 
| 20 20 | 
             
            files which following the specification.
         | 
| 21 21 |  | 
| @@ -27,26 +27,27 @@ files which following the specification. | |
| 27 27 | 
             
            require 'gtfs_reader'
         | 
| 28 28 |  | 
| 29 29 | 
             
            GtfsReader.config do
         | 
| 30 | 
            +
              # verbose true # TODO: uncomment for verbose output
         | 
| 30 31 | 
             
              return_hashes true
         | 
| 31 | 
            -
             | 
| 32 | 
            +
             | 
| 32 33 | 
             
              sources do
         | 
| 33 34 | 
             
                sample do
         | 
| 34 | 
            -
                  url 'http://localhost/sample-feed.zip' # you can also use a filepath here | 
| 35 | 
            +
                  url 'http://localhost/sample-feed.zip' # you can also use a filepath here
         | 
| 35 36 | 
             
                  before { |etag| puts "Processing source with tag #{etag}..." }
         | 
| 36 37 | 
             
                  handlers do
         | 
| 37 | 
            -
                    agency {|row| puts "Read Agency: #{row[:agency_name]}" }
         | 
| 38 | 
            -
                    routes {|row| puts "Read Route: #{row[:route_long_name]}" }
         | 
| 38 | 
            +
                    agency { |row| puts "Read Agency: #{row[:agency_name]}" }
         | 
| 39 | 
            +
                    routes { |row| puts "Read Route: #{row[:route_long_name]}" }
         | 
| 39 40 | 
             
                  end
         | 
| 40 41 | 
             
                end
         | 
| 41 42 | 
             
              end
         | 
| 42 43 | 
             
            end
         | 
| 43 44 |  | 
| 44 | 
            -
            GtfsReader.update | 
| 45 | 
            +
            GtfsReader.update(:sample) # or GtfsReader.update_all!
         | 
| 45 46 | 
             
            ```
         | 
| 46 47 |  | 
| 47 | 
            -
            Assuming that `http://localhost/sample-feed.zip` returns the | 
| 48 | 
            -
            (https://developers.google.com/transit/gtfs/examples/gtfs-feed), | 
| 49 | 
            -
            will print the following:
         | 
| 48 | 
            +
            Assuming that `http://localhost/sample-feed.zip` returns the
         | 
| 49 | 
            +
            [Example Feed](https://developers.google.com/transit/gtfs/examples/gtfs-feed),
         | 
| 50 | 
            +
            this script will print the following:
         | 
| 50 51 |  | 
| 51 52 | 
             
            ```
         | 
| 52 53 | 
             
            Processing source with tag 4d9d3040c284f0581cd5620d5c131109...
         | 
| @@ -73,25 +74,27 @@ GtfsReader.config do | |
| 73 74 | 
             
              sources do
         | 
| 74 75 | 
             
                sample do
         | 
| 75 76 | 
             
                  feed_definition do
         | 
| 76 | 
            -
                    file | 
| 77 | 
            -
                      col | 
| 77 | 
            +
                    file(:drivers, required: true) do # for my_file.txt
         | 
| 78 | 
            +
                      col(:licence_number, required: true, unique: true)
         | 
| 78 79 |  | 
| 79 80 | 
             
                      # If the sex column contains "1", the symbol :male will be returned,
         | 
| 80 81 | 
             
                      # otherwise :female will be returned
         | 
| 81 | 
            -
                      col :sex, &output_map(  | 
| 82 | 
            +
                      col :sex, &output_map({ female: '1', male: '2' }, :unspecified)
         | 
| 82 83 |  | 
| 83 84 | 
             
                      # This will allow you to create a custom parser. Within the given
         | 
| 84 85 | 
             
                      # block you can reference other columns in the current row by name.
         | 
| 85 86 | 
             
                      col :name do |name|
         | 
| 86 87 | 
             
                        case sex
         | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 88 | 
            +
                        when :female then "Ms. #{name}"
         | 
| 89 | 
            +
                        when :male   then "Mr. #{name}"
         | 
| 90 | 
            +
                        else              name
         | 
| 90 91 | 
             
                        end
         | 
| 91 92 | 
             
                      end
         | 
| 92 93 | 
             
                    end
         | 
| 93 94 | 
             
                  end
         | 
| 95 | 
            +
             | 
| 94 96 | 
             
                  # ...
         | 
| 97 | 
            +
             | 
| 95 98 | 
             
                end
         | 
| 96 99 | 
             
              end
         | 
| 97 100 | 
             
            end
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            # encoding: utf-8
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            require 'rubygems'
         | 
| 4 2 | 
             
            require 'bundler'
         | 
| 5 3 | 
             
            require 'rake'
         | 
| @@ -11,8 +9,8 @@ require_relative 'lib/gtfs_reader/version' | |
| 11 9 | 
             
            begin
         | 
| 12 10 | 
             
              Bundler.setup :default, :development
         | 
| 13 11 | 
             
            rescue Bundler::BundlerError => e
         | 
| 14 | 
            -
               | 
| 15 | 
            -
               | 
| 12 | 
            +
              warn e.message
         | 
| 13 | 
            +
              warn 'Run `bundle install` to install missing gems'
         | 
| 16 14 | 
             
              exit e.status_code
         | 
| 17 15 | 
             
            end
         | 
| 18 16 |  | 
| @@ -20,15 +18,15 @@ Jeweler::Tasks.new do |gem| | |
| 20 18 | 
             
              gem.name = 'gtfs_reader'
         | 
| 21 19 | 
             
              gem.version = GtfsReader::Version.to_s
         | 
| 22 20 | 
             
              gem.homepage = 'http://github.com/sangster/gtfs_reader'
         | 
| 23 | 
            -
              gem.license = 'GPL | 
| 21 | 
            +
              gem.license = 'GPL-3.0'
         | 
| 24 22 | 
             
              gem.summary = 'Read General Transit Feed Specification zip files'
         | 
| 25 | 
            -
              gem.description = <<- | 
| 23 | 
            +
              gem.description = <<-DESC.strip.gsub(/\s+/, ' ')
         | 
| 26 24 | 
             
                Reads and parses zip files conforming to Google's GTFS spec. Such files can
         | 
| 27 25 | 
             
                take up quite a bit of memory when inflated, so this gem prefers to read
         | 
| 28 26 | 
             
                them as a stream of rows.
         | 
| 29 27 |  | 
| 30 28 | 
             
                GTFS Spec: https://developers.google.com/transit/gtfs
         | 
| 31 | 
            -
               | 
| 29 | 
            +
              DESC
         | 
| 32 30 | 
             
              gem.email = 'jon@ertt.ca'
         | 
| 33 31 | 
             
              gem.authors = ['Jon Sangster']
         | 
| 34 32 |  | 
| @@ -52,6 +50,5 @@ end | |
| 52 50 |  | 
| 53 51 | 
             
            # RSpec
         | 
| 54 52 | 
             
            require 'rspec/core/rake_task'
         | 
| 55 | 
            -
            RSpec::Core::RakeTask.new | 
| 53 | 
            +
            RSpec::Core::RakeTask.new(:spec)
         | 
| 56 54 | 
             
            task default: :spec
         | 
| 57 | 
            -
             | 
| @@ -1,23 +1,23 @@ | |
| 1 1 | 
             
            module GtfsReader
         | 
| 2 2 | 
             
              class BulkFeedHandler
         | 
| 3 | 
            -
                def initialize(bulk_size, args=[], &block)
         | 
| 3 | 
            +
                def initialize(bulk_size, args = [], &block)
         | 
| 4 4 | 
             
                  @bulk_size = bulk_size
         | 
| 5 5 | 
             
                  @callbacks = {}
         | 
| 6 | 
            -
                  BulkFeedHandlerDsl.new(self).instance_exec | 
| 6 | 
            +
                  BulkFeedHandlerDsl.new(self).instance_exec(*args, &block)
         | 
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 9 | 
             
                def handler?(filename)
         | 
| 10 | 
            -
                  @callbacks.key? | 
| 10 | 
            +
                  @callbacks.key?(filename)
         | 
| 11 11 | 
             
                end
         | 
| 12 12 |  | 
| 13 13 | 
             
                def handle_file(filename, reader)
         | 
| 14 | 
            -
                  unless @callbacks.key? | 
| 14 | 
            +
                  unless @callbacks.key?(filename)
         | 
| 15 15 | 
             
                    Log.warn { "No handler registered for #{filename.to_s.red}.txt" }
         | 
| 16 16 | 
             
                    return
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 |  | 
| 19 | 
            -
                  calls = callbacks | 
| 20 | 
            -
                  calls[:before].call if calls.key? | 
| 19 | 
            +
                  calls = callbacks(filename)
         | 
| 20 | 
            +
                  calls[:before].call if calls.key?(:before)
         | 
| 21 21 | 
             
                  read_row = calls[:read]
         | 
| 22 22 |  | 
| 23 23 | 
             
                  values = []
         | 
| @@ -27,16 +27,16 @@ module GtfsReader | |
| 27 27 | 
             
                    values << (read_row ? read_row.call(row) : row)
         | 
| 28 28 | 
             
                    bulk_count += 1
         | 
| 29 29 |  | 
| 30 | 
            -
                     | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                     | 
| 30 | 
            +
                    next unless bulk_count == @bulk_size
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    total += bulk_count
         | 
| 33 | 
            +
                    calls[:bulk].call values, bulk_count, total, cols
         | 
| 34 | 
            +
                    bulk_count = 0
         | 
| 35 | 
            +
                    values = []
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 |  | 
| 38 | 
            -
                  unless bulk_count | 
| 39 | 
            -
                    calls[:bulk].call | 
| 38 | 
            +
                  unless bulk_count.zero?
         | 
| 39 | 
            +
                    calls[:bulk].call(values, bulk_count, (total + bulk_count), cols)
         | 
| 40 40 | 
             
                  end
         | 
| 41 41 | 
             
                  nil
         | 
| 42 42 | 
             
                end
         | 
| @@ -50,7 +50,7 @@ module GtfsReader | |
| 50 50 | 
             
                end
         | 
| 51 51 |  | 
| 52 52 | 
             
                def callback?(kind, filename)
         | 
| 53 | 
            -
                  @callbacks.key? | 
| 53 | 
            +
                  @callbacks.key?(filename) && @callbacks[filename].key?(kind)
         | 
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 56 | 
             
                private
         | 
| @@ -65,30 +65,34 @@ module GtfsReader | |
| 65 65 | 
             
                  @feed_handler = feed_handler
         | 
| 66 66 | 
             
                end
         | 
| 67 67 |  | 
| 68 | 
            -
                def method_missing(filename, * | 
| 69 | 
            -
                  BulkDsl.new(@feed_handler, filename).instance_exec | 
| 68 | 
            +
                def method_missing(filename, *_args, &block)
         | 
| 69 | 
            +
                  BulkDsl.new(@feed_handler, filename).instance_exec(&block)
         | 
| 70 70 |  | 
| 71 | 
            -
                   | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 71 | 
            +
                  return if @feed_handler.callback?(:bulk, filename)
         | 
| 72 | 
            +
                  raise HandlerMissingError, "No bulk block for #{filename}"
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def respond_to_missing?(_name, _include_private = false)
         | 
| 76 | 
            +
                  true
         | 
| 74 77 | 
             
                end
         | 
| 75 78 | 
             
              end
         | 
| 76 79 |  | 
| 77 80 | 
             
              class BulkDsl
         | 
| 78 81 | 
             
                def initialize(feed_handler, filename)
         | 
| 79 | 
            -
                  @feed_handler | 
| 82 | 
            +
                  @feed_handler = feed_handler
         | 
| 83 | 
            +
                  @filename = filename
         | 
| 80 84 | 
             
                end
         | 
| 81 85 |  | 
| 82 86 | 
             
                def before(&block)
         | 
| 83 | 
            -
                  @feed_handler.create_callback | 
| 87 | 
            +
                  @feed_handler.create_callback(:before, @filename, block)
         | 
| 84 88 | 
             
                end
         | 
| 85 89 |  | 
| 86 90 | 
             
                def read(&block)
         | 
| 87 | 
            -
                  @feed_handler.create_callback | 
| 91 | 
            +
                  @feed_handler.create_callback(:read, @filename, block)
         | 
| 88 92 | 
             
                end
         | 
| 89 93 |  | 
| 90 94 | 
             
                def bulk(&block)
         | 
| 91 | 
            -
                  @feed_handler.create_callback | 
| 95 | 
            +
                  @feed_handler.create_callback(:bulk, @filename, block)
         | 
| 92 96 | 
             
                end
         | 
| 93 97 | 
             
              end
         | 
| 94 98 | 
             
            end
         | 
| @@ -7,16 +7,16 @@ module GtfsReader | |
| 7 7 |  | 
| 8 8 | 
             
                  attr_reader :name
         | 
| 9 9 |  | 
| 10 | 
            -
                   | 
| 11 | 
            -
                   | 
| 12 | 
            -
                  # | 
| 13 | 
            -
                   | 
| 14 | 
            -
                  # | 
| 15 | 
            -
                  def initialize(name, opts={}, &parser)
         | 
| 10 | 
            +
                  # @param name [String] the name of the column
         | 
| 11 | 
            +
                  # @option opts [Boolean] :required (false) If this column is required to
         | 
| 12 | 
            +
                  #   appear in the given file
         | 
| 13 | 
            +
                  # @option opts [Boolean] :unique (false) if values in this column need to
         | 
| 14 | 
            +
                  #   be unique among all rows in the file.
         | 
| 15 | 
            +
                  def initialize(name, opts = {}, &parser)
         | 
| 16 16 | 
             
                    @name = name
         | 
| 17 17 | 
             
                    @parser = block_given? ? parser : IDENTITY_PARSER
         | 
| 18 18 |  | 
| 19 | 
            -
                    @opts = { required: false, unique: false }.merge | 
| 19 | 
            +
                    @opts = { required: false, unique: false }.merge(opts || {})
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 22 | 
             
                  def parser(&block)
         | 
| @@ -24,30 +24,30 @@ module GtfsReader | |
| 24 24 | 
             
                    @parser
         | 
| 25 25 | 
             
                  end
         | 
| 26 26 |  | 
| 27 | 
            -
                   | 
| 27 | 
            +
                  # @return [Boolean] if this column is required to appear in the file
         | 
| 28 28 | 
             
                  def required?
         | 
| 29 29 | 
             
                    @opts[:required]
         | 
| 30 30 | 
             
                  end
         | 
| 31 31 |  | 
| 32 | 
            -
                   | 
| 33 | 
            -
                  # | 
| 32 | 
            +
                  # @return [Boolean] if values in this column need to be unique among all
         | 
| 33 | 
            +
                  #   rows in the file.
         | 
| 34 34 | 
             
                  def unique?
         | 
| 35 35 | 
             
                    @opts[:unique]
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 |  | 
| 38 | 
            -
                   | 
| 38 | 
            +
                  # @return [Boolean]
         | 
| 39 39 | 
             
                  def parser?
         | 
| 40 40 | 
             
                    parser != IDENTITY_PARSER
         | 
| 41 41 | 
             
                  end
         | 
| 42 42 |  | 
| 43 43 | 
             
                  def to_s
         | 
| 44 | 
            -
                    opts = @opts.map do |key,value|
         | 
| 44 | 
            +
                    opts = @opts.map do |key, value|
         | 
| 45 45 | 
             
                      case value
         | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 46 | 
            +
                      when true then key
         | 
| 47 | 
            +
                      when false, nil then nil
         | 
| 48 | 
            +
                      else "#{key}=#{value}"
         | 
| 49 49 | 
             
                      end
         | 
| 50 | 
            -
                    end.reject | 
| 50 | 
            +
                    end.reject(&:nil?)
         | 
| 51 51 |  | 
| 52 52 | 
             
                    opts << 'has_parser' if parser?
         | 
| 53 53 |  | 
| @@ -15,36 +15,36 @@ module GtfsReader | |
| 15 15 | 
             
                        col :agency_name,     required: true
         | 
| 16 16 | 
             
                        col :agency_url,      required: true
         | 
| 17 17 | 
             
                        col :agency_timezone, required: true
         | 
| 18 | 
            -
                        col :agency_id, | 
| 18 | 
            +
                        col :agency_id, unique: true
         | 
| 19 19 | 
             
                        col :agency_lang
         | 
| 20 20 | 
             
                        col :agency_phone
         | 
| 21 21 | 
             
                        col :agency_fare_url
         | 
| 22 22 | 
             
                      end
         | 
| 23 23 |  | 
| 24 24 | 
             
                      file :stops, required: true do
         | 
| 25 | 
            -
                        col :stop_id, | 
| 25 | 
            +
                        col :stop_id, required: true, unique: true
         | 
| 26 26 | 
             
                        col :stop_code
         | 
| 27 | 
            -
                        col :stop_name, | 
| 27 | 
            +
                        col :stop_name, required: true
         | 
| 28 28 | 
             
                        col :stop_desc
         | 
| 29 29 | 
             
                        col :stop_lat,      required: true
         | 
| 30 30 | 
             
                        col :stop_lon,      required: true
         | 
| 31 31 | 
             
                        col :stop_url
         | 
| 32 32 | 
             
                        col :stop_timezone
         | 
| 33 33 | 
             
                        col :zone_id
         | 
| 34 | 
            -
                        col :location_type, &output_map(  | 
| 34 | 
            +
                        col :location_type, &output_map({ station: '1' }, :stop)
         | 
| 35 35 | 
             
                        col :parent_station
         | 
| 36 36 |  | 
| 37 37 | 
             
                        col :wheelchair_boarding do |val|
         | 
| 38 38 | 
             
                          if parent_station
         | 
| 39 39 | 
             
                            case val
         | 
| 40 | 
            -
                            when  | 
| 41 | 
            -
                            when  | 
| 40 | 
            +
                            when '2' then :no
         | 
| 41 | 
            +
                            when '1' then :yes
         | 
| 42 42 | 
             
                            else :inherit
         | 
| 43 43 | 
             
                            end
         | 
| 44 44 | 
             
                          else
         | 
| 45 45 | 
             
                            case val
         | 
| 46 | 
            -
                            when  | 
| 47 | 
            -
                            when  | 
| 46 | 
            +
                            when '2' then :no_vehicles
         | 
| 47 | 
            +
                            when '1' then :some_vehicles
         | 
| 48 48 | 
             
                            else :unknown
         | 
| 49 49 | 
             
                            end
         | 
| 50 50 | 
             
                          end
         | 
| @@ -56,16 +56,17 @@ module GtfsReader | |
| 56 56 | 
             
                        col :route_short_name, required: true
         | 
| 57 57 | 
             
                        col :route_long_name,  required: true
         | 
| 58 58 | 
             
                        col :route_desc
         | 
| 59 | 
            -
                        col :route_type, | 
| 60 | 
            -
                            &output_map( | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 59 | 
            +
                        col :route_type, required: true,
         | 
| 60 | 
            +
                            &output_map({
         | 
| 61 | 
            +
                                          tram: '0',
         | 
| 62 | 
            +
                                          subway: '1',
         | 
| 63 | 
            +
                                          rail: '2',
         | 
| 64 | 
            +
                                          bus: '3',
         | 
| 65 | 
            +
                                          ferry: '4',
         | 
| 66 | 
            +
                                          cable_car: '5',
         | 
| 67 | 
            +
                                          gondola: '6',
         | 
| 68 | 
            +
                                          funicular: '7'
         | 
| 69 | 
            +
                                        }, :unknown)
         | 
| 69 70 | 
             
                        col :route_url
         | 
| 70 71 | 
             
                        col :route_color
         | 
| 71 72 | 
             
                        col :route_text_color
         | 
| @@ -73,17 +74,17 @@ module GtfsReader | |
| 73 74 | 
             
                      end
         | 
| 74 75 |  | 
| 75 76 | 
             
                      file :trips, required: true do
         | 
| 76 | 
            -
                        col :trip_id, | 
| 77 | 
            +
                        col :trip_id, required: true, unique: true
         | 
| 77 78 | 
             
                        col :trip_headsign
         | 
| 78 79 | 
             
                        col :trip_short_name
         | 
| 79 80 | 
             
                        col :trip_long_name
         | 
| 80 81 | 
             
                        col :route_id,              required: true
         | 
| 81 82 | 
             
                        col :service_id,            required: true
         | 
| 82 | 
            -
                        col :direction_id,          &output_map( | 
| 83 | 
            +
                        col :direction_id,          &output_map(primary: '0', opposite: '1')
         | 
| 83 84 | 
             
                        col :block_id
         | 
| 84 85 | 
             
                        col :shape_id
         | 
| 85 | 
            -
                        col :wheelchair_accessible, &output_map(  | 
| 86 | 
            -
                        col :bikes_allowed,         &output_map(  | 
| 86 | 
            +
                        col :wheelchair_accessible, &output_map({ yes: '1', no: '2' }, :unknown)
         | 
| 87 | 
            +
                        col :bikes_allowed,         &output_map({ yes: '1', no: '2' }, :unknown)
         | 
| 87 88 | 
             
                      end
         | 
| 88 89 |  | 
| 89 90 | 
             
                      file :stop_times, required: true do
         | 
| @@ -95,29 +96,31 @@ module GtfsReader | |
| 95 96 | 
             
                        col :stop_headsign
         | 
| 96 97 |  | 
| 97 98 | 
             
                        col :pickup_type,
         | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 99 | 
            +
                            &output_map({
         | 
| 100 | 
            +
                                          none: '1',
         | 
| 101 | 
            +
                                          phone_agency: '2',
         | 
| 102 | 
            +
                                          coordinate_with_driver: '3'
         | 
| 103 | 
            +
                                        }, :regular)
         | 
| 102 104 |  | 
| 103 105 | 
             
                        col :drop_off_type,
         | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 106 | 
            +
                            &output_map({
         | 
| 107 | 
            +
                                          none: '1',
         | 
| 108 | 
            +
                                          phone_agency: '2',
         | 
| 109 | 
            +
                                          coordinate_with_driver: '3'
         | 
| 110 | 
            +
                                        }, :regular)
         | 
| 108 111 |  | 
| 109 112 | 
             
                        col :shape_dist_traveled
         | 
| 110 113 | 
             
                      end
         | 
| 111 114 |  | 
| 112 115 | 
             
                      file :calendar, required: true do
         | 
| 113 116 | 
             
                        col :service_id, required: true, unique: true
         | 
| 114 | 
            -
                        col :monday,     required: true, &output_map( | 
| 115 | 
            -
                        col :tuesday,    required: true, &output_map( | 
| 116 | 
            -
                        col :wednesday,  required: true, &output_map( | 
| 117 | 
            -
                        col :thursday,   required: true, &output_map( | 
| 118 | 
            -
                        col :friday,     required: true, &output_map( | 
| 119 | 
            -
                        col :saturday,   required: true, &output_map( | 
| 120 | 
            -
                        col :sunday,     required: true, &output_map( | 
| 117 | 
            +
                        col :monday,     required: true, &output_map(yes: '1', no: '0')
         | 
| 118 | 
            +
                        col :tuesday,    required: true, &output_map(yes: '1', no: '0')
         | 
| 119 | 
            +
                        col :wednesday,  required: true, &output_map(yes: '1', no: '0')
         | 
| 120 | 
            +
                        col :thursday,   required: true, &output_map(yes: '1', no: '0')
         | 
| 121 | 
            +
                        col :friday,     required: true, &output_map(yes: '1', no: '0')
         | 
| 122 | 
            +
                        col :saturday,   required: true, &output_map(yes: '1', no: '0')
         | 
| 123 | 
            +
                        col :sunday,     required: true, &output_map(yes: '1', no: '0')
         | 
| 121 124 | 
             
                        col :start_date
         | 
| 122 125 | 
             
                        col :end_date
         | 
| 123 126 | 
             
                      end
         | 
| @@ -126,7 +129,7 @@ module GtfsReader | |
| 126 129 | 
             
                        col :service_id,     required: true
         | 
| 127 130 | 
             
                        col :date,           required: true
         | 
| 128 131 | 
             
                        col :exception_type, required: true,
         | 
| 129 | 
            -
             | 
| 132 | 
            +
                            &output_map(added: '1', removed: '2')
         | 
| 130 133 | 
             
                      end
         | 
| 131 134 |  | 
| 132 135 | 
             
                      file :fare_attributes do
         | 
| @@ -134,14 +137,14 @@ module GtfsReader | |
| 134 137 | 
             
                        col :price,          required: true
         | 
| 135 138 | 
             
                        col :currency_type,  required: true
         | 
| 136 139 | 
             
                        col :payment_method, required: true,
         | 
| 137 | 
            -
             | 
| 140 | 
            +
                            &output_map(on_board: 0, before: 1)
         | 
| 138 141 | 
             
                        col :transfers,      required: true,
         | 
| 139 | 
            -
             | 
| 142 | 
            +
                            &output_map({ none: 0, once: 1, twice: 2 }, :unlimited)
         | 
| 140 143 | 
             
                        col :transfer_duration
         | 
| 141 144 | 
             
                      end
         | 
| 142 145 |  | 
| 143 146 | 
             
                      file :fare_rules do
         | 
| 144 | 
            -
                        col :fare_id, | 
| 147 | 
            +
                        col :fare_id, required: true
         | 
| 145 148 | 
             
                        col :route_id
         | 
| 146 149 | 
             
                        col :origin_id
         | 
| 147 150 | 
             
                        col :destination_id
         | 
| @@ -161,17 +164,18 @@ module GtfsReader | |
| 161 164 | 
             
                        col :start_time,   required: true
         | 
| 162 165 | 
             
                        col :end_time,     required: true
         | 
| 163 166 | 
             
                        col :headway_secs, required: true
         | 
| 164 | 
            -
                        col :exact_times,  &output_map(  | 
| 167 | 
            +
                        col :exact_times,  &output_map({ exact: 1 }, :inexact)
         | 
| 165 168 | 
             
                      end
         | 
| 166 169 |  | 
| 167 170 | 
             
                      file :transfers do
         | 
| 168 171 | 
             
                        col :from_stop_id,      required: true
         | 
| 169 172 | 
             
                        col :to_stop_id,        required: true
         | 
| 170 173 | 
             
                        col :transfer_type,     required: true,
         | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 174 | 
            +
                            &output_map({
         | 
| 175 | 
            +
                                          timed_transfer: 1,
         | 
| 176 | 
            +
                                          minimum_time_required: 2,
         | 
| 177 | 
            +
                                          impossible: 3
         | 
| 178 | 
            +
                                        }, :recommended)
         | 
| 175 179 | 
             
                        col :min_transfer_time
         | 
| 176 180 | 
             
                      end
         | 
| 177 181 |  |