barometer 0.7.2 → 0.7.3

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 CHANGED
@@ -15,7 +15,7 @@ this.
15
15
 
16
16
  == version
17
17
 
18
- Version 0.7.2 is the current release of this gem. The gem is available from
18
+ Version 0.7.3 is the current release of this gem. The gem is available from
19
19
  gemcutter (barometer: http://gemcutter.org/gems/barometer).
20
20
  Older version are available through rubyforge (barometer) and github
21
21
  (attack-barometer).
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 7
4
- :patch: 2
4
+ :patch: 3
5
5
  :build:
data/barometer.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{barometer}
5
- s.version = "0.7.2"
5
+ s.version = "0.7.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.rubygems_version = %q{1.3.5}
data/bin/barometer CHANGED
@@ -53,7 +53,7 @@ require 'yaml'
53
53
 
54
54
  # file where API keys are stored
55
55
  KEY_FILE = File.expand_path(File.join('~', '.barometer'))
56
- BAROMETER_VERSION = '0.7.2'
56
+ BAROMETER_VERSION = '0.7.3'
57
57
 
58
58
  class App
59
59
 
@@ -69,7 +69,7 @@ class App
69
69
  @options.timezone = false
70
70
  @options.metric = true
71
71
  @options.sources = []
72
- @options.verbode = false
72
+ @options.verbose = false
73
73
  @options.at = nil
74
74
  @options.default = true
75
75
 
data/lib/barometer.rb CHANGED
@@ -15,6 +15,13 @@ module Barometer
15
15
  def self.debug!; @@debug_mode = true; end;
16
16
  def self.debug?; @@debug_mode; end;
17
17
 
18
+ def self.google_geocode_key
19
+ warn "[DEPRECATION] `Barometer.google_geocode_key` is deprecated. A Google API key is no longer needed"
20
+ end
21
+ def self.google_geocode_key=(google_key)
22
+ warn "[DEPRECATION] `Barometer.google_geocode_key=(key)` is deprecated. A Google API key is no longer needed"
23
+ end
24
+
18
25
  @@yahoo_placemaker_app_id = nil
19
26
  def self.yahoo_placemaker_app_id; @@yahoo_placemaker_app_id; end;
20
27
  def self.yahoo_placemaker_app_id=(yahoo_key); @@yahoo_placemaker_app_id = yahoo_key; end;
@@ -16,44 +16,42 @@ module Barometer
16
16
  self
17
17
  end
18
18
 
19
- # build the Geo object from a Hash
20
- #
21
19
  def build_from_hash(location=nil)
22
20
  return nil unless location
23
21
  raise ArgumentError unless location.is_a?(Hash)
24
22
 
25
- @query = location["name"]
26
- placemark = location["Placemark"]
27
- placemark = find_most_accurate(placemark)
28
-
29
- if placemark && placemark["Point"] && placemark["Point"]["coordinates"]
30
- if placemark["Point"]["coordinates"].is_a?(Array)
31
- @latitude = placemark["Point"]["coordinates"][1].to_f
32
- @longitude = placemark["Point"]["coordinates"][0].to_f
33
- else
34
- @latitude = placemark["Point"]["coordinates"].split(',')[1].to_f
35
- @longitude = placemark["Point"]["coordinates"].split(',')[0].to_f
36
- end
23
+ if location["geometry"] && location["geometry"]["location"]
24
+ @latitude = location["geometry"]["location"]["lat"].to_f
25
+ @longitude = location["geometry"]["location"]["lng"].to_f
37
26
  end
38
- if placemark && placemark["AddressDetails"] && placemark["AddressDetails"]["Country"]
39
- country = placemark["AddressDetails"]["Country"]
40
- if country["AdministrativeArea"]
41
- ad_area = country["AdministrativeArea"]
42
- if ad_area["SubAdministrativeArea"]
43
- @locality = ad_area["SubAdministrativeArea"]["Locality"]["LocalityName"]
44
- elsif ad_area["DependentLocality"] && ad_area["DependentLocality"]["DependentLocalityName"]
45
- @locality = ad_area["DependentLocality"]["DependentLocalityName"]
46
- elsif ad_area["Locality"] && ad_area["Locality"]["LocalityName"]
47
- @locality = ad_area["Locality"]["LocalityName"]
48
- else
49
- @locality = ""
27
+
28
+ query_parts = []
29
+ if location["address_components"]
30
+ location["address_components"].each do |address_components|
31
+ skip unless address_components["types"]
32
+ # sublocality trumps locality
33
+ if address_components["types"].include?('sublocality')
34
+ @locality = address_components["long_name"]
35
+ end
36
+ if address_components["types"].include?('locality')
37
+ @locality ||= address_components["long_name"]
38
+ end
39
+ if address_components["types"].include?('administrative_area_level_1')
40
+ #@region = address_components["long_name"]
41
+ @region = address_components["short_name"]
42
+ end
43
+ if address_components["types"].include?('country')
44
+ @country = address_components["long_name"]
45
+ @country_code = address_components["short_name"]
46
+ end
47
+ if !(address_components["types"] & location["types"]).empty?
48
+ query_parts << address_components["long_name"]
50
49
  end
51
- @region = ad_area["AdministrativeAreaName"]
52
50
  end
53
- @country = country["CountryName"]
54
- @country_code = country["CountryNameCode"]
55
- @address = country["AddressLine"]
56
51
  end
52
+
53
+ @query = query_parts.join(', ')
54
+ @address = ""
57
55
  end
58
56
 
59
57
  def coordinates
@@ -65,17 +63,6 @@ module Barometer
65
63
  s.delete("")
66
64
  s.compact.join(', ')
67
65
  end
68
-
69
- # geocode may return multiple results, use the first one that has the best accuracy
70
- #
71
- def find_most_accurate(placemark)
72
- return placemark unless placemark.is_a?(Array)
73
- most_accurate = placemark.first
74
- placemark.each do |p|
75
- most_accurate = p if p && p["AddressDetails"] && p["AddressDetails"]["Accuracy"] && p["AddressDetails"]["Accuracy"].to_i < most_accurate["AddressDetails"]["Accuracy"].to_i
76
- end
77
- most_accurate
78
- end
79
66
 
80
67
  end
81
68
  end
@@ -127,7 +127,7 @@ module Barometer
127
127
  forecasts = Measurement::ResultArray.new
128
128
  # go through each forecast and create an instance
129
129
  if data && data["aws:forecast"]
130
- start_date = Date.strptime(data['date'], "%a, %d %b %Y %H:%M:%S %Z")
130
+ start_date = Date.strptime(data['date'], "%m/%d/%Y %H:%M:%S %p")
131
131
  i = 0
132
132
  data["aws:forecast"].each do |forecast|
133
133
  forecast_measurement = Measurement::Result.new
@@ -9,17 +9,24 @@ module Barometer
9
9
  def self.fetch(query)
10
10
  raise ArgumentError unless _is_a_query?(query)
11
11
  puts "geocoding: #{query.q}" if Barometer::debug?
12
+
13
+ query_params = {}
14
+ query_params[:region] = query.country_code
15
+ query_params[:sensor] = 'false'
16
+
17
+ if query.format == :coordinates
18
+ query_params[:latlng] = query.q
19
+ else
20
+ query_params[:address] = query.q
21
+ end
22
+
12
23
  location = self.get(
13
- "http://maps.google.com/maps/geo",
14
- :query => {
15
- :gl => query.country_code,
16
- :output => "json",
17
- :q => query.q,
18
- :sensor => "false"
19
- },
20
- :format => :json, :timeout => Barometer.timeout
24
+ "http://maps.googleapis.com/maps/api/geocode/json",
25
+ :query => query_params,
26
+ :format => :json,
27
+ :timeout => Barometer.timeout
21
28
  )
22
- location = location['kml']['Response'] if (location && location['kml'])
29
+ location = location['results'].first if (location && location['results'])
23
30
  location ? (geo = Data::Geo.new(location)) : nil
24
31
  end
25
32
 
@@ -21,6 +21,18 @@ describe "Barometer" do
21
21
  Barometer.source(:wunderground).should == Barometer::WeatherService::Wunderground
22
22
  end
23
23
 
24
+ it "deprecates the Google geocoding API key reader" do
25
+ Barometer.should_receive(:warn)
26
+ Barometer.respond_to?("google_geocode_key").should be_true
27
+ Barometer.google_geocode_key
28
+ end
29
+
30
+ it "deprecates the Google geocoding API key writer" do
31
+ Barometer.should_receive(:warn)
32
+ Barometer.respond_to?("google_geocode_key=").should be_true
33
+ Barometer.google_geocode_key= 'KEY'
34
+ end
35
+
24
36
  it "sets the Placemaker Yahoo! app ID" do
25
37
  Barometer.respond_to?("yahoo_placemaker_app_id").should be_true
26
38
  Barometer.yahoo_placemaker_app_id = nil
@@ -12,49 +12,49 @@ YAHOO_KEY = "YAHOO"
12
12
  #
13
13
  # for geocoding
14
14
  #
15
- geo_url = "http://maps.google.com/maps/geo?"
15
+ geo_url_v3 = "http://maps.googleapis.com/maps/api/geocode/json?"
16
16
 
17
- # http://maps.google.com/maps/geo?gl=US&sensor=false&q=90210&output=json
17
+ # http://maps.googleapis.com/maps/api/geocode/json?region=US&sensor=false&address=90210
18
18
  FakeWeb.register_uri(:get,
19
- "#{geo_url}gl=US&sensor=false&q=90210&output=json",
20
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/90210.json')
19
+ "#{geo_url_v3}region=US&sensor=false&address=90210",
20
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/90210_v3.json')
21
21
  )
22
- # http://maps.google.com/maps/geo?gl=&q=40.756054%2C-73.986951&output=json&sensor=false
22
+ # http://maps.googleapis.com/maps/api/geocode/json?region=&sensor=false&latlng=40.756054%2C-73.986951
23
23
  FakeWeb.register_uri(:get,
24
- "#{geo_url}gl=&q=#{CGI.escape("40.756054,-73.986951")}&output=json&sensor=false",
25
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/40_73.json')
24
+ "#{geo_url_v3}region=&sensor=false&latlng=40.756054%2C-73.986951",
25
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/40_73_v3.json')
26
26
  )
27
- # http://maps.google.com/maps/geo?gl=&q=New%20York%2C%20NY&output=json&sensor=false
27
+ # http://maps.googleapis.com/maps/api/geocode/json?region=&sensor=false&address=New%20York%2C%20NY
28
28
  FakeWeb.register_uri(:get,
29
- "#{geo_url}gl=&q=New%20York%2C%20NY&output=json&sensor=false",
30
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/newyork_ny.json')
29
+ "#{geo_url_v3}region=&sensor=false&address=New%20York%2C%20NY",
30
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/newyork_ny_v3.json')
31
31
  )
32
- # http://maps.google.com/maps/geo?gl=CA&output=json&q=T5B%204M9&sensor=false
32
+ # http://maps.googleapis.com/maps/api/geocode/json?region=CA&sensor=false&address=T5B%204M9
33
33
  FakeWeb.register_uri(:get,
34
- "#{geo_url}gl=CA&output=json&q=T5B%204M9&sensor=false",
35
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/T5B4M9.json')
34
+ "#{geo_url_v3}region=CA&sensor=false&address=T5B%204M9",
35
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/T5B4M9_v3.json')
36
36
  )
37
- # http://maps.google.com/maps/geo?gl=US&q=KSFO&output=json&sensor=false
37
+ # http://maps.googleapis.com/maps/api/geocode/json?region=US&sensor=false&address=KSFO
38
38
  FakeWeb.register_uri(:get,
39
- "#{geo_url}gl=US&q=KSFO&output=json&sensor=false",
40
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/ksfo.json')
39
+ "#{geo_url_v3}region=US&sensor=false&address=KSFO",
40
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/ksfo_v3.json')
41
41
  )
42
- # http://maps.google.com/maps/geo?gl=&q=Atlanta%2C%20GA%2C%20US&output=json&sensor=false
42
+ # http://maps.googleapis.com/maps/api/geocode/json?region=&sensor=false&address=Atlanta%2C%20GA%2C%20US
43
43
  FakeWeb.register_uri(:get,
44
- "#{geo_url}gl=&q=Atlanta%2C%20GA%2C%20US&output=json&sensor=false",
45
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/atlanta.json')
44
+ "#{geo_url_v3}region=&sensor=false&address=Atlanta%2C%20GA%2C%20US",
45
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/atlanta_v3.json')
46
46
  )
47
- # http://maps.google.com/maps/geo?gl=&q=Calgary%2CAB&sensor=false&output=json
47
+ # http://maps.googleapis.com/maps/api/geocode/json?region=&sensor=false&address=Calgary%2CAB
48
48
  FakeWeb.register_uri(:get,
49
- "#{geo_url}gl=&q=Calgary%2CAB&sensor=false&output=json",
50
- :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/calgary_ab.json')
49
+ "#{geo_url_v3}region=&sensor=false&address=Calgary%2CAB",
50
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/geocode/calgary_ab_v3.json')
51
51
  )
52
52
  #
53
53
  # for weather.com searches
54
54
  #
55
55
  # http://xoap.weather.com:80/search/search?where=Beverly%20Hills%2C%20CA%2C%20USA
56
56
  FakeWeb.register_uri(:get,
57
- "http://xoap.weather.com:80/search/search?where=Beverly%20Hills%2C%20CA%2C%20USA",
57
+ "http://xoap.weather.com:80/search/search?where=Beverly%20Hills%2C%20CA%2C%20United%20States",
58
58
  :body => File.read(File.dirname(__FILE__) + '/fixtures/formats/weather_id/the_hills.xml')
59
59
  )
60
60
  # http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY
@@ -64,12 +64,12 @@ FakeWeb.register_uri(:get,
64
64
  )
65
65
  # http://xoap.weather.com:80/search/search?where=Manhattan%2C%20NY%2C%20USA
66
66
  FakeWeb.register_uri(:get,
67
- "http://xoap.weather.com:80/search/search?where=Manhattan%2C%20NY%2C%20USA",
67
+ "http://xoap.weather.com:80/search/search?where=Manhattan%2C%20NY%2C%20United%20States",
68
68
  :body => File.read(File.dirname(__FILE__) + '/fixtures/formats/weather_id/manhattan.xml')
69
69
  )
70
70
  # http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY%2C%20USA
71
71
  FakeWeb.register_uri(:get,
72
- "http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY%2C%20USA",
72
+ "http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY%2C%20United%20States",
73
73
  :body => File.read(File.dirname(__FILE__) + '/fixtures/formats/weather_id/new_york.xml')
74
74
  )
75
75
  # http://xoap.weather.com:80/search/search?where=90210
@@ -79,7 +79,7 @@ FakeWeb.register_uri(:get,
79
79
  )
80
80
  # http://xoap.weather.com:80/search/search?where=San%20Francisco%2C%20CA%2C%20USA
81
81
  FakeWeb.register_uri(:get,
82
- "http://xoap.weather.com:80/search/search?where=San%20Francisco%2C%20CA%2C%20USA",
82
+ "http://xoap.weather.com:80/search/search?where=San%20Francisco%2C%20CA%2C%20United%20States",
83
83
  :body => File.read(File.dirname(__FILE__) + '/fixtures/formats/weather_id/ksfo.xml')
84
84
  )
85
85
  #
@@ -101,17 +101,18 @@ FakeWeb.register_uri(:get,
101
101
  #
102
102
  # for WeatherBug weather
103
103
  #
104
- bug_url_current = "http://#{WEATHERBUG_CODE}.api.wxbug.net:80/getLiveWeatherRSS.aspx?"
105
- FakeWeb.register_uri(:get,
106
- "#{bug_url_current}ACode=#{WEATHERBUG_CODE}&OutputType=1&UnitType=1&zipCode=90210",
107
- :body => File.read(File.dirname(__FILE__) + '/fixtures/services/weather_bug/90210_current.xml')
108
- )
109
-
110
- bug_url_future = "http://#{WEATHERBUG_CODE}.api.wxbug.net:80/getForecastRSS.aspx?"
111
- FakeWeb.register_uri(:get,
112
- "#{bug_url_future}ACode=#{WEATHERBUG_CODE}&OutputType=1&UnitType=1&zipCode=90210",
113
- :body => File.read(File.dirname(__FILE__) + '/fixtures/services/weather_bug/90210_forecast.xml')
114
- )
104
+ # http://CODE.api.wxbug.net/getLiveWeatherRSS.aspx?ACode=CODE&OutputType=1&UnitType=1&zipCode=90210
105
+ bug_url_current = "http://#{WEATHERBUG_CODE}.api.wxbug.net:80/getLiveWeatherRSS.aspx?"
106
+ FakeWeb.register_uri(:get,
107
+ "#{bug_url_current}ACode=#{WEATHERBUG_CODE}&OutputType=1&UnitType=1&zipCode=90210",
108
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/services/weather_bug/90210_current.xml')
109
+ )
110
+ # http://CODE.api.wxbug.net/getForecastRSS.aspx?ACode=CODE&OutputType=1&UnitType=1&zipCode=90210
111
+ bug_url_future = "http://#{WEATHERBUG_CODE}.api.wxbug.net:80/getForecastRSS.aspx?"
112
+ FakeWeb.register_uri(:get,
113
+ "#{bug_url_future}ACode=#{WEATHERBUG_CODE}&OutputType=1&UnitType=1&zipCode=90210",
114
+ :body => File.read(File.dirname(__FILE__) + '/fixtures/services/weather_bug/90210_forecast.xml')
115
+ )
115
116
  #
116
117
  # for weather.com weather
117
118
  #
@@ -135,12 +136,12 @@ FakeWeb.register_uri(:get,
135
136
  #
136
137
  # http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=51.045%2C-114.0572222
137
138
  FakeWeb.register_uri(:get,
138
- "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=51.045%2C-114.0572222",
139
+ "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=51.04499999999999%2C-114.0572222",
139
140
  :body => File.read(File.dirname(__FILE__) + '/fixtures/services/wunderground/current_calgary_ab.xml')
140
141
  )
141
142
  # http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=51.045%2C-114.0572222
142
143
  FakeWeb.register_uri(:get,
143
- "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=51.045%2C-114.0572222",
144
+ "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=51.04499999999999%2C-114.0572222",
144
145
  :body => File.read(File.dirname(__FILE__) + '/fixtures/services/wunderground/forecast_calgary_ab.xml')
145
146
  )
146
147
  FakeWeb.register_uri(:get,
@@ -0,0 +1,497 @@
1
+ {
2
+ "results" : [
3
+ {
4
+ "address_components" : [
5
+ {
6
+ "long_name" : "601-699",
7
+ "short_name" : "601-699",
8
+ "types" : [ "street_number" ]
9
+ },
10
+ {
11
+ "long_name" : "7th Ave",
12
+ "short_name" : "7th Ave",
13
+ "types" : [ "route" ]
14
+ },
15
+ {
16
+ "long_name" : "Manhattan",
17
+ "short_name" : "Manhattan",
18
+ "types" : [ "sublocality", "political" ]
19
+ },
20
+ {
21
+ "long_name" : "New York",
22
+ "short_name" : "New York",
23
+ "types" : [ "locality", "political" ]
24
+ },
25
+ {
26
+ "long_name" : "New York",
27
+ "short_name" : "New York",
28
+ "types" : [ "administrative_area_level_2", "political" ]
29
+ },
30
+ {
31
+ "long_name" : "New York",
32
+ "short_name" : "NY",
33
+ "types" : [ "administrative_area_level_1", "political" ]
34
+ },
35
+ {
36
+ "long_name" : "United States",
37
+ "short_name" : "US",
38
+ "types" : [ "country", "political" ]
39
+ },
40
+ {
41
+ "long_name" : "10036",
42
+ "short_name" : "10036",
43
+ "types" : [ "postal_code" ]
44
+ }
45
+ ],
46
+ "formatted_address" : "601-699 7th Ave, Manhattan, NY 10036, USA",
47
+ "geometry" : {
48
+ "bounds" : {
49
+ "northeast" : {
50
+ "lat" : 40.75669690,
51
+ "lng" : -73.98648360
52
+ },
53
+ "southwest" : {
54
+ "lat" : 40.7560340,
55
+ "lng" : -73.98694510
56
+ }
57
+ },
58
+ "location" : {
59
+ "lat" : 40.75603950,
60
+ "lng" : -73.98691470
61
+ },
62
+ "location_type" : "RANGE_INTERPOLATED",
63
+ "viewport" : {
64
+ "northeast" : {
65
+ "lat" : 40.75951307068017,
66
+ "lng" : -73.98356672931983
67
+ },
68
+ "southwest" : {
69
+ "lat" : 40.75321782931983,
70
+ "lng" : -73.98986197068018
71
+ }
72
+ }
73
+ },
74
+ "types" : [ "street_address" ]
75
+ },
76
+ {
77
+ "address_components" : [
78
+ {
79
+ "long_name" : "Theater District - Times Square",
80
+ "short_name" : "Theater District - Times Square",
81
+ "types" : [ "neighborhood", "political" ]
82
+ },
83
+ {
84
+ "long_name" : "Manhattan",
85
+ "short_name" : "Manhattan",
86
+ "types" : [ "sublocality", "political" ]
87
+ },
88
+ {
89
+ "long_name" : "New York",
90
+ "short_name" : "New York",
91
+ "types" : [ "locality", "political" ]
92
+ },
93
+ {
94
+ "long_name" : "New York",
95
+ "short_name" : "New York",
96
+ "types" : [ "administrative_area_level_2", "political" ]
97
+ },
98
+ {
99
+ "long_name" : "New York",
100
+ "short_name" : "NY",
101
+ "types" : [ "administrative_area_level_1", "political" ]
102
+ },
103
+ {
104
+ "long_name" : "United States",
105
+ "short_name" : "US",
106
+ "types" : [ "country", "political" ]
107
+ }
108
+ ],
109
+ "formatted_address" : "Theater District - Times Square, New York, NY, USA",
110
+ "geometry" : {
111
+ "bounds" : {
112
+ "northeast" : {
113
+ "lat" : 40.7641790,
114
+ "lng" : -73.9790780
115
+ },
116
+ "southwest" : {
117
+ "lat" : 40.753730,
118
+ "lng" : -73.99088209999999
119
+ }
120
+ },
121
+ "location" : {
122
+ "lat" : 40.756590,
123
+ "lng" : -73.986260
124
+ },
125
+ "location_type" : "APPROXIMATE",
126
+ "viewport" : {
127
+ "northeast" : {
128
+ "lat" : 40.7641790,
129
+ "lng" : -73.9790780
130
+ },
131
+ "southwest" : {
132
+ "lat" : 40.753730,
133
+ "lng" : -73.99088209999999
134
+ }
135
+ }
136
+ },
137
+ "types" : [ "neighborhood", "political" ]
138
+ },
139
+ {
140
+ "address_components" : [
141
+ {
142
+ "long_name" : "10036",
143
+ "short_name" : "10036",
144
+ "types" : [ "postal_code" ]
145
+ },
146
+ {
147
+ "long_name" : "Manhattan",
148
+ "short_name" : "Manhattan",
149
+ "types" : [ "sublocality", "political" ]
150
+ },
151
+ {
152
+ "long_name" : "New York",
153
+ "short_name" : "NY",
154
+ "types" : [ "administrative_area_level_1", "political" ]
155
+ },
156
+ {
157
+ "long_name" : "United States",
158
+ "short_name" : "US",
159
+ "types" : [ "country", "political" ]
160
+ }
161
+ ],
162
+ "formatted_address" : "Manhattan, NY 10036, USA",
163
+ "geometry" : {
164
+ "bounds" : {
165
+ "northeast" : {
166
+ "lat" : 40.7760470,
167
+ "lng" : -73.9781160
168
+ },
169
+ "southwest" : {
170
+ "lat" : 40.7541550,
171
+ "lng" : -74.00951999999999
172
+ }
173
+ },
174
+ "location" : {
175
+ "lat" : 40.76314850,
176
+ "lng" : -73.99622549999999
177
+ },
178
+ "location_type" : "APPROXIMATE",
179
+ "viewport" : {
180
+ "northeast" : {
181
+ "lat" : 40.7760470,
182
+ "lng" : -73.9781160
183
+ },
184
+ "southwest" : {
185
+ "lat" : 40.7541550,
186
+ "lng" : -74.00951999999999
187
+ }
188
+ }
189
+ },
190
+ "types" : [ "postal_code" ]
191
+ },
192
+ {
193
+ "address_components" : [
194
+ {
195
+ "long_name" : "Midtown",
196
+ "short_name" : "Midtown",
197
+ "types" : [ "neighborhood", "political" ]
198
+ },
199
+ {
200
+ "long_name" : "Manhattan",
201
+ "short_name" : "Manhattan",
202
+ "types" : [ "sublocality", "political" ]
203
+ },
204
+ {
205
+ "long_name" : "New York",
206
+ "short_name" : "New York",
207
+ "types" : [ "locality", "political" ]
208
+ },
209
+ {
210
+ "long_name" : "New York",
211
+ "short_name" : "New York",
212
+ "types" : [ "administrative_area_level_2", "political" ]
213
+ },
214
+ {
215
+ "long_name" : "New York",
216
+ "short_name" : "NY",
217
+ "types" : [ "administrative_area_level_1", "political" ]
218
+ },
219
+ {
220
+ "long_name" : "United States",
221
+ "short_name" : "US",
222
+ "types" : [ "country", "political" ]
223
+ }
224
+ ],
225
+ "formatted_address" : "Midtown, New York, NY, USA",
226
+ "geometry" : {
227
+ "bounds" : {
228
+ "northeast" : {
229
+ "lat" : 40.8060980,
230
+ "lng" : -73.94221689999999
231
+ },
232
+ "southwest" : {
233
+ "lat" : 40.72732999999999,
234
+ "lng" : -74.00882020
235
+ }
236
+ },
237
+ "location" : {
238
+ "lat" : 40.7690810,
239
+ "lng" : -73.9771260
240
+ },
241
+ "location_type" : "APPROXIMATE",
242
+ "viewport" : {
243
+ "northeast" : {
244
+ "lat" : 40.8060980,
245
+ "lng" : -73.94221689999999
246
+ },
247
+ "southwest" : {
248
+ "lat" : 40.72732999999999,
249
+ "lng" : -74.00882020
250
+ }
251
+ }
252
+ },
253
+ "types" : [ "neighborhood", "political" ]
254
+ },
255
+ {
256
+ "address_components" : [
257
+ {
258
+ "long_name" : "Manhattan",
259
+ "short_name" : "Manhattan",
260
+ "types" : [ "sublocality", "political" ]
261
+ },
262
+ {
263
+ "long_name" : "New York",
264
+ "short_name" : "New York",
265
+ "types" : [ "locality", "political" ]
266
+ },
267
+ {
268
+ "long_name" : "New York",
269
+ "short_name" : "New York",
270
+ "types" : [ "administrative_area_level_2", "political" ]
271
+ },
272
+ {
273
+ "long_name" : "New York",
274
+ "short_name" : "NY",
275
+ "types" : [ "administrative_area_level_1", "political" ]
276
+ },
277
+ {
278
+ "long_name" : "United States",
279
+ "short_name" : "US",
280
+ "types" : [ "country", "political" ]
281
+ }
282
+ ],
283
+ "formatted_address" : "Manhattan, New York, NY, USA",
284
+ "geometry" : {
285
+ "bounds" : {
286
+ "northeast" : {
287
+ "lat" : 40.8200450,
288
+ "lng" : -73.90331300000001
289
+ },
290
+ "southwest" : {
291
+ "lat" : 40.6980780,
292
+ "lng" : -74.03514899999999
293
+ }
294
+ },
295
+ "location" : {
296
+ "lat" : 40.78343450,
297
+ "lng" : -73.96624950
298
+ },
299
+ "location_type" : "APPROXIMATE",
300
+ "viewport" : {
301
+ "northeast" : {
302
+ "lat" : 40.8200450,
303
+ "lng" : -73.90331300000001
304
+ },
305
+ "southwest" : {
306
+ "lat" : 40.6980780,
307
+ "lng" : -74.03514899999999
308
+ }
309
+ }
310
+ },
311
+ "types" : [ "sublocality", "political" ]
312
+ },
313
+ {
314
+ "address_components" : [
315
+ {
316
+ "long_name" : "New York",
317
+ "short_name" : "New York",
318
+ "types" : [ "administrative_area_level_2", "political" ]
319
+ },
320
+ {
321
+ "long_name" : "New York",
322
+ "short_name" : "NY",
323
+ "types" : [ "administrative_area_level_1", "political" ]
324
+ },
325
+ {
326
+ "long_name" : "United States",
327
+ "short_name" : "US",
328
+ "types" : [ "country", "political" ]
329
+ }
330
+ ],
331
+ "formatted_address" : "New York, USA",
332
+ "geometry" : {
333
+ "bounds" : {
334
+ "northeast" : {
335
+ "lat" : 40.8822140,
336
+ "lng" : -73.9070
337
+ },
338
+ "southwest" : {
339
+ "lat" : 40.67954790,
340
+ "lng" : -74.0472850
341
+ }
342
+ },
343
+ "location" : {
344
+ "lat" : 40.78306030,
345
+ "lng" : -73.97124880
346
+ },
347
+ "location_type" : "APPROXIMATE",
348
+ "viewport" : {
349
+ "northeast" : {
350
+ "lat" : 40.8822140,
351
+ "lng" : -73.9070
352
+ },
353
+ "southwest" : {
354
+ "lat" : 40.67954790,
355
+ "lng" : -74.0472850
356
+ }
357
+ }
358
+ },
359
+ "types" : [ "administrative_area_level_2", "political" ]
360
+ },
361
+ {
362
+ "address_components" : [
363
+ {
364
+ "long_name" : "New York",
365
+ "short_name" : "New York",
366
+ "types" : [ "locality", "political" ]
367
+ },
368
+ {
369
+ "long_name" : "New York",
370
+ "short_name" : "New York",
371
+ "types" : [ "administrative_area_level_2", "political" ]
372
+ },
373
+ {
374
+ "long_name" : "New York",
375
+ "short_name" : "NY",
376
+ "types" : [ "administrative_area_level_1", "political" ]
377
+ },
378
+ {
379
+ "long_name" : "United States",
380
+ "short_name" : "US",
381
+ "types" : [ "country", "political" ]
382
+ }
383
+ ],
384
+ "formatted_address" : "New York, NY, USA",
385
+ "geometry" : {
386
+ "bounds" : {
387
+ "northeast" : {
388
+ "lat" : 40.9175770,
389
+ "lng" : -73.7002720
390
+ },
391
+ "southwest" : {
392
+ "lat" : 40.4773990,
393
+ "lng" : -74.259090
394
+ }
395
+ },
396
+ "location" : {
397
+ "lat" : 40.71435280,
398
+ "lng" : -74.00597309999999
399
+ },
400
+ "location_type" : "APPROXIMATE",
401
+ "viewport" : {
402
+ "northeast" : {
403
+ "lat" : 40.9175770,
404
+ "lng" : -73.7002720
405
+ },
406
+ "southwest" : {
407
+ "lat" : 40.4773990,
408
+ "lng" : -74.259090
409
+ }
410
+ }
411
+ },
412
+ "types" : [ "locality", "political" ]
413
+ },
414
+ {
415
+ "address_components" : [
416
+ {
417
+ "long_name" : "New York",
418
+ "short_name" : "NY",
419
+ "types" : [ "administrative_area_level_1", "political" ]
420
+ },
421
+ {
422
+ "long_name" : "United States",
423
+ "short_name" : "US",
424
+ "types" : [ "country", "political" ]
425
+ }
426
+ ],
427
+ "formatted_address" : "New York, USA",
428
+ "geometry" : {
429
+ "bounds" : {
430
+ "northeast" : {
431
+ "lat" : 45.0158650,
432
+ "lng" : -71.7774910
433
+ },
434
+ "southwest" : {
435
+ "lat" : 40.4773990,
436
+ "lng" : -79.762590
437
+ }
438
+ },
439
+ "location" : {
440
+ "lat" : 43.29942850,
441
+ "lng" : -74.21793260000001
442
+ },
443
+ "location_type" : "APPROXIMATE",
444
+ "viewport" : {
445
+ "northeast" : {
446
+ "lat" : 45.0158650,
447
+ "lng" : -71.7774910
448
+ },
449
+ "southwest" : {
450
+ "lat" : 40.4773990,
451
+ "lng" : -79.762590
452
+ }
453
+ }
454
+ },
455
+ "types" : [ "administrative_area_level_1", "political" ]
456
+ },
457
+ {
458
+ "address_components" : [
459
+ {
460
+ "long_name" : "United States",
461
+ "short_name" : "US",
462
+ "types" : [ "country", "political" ]
463
+ }
464
+ ],
465
+ "formatted_address" : "United States",
466
+ "geometry" : {
467
+ "bounds" : {
468
+ "northeast" : {
469
+ "lat" : 71.53879999999999,
470
+ "lng" : -66.88507489999999
471
+ },
472
+ "southwest" : {
473
+ "lat" : 18.77630,
474
+ "lng" : 170.59570
475
+ }
476
+ },
477
+ "location" : {
478
+ "lat" : 37.090240,
479
+ "lng" : -95.7128910
480
+ },
481
+ "location_type" : "APPROXIMATE",
482
+ "viewport" : {
483
+ "northeast" : {
484
+ "lat" : 71.53879999999999,
485
+ "lng" : -66.88507489999999
486
+ },
487
+ "southwest" : {
488
+ "lat" : 18.77630,
489
+ "lng" : 170.59570
490
+ }
491
+ }
492
+ },
493
+ "types" : [ "country", "political" ]
494
+ }
495
+ ],
496
+ "status" : "OK"
497
+ }