rails-geocoder 0.9.8 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG.rdoc +16 -1
- data/README.rdoc +123 -55
- data/Rakefile +2 -33
- data/VERSION +1 -0
- data/lib/geocoder.rb +79 -5
- data/lib/geocoder/configuration.rb +11 -3
- data/lib/geocoder/lookups/base.rb +110 -0
- data/lib/geocoder/lookups/freegeoip.rb +40 -0
- data/lib/geocoder/lookups/google.rb +31 -0
- data/lib/geocoder/lookups/yahoo.rb +29 -0
- data/lib/geocoder/{active_record.rb → orms/active_record.rb} +27 -82
- data/lib/geocoder/orms/active_record_legacy.rb +58 -0
- data/lib/geocoder/orms/base.rb +96 -0
- data/lib/geocoder/railtie.rb +50 -38
- data/lib/geocoder/request.rb +17 -0
- data/lib/geocoder/results/base.rb +58 -0
- data/lib/geocoder/results/freegeoip.rb +37 -0
- data/lib/geocoder/{result.rb → results/google.rb} +26 -8
- data/lib/geocoder/results/yahoo.rb +40 -0
- data/lib/tasks/geocoder.rake +1 -1
- data/rails-geocoder.gemspec +15 -0
- data/test/fixtures/freegeoip_74_200_247_59.json +12 -0
- data/test/fixtures/google_garbage.json +456 -0
- data/test/fixtures/google_madison_square_garden.json +57 -0
- data/test/fixtures/google_no_results.json +4 -0
- data/test/fixtures/yahoo_garbage.json +50 -0
- data/test/fixtures/yahoo_madison_square_garden.json +46 -0
- data/test/fixtures/yahoo_no_results.json +10 -0
- data/test/geocoder_test.rb +185 -12
- data/test/test_helper.rb +84 -17
- metadata +51 -17
- data/lib/geocoder/lookup.rb +0 -90
data/lib/geocoder/railtie.rb
CHANGED
@@ -17,52 +17,64 @@ module Geocoder
|
|
17
17
|
|
18
18
|
class Railtie
|
19
19
|
def self.insert
|
20
|
-
|
21
20
|
return unless defined?(::ActiveRecord)
|
21
|
+
::ActiveRecord::Base.extend(ModelMethods)
|
22
|
+
end
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
##
|
26
|
+
# Methods available in the model class before Geocoder is invoked.
|
27
|
+
#
|
28
|
+
module ModelMethods
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
##
|
31
|
+
# Set attribute names and include the Geocoder module.
|
32
|
+
#
|
33
|
+
def geocoded_by(address_attr, options = {}, &block)
|
34
|
+
geocoder_init(
|
35
|
+
:geocode => true,
|
36
|
+
:user_address => address_attr,
|
37
|
+
:latitude => options[:latitude] || :latitude,
|
38
|
+
:longitude => options[:longitude] || :longitude,
|
39
|
+
:geocode_block => block
|
40
|
+
)
|
41
|
+
end
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
##
|
44
|
+
# Set attribute names and include the Geocoder module.
|
45
|
+
#
|
46
|
+
def reverse_geocoded_by(latitude_attr, longitude_attr, options = {}, &block)
|
47
|
+
geocoder_init(
|
48
|
+
:reverse_geocode => true,
|
49
|
+
:fetched_address => options[:address] || :address,
|
50
|
+
:latitude => latitude_attr,
|
51
|
+
:longitude => longitude_attr,
|
52
|
+
:reverse_block => block
|
53
|
+
)
|
54
|
+
end
|
49
55
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
class_inheritable_hash_writer :geocoder_options
|
54
|
-
end
|
55
|
-
self.geocoder_options = options
|
56
|
-
unless _geocoder_initialized?
|
57
|
-
include Geocoder::ActiveRecord
|
58
|
-
end
|
59
|
-
end
|
56
|
+
def geocoder_options
|
57
|
+
@geocoder_options
|
58
|
+
end
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
|
61
|
+
private # ----------------------------------------------------------------
|
62
|
+
|
63
|
+
def geocoder_init(options)
|
64
|
+
unless geocoder_initialized?
|
65
|
+
@geocoder_options = {}
|
66
|
+
require 'geocoder/orms/active_record'
|
67
|
+
include Geocoder::Orm::ActiveRecord
|
64
68
|
end
|
69
|
+
@geocoder_options.merge! options
|
70
|
+
end
|
65
71
|
|
72
|
+
def geocoder_initialized?
|
73
|
+
begin
|
74
|
+
included_modules.include? Geocoder::Orm::ActiveRecord
|
75
|
+
rescue NameError
|
76
|
+
false
|
77
|
+
end
|
66
78
|
end
|
67
79
|
end
|
68
80
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'geocoder'
|
2
|
+
|
3
|
+
module Geocoder
|
4
|
+
module Request
|
5
|
+
|
6
|
+
def location
|
7
|
+
unless defined?(@location)
|
8
|
+
@location = Geocoder.search(ip)
|
9
|
+
end
|
10
|
+
@location
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if defined?(Rack) and defined?(Rack::Request)
|
16
|
+
Rack::Request.send :include, Geocoder::Request
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Geocoder
|
2
|
+
module Result
|
3
|
+
class Base
|
4
|
+
attr_accessor :data
|
5
|
+
|
6
|
+
##
|
7
|
+
# Takes a hash of result data from a parsed Google result document.
|
8
|
+
#
|
9
|
+
def initialize(data)
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# A string in the given format.
|
15
|
+
#
|
16
|
+
def address(format = :full)
|
17
|
+
fail
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# A two-element array: [lat, lon].
|
22
|
+
#
|
23
|
+
def coordinates
|
24
|
+
[@data['latitude'].to_f, @data['longitude'].to_f]
|
25
|
+
end
|
26
|
+
|
27
|
+
def latitude
|
28
|
+
coordinates[0]
|
29
|
+
end
|
30
|
+
|
31
|
+
def longitude
|
32
|
+
coordinates[1]
|
33
|
+
end
|
34
|
+
|
35
|
+
def country
|
36
|
+
fail
|
37
|
+
end
|
38
|
+
|
39
|
+
def country_code
|
40
|
+
fail
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](i)
|
44
|
+
if i == 0
|
45
|
+
warn "DEPRECATION WARNING: You called '[0]' on a Geocoder::Result object. Geocoder.search(...) now returns a single result instead of an array so this is no longer necessary. This warning will be removed and an error will result in geocoder 1.0."
|
46
|
+
elsif i.is_a?(Fixnum)
|
47
|
+
warn "DEPRECATION WARNING: You tried to access a Geocoder result but Geocoder.search(...) now returns a single result instead of an array. This warning will be removed and an error will result in geocoder 1.0."
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def first
|
53
|
+
warn "DEPRECATION WARNING: You called '.first' on a Geocoder::Result object. Geocoder.search(...) now returns a single result instead of an array so this is no longer necessary. This warning will be removed and an error will result in geocoder 1.0."
|
54
|
+
self
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Freegeoip < Base
|
5
|
+
|
6
|
+
def address(format = :full)
|
7
|
+
"#{city}#{', ' + region_code unless region_code == ''} #{postal_code}, #{country}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def city
|
11
|
+
@data['city']
|
12
|
+
end
|
13
|
+
|
14
|
+
def country
|
15
|
+
@data['country_name']
|
16
|
+
end
|
17
|
+
|
18
|
+
def country_code
|
19
|
+
@data['country_code']
|
20
|
+
end
|
21
|
+
|
22
|
+
def postal_code
|
23
|
+
@data['zipcode']
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.response_attributes
|
27
|
+
%w[city region_code region_name metrocode
|
28
|
+
zipcode country_name country_code ip]
|
29
|
+
end
|
30
|
+
|
31
|
+
response_attributes.each do |a|
|
32
|
+
define_method a do
|
33
|
+
@data[a]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,12 +1,30 @@
|
|
1
|
-
|
2
|
-
class Result
|
3
|
-
attr_accessor :data
|
1
|
+
require 'geocoder/results/base'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def
|
9
|
-
|
3
|
+
module Geocoder::Result
|
4
|
+
class Google < Base
|
5
|
+
|
6
|
+
def coordinates
|
7
|
+
['lat', 'lng'].map{ |i| geometry['location'][i] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def address(format = :full)
|
11
|
+
formatted_address
|
12
|
+
end
|
13
|
+
|
14
|
+
def city
|
15
|
+
address_components_of_type(:locality).first['long_name']
|
16
|
+
end
|
17
|
+
|
18
|
+
def country
|
19
|
+
address_components_of_type(:country).first['long_name']
|
20
|
+
end
|
21
|
+
|
22
|
+
def country_code
|
23
|
+
address_components_of_type(:country).first['short_name']
|
24
|
+
end
|
25
|
+
|
26
|
+
def postal_code
|
27
|
+
address_components_of_type(:postal_code).first['long_name']
|
10
28
|
end
|
11
29
|
|
12
30
|
def types
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class Yahoo < Base
|
5
|
+
|
6
|
+
def address(format = :full)
|
7
|
+
(1..4).to_a.map{ |i| @data["line#{i}"] }.reject{ |i| i.nil? or i == "" }.join(", ")
|
8
|
+
end
|
9
|
+
|
10
|
+
def city
|
11
|
+
@data['city']
|
12
|
+
end
|
13
|
+
|
14
|
+
def country
|
15
|
+
@data['country']
|
16
|
+
end
|
17
|
+
|
18
|
+
def country_code
|
19
|
+
@data['countrycode']
|
20
|
+
end
|
21
|
+
|
22
|
+
def postal_code
|
23
|
+
@data['postal']
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.response_attributes
|
27
|
+
%w[quality offsetlat offsetlon radius boundingbox name
|
28
|
+
line1 line2 line3 line4 cross house street xstreet unittype unit postal
|
29
|
+
neighborhood city county state country countrycode statecode countycode
|
30
|
+
level0 level1 level2 level3 level4 level0code level1code level2code
|
31
|
+
timezone areacode uzip hash woeid woetype]
|
32
|
+
end
|
33
|
+
|
34
|
+
response_attributes.each do |a|
|
35
|
+
define_method a do
|
36
|
+
@data[a]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/tasks/geocoder.rake
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = "rails-geocoder"
|
4
|
+
s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION'))
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.authors = ["Alex Reisner"]
|
7
|
+
s.email = ["alex@alexreisner.com"]
|
8
|
+
s.homepage = "http://github.com/alexreisner/geocoder"
|
9
|
+
s.date = Date.today.to_s
|
10
|
+
s.summary = "Complete geocoding solution for Ruby."
|
11
|
+
s.description = "Provides object geocoding (by street or IP address), reverse geocoding (coordinates to street address), and distance calculations for geocoded objects. Designed for Rails but works with other frameworks too."
|
12
|
+
s.files = `git ls-files`.split("\n") - %w[geocoder.gemspec Gemfile init.rb]
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
s.add_dependency 'json', '>= 1.0.0'
|
15
|
+
end
|
@@ -0,0 +1,456 @@
|
|
1
|
+
{
|
2
|
+
"status": "OK",
|
3
|
+
"results": [ {
|
4
|
+
"types": [ "postal_code" ],
|
5
|
+
"formatted_address": "Hedge End, Southampton, Hampshire SO30 4RT, UK",
|
6
|
+
"address_components": [ {
|
7
|
+
"long_name": "SO30 4RT",
|
8
|
+
"short_name": "SO30 4RT",
|
9
|
+
"types": [ "postal_code" ]
|
10
|
+
}, {
|
11
|
+
"long_name": "Hedge End",
|
12
|
+
"short_name": "Hedge End",
|
13
|
+
"types": [ "sublocality", "political" ]
|
14
|
+
}, {
|
15
|
+
"long_name": "Southampton",
|
16
|
+
"short_name": "Southampton",
|
17
|
+
"types": [ "locality", "political" ]
|
18
|
+
}, {
|
19
|
+
"long_name": "Hampshire",
|
20
|
+
"short_name": "Hampshire",
|
21
|
+
"types": [ "administrative_area_level_2", "political" ]
|
22
|
+
}, {
|
23
|
+
"long_name": "United Kingdom",
|
24
|
+
"short_name": "GB",
|
25
|
+
"types": [ "country", "political" ]
|
26
|
+
}, {
|
27
|
+
"long_name": "SO30",
|
28
|
+
"short_name": "SO30",
|
29
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
30
|
+
} ],
|
31
|
+
"geometry": {
|
32
|
+
"location": {
|
33
|
+
"lat": 50.9173897,
|
34
|
+
"lng": -1.3125111
|
35
|
+
},
|
36
|
+
"location_type": "APPROXIMATE",
|
37
|
+
"viewport": {
|
38
|
+
"southwest": {
|
39
|
+
"lat": 50.9142421,
|
40
|
+
"lng": -1.3156587
|
41
|
+
},
|
42
|
+
"northeast": {
|
43
|
+
"lat": 50.9205373,
|
44
|
+
"lng": -1.3093635
|
45
|
+
}
|
46
|
+
}
|
47
|
+
},
|
48
|
+
"partial_match": true
|
49
|
+
}, {
|
50
|
+
"types": [ "postal_code" ],
|
51
|
+
"formatted_address": "Enfield, London N13 4RT, UK",
|
52
|
+
"address_components": [ {
|
53
|
+
"long_name": "N13 4RT",
|
54
|
+
"short_name": "N13 4RT",
|
55
|
+
"types": [ "postal_code" ]
|
56
|
+
}, {
|
57
|
+
"long_name": "London",
|
58
|
+
"short_name": "London",
|
59
|
+
"types": [ "locality", "political" ]
|
60
|
+
}, {
|
61
|
+
"long_name": "Enfield",
|
62
|
+
"short_name": "Enfield",
|
63
|
+
"types": [ "administrative_area_level_3", "political" ]
|
64
|
+
}, {
|
65
|
+
"long_name": "Greater London",
|
66
|
+
"short_name": "Greater London",
|
67
|
+
"types": [ "administrative_area_level_2", "political" ]
|
68
|
+
}, {
|
69
|
+
"long_name": "United Kingdom",
|
70
|
+
"short_name": "GB",
|
71
|
+
"types": [ "country", "political" ]
|
72
|
+
}, {
|
73
|
+
"long_name": "N13",
|
74
|
+
"short_name": "N13",
|
75
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
76
|
+
} ],
|
77
|
+
"geometry": {
|
78
|
+
"location": {
|
79
|
+
"lat": 51.6329009,
|
80
|
+
"lng": -0.0994552
|
81
|
+
},
|
82
|
+
"location_type": "APPROXIMATE",
|
83
|
+
"viewport": {
|
84
|
+
"southwest": {
|
85
|
+
"lat": 51.6297533,
|
86
|
+
"lng": -0.1026028
|
87
|
+
},
|
88
|
+
"northeast": {
|
89
|
+
"lat": 51.6360485,
|
90
|
+
"lng": -0.0963076
|
91
|
+
}
|
92
|
+
}
|
93
|
+
},
|
94
|
+
"partial_match": true
|
95
|
+
}, {
|
96
|
+
"types": [ "postal_code" ],
|
97
|
+
"formatted_address": "Cardiff, South Glamorgan CF5 4RT, UK",
|
98
|
+
"address_components": [ {
|
99
|
+
"long_name": "CF5 4RT",
|
100
|
+
"short_name": "CF5 4RT",
|
101
|
+
"types": [ "postal_code" ]
|
102
|
+
}, {
|
103
|
+
"long_name": "Caerau",
|
104
|
+
"short_name": "Caerau",
|
105
|
+
"types": [ "locality", "political" ]
|
106
|
+
}, {
|
107
|
+
"long_name": "Cardiff",
|
108
|
+
"short_name": "Cardiff",
|
109
|
+
"types": [ "locality", "political" ]
|
110
|
+
}, {
|
111
|
+
"long_name": "South Glamorgan",
|
112
|
+
"short_name": "South Glam",
|
113
|
+
"types": [ "administrative_area_level_2", "political" ]
|
114
|
+
}, {
|
115
|
+
"long_name": "Cardiff",
|
116
|
+
"short_name": "Cardiff",
|
117
|
+
"types": [ "administrative_area_level_2", "political" ]
|
118
|
+
}, {
|
119
|
+
"long_name": "United Kingdom",
|
120
|
+
"short_name": "GB",
|
121
|
+
"types": [ "country", "political" ]
|
122
|
+
}, {
|
123
|
+
"long_name": "CF5",
|
124
|
+
"short_name": "CF5",
|
125
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
126
|
+
} ],
|
127
|
+
"geometry": {
|
128
|
+
"location": {
|
129
|
+
"lat": 51.4675314,
|
130
|
+
"lng": -3.2642245
|
131
|
+
},
|
132
|
+
"location_type": "APPROXIMATE",
|
133
|
+
"viewport": {
|
134
|
+
"southwest": {
|
135
|
+
"lat": 51.4643838,
|
136
|
+
"lng": -3.2673721
|
137
|
+
},
|
138
|
+
"northeast": {
|
139
|
+
"lat": 51.4706790,
|
140
|
+
"lng": -3.2610769
|
141
|
+
}
|
142
|
+
}
|
143
|
+
},
|
144
|
+
"partial_match": true
|
145
|
+
}, {
|
146
|
+
"types": [ "postal_code" ],
|
147
|
+
"formatted_address": "Monifieth, Dundee, Angus DD5 4RT, UK",
|
148
|
+
"address_components": [ {
|
149
|
+
"long_name": "DD5 4RT",
|
150
|
+
"short_name": "DD5 4RT",
|
151
|
+
"types": [ "postal_code" ]
|
152
|
+
}, {
|
153
|
+
"long_name": "Monifieth",
|
154
|
+
"short_name": "Monifieth",
|
155
|
+
"types": [ "sublocality", "political" ]
|
156
|
+
}, {
|
157
|
+
"long_name": "Dundee",
|
158
|
+
"short_name": "Dundee",
|
159
|
+
"types": [ "locality", "political" ]
|
160
|
+
}, {
|
161
|
+
"long_name": "Angus",
|
162
|
+
"short_name": "Angus",
|
163
|
+
"types": [ "administrative_area_level_2", "political" ]
|
164
|
+
}, {
|
165
|
+
"long_name": "United Kingdom",
|
166
|
+
"short_name": "GB",
|
167
|
+
"types": [ "country", "political" ]
|
168
|
+
}, {
|
169
|
+
"long_name": "DD5",
|
170
|
+
"short_name": "DD5",
|
171
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
172
|
+
} ],
|
173
|
+
"geometry": {
|
174
|
+
"location": {
|
175
|
+
"lat": 56.4840193,
|
176
|
+
"lng": -2.8291620
|
177
|
+
},
|
178
|
+
"location_type": "APPROXIMATE",
|
179
|
+
"viewport": {
|
180
|
+
"southwest": {
|
181
|
+
"lat": 56.4808717,
|
182
|
+
"lng": -2.8323096
|
183
|
+
},
|
184
|
+
"northeast": {
|
185
|
+
"lat": 56.4871669,
|
186
|
+
"lng": -2.8260144
|
187
|
+
}
|
188
|
+
}
|
189
|
+
},
|
190
|
+
"partial_match": true
|
191
|
+
}, {
|
192
|
+
"types": [ "postal_code" ],
|
193
|
+
"formatted_address": "Reading RG30 4RT, UK",
|
194
|
+
"address_components": [ {
|
195
|
+
"long_name": "RG30 4RT",
|
196
|
+
"short_name": "RG30 4RT",
|
197
|
+
"types": [ "postal_code" ]
|
198
|
+
}, {
|
199
|
+
"long_name": "Reading",
|
200
|
+
"short_name": "Reading",
|
201
|
+
"types": [ "locality", "political" ]
|
202
|
+
}, {
|
203
|
+
"long_name": "Reading",
|
204
|
+
"short_name": "Reading",
|
205
|
+
"types": [ "administrative_area_level_2", "political" ]
|
206
|
+
}, {
|
207
|
+
"long_name": "United Kingdom",
|
208
|
+
"short_name": "GB",
|
209
|
+
"types": [ "country", "political" ]
|
210
|
+
}, {
|
211
|
+
"long_name": "RG30",
|
212
|
+
"short_name": "RG30",
|
213
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
214
|
+
} ],
|
215
|
+
"geometry": {
|
216
|
+
"location": {
|
217
|
+
"lat": 51.4554901,
|
218
|
+
"lng": -1.0393378
|
219
|
+
},
|
220
|
+
"location_type": "APPROXIMATE",
|
221
|
+
"viewport": {
|
222
|
+
"southwest": {
|
223
|
+
"lat": 51.4523425,
|
224
|
+
"lng": -1.0424854
|
225
|
+
},
|
226
|
+
"northeast": {
|
227
|
+
"lat": 51.4586377,
|
228
|
+
"lng": -1.0361902
|
229
|
+
}
|
230
|
+
}
|
231
|
+
},
|
232
|
+
"partial_match": true
|
233
|
+
}, {
|
234
|
+
"types": [ "postal_code" ],
|
235
|
+
"formatted_address": "Blyth, Northumberland NE24 4RT, UK",
|
236
|
+
"address_components": [ {
|
237
|
+
"long_name": "NE24 4RT",
|
238
|
+
"short_name": "NE24 4RT",
|
239
|
+
"types": [ "postal_code" ]
|
240
|
+
}, {
|
241
|
+
"long_name": "Blyth",
|
242
|
+
"short_name": "Blyth",
|
243
|
+
"types": [ "locality", "political" ]
|
244
|
+
}, {
|
245
|
+
"long_name": "Northumberland",
|
246
|
+
"short_name": "Nthumb",
|
247
|
+
"types": [ "administrative_area_level_2", "political" ]
|
248
|
+
}, {
|
249
|
+
"long_name": "United Kingdom",
|
250
|
+
"short_name": "GB",
|
251
|
+
"types": [ "country", "political" ]
|
252
|
+
}, {
|
253
|
+
"long_name": "NE24",
|
254
|
+
"short_name": "NE24",
|
255
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
256
|
+
} ],
|
257
|
+
"geometry": {
|
258
|
+
"location": {
|
259
|
+
"lat": 55.1314523,
|
260
|
+
"lng": -1.5533331
|
261
|
+
},
|
262
|
+
"location_type": "APPROXIMATE",
|
263
|
+
"viewport": {
|
264
|
+
"southwest": {
|
265
|
+
"lat": 55.1283047,
|
266
|
+
"lng": -1.5564807
|
267
|
+
},
|
268
|
+
"northeast": {
|
269
|
+
"lat": 55.1345999,
|
270
|
+
"lng": -1.5501855
|
271
|
+
}
|
272
|
+
}
|
273
|
+
},
|
274
|
+
"partial_match": true
|
275
|
+
}, {
|
276
|
+
"types": [ "postal_code" ],
|
277
|
+
"formatted_address": "Glasgow, Glasgow City G44 4RT, UK",
|
278
|
+
"address_components": [ {
|
279
|
+
"long_name": "G44 4RT",
|
280
|
+
"short_name": "G44 4RT",
|
281
|
+
"types": [ "postal_code" ]
|
282
|
+
}, {
|
283
|
+
"long_name": "Glasgow",
|
284
|
+
"short_name": "Glasgow",
|
285
|
+
"types": [ "locality", "political" ]
|
286
|
+
}, {
|
287
|
+
"long_name": "Glasgow City",
|
288
|
+
"short_name": "Glasgow City",
|
289
|
+
"types": [ "administrative_area_level_2", "political" ]
|
290
|
+
}, {
|
291
|
+
"long_name": "United Kingdom",
|
292
|
+
"short_name": "GB",
|
293
|
+
"types": [ "country", "political" ]
|
294
|
+
}, {
|
295
|
+
"long_name": "G44",
|
296
|
+
"short_name": "G44",
|
297
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
298
|
+
} ],
|
299
|
+
"geometry": {
|
300
|
+
"location": {
|
301
|
+
"lat": 55.8234812,
|
302
|
+
"lng": -4.2507991
|
303
|
+
},
|
304
|
+
"location_type": "APPROXIMATE",
|
305
|
+
"viewport": {
|
306
|
+
"southwest": {
|
307
|
+
"lat": 55.8203336,
|
308
|
+
"lng": -4.2539467
|
309
|
+
},
|
310
|
+
"northeast": {
|
311
|
+
"lat": 55.8266288,
|
312
|
+
"lng": -4.2476515
|
313
|
+
}
|
314
|
+
}
|
315
|
+
},
|
316
|
+
"partial_match": true
|
317
|
+
}, {
|
318
|
+
"types": [ "postal_code" ],
|
319
|
+
"formatted_address": "Waltham Forest, London E17 4RT, UK",
|
320
|
+
"address_components": [ {
|
321
|
+
"long_name": "E17 4RT",
|
322
|
+
"short_name": "E17 4RT",
|
323
|
+
"types": [ "postal_code" ]
|
324
|
+
}, {
|
325
|
+
"long_name": "London",
|
326
|
+
"short_name": "London",
|
327
|
+
"types": [ "locality", "political" ]
|
328
|
+
}, {
|
329
|
+
"long_name": "Walthamstow",
|
330
|
+
"short_name": "Walthamstow",
|
331
|
+
"types": [ "locality", "political" ]
|
332
|
+
}, {
|
333
|
+
"long_name": "Waltham Forest",
|
334
|
+
"short_name": "Waltham Forest",
|
335
|
+
"types": [ "administrative_area_level_3", "political" ]
|
336
|
+
}, {
|
337
|
+
"long_name": "Greater London",
|
338
|
+
"short_name": "Greater London",
|
339
|
+
"types": [ "administrative_area_level_2", "political" ]
|
340
|
+
}, {
|
341
|
+
"long_name": "United Kingdom",
|
342
|
+
"short_name": "GB",
|
343
|
+
"types": [ "country", "political" ]
|
344
|
+
}, {
|
345
|
+
"long_name": "E17",
|
346
|
+
"short_name": "E17",
|
347
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
348
|
+
} ],
|
349
|
+
"geometry": {
|
350
|
+
"location": {
|
351
|
+
"lat": 51.5853714,
|
352
|
+
"lng": -0.0192463
|
353
|
+
},
|
354
|
+
"location_type": "APPROXIMATE",
|
355
|
+
"viewport": {
|
356
|
+
"southwest": {
|
357
|
+
"lat": 51.5822238,
|
358
|
+
"lng": -0.0223939
|
359
|
+
},
|
360
|
+
"northeast": {
|
361
|
+
"lat": 51.5885190,
|
362
|
+
"lng": -0.0160987
|
363
|
+
}
|
364
|
+
}
|
365
|
+
},
|
366
|
+
"partial_match": true
|
367
|
+
}, {
|
368
|
+
"types": [ "postal_code" ],
|
369
|
+
"formatted_address": "Dunstable, Central Bedfordshire LU5 4RT, UK",
|
370
|
+
"address_components": [ {
|
371
|
+
"long_name": "LU5 4RT",
|
372
|
+
"short_name": "LU5 4RT",
|
373
|
+
"types": [ "postal_code" ]
|
374
|
+
}, {
|
375
|
+
"long_name": "Dunstable",
|
376
|
+
"short_name": "Dunstable",
|
377
|
+
"types": [ "locality", "political" ]
|
378
|
+
}, {
|
379
|
+
"long_name": "Central Bedfordshire",
|
380
|
+
"short_name": "Central Bedfordshire",
|
381
|
+
"types": [ "administrative_area_level_2", "political" ]
|
382
|
+
}, {
|
383
|
+
"long_name": "United Kingdom",
|
384
|
+
"short_name": "GB",
|
385
|
+
"types": [ "country", "political" ]
|
386
|
+
}, {
|
387
|
+
"long_name": "LU5",
|
388
|
+
"short_name": "LU5",
|
389
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
390
|
+
} ],
|
391
|
+
"geometry": {
|
392
|
+
"location": {
|
393
|
+
"lat": 51.8869978,
|
394
|
+
"lng": -0.5175666
|
395
|
+
},
|
396
|
+
"location_type": "APPROXIMATE",
|
397
|
+
"viewport": {
|
398
|
+
"southwest": {
|
399
|
+
"lat": 51.8838502,
|
400
|
+
"lng": -0.5207142
|
401
|
+
},
|
402
|
+
"northeast": {
|
403
|
+
"lat": 51.8901454,
|
404
|
+
"lng": -0.5144190
|
405
|
+
}
|
406
|
+
}
|
407
|
+
},
|
408
|
+
"partial_match": true
|
409
|
+
}, {
|
410
|
+
"types": [ "postal_code" ],
|
411
|
+
"formatted_address": "Newton Aycliffe, County Durham DL5 4RT, UK",
|
412
|
+
"address_components": [ {
|
413
|
+
"long_name": "DL5 4RT",
|
414
|
+
"short_name": "DL5 4RT",
|
415
|
+
"types": [ "postal_code" ]
|
416
|
+
}, {
|
417
|
+
"long_name": "Newton Aycliffe",
|
418
|
+
"short_name": "Newton Aycliffe",
|
419
|
+
"types": [ "locality", "political" ]
|
420
|
+
}, {
|
421
|
+
"long_name": "Great Aycliffe",
|
422
|
+
"short_name": "Great Aycliffe",
|
423
|
+
"types": [ "locality", "political" ]
|
424
|
+
}, {
|
425
|
+
"long_name": "Durham",
|
426
|
+
"short_name": "Dur",
|
427
|
+
"types": [ "administrative_area_level_2", "political" ]
|
428
|
+
}, {
|
429
|
+
"long_name": "United Kingdom",
|
430
|
+
"short_name": "GB",
|
431
|
+
"types": [ "country", "political" ]
|
432
|
+
}, {
|
433
|
+
"long_name": "DL5",
|
434
|
+
"short_name": "DL5",
|
435
|
+
"types": [ "postal_code_prefix", "postal_code" ]
|
436
|
+
} ],
|
437
|
+
"geometry": {
|
438
|
+
"location": {
|
439
|
+
"lat": 54.6323273,
|
440
|
+
"lng": -1.5704658
|
441
|
+
},
|
442
|
+
"location_type": "APPROXIMATE",
|
443
|
+
"viewport": {
|
444
|
+
"southwest": {
|
445
|
+
"lat": 54.6291797,
|
446
|
+
"lng": -1.5736134
|
447
|
+
},
|
448
|
+
"northeast": {
|
449
|
+
"lat": 54.6354749,
|
450
|
+
"lng": -1.5673182
|
451
|
+
}
|
452
|
+
}
|
453
|
+
},
|
454
|
+
"partial_match": true
|
455
|
+
} ]
|
456
|
+
}
|