geonames_local 0.3.1 → 0.5.0

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/README.rdoc CHANGED
@@ -1,19 +1,23 @@
1
1
  = Geonames Local
2
2
 
3
- Download and store Geonames.org data.
3
+ Download and store (pg, mongo, tokyo) Geonames.org data.
4
4
  Making every Geoname API operation possible on your servers.
5
5
  No hit limit, fast as possible.
6
6
 
7
7
 
8
8
  == Usage
9
9
 
10
- To use the adapter, install the corresponding gem:
10
+ To use one adapter, install the corresponding gem:
11
11
 
12
12
  PostgreSQL => pg
13
- MongoDB => mongodb (optional: mongo_ext)
13
+ MongoDB => mongo (optional: mongo_ext)
14
14
  Tokyo => tokyocabinet
15
15
 
16
- Don't forget to install *unzip* and *curl*.
16
+ You will also need in your system:
17
+
18
+ * unzip
19
+ * curl
20
+
17
21
 
18
22
  === PostgreSQL
19
23
 
@@ -35,7 +39,7 @@ The file is self explanatory.
35
39
 
36
40
  geonames -c geonames.yml
37
41
 
38
- Work. Use -v for verbose.
42
+ To run it. Use -v for verbose.
39
43
 
40
44
  If you are not sure your country code, use:
41
45
 
@@ -45,7 +49,14 @@ If you are not sure your country code, use:
45
49
  == Relational Mapping
46
50
 
47
51
  When using PG, this gem will (try) to relational map Geonames
48
- data on your scheme. Postgresql done, tokyo still need heavy work.
52
+ data on your scheme.
53
+
54
+ == ActiveRecord
55
+
56
+ Check out lib/geonames/models/ar.rb
57
+
58
+ I`m wondering the best way (and if it`s a good idea) to auto include'em on rails.
59
+ For now, just copy as you see fit.
49
60
 
50
61
 
51
62
  == PostgreSQL
@@ -55,6 +66,7 @@ So, supposing ActiveRecord, something like this is possible:
55
66
  City.first.province.country.abbr
56
67
  => "BR"
57
68
 
69
+
58
70
  === Migration
59
71
 
60
72
  Default PG migration:
@@ -62,7 +74,7 @@ Default PG migration:
62
74
  create_table :cities do |t|
63
75
  t.references :country, :null => false
64
76
  t.references :province
65
- t.string :name, :null => false
77
+ t.string :name, :null => false
66
78
  t.point :geom, :srid => 4326
67
79
  t.integer :gid, :zip
68
80
  end
@@ -80,22 +92,25 @@ Default PG migration:
80
92
  end
81
93
 
82
94
  add_index :cities, :name
83
- add_index :cities, :gid
84
95
  add_index :cities, :zip
85
96
  add_index :cities, :country_id
86
97
  add_index :cities, :province_id
98
+ add_index :cities, :gid, :unique => true
87
99
  add_index :cities, :geom, :spatial => true
88
100
  add_index :provinces, :name
89
101
  add_index :provinces, :abbr
90
- add_index :provinces, :gid
91
102
  add_index :provinces, :country_id
103
+ add_index :provinces, :gid, :unique => true
104
+ add_index :countries, :abbr, :unique => true
105
+ add_index :countries, :name, :unique => true
92
106
 
93
107
 
94
- == Features/Problems
108
+ == TODO/Problems
95
109
 
96
110
  - Local relational mapping of geonames data
97
- - Map geonames fields to your db scheme UNDONE
111
+ - Map geonames fields to your db scheme
98
112
  - Countries are a static yml file :/
113
+ - IP Geonames? http://ipinfodb.com
99
114
 
100
115
 
101
116
  == Note on Patches/Pull Requests
data/Rakefile CHANGED
@@ -44,20 +44,13 @@ rescue LoadError
44
44
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
45
45
  end
46
46
 
47
- require 'spec/rake/spectask'
48
- Spec::Rake::SpecTask.new(:spec) do |spec|
49
- spec.libs << 'lib' << 'spec'
50
- spec.spec_files = FileList['spec/**/*_spec.rb']
47
+ require 'rspec/core/rake_task'
48
+ desc "Runs spec suite"
49
+ RSpec::Core::RakeTask.new(:spec) do |spec|
50
+ spec.pattern = 'spec/*_spec.rb'
51
+ spec.rspec_opts = ['--backtrace --colour']
51
52
  end
