elcgeo 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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