elcgeo 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest CHANGED
@@ -1,3 +1,16 @@
1
+ Manifest
2
+ README.textile
1
3
  Rakefile
4
+ TODO
5
+ elcgeo.gemspec
2
6
  lib/elcgeo.rb
3
- Manifest
7
+ rails_generators/geo/USAGE
8
+ rails_generators/geo/geo_generator.rb
9
+ rails_generators/geo/templates/migration.rb
10
+ rails_generators/geo/templates/models/city.rb
11
+ rails_generators/geo/templates/models/country.rb
12
+ rails_generators/geo/templates/models/county.rb
13
+ rails_generators/geo/templates/models/place.rb
14
+ rails_generators/geo/templates/models/state.rb
15
+ rails_generators/geo/templates/models/zip_code.rb
16
+ rails_generators/geo/templates/tasks/import_places.rake
@@ -0,0 +1,14 @@
1
+ GEO generator creates database migrations, models and helper rake tasks to add GEO functionality to a Rails application.
2
+
3
+ *Supported countries:*
4
+
5
+ * USA
6
+
7
+ h3. Usage
8
+
9
+ <pre><code>$ script/generate geo
10
+ </code></pre>
11
+
12
+
13
+ Built thanks to instructions:
14
+ http://buzaz.com/index.php/2010/01/03/how-to-build-a-ruby-gem/
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('elcgeo', '0.0.1') do |p|
5
+ Echoe.new('elcgeo', '0.0.2') do |p|
6
6
  p.description = "ELC Technologies GEO tools"
7
7
  p.url = "http://github.com/elc/elcgeo"
8
8
  p.author = "ELC Technologies"
data/TODO ADDED
@@ -0,0 +1,6 @@
1
+ - Update README
2
+ - Add Canada
3
+ - Add tests
4
+ - Add index to places table
5
+ - Add controllers(?)
6
+ - Publish gem to rubygems.org
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{elcgeo}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["ELC Technologies"]
9
- s.date = %q{2010-05-07}
9
+ s.date = %q{2010-05-11}
10
10
  s.description = %q{ELC Technologies GEO tools}
11
11
  s.email = %q{info @nospam@ elctech.com}
12
- s.extra_rdoc_files = ["lib/elcgeo.rb"]
13
- s.files = ["Rakefile", "lib/elcgeo.rb", "Manifest", "elcgeo.gemspec"]
12
+ s.extra_rdoc_files = ["README.textile", "TODO", "lib/elcgeo.rb"]
13
+ s.files = ["Manifest", "README.textile", "Rakefile", "TODO", "elcgeo.gemspec", "lib/elcgeo.rb", "rails_generators/geo/USAGE", "rails_generators/geo/geo_generator.rb", "rails_generators/geo/templates/migration.rb", "rails_generators/geo/templates/models/city.rb", "rails_generators/geo/templates/models/country.rb", "rails_generators/geo/templates/models/county.rb", "rails_generators/geo/templates/models/place.rb", "rails_generators/geo/templates/models/state.rb", "rails_generators/geo/templates/models/zip_code.rb", "rails_generators/geo/templates/tasks/import_places.rake"]
14
14
  s.homepage = %q{http://github.com/elc/elcgeo}
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Elcgeo", "--main", "README"]
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Elcgeo", "--main", "README.textile"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{elcgeo}
18
18
  s.rubygems_version = %q{1.3.6}
@@ -1,3 +1,5 @@
1
+ # nothing to see here, the real action is under rails_generators
2
+
1
3
  # rake install elcgeo.gemspec
2
4
  # start irb and test
3
5
  #
@@ -5,13 +7,13 @@
5
7
  # require 'rubygems'
6
8
  # require 'elcgeo'
7
9
  # ELC::Geo.version
8
- # => 0.1
10
+ # => 0.2
9
11
  #
10
12
  # rake gem
11
13
  module ELC
12
14
  module Geo
13
15
  def self.version
14
- puts '0.1'
16
+ puts '0.2'
15
17
  end
16
18
  end
17
19
  end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ The GEO generator creates database migrations, models and helper rake tasks to
3
+ add GEO functionality to a Rails application.
4
+
5
+ Supported countries:
6
+ * USA
7
+
8
+ Examples:
9
+ script/generate geo
@@ -0,0 +1,50 @@
1
+ class GeoGenerator < Rails::Generator::Base
2
+ def initialize(runtime_args, runtime_options = {})
3
+ super
4
+ end
5
+
6
+ def manifest
7
+ record do |m|
8
+ m.directory "app/models"
9
+ m.directory "lib"
10
+ m.directory "lib/tasks"
11
+ m.directory "db/migrate"
12
+ m.directory "db/data"
13
+
14
+ models = %w(city country county place state zip_code)
15
+ models.each do |model|
16
+ m.template "models/#{model}.rb", "app/models/#{model}.rb"
17
+ end
18
+
19
+ m.template "tasks/import_places.rake", "lib/tasks/import_places.rake"
20
+
21
+ m.migration_template "migration.rb", "db/migrate", :migration_file_name => "create_countries_and_places"
22
+
23
+ if test_framework == :rspec
24
+ else
25
+ end
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def test_framework
32
+ options[:test_framework] ||= File.exist?(destination_path("spec")) ? :rspec : :testunit
33
+ end
34
+
35
+ # def add_options!(opt)
36
+ # opt.separator ''
37
+ # opt.separator 'Options:'
38
+ # opt.on("--testunit", "Use test/unit for test files.") { options[:test_framework] = :testunit }
39
+ # opt.on("--rspec", "Use RSpec for test files.") { options[:test_framework] = :rspec }
40
+ # end
41
+
42
+ def banner
43
+ <<-EOS
44
+ Creates GEO models, migrations and helper rake tasks.
45
+
46
+ USAGE: #{$0} #{spec.name}
47
+ EOS
48
+ end
49
+
50
+ end
@@ -0,0 +1,66 @@
1
+ class CreateCountriesAndPlaces < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :places, :primary_key => :geonameid do |t|
4
+ t.string :name
5
+ t.string :asciiname
6
+ t.string :alternatenames, :limit => 4000
7
+ t.float :latitude
8
+ t.float :longitude
9
+ t.string :feature_class, :limit => 1
10
+ t.string :feature_code, :limit => 10
11
+ t.string :country_code, :limit => 2
12
+ t.string :cc2, :limit => 60
13
+ t.string :admin1_code, :limit => 20
14
+ t.string :admin2_code, :limit => 80
15
+ t.string :admin3_code, :limit => 20
16
+ t.string :admin4_code, :limit => 20
17
+ t.integer :population, :limit => 8
18
+ t.integer :elevation
19
+ t.integer :gtopo30
20
+ t.string :timezone
21
+ t.string :modification_date
22
+ t.integer :country_id
23
+ t.integer :state_id
24
+ t.integer :city_id
25
+ t.integer :county_id
26
+ t.string :type
27
+
28
+ t.timestamps
29
+ end
30
+
31
+ create_table :countries do |t|
32
+ t.string :name
33
+ t.string :abbr
34
+ t.string :code
35
+
36
+ t.timestamps
37
+ end
38
+ add_index :countries, :name
39
+ add_index :countries, :abbr
40
+ add_index :countries, :code
41
+
42
+ create_table :zip_codes do |t|
43
+ t.string :name
44
+ t.string :zip_code
45
+ t.string :lat
46
+ t.string :lng
47
+ t.string :country_code
48
+ t.string :country_name
49
+ t.string :state_province_code
50
+ t.string :state_province_name
51
+ t.integer :county_code
52
+ t.string :county_name
53
+ t.integer :state_id
54
+ t.integer :county_id
55
+ t.integer :city_id
56
+
57
+ t.timestamps
58
+ end
59
+ end
60
+
61
+ def self.down
62
+ drop_table :places
63
+ drop_table :countries
64
+ drop_table :zip_codes
65
+ end
66
+ end
@@ -0,0 +1,7 @@
1
+ class City < Place
2
+ belongs_to :country
3
+ belongs_to :state
4
+ belongs_to :county
5
+
6
+ named_scope :popular, :conditions => ['state_id IS NOT NULL'], :order => 'population DESC', :limit => 25
7
+ end
@@ -0,0 +1,10 @@
1
+ class Country < ActiveRecord::Base
2
+ attr_accessible :all
3
+ validates_presence_of :code, :name
4
+ validates_uniqueness_of :code, :abbr, :name
5
+
6
+ has_many :states
7
+ has_many :counties
8
+ end
9
+
10
+
@@ -0,0 +1,8 @@
1
+ class County < Place
2
+ belongs_to :country
3
+ belongs_to :state
4
+ has_many :cities, :class_name => "City", :foreign_key => "county_id"
5
+
6
+ named_scope :popular, :order => 'population DESC', :limit => 25
7
+ def county_code; admin2_code; end
8
+ end
@@ -0,0 +1,13 @@
1
+ class Place < ActiveRecord::Base
2
+ set_primary_key :geonameid
3
+
4
+ def state_province_code; admin1_code; end
5
+ alias :code :state_province_code
6
+
7
+ def lat; latitude; end
8
+ def lng; longitude; end
9
+
10
+ def self.find_by_code(code)
11
+ self.find_by_admin1_code(code)
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ class State < Place
2
+ has_many :counties
3
+ has_many :cities
4
+ has_many :zip_codes
5
+ belongs_to :country
6
+
7
+ named_scope :popular, :order => 'population DESC', :limit => 25
8
+
9
+ # This is US states...
10
+ # named_scope :states, :conditions => { :country_code => Country.find_by_country_code("US") }
11
+ end
@@ -0,0 +1,5 @@
1
+ class ZipCode < ActiveRecord::Base
2
+ belongs_to :state
3
+ belongs_to :county
4
+ belongs_to :city
5
+ end
@@ -0,0 +1,132 @@
1
+ namespace :import do
2
+
3
+ desc "Download and Import data files"
4
+ task :download_and_import do
5
+ Rake::Task["import:download"]. invoke
6
+ Rake::Task["import:places"]. invoke
7
+ Rake::Task["import:zip_codes"].invoke
8
+ end
9
+
10
+ desc "Download data files"
11
+ task :download do
12
+ puts 'Downloading http://download.geonames.org/export/zip/US.zip'
13
+ `cd db/data && curl -O http://download.geonames.org/export/zip/US.zip`
14
+ `cd db/data && unzip US.zip`
15
+ `cd db/data && rm US.zip`
16
+ `cd db/data && mv US.txt US_zip.csv`
17
+ `cd db/data && mv readme.txt US_zip_readme.txt`
18
+
19
+ puts 'Downloading http://download.geonames.org/export/dump/US.zip'
20
+ `cd db/data && curl -O http://download.geonames.org/export/dump/US.zip`
21
+ `cd db/data && unzip US.zip`
22
+ `cd db/data && rm US.zip`
23
+ `cd db/data && mv US.txt US.csv`
24
+ `cd db/data && mv readme.txt US_readme.txt`
25
+ puts
26
+ puts 'Done. Now run following rake tasks to import places and/or zip codes'
27
+ puts 'rake import:places'
28
+ puts 'rake import:zip_codes'
29
+ end
30
+
31
+ # This only works on MySQL because of the CSV "LOAD DATA INFILE"
32
+ desc "Import places"
33
+ task :places => :environment do
34
+ puts "Deleting all places..."
35
+ Place.delete_all
36
+
37
+ puts "Importing places..."
38
+ ActiveRecord::Base.connection.execute "LOAD DATA LOCAL INFILE '#{RAILS_ROOT}/db/data/US.csv' INTO TABLE places FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n';"
39
+
40
+ Place.delete_all("feature_code <> 'ADM1' AND feature_code <> 'ADM2' AND feature_code <> 'PPL' AND feature_code <> 'PPLA'")
41
+
42
+ puts "Updating states..."
43
+ Place.update_all("type = 'State'", "feature_code = 'ADM1'")
44
+ puts "Updating counties..."
45
+ Place.update_all("type = 'County'", "feature_code = 'ADM2'")
46
+ puts "Updating cities..."
47
+ Place.update_all("type = 'City'", "feature_code = 'PPL' OR feature_code = 'PPLA'")
48
+
49
+ puts "Setting country..."
50
+ country = Country.find_by_abbr("USA")
51
+ Place.update_all("country_id = #{country.id}") if country
52
+
53
+ Rake::Task["import:update_place_ids"].invoke
54
+
55
+ puts "Done."
56
+ end
57
+
58
+ task :update_place_ids => :environment do
59
+ State.find_each do |state|
60
+ sql_string = "update places
61
+ set state_id = #{state.id}
62
+ where admin1_code = \"#{state.state_province_code}\"
63
+ and type <> \"State\""
64
+ puts sql_string.gsub(/\n|\t/,"").squeeze(" ")
65
+ ActiveRecord::Base.connection.execute(sql_string)
66
+ end
67
+
68
+ County.find_each do |county|
69
+ sql_string = "update places
70
+ set county_id = #{county.id}
71
+ where admin2_code = \"#{county.county_code}\"
72
+ and admin1_code = \"#{county.state_province_code}\"
73
+ and type = \"City\""
74
+ puts sql_string.gsub(/\n|\t/,"").squeeze(" ")
75
+ ActiveRecord::Base.connection.execute(sql_string)
76
+ end
77
+ end
78
+
79
+ desc "Import zip codes"
80
+ task :zip_codes => :environment do
81
+ puts "Deleting all zip codes..."
82
+ ZipCode.delete_all
83
+
84
+ puts "Importing zip codes..."
85
+ ActiveRecord::Base.connection.execute "LOAD DATA LOCAL INFILE '#{RAILS_ROOT}/db/data/US_zip.csv' \
86
+ INTO TABLE zip_codes FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' \
87
+ (country_code, zip_code, name, state_province_name, state_province_code, county_name, county_code, lat, lng)"
88
+
89
+ Rake::Task["import:update_zipcode_ids"].invoke
90
+ end
91
+
92
+ desc "Update the city/county/state zipcode relationships"
93
+ task :update_zipcode_ids => :environment do
94
+ Rake::Task["import:update_zipcode_state_ids"].invoke
95
+ Rake::Task["import:update_zipcode_county_ids"].invoke
96
+ Rake::Task["import:update_zipcode_city_ids"].invoke
97
+ end
98
+
99
+ task :update_zipcode_state_ids => :environment do
100
+ puts "Updating the state zipcode relationships..."
101
+ State.find(:all).each do |state|
102
+ sql_string = "update zip_codes
103
+ set state_id = #{state.id}
104
+ where state_province_code = \'#{state.state_province_code}\'"
105
+ puts sql_string
106
+ ActiveRecord::Base.connection.execute(sql_string)
107
+ end
108
+ end
109
+
110
+ task :update_zipcode_county_ids => :environment do
111
+ puts "Updating the county zipcode relationships..."
112
+ County.find(:all).each do |county|
113
+ sql_string = "update zip_codes
114
+ set county_id = #{county.id}
115
+ where county_code = \"#{county.county_code}\"
116
+ and state_province_code = \'#{county.state_province_code}\'"
117
+ puts sql_string.gsub(/\n|\t/,"").squeeze(" ")
118
+ ActiveRecord::Base.connection.execute(sql_string)
119
+ end
120
+ end
121
+
122
+ task :update_zipcode_city_ids => :environment do
123
+ puts "Updating the city zipcode relationships..."
124
+ City.find(:all, :select => "geonameid, name, state_id, county_id, city_id", :conditions => 'name IS NOT NULL').each do |city|
125
+ if city.state_id && city.county_id
126
+ ZipCode.update_all("city_id = #{city.id}", "state_id = #{city.state_id} AND county_id = #{city.county_id} AND replace(name, '''', ' ') = '#{city.name.gsub(/\'/," ")}'")
127
+ puts "updated #{city.name} zip codes"
128
+ end
129
+ end
130
+ end
131
+
132
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - ELC Technologies
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-07 00:00:00 +01:00
17
+ date: 2010-05-11 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -25,12 +25,26 @@ executables: []
25
25
  extensions: []
26
26
 
27
27
  extra_rdoc_files:
28
+ - README.textile
29
+ - TODO
28
30
  - lib/elcgeo.rb
29
31
  files:
30
- - Rakefile
31
- - lib/elcgeo.rb
32
32
  - Manifest
33
+ - README.textile
34
+ - Rakefile
35
+ - TODO
33
36
  - elcgeo.gemspec
37
+ - lib/elcgeo.rb
38
+ - rails_generators/geo/USAGE
39
+ - rails_generators/geo/geo_generator.rb
40
+ - rails_generators/geo/templates/migration.rb
41
+ - rails_generators/geo/templates/models/city.rb
42
+ - rails_generators/geo/templates/models/country.rb
43
+ - rails_generators/geo/templates/models/county.rb
44
+ - rails_generators/geo/templates/models/place.rb
45
+ - rails_generators/geo/templates/models/state.rb
46
+ - rails_generators/geo/templates/models/zip_code.rb
47
+ - rails_generators/geo/templates/tasks/import_places.rake
34
48
  has_rdoc: true
35
49
  homepage: http://github.com/elc/elcgeo
36
50
  licenses: []
@@ -42,7 +56,7 @@ rdoc_options:
42
56
  - --title
43
57
  - Elcgeo
44
58
  - --main
45
- - README
59
+ - README.textile
46
60
  require_paths:
47
61
  - lib
48
62
  required_ruby_version: !ruby/object:Gem::Requirement