geonozzle 0.0.1

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.
@@ -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