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