geo_coder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/Gemfile +12 -0
  2. data/Gemfile.lock +32 -0
  3. data/History.txt +6 -0
  4. data/Makefile +13 -0
  5. data/Manifest.txt +18 -0
  6. data/README.rdoc +197 -0
  7. data/Rakefile +53 -0
  8. data/TODO.txt +8 -0
  9. data/VERSION +1 -0
  10. data/bin/build_indexes +8 -0
  11. data/bin/rebuild_cluster +22 -0
  12. data/bin/rebuild_metaphones +23 -0
  13. data/bin/tiger_import +59 -0
  14. data/demos/demo/app/ext/geocodewrap.rb +84 -0
  15. data/demos/demo/app/views/index.builder +13 -0
  16. data/demos/demo/app/views/index.erb +71 -0
  17. data/demos/demo/config.ru +12 -0
  18. data/demos/demo/config/bootstraps.rb +130 -0
  19. data/demos/demo/config/geoenvironment.rb +25 -0
  20. data/demos/demo/geocoder_helper.rb +12 -0
  21. data/demos/demo/geocom_geocode.rb +10 -0
  22. data/demos/demo/main.rb +3 -0
  23. data/demos/demo/rakefile.rb +17 -0
  24. data/demos/demo/tmp/restart.txt +0 -0
  25. data/demos/simpledemo/views/index.builder +13 -0
  26. data/demos/simpledemo/views/index.erb +69 -0
  27. data/demos/simpledemo/ws.rb +83 -0
  28. data/doc/Makefile +7 -0
  29. data/doc/html4css1.css +279 -0
  30. data/doc/lookup.rst +193 -0
  31. data/doc/parsing.rst +125 -0
  32. data/doc/voidspace.css +147 -0
  33. data/geo_coder.gemspec +172 -0
  34. data/lib/geocoder/us.rb +21 -0
  35. data/lib/geocoder/us/address.rb +290 -0
  36. data/lib/geocoder/us/constants.rb +670 -0
  37. data/lib/geocoder/us/database.rb +745 -0
  38. data/lib/geocoder/us/import.rb +181 -0
  39. data/lib/geocoder/us/import/tiger.rb +13 -0
  40. data/lib/geocoder/us/numbers.rb +58 -0
  41. data/navteq/README +4 -0
  42. data/navteq/convert.sql +37 -0
  43. data/navteq/navteq_import +39 -0
  44. data/navteq/prepare.sql +92 -0
  45. data/sql/cluster.sql +16 -0
  46. data/sql/convert.sql +80 -0
  47. data/sql/create.sql +37 -0
  48. data/sql/index.sql +12 -0
  49. data/sql/place.csv +104944 -0
  50. data/sql/place.sql +104948 -0
  51. data/sql/setup.sql +78 -0
  52. data/src/Makefile +13 -0
  53. data/src/README +14 -0
  54. data/src/liblwgeom/Makefile +75 -0
  55. data/src/liblwgeom/box2d.c +54 -0
  56. data/src/liblwgeom/lex.yy.c +4799 -0
  57. data/src/liblwgeom/liblwgeom.h +1405 -0
  58. data/src/liblwgeom/lwalgorithm.c +946 -0
  59. data/src/liblwgeom/lwalgorithm.h +52 -0
  60. data/src/liblwgeom/lwcircstring.c +759 -0
  61. data/src/liblwgeom/lwcollection.c +541 -0
  62. data/src/liblwgeom/lwcompound.c +118 -0
  63. data/src/liblwgeom/lwcurvepoly.c +86 -0
  64. data/src/liblwgeom/lwgeom.c +886 -0
  65. data/src/liblwgeom/lwgeom_api.c +2201 -0
  66. data/src/liblwgeom/lwgparse.c +1219 -0
  67. data/src/liblwgeom/lwgunparse.c +1054 -0
  68. data/src/liblwgeom/lwline.c +525 -0
  69. data/src/liblwgeom/lwmcurve.c +125 -0
  70. data/src/liblwgeom/lwmline.c +137 -0
  71. data/src/liblwgeom/lwmpoint.c +138 -0
  72. data/src/liblwgeom/lwmpoly.c +141 -0
  73. data/src/liblwgeom/lwmsurface.c +129 -0
  74. data/src/liblwgeom/lwpoint.c +439 -0
  75. data/src/liblwgeom/lwpoly.c +579 -0
  76. data/src/liblwgeom/lwsegmentize.c +1047 -0
  77. data/src/liblwgeom/lwutil.c +369 -0
  78. data/src/liblwgeom/measures.c +861 -0
  79. data/src/liblwgeom/postgis_config.h +93 -0
  80. data/src/liblwgeom/ptarray.c +847 -0
  81. data/src/liblwgeom/vsprintf.c +179 -0
  82. data/src/liblwgeom/wktparse.h +126 -0
  83. data/src/liblwgeom/wktparse.lex +74 -0
  84. data/src/liblwgeom/wktparse.tab.c +2353 -0
  85. data/src/liblwgeom/wktparse.tab.h +145 -0
  86. data/src/liblwgeom/wktparse.y +385 -0
  87. data/src/libsqlite3_geocoder/Makefile +22 -0
  88. data/src/libsqlite3_geocoder/Makefile.nix +15 -0
  89. data/src/libsqlite3_geocoder/Makefile.redhat +15 -0
  90. data/src/libsqlite3_geocoder/extension.c +121 -0
  91. data/src/libsqlite3_geocoder/extension.h +13 -0
  92. data/src/libsqlite3_geocoder/levenshtein.c +42 -0
  93. data/src/libsqlite3_geocoder/metaphon.c +278 -0
  94. data/src/libsqlite3_geocoder/util.c +37 -0
  95. data/src/libsqlite3_geocoder/wkb_compress.c +54 -0
  96. data/src/metaphone/Makefile +7 -0
  97. data/src/metaphone/README +49 -0
  98. data/src/metaphone/extension.c +37 -0
  99. data/src/metaphone/metaphon.c +251 -0
  100. data/src/shp2sqlite/Makefile +37 -0
  101. data/src/shp2sqlite/Makefile.nix +36 -0
  102. data/src/shp2sqlite/Makefile.redhat +35 -0
  103. data/src/shp2sqlite/dbfopen.c +1595 -0
  104. data/src/shp2sqlite/getopt.c +695 -0
  105. data/src/shp2sqlite/getopt.h +127 -0
  106. data/src/shp2sqlite/shapefil.h +500 -0
  107. data/src/shp2sqlite/shp2sqlite.c +1974 -0
  108. data/src/shp2sqlite/shpopen.c +1894 -0
  109. data/tests/address.rb +236 -0
  110. data/tests/benchmark.rb +20 -0
  111. data/tests/constants.rb +57 -0
  112. data/tests/data/address-sample.csv +52 -0
  113. data/tests/data/db-test.csv +57 -0
  114. data/tests/data/locations.csv +4 -0
  115. data/tests/database.rb +137 -0
  116. data/tests/generate.rb +34 -0
  117. data/tests/numbers.rb +46 -0
  118. data/tests/run.rb +11 -0
  119. metadata +237 -0
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'geocoder/us/database'
3
+ require 'logger'
4
+
5
+ module Sinatra
6
+ module GeocodeWrap
7
+ attr_accessor :db
8
+ def self.registered(app)
9
+ options = {:cache_size => 100000}
10
+ @@db = Geocoder::US::Database.new("/Users/katechapman/usgeocode.db", options)
11
+ stats = Logger.new("geocoderstats.log", 10, 1024000)
12
+ app.get '/' do
13
+ unless params[:address].nil?
14
+ begin
15
+ @records = @@db.geocode params[:address]
16
+ stats.debug "Geocoded: 1, Failed: 0, Geocoded At: " << DateTime.now.to_s
17
+ rescue Exception => e
18
+ stats.debug "Geocoded: 1, Failed: 1, Geocoded At: " << DateTime.now.to_s
19
+ puts e.message
20
+ end
21
+ end
22
+
23
+ case params[:format]
24
+ when /xml/
25
+ builder :index
26
+ when /atom/
27
+ builder :atom
28
+ when /json/
29
+ @records.to_json
30
+ else
31
+ erb :index
32
+ end
33
+ end
34
+
35
+ app.post '/batch' do
36
+ failed_codes = 0
37
+ total_codes = 0
38
+ puts Time.now
39
+ if params[:uploaded_csv].nil?
40
+ csv_file = request.env["rack.input"].read
41
+ csv = FasterCSV.parse(csv_file, :row_sep => "*", :col_sep => "|")
42
+ else
43
+ FileUtils.mkdir_p('uploads/')
44
+ FileUtils.mv(params[:uploaded_csv][:tempfile].path, "uploads/#{params[:uploaded_csv][:filename]}")
45
+ csv_file = open("uploads/#{params[:uploaded_csv][:filename]}")
46
+ @filename = params[:uploaded_csv][:filename].gsub(/\.csv/,"")
47
+ csv = FasterCSV.parse(csv_file)
48
+ end
49
+ headers = csv[0]
50
+
51
+ @records = csv.collect do |record|
52
+ total_codes += 1
53
+ next if record == headers
54
+ begin
55
+ result = @@db.geocode record[1]
56
+ if result.empty?
57
+ result[0] = {:lon => nil, :lat => nil, :precision => 'unmatched', :score => 0}
58
+ failed_codes += 1
59
+ end
60
+ result.first.merge(headers[0] => record[0])
61
+ rescue Exception => e
62
+ failed_codes += 1
63
+ puts e.message
64
+ next
65
+ end
66
+ end.compact
67
+ puts Time.now
68
+ stats.debug "Geocoded: " << total_codes.to_s << ", Failed: " << failed_codes.to_s << ",Geocoded At: " << DateTime.now.to_s
69
+ case params[:format]
70
+ when /xml/
71
+ builder :index
72
+ when /atom/
73
+ builder :atom
74
+ when /json/
75
+ @records.to_json
76
+
77
+ else
78
+ erb :index
79
+ end
80
+ end
81
+ end
82
+ end
83
+ register GeocodeWrap
84
+ end
@@ -0,0 +1,13 @@
1
+ xml.locations do
2
+ unless @records.nil?
3
+ @records.each do |record|
4
+ xml.location do
5
+ xml.score format("%.2f", record[:score]*100)
6
+ %w{lat lon number prefix pretyp predir prequal street suftyp sufdir sufqual city state zip}.each do |field|
7
+ xml.tag! field, record[field.to_sym]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html
2
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
+ <head>
6
+ <style type="text/css">
7
+ html {font-family: Arial, sans-serif;}
8
+ table {font-size: 8pt; border-collapse: collapse;}
9
+ td { border: 1px solid black; padding: .25em .5em .25em .5em; }
10
+ </style>
11
+ </head>
12
+ <body onload="">
13
+ <p><b>Geocoder Demo</b></p>
14
+ <p>
15
+ <form>
16
+ <label>Enter an address:</label> <input type="text" name="address" value="<%= params[:address] %>" size="80">
17
+ <input type="submit" value="Geocode" />
18
+ </form>
19
+ <form action="batch" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
20
+ <label>Upload a CSV:</label> <input type="file" name="uploaded_csv" id="uploaded_csv">
21
+ <input type="submit" value="Batch Geocode" />
22
+ </form>
23
+ </p>
24
+ <% unless @records.nil? %>
25
+ <table>
26
+ <tr>
27
+ <td>Match</td>
28
+ <td>Precision</td>
29
+ <td>Lat</td>
30
+ <td>Lon</td>
31
+ <td>#</td>
32
+ <td>Qual</td>
33
+ <td>Dir</td>
34
+ <td>Type</td>
35
+ <td>Street</td>
36
+ <td>Type</td>
37
+ <td>Dir</td>
38
+ <td>Qual</td>
39
+ <td>City</td>
40
+ <td>St</td>
41
+ <td>ZIP</td>
42
+ <td>&nbsp;</td>
43
+ </tr>
44
+ <% for record in @records %>
45
+ <tr>
46
+ <td><%= format("%.2f", record[:score]*100) %>%</td>
47
+ <td><%= record[:precision].to_s %></td>
48
+ <td><%= record[:lat].to_s %></td>
49
+ <td><%= record[:lon].to_s %></td>
50
+ <td><%= record[:prefix] if record[:prefix] %><%= record[:number] %></td>
51
+ <td><%= record[:pretyp] %></td>
52
+ <td><%= record[:predir] %></td>
53
+ <td><%= record[:prequal] %></td>
54
+ <td><%= record[:street] %></td>
55
+ <td><%= record[:suftyp] %></td>
56
+ <td><%= record[:sufdir] %></td>
57
+ <td><%= record[:sufqual] %></td>
58
+ <td><%= record[:city] %></td>
59
+ <td><%= record[:state] %></td>
60
+ <td><%= record[:zip] %></td>
61
+ <td><a href="http://maps.google.com/maps?q=<%=record[:lat]%>,<%=record[:lon]%>"
62
+ target="_blank">map</a></td>
63
+ </tr>
64
+ <% end %>
65
+ </table>
66
+ <% end %>
67
+ <% unless @filename.nil? %>
68
+ <a href="/link.atom?filename=<%= @filename %>">Atom Feed</a>
69
+ <% end %>
70
+ </body>
71
+ </html>
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+
4
+
5
+ Sinatra::Application.default_options.merge!(
6
+ :run => false,
7
+ :env => ENV['RACK_ENV']
8
+ )
9
+ require 'geocom_geocode'
10
+ run GeocomGeocode::GeocodeServer
11
+
12
+
@@ -0,0 +1,130 @@
1
+ require 'rubygems'
2
+
3
+ module BootStraps
4
+
5
+ class Framework
6
+
7
+ def initialize
8
+ @methods = {}
9
+ end
10
+
11
+ def apply_settings!(app)
12
+ @methods.each_pair do |method, calls|
13
+ calls.each do |arg_set|
14
+ app.send(method, *arg_set)
15
+ end
16
+ end
17
+ end
18
+
19
+ def method_missing(method, *args)
20
+ @methods[method] ||= []
21
+ @methods[method] << args
22
+ end
23
+ end
24
+
25
+
26
+ class DataStore
27
+ def connect_action(&block)
28
+ @connect_action = block
29
+ end
30
+
31
+ #TODO raise UndefinedConnectAction
32
+ def connect
33
+ @connect_action.call if @connect_action
34
+ end
35
+ end
36
+
37
+ class Configuration
38
+ attr_accessor :db, :global, :default_env, :vendor_dir, :lib_paths, :framework, :vendored
39
+ attr_reader :gems
40
+
41
+ def initialize
42
+ @framework = Framework.new
43
+ @gems = {}
44
+ @global = {}
45
+ @default_env = 'production'
46
+ @vendor_dir = File.join(root, 'vendor')
47
+ @lib_paths = []
48
+ @vendored = false
49
+ end
50
+
51
+ def env
52
+ ENV['RACK_ENV'] ||= default_env
53
+ end
54
+
55
+ def env=(val)
56
+ ENV['RACK_ENV'] = val
57
+ end
58
+
59
+ def root
60
+ File.join(File.expand_path(File.dirname(__FILE__)), "..")
61
+ end
62
+
63
+ def gem(*args)
64
+ gem = args.first
65
+ ver = args.last
66
+
67
+ @gems[gem] = ver
68
+
69
+ #its concievable that vendored could be changed mid config
70
+ use_vendor if vendored
71
+ Kernel.send(:gem, *args)
72
+ require gem
73
+ end
74
+
75
+ private
76
+ def use_vendor
77
+ Gem.clear_paths
78
+ prepend_gem_path!(File.join(root, 'vendor'))
79
+ end
80
+
81
+ def prepend_gem_path!(path)
82
+ ENV['GEM_PATH'] = path
83
+ end
84
+ end
85
+
86
+ class Initializer
87
+ @@config = Configuration.new
88
+ class << self
89
+ def configure
90
+ unless @@config.frozen?
91
+ yield @@config
92
+ @@config.freeze
93
+ end
94
+ end
95
+
96
+ def config
97
+ @@config
98
+ end
99
+
100
+ def boot!
101
+ require File.join(@@config.root, 'config', 'geoenvironment.rb')
102
+ require_libs
103
+ end
104
+
105
+
106
+ private
107
+ def require_libs
108
+ [
109
+ subdir_expansion('lib'),
110
+ subdir_expansion(File.join('app','ext'))
111
+ ].each do |p|
112
+ require_all(p)
113
+ end
114
+ end
115
+
116
+ def require_all(path)
117
+ Dir[path].each { |f| require f }
118
+ end
119
+
120
+ def subdir_expansion(subdir)
121
+ File.join(@@config.root, subdir, '**', '*.rb')
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ BootStraps::Initializer.boot!
128
+ Straps = BootStraps::Initializer.config
129
+
130
+
@@ -0,0 +1,25 @@
1
+
2
+ BootStraps::Initializer.configure do |config|
3
+
4
+ #Use the vendor directory
5
+ config.vendored = true
6
+ config.default_env = 'production'
7
+
8
+ config.gem 'sinatra'
9
+ config.gem 'fastercsv'
10
+ config.gem 'json'
11
+
12
+
13
+
14
+
15
+ config.framework.set :root, config.root
16
+ config.framework.set :environment, config.env
17
+ config.framework.set :raise_errors, true
18
+ config.framework.set :views, File.join('app','views')
19
+ config.framework.set :server, 'mongrel'
20
+ config.framework.set :static, true
21
+ config.framework.set :logging, true
22
+ config.framework.set :port, 4567
23
+ config.framework.set :lock, false
24
+
25
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'geocoder/us/database'
3
+ require 'fastercsv'
4
+ require 'json'
5
+
6
+
7
+
8
+ def initialize
9
+
10
+
11
+
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'config/bootstraps'
2
+
3
+ module GeocomGeocode
4
+ class GeocodeServer < Sinatra::Base
5
+ register Sinatra::GeocodeWrap
6
+ configure do
7
+ Straps.framework.apply_settings!(self)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ require 'geocom_geocode'
2
+
3
+ GeocomGeocode::GeocodeServer.run!
@@ -0,0 +1,17 @@
1
+ require 'rake'
2
+
3
+ task :boot_env do
4
+ require 'config/bootstraps';
5
+ end
6
+
7
+ namespace :db do
8
+ task :migrate => :connect do
9
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
10
+ ActiveRecord::Migration.verbose = true
11
+ ActiveRecord::Migrator.migrate('db/migrate/', nil)
12
+ end
13
+
14
+ task :connect => :boot_env do
15
+ BootStraps::Initializer.config.db.connect
16
+ end
17
+ end
File without changes
@@ -0,0 +1,13 @@
1
+ xml.locations do
2
+ unless @records.nil?
3
+ @records.each do |record|
4
+ xml.location do
5
+ xml.score format("%.2f", record[:score]*100)
6
+ %w{lat lon number prefix pretyp predir prequal street suftyp sufdir sufqual city state zip}.each do |field|
7
+ xml.tag! field, record[field.to_sym]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,69 @@
1
+ <!DOCTYPE html
2
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
+ <head>
6
+ <style type="text/css">
7
+ html {font-family: Arial, sans-serif;}
8
+ table {font-size: 8pt; border-collapse: collapse;}
9
+ td { border: 1px solid black; padding: .25em .5em .25em .5em; }
10
+ </style>
11
+ </head>
12
+ <body onload="">
13
+ <p><b>Geocoder Demo</b></p>
14
+ <p>
15
+ <form>
16
+ <label>Enter an address:</label> <input type="text" name="address" value="<%= params[:address] %>" size="80">
17
+ <input type="submit" value="Geocode" />
18
+ </form>
19
+ <form action="batch" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
20
+ <label>Upload a CSV:</label> <input type="file" name="uploaded_csv" id="uploaded_csv">
21
+ <input type="submit" value="Batch Geocode" />
22
+ </form>
23
+ </p>
24
+ <% unless @records.nil? %>
25
+ <table>
26
+ <tr>
27
+ <td>Match</td>
28
+ <td>Lat</td>
29
+ <td>Lon</td>
30
+ <td>#</td>
31
+ <td>Qual</td>
32
+ <td>Dir</td>
33
+ <td>Type</td>
34
+ <td>Street</td>
35
+ <td>Type</td>
36
+ <td>Dir</td>
37
+ <td>Qual</td>
38
+ <td>City</td>
39
+ <td>St</td>
40
+ <td>ZIP</td>
41
+ <td>&nbsp;</td>
42
+ </tr>
43
+ <% for record in @records %>
44
+ <tr>
45
+ <td><%= format("%.2f", record[:score]*100) %>%</td>
46
+ <td><%= record[:lat].to_s %></td>
47
+ <td><%= record[:lon].to_s %></td>
48
+ <td><%= record[:prefix] if record[:prefix] %><%= record[:number] %></td>
49
+ <td><%= record[:pretyp] %></td>
50
+ <td><%= record[:predir] %></td>
51
+ <td><%= record[:prequal] %></td>
52
+ <td><%= record[:street] %></td>
53
+ <td><%= record[:suftyp] %></td>
54
+ <td><%= record[:sufdir] %></td>
55
+ <td><%= record[:sufqual] %></td>
56
+ <td><%= record[:city] %></td>
57
+ <td><%= record[:state] %></td>
58
+ <td><%= record[:zip] %></td>
59
+ <td><a href="http://maps.google.com/maps?q=<%=record[:lat]%>,<%=record[:lon]%>"
60
+ target="_blank">map</a></td>
61
+ </tr>
62
+ <% end %>
63
+ </table>
64
+ <% end %>
65
+ <% unless @filename.nil? %>
66
+ <a href="/link.atom?filename=<%= @filename %>">Atom Feed</a>
67
+ <% end %>
68
+ </body>
69
+ </html>