geocoding snippets

How to parse geonames.org data with Ruby

Tagged ruby, geonames, geocoding  Languages ruby
require 'rubygems'
require 'ostruct'
require 'time'

class GeoName < OpenStruct
end  

class GeoNames
  class << self
    def parse(file)
      File.new(file).each_line do |line|
        g = GeoName.new
        s = line.chomp.split("\t")
        g.geonameid = s[0]
        g.name = s[1]
        g.asciiname = s[2]
        g.alternatenames = s[3]
        g.latitude = s[4]
        g.longitude = s[5]
        g.feature_class = s[6]
        g.feature_code = s[7]
        g.country_code = s[8]
        g.cc2 = s[9]
        g.admin1 = s[10]
        g.admin2 = s[11]
        g.admin3 = s[12]
        g.admin4 = s[13]
        g.population = s[14]
        g.elevation = s[15]
        g.gtopo30 = s[16]
        g.timezone = s[17]
        g.modification_date = Time.parse(s[18])
      
        yield g
      end
    end
  end
end

file = "geonames/features.txt"

GeoNames.parse(file) do |place|
  p place.geonameid
  break
end

Inspired by this article

How to setup and use GeoKit with Rails 2.3.2

Tagged rails, geocoding, geokit  Languages ruby

Install the GeoKit gem and the Rails plugin:

sudo gem install geokit
script/plugin install git://github.com/andre/geokit-rails.git

Edit config/environment.rb:

Rails::Initializer.run do |config|
  config.gem "geokit"
end

Generate a model and migration file with script/generate model Place:

class CreatePlaces < ActiveRecord::Migration
  def self.up
    create_table :places do |t|
      t.string :name

      t.string :external_id
      t.string :external_type

      t.decimal :latitude,  :precision => 15, :scale => 10
      t.decimal :longitude, :precision => 15, :scale => 10

      t.timestamps
    end

    add_index :places, :latitude
    add_index :places, :longitude
    add_index :places, [:latitude, :longitude]
  end

  def self.down
    drop_table :places
  end
end

Configure GeoKit:

class Place < ActiveRecord::Base
  acts_as_mappable :default_units => :kms, 
                   :default_formula => :sphere, 
                   :distance_field_name => :distance,
                   :lat_column_name => :latitude,
                   :lng_column_name => :longitude
end

Use your GeoKit enabled model:

Place.find_within(105, :origin => Place.last)