aboutsummaryrefslogblamecommitdiffstats
path: root/lib/postcodes-norway.rb
blob: 86d0ab4fc78221e8026d74dafd43e83a960f85aa (plain) (tree)
1
2
3
4
5

                
                                                       
 
                                       

























                         
                                   
                

                          
 



















                                                                       



                                                                                                      

                                                           




                                     
                                                                                   





                                                                            



                                                               
                  
                     






                                                               




                                                                    






                                                                       
                     
                                                      
         

       









                                                                       


       
module PostCodes

  require 'postcodes-norway/railtie' if defined?(Rails)

  # Correspond to the Norwegian 'Fylke'
  Counties = [
    "ØSTFOLD",
    "AKERSHUS",
    "OSLO",
    "HEDMARK",
    "OPPLAND",
    "BUSKERUD",
    "VESTFOLD",
    "TELEMARK",
    "AUST-AGDER",
    "VEST-AGDER",
    "ROGALAND",
    "HORDALAND",
    "(BERGEN)",
    "SOGN OG FJORDANE",
    "MØRE OG ROMSDAL",
    "SØR-TRØNDELAG",
    "NORD-TRØNDELAG",
    "NORDLAND",
    "TROMS",
    "FINNMARK",
    "SVALBARD",
    "JAN MAYEN",
    "KONTINENTALSOKKELEN"
  ]

  # Class for holding postcode data
  class PostCode
    # Four digit post code
    attr_reader :postcode

    # Name of city
    attr_reader :city

    # Four digit municipality ('kommune') id
    attr_reader :municipality

    # Name of municipality ('kommune')
    attr_reader :municipality_name

    # Category
    # * 'G' = street address
    # * 'P' = Postboxes
    # * 'B' = Both street addresses and postboxes
    # * 'S' = Service addresses
    # * 'K' = Customer with its own post code
    # * 'F' = Multiple uses
    attr_reader :cat

    # Create a new post code.
    # This method should generally not be used by users of the library.
    def initialize(postcode, city, muni, muni_name, cat)
      @postcode, @city, @municipality, @municipality_name, @cat = postcode, city, muni, muni_name, cat
    end

    # Return the County ('kommune') from the postcode data.
    # The returned format is `[county_id, county_name]`
    def county
      code = @municipality[0..1].to_i
      [code, PostCodes.county(code)]
    end

    # Output postcode data in the same format as in the original postcode database.
    def to_s
      [@postcode, @city, @municipality, @municipality_name, @cat].join("\t")
    end
  end

  class << self

    # Load the postcode data into memory.
    #
    # +file+ is a file name or IO object to read the data from.
    def load(file)
      @postcodes = []
      if file.is_a?(String)
        f = File.open(file, :encoding => Encoding::ISO_8859_15)
      else
        f = file
      end

      f.each_line do |l|
        a = l.chomp().split("\t").map{|s| s.encode(Encoding::UTF_8)}
        @postcodes << PostCode.new(*a)
      end
    end

    # Search for a given postcode.
    #
    # Takes a 4 digit postcode as a string, and returns an object of
    # type PostCodes::PostCode, or +nil+ if the postcode was not found.
    #
    def search(postcode)
      res = @postcodes.bsearch {|x| x.postcode.to_i >= postcode.to_i}
      unless res.nil?
        res.postcode.to_i == postcode.to_i ? res : nil
      end
    end

    # Return the county by number.
    #
    # Takes a number between 1 and 23 as input. This corresponds to the
    # first two digits in the municipality number.
    #
    # The county name as a string is returned.
    #
    def county(index)
      return nil unless index > 0 && index <= Counties.size
      Counties[index - 1]
    end
  end
end