52
53
 
53
- Spec::Rake::SpecTask.new(:rcov) do |spec|
54
- spec.libs << 'lib' << 'spec'
55
- spec.pattern = 'spec/**/*_spec.rb'
56
- spec.rcov = true
57
- end
58
-
59
- task :spec => :check_dependencies
60
-
61
54
  task :default => :spec
62
55
 
63
56
  require 'rake/rdoctask'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.5.0
data/bin/geonames CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  $VERBOSE = true # -w
3
- $KCODE = "u" # -Ku
3
+ # $KCODE = "u" # -Ku
4
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
5
 
6
6
  require "geonames_cli"
data/geonames.yml CHANGED
@@ -1,14 +1,15 @@
1
1
  #
2
2
  # Geonames Local Config Example
3
3
  #
4
- :store: mongodb
4
+ :store: postgres
5
5
  :codes: [br]
6
6
  :level: city
7
+ :min_pop: 100000
7
8
  :mapping:
8
9
  :name: name
9
10
  :geom: true
10
11
  :db:
11
12
  :host: localhost
12
- :dbname: rtrac_development
13
+ :dbname: geonames_ar
13
14
  :user: postgres
14
15
  :password:
@@ -1,74 +1,71 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{geonames_local}
8
- s.version = "0.3.1"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Marcos Piccinini"]
12
- s.date = %q{2010-09-14}
12
+ s.date = %q{2011-04-24}
13
13
  s.default_executable = %q{geonames}
14
14
  s.description = %q{Dump and feed a tokyo cabinet for local geonames search}
15
15
  s.email = %q{x@nofxx.com}
16
16
  s.executables = ["geonames"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE",
19
- "README.rdoc"
19
+ "README.rdoc"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
- ".gitignore",
24
- "LICENSE",
25
- "README.rdoc",
26
- "Rakefile",
27
- "VERSION",
28
- "bin/geonames",
29
- "geonames.yml",
30
- "geonames_local.gemspec",
31
- "lib/geonames_ar.rb",
32
- "lib/geonames_cli.rb",
33
- "lib/geonames_local.rb",
34
- "lib/geonames_local/adapters/mongodb.rb",
35
- "lib/geonames_local/adapters/postgres.rb",
36
- "lib/geonames_local/adapters/tokyo.rb",
37
- "lib/geonames_local/cli.rb",
38
- "lib/geonames_local/config/codes.yml",
39
- "lib/geonames_local/config/geonames.sql",
40
- "lib/geonames_local/config/geonames.yml",
41
- "lib/geonames_local/data/dump.rb",
42
- "lib/geonames_local/data/export.rb",
43
- "lib/geonames_local/data/shp.rb",
44
- "lib/geonames_local/features/road.rb",
45
- "lib/geonames_local/features/spot.rb",
46
- "lib/geonames_local/features/zone.rb",
47
- "lib/geonames_local/geonames.rb",
48
- "lib/geonames_local/model/city.rb",
49
- "lib/geonames_local/model/country.rb",
50
- "lib/geonames_local/model/province.rb",
51
- "lib/geonames_local/mongo/city.rb",
52
- "lib/geonames_local/mongo/country.rb",
53
- "lib/geonames_local/mongo/province.rb",
54
- "spec/geonames_local/adapters/mongodb_spec.rb",
55
- "spec/geonames_local/adapters/postgres_spec.rb",
56
- "spec/geonames_local/adapters/tokyo_spec.rb",
57
- "spec/geonames_local/cli_spec.rb",
58
- "spec/geonames_local/data/cache_spec.rb",
59
- "spec/geonames_local/data/shp_spec.rb",
60
- "spec/geonames_local/features/road_spec.rb",
61
- "spec/geonames_local/features/spot_spec.rb",
62
- "spec/geonames_local/features/zone_spec.rb",
63
- "spec/geonames_local/model/ar_spec.rb",
64
- "spec/geonames_local/mongo/city_spec.rb",
65
- "spec/geonames_local_spec.rb",
66
- "spec/spec.opts",
67
- "spec/spec_ar_helper.rb",
68
- "spec/spec_helper.rb",
69
- "spec/spec_mongo_helper.rb",
70
- "task/benchmark.rb",
71
- "task/benchmark_cabinet.rb"
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/geonames",
28
+ "geonames.yml",
29
+ "geonames_local.gemspec",
30
+ "lib/geonames_ar.rb",
31
+ "lib/geonames_cli.rb",
32
+ "lib/geonames_local.rb",
33
+ "lib/geonames_local/adapters/mongodb.rb",
34
+ "lib/geonames_local/adapters/postgres.rb",
35
+ "lib/geonames_local/adapters/tokyo.rb",
36
+ "lib/geonames_local/cli.rb",
37
+ "lib/geonames_local/config/codes.yml",
38
+ "lib/geonames_local/config/geonames.sql",
39
+ "lib/geonames_local/config/geonames.yml",
40
+ "lib/geonames_local/data/dump.rb",
41
+ "lib/geonames_local/data/export.rb",
42
+ "lib/geonames_local/data/shp.rb",
43
+ "lib/geonames_local/data/sync.rb",
44
+ "lib/geonames_local/features/road.rb",
45
+ "lib/geonames_local/features/spot.rb",
46
+ "lib/geonames_local/features/zone.rb",
47
+ "lib/geonames_local/geonames.rb",
48
+ "lib/geonames_local/models/ar.rb",
49
+ "lib/geonames_local/models/mongo.rb",
50
+ "lib/geonames_local/models/tokyo.rb",
51
+ "spec/geonames_local/adapters/mongodb_spec.rb",
52
+ "spec/geonames_local/adapters/postgres_spec.rb",
53
+ "spec/geonames_local/adapters/tokyo_spec.rb",
54
+ "spec/geonames_local/cli_spec.rb",
55
+ "spec/geonames_local/data/cache_spec.rb",
56
+ "spec/geonames_local/data/dump_spec.rb",
57
+ "spec/geonames_local/data/shp_spec.rb",
58
+ "spec/geonames_local/features/road_spec.rb",
59
+ "spec/geonames_local/features/spot_spec.rb",
60
+ "spec/geonames_local/features/zone_spec.rb",
61
+ "spec/geonames_local/models/ar_spec.rb",
62
+ "spec/geonames_local/models/mongo_spec.rb",
63
+ "spec/geonames_local_spec.rb",
64
+ "spec/spec_ar_helper.rb",
65
+ "spec/spec_helper.rb",
66
+ "spec/spec_mongo_helper.rb",
67
+ "task/benchmark.rb",
68
+ "task/benchmark_cabinet.rb"
72
69
  ]
73
70
  s.homepage = %q{http://github.com/nofxx/geonames_local}
74
71
  s.post_install_message = %q{
@@ -94,26 +91,26 @@ http://github.com/mongodb/mongo-ruby-driver
94
91
 
95
92
  Have fun because:
96
93
  }
97
- s.rdoc_options = ["--charset=UTF-8"]
98
94
  s.require_paths = ["lib"]
99
95
  s.rubygems_version = %q{1.3.7}
100
96
  s.summary = %q{Dump and feed a tokyo local geonames db}
101
97
  s.test_files = [
98
+ "spec/geonames_local/adapters/mongodb_spec.rb",
99
+ "spec/geonames_local/adapters/postgres_spec.rb",
100
+ "spec/geonames_local/adapters/tokyo_spec.rb",
101
+ "spec/geonames_local/cli_spec.rb",
102
+ "spec/geonames_local/data/cache_spec.rb",
103
+ "spec/geonames_local/data/dump_spec.rb",
104
+ "spec/geonames_local/data/shp_spec.rb",
105
+ "spec/geonames_local/features/road_spec.rb",
106
+ "spec/geonames_local/features/spot_spec.rb",
107
+ "spec/geonames_local/features/zone_spec.rb",
108
+ "spec/geonames_local/models/ar_spec.rb",
109
+ "spec/geonames_local/models/mongo_spec.rb",
110
+ "spec/geonames_local_spec.rb",
102
111
  "spec/spec_ar_helper.rb",
103
- "spec/spec_helper.rb",
104
- "spec/geonames_local/data/shp_spec.rb",
105
- "spec/geonames_local/data/cache_spec.rb",
106
- "spec/geonames_local/model/ar_spec.rb",
107
- "spec/geonames_local/mongo/city_spec.rb",
108
- "spec/geonames_local/cli_spec.rb",
109
- "spec/geonames_local/adapters/postgres_spec.rb",
110
- "spec/geonames_local/adapters/tokyo_spec.rb",
111
- "spec/geonames_local/adapters/mongodb_spec.rb",
112
- "spec/geonames_local/features/spot_spec.rb",
113
- "spec/geonames_local/features/zone_spec.rb",
114
- "spec/geonames_local/features/road_spec.rb",
115
- "spec/spec_mongo_helper.rb",
116
- "spec/geonames_local_spec.rb"
112
+ "spec/spec_helper.rb",
113
+ "spec/spec_mongo_helper.rb"
117
114
  ]
118
115
 
119
116
  if s.respond_to? :specification_version then
data/lib/geonames_ar.rb CHANGED
@@ -4,11 +4,9 @@
4
4
  $:.unshift(File.dirname(__FILE__)) unless
5
5
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
6
6
 
7
+ # Adapter = Geonames::Postgres.new(Opt[:db])
7
8
  # Require Libs
8
9
  require 'geonames_local/geonames'
9
10
 
10
- require 'geonames_local/model/country'
11
- require 'geonames_local/model/province'
12
- require 'geonames_local/model/city'
11
+ require 'geonames_local/models/ar'
13
12
  #require 'geonames_local/data/shp'
14
-
data/lib/geonames_cli.rb CHANGED
@@ -6,8 +6,9 @@ $:.unshift(File.dirname(__FILE__)) unless
6
6
 
7
7
  # Require CLI Stuff
8
8
  require 'geonames_local/geonames'
9
- require 'geonames_local/cli'
10
9
  require 'geonames_local/data/shp'
11
10
  require 'geonames_local/data/dump'
11
+ require 'geonames_local/data/sync'
12
12
  require 'geonames_local/data/export'
13
+ require 'geonames_local/cli'
13
14
 
@@ -78,7 +78,8 @@ module Geonames
78
78
  # getNear command returns distance too
79
79
  # <1.9 needs OrderedHash
80
80
  def near(resource, x, y, limit=nil)
81
- cmd = OrderedHash.new
81
+ # FIXME: Better explicity require OrderedHash?
82
+ cmd = Object.const_defined?("OrderedHash") ? OrderedHash.new : { }
82
83
  cmd["geoNear"] = resource
83
84
  cmd["near"] = sin_proj(x,y)
84
85
  cmd["num"] = limit if limit
@@ -5,27 +5,30 @@ module Geonames
5
5
  Countries = {}
6
6
  Provinces = {}
7
7
 
8
- def initialize(opts) #table, addr = "localhost", port = 5432)
8
+ def initialize(opts={}) #table, addr = "localhost", port = 5432)
9
9
  @conn = PGconn.new(opts)
10
10
  end
11
11
 
12
12
  #
13
13
  # Get Country and Province ID from the DB
14
+ #
15
+ # Maps the FKs ids correctly for our bank
16
+ #
14
17
  def get_some_ids(some)
15
- c = Countries[some.country] ||=
18
+ cid = Countries[some.country] ||=
16
19
  @conn.exec("SELECT countries.id FROM countries WHERE UPPER(countries.abbr) = UPPER('#{some.country}')")[0]["id"] rescue nil
17
- c ||= write("countries", {:name => Codes[some.country.downcase.to_sym][:pt_br], :abbr => some.country })
20
+ cid ||= write("countries", {:name => Codes[some.country.downcase.to_sym][:pt_br], :abbr => some.country })
18
21
 
19
- p = nil
20
- ci = nil
22
+ pid = nil
23
+ tid = nil
21
24
  if some.kind_of? Spot
22
- p = Provinces[some.province] ||= find("provinces", Cache[:provinces].
25
+ pid = Provinces[some.province] ||= find("provinces", Cache[:provinces].
23
26
  find{ |p| p.province == some.province}.gid)
24
27
  else
25
- ci = find("cities", some.city)
26
- p = @conn.exec("SELECT cities.province_id FROM cities WHERE cities.id = #{ci}")[0]["province_id"] rescue nil
28
+ tid = find("cities", some.city)
29
+ pid = @conn.exec("SELECT cities.province_id FROM cities WHERE cities.id = #{tid}")[0]["province_id"] rescue nil
27
30
  end
28
- [c, p, ci]
31
+ [cid, pid, tid]
29
32
  end
30
33
 
31
34
  #
@@ -33,22 +36,25 @@ module Geonames
33
36
  def insert(table, some)
34
37
  country_id, province_id, city_id = get_some_ids(some)
35
38
  case table
36
- when :cities
39
+ when :city
37
40
  write("cities", {:name => some.name, :country_id => country_id,
38
41
  :geom => some.geom.as_hex_ewkb, :gid => some.gid,
39
42
  :zip => some.zip, :province_id => province_id})
40
- when :provinces
43
+ when :province
41
44
  write("provinces", { :name => some.name, :abbr => some.abbr,
42
45
  :country_id => country_id, :gid => some.gid })
43
- when :roads
46
+ when :road
44
47
  write("roads", { :name => some.name, :geom => some.geom.as_hex_ewkb, :kind => some.kind,
45
48
  :country_id => country_id, :city_id => city_id, :province_id => province_id })
49
+ else
50
+ puts "Fail to insert #{some}"
46
51
  end
47
52
  end
48
53
 
49
54
  #
50
55
  # Find a record`s ID
51
- def find(table, id, name=nil)
56
+ def find(kind, id, name=nil)
57
+ table = get_table kind
52
58
  begin
53
59
  if name
54
60
  @conn.exec("SELECT #{table}.id FROM #{table} WHERE (#{table}.name = E'#{id}')")[0]["id"]
@@ -79,6 +85,15 @@ module Geonames
79
85
  end.join(",")
80
86
  end
81
87
 
88
+ def get_table(kind)
89
+ case kind
90
+ when :city then "cities"
91
+ when :country then "countries"
92
+ else
93
+ kind.to_s + "s"
94
+ end
95
+ end
96
+
82
97
  #
83
98
  # Naive PG insert ORM =D
84
99
  def write(table, hsh)
@@ -60,6 +60,11 @@ BANNER
60
60
  Opt.merge! YAML.load(File.read(Opt[:config]))
61
61
  end
62
62
 
63
+ # Load config/geonames.yml if there's one
64
+ if File.exists?(cfg = File.join("config", "geonames.yml"))
65
+ Opt.merge! YAML.load(File.read(cfg))
66
+ end
67
+
63
68
  if shp = Opt[:shp]
64
69
  SHP.import(shp)
65
70
  exit
@@ -94,69 +99,14 @@ BANNER
94
99
  if argv[0] =~ /csv|json/
95
100
  Geonames::Export.new(Country.all).to_csv
96
101
  else
97
- db = load_adapter(Opt[:store])
98
102
  info "Using adapter #{Opt[:store]}.."
99
103
  Geonames::Dump.work(Opt[:codes], :zip) #rescue puts "Command not found: #{comm} #{@usage}"
100
104
  Geonames::Dump.work(Opt[:codes], :dump) #rescue puts "Command not found: #{comm} #{@usage}"
101
105
  info "\n---\nTotal #{Cache[:dump].length} parsed. #{Cache[:zip].length} zips."
102
- info "Join dump << zip"
103
- unify!
104
- write_to_store!(db)
105
- end
106
- end
107
-
108
- def load_adapter(name)
109
- begin
110
- require "geonames_local/adapters/#{name}"
111
- Geonames.class_eval(name.capitalize).new(Opt[:db])
112
- rescue LoadError
113
- puts "Can't find adapter #{name}"
114
- stop!
106
+ Sync.work!
115
107
  end
116
108
  end
117
109
 
118
- def write_to_store!(db)
119
- groups = Cache[:dump].group_by(&:kind)
120
- Cache[:provinces] = groups[:provinces]
121
- # ensure this order....
122
- do_write(db, groups[:provinces])
123
- do_write(db, groups[:cities])
124
- end
125
-
126
- def do_write(db, values)
127
- return if values.empty?
128
- key = values[0].table
129
- start = Time.now
130
- writt = 0
131
- info "\nWriting #{values.length} #{key}..."
132
- values.each do |val|
133
- meth = val.respond_to?(:gid) ? [val.gid] : [val.name, true]
134
- unless db.find(val.table, *meth)
135
- db.insert(val.table, val)
136
- writt += 1
137
- end
138
- end
139
- total = Time.now - start
140
- info "#{writt} #{key} written in #{total} sec (#{(writt/total).to_i}/s)"
141
- end
142
-
143
- def unify!
144
- start = Time.now
145
- Cache[:dump].map! do |spot|
146
- if other = Cache[:zip].find { |d| d.code == spot.code }
147
- spot.zip = other.zip
148
- spot
149
- else
150
- spot
151
- end
152
- end
153
- info "Done. #{(Time.now-start).to_i}s"
154
- end
155
-
156
- def stop!
157
- puts "Closing Geonames..."
158
- exit
159
- end
160
110
  end
161
111
 
162
112
  end