rails-geocoder 0.9.8 → 0.9.9
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/.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
|
+
}
|