ym4r 0.0.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/README +24 -8
  2. data/lib/ym4r.rb +3 -4
  3. data/lib/ym4r/google_maps.rb +7 -0
  4. data/lib/ym4r/google_maps/api_key.rb +10 -0
  5. data/lib/ym4r/google_maps/config/config.yml +1 -0
  6. data/lib/ym4r/google_maps/control.rb +59 -0
  7. data/lib/ym4r/google_maps/helper.rb +19 -0
  8. data/lib/ym4r/google_maps/map.rb +94 -0
  9. data/lib/ym4r/google_maps/mapping.rb +70 -0
  10. data/lib/ym4r/google_maps/overlay.rb +125 -0
  11. data/lib/ym4r/google_maps/point.rb +34 -0
  12. data/lib/ym4r/yahoo_maps.rb +2 -0
  13. data/lib/ym4r/yahoo_maps/app_id.rb +5 -0
  14. data/lib/ym4r/yahoo_maps/building_block.rb +4 -0
  15. data/lib/ym4r/yahoo_maps/building_block/exception.rb +21 -0
  16. data/lib/ym4r/yahoo_maps/building_block/geocoding.rb +81 -0
  17. data/lib/ym4r/yahoo_maps/building_block/local_search.rb +156 -0
  18. data/lib/ym4r/yahoo_maps/building_block/map_image.rb +75 -0
  19. data/lib/ym4r/yahoo_maps/building_block/traffic.rb +120 -0
  20. data/lib/ym4r/yahoo_maps/flash.rb +7 -0
  21. data/lib/ym4r/yahoo_maps/flash/latlon.rb +18 -0
  22. data/lib/ym4r/yahoo_maps/flash/map.rb +74 -0
  23. data/lib/ym4r/yahoo_maps/flash/mapping.rb +71 -0
  24. data/lib/ym4r/yahoo_maps/flash/marker.rb +43 -0
  25. data/lib/ym4r/yahoo_maps/flash/overlay.rb +44 -0
  26. data/lib/ym4r/yahoo_maps/flash/tool.rb +30 -0
  27. data/lib/ym4r/yahoo_maps/flash/widget.rb +33 -0
  28. data/rakefile.rb +4 -4
  29. data/test/test_geocoding.rb +3 -3
  30. data/test/test_local_search.rb +2 -2
  31. data/test/test_map_image.rb +3 -3
  32. data/test/test_maps.rb +14 -0
  33. data/test/test_traffic.rb +1 -1
  34. metadata +30 -9
  35. data/lib/ym4r/app_id.rb +0 -3
  36. data/lib/ym4r/building_block/geocoding.rb +0 -81
  37. data/lib/ym4r/building_block/local_search.rb +0 -156
  38. data/lib/ym4r/building_block/map_image.rb +0 -76
  39. data/lib/ym4r/building_block/traffic.rb +0 -120
  40. data/lib/ym4r/exception.rb +0 -18
