geo_coder 0.1.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.
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>