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