@@ -0,0 +1,34 @@
1
+ require 'ym4r/google_maps/mapping'
2
+
3
+ module Ym4r
4
+ module GoogleMaps
5
+ class GPoint < Struct.new(:x,:y)
6
+ include MappingObject
7
+ def create
8
+ "new GPoint(#{x},#{y})"
9
+ end
10
+ end
11
+ class GBounds
12
+ include MappingObject
13
+ attr_accessor :points
14
+
15
+ def initialize(points)
16
+ if !points.empty? and points[0].is_a?(Array)
17
+ @points = points.collect { |pt| GPoint.new(pt[0],pt[1]) }
18
+ else
19
+ @points = points
20
+ end
21
+ end
22
+ def create
23
+ "new GBounds([#{@points.map { |pt| pt.to_javascript}.join(",")}])"
24
+ end
25
+ end
26
+ class GSize < Struct.new(:width,:height)
27
+ include MappingObject
28
+ def create
29
+ "new GSize(#{width},#{height})"
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,2 @@
1
+ require 'ym4r/yahoo_maps/building_block'
2
+ require 'ym4r/yahoo_maps/flash'
@@ -0,0 +1,5 @@
1
+ module Ym4r
2
+ module YahooMaps
3
+ APP_ID = "YahooMaps4Ruby"
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ require 'ym4r/yahoo_maps/building_block/geocoding'
2
+ require 'ym4r/yahoo_maps/building_block/map_image'
3
+ require 'ym4r/yahoo_maps/building_block/traffic'
4
+ require 'ym4r/yahoo_maps/building_block/local_search'
@@ -0,0 +1,21 @@
1
+ module Ym4r
2
+ module YahooMaps
3
+ module BuildingBlock
4
+ #Raised if the rate limit per 24 hours per IP is reached
5
+ class RateLimitExceededException < StandardError
6
+ end
7
+
8
+ #Raised if the Yahoo Maps building bloc service is unreachable
9
+ class ConnectionException < StandardError
10
+ end
11
+
12
+ #Raised if the service returns an HTTP error (due to bad arguments passed to the service)
13
+ class BadRequestException < StandardError
14
+ end
15
+
16
+ #Raised if all the data needed is not passed to the get method of the service
17
+ class MissingParameterException < StandardError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+ require 'ym4r/yahoo_maps/app_id'
2
+ require 'ym4r/yahoo_maps/building_block/exception'
3
+ require 'open-uri'
4
+ require 'rexml/document'
5
+
6
+ module Ym4r
7
+ module YahooMaps
8
+ module BuildingBlock
9
+ module Geocoding
10
+ #Sends a request to the Yahoo! Maps geocoding service and returns the result in an easy to use Ruby object, hiding the creation of the query string and the XML parsing of the answer.
11
+ def self.get(param)
12
+ unless param.has_key?(:street) or
13
+ param.has_key?(:city) or
14
+ param.has_key?(:state) or
15
+ param.has_key?(:zip) or
16
+ param.has_key?(:location)
17
+ raise MissingParameterException.new("Missing location data for the Yahoo! Maps Geocoding service")
18
+ end
19
+
20
+ url = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=#{Ym4r::YahooMaps::APP_ID}&"
21
+ url << "street=#{param[:street]}&" if param.has_key?(:street)
22
+ url << "city=#{param[:city]}&" if param.has_key?(:city)
23
+ url << "state=#{param[:state]}&" if param.has_key?(:state)
24
+ url << "zip=#{param[:zip]}&" if param.has_key?(:zip)
25
+ url << "location=#{param[:location]}&" if param.has_key?(:location)
26
+ url << "output=xml"
27
+
28
+ begin
29
+ xml = open(URI.encode(url)).read
30
+ rescue OpenURI::HTTPError => error
31
+ raise BadRequestException.new(error.to_s)
32
+ rescue
33
+ raise ConnectionException.new("Unable to connect to Yahoo! Maps Geocoding service")
34
+ end
35
+
36
+ doc = REXML::Document.new(xml)
37
+
38
+ if doc.root.name == "Error"
39
+ raise RateLimitExceededException.new("Rate limit exceeded for Yahoo! Maps Geocoding service")
40
+ else
41
+ results = []
42
+ doc.elements.each("//Result") do |result|
43
+ data = result.elements
44
+ results << Geocoding::Result.new(result.attributes['precision'],
45
+ result.attributes['warning'],
46
+ data['Latitude'].text.to_f,
47
+ data['Longitude'].text.to_f,
48
+ data['Address'].text,
49
+ data['City'].text,
50
+ data['State'].text,
51
+ data['Zip'].text,
52
+ data['Country'].text)
53
+ end
54
+ results
55
+ end
56
+ end
57
+
58
+ #Contains a result match from the Yahoo! Maps geocoding service.
59
+ class Result < Struct.new(:precision,:warning,:latitude,:longitude,:address,:city,:state,:zip,:country)
60
+
61
+ #Convenience method for the lazy.
62
+ def latlon
63
+ [latitude,longitude]
64
+ end
65
+
66
+ #Convenience method for the lazy.
67
+ def lonlat
68
+ [longitude,latitude]
69
+ end
70
+
71
+ #Indicates if the location passed in the request could be exactly identified.
72
+ def exact_match?
73
+ warning.nil?
74
+ end
75
+
76
+ end
77
+
78
+ end #Geocoding
79
+ end #BuildingBlock
80
+ end
81
+ end #Ym4r
@@ -0,0 +1,156 @@
1
+ require 'ym4r/yahoo_maps/app_id'
2
+ require 'ym4r/yahoo_maps/building_block/exception'
3
+ require 'open-uri'
4
+ require 'rexml/document'
5
+
6
+ module Ym4r
7
+ module YahooMaps
8
+ module BuildingBlock
9
+ module LocalSearch
10
+ #Send a request to the local search REST API V3.
11
+ def self.get(param)
12
+
13
+ unless param.has_key?(:street) or
14
+ param.has_key?(:city) or
15
+ param.has_key?(:state) or
16
+ param.has_key?(:zip) or
17
+ param.has_key?(:location) or
18
+ (param.has_key?(:longitude) and param.has_key?(:latitude))
19
+ raise MissingParameterException.new("Missing location data for the Yahoo! Maps Local Search service")
20
+ end
21
+
22
+ unless param.has_key?(:query) or
23
+ param.has_key?(:listing_id)
24
+ raise MissingParameterException.new("Missing query data for the Yahoo! Maps Local Search service")
25
+ end
26
+
27
+ url = "http://api.local.yahoo.com/LocalSearchService/V3/localSearch?appid=#{Ym4r::YahooMaps::APP_ID}&"
28
+ url << "query=#{param[:query]}&" if param.has_key?(:query)
29
+ url << "listing_id=#{param[:query]}&" if param.has_key?(:listing_id)
30
+ url << "results=#{param[:results]}&" if param.has_key?(:results)
31
+ url << "start=#{param[:start]}&" if param.has_key?(:start)
32
+ url << "sort=#{param[:sort]}&" if param.has_key?(:sort)
33
+ url << "radius=#{param[:radius]}&" if param.has_key?(:radius)
34
+ url << "street=#{param[:street]}&" if param.has_key?(:street)
35
+ url << "city=#{param[:city]}&" if param.has_key?(:city)
36
+ url << "state=#{param[:state]}&" if param.has_key?(:state)
37
+ url << "zip=#{param[:zip]}&" if param.has_key?(:zip)
38
+ url << "location=#{param[:location]}&" if param.has_key?(:location)
39
+ url << "latitude=#{param[:latitude]}&" if param.has_key?(:latitude)
40
+ url << "longitude=#{param[:longitude]}&" if param.has_key?(:longitude)
41
+ url << "category=#{param[:category]}&" if param.has_key?(:category)
42
+ url << "omit_category=#{param[:omit_category]}&" if param.has_key?(:omit_category)
43
+ url << "minimum_rating=#{param[:minimum_rating]}&" if param.has_key?(:minimum_rating)
44
+ url << "output=json"
45
+
46
+ begin
47
+ json = open(URI.encode(url)).read
48
+ rescue OpenURI::HTTPError => error
49
+ raise BadRequestException.new(error.to_s)
50
+ rescue
51
+ raise ConnectionException.new("Unable to connect to Yahoo! Maps REST service")
52
+ end
53
+
54
+ #see http://rubyforge.org/snippet/detail.php?type=snippet&id=29. Safe?
55
+ json_obj = eval(json.gsub(/(["'])\s*:\s*(['"0-9tfn\[{])/){"#{$1}=>#{$2}"})
56
+
57
+ if json_obj.has_key?("Error")
58
+ raise RateLimitExceededException.new("Rate limit exceeded for Yahoo! Maps Traffic REST service")
59
+ else
60
+ json_result_set = json_obj['ResultSet']
61
+
62
+ result_set = LocalSearch::ResultSet.new(json_result_set['ResultSetMapUrl'],
63
+ json_result_set['totalResultsAvailable'].to_i,
64
+ json_result_set['totalResultsReturned'].to_i,
65
+ json_result_set['firstResultPosition'].to_i)
66
+
67
+ unless json_result_set['Result'].nil?
68
+ json_results = [json_result_set['Result']].flatten #uniform processing in case there is only one result
69
+
70
+ json_results.each do |json_result|
71
+
72
+ #get the rating
73
+ json_rating = json_result['Rating']
74
+ rating = LocalSearch::Rating.new(json_rating['AverageRating'].to_f, #when NaN, converted to 0 but can be tested (since TotalRating is 0 in this case) with is_rated? on the rating object
75
+ json_rating['TotalRatings'].to_i,
76
+ json_rating['TotalReviews'].to_i,
77
+ Time.at(json_rating['LastReviewDate'].to_i),
78
+ json_rating['LastReviewIntro'])
79
+
80
+ #get the categories
81
+ categories = []
82
+ unless json_result['Categories']['Category'].nil? #no category present in the result
83
+ json_categories = [json_result['Categories']['Category']].flatten #uniform processing in case there is only one category
84
+ json_categories.each do |json_category|
85
+ categories << LocalSearch::Category.new(json_category['id'].to_i,
86
+ json_category['content'])
87
+ end
88
+ end
89
+
90
+ result_set << LocalSearch::Result.new(json_result['id'].to_i,
91
+ json_result['Title'],
92
+ json_result['Address'],
93
+ json_result['City'],
94
+ json_result['State'],
95
+ json_result['Phone'],
96
+ json_result['Latitude'].to_f,
97
+ json_result['Longitude'].to_f,
98
+ rating,
99
+ json_result['Distance'].to_f,
100
+ json_result['Url'],
101
+ json_result['ClickUrl'],
102
+ json_result['MapUrl'],
103
+ json_result['BusinessUrl'],
104
+ json_result['BusinessClickUrl'],
105
+ categories)
106
+
107
+ end
108
+ end #unless json_result_set['Result'].nil?
109
+
110
+ result_set
111
+
112
+ end
113
+ end
114
+
115
+ #Contains a list of results from the Yahoo! Maps Local Search REST service V3
116
+ class ResultSet < Array
117
+ attr_accessor :map_url, :total_results_available, :total_results_returned, :first_result_position
118
+
119
+ def initialize(map_url,total_results_available, total_results_returned, first_result_position)
120
+ super(0)
121
+ @map_url = map_url
122
+ @total_results_available = total_results_available
123
+ @total_results_returned = total_results_returned
124
+ @first_result_position = first_result_position
125
+ end
126
+
127
+ end
128
+
129
+ #Contains a result from the Yahoo! Maps Local Search REST service V3.
130
+ class Result < Struct.new(:id,:title,:address,:city,:state,:phone,:latitude,:longitude,:rating,:distance,:url,:click_url,:map_url,:business_url,:business_click_url,:categories)
131
+
132
+ #convenience method for the lazy
133
+ def lonlat
134
+ [longitude,latitude]
135
+ end
136
+
137
+ #convenience method for the lazy
138
+ def latlon
139
+ [latitude,longitude]
140
+ end
141
+
142
+ end
143
+
144
+ class Category < Struct.new(:id,:name)
145
+ end
146
+
147
+ class Rating < Struct.new(:average_rating,:total_ratings,:total_reviews,:last_review_date,:last_review_intro)
148
+ def is_rated?
149
+ total_ratings != 0
150
+ end
151
+ end
152
+
153
+ end #LocalSearch
154
+ end #BuildingBlock
155
+ end
156
+ end #Ym4r
@@ -0,0 +1,75 @@
1
+ require 'ym4r/yahoo_maps/app_id'
2
+ require 'ym4r/yahoo_maps/building_block/exception'
3
+ require 'open-uri'
4
+ require 'rexml/document'
5
+
6
+ module Ym4r
7
+ module YahooMaps
8
+ module BuildingBlock
9
+ module MapImage
10
+ #Send a request to the Map image API. Gets back a url to an image. This image can be downloaded later.
11
+ def self.get(param)
12
+ unless param.has_key?(:street) or
13
+ param.has_key?(:city) or
14
+ param.has_key?(:state) or
15
+ param.has_key?(:zip) or
16
+ param.has_key?(:location) or
17
+ (param.has_key?(:longitude) and param.has_key?(:latitude))
18
+ raise MissingParameterException.new("Missing location data for the Yahoo! Maps Map Image service")
19
+ end
20
+
21
+ url = "http://api.local.yahoo.com/MapsService/V1/mapImage?appid=#{Ym4r::YahooMaps::APP_ID}&"
22
+ url << "street=#{param[:street]}&" if param.has_key?(:street)
23
+ url << "city=#{param[:city]}&" if param.has_key?(:city)
24
+ url << "state=#{param[:state]}&" if param.has_key?(:state)
25
+ url << "zip=#{param[:zip]}&" if param.has_key?(:zip)
26
+ url << "location=#{param[:location]}&" if param.has_key?(:location)
27
+ url << "latitude=#{param[:latitude]}&" if param.has_key?(:latitude)
28
+ url << "longitude=#{param[:longitude]}&" if param.has_key?(:longitude)
29
+ url << "image_type=#{param[:image_type]}&" if param.has_key?(:image_type) #defaults to PNG
30
+ url << "image_height=#{param[:image_height]}&" if param.has_key?(:image_height) #defaults to 500
31
+ url << "image_width=#{param[:image_width]}&" if param.has_key?(:image_width) #defaults to 620
32
+ url << "zoom=#{param[:zoom]}&" if param.has_key?(:zoom) #defaults to 6
33
+ url << "radius=#{param[:radius]}&" if param.has_key?(:radius)
34
+ url << "output=xml"
35
+
36
+ begin
37
+ xml = open(URI.encode(url)).read
38
+ rescue OpenURI::HTTPError => error
39
+ raise BadRequestException.new(error.to_s)
40
+ rescue
41
+ raise ConnectionException.new("Unable to connect to Yahoo! Maps Map Image service")
42
+ end
43
+
44
+ doc = REXML::Document.new(xml)
45
+
46
+ if doc.root.name == "Error"
47
+ raise RateLimitExceededException.new("Rate limit exceeded for Yahoo! Maps Map Image service")
48
+ else
49
+ result = doc.root
50
+ MapImage::Result.new(result.attributes['warning'],
51
+ result.text)
52
+ end
53
+ end
54
+
55
+ #Contains a result match from the Yahoo! Maps Map Image service.
56
+ class Result < Struct.new(:warning,:url)
57
+
58
+ #Downloads the image to +file+.
59
+ def download_to(file)
60
+ data = open(url).read
61
+ open(file,"wb") do |f|
62
+ f.write data
63
+ end
64
+ end
65
+
66
+ #Indicates if the location passed in the request could be exactly identified.
67
+ def exact_match?
68
+ warning.nil?
69
+ end
70
+
71
+ end
72
+ end #MapImage
73
+ end #BuildingBlock
74
+ end
75
+ end #Ym4r
@@ -0,0 +1,120 @@
1
+ require 'ym4r/yahoo_maps/app_id'
2
+ require 'ym4r/yahoo_maps/building_block/exception'
3
+ require 'open-uri'
4
+ require 'rexml/document'
5
+
6
+ module Ym4r
7
+ module YahooMaps
8
+ module BuildingBlock
9
+ module Traffic
10
+ #Send a request to the traffic REST API.
11
+ def self.get(param)
12
+ unless param.has_key?(:street) or
13
+ param.has_key?(:city) or
14
+ param.has_key?(:state) or
15
+ param.has_key?(:zip) or
16
+ param.has_key?(:location) or
17
+ (param.has_key?(:longitude) and param.has_key?(:latitude))
18
+ raise MissingParameterException.new("Missing location data for the Yahoo! Maps Traffic service")
19
+ end
20
+
21
+ url = "http://api.local.yahoo.com/MapsService/V1/trafficData?appid=#{Ym4r::YahooMaps::APP_ID}&"
22
+ url << "street=#{param[:street]}&" if param.has_key?(:street)
23
+ url << "city=#{param[:city]}&" if param.has_key?(:city)
24
+ url << "state=#{param[:state]}&" if param.has_key?(:state)
25
+ url << "zip=#{param[:zip]}&" if param.has_key?(:zip)
26
+ url << "location=#{param[:location]}&" if param.has_key?(:location)
27
+ url << "latitude=#{param[:latitude]}&" if param.has_key?(:latitude)
28
+ url << "longitude=#{param[:longitude]}&" if param.has_key?(:longitude)
29
+ url << "image_type=#{param[:image_type]}&" if param.has_key?(:image_type) #defaults to PNG
30
+ url << "image_height=#{param[:image_height]}&" if param.has_key?(:image_height) #defaults to 500
31
+ url << "image_width=#{param[:image_width]}&" if param.has_key?(:image_width) #defaults to 620
32
+ url << "zoom=#{param[:zoom]}&" if param.has_key?(:zoom) #defaults to 6
33
+ url << "radius=#{param[:radius]}&" if param.has_key?(:radius)
34
+ url << "include_map=#{param[:include_map]?1:0}&" if param.has_key?(:include_map)
35
+ url << "severity=#{param[:severity]}&" if param.has_key?(:severity)
36
+ url << "output=xml"
37
+
38
+ begin
39
+ xml = open(URI.encode(url)).read
40
+ rescue OpenURI::HTTPError => error
41
+ raise BadRequestException.new(error.to_s)
42
+ rescue
43
+ raise ConnectionException.new("Unable to connect to Yahoo! Maps Traffic REST service")
44
+ end
45
+
46
+ doc = REXML::Document.new(xml)
47
+
48
+ if doc.root.name == "Error"
49
+ raise RateLimitExceededException.new("Rate limit exceeded for Yahoo! Maps Traffic REST service")
50
+ else
51
+ results = Traffic::ResultSet.new(Time.at(doc.root.elements['LastUpdateDate'].text.to_i),doc.root.elements['Warning'].nil? ? nil : doc.root.elements['Warning'].text)
52
+
53
+ doc.root.elements.each('//Result') do |result|
54
+ data = result.elements
55
+ results << Traffic::Result.new(result.attributes['type'],
56
+ data['Title'].text,
57
+ data['Description'].text,
58
+ data['Latitude'].text.to_f,
59
+ data['Longitude'].text.to_f,
60
+ data['Direction'].text,
61
+ data['Severity'].text.to_i,
62
+ Time.at(data['ReportDate'].text.to_i),
63
+ Time.at(data['UpdateDate'].text.to_i),
64
+ Time.at(data['EndDate'].text.to_i),
65
+ data['ImageUrl'].nil? ? nil : data['ImageUrl'].text)
66
+ end
67
+ results
68
+
69
+ end
70
+ end
71
+
72
+ #Contains a list of results from the Yahoo! Maps Traffic REST API
73
+ class ResultSet < Array
74
+ attr_accessor :last_update_date,:warning
75
+
76
+ def initialize(last_update_date,warning)
77
+ super(0)
78
+ @last_update_date = last_update_date
79
+ @warning = warning
80
+ end
81
+
82
+ #Indicates if the location passed in the request could be exactly identified.
83
+ def exact_match?
84
+ warning.nil?
85
+ end
86
+ end
87
+
88
+ #Contains a result from the Yahoo! Maps Traffic REST service.
89
+ class Result < Struct.new(:type,:title,:description,:latitude,:longitude,:direction,:severity,:report_date,:update_date,:end_date,:image_url)
90
+
91
+ #Downloads the image (if there is one) to +file+.
92
+ def download_to(file)
93
+ if has_image?
94
+ data = open(image_url).read
95
+ open(file,"wb") do |f|
96
+ f.write data
97
+ end
98
+ end
99
+ end
100
+
101
+ def has_image?
102
+ ! image_url.nil?
103
+ end
104
+
105
+ #Convenience method for the lazy.
106
+ def lonlat
107
+ [longitude,latitude]
108
+ end
109
+
110
+ #Convenience method for the lazy.
111
+ def latlon
112
+ [latitude,longitude]
113
+ end
114
+
115
+ end
116
+
117
+ end #Traffic
118
+ end #BuildingBlock
119
+ end
120
+ end #Ym4r