geonames-wrapper 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7fccc103d99772879807bf97cf16dd02174ada1
4
+ data.tar.gz: 830586cc4d990bce38f3c11c93849301662e06e3
5
+ SHA512:
6
+ metadata.gz: 75131eabeeffa9bfec7ea7432ecd533128f24cfb88949ca779c63b78b6c8279e1f7c43b2d5625b2e806bf3b490938ce24cc85822117934a5d2dd65456b6b0278
7
+ data.tar.gz: bf1594d5120ea4568ddd8cb138541042a96a6b2ec3362015de013c02d129a25ebd0355a976c7f7fa5bf401a40b5098f6491e7949ef301ade1c8cfada84a3d332
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ geonames-wrapper (1.0.0)
5
+ addressable (~> 2.3)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ addressable (2.3.2)
11
+ rake (10.0.2)
12
+ yard (0.8.3)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ geonames-wrapper!
19
+ rake
20
+ yard
@@ -0,0 +1,55 @@
1
+ # GeoNames API wrapper
2
+
3
+ The GeoNames geographical database covers all countries and contains over eight
4
+ million placenames that are available for download free of charge.
5
+
6
+ http://www.geonames.org/
7
+
8
+
9
+ ## Dependencies
10
+
11
+ This library depends on addressable, you can install it with
12
+ `gem install addressable`.
13
+
14
+
15
+ ## Usage
16
+
17
+ Instantiate the API and make a query:
18
+
19
+ >> api = GeoNames.new
20
+ >> api.ocean(lat: 0, lng: 0)
21
+ => {"name"=>"North Atlantic Ocean"}
22
+
23
+ Please read the documentation of the methods in the GeoNames class for more
24
+ information about the available methods and their arguments.
25
+
26
+
27
+ ## About
28
+
29
+ I wrote this library in hopes to improve upon the original geonames library
30
+ written by Adam Wisniewski.
31
+ It's around 1/5 of the code now, and should be easier to read, understand,
32
+ extend, and hack while being closer to the original specification of the API.
33
+
34
+
35
+ ### This library is licensed under the MIT License
36
+
37
+ Copyright (c) 2010 Michael Fellinger
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining a copy
40
+ of this software and associated documentation files (the "Software"), to deal
41
+ in the Software without restriction, including without limitation the rights
42
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43
+ copies of the Software, and to permit persons to whom the Software is
44
+ furnished to do so, subject to the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be included in
47
+ all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55
+ THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "geonames-wrapper"
6
+ s.version = "1.1.0"
7
+ s.summary = "GeoNames JSON Web Service Wrapper"
8
+ s.description = "Bare-metal wrapper for GeoNames JSON Web Service API. Simple and effective."
9
+
10
+ s.platform = Gem::Platform::RUBY
11
+ s.required_ruby_version = ">= 1.9.0"
12
+
13
+ s.authors = ["Michael Fellinger", "Marcello Barnaba"]
14
+ s.email = ["m.fellinger@gmail.com", "vjt@openssl.it" ]
15
+ s.homepage = "http://github.com/vjt/geonames"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency 'addressable', '~> 2.3'
21
+
22
+ s.add_development_dependency("rake")
23
+ s.add_development_dependency("yard")
24
+ end
@@ -0,0 +1,788 @@
1
+ require 'json'
2
+ require 'open-uri'
3
+ require 'addressable/template'
4
+
5
+ class GeoNames
6
+ class APIError < RuntimeError; end
7
+
8
+ OPTIONS = {
9
+ host: 'api.geonames.org',
10
+ time_format: '%Y-%m-%d %T %z',
11
+ timezone: 'UTC',
12
+ username: nil,
13
+ }
14
+
15
+ QUERY = {}
16
+
17
+ attr_reader :options, :uris
18
+
19
+ def initialize(options = {})
20
+ @options = OPTIONS.merge(options)
21
+ @uris = Hash[QUERY.map{|name, args|
22
+ if args.empty?
23
+ template = Addressable::Template.new(
24
+ "http://{host}/#{name}JSON"
25
+ )
26
+ else
27
+ joined = (%w{ username } + args.flatten).uniq.sort.join(',')
28
+ template = Addressable::Template.new(
29
+ "http://{host}/#{name}JSON{?#{joined}}"
30
+ )
31
+ end
32
+ [name, template]
33
+ }]
34
+ end
35
+
36
+ # Execute query for given +name+ with +parameters+ translated via URI
37
+ # template expansion.
38
+ def query(name, parameters)
39
+ default = {host: options[:host]}
40
+ default[:username] = options[:username] if options[:username]
41
+
42
+ uri = uris[name].expand(default.merge(parameters))
43
+
44
+ result =
45
+ if block_given?
46
+ open(uri.to_s){|io| yield(io.read) }
47
+ else
48
+ open(uri.to_s){|io| JSON.parse(io.read) }
49
+ end
50
+
51
+ if status = result["status"]
52
+ raise APIError, status.inspect
53
+ else
54
+ result
55
+ end
56
+ end
57
+
58
+ # Utility method for some queries that return times, we convert them to real
59
+ # Time instances with proper UTC timezone.
60
+ def fix_datetime(hash)
61
+ if time = hash['datetime']
62
+ zone, format = options.values_at(:timezone, :time_format)
63
+ hash['datetime'] = Time.strptime("#{time} #{zone}", format)
64
+ end
65
+
66
+ hash
67
+ end
68
+
69
+ # Returns the attribute of the geoNames feature with the given geonameId
70
+ #
71
+ # Parameters: geonameId
72
+ #
73
+ # Example:
74
+ #
75
+ # api.get(geonameId: 2643743)
76
+ def get(parameters)
77
+ query(:get, parameters)
78
+ end
79
+ QUERY[:get] = %w[geonameId]
80
+
81
+ # Returns a list of recent earthquakes, ordered by magnitude
82
+ #
83
+ # north, south, east, west: coordinates of bounding box
84
+ # callback: name of javascript function (optional parameter)
85
+ # date: date of earthquakes 'yyyy-MM-dd', optional parameter
86
+ # minMagnitude: minimal magnitude, optional parameter
87
+ # maxRows: maximal number of rows returned (default = 10)
88
+ #
89
+ # Example:
90
+ #
91
+ # api.earthquakes(north: 44.1, south: -9.9, east: -22.4, west: 55.2)
92
+ def earthquakes(parameters = {})
93
+ quakes = query(:earthquakes, parameters)['earthquakes']
94
+ quakes.map{|quake| fix_datetime(quake) }
95
+ end
96
+ QUERY[:earthquakes] = %w[
97
+ north south east west date callback minMagnitude maxRows
98
+ ]
99
+
100
+ # Elevation - Aster Global Digital Elevation Model
101
+ #
102
+ # Parameters: lat,lng
103
+ #
104
+ # Sample area: ca 30m x 30m, between 83N and 65S latitude.
105
+ # Result: a single number giving the elevation in meters according to aster
106
+ # gdem, ocean areas have been masked as "no data" and have been assigned a
107
+ # value of -9999.
108
+ #
109
+ # Example:
110
+ #
111
+ # api.astergdem(lat: 50.01, lng: 10.2)
112
+ def astergdem(parameters = {})
113
+ query(:astergdem, parameters)
114
+ end
115
+ QUERY[:astergdem] = %w[lat lng]
116
+
117
+ # GTOPO30 is a global digital elevation model (DEM) with a horizontal grid
118
+ # spacing of 30 arc seconds (approximately 1 kilometer). GTOPO30 was derived
119
+ # from several raster and vector sources of topographic information.
120
+ #
121
+ # Parameters: lat,lng
122
+ #
123
+ # Sample area: ca 1km x 1km Result : a single number giving the elevation in
124
+ # meters according to gtopo30, ocean areas have been masked as "no data" and
125
+ # have been assigned a value of -9999.
126
+ #
127
+ # Example:
128
+ #
129
+ # api.gtopo30(lat: 50.01, lng: 10.2)
130
+ def gtopo30(parameters = {})
131
+ query(:gtopo30, parameters)
132
+ end
133
+ QUERY[:gtopo30] = %w[lat lng]
134
+
135
+ # Returns the children for a given geonameId. The children are the
136
+ # administrative divisions within an other administrative division. Like the
137
+ # counties (ADM2) in a state (ADM1) or also the countries in a continent.
138
+ #
139
+ # Parameters:
140
+ # geonameId: the geonameId of the parent
141
+ # maxRows: number of rows returned, default is 200
142
+ #
143
+ # Result: returns a list of GeoName records
144
+ #
145
+ # Example:
146
+ #
147
+ # api.children(geonameId: 3175395, maxRows: 5)
148
+ def children(parameters = {})
149
+ query(:children, parameters)
150
+ end
151
+ QUERY[:children] = %w[geonameId maxRows]
152
+
153
+ # Returns all GeoNames higher up in the hierarchy of a place name.
154
+ #
155
+ # Parameters:
156
+ # geonameId: the geonameId for the hierarchy
157
+ #
158
+ # Result: returns a list of GeoName records, ordered by hierarchy level. The
159
+ # top hierarchy (continent) is the first element in the list
160
+ #
161
+ # Example:
162
+ #
163
+ # api.hierarchy(geonameId: 2657896)
164
+ def hierarchy(parameters = {})
165
+ query(:hierarchy, parameters)
166
+ end
167
+ QUERY[:hierarchy] = %w[geonameId]
168
+
169
+ # Returns all neighbours for a place name (currently only available for
170
+ # countries).
171
+ #
172
+ # Parameters:
173
+ # geonameId: the geonameId for the neighbours
174
+ #
175
+ # Result: returns the neighbours of a toponym, currently only implemented for
176
+ # countries
177
+ #
178
+ # Example:
179
+ #
180
+ # api.neighbours(geonameId: 2658434)
181
+ def neighbours(parameters = {})
182
+ query(:neighbours, parameters)
183
+ end
184
+ QUERY[:neighbours] = %w[geonameId]
185
+
186
+ # Returns all siblings of a GeoNames toponym.
187
+ #
188
+ # Parameters:
189
+ # geonameId: the geonameId for the siblings
190
+ #
191
+ # Result: returns a list of GeoNames records that have the same
192
+ # administrative level and the same father
193
+ #
194
+ # Example:
195
+ #
196
+ # api.siblings(geonameId: 3017382)
197
+ def siblings(parameters = {})
198
+ query(:siblings, parameters)['geonames']
199
+ end
200
+ QUERY[:siblings] = %w[geonameId]
201
+
202
+ # Cities and Placenames
203
+ #
204
+ # Returns a list of cities and placenames in the bounding box, ordered by
205
+ # relevancy (capital/population).
206
+ # Placenames close together are filterered out and only the larger name is
207
+ # included in the resulting list.
208
+ #
209
+ # Parameters:
210
+ # north,south,east,west: coordinates of bounding box
211
+ # callback: name of javascript function (optional parameter)
212
+ # lang: language of placenames and wikipedia urls (default = en)
213
+ # maxRows: maximal number of rows returned (default = 10)
214
+ #
215
+ # Example:
216
+ #
217
+ # api.cities(north: 44.1, south: -9.9, east: -22.4, west: 55.2, lang: 'de')
218
+ def cities(parameters = {})
219
+ query(:cities, parameters)['geonames']
220
+ end
221
+ QUERY[:cities] = %w[north south east west callback lang maxRows]
222
+
223
+ # Weather Stations with most recent Weather Observation
224
+ #
225
+ # Returns a list of weather stations with the most recent weather observation.
226
+ #
227
+ # Parameters:
228
+ # north,south,east,west: coordinates of bounding box
229
+ # callback: name of javascript function (optional parameter)
230
+ # maxRows: maximal number of rows returned (default = 10)
231
+ #
232
+ # Example:
233
+ #
234
+ # api.weather(north: 44.1, south: -9.9, east: -22.4, west: 55.2)
235
+ def weather(parameters = {})
236
+ observations = query(:weather, parameters)['weatherObservations']
237
+ observations.map{|observation| fix_datetime(observation) }
238
+ end
239
+ QUERY[:weather] = %w[north south east west callbck maxRows]
240
+
241
+ # Returns the weather station and the most recent weather observation for the
242
+ # ICAO code.
243
+ #
244
+ # Parameters:
245
+ # ICAO: International Civil Aviation Organization (ICAO) code
246
+ # callback: name of javascript function (optional parameter)
247
+ #
248
+ # Example:
249
+ #
250
+ # api.weather_icao(ICAO: 'LSZH')
251
+ def weather_icao(parameters = {})
252
+ weather = query(:weatherIcao, parameters)['weatherObservation']
253
+ fix_datetime(weather)
254
+ end
255
+ QUERY[:weatherIcao] = %w[ICAO callback]
256
+
257
+ # Country information: Capital, Population, Area in square km, Bounding Box
258
+ # of mainland (excluding offshore islands)
259
+
260
+ # Parameters : country (default = all countries)
261
+ # lang: ISO-639-1 language code (en,de,fr,it,es,...) (default = english)
262
+ #
263
+ # Example:
264
+ #
265
+ # api.country_info(lang: 'it', country: 'DE')
266
+ def country_info(parameters = {})
267
+ query(:countryInfo, parameters)["geonames"]
268
+ end
269
+ QUERY[:countryInfo] = %w[country lang]
270
+
271
+ # The ISO country code of any given point.
272
+ #
273
+ # Parameters: lat, lng, type, lang, and radius (buffer in km for closest
274
+ # country in coastal areas)
275
+ #
276
+ # With the parameter type=xml this service returns an xml document with iso
277
+ # country code and country name. The optional parameter lang can be used to
278
+ # specify the language the country name should be in.
279
+ # JSON output is produced with type=JSON, which is the default for this
280
+ # library and will be parsed automatically.
281
+ #
282
+ # Example:
283
+ #
284
+ # api.country_code(lat: 47.03, lng: 10.2)
285
+ def country_code(parameters = {})
286
+ if parameters[:type].to_s =~ /^xml$/i
287
+ query(:countryCode, parameters){|content| return content }
288
+ else
289
+ query(:countryCode, {type: 'JSON'}.merge(parameters))
290
+ end
291
+ end
292
+ QUERY[:countryCode] = %w[lat lng type lang radius]
293
+
294
+ # Country Subdivision / reverse geocoding
295
+ # The ISO country code and the administrative subdivision (state, province, ...) of any given point.
296
+ #
297
+ # Parameters: lat, lng, lang, radius
298
+ #
299
+ # If lang is not given, will return the name in the local language.
300
+ # The radius is measured in km and acts as buffer for closest country in
301
+ # costal areas.
302
+ #
303
+ # Example:
304
+ #
305
+ # api.country_subdivision(lat: 47.03, lng: 10.2)
306
+ #
307
+ # # With the parameters 'radius' and 'maxRows' you get the closest
308
+ # # subdivisions ordered by distance:
309
+ # api.country_subdivision(lat: 47.03, lng: 10.2, maxRows: 10, radius: 40)
310
+ def country_subdivision(parameters = {})
311
+ query(:countrySubdivision, parameters)
312
+ end
313
+ QUERY[:countrySubdivision] = %w[lat lng lang radius]
314
+
315
+ # Ocean / reverse geocoding
316
+ # Returns the name of the ocean or sea for the given latitude/longitude.
317
+ #
318
+ # Parameters : lat,lng
319
+ #
320
+ # Example:
321
+ #
322
+ # api.ocean(lat: 40.78343, lng: -43.96625)
323
+ def ocean(parameters = {})
324
+ query(:ocean, parameters)["ocean"]
325
+ end
326
+ QUERY[:ocean] = %w[lat lng]
327
+
328
+ # Neighbourhood / reverse geocoding
329
+ # The neighbourhood for US cities. Data provided by Zillow under cc-by-sa
330
+ # license.
331
+ #
332
+ # Parameters: lat,lng
333
+ #
334
+ # Example:
335
+ #
336
+ # api.neighbourhood(lat: 40.78343, lng: -73.96625)
337
+ def neighbourhood(parameters = {})
338
+ query(:neighbourhood, parameters)["neighbourhood"]
339
+ end
340
+ QUERY[:neighbourhood] = %w[lat lng]
341
+
342
+ # Elevation - SRTM3
343
+ #
344
+ # Shuttle Radar Topography Mission (SRTM) elevation data. SRTM consisted of a
345
+ # specially modified radar system that flew onboard the Space Shuttle
346
+ # Endeavour during an 11-day mission in February of 2000. The dataset covers
347
+ # land areas between 60 degrees north and 56 degrees south.
348
+ # This web service is using SRTM3 data with data points located every
349
+ # 3-arc-second (approximately 90 meters) on a latitude/longitude grid.
350
+ #
351
+ # Parameters : lat,lng;
352
+ # sample area: ca 90m x 90m Result : a single number giving the elevation in
353
+ # meters according to srtm3, ocean areas have been masked as "no data" and
354
+ # have been assigned a value of -32768.
355
+ #
356
+ # Example:
357
+ #
358
+ # api.srtm3(lat: 50.01, lng: 10.2)
359
+ def srtm3(parameters = {})
360
+ query(:srtm3, parameters)
361
+ end
362
+ QUERY[:srtm3] = %w[lat lng]
363
+
364
+ # The timezone at the lat/lng with gmt offset (1. January) and dst offset (1. July)
365
+ #
366
+ # Parameters: lat, lng, radius (buffer in km for closest timezone in coastal areas)
367
+ # needs username
368
+ #
369
+ # If you want to work with the returned time, I recommend the tzinfo library,
370
+ # which can handle the timezoneId. In order to keep dependencies low and the
371
+ # code flexible and fast, we won't do any further handling here.
372
+ #
373
+ # Example:
374
+ #
375
+ # api.timezone(lat: 47.01, lng: 10.2)
376
+ def timezone(parameters = {})
377
+ query(:timezone, parameters)
378
+ end
379
+ QUERY[:timezone] = %w[lat lng radius]
380
+
381
+ # Find nearby toponym
382
+ #
383
+ # Parameters: lat, lng, featureClass, featureCode,
384
+ # radius: radius in km (optional)
385
+ # maxRows: max number of rows (default 10)
386
+ # style: SHORT, MEDIUM, LONG, FULL (default = MEDIUM), verbosity result.
387
+ #
388
+ # Example:
389
+ #
390
+ # api.find_nearby(lat: 47.3, lng: 9)
391
+ def find_nearby(parameters = {})
392
+ query(:findNearby, parameters)["geonames"]
393
+ end
394
+ QUERY[:findNearby] = %w[
395
+ lat lng featureClass featureCode radius maxRows style
396
+ ]
397
+
398
+ # Returns the most detailed information available for the lat/lng query.
399
+ # It is a combination of several services. Example:
400
+ # In the US it returns the address information.
401
+ # In other countries it returns the hierarchy service: http://ws.geonames.org/extendedFindNearby?lat=47.3&lng=9
402
+ # On oceans it returns the ocean name.
403
+ #
404
+ # Parameters : lat,lng
405
+ #
406
+ # Example:
407
+ #
408
+ # api.extended_find_nearby(lat: 47.3, lng: 9)
409
+ def extended_find_nearby(parameters = {})
410
+ raise(NotImplementedError, "XML queries haven't been implemented.")
411
+ query(:extendedFindNearby, parameters)
412
+ end
413
+ QUERY[:extendedFindNearby] = %w[lat lng]
414
+
415
+ # Find nearby populated place / reverse geocoding
416
+ # Returns the closest populated place for the lat/lng query.
417
+ # The unit of the distance element is 'km'.
418
+ #
419
+ # Parameters:
420
+ # lat, lng,
421
+ # radius: radius in km (optional),
422
+ # maxRows: max number of rows (default 10),
423
+ # style: SHORT, MEDIUM, LONG, FULL (default = MEDIUM), verbosity of result
424
+ #
425
+ # Example:
426
+ #
427
+ # api.find_nearby_place_name(lat: 47.3, lng: 9)
428
+ def find_nearby_place_name(parameters = {})
429
+ query(:findNearbyPlaceName, parameters)["geonames"]
430
+ end
431
+ QUERY[:findNearbyPlaceName] = %w[lat lng radius maxRows style]
432
+
433
+ # List of nearby postalcodes and places for the lat/lng query.
434
+ # The result is sorted by distance.
435
+ #
436
+ # This service comes in two flavors. You can either pass the lat/long or a
437
+ # postalcode/placename.
438
+ #
439
+ # Parameters:
440
+ #
441
+ # lat, lng, radius (in km),
442
+ # maxRows (default = 5),
443
+ # style (verbosity : SHORT,MEDIUM,LONG,FULL),
444
+ # country (default = all countries),
445
+ # localCountry (restrict search to local country in border areas)
446
+ #
447
+ # or
448
+ #
449
+ # postalcode, country, radius (in Km), maxRows (default = 5)
450
+ #
451
+ # Example:
452
+ #
453
+ # api.find_nearby_postal_codes(lat: 47, lng: 9)
454
+ # api.find_nearby_postal_codes(postalcode: 8775, country: 'CH', radius: 10)
455
+ def find_nearby_postal_codes(parameters = {})
456
+ query(:findNearbyPostalCodes, parameters)["postalCodes"]
457
+ end
458
+ QUERY[:findNearbyPostalCodes] = %w[
459
+ lat lng radius maxRows style country localCountry postalcode country radius
460
+ ]
461
+
462
+ # Returns the nearest street segments for the given latitude/longitude, this
463
+ # service is only available for the US.
464
+ #
465
+ # @param [Float] latitude Latitude
466
+ # @param [Float] longitude Longitude
467
+ #
468
+ # @return [Array] An Array containing zero or more street segments.
469
+ #
470
+ # A street segment has following keys:
471
+ # "adminCode1": Identifier of state.
472
+ # "adminCode2": Area code.
473
+ # "adminName1": Name of state.
474
+ # "adminName2": Name of province.
475
+ # "countryCode": Name of country (usually "US")
476
+ # "distance": Distance of street to given coordinates in km.
477
+ # "fraddl": From address left.
478
+ # "fraddr": From address right.
479
+ # "line": A string with lng/lat points, comma separated.
480
+ # "mtfcc": MAF/TIGER Feature class code.
481
+ # "name:" Name of the street.
482
+ # "postalcode": Postal code of the address.
483
+ # "toaddl": To address left.
484
+ # "toaddr": To address right.
485
+ #
486
+ # @example
487
+ # api.find_nearby_streets(37.451, -122.18)
488
+ def find_nearby_streets(latitude, longitude)
489
+ [*query(:findNearbyStreets, lat: latitude, lng: longitude)['streetSegment']]
490
+ end
491
+ QUERY[:findNearbyStreets] = %w[lat lng]
492
+
493
+
494
+ # Find nearby street segments on OpenStreetMap for the given
495
+ # latitude/longitude.
496
+ #
497
+ # @param [Float, String] latitude
498
+ # @param [Float, String] longitude
499
+ #
500
+ # @example
501
+ # api.find_nearby_streets_osm(37.451, -122.18)
502
+ def find_nearby_streets_osm(latitude, longitude)
503
+ query(:findNearbyStreetsOSM, lat: latitude, lng: longitude)
504
+ end
505
+ QUERY[:findNearbyStreetsOSM] = %w[lat lng]
506
+
507
+ # Weather Station with most recent weather observation / reverse geocoding
508
+ # needs username
509
+ #
510
+ # Webservice Type : REST
511
+ # Url : ws.geonames.org/findNearByWeatherJSON?
512
+ # Parameters :
513
+ # lat,lng : the service will return the station closest to this given point (reverse geocoding)
514
+ # callback : name of javascript function (optional parameter)
515
+ #
516
+ # Result : returns a weather station with the most recent weather observation
517
+ #
518
+ # Example http://ws.geonames.org/findNearByWeatherJSON?lat=43&lng=-2
519
+ def find_near_by_weather(parameters = {})
520
+ query(:findNearByWeather, parameters)
521
+ end
522
+ QUERY[:findNearByWeather] = %w[lat lng]
523
+
524
+ # Find nearby Wikipedia Entries / reverse geocoding
525
+ #
526
+ # This service comes in two flavors. You can either pass the lat/long or a postalcode/placename.
527
+ # Webservice Type : XML,JSON or RSS
528
+ # Url : ws.geonames.org/findNearbyWikipedia?
529
+ # ws.geonames.org/findNearbyWikipediaJSON?
530
+ # ws.geonames.org/findNearbyWikipediaRSS?
531
+ # Parameters :
532
+ # lang : language code (around 240 languages) (default = en)
533
+ # lat,lng, radius (in km), maxRows (default = 5),country (default = all countries)
534
+ # or
535
+ # postalcode,country, radius (in Km), maxRows (default = 5)
536
+ # Result : returns a list of wikipedia entries as xml document
537
+ # Example:
538
+ # http://ws.geonames.org/findNearbyWikipedia?lat=47&lng=9
539
+ # or
540
+ # ws.geonames.org/findNearbyWikipedia?postalcode=8775&country=CH&radius=10
541
+ def find_nearby_wikipedia(parameters = {})
542
+ query(:findNearbyWikipedia, parameters)
543
+ end
544
+ QUERY[:findNearbyWikipedia] = %w[
545
+ lang lat lng maxRows country postalcode country radius
546
+ ]
547
+
548
+ # Find nearest Address
549
+ #
550
+ # Finds the nearest street and address for a given lat/lng pair.
551
+ # Url : ws.geonames.org/findNearestAddress?
552
+ # Parameters : lat,lng;
553
+ # Restriction : this webservice is only available for the US.
554
+ # Result : returns the nearest address for the given latitude/longitude, the street number is an 'educated guess' using an interpolation of street number at the end of a street segment.
555
+ # Example http://ws.geonames.org/findNearestAddress?lat=37.451&lng=-122.18
556
+ #
557
+ # This service is also available in JSON format :
558
+ # http://ws.geonames.org/findNearestAddressJSON?lat=37.451&lng=-122.18
559
+ def find_nearest_address(parameters = {})
560
+ query(:findNearestAddress, parameters)
561
+ end
562
+ QUERY[:findNearestAddress] = %w[lat lng]
563
+
564
+ # Find nearest Intersection
565
+ #
566
+ # Finds the nearest street and the next crossing street for a given lat/lng pair.
567
+ # Url : ws.geonames.org/findNearestIntersection?
568
+ # Parameters : lat,lng;
569
+ # Restriction : this webservice is only available for the US.
570
+ # Result : returns the nearest intersection for the given latitude/longitude
571
+ # Example http://ws.geonames.org/findNearestIntersection?lat=37.451&lng=-122.18
572
+ #
573
+ # This service is also available in JSON format :
574
+ # http://ws.geonames.org/findNearestIntersectionJSON?lat=37.451&lng=-122.18
575
+ def find_nearest_intersection(parameters = {})
576
+ query(:findNearestIntersection, parameters)
577
+ end
578
+ QUERY[:findNearestIntersection] = %w[lat lng]
579
+
580
+ # Find nearest street and crossing for a given latitude/longitude pair on
581
+ # OpenStreetMap.
582
+ #
583
+ # @param [Float] latitude
584
+ # @param [Float] longitude
585
+ #
586
+ # @example
587
+ # api.find_nearest_intersection_osm(37.451, -122.18)
588
+ def find_nearest_intersection_osm(parameters = {})
589
+ query(:findNearestIntersectionOSM, parameters)
590
+ end
591
+ QUERY[:findNearestIntersectionOSM] = %w[lat lng]
592
+
593
+ # Postal code country info
594
+ #
595
+ # @return [Array] Countries for which postal code geocoding is available.
596
+ #
597
+ # @example
598
+ # api.postal_code_country_info
599
+ def postal_code_country_info(parameters = {})
600
+ query(:postalCodeCountryInfo, {})['geonames']
601
+ end
602
+ QUERY[:postalCodeCountryInfo] = []
603
+
604
+ # Placename lookup with postalcode
605
+ #
606
+ #
607
+ # @param [Hash] parameters
608
+ # @option parameters [String, Fixnum] :postalcode
609
+ # @option parameters [String] :country
610
+ # @option parameters [Fixnum] :maxRows (20)
611
+ # @option parameters [String] :callback
612
+ # @option parameters [String] :charset ('UTF-8')
613
+ #
614
+ # @return [Array] List of places for the given postalcode.
615
+ #
616
+ # @example
617
+ # api.postal_code_lookup(postalcode: 6600, country: 'AT')
618
+ def postal_code_lookup(parameters = {})
619
+ query(:postalCodeLookup, parameters)
620
+ end
621
+ QUERY[:postalCodeLookup] = %w[postalcode country maxRows, callback charset]
622
+
623
+ # Postal Code Search
624
+ # Returns a list of postal codes and places for the placename/postalcode query.
625
+ #
626
+ # For the US the first returned zip code is determined using zip code area
627
+ # shapes, the following zip codes are based on the centroid. For all other
628
+ # supported countries all returned postal codes are based on centroids.
629
+ #
630
+ # Parameter Value Description
631
+ # postalcode string (postalcode or placename required) postal code
632
+ # postalcode_startsWith string the first characters or letters of a postal code
633
+ # placename string (postalcode or placename required) all fields : placename,postal code, country, admin name (Important:urlencoded utf8)
634
+ # placename_startsWith string the first characters of a place name
635
+ # country string : country code, ISO-3166 (optional) Default is all countries.
636
+ # countryBias string records from the countryBias are listed first
637
+ # maxRows integer (optional) the maximal number of rows in the document returned by the service. Default is 10
638
+ # style string SHORT,MEDIUM,LONG,FULL (optional) verbosity of returned xml document, default = MEDIUM
639
+ # operator string AND,OR (optional) the operator 'AND' searches for all terms in the placename parameter, the operator 'OR' searches for any term, default = AND
640
+ # charset string (optional) default is 'UTF8', defines the encoding used for the document returned by the web service.
641
+ # isReduced true or false (optional) default is 'false', when set to 'true' only the UK outer codes are returned. Attention: the default value on the commercial servers is currently set to 'true'. It will be changed later to 'false'.
642
+ #
643
+ # @example
644
+ # api.postal_code_search(postalcode: 9011, maxRows: 10)
645
+ def postal_code_search(parameters = {})
646
+ query(:postalCodeSearch, parameters)
647
+ end
648
+ QUERY[:postalCodeSearch] = %w[
649
+ postalcode postalcode_starts placename placename_starts country countryBias
650
+ maxRows style operator charset isReduced
651
+ ]
652
+
653
+ # Returns the names found for the searchterm as xml, json, or rdf document,
654
+ # the search is using the AND operator.
655
+ #
656
+ # @param [Hash] parameters
657
+ # @option parameters [String] :q
658
+ # search over all attributes of a place, place name, country name,
659
+ # continent, admin codes, ...
660
+ # @option parameters [String] :name
661
+ # place name only
662
+ # @option parameters [String] :name_equals
663
+ # exact place name
664
+ # @option parameters [String] :name_startsWith
665
+ # place name starts with given characters
666
+ # @option parameters [Fixnum] :maxRows (100)
667
+ # maximum number of results, up to 1000
668
+ # @option parameters [Fixnum] :startRow (0)
669
+ # used for paging results.
670
+ # @option parameters [String, Array] :country
671
+ # Country code, ISO-3166 (optional). Default is all countries. May have
672
+ # more than one country as an Array.
673
+ # @option parameters [String] :countryBias
674
+ # records from this country will be listed first.
675
+ # @option parameters [String] :continentCode
676
+ # AF,AS,EU,NA,OC,SA,AN (optional) restricts the search to the given
677
+ # continent.
678
+ # @option parameters [String] :adminCode1
679
+ # code of administrative subdivision
680
+ # @option parameters [String] :adminCode2
681
+ # code of administrative subdivision
682
+ # @option parameters [String] :adminCode3
683
+ # code of administrative subdivision
684
+ # @option parameters [String, Array] :featureClass
685
+ # one or more feature class codes, explanation at
686
+ # http://forum.geonames.org/gforum/posts/list/130.page
687
+ # @option parameters [String, Array] :featureCode
688
+ # one or more feature class codes, explanation at
689
+ # http://forum.geonames.org/gforum/posts/list/130.page
690
+ # @option parameters [String] :lang ('en')
691
+ # ISO-636 2-letter language code; en, de, fr, it, es, ...
692
+ # place names and country names will be returned in the specified language.
693
+ # Feature classes and codes are only available in English and Bulgarian.
694
+ # @option parameters [String] :type ('json')
695
+ # format of returned document.
696
+ # @option parameters [String] :style ('MEDIUM')
697
+ # verbosity of returned document.
698
+ # @option parameters [String] :isNameRequired (false)
699
+ # At least one of the search term needs to be part of the place name.
700
+ # Example: A normal seach for Berlin will return all places within the
701
+ # state of Berlin. If we only want to find places with 'Berlin' in the name
702
+ # we se the parameter isNameRequired to `true`. The difference to the
703
+ # :name_equals parameter is that this will allow searches for 'Berlin,
704
+ # Germany' as only one search term needs to be part of the name.
705
+ # @option parameters [String] :tag
706
+ # search for toponyms tagged with the given tag.
707
+ # @option parameters [String] :charset ('UTF8')
708
+ # encoding of returned document, this wrapper only handles UTF8 for now.
709
+ #
710
+ # @example
711
+ # api.search(q: 'london', maxRows: 10)
712
+ # api.search(q: 'london', maxRows: 10, type: 'rdf')
713
+ # api.search(q: 'skiresort')
714
+ # api.search(q: 'tags:skiresort')
715
+ # api.search(q: 'tags:skiresort@marc')
716
+ #
717
+ # With the parameter `type: 'rdf'` the search service returns the result in RDF
718
+ # format defined by the GeoNames Semantic Web Ontology.
719
+ #
720
+ #
721
+ # Tags
722
+ # GeoNames is using a simple tagging system. Every user can tag places. In
723
+ # contrast to the feature codes and feature classes which are one-dimensional
724
+ # (a place name can only have one feature code) several tags can be used for
725
+ # each place name. It is an additional categorization mechanism where the
726
+ # simple classification with feature codes is not sufficient.
727
+ #
728
+ # I have tagged a place with the tag 'skiresort'. You can search for tags
729
+ # with the search: `api.search(q: 'skiresort')` If you only want to search
730
+ # for a tag and not for other occurences of the term (in case you tag
731
+ # something with 'spain' for example), then you add the attribute 'tags:' to
732
+ # the search term: `api.search(q: 'tags:skiresort')`
733
+ #
734
+ # And if you want to search for tags of a particular user (or your own) then
735
+ # you append '@username' to the tag. Like this:
736
+ # `api.search(q: 'tags:skiresort@marc')
737
+ def search(parameters = {})
738
+ query(:search, parameters)['geonames']
739
+ end
740
+ QUERY[:search] = %w[
741
+ q name name_equals name_startsWith maxRows startRow country countryBias
742
+ continentCode adminCode1 adminCode2 adminCode3 featureClass featureCode
743
+ lang type style isNameRequired tag operator charset
744
+ ]
745
+
746
+ # Wikipedia articles within a bounding box
747
+ #
748
+ # @param [Hash] parameters
749
+ # @option parameters [Float] :south Southern latitude
750
+ # @option parameters [Float] :north Northern latitude
751
+ # @option parameters [Float] :east Eastern longitude
752
+ # @option parameters [Float] :west Western longitude
753
+ # @option parameters [String] :lang ('en') language
754
+ # @option parameters [Fixnum] :maxRows ('10') maximum number of results
755
+ #
756
+ # @return [Array] The Wikipedia entries found.
757
+ #
758
+ # @example
759
+ # api.wikipedia_bounding_box(north: 44.1, south: -9.9, east: -22.4, west: 55.2)
760
+ def wikipedia_bounding_box(parameters = {})
761
+ [*query(:wikipediaBoundingBox, parameters)['geonames']]
762
+ end
763
+ QUERY[:wikipediaBoundingBox] = %w[south north east west lang maxRows]
764
+
765
+ # Wikipedia Fulltext Search
766
+ #
767
+ # @param [Hash] parameters
768
+ # @option parameters [String] :q
769
+ # place name
770
+ # @option parameters [String] :title (false)
771
+ # search in the wikipedia title (optional, true/false)
772
+ # @option parameters [String] :lang ('en')
773
+ # language
774
+ # @option parameters [Fixnum] :maxRows (10)
775
+ # maximum number of results
776
+ #
777
+ # @return [Array] The Wikipedia entries found.
778
+ #
779
+ # @example
780
+ # api.wikipedia_search(q: 'London', maxRows: 10, lang: 'en', title: true)
781
+ # api.wikipedia_search(q: '秋葉原')
782
+ def wikipedia_search(parameters = {})
783
+ params = parameters.dup
784
+ params[:title] = '' if params[:title] # weird?
785
+ [*query(:wikipediaSearch, params)['geonames']]
786
+ end
787
+ QUERY[:wikipediaSearch] = %w[q title lang maxRows]
788
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geonames-wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Fellinger
8
+ - Marcello Barnaba
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: addressable
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '2.3'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '2.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: yard
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ description: Bare-metal wrapper for GeoNames JSON Web Service API. Simple and effective.
57
+ email:
58
+ - m.fellinger@gmail.com
59
+ - vjt@openssl.it
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - geonames-wrapper.gemspec
68
+ - lib/geonames.rb
69
+ homepage: http://github.com/vjt/geonames
70
+ licenses: []
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: 1.9.0
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.1.11
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: GeoNames JSON Web Service Wrapper
92
+ test_files: []