geonozzle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Joe Edelman, Citizen Logistics INC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = geonozzle
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Citizen Logistics, INC. See LICENSE for details.
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "geonozzle"
8
+ gem.summary = "Some extra geocoding and caching smarts atop geokit"
9
+ gem.description = "Some extra geocoding and caching smarts atop geokit"
10
+ gem.email = "joe@citizenlogistics.com"
11
+ gem.homepage = "http://github.com/citizenlogistics/geonozzle"
12
+ gem.authors = ["Joe Edelman"]
13
+ gem.add_dependency "geokit"
14
+ gem.add_dependency "methodcache"
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "geonozzle #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,53 @@
1
+ require 'geokit'
2
+ require 'tzinfo'
3
+ require 'set'
4
+ require 'methodcache'
5
+
6
+ require 'geonozzle/country_codes'
7
+ require 'geonozzle/city'
8
+ require 'geonozzle/cities'
9
+ require 'geonozzle/locstring'
10
+
11
+ module Geonozzle
12
+ extend MethodCache::ModuleExtensions
13
+ module_function
14
+ PretendGeo = Struct.new(:lat, :lng, :acc, :cc2)
15
+
16
+ def basic_geocode(loc, cc2 = nil)
17
+ g = GeoKit::Geocoders::GoogleGeocoder.geocode(loc, :bias => cc2)
18
+ g if g && g.success
19
+ end
20
+
21
+ def city_radial_geocode(city_num, loc)
22
+ spot = City.num(city_num).to_lat_lng
23
+ [2, 5, 10, 30].each do |distance_in_miles|
24
+ bounds = Geokit::Bounds.from_point_and_radius(spot, distance_in_miles)
25
+ geoloc = GeoKit::Geocoders::GoogleGeocoder.geocode(loc, :bias => bounds) rescue nil
26
+ next unless geoloc and geoloc.success and geoloc.distance_to(spot) < distance_in_miles
27
+ geoloc
28
+ end
29
+ end
30
+
31
+ module_cache :basic_geocode, :with => :redis
32
+ module_cache :city_radial_geocode, :with => :redis
33
+
34
+ def universal_geocode(loc, city=nil, delegate=nil)
35
+ loc.strip!
36
+ loc.extend Locstring
37
+ loc.blank? and return
38
+ ll = loc.lat_lng? and return PretendGeo.new(ll.first, ll.last, 'building')
39
+ city, loc = loc.city, loc.noncity_part if loc.city
40
+ city = nil if loc.obviously_worldwide?
41
+ loc = loc.normalized
42
+
43
+ result = nil
44
+ if city
45
+ result ||= delegate && delegate.call(loc, city)
46
+ result ||= basic_geocode("#{loc}, #{city.name}")
47
+ result ||= radial_geocode(city.num, loc)
48
+ end
49
+ result ||= delegate && delegate.call(loc, nil)
50
+ result ||= basic_geocode(loc)
51
+ return result
52
+ end
53
+ end
@@ -0,0 +1,484 @@
1
+ Geonozzle::City.new(1,'Dunedin, New Zealand',-45.86,170.5)
2
+ Geonozzle::City.new(2,'Christchurch, New Zealand',-43.53,172.63)
3
+ Geonozzle::City.new(3,'Hobart, Australia',-42.9167,147.333)
4
+ Geonozzle::City.new(4,'Wellington, New Zealand',-41.3,174.78)
5
+ Geonozzle::City.new(5,'Nelson, New Zealand',-41.28,173.28)
6
+ Geonozzle::City.new(6,'Melbourne, Australia',-37.8167,144.967)
7
+ Geonozzle::City.new(7,'Hamilton, New Zealand',-37.78,175.28)
8
+ Geonozzle::City.new(8,'Auckland, New Zealand',-36.86,174.76)
9
+ Geonozzle::City.new(9,'Canberra, Australia',-35.2833,149.217)
10
+ Geonozzle::City.new(10,'Adelaide, Australia',-34.9333,138.6)
11
+ Geonozzle::City.new(11,'Buenos Aires, Argentina',-34.5875,-58.6725)
12
+ Geonozzle::City.new(12,'Cape Town, South Africa',-33.91,18.41)
13
+ Geonozzle::City.new(13,'Sydney, Australia',-33.8833,151.217)
14
+ Geonozzle::City.new(14,'Santiago, Chile',-33.45,-70.6667)
15
+ Geonozzle::City.new(15,'Newcastle, Australia',-32.9167,151.75)
16
+ Geonozzle::City.new(16,'Mendoza, Argentina',-32.8833,-68.8167)
17
+ Geonozzle::City.new(17,'Perth, Australia',-31.9333,115.833)
18
+ Geonozzle::City.new(18,'Cordoba, Argentina',-31.4,-64.18)
19
+ Geonozzle::City.new(19,'Porto Alegre, Brazil',-30.0333,-51.2)
20
+ Geonozzle::City.new(20,'Durban, South Africa',-29.85,31.01)
21
+ Geonozzle::City.new(21,'Gold Coast, Australia',-28,153.43)
22
+ Geonozzle::City.new(22,'Florianopolis, Brazil',-27.5833,-48.5667)
23
+ Geonozzle::City.new(23,'Brisbane, Australia',-27.5,153.01)
24
+ Geonozzle::City.new(24,'Johannesburg, South Africa',-26.2,28.08)
25
+ Geonozzle::City.new(25,'Pretoria, South Africa',-25.7069,28.2294)
26
+ Geonozzle::City.new(26,'Curitiba, Brazil',-25.4167,-49.25)
27
+ Geonozzle::City.new(27,'Sao Paulo, Brazil',-23.5333,-46.6167)
28
+ Geonozzle::City.new(28,'Campinas, Brazil',-22.9,-47.08)
29
+ Geonozzle::City.new(29,'Rio de Janeiro, Brazil',-22.9,-43.23)
30
+ Geonozzle::City.new(30,'Niteroi, Brazil',-22.8844,-43.0944)
31
+ Geonozzle::City.new(31,'Belo Horizonte, Brazil',-19.9167,-43.9333)
32
+ Geonozzle::City.new(32,'Arequipa, Peru',-16.39,-71.53)
33
+ Geonozzle::City.new(33,'Brasilia, Brazil',-15.7833,-47.9167)
34
+ Geonozzle::City.new(34,'Salvador, Brazil',-14.6833,-41.0333)
35
+ Geonozzle::City.new(35,'Lima, Peru',-12.05,-77.05)
36
+ Geonozzle::City.new(36,'Recife, Brazil',-8.05,-34.9)
37
+ Geonozzle::City.new(37,'Jakarta, Indonesia',-6.17,106.82)
38
+ Geonozzle::City.new(38,'Fortaleza, Brazil',-3.71667,-38.5)
39
+ Geonozzle::City.new(39,'Nairobi, Kenya',-1.28,36.81)
40
+ Geonozzle::City.new(40,'Quito, Ecuador',-0.21,-78.5)
41
+ Geonozzle::City.new(41,'Kampala, Uganda',0.31,32.58)
42
+ Geonozzle::City.new(42,'Singapore, Singapore',1.29306,103.856)
43
+ Geonozzle::City.new(43,'Petaling Jaya, Malaysia',3.08333,101.65)
44
+ Geonozzle::City.new(44,'Kuala Lumpur, Malaysia',3.16667,101.7)
45
+ Geonozzle::City.new(45,'Bogota, Colombia',4.6,-74.0833)
46
+ Geonozzle::City.new(46,'Abidjan, Cote D''Ivoire',5.31,-4.03)
47
+ Geonozzle::City.new(47,'Accra, Ghana',5.55,-0.21)
48
+ Geonozzle::City.new(48,'San Jose, Costa Rica',9.93333,-84.0833)
49
+ Geonozzle::City.new(49,'Caracas, Venezuela',10.5,-66.9167)
50
+ Geonozzle::City.new(50,'Bangalore, India',12.98,77.58)
51
+ Geonozzle::City.new(51,'Chennai, India',13.08,80.28)
52
+ Geonozzle::City.new(52,'Bangkok, Thailand',13.75,100.51)
53
+ Geonozzle::City.new(53,'Manila, Philippines',14.6042,120.982)
54
+ Geonozzle::City.new(54,'Guatemala, Guatemala',14.62,-90.52)
55
+ Geonozzle::City.new(55,'Hyderabad, India',17.3753,78.4744)
56
+ Geonozzle::City.new(56,'San Juan, Puerto Rico',18.4683,-66.1061)
57
+ Geonozzle::City.new(57,'Pune, India',18.53,73.86)
58
+ Geonozzle::City.new(58,'Mumbai, India',18.97,72.82)
59
+ Geonozzle::City.new(59,'Mexico, Mexico',19.4,-99.05)
60
+ Geonozzle::City.new(60,'Guadalajara, Mexico',20.66,-103.33)
61
+ Geonozzle::City.new(61,'Honolulu, United States',21.3,-157.85)
62
+ Geonozzle::City.new(62,'Hong Kong, China',22.28,114.15)
63
+ Geonozzle::City.new(63,'Shenzhen, China',22.5333,114.133)
64
+ Geonozzle::City.new(64,'Calcutta, India',22.56,88.36)
65
+ Geonozzle::City.new(65,'Guangzhou, China',23.1167,113.25)
66
+ Geonozzle::City.new(66,'Karachi, Pakistan',24.8667,67.05)
67
+ Geonozzle::City.new(67,'Taipei, Taiwan',25.037,121.507)
68
+ Geonozzle::City.new(68,'Dubai, United Arab Emirates',25.2522,55.28)
69
+ Geonozzle::City.new(69,'Monterrey, Mexico',25.66,-100.31)
70
+ Geonozzle::City.new(70,'Miami, United States',25.7739,-80.1939)
71
+ Geonozzle::City.new(71,'Fort Lauderdale, United States',26.1219,-80.1436)
72
+ Geonozzle::City.new(72,'Sarasota, United States',27.3361,-82.5308)
73
+ Geonozzle::City.new(73,'Kathmandu, Nepal',27.71,85.31)
74
+ Geonozzle::City.new(74,'Saint Petersburg, United States',27.7706,-82.6794)
75
+ Geonozzle::City.new(75,'Tampa, United States',27.9472,-82.4586)
76
+ Geonozzle::City.new(76,'Orlando, United States',28.53,-81.37)
77
+ Geonozzle::City.new(77,'New Delhi, India',28.6,77.2)
78
+ Geonozzle::City.new(78,'San Antonio, United States',29.4239,-98.4933)
79
+ Geonozzle::City.new(79,'Gainesville, United States',29.6514,-82.325)
80
+ Geonozzle::City.new(80,'Houston, United States',29.7631,-95.3631)
81
+ Geonozzle::City.new(81,'New Orleans, United States',29.9544,-90.075)
82
+ Geonozzle::City.new(82,'Cairo, Egypt',30.05,31.25)
83
+ Geonozzle::City.new(83,'Austin, United States',30.2669,-97.7428)
84
+ Geonozzle::City.new(84,'Jacksonville, United States',30.33,-81.65)
85
+ Geonozzle::City.new(85,'Agadir, Morocco',30.4,-9.6)
86
+ Geonozzle::City.new(86,'Tallahassee, United States',30.4381,-84.2808)
87
+ Geonozzle::City.new(87,'Baton Rouge, United States',30.4506,-91.1544)
88
+ Geonozzle::City.new(88,'College Station, United States',30.6278,-96.3342)
89
+ Geonozzle::City.new(89,'Shanghai, China',31.2222,121.458)
90
+ Geonozzle::City.new(90,'Marrakech, Morocco',31.63,-8)
91
+ Geonozzle::City.new(91,'Tel Aviv, Israel',32.06,34.76)
92
+ Geonozzle::City.new(92,'Savannah, United States',32.0833,-81.1)
93
+ Geonozzle::City.new(93,'Tucson, United States',32.2217,-110.926)
94
+ Geonozzle::City.new(94,'Distrito Federal, Mexico',32.49,-115.03)
95
+ Geonozzle::City.new(95,'San Diego, United States',32.7153,-117.156)
96
+ Geonozzle::City.new(96,'Fort Worth, United States',32.7253,-97.3206)
97
+ Geonozzle::City.new(97,'Charleston, United States',32.7764,-79.9311)
98
+ Geonozzle::City.new(98,'Dallas, United States',32.78332901,-96.800003052)
99
+ Geonozzle::City.new(99,'Haifa, Israel',32.81,34.98)
100
+ Geonozzle::City.new(100,'Denton, United States',33.2147,-97.1328)
101
+ Geonozzle::City.new(101,'Tempe, United States',33.4147,-111.909)
102
+ Geonozzle::City.new(102,'Mesa, United States',33.4222,-111.822)
103
+ Geonozzle::City.new(103,'Phoenix, United States',33.4483,-112.073)
104
+ Geonozzle::City.new(104,'Damascus, Syria',33.5,36.3)
105
+ Geonozzle::City.new(105,'Scottsdale, United States',33.5092,-111.898)
106
+ Geonozzle::City.new(106,'Birmingham, United States',33.5206,-86.8025)
107
+
108
+ Geonozzle::City.new(107,'Casablanca, Morocco',33.59,-7.61)
109
+ Geonozzle::City.new(108,'Huntington Beach, United States',33.6603,-117.998)
110
+ Geonozzle::City.new(109,'Irvine, United States',33.6694,-117.822)
111
+ Geonozzle::City.new(110,'Atlanta, United States',33.7489,-84.3881)
112
+ Geonozzle::City.new(111,'Long Beach, United States',33.76,-118.18)
113
+ Geonozzle::City.new(112,'Athens, United States',33.9608,-83.3781)
114
+ Geonozzle::City.new(113,'Venice, United States',33.9908,-118.459)
115
+ Geonozzle::City.new(114,'Columbia, United States',34.0006,-81.035)
116
+ Geonozzle::City.new(115,'Santa Monica, United States',34.0194,-118.49)
117
+ Geonozzle::City.new(116,'Rabat, Morocco',34.02,-6.83)
118
+ Geonozzle::City.new(117,'Los Angeles, United States',34.0522,-118.243)
119
+ Geonozzle::City.new(118,'Hollywood, United States',34.0983,-118.326)
120
+ Geonozzle::City.new(119,'Pasadena, United States',34.1478,-118.144)
121
+ Geonozzle::City.new(120,'Wilmington, United States',34.2256,-77.945)
122
+ Geonozzle::City.new(121,'Santa Barbara, United States',34.4208,-119.697)
123
+ Geonozzle::City.new(122,'Albuquerque, United States',35.0844,-106.651)
124
+ Geonozzle::City.new(123,'Pusan, South Korea',35.1,129.04)
125
+ Geonozzle::City.new(124,'Memphis, United States',35.1494,-90.0489)
126
+ Geonozzle::City.new(125,'Flagstaff, United States',35.1981,-111.651)
127
+ Geonozzle::City.new(126,'Norman, United States',35.2225,-97.4392)
128
+ Geonozzle::City.new(127,'Charlotte, United States',35.2269,-80.8433)
129
+ Geonozzle::City.new(128,'San Luis Obispo, United States',35.28,-120.65)
130
+ Geonozzle::City.new(129,'Oklahoma City, United States',35.4675,-97.5161)
131
+ Geonozzle::City.new(130,'Asheville, United States',35.6008,-82.5542)
132
+ Geonozzle::City.new(131,'Tehran, Iran',35.67,51.42)
133
+ Geonozzle::City.new(132,'Tokyo, Japan',35.68,139.75)
134
+ Geonozzle::City.new(133,'Santa Fe, United States',35.6869,-105.937)
135
+ Geonozzle::City.new(134,'Raleigh, United States',35.77,-78.63)
136
+ Geonozzle::City.new(135,'Chapel Hill, United States',35.9131,-79.0561)
137
+ Geonozzle::City.new(136,'Knoxville, United States',35.96,-83.92)
138
+ Geonozzle::City.new(137,'Greensboro, United States',36.0725,-79.7922)
139
+ Geonozzle::City.new(138,'Tulsa, United States',36.1539,-95.9925)
140
+ Geonozzle::City.new(139,'Nashville, United States',36.1658,-86.7844)
141
+ Geonozzle::City.new(140,'Las Vegas, United States',36.175,-115.136)
142
+ Geonozzle::City.new(141,'Malaga, Spain',36.7167,-4.41667)
143
+ Geonozzle::City.new(142,'Fresno, United States',36.7478,-119.771)
144
+ Geonozzle::City.new(143,'Virginia Beach, United States',36.8528,-75.9783)
145
+ Geonozzle::City.new(144,'Antalya, Turkey',36.9125,30.6897)
146
+ Geonozzle::City.new(145,'Santa Cruz, United States',36.97,-122.02)
147
+ Geonozzle::City.new(146,'Faro, Portugal',37.0167,-7.93333)
148
+ Geonozzle::City.new(147,'Granada, Spain',37.1833,-3.6)
149
+ Geonozzle::City.new(148,'Arlington, United States',37.2264,-76.0017)
150
+ Geonozzle::City.new(149,'San Jose, United States',37.3394,-121.894)
151
+ Geonozzle::City.new(150,'Sevilla, Spain',37.3772,-5.98694)
152
+ Geonozzle::City.new(151,'Palo Alto, United States',37.4419,-122.142)
153
+ Geonozzle::City.new(152,'Catania, Italy',37.5,15.1)
154
+ Geonozzle::City.new(153,'Richmond, United States',37.5536,-77.4606)
155
+ Geonozzle::City.new(154,'Seoul, South Korea',37.56,126.99)
156
+ Geonozzle::City.new(155,'San Francisco, United States',37.775,-122.418)
157
+ Geonozzle::City.new(156,'Athens, Greece',37.98,23.73)
158
+ Geonozzle::City.new(157,'Lexington, United States',37.9886,-84.4778)
159
+ Geonozzle::City.new(158,'Charlottesville, United States',38.02,-78.47)
160
+ Geonozzle::City.new(159,'Palermo, Italy',38.11,13.36)
161
+ Geonozzle::City.new(160,'Louisville, United States',38.25,-85.75)
162
+ Geonozzle::City.new(161,'Izmir, Turkey',38.4072,27.1503)
163
+ Geonozzle::City.new(162,'Davis, United States',38.545,-121.739)
164
+ Geonozzle::City.new(163,'Sacramento, United States',38.5817,-121.493)
165
+ Geonozzle::City.new(164,'Saint Louis, United States',38.6272,-90.1978)
166
+ Geonozzle::City.new(165,'Cascais, Portugal',38.7,-9.41)
167
+ Geonozzle::City.new(166,'Lisboa, Portugal',38.7167,-9.13333)
168
+ Geonozzle::City.new(167,'Amadora, Portugal',38.75,-9.23)
169
+ Geonozzle::City.new(168,'Sintra, Portugal',38.8,-9.38333)
170
+ Geonozzle::City.new(169,'Alexandria, United States',38.8047,-77.0472)
171
+ Geonozzle::City.new(170,'Colorado Springs, United States',38.8339,-104.821)
172
+ Geonozzle::City.new(171,'Fairfax, United States',38.8461,-77.3067)
173
+ Geonozzle::City.new(172,'Washington, United States',38.89,-77.03)
174
+ Geonozzle::City.new(173,'Columbia, United States',38.9517,-92.3339)
175
+ Geonozzle::City.new(174,'Lawrence, United States',38.9717,-95.235)
176
+ Geonozzle::City.new(175,'Silver Spring, United States',38.9906,-77.0264)
177
+ Geonozzle::City.new(176,'Kansas City, United States',39.09,-94.57)
178
+ Geonozzle::City.new(177,'Bloomington, United States',39.16,-86.52)
179
+ Geonozzle::City.new(178,'Cincinnati, United States',39.1619,-84.4569)
180
+ Geonozzle::City.new(179,'Cagliari, Italy',39.21,9.11)
181
+ Geonozzle::City.new(180,'Baltimore, United States',39.29,-76.61)
182
+ Geonozzle::City.new(181,'Washington, United States',39.3594,-120.798)
183
+ Geonozzle::City.new(182,'Reno, United States',39.5297,-119.813)
184
+ Geonozzle::City.new(183,'Chico, United States',39.72,-121.83)
185
+ Geonozzle::City.new(184,'Denver, United States',39.7392,-104.984)
186
+ Geonozzle::City.new(185,'Leiria, Portugal',39.75,-8.8)
187
+ Geonozzle::City.new(186,'Indianapolis, United States',39.7683,-86.1581)
188
+ Geonozzle::City.new(187,'Ankara, Turkey',39.9272,32.8644)
189
+ Geonozzle::City.new(188,'Beijing, China',39.9289,116.388)
190
+ Geonozzle::City.new(189,'Philadelphia, United States',39.95,-75.16)
191
+ Geonozzle::City.new(190,'Columbus, United States',39.9611,-82.9989)
192
+ Geonozzle::City.new(191,'Boulder, United States',40.015,-105.27)
193
+ Geonozzle::City.new(192,'Coimbra, Portugal',40.2,-8.41)
194
+ Geonozzle::City.new(193,'Madrid, Spain',40.4,-3.68)
195
+ Geonozzle::City.new(194,'Pittsburgh, United States',40.4406,-79.9961)
196
+ Geonozzle::City.new(195,'Fort Collins, United States',40.5853,-105.084)
197
+ Geonozzle::City.new(196,'Aveiro, Portugal',40.6333,-8.65)
198
+ Geonozzle::City.new(197,'Thessaloniki, Greece',40.64,22.94)
199
+ Geonozzle::City.new(198,'Brooklyn, United States',40.65,-73.95)
200
+ Geonozzle::City.new(199,'Salt Lake City, United States',40.7608,-111.89)
201
+ Geonozzle::City.new(200,'State College, United States',40.7933,-77.8603)
202
+ Geonozzle::City.new(201,'Lincoln, United States',40.8,-96.66)
203
+ Geonozzle::City.new(202,'Naples, Italy',40.83,14.25)
204
+ Geonozzle::City.new(203,'Arcata, United States',40.8667,-124.082)
205
+ Geonozzle::City.new(204,'Istanbul, Turkey',41.0186,28.9647)
206
+ Geonozzle::City.new(205,'Bari, Italy',41.13,16.85)
207
+ Geonozzle::City.new(206,'Vila Nova de Gaia, Portugal',41.1333,-8.61667)
208
+ Geonozzle::City.new(207,'Porto, Portugal',41.15,-8.61)
209
+ Geonozzle::City.new(208,'Omaha, United States',41.2586,-95.9375)
210
+ Geonozzle::City.new(209,'New Haven, United States',41.3,-72.92)
211
+ Geonozzle::City.new(210,'Barcelona, Spain',41.3833,2.18333)
212
+ Geonozzle::City.new(211,'Cleveland, United States',41.49,-81.69)
213
+ Geonozzle::City.new(212,'Braga, Portugal',41.55,-8.43)
214
+ Geonozzle::City.new(213,'Iowa City, United States',41.6611,-91.53)
215
+ Geonozzle::City.new(214,'Providence, United States',41.8239,-71.4133)
216
+ Geonozzle::City.new(215,'Chicago, United States',41.85,-87.65)
217
+ Geonozzle::City.new(216,'Rome, Italy',41.9,12.48)
218
+ Geonozzle::City.new(217,'Ames, United States',42.0347,-93.6197)
219
+ Geonozzle::City.new(218,'Ann Arbor, United States',42.2708,-83.7264)
220
+ Geonozzle::City.new(219,'Kalamazoo, United States',42.2917,-85.5872)
221
+ Geonozzle::City.new(220,'Northampton, MA, United States',42.325,-72.6417)
222
+ Geonozzle::City.new(221,'Detroit, United States',42.3314,-83.0458)
223
+ Geonozzle::City.new(222,'Windsor, Canada',42.3333,-83.0333)
224
+ Geonozzle::City.new(223,'Boston, United States',42.3583,-71.0603)
225
+ Geonozzle::City.new(224,'Valencia, Spain',42.4,-7.06667)
226
+ Geonozzle::City.new(225,'Ithaca, United States',42.4406,-76.4969)
227
+ Geonozzle::City.new(226,'Sofia, Bulgaria',42.6833,23.3167)
228
+ Geonozzle::City.new(227,'East Lansing, United States',42.7369,-84.4839)
229
+ Geonozzle::City.new(228,'Buffalo, United States',42.8864,-78.8786)
230
+ Geonozzle::City.new(229,'Grand Rapids, United States',42.9633,-85.6681)
231
+ Geonozzle::City.new(230,'London, Canada',42.9833,-81.25)
232
+ Geonozzle::City.new(231,'Milwaukee, United States',43.0389,-87.9064)
233
+ Geonozzle::City.new(232,'Syracuse, United States',43.0481,-76.1478)
234
+ Geonozzle::City.new(233,'Madison, United States',43.0731,-89.4011)
235
+ Geonozzle::City.new(234,'Perugia, Italy',43.13,12.36)
236
+ Geonozzle::City.new(235,'Mississauga, Canada',43.15,-79.5)
237
+ Geonozzle::City.new(236,'Rochester, United States',43.1547,-77.6158)
238
+ Geonozzle::City.new(237,'Hamilton, Canada',43.25,-79.83)
239
+ Geonozzle::City.new(238,'Marseille, France',43.3,5.4)
240
+ Geonozzle::City.new(239,'Kitchener, Canada',43.45,-80.5)
241
+ Geonozzle::City.new(240,'Waterloo, Canada',43.4667,-80.5333)
242
+ Geonozzle::City.new(241,'Aix-en-Provence, France',43.53,5.43)
243
+ Geonozzle::City.new(242,'Guelph, Canada',43.55,-80.25)
244
+ Geonozzle::City.new(243,'Montpellier, France',43.6,3.88)
245
+ Geonozzle::City.new(244,'Toulouse, France',43.6,1.43)
246
+ Geonozzle::City.new(245,'Boise, United States',43.6136,-116.202)
247
+ Geonozzle::City.new(246,'Portland, United States',43.6614,-70.2558)
248
+ Geonozzle::City.new(247,'Toronto, Canada',43.6667,-79.4167)
249
+ Geonozzle::City.new(248,'Nice, France',43.7,7.25)
250
+ Geonozzle::City.new(249,'Pisa, Italy',43.71,10.38)
251
+ Geonozzle::City.new(250,'Florence, Italy',43.76,11.25)
252
+ Geonozzle::City.new(251,'Eugene, United States',44.0522,-123.086)
253
+ Geonozzle::City.new(252,'Kingston, Canada',44.3,-76.56)
254
+ Geonozzle::City.new(253,'Peterborough, Canada',44.3,-78.33)
255
+ Geonozzle::City.new(254,'Barrie, Canada',44.3833,-79.7)
256
+ Geonozzle::City.new(255,'Genova, Italy',44.41,8.95)
257
+ Geonozzle::City.new(256,'Bucharest, Romania',44.4333,26.1)
258
+ Geonozzle::City.new(257,'Burlington, United States',44.4758,-73.2125)
259
+ Geonozzle::City.new(258,'Bologna, Italy',44.48,11.33)
260
+ Geonozzle::City.new(259,'Corvallis, United States',44.5647,-123.261)
261
+ Geonozzle::City.new(260,'Halifax, Canada',44.65,-63.6)
262
+ Geonozzle::City.new(261,'Parma, Italy',44.8,10.33)
263
+ Geonozzle::City.new(262,'Belgrade, Serbia and Montenegro',44.8186,20.4681)
264
+ Geonozzle::City.new(263,'Bordeaux, France',44.83,-0.56)
265
+ Geonozzle::City.new(264,'Salem, United States',44.9431,-123.034)
266
+ Geonozzle::City.new(265,'Saint Paul, United States',44.9444,-93.0931)
267
+ Geonozzle::City.new(266,'Minneapolis, United States',44.98,-93.26)
268
+ Geonozzle::City.new(267,'Torino, Italy',45.05,7.66)
269
+ Geonozzle::City.new(268,'Grenoble, France',45.16,5.71)
270
+ Geonozzle::City.new(269,'Novi Sad, Serbia and Montenegro',45.2517,19.8369)
271
+ Geonozzle::City.new(270,'Sherbrooke, Canada',45.4,-71.9)
272
+ Geonozzle::City.new(271,'Padova, Italy',45.41,11.88)
273
+ Geonozzle::City.new(272,'Ottawa, Canada',45.4167,-75.7)
274
+ Geonozzle::City.new(273,'Venezia, Italy',45.43,12.32)
275
+ Geonozzle::City.new(274,'Verona, Italy',45.45,11)
276
+ Geonozzle::City.new(275,'Milano, Italy',45.46,9.2)
277
+ Geonozzle::City.new(276,'Gatineau, Canada',45.4833,-75.65)
278
+ Geonozzle::City.new(277,'Montreal, Canada',45.5,-73.58)
279
+ Geonozzle::City.new(278,'Portland, United States',45.5236,-122.675)
280
+ Geonozzle::City.new(279,'Longueuil, Canada',45.5333,-73.5167)
281
+ Geonozzle::City.new(280,'Brescia, Italy',45.55,10.25)
282
+ Geonozzle::City.new(281,'Vicenza, Italy',45.55,11.55)
283
+ Geonozzle::City.new(282,'Laval, Canada',45.6,-73.73)
284
+ Geonozzle::City.new(283,'Trieste, Italy',45.64,13.78)
285
+ Geonozzle::City.new(284,'Treviso, Italy',45.66,12.24)
286
+ Geonozzle::City.new(285,'Bozeman, United States',45.6797,-111.038)
287
+ Geonozzle::City.new(286,'Bergamo, Italy',45.68,9.71)
288
+ Geonozzle::City.new(287,'Lyon, France',45.75,4.85)
289
+ Geonozzle::City.new(288,'Clermont-Ferrand, France',45.78,3.08)
290
+ Geonozzle::City.new(289,'Zagreb, Croatia',45.8,16)
291
+ Geonozzle::City.new(290,'Annecy, France',45.9,6.11)
292
+ Geonozzle::City.new(291,'Ljubljana, Slovenia',46.0553,14.5144)
293
+ Geonozzle::City.new(292,'Trento, Italy',46.06,11.13)
294
+ Geonozzle::City.new(293,'Pecs, Hungary',46.08,18.23)
295
+ Geonozzle::City.new(294,'Geneva, Switzerland',46.2,6.16)
296
+ Geonozzle::City.new(295,'Charlottetown, Canada',46.2333,-63.1333)
297
+ Geonozzle::City.new(296,'Trois-Rivieres, Canada',46.35,-72.55)
298
+ Geonozzle::City.new(297,'Lausanne, Switzerland',46.53,6.66)
299
+ Geonozzle::City.new(298,'Fribourg, Switzerland',46.8,7.15)
300
+ Geonozzle::City.new(299,'Quebec, Canada',46.8,-71.25)
301
+ Geonozzle::City.new(300,'Missoula, United States',46.8722,-113.993)
302
+ Geonozzle::City.new(301,'Bern, Switzerland',46.9167,7.46667)
303
+ Geonozzle::City.new(302,'Olympia, United States',47.03,-122.89)
304
+ Geonozzle::City.new(303,'Graz, Austria',47.06,15.45)
305
+ Geonozzle::City.new(304,'Luzern, Switzerland',47.08,8.26)
306
+ Geonozzle::City.new(305,'Nantes, France',47.21,-1.55)
307
+ Geonozzle::City.new(306,'Tacoma, United States',47.2531,-122.443)
308
+ Geonozzle::City.new(307,'Innsbruck, Austria',47.26,11.4)
309
+ Geonozzle::City.new(308,'Dijon, France',47.31,5.01)
310
+ Geonozzle::City.new(309,'Zurich, Switzerland',47.36,8.55)
311
+ Geonozzle::City.new(310,'Tours, France',47.38,0.68)
312
+ Geonozzle::City.new(311,'Angers, France',47.46,-0.55)
313
+ Geonozzle::City.new(312,'Budapest, Hungary',47.5,19.08)
314
+ Geonozzle::City.new(313,'Basel, Switzerland',47.56,7.6)
315
+ Geonozzle::City.new(314,'Seattle, United States',47.6064,-122.331)
316
+ Geonozzle::City.new(315,'Spokane, United States',47.6589,-117.425)
317
+ Geonozzle::City.new(316,'Salzburg, Austria',47.8,13.03)
318
+ Geonozzle::City.new(317,'Freiburg, Germany',48,7.85)
319
+ Geonozzle::City.new(318,'Rennes, France',48.08,-1.68)
320
+ Geonozzle::City.new(319,'Bratislava, Slovakia',48.15,17.11)
321
+ Geonozzle::City.new(320,'Munich, Germany',48.15,11.58)
322
+ Geonozzle::City.new(321,'Vienna, Austria',48.2,16.36)
323
+ Geonozzle::City.new(322,'Linz, Austria',48.3,14.3)
324
+ Geonozzle::City.new(323,'Augsburg, Germany',48.36,10.88)
325
+ Geonozzle::City.new(324,'Victoria, Canada',48.4333,-123.35)
326
+ Geonozzle::City.new(325,'Tubingen, Germany',48.53,9.05)
327
+ Geonozzle::City.new(326,'Strasbourg, France',48.58,7.75)
328
+ Geonozzle::City.new(327,'Nancy, France',48.68,6.2)
329
+ Geonozzle::City.new(328,'Bellingham, United States',48.7597,-122.487)
330
+ Geonozzle::City.new(329,'Stuttgart, Germany',48.76,9.18)
331
+ Geonozzle::City.new(330,'Paris, France',48.86,2.33)
332
+ Geonozzle::City.new(331,'Karlsruhe, Germany',49,8.38)
333
+ Geonozzle::City.new(332,'Regensburg, Germany',49.01,12.09)
334
+ Geonozzle::City.new(333,'Metz, France',49.13,6.16)
335
+ Geonozzle::City.new(334,'Nanaimo, Canada',49.15,-123.91)
336
+ Geonozzle::City.new(335,'Surrey, Canada',49.17,-122.836)
337
+ Geonozzle::City.new(336,'Caen, France',49.18,-0.35)
338
+ Geonozzle::City.new(337,'Brno, Czech Republic',49.2,16.63)
339
+ Geonozzle::City.new(338,'Vancouver, Canada',49.25,-123.13)
340
+ Geonozzle::City.new(339,'Heidelberg, Germany',49.41,8.7)
341
+ Geonozzle::City.new(340,'Rouen, France',49.43,1.08)
342
+ Geonozzle::City.new(341,'Nurnberg, Germany',49.44,11.06)
343
+ Geonozzle::City.new(342,'Mannheim, Germany',49.4883,8.46472)
344
+ Geonozzle::City.new(343,'Erlangen, Germany',49.58,11)
345
+ Geonozzle::City.new(344,'Trier, Germany',49.75,6.63)
346
+ Geonozzle::City.new(345,'Wurzburg, Germany',49.78,9.93)
347
+ Geonozzle::City.new(346,'Darmstadt, Germany',49.87,8.64)
348
+ Geonozzle::City.new(347,'Winnipeg, Canada',49.8833,-97.1667)
349
+ Geonozzle::City.new(348,'Kelowna, Canada',49.9,-119.483)
350
+ Geonozzle::City.new(349,'Mainz, Germany',50,8.27)
351
+ Geonozzle::City.new(350,'Prague, Czech Republic',50.08,14.46)
352
+ Geonozzle::City.new(351,'Wiesbaden, Germany',50.08,8.25)
353
+ Geonozzle::City.new(352,'Krakow, Poland',50.0833,19.9167)
354
+ Geonozzle::City.new(353,'Frankfurt, Germany',50.11,8.68)
355
+ Geonozzle::City.new(354,'Kiev, Ukraine',50.4333,30.5167)
356
+ Geonozzle::City.new(355,'Regina, Canada',50.45,-104.61)
357
+ Geonozzle::City.new(356,'Giessen, Germany',50.5833,8.65)
358
+ Geonozzle::City.new(357,'Liege, Belgium',50.63,5.56)
359
+ Geonozzle::City.new(358,'Lille, France',50.63,3.06)
360
+ Geonozzle::City.new(359,'Bournemouth, United Kingdom',50.71,-1.88)
361
+ Geonozzle::City.new(360,'Bonn, Germany',50.73,7.1)
362
+ Geonozzle::City.new(361,'Aachen, Germany',50.76,6.1)
363
+ Geonozzle::City.new(362,'Marburg, Germany',50.81,8.76)
364
+ Geonozzle::City.new(363,'Brighton, United Kingdom',50.8333,-0.15)
365
+ Geonozzle::City.new(364,'Brussels, Belgium',50.8333,4.33333)
366
+ Geonozzle::City.new(365,'Maastricht, Netherlands',50.85,5.68)
367
+ Geonozzle::City.new(366,'Leuven, Belgium',50.88,4.7)
368
+ Geonozzle::City.new(367,'Southampton, United Kingdom',50.9,-1.4)
369
+ Geonozzle::City.new(368,'Cologne, Germany',50.93,6.95)
370
+ Geonozzle::City.new(369,'Dresden, Germany',51.05,13.75)
371
+ Geonozzle::City.new(370,'Gent, Belgium',51.05,3.71)
372
+ Geonozzle::City.new(371,'Calgary, Canada',51.0833,-114.083)
373
+ Geonozzle::City.new(372,'Wroclaw, Poland',51.1,17.03)
374
+ Geonozzle::City.new(373,'Antwerpen, Belgium',51.21,4.41)
375
+ Geonozzle::City.new(374,'Dusseldorf, Germany',51.21,6.76)
376
+ Geonozzle::City.new(375,'Leipzig, Germany',51.3,12.33)
377
+ Geonozzle::City.new(376,'Bath, United Kingdom',51.38,-2.35)
378
+ Geonozzle::City.new(377,'Reading, United Kingdom',51.43,-1)
379
+ Geonozzle::City.new(378,'Bristol, United Kingdom',51.45,-2.58)
380
+ Geonozzle::City.new(379,'Eindhoven, Netherlands',51.45,5.46)
381
+ Geonozzle::City.new(380,'Essen, Germany',51.45,7.01)
382
+ Geonozzle::City.new(381,'Bochum, Germany',51.48,7.21)
383
+ Geonozzle::City.new(382,'Cardiff, United Kingdom',51.5,-3.2)
384
+ Geonozzle::City.new(383,'Halle, Germany',51.5,12)
385
+ Geonozzle::City.new(384,'Dortmund, Germany',51.51,7.45)
386
+ Geonozzle::City.new(385,'London, United Kingdom',51.52,0.14)
387
+ Geonozzle::City.new(386,'Gottingen, Germany',51.53,9.93)
388
+ Geonozzle::City.new(387,'Tilburg, Netherlands',51.55,5.11)
389
+ Geonozzle::City.new(388,'Breda, Netherlands',51.56,4.8)
390
+ Geonozzle::City.new(389,'Oxford, United Kingdom',51.75,-1.25)
391
+ Geonozzle::City.new(390,'Nijmegen, Netherlands',51.83,5.86)
392
+ Geonozzle::City.new(391,'Cork, Ireland',51.89,-8.49)
393
+ Geonozzle::City.new(392,'Rotterdam, Netherlands',51.91,4.5)
394
+ Geonozzle::City.new(393,'Muenster, Germany',51.96,7.63)
395
+ Geonozzle::City.new(394,'Arnhem, Netherlands',51.98,5.91)
396
+ Geonozzle::City.new(395,'Delft, Netherlands',52,4.36)
397
+ Geonozzle::City.new(396,'Bielefeld, Germany',52.03,8.53)
398
+ Geonozzle::City.new(397,'Den Haag, Netherlands',52.08,4.3)
399
+ Geonozzle::City.new(398,'Utrecht, Netherlands',52.08,5.13)
400
+ Geonozzle::City.new(399,'Saskatoon, Canada',52.1333,-106.667)
401
+ Geonozzle::City.new(400,'Leiden, Netherlands',52.15,4.5)
402
+ Geonozzle::City.new(401,'Cambridge, United Kingdom',52.2,0.11)
403
+ Geonozzle::City.new(402,'Enschede, Netherlands',52.21,6.9)
404
+ Geonozzle::City.new(403,'Warsaw, Poland',52.25,21)
405
+ Geonozzle::City.new(404,'Braunschweig, Germany',52.26,10.53)
406
+ Geonozzle::City.new(405,'Amsterdam, Netherlands',52.35,4.91)
407
+ Geonozzle::City.new(406,'Poznan, Poland',52.4167,16.9667)
408
+ Geonozzle::City.new(407,'Newcastle, United Kingdom',52.4333,-3.11667)
409
+ Geonozzle::City.new(408,'Birmingham, United Kingdom',52.46,-1.91)
410
+ Geonozzle::City.new(409,'Berlin, Germany',52.51,13.4)
411
+ Geonozzle::City.new(410,'Dublin, Ireland',52.57,-7.55)
412
+ Geonozzle::City.new(411,'Leicester, United Kingdom',52.63,-1.13)
413
+ Geonozzle::City.new(412,'Norwich, United Kingdom',52.63,1.3)
414
+ Geonozzle::City.new(413,'Nottingham, United Kingdom',52.96,-1.16)
415
+ Geonozzle::City.new(414,'Bremen, Germany',53.08,8.8)
416
+ Geonozzle::City.new(415,'Oldenburg, Germany',53.16,8.2)
417
+ Geonozzle::City.new(416,'Hannover, Germany',53.1833,8.51667)
418
+ Geonozzle::City.new(417,'Groningen, Netherlands',53.21,6.55)
419
+ Geonozzle::City.new(418,'Galway, Ireland',53.27,-9.04)
420
+ Geonozzle::City.new(419,'Dublin, Ireland',53.33,-6.24)
421
+ Geonozzle::City.new(420,'Sheffield, United Kingdom',53.36,-1.5)
422
+ Geonozzle::City.new(421,'Liverpool, United Kingdom',53.41,-3)
423
+ Geonozzle::City.new(422,'Manchester, United Kingdom',53.5,-2.21)
424
+ Geonozzle::City.new(423,'Edmonton, Canada',53.55,-113.5)
425
+ Geonozzle::City.new(424,'Hamburg, Germany',53.55,10)
426
+ Geonozzle::City.new(425,'Leeds, United Kingdom',53.8,-1.58)
427
+ Geonozzle::City.new(426,'Minsk, Belarus',53.9,27.56)
428
+ Geonozzle::City.new(427,'York, United Kingdom',53.96,-1.08)
429
+ Geonozzle::City.new(428,'Kiel, Germany',54.33,10.13)
430
+ Geonozzle::City.new(429,'Gdansk, Poland',54.35,18.6667)
431
+ Geonozzle::City.new(430,'Belfast, United Kingdom',54.58,-5.93)
432
+ Geonozzle::City.new(431,'Vilnius, Lithuania',54.68,25.31)
433
+ Geonozzle::City.new(432,'Kaunas, Lithuania',54.9,23.9)
434
+ Geonozzle::City.new(433,'Newcastle upon Tyne, United Kingdom',54.98,-1.61)
435
+ Geonozzle::City.new(434,'Odense, Denmark',55.4,10.38)
436
+ Geonozzle::City.new(435,'Malmo, Sweden',55.6,13)
437
+ Geonozzle::City.new(436,'Copenhagen, Denmark',55.66,12.58)
438
+ Geonozzle::City.new(437,'Lund, Sweden',55.7,13.18)
439
+ Geonozzle::City.new(438,'Moscow, Russia',55.7522,37.6156)
440
+ Geonozzle::City.new(439,'Glasgow, United Kingdom',55.83,-4.25)
441
+ Geonozzle::City.new(440,'Edinburgh, United Kingdom',55.95,-3.2)
442
+ Geonozzle::City.new(441,'Arhus, Denmark',56.15,10.21)
443
+ Geonozzle::City.new(442,'Riga, Latvia',56.95,24.1)
444
+ Geonozzle::City.new(443,'Aalborg, Denmark',57.05,9.93)
445
+ Geonozzle::City.new(444,'Aberdeen, United Kingdom',57.13,-2.1)
446
+ Geonozzle::City.new(445,'Gothenburg, Sweden',57.7167,11.9667)
447
+ Geonozzle::City.new(446,'Tartu, Estonia',58.36,26.73)
448
+ Geonozzle::City.new(447,'Linkoping, Sweden',58.4167,15.6167)
449
+ Geonozzle::City.new(448,'Stavanger, Norway',58.96,5.75)
450
+ Geonozzle::City.new(449,'Stockholm, Sweden',59.3333,18.05)
451
+ Geonozzle::City.new(450,'Tallinn, Estonia',59.43,24.72)
452
+ Geonozzle::City.new(451,'Uppsala, Sweden',59.866664886,17.633333206)
453
+ Geonozzle::City.new(452,'Saint Petersburg, Russia',59.8944,30.2642)
454
+ Geonozzle::City.new(453,'Oslo, Norway',59.91,10.75)
455
+ Geonozzle::City.new(454,'Helsinki, Finland',60.17,24.93)
456
+ Geonozzle::City.new(455,'Espoo, Finland',60.21,24.66)
457
+ Geonozzle::City.new(456,'Bergen, Norway',60.39,5.32)
458
+ Geonozzle::City.new(457,'Turku, Finland',60.45,22.28)
459
+ Geonozzle::City.new(458,'Helsinki, Finland',60.6,21.43)
460
+ Geonozzle::City.new(459,'Anchorage, United States',61.2181,-149.9)
461
+ Geonozzle::City.new(460,'Tampere, Finland',61.5,23.75)
462
+ Geonozzle::City.new(461,'Jyvaskyla, Finland',62.23,25.73)
463
+ Geonozzle::City.new(462,'Trondheim, Norway',63.41,10.41)
464
+ Geonozzle::City.new(463,'Umea, Sweden',63.8333,20.25)
465
+ Geonozzle::City.new(464,'Reykjavik, Iceland',64.15,-21.95)
466
+ Geonozzle::City.new(465,'Fairbanks, United States',64.8378,-147.716)
467
+ Geonozzle::City.new(466,'Oulu, Finland',65.01,25.46)
468
+
469
+
470
+ # Cities for Intl clients
471
+ # 500-519 - pakistan
472
+ Geonozzle::City.new(500,'Lahore, Pakistan',31.539,74.328)
473
+ Geonozzle::City.new(501,'Faisalabad, Pakistan',31.412,73.084)
474
+ Geonozzle::City.new(502,'Rawalpindi, Pakistan',33.608,73.044)
475
+ Geonozzle::City.new(503,'Gujranwala, Pakistan',32.153,74.184)
476
+ Geonozzle::City.new(504,'Multan, Pakistan',30.193,71.459)
477
+ Geonozzle::City.new(505,'Hyderabad, Pakistan',25.382,68.366)
478
+ Geonozzle::City.new(506,'Peshawar, Pakistan',34.005,71.545)
479
+ Geonozzle::City.new(507,'Quetta, Pakistan',30.211,67.018)
480
+ Geonozzle::City.new(508,'Islamabad, Pakistan',33.719,73.061)
481
+
482
+
483
+ # Cities for US Clients
484
+ Geonozzle::City.new(1001,'Montgomery, United States',32.361667, -86.279167)
@@ -0,0 +1,84 @@
1
+ module Geonozzle
2
+ class City < Struct.new(:num, :name, :lat, :lng)
3
+ include GeoKit::Mappable
4
+ extend MethodCache::ModuleExtensions
5
+ attr_accessor :ll, :distance
6
+ @@all = []
7
+ @@by_num = []
8
+
9
+ def initialize(*args)
10
+ super
11
+ @ll = GeoKit::LatLng.normalize(lat, lng)
12
+ @@all << self
13
+ @@by_num[num] = self
14
+ end
15
+
16
+ def self.num(num)
17
+ @@by_num[num.to_i]
18
+ end
19
+
20
+ def self.all
21
+ @@all
22
+ end
23
+
24
+ def js
25
+ args = [num, name, lat, lng].to_json[1..-2]
26
+ "city(#{args});\n"
27
+ end
28
+
29
+ def self.[](lat, lng)
30
+ return unless thing = GeoKit::LatLng.normalize(lat, lng)
31
+ @@all.min{ |a, b| a.ll.distance_to(thing) <=> b.ll.distance_to(thing) }
32
+ end
33
+
34
+ def self.closest_city_cached(lat, lng)
35
+ City[lat, lng]
36
+ end
37
+
38
+ class_cache :closest_city_cached, :for => 30*24*60*60
39
+
40
+ def self.closest(lat, lng)
41
+ nlat = (lat.to_f*2000.0).round/2000.0
42
+ nlng = (lng.to_f*2000.0).round/2000.0
43
+ closest_city_cached(nlat, nlng)
44
+ end
45
+
46
+ def to_lat_lng
47
+ Geokit::LatLng.new(lat, lng)
48
+ end
49
+
50
+ def distance_to_ll(*ll)
51
+ GeoKit::LatLng.normalize(*ll).distance_to(to_lat_lng, :units => :kms) * 1000
52
+ end
53
+
54
+ def synonyms
55
+ suffixes = [province_code, country_code, country_name].compact
56
+ ([city_name] + suffixes.map{ |suf| "#{city_name} #{suf}" }).map(&:downcase)
57
+ end
58
+
59
+ # TODO: local city names, etc
60
+ def country_name
61
+ @country_name ||= name.split(', ').last
62
+ end
63
+
64
+ # TODO: local city names, etc
65
+ def city_name
66
+ @city_name ||= name.split(', ').first
67
+ end
68
+
69
+ def province_code
70
+ @province_code ||= name.split(', ')[1..-2].first
71
+ end
72
+
73
+ def country_code
74
+ @country_code ||= COUNTRY_CODES.index(country_name)
75
+ end
76
+
77
+ def timezone
78
+ raise "no country code for #{country_name}" unless country_code
79
+ TZInfo::Country.get(country_code).zone_info.min_by do |tz_country|
80
+ (lng - tz_country.longitude).abs
81
+ end.timezone
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,242 @@
1
+ COUNTRY_CODES = {
2
+ 'AF'=>'Afghanistan',
3
+ 'AL'=>'Albania',
4
+ 'DZ'=>'Algeria',
5
+ 'AS'=>'American Samoa',
6
+ 'AD'=>'Andorra',
7
+ 'AO'=>'Angola',
8
+ 'AI'=>'Anguilla',
9
+ 'AQ'=>'Antarctica',
10
+ 'AG'=>'Antigua And Barbuda',
11
+ 'AR'=>'Argentina',
12
+ 'AM'=>'Armenia',
13
+ 'AW'=>'Aruba',
14
+ 'AU'=>'Australia',
15
+ 'AT'=>'Austria',
16
+ 'AZ'=>'Azerbaijan',
17
+ 'BS'=>'Bahamas',
18
+ 'BH'=>'Bahrain',
19
+ 'BD'=>'Bangladesh',
20
+ 'BB'=>'Barbados',
21
+ 'BY'=>'Belarus',
22
+ 'BE'=>'Belgium',
23
+ 'BZ'=>'Belize',
24
+ 'BJ'=>'Benin',
25
+ 'BM'=>'Bermuda',
26
+ 'BT'=>'Bhutan',
27
+ 'BO'=>'Bolivia',
28
+ 'BA'=>'Bosnia And Herzegovina',
29
+ 'BW'=>'Botswana',
30
+ 'BV'=>'Bouvet Island',
31
+ 'BR'=>'Brazil',
32
+ 'IO'=>'British Indian Ocean Territory',
33
+ 'BN'=>'Brunei',
34
+ 'BG'=>'Bulgaria',
35
+ 'BF'=>'Burkina Faso',
36
+ 'BI'=>'Burundi',
37
+ 'KH'=>'Cambodia',
38
+ 'CM'=>'Cameroon',
39
+ 'CA'=>'Canada',
40
+ 'CV'=>'Cape Verde',
41
+ 'KY'=>'Cayman Islands',
42
+ 'CF'=>'Central African Republic',
43
+ 'TD'=>'Chad',
44
+ 'CL'=>'Chile',
45
+ 'CN'=>'China',
46
+ 'CX'=>'Christmas Island',
47
+ 'CC'=>'Cocos (Keeling) Islands',
48
+ 'CO'=>'Columbia',
49
+ 'KM'=>'Comoros',
50
+ 'CG'=>'Congo',
51
+ 'CK'=>'Cook Islands',
52
+ 'CR'=>'Costa Rica',
53
+ 'CI'=>"Cote D'Ivoire",
54
+ 'HR'=>'Croatia',
55
+ 'CU'=>'Cuba',
56
+ 'CY'=>'Cyprus',
57
+ 'CZ'=>'Czech Republic',
58
+ 'CD'=>'Democratic Republic Of Congo (Zaire)',
59
+ 'DK'=>'Denmark',
60
+ 'DJ'=>'Djibouti',
61
+ 'DM'=>'Dominica',
62
+ 'DO'=>'Dominican Republic',
63
+ 'TP'=>'East Timor',
64
+ 'EC'=>'Ecuador',
65
+ 'EG'=>'Egypt',
66
+ 'SV'=>'El Salvador',
67
+ 'GQ'=>'Equatorial Guinea',
68
+ 'ER'=>'Eritrea',
69
+ 'EE'=>'Estonia',
70
+ 'ET'=>'Ethiopia',
71
+ 'FK'=>'Falkland Islands (Malvinas)',
72
+ 'FO'=>'Faroe Islands',
73
+ 'FJ'=>'Fiji',
74
+ 'FI'=>'Finland',
75
+ 'FR'=>'France',
76
+ 'FX'=>'France, Metropolitan',
77
+ 'GF'=>'French Guinea',
78
+ 'PF'=>'French Polynesia',
79
+ 'TF'=>'French Southern Territories',
80
+ 'GA'=>'Gabon',
81
+ 'GM'=>'Gambia',
82
+ 'GE'=>'Georgia',
83
+ 'DE'=>'Germany',
84
+ 'GH'=>'Ghana',
85
+ 'GI'=>'Gibraltar',
86
+ 'GR'=>'Greece',
87
+ 'GL'=>'Greenland',
88
+ 'GD'=>'Grenada',
89
+ 'GP'=>'Guadeloupe',
90
+ 'GU'=>'Guam',
91
+ 'GT'=>'Guatemala',
92
+ 'GN'=>'Guinea',
93
+ 'GW'=>'Guinea-Bissau',
94
+ 'GY'=>'Guyana',
95
+ 'HT'=>'Haiti',
96
+ 'HM'=>'Heard And McDonald Islands',
97
+ 'HN'=>'Honduras',
98
+ 'HK'=>'Hong Kong',
99
+ 'HU'=>'Hungary',
100
+ 'IS'=>'Iceland',
101
+ 'IN'=>'India',
102
+ 'ID'=>'Indonesia',
103
+ 'IR'=>'Iran',
104
+ 'IQ'=>'Iraq',
105
+ 'IE'=>'Ireland',
106
+ 'IL'=>'Israel',
107
+ 'IT'=>'Italy',
108
+ 'JM'=>'Jamaica',
109
+ 'JP'=>'Japan',
110
+ 'JO'=>'Jordan',
111
+ 'KZ'=>'Kazakhstan',
112
+ 'KE'=>'Kenya',
113
+ 'KI'=>'Kiribati',
114
+ 'KW'=>'Kuwait',
115
+ 'KG'=>'Kyrgyzstan',
116
+ 'LA'=>'Laos',
117
+ 'LV'=>'Latvia',
118
+ 'LB'=>'Lebanon',
119
+ 'LS'=>'Lesotho',
120
+ 'LR'=>'Liberia',
121
+ 'LY'=>'Libya',
122
+ 'LI'=>'Liechtenstein',
123
+ 'LT'=>'Lithuania',
124
+ 'LU'=>'Luxembourg',
125
+ 'MO'=>'Macau',
126
+ 'MK'=>'Macedonia',
127
+ 'MG'=>'Madagascar',
128
+ 'MW'=>'Malawi',
129
+ 'MY'=>'Malaysia',
130
+ 'MV'=>'Maldives',
131
+ 'ML'=>'Mali',
132
+ 'MT'=>'Malta',
133
+ 'MH'=>'Marshall Islands',
134
+ 'MQ'=>'Martinique',
135
+ 'MR'=>'Mauritania',
136
+ 'MU'=>'Mauritius',
137
+ 'YT'=>'Mayotte',
138
+ 'MX'=>'Mexico',
139
+ 'FM'=>'Micronesia',
140
+ 'MD'=>'Moldova',
141
+ 'MC'=>'Monaco',
142
+ 'MN'=>'Mongolia',
143
+ 'MS'=>'Montserrat',
144
+ 'MA'=>'Morocco',
145
+ 'MZ'=>'Mozambique',
146
+ 'MM'=>'Myanmar (Burma)',
147
+ 'NA'=>'Namibia',
148
+ 'NR'=>'Nauru',
149
+ 'NP'=>'Nepal',
150
+ 'NL'=>'Netherlands',
151
+ 'AN'=>'Netherlands Antilles',
152
+ 'NC'=>'New Caledonia',
153
+ 'NZ'=>'New Zealand',
154
+ 'NI'=>'Nicaragua',
155
+ 'NE'=>'Niger',
156
+ 'NG'=>'Nigeria',
157
+ 'NU'=>'Niue',
158
+ 'NF'=>'Norfolk Island',
159
+ 'KP'=>'North Korea',
160
+ 'MP'=>'Northern Mariana Islands',
161
+ 'NO'=>'Norway',
162
+ 'OM'=>'Oman',
163
+ 'PK'=>'Pakistan',
164
+ 'PW'=>'Palau',
165
+ 'PA'=>'Panama',
166
+ 'PG'=>'Papua New Guinea',
167
+ 'PY'=>'Paraguay',
168
+ 'PE'=>'Peru',
169
+ 'PH'=>'Philippines',
170
+ 'PN'=>'Pitcairn',
171
+ 'PL'=>'Poland',
172
+ 'PT'=>'Portugal',
173
+ 'PR'=>'Puerto Rico',
174
+ 'QA'=>'Qatar',
175
+ 'RE'=>'Reunion',
176
+ 'RO'=>'Romania',
177
+ 'RU'=>'Russia',
178
+ 'RW'=>'Rwanda',
179
+ 'RS'=>'Serbia and Montenegro',
180
+ 'SH'=>'Saint Helena',
181
+ 'KN'=>'Saint Kitts And Nevis',
182
+ 'LC'=>'Saint Lucia',
183
+ 'PM'=>'Saint Pierre And Miquelon',
184
+ 'VC'=>'Saint Vincent And The Grenadines',
185
+ 'SM'=>'San Marino',
186
+ 'ST'=>'Sao Tome And Principe',
187
+ 'SA'=>'Saudi Arabia',
188
+ 'SN'=>'Senegal',
189
+ 'SC'=>'Seychelles',
190
+ 'SL'=>'Sierra Leone',
191
+ 'SG'=>'Singapore',
192
+ 'SK'=>'Slovak Republic',
193
+ 'SI'=>'Slovenia',
194
+ 'SB'=>'Solomon Islands',
195
+ 'SO'=>'Somalia',
196
+ 'ZA'=>'South Africa',
197
+ 'GS'=>'South Georgia And South Sandwich Islands',
198
+ 'KR'=>'South Korea',
199
+ 'ES'=>'Spain',
200
+ 'LK'=>'Sri Lanka',
201
+ 'SD'=>'Sudan',
202
+ 'SR'=>'Suriname',
203
+ 'SJ'=>'Svalbard And Jan Mayen',
204
+ 'SZ'=>'Swaziland',
205
+ 'SE'=>'Sweden',
206
+ 'CH'=>'Switzerland',
207
+ 'SY'=>'Syria',
208
+ 'TW'=>'Taiwan',
209
+ 'TJ'=>'Tajikistan',
210
+ 'TZ'=>'Tanzania',
211
+ 'TH'=>'Thailand',
212
+ 'TG'=>'Togo',
213
+ 'TK'=>'Tokelau',
214
+ 'TO'=>'Tonga',
215
+ 'TT'=>'Trinidad And Tobago',
216
+ 'TN'=>'Tunisia',
217
+ 'TR'=>'Turkey',
218
+ 'TM'=>'Turkmenistan',
219
+ 'TC'=>'Turks And Caicos Islands',
220
+ 'TV'=>'Tuvalu',
221
+ 'UG'=>'Uganda',
222
+ 'UA'=>'Ukraine',
223
+ 'AE'=>'United Arab Emirates',
224
+ 'UK'=>'United Kingdom',
225
+ 'US'=>'United States',
226
+ 'UM'=>'United States Minor Outlying Islands',
227
+ 'UY'=>'Uruguay',
228
+ 'UZ'=>'Uzbekistan',
229
+ 'VU'=>'Vanuatu',
230
+ 'VA'=>'Vatican City (Holy See)',
231
+ 'VE'=>'Venezuela',
232
+ 'VN'=>'Vietnam',
233
+ 'VG'=>'Virgin Islands (British)',
234
+ 'VI'=>'Virgin Islands (US)',
235
+ 'WF'=>'Wallis And Futuna Islands',
236
+ 'EH'=>'Western Sahara',
237
+ 'WS'=>'Western Samoa',
238
+ 'YE'=>'Yemen',
239
+ 'YU'=>'Yugoslavia',
240
+ 'ZM'=>'Zambia',
241
+ 'ZW'=>'Zimbabwe'
242
+ }
@@ -0,0 +1,76 @@
1
+ module Geonozzle
2
+ module Locstring
3
+ STREET_ENDINGS = %w{
4
+ st rd pl av ave street road blvd circle cir
5
+ dr drive loop ln lane park terr pkwy
6
+ }.to_set
7
+ ISO2_CODES = COUNTRY_CODES.keys.map(&:downcase).to_set
8
+ COUNTRY_NAMES = COUNTRY_CODES.values.map do |name|
9
+ name.downcase.sub(/\s*\(.*\)\s*/,'')
10
+ end.to_set
11
+ CITY_ENDINGS = {}
12
+ City.all.each do |city|
13
+ city.synonyms.each{ |syn| CITY_ENDINGS[syn] = city }
14
+ end
15
+
16
+ def normalized
17
+ @normalized ||= downcase.gsub(/\W+/, ' ').gsub(/ +/, ' ').strip
18
+ end
19
+
20
+ def blank?
21
+ !normalized or normalized == ''
22
+ end
23
+
24
+ def words
25
+ @words ||= normalized.split
26
+ end
27
+
28
+ def last_word
29
+ words.last
30
+ end
31
+
32
+ def last_two_words
33
+ return last_word unless words.size > 1
34
+ return words[-2..-1].join(' ')
35
+ end
36
+
37
+ def city
38
+ CITY_ENDINGS[last_two_words] || CITY_ENDINGS[last_word]
39
+ end
40
+
41
+ def noncity_part
42
+ x = normalized.split
43
+ words = if CITY_ENDINGS[last_two_words]; x[0..-3]
44
+ elsif CITY_ENDINGS[last_word]; x[0..-2]
45
+ end
46
+ return self unless words
47
+
48
+ str = words.join(' ')
49
+ str.extend Locstring
50
+ str
51
+ end
52
+
53
+ def obviously_worldwide?
54
+ lat_lng? or zipcode? or ends_with_country?
55
+ end
56
+
57
+ def zipcode?
58
+ last_word =~ /^\d{4,5}$/
59
+ end
60
+
61
+ def lat_lng?
62
+ if self =~ /^(.*\s+)?(-?\d+\.\d+)\s*,\s*(-?\d+\.\d+)\s*$/
63
+ [$2.to_f, $3.to_f]
64
+ end
65
+ end
66
+
67
+ def ends_with_country?
68
+ return false if looks_local?
69
+ COUNTRY_NAMES.include? last_word or ISO2_CODES.include? last_word
70
+ end
71
+
72
+ def looks_local?
73
+ STREET_ENDINGS.include? last_word
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'geonozzle'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,20 @@
1
+ require 'helper'
2
+
3
+ class TestGeonozzle < Test::Unit::TestCase
4
+ def assert_geo loc, cnum, lat, lng, acc
5
+ assert g = Geonozzle.universal_geocode(loc, Geonozzle::City.num(cnum))
6
+ assert_equal lat, g.lat
7
+ assert_equal lng, g.lng
8
+ assert_equal acc, g.precision
9
+ end
10
+
11
+ def test_universal_geocoding_no_hash
12
+ assert_geo "12 cherry", 220, 42.323547, -72.629872, "address"
13
+ assert_geo "cherry st", 220, 42.3241601, -72.6285171, "zip+4"
14
+ assert_geo "mobile, al", 220, 30.6943566, -88.0430541, "city"
15
+ assert_geo "mobile, al", nil, 30.6943566, -88.0430541, "city"
16
+ assert_geo "1 haywood rd asheville", nil, 35.5848508, -82.5691946, "address"
17
+ assert_geo "19 lawrence road lahore", nil, 31.5522173, 74.3271002, "zip+4"
18
+ assert_geo "santa cruz, ca", 220, 36.9741171, -122.0307963, "city"
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geonozzle
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Joe Edelman
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-15 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: geokit
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: methodcache
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ description: Some extra geocoding and caching smarts atop geokit
45
+ email: joe@citizenlogistics.com
46
+ executables: []
47
+
48
+ extensions: []
49
+
50
+ extra_rdoc_files:
51
+ - LICENSE
52
+ - README.rdoc
53
+ files:
54
+ - .document
55
+ - .gitignore
56
+ - LICENSE
57
+ - README.rdoc
58
+ - Rakefile
59
+ - VERSION
60
+ - lib/geonozzle.rb
61
+ - lib/geonozzle/cities.rb
62
+ - lib/geonozzle/city.rb
63
+ - lib/geonozzle/country_codes.rb
64
+ - lib/geonozzle/locstring.rb
65
+ - test/helper.rb
66
+ - test/test_geonozzle.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/citizenlogistics/geonozzle
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --charset=UTF-8
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.6
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Some extra geocoding and caching smarts atop geokit
97
+ test_files:
98
+ - test/helper.rb
99
+ - test/test_geonozzle.rb