geoplanet 0.2.2

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.
data/README.rdoc ADDED
@@ -0,0 +1,132 @@
1
+ = geoplanet
2
+
3
+ A Ruby wrapper for the Yahoo! GeoPlanet APIs. It's inspired on Mattt Thompson's yahoo-geoplanet gem,
4
+ but this version supports better usage of matrix and query parameters, uses JSON for API communication to minimize bandwidth usage, supports both short & long versions of a place, and supports multiple languages.
5
+
6
+ == Usage
7
+
8
+ === Searching for a Location:
9
+
10
+ require 'geoplanet'
11
+ GeoPlanet.appid = [Your App ID Here]
12
+
13
+ # Search for places that matches "Springfield" (the API returns 1 by default)
14
+ GeoPlanet::Place.search("Springfield")
15
+
16
+ # Search for *all* places that matches "Springfield"
17
+ GeoPlanet::Place.search("Springfield", :count => 0)
18
+
19
+ # You can pass in any Matrix or Query parameters this way too
20
+ # For more details see the following URLs:
21
+ # http://developer.yahoo.com/geo/guide/resources_and_collections.html#matrix_parameters
22
+ # http://developer.yahoo.com/geo/guide/resources_and_collections.html#query_parameters
23
+
24
+ === Initializing by Where On Earth ID && Associations
25
+
26
+ require 'geoplanet'
27
+ GeoPlanet.appid = [Your App ID Here]
28
+
29
+ a = GeoPlanet::Place.new(752067) # WoE ID for Algeciras
30
+
31
+ # Everything you get back from the API you have direct access to
32
+ # through the Place object. For example:
33
+
34
+ a.version # "long"
35
+ a.placetype # "Town"
36
+ a.placetype_code # 7
37
+ a.admin1 # "Andalucia"
38
+ a.admin1_code # "ES-AN"
39
+ a.admin1_placetype # "Autonomous Community"
40
+ a.admin2 # "Cadiz"
41
+ a.admin2_code # ""
42
+ a.admin2_placetype # "Province"
43
+ a.latitude # 36.127602
44
+ # Latitude and Longitude are values at Centroid
45
+ a.bounding_box # [[36.109779, -5.47725], [36.164268, -5.43527]]
46
+ # Bounding box are SW / NE coordinates in array
47
+
48
+ # We unlock the true power of GeoPlanet with association collections
49
+ # Check out this truly amazing stuff:
50
+
51
+ # A list of other towns in the area
52
+ a.siblings
53
+
54
+ # A complete hierarchy, from country down to municipality
55
+ a.ancestors
56
+
57
+ # Postal Codes at Algeciras
58
+ a.children(:select => "long", :type => 11)
59
+
60
+ # You can use multiple types on the same query.
61
+ # e.g. Country and Province for Algeciras
62
+ a.belongtos(:type => [12, 9])
63
+
64
+ # You can specify the language you want for the results.
65
+ a.belongtos(:type => 12, :lang => 'es_ES').first.name # España
66
+
67
+ a = GeoPlanet::Place.new(752067, :lang => :es)
68
+ a.country # España
69
+
70
+ # It is also possible to query for any association directly using a WOE ID, without
71
+ # create a Place object. Append a '_of' suffix to the association name to build the
72
+ # method name to execute. The first argument is the WOE ID.
73
+
74
+ GeoPlanet::Place.belongtos_of(752067, :type => [12, 9])
75
+
76
+ === Debug Mode
77
+
78
+ If you want to look at the requests that are being executed against the Yahoo GeoPlanet API, you can enable the debug mode. It uses the standard output.
79
+
80
+ GeoPlanet.debug = true
81
+ GeoPlanet::Place.new(752067, :lang => :es)
82
+ # outputs:
83
+ # Yahoo GeoPlanet: GET http://where.yahooapis.com/v1/place/752067?appid=[your_appid]&format=json&lang=es
84
+
85
+
86
+ == REQUIREMENTS:
87
+
88
+ To use this library, you must have a valid Yahoo! App ID.
89
+ You can get one at http://developer.yahoo.com/wsregapp/
90
+
91
+ Additionally, geoplanet has the following gem dependencies:
92
+
93
+ * rest-client >= 0.9
94
+ * json >= 1.1.3
95
+
96
+ Please note that if you have ActiveSupport::JSON defined (either by
97
+ manually having loaded it or when you use geoplanet within a Rails
98
+ application) the json dependency will be ignored and geoplanet uses
99
+ ActiveSupport::JSON instead.
100
+
101
+ == INSTALL:
102
+
103
+ gem install carlosparamio-geoplanet --source http://gems.github.com
104
+
105
+ == LICENSE:
106
+
107
+ (The MIT License)
108
+
109
+ Copyright (c) 2009 Carlos Paramio
110
+
111
+ Permission is hereby granted, free of charge, to any person obtaining
112
+ a copy of this software and associated documentation files (the
113
+ 'Software'), to deal in the Software without restriction, including
114
+ without limitation the rights to use, copy, modify, merge, publish,
115
+ distribute, sublicense, and/or sell copies of the Software, and to
116
+ permit persons to whom the Software is furnished to do so, subject to
117
+ the following conditions:
118
+
119
+ The above copyright notice and this permission notice shall be
120
+ included in all copies or substantial portions of the Software.
121
+
122
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
123
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
124
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
125
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
126
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
127
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
128
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
129
+
130
+ == CONTRIBUTORS:
131
+
132
+ Nielsomat <http://github.com/Nielsomat> : Usage of ActiveSupport::JSON when available
data/geoplanet.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "geoplanet"
3
+ s.version = "0.2.2"
4
+ s.date = "2009-04-01"
5
+ s.summary = "A Ruby wrapper for the Yahoo! GeoPlanet API."
6
+ s.email = "carlosparamio@gmail.com"
7
+ s.homepage = "http://github.com/carlosparamio/geoplanet/"
8
+ s.description = "A Ruby wrapper for the Yahoo! GeoPlanet API. It uses JSON format by default to minimize bandwidth usage. See http://developer.yahoo.com/geo/ for more information about the API."
9
+ s.authors = ["Carlos Paramio"]
10
+
11
+ s.files = [
12
+ "README.rdoc",
13
+ "geoplanet.gemspec",
14
+ "lib/geoplanet.rb",
15
+ "lib/geoplanet/base.rb",
16
+ "lib/geoplanet/place.rb",
17
+ "lib/geoplanet/version.rb"
18
+ ]
19
+
20
+ s.add_dependency("rest-client", [">= 0.9"])
21
+ s.add_dependency("json", [">= 1.1.3"])
22
+
23
+ s.has_rdoc = false
24
+ s.rdoc_options = ["--main", "README.rdoc"]
25
+ end
data/lib/geoplanet.rb ADDED
@@ -0,0 +1,29 @@
1
+ %w{rubygems rest_client}.each { |x| require x }
2
+
3
+ if defined?(ActiveSupport::JSON)
4
+ JSON = ActiveSupport::JSON
5
+ module JSON
6
+ def self.parse(json)
7
+ decode(json)
8
+ end
9
+ end
10
+ else
11
+ require 'json'
12
+ end
13
+
14
+ require 'geoplanet/version'
15
+ require 'geoplanet/base'
16
+ require 'geoplanet/place'
17
+
18
+ module GeoPlanet
19
+ API_VERSION = "v1"
20
+ API_URL = "http://where.yahooapis.com/#{API_VERSION}/"
21
+
22
+ class << self
23
+ attr_accessor :appid, :debug
24
+ end
25
+
26
+ class BadRequest < StandardError; end
27
+ class NotFound < StandardError; end
28
+ class NotAcceptable < StandardError; end
29
+ end
@@ -0,0 +1,76 @@
1
+ module GeoPlanet
2
+ class Base
3
+ class << self
4
+ def build_url(resource_path, options = {})
5
+ check_options_for(resource_path, options)
6
+
7
+ filters = extract_filters(options)
8
+ matrix_params = extract_matrix_params(options)
9
+ query_params = extract_query_params(options)
10
+
11
+ query_params[:appid] ||= GeoPlanet.appid # use default appid if not provided
12
+
13
+ raise ArgumentError, "appid or q filter missing" if query_params[:appid].nil? || resource_path == 'places' && filters[:q].nil? # required
14
+
15
+ q = ".q('#{filters[:q]}')" if filters[:q]
16
+ type = ".type('#{filters[:type]}')" if filters[:type]
17
+
18
+ query_string = q && type ? "$and(#{q},#{type})" : "#{q}#{type}"
19
+
20
+ matrix_params = ";#{matrix_params.map{|k,v| "#{k}=#{v}"}.join(';')}" if matrix_params.any?
21
+ query_params = "?#{query_params.map{|k,v| "#{k}=#{v}"}.join('&')}" if query_params.any?
22
+
23
+ query_string += "#{matrix_params}#{query_params}"
24
+
25
+ "#{GeoPlanet::API_URL}#{resource_path}#{query_string}"
26
+ end
27
+
28
+ def get(url)
29
+ RestClient.get(url)
30
+ rescue RestClient::RequestFailed
31
+ raise BadRequest, "appid, q filter or format invalid"
32
+ rescue RestClient::ResourceNotFound
33
+ raise NotFound, "woeid or URI invalid"
34
+ end
35
+
36
+ protected
37
+ def supported_options_for(resource_path)
38
+ case resource_path
39
+ when 'places'
40
+ %w(q type start count lang format callback select appid)
41
+ when /^place\/\d+\/parent$/, /^place\/\d+\/ancestors$/, /^place\/\d+$/, 'placetype'
42
+ %w(lang format callback select appid)
43
+ when /^place\/\d+\/belongtos$/, /^place\/\d+\/children$/, 'placetypes'
44
+ %w(type start count lang format callback select appid)
45
+ when /^place\/\d+\/neighbors$/, /^place\/\d+\/siblings$/
46
+ %w(start count lang format callback select appid)
47
+ else
48
+ raise NotFound, "URI invalid"
49
+ end
50
+ end
51
+
52
+ def check_options_for(resource_path, options)
53
+ supported = supported_options_for(resource_path)
54
+ unless options.keys.all?{|o| supported.include?(o.to_s)}
55
+ raise ArgumentError, "invalid option(s) for #{resource_path}. Supported are: #{supported.join(', ')}. You used: #{options.keys.join(', ')}"
56
+ end
57
+ end
58
+
59
+ def extract_filters(options)
60
+ filters = %w(q type)
61
+ options[:type] = options[:type].join(",") if options[:type].is_a?(Array)
62
+ Hash[*(options.select{|k,v| filters.include?(k.to_s)}).flatten]
63
+ end
64
+
65
+ def extract_matrix_params(options)
66
+ matrix_params = %w(start count)
67
+ Hash[*(options.select{|k,v| matrix_params.include?(k.to_s)}).flatten]
68
+ end
69
+
70
+ def extract_query_params(options)
71
+ query_params = %w(lang format callback select appid)
72
+ Hash[*(options.select{|k,v| query_params.include?(k.to_s)}).flatten]
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,119 @@
1
+ module GeoPlanet
2
+ class Place < Base
3
+ attr_reader :version # short or long
4
+ # short
5
+ attr_reader :woeid, :placetype, :placetype_code, :name, :uri, :lang
6
+ # long
7
+ attr_reader :country, :country_code, :postal
8
+ attr_reader :latitude, :longitude, :bounding_box
9
+ attr_reader :admin1, :admin1_code, :admin1_placetype
10
+ attr_reader :admin2, :admin2_code, :admin2_placetype
11
+ attr_reader :admin3, :admin3_code, :admin3_placetype
12
+ attr_reader :locality1, :locality1_placetype
13
+ attr_reader :locality2, :locality2_placetype
14
+ alias_method :lat, :latitude
15
+ alias_method :lon, :longitude
16
+
17
+ # Class methods
18
+ def self.search(text, options = {})
19
+ text = URI.encode(text)
20
+ url = build_url('places', options.merge(:q => text, :format => 'json'))
21
+ puts "Yahoo GeoPlanet: GET #{url}" if GeoPlanet.debug
22
+ get_then_parse(url)
23
+ end
24
+
25
+ def self.get_then_parse(url)
26
+ results = JSON.parse get(url)
27
+ return results['places']['place'].map{|attrs| Place.new attrs} if results['places']
28
+ return Place.new(results['place']) if results['place']
29
+ nil
30
+ rescue
31
+ nil
32
+ end
33
+
34
+ %w(parent ancestors belongtos neighbors siblings children).each do |association|
35
+ self.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
36
+ def self.#{association}_of(woeid, options = {})
37
+ url = build_url("place/\#{woeid}/#{association}", options.merge(:format => "json"))
38
+ puts "Yahoo GeoPlanet: GET \#{url}" if GeoPlanet.debug
39
+ get_then_parse(url)
40
+ end
41
+ RUBY
42
+ end
43
+
44
+ # Instance methods
45
+ def initialize(woe_or_attrs, options = {})
46
+ case woe_or_attrs
47
+ when Integer then initialize_with_woe(woe_or_attrs, options)
48
+ when Hash then initialize_with_attrs(woe_or_attrs)
49
+ else
50
+ raise ArgumentError
51
+ end
52
+ end
53
+
54
+ def initialize_with_woe(woe, options = {})
55
+ url = self.class.build_url("place/#{woe}", options.merge(:format => "json"))
56
+ puts "Yahoo GeoPlanet: GET #{url}" if GeoPlanet.debug
57
+ initialize_with_attrs JSON.parse(Place.get(url))['place']
58
+ end
59
+
60
+
61
+ def initialize_with_attrs(attrs)
62
+ @version = attrs['centroid'] ? 'long' : 'short'
63
+
64
+ # short
65
+ @woeid = attrs['woeid']
66
+ @placetype = attrs['placeTypeName']
67
+ @placetype_code = attrs['placeTypeName attrs']['code']
68
+ @name = attrs['name']
69
+ @uri = attrs['uri']
70
+ @lang = attrs['lang']
71
+
72
+ if version == 'long'
73
+ # long
74
+ @latitude = attrs['centroid']['latitude']
75
+ @longitude = attrs['centroid']['longitude']
76
+ @bounding_box = [ [ attrs['boundingBox']['southWest']['latitude'],
77
+ attrs['boundingBox']['southWest']['longitude'] ],
78
+ [ attrs['boundingBox']['northEast']['latitude'],
79
+ attrs['boundingBox']['northEast']['longitude'] ],
80
+ ]
81
+ @country = attrs['country']
82
+ @country_code = attrs['country attrs']['code'] rescue nil
83
+ @postal = attrs['postal']
84
+ @admin1 = attrs['admin1']
85
+ @admin1_code = attrs['admin1 attrs']['code'] rescue nil
86
+ @admin1_placetype = attrs['admin1 attrs']['type'] rescue nil
87
+ @admin2 = attrs['admin2']
88
+ @admin2_code = attrs['admin2 attrs']['code'] rescue nil
89
+ @admin2_placetype = attrs['admin2 attrs']['type'] rescue nil
90
+ @admin3 = attrs['admin3']
91
+ @admin3_code = attrs['admin3 attrs']['code'] rescue nil
92
+ @admin3_placetype = attrs['admin3 attrs']['type'] rescue nil
93
+ @locality1 = attrs['locality1']
94
+ @locality1_placetype = attrs['locality1 attrs']['type'] rescue nil
95
+ @locality2 = attrs['locality2']
96
+ @locality2_placetype = attrs['locality2 attrs']['type'] rescue nil
97
+ end
98
+ self
99
+ end
100
+
101
+ # Association Collections
102
+ %w(parent ancestors belongtos neighbors siblings children).each do |association|
103
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
104
+ def #{association}(options = {})
105
+ Place.send("#{association}_of", self.woeid, options)
106
+ end
107
+ RUBY
108
+ end
109
+
110
+ def to_s
111
+ self.name
112
+ end
113
+
114
+ def to_i
115
+ self.woeid.to_i
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,8 @@
1
+ module GeoPlanet
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 2
5
+ TINY = 2
6
+ STRING = [MAJOR, MINOR, TINY].join('.')
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geoplanet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Carlos Paramio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-01 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rest-client
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0.9"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.3
34
+ version:
35
+ description: A Ruby wrapper for the Yahoo! GeoPlanet API. It uses JSON format by default to minimize bandwidth usage. See http://developer.yahoo.com/geo/ for more information about the API.
36
+ email: carlosparamio@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - README.rdoc
45
+ - geoplanet.gemspec
46
+ - lib/geoplanet.rb
47
+ - lib/geoplanet/base.rb
48
+ - lib/geoplanet/place.rb
49
+ - lib/geoplanet/version.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/carlosparamio/geoplanet/
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --main
57
+ - README.rdoc
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ requirements: []
73
+
74
+ rubyforge_project:
75
+ rubygems_version: 1.3.5
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: A Ruby wrapper for the Yahoo! GeoPlanet API.
79
+ test_files: []
80
+