lib/offline_geocoder.rb in offline_geocoder-0.1.0 vs lib/offline_geocoder.rb in offline_geocoder-0.2.0

- old
+ new

@@ -1,46 +1,51 @@ -require "offline_geocoder/version" -require "csv" -require "kdtree" +# frozen_string_literal: true +require 'offline_geocoder/version' +require 'csv' +require 'geokdtree' + class OfflineGeocoder + CSV_PATH = File.expand_path('../og_cities1000.csv', __dir__) + def initialize - unless defined? @@cities - @@cities = [] - @@points = [] - index = 0 - csv_path = File.expand_path("../../og_cities1000.csv", __FILE__) - lines = File.read(csv_path).split("\n") - @@fields = lines[0].split(',').collect(&:to_sym) - lines[1..-1].each {|line| - parsed_line = - if line.include?('"') - CSV.parse(line)[0] - else - line.split(',') - end - parsed_line[0] = parsed_line[0].to_f - parsed_line[1] = parsed_line[1].to_f - @@cities << parsed_line - @@points << [parsed_line[0], parsed_line[1], index] - index += 1 - } + return if defined? @@cities - @@tree = Kdtree.new(@@points) - return nil + @@cities = [] + @@tree = Geokdtree::Tree.new(2) + @@table = [] + index = 0 + CSV.foreach(CSV_PATH, headers: true, header_converters: :symbol) do |row| + as_hash = row.to_h + as_hash[:lat] = as_hash[:lat].to_f + as_hash[:lon] = as_hash[:lon].to_f + @@tree.insert([row[:lat], row[:lon]], index) + @@table << as_hash + index += 1 end end - def search(latitude, longitude) - record = @@cities[@@tree.nearest(latitude.to_f, longitude.to_f)] - hash_record = {} - record.each_with_index do |value, index| - hash_record[@@fields[index]] = value + def search(query, lon = nil) + lat, lon = lon.nil? ? [query[:lat], query[:lon]] : [query, lon] + + if lat && lon + search_by_latlon(lat.to_f, lon.to_f) + else + search_by_attr(query) end - hash_record end # Hide internal variables def inspect - "#<#{self.class}:0x#{'%014x' % (self.object_id << 1)}>" + "#<#{self.class}:0x#{format('%<id>014x', id: (object_id << 1))}>" + end + + private + + def search_by_latlon(lat, lon) + @@table[@@tree.nearest([lat, lon]).data.to_i].to_h + end + + def search_by_attr(query = {}) + @@table.select { |object| object >= query }.first end end