geocoder 1.1.9 → 1.8.0
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +309 -0
- data/LICENSE +1 -1
- data/README.md +544 -540
- data/bin/console +13 -0
- data/examples/app_defined_lookup_services.rb +22 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +22 -16
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +20 -32
- data/lib/geocoder/cache_stores/base.rb +40 -0
- data/lib/geocoder/cache_stores/generic.rb +35 -0
- data/lib/geocoder/cache_stores/redis.rb +34 -0
- data/lib/geocoder/calculations.rb +67 -36
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +33 -16
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +19 -0
- data/lib/geocoder/ip_address.rb +33 -0
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +74 -11
- data/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/amazon_location_service.rb +54 -0
- data/lib/geocoder/lookups/baidu.rb +24 -15
- data/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/lib/geocoder/lookups/base.rb +109 -23
- data/lib/geocoder/lookups/bing.rb +45 -10
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +61 -8
- data/lib/geocoder/lookups/freegeoip.rb +25 -6
- data/lib/geocoder/lookups/geoapify.rb +72 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +42 -0
- data/lib/geocoder/lookups/geoip2.rb +49 -0
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +45 -12
- data/lib/geocoder/lookups/google_places_details.rb +64 -0
- data/lib/geocoder/lookups/google_places_search.rb +76 -0
- data/lib/geocoder/lookups/google_premier.rb +16 -2
- data/lib/geocoder/lookups/here.rb +73 -0
- data/lib/geocoder/lookups/ip2location.rb +71 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +58 -0
- data/lib/geocoder/lookups/location_iq.rb +54 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +9 -10
- data/lib/geocoder/lookups/maxmind.rb +10 -8
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +71 -0
- data/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/nominatim.rb +26 -6
- data/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/photon.rb +89 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +69 -0
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +68 -0
- data/lib/geocoder/lookups/telize.rb +75 -0
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/twogis.rb +58 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +18 -11
- data/lib/geocoder/models/active_record.rb +9 -4
- data/lib/geocoder/models/base.rb +1 -4
- data/lib/geocoder/models/mongo_base.rb +6 -4
- data/lib/geocoder/query.rb +23 -5
- data/lib/geocoder/railtie.rb +2 -2
- data/lib/geocoder/request.rb +102 -11
- data/lib/geocoder/results/abstract_api.rb +146 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/amazon_location_service.rb +57 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +5 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/esri.rb +35 -8
- data/lib/geocoder/results/freegeoip.rb +2 -7
- data/lib/geocoder/results/geoapify.rb +179 -0
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geocodio.rb +78 -0
- data/lib/geocoder/results/geoip2.rb +76 -0
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +26 -0
- data/lib/geocoder/results/google_places_details.rb +39 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/here.rb +77 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/lib/geocoder/results/ipregistry.rb +304 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +63 -0
- data/lib/geocoder/results/mapquest.rb +5 -8
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +44 -0
- data/lib/geocoder/results/melissa_street.rb +46 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/nominatim.rb +41 -14
- data/lib/geocoder/results/opencagedata.rb +100 -0
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/photon.rb +119 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +40 -0
- data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +142 -0
- data/lib/geocoder/results/telize.rb +40 -0
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +20 -3
- data/lib/geocoder/results/twogis.rb +76 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +244 -32
- data/lib/geocoder/sql.rb +25 -21
- data/lib/geocoder/stores/active_record.rb +82 -26
- data/lib/geocoder/stores/base.rb +9 -14
- data/lib/geocoder/stores/mongo_base.rb +0 -31
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- data/lib/geocoder.rb +6 -13
- data/lib/maxmind_database.rb +109 -0
- data/lib/tasks/geocoder.rake +30 -3
- data/lib/tasks/maxmind.rake +73 -0
- metadata +115 -98
- data/.gitignore +0 -5
- data/.travis.yml +0 -27
- data/Rakefile +0 -25
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -28
- data/gemfiles/Gemfile.mongoid-2.4.x +0 -15
- data/lib/geocoder/lookups/geocoder_us.rb +0 -39
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/lookups/yahoo.rb +0 -86
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/ovi.rb +0 -62
- data/lib/geocoder/results/yahoo.rb +0 -55
- data/lib/hash_recursive_merge.rb +0 -74
- data/lib/oauth_util.rb +0 -112
- data/test/active_record_test.rb +0 -15
- data/test/cache_test.rb +0 -35
- data/test/calculations_test.rb +0 -211
- data/test/configuration_test.rb +0 -78
- data/test/custom_block_test.rb +0 -32
- data/test/error_handling_test.rb +0 -43
- data/test/fixtures/baidu_invalid_key +0 -1
- data/test/fixtures/baidu_no_results +0 -1
- data/test/fixtures/baidu_reverse +0 -1
- data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
- data/test/fixtures/bing_invalid_key +0 -1
- data/test/fixtures/bing_madison_square_garden +0 -40
- data/test/fixtures/bing_no_results +0 -16
- data/test/fixtures/bing_reverse +0 -42
- data/test/fixtures/esri_madison_square_garden +0 -59
- data/test/fixtures/esri_no_results +0 -8
- data/test/fixtures/esri_reverse +0 -21
- data/test/fixtures/freegeoip_74_200_247_59 +0 -12
- data/test/fixtures/freegeoip_no_results +0 -1
- data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
- data/test/fixtures/geocoder_ca_no_results +0 -1
- data/test/fixtures/geocoder_ca_reverse +0 -34
- data/test/fixtures/geocoder_us_madison_square_garden +0 -1
- data/test/fixtures/geocoder_us_no_results +0 -1
- data/test/fixtures/google_garbage +0 -456
- data/test/fixtures/google_madison_square_garden +0 -57
- data/test/fixtures/google_no_city_data +0 -44
- data/test/fixtures/google_no_locality +0 -51
- data/test/fixtures/google_no_results +0 -4
- data/test/fixtures/google_over_limit +0 -4
- data/test/fixtures/mapquest_error +0 -16
- data/test/fixtures/mapquest_invalid_api_key +0 -16
- data/test/fixtures/mapquest_invalid_request +0 -16
- data/test/fixtures/mapquest_madison_square_garden +0 -52
- data/test/fixtures/mapquest_no_results +0 -16
- data/test/fixtures/maxmind_24_24_24_21 +0 -1
- data/test/fixtures/maxmind_24_24_24_22 +0 -1
- data/test/fixtures/maxmind_24_24_24_23 +0 -1
- data/test/fixtures/maxmind_24_24_24_24 +0 -1
- data/test/fixtures/maxmind_74_200_247_59 +0 -1
- data/test/fixtures/maxmind_invalid_key +0 -1
- data/test/fixtures/maxmind_no_results +0 -1
- data/test/fixtures/nominatim_madison_square_garden +0 -150
- data/test/fixtures/nominatim_no_results +0 -1
- data/test/fixtures/ovi_madison_square_garden +0 -72
- data/test/fixtures/ovi_no_results +0 -8
- data/test/fixtures/yahoo_error +0 -1
- data/test/fixtures/yahoo_invalid_key +0 -2
- data/test/fixtures/yahoo_madison_square_garden +0 -52
- data/test/fixtures/yahoo_no_results +0 -10
- data/test/fixtures/yahoo_over_limit +0 -2
- data/test/fixtures/yandex_invalid_key +0 -1
- data/test/fixtures/yandex_kremlin +0 -48
- data/test/fixtures/yandex_no_city_and_town +0 -112
- data/test/fixtures/yandex_no_results +0 -16
- data/test/geocoder_test.rb +0 -59
- data/test/https_test.rb +0 -16
- data/test/integration/smoke_test.rb +0 -26
- data/test/lookup_test.rb +0 -117
- data/test/method_aliases_test.rb +0 -25
- data/test/mongoid_test.rb +0 -46
- data/test/mongoid_test_helper.rb +0 -43
- data/test/near_test.rb +0 -61
- data/test/oauth_util_test.rb +0 -30
- data/test/proxy_test.rb +0 -36
- data/test/query_test.rb +0 -52
- data/test/request_test.rb +0 -29
- data/test/result_test.rb +0 -42
- data/test/services_test.rb +0 -393
- data/test/test_helper.rb +0 -289
- data/test/test_mode_test.rb +0 -59
|
@@ -10,12 +10,6 @@ module Geocoder
|
|
|
10
10
|
#
|
|
11
11
|
COMPASS_POINTS = %w[N NE E SE S SW W NW]
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
# Radius of the Earth, in kilometers.
|
|
15
|
-
# Value taken from: http://en.wikipedia.org/wiki/Earth_radius
|
|
16
|
-
#
|
|
17
|
-
EARTH_RADIUS = 6371.0
|
|
18
|
-
|
|
19
13
|
##
|
|
20
14
|
# Conversion factor: multiply by kilometers to get miles.
|
|
21
15
|
#
|
|
@@ -26,6 +20,21 @@ module Geocoder
|
|
|
26
20
|
#
|
|
27
21
|
KM_IN_NM = 0.539957
|
|
28
22
|
|
|
23
|
+
##
|
|
24
|
+
# Conversion factor: multiply by radians to get degrees.
|
|
25
|
+
#
|
|
26
|
+
DEGREES_PER_RADIAN = 57.2957795
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Radius of the Earth, in kilometers.
|
|
30
|
+
# Value taken from: http://en.wikipedia.org/wiki/Earth_radius
|
|
31
|
+
#
|
|
32
|
+
EARTH_RADII = {km: 6371.0}
|
|
33
|
+
EARTH_RADII[:mi] = EARTH_RADII[:km] * KM_IN_MI
|
|
34
|
+
EARTH_RADII[:nm] = EARTH_RADII[:km] * KM_IN_NM
|
|
35
|
+
|
|
36
|
+
EARTH_RADIUS = EARTH_RADII[:km] # TODO: deprecate this constant (use `EARTH_RADII[:km]`)
|
|
37
|
+
|
|
29
38
|
# Not a number constant
|
|
30
39
|
NAN = defined?(::Float::NAN) ? ::Float::NAN : 0 / 0.0
|
|
31
40
|
|
|
@@ -45,7 +54,6 @@ module Geocoder
|
|
|
45
54
|
# Distance spanned by one degree of latitude in the given units.
|
|
46
55
|
#
|
|
47
56
|
def latitude_degree_distance(units = nil)
|
|
48
|
-
units ||= Geocoder.config.units
|
|
49
57
|
2 * Math::PI * earth_radius(units) / 360
|
|
50
58
|
end
|
|
51
59
|
|
|
@@ -54,7 +62,6 @@ module Geocoder
|
|
|
54
62
|
# This ranges from around 69 miles at the equator to zero at the poles.
|
|
55
63
|
#
|
|
56
64
|
def longitude_degree_distance(latitude, units = nil)
|
|
57
|
-
units ||= Geocoder.config.units
|
|
58
65
|
latitude_degree_distance(units) * Math.cos(to_radians(latitude))
|
|
59
66
|
end
|
|
60
67
|
|
|
@@ -75,10 +82,6 @@ module Geocoder
|
|
|
75
82
|
# Use Geocoder.configure(:units => ...) to configure default units.
|
|
76
83
|
#
|
|
77
84
|
def distance_between(point1, point2, options = {})
|
|
78
|
-
|
|
79
|
-
# set default options
|
|
80
|
-
options[:units] ||= Geocoder.config.units
|
|
81
|
-
|
|
82
85
|
# convert to coordinate arrays
|
|
83
86
|
point1 = extract_coordinates(point1)
|
|
84
87
|
point2 = extract_coordinates(point2)
|
|
@@ -151,7 +154,7 @@ module Geocoder
|
|
|
151
154
|
# Translate a bearing (float) into a compass direction (string, eg "North").
|
|
152
155
|
#
|
|
153
156
|
def compass_point(bearing, points = COMPASS_POINTS)
|
|
154
|
-
seg_size = 360 / points.size
|
|
157
|
+
seg_size = 360.0 / points.size
|
|
155
158
|
points[((bearing + (seg_size / 2)) % 360) / seg_size]
|
|
156
159
|
end
|
|
157
160
|
|
|
@@ -207,12 +210,11 @@ module Geocoder
|
|
|
207
210
|
def bounding_box(point, radius, options = {})
|
|
208
211
|
lat,lon = extract_coordinates(point)
|
|
209
212
|
radius = radius.to_f
|
|
210
|
-
units = options[:units] || Geocoder.config.units
|
|
211
213
|
[
|
|
212
|
-
lat - (radius / latitude_degree_distance(units)),
|
|
213
|
-
lon - (radius / longitude_degree_distance(lat, units)),
|
|
214
|
-
lat + (radius / latitude_degree_distance(units)),
|
|
215
|
-
lon + (radius / longitude_degree_distance(lat, units))
|
|
214
|
+
lat - (radius / latitude_degree_distance(options[:units])),
|
|
215
|
+
lon - (radius / longitude_degree_distance(lat, options[:units])),
|
|
216
|
+
lat + (radius / latitude_degree_distance(options[:units])),
|
|
217
|
+
lon + (radius / longitude_degree_distance(lat, options[:units]))
|
|
216
218
|
]
|
|
217
219
|
end
|
|
218
220
|
|
|
@@ -232,10 +234,9 @@ module Geocoder
|
|
|
232
234
|
#
|
|
233
235
|
# * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>
|
|
234
236
|
# Use Geocoder.configure(:units => ...) to configure default units.
|
|
237
|
+
# * <tt>:seed</tt> - The seed for the random number generator
|
|
235
238
|
def random_point_near(center, radius, options = {})
|
|
236
|
-
|
|
237
|
-
# set default options
|
|
238
|
-
options[:units] ||= Geocoder.config.units
|
|
239
|
+
random = Random.new(options[:seed] || Random.new_seed)
|
|
239
240
|
|
|
240
241
|
# convert to coordinate arrays
|
|
241
242
|
center = extract_coordinates(center)
|
|
@@ -244,16 +245,49 @@ module Geocoder
|
|
|
244
245
|
max_degree_delta = 360.0 * (radius / earth_circumference)
|
|
245
246
|
|
|
246
247
|
# random bearing in radians
|
|
247
|
-
theta = 2 * Math::PI * rand
|
|
248
|
+
theta = 2 * Math::PI * random.rand
|
|
248
249
|
|
|
249
250
|
# random radius, use the square root to ensure a uniform
|
|
250
251
|
# distribution of points over the circle
|
|
251
|
-
r = Math.sqrt(rand) * max_degree_delta
|
|
252
|
+
r = Math.sqrt(random.rand) * max_degree_delta
|
|
252
253
|
|
|
253
254
|
delta_lat, delta_long = [r * Math.cos(theta), r * Math.sin(theta)]
|
|
254
255
|
[center[0] + delta_lat, center[1] + delta_long]
|
|
255
256
|
end
|
|
256
257
|
|
|
258
|
+
##
|
|
259
|
+
# Given a start point, heading (in degrees), and distance, provides
|
|
260
|
+
# an endpoint.
|
|
261
|
+
# The starting point is given in the same way that points are given to all
|
|
262
|
+
# Geocoder methods that accept points as arguments. It can be:
|
|
263
|
+
#
|
|
264
|
+
# * an array of coordinates ([lat,lon])
|
|
265
|
+
# * a geocodable address (string)
|
|
266
|
+
# * a geocoded object (one which implements a +to_coordinates+ method
|
|
267
|
+
# which returns a [lat,lon] array
|
|
268
|
+
#
|
|
269
|
+
def endpoint(start, heading, distance, options = {})
|
|
270
|
+
radius = earth_radius(options[:units])
|
|
271
|
+
|
|
272
|
+
start = extract_coordinates(start)
|
|
273
|
+
|
|
274
|
+
# convert degrees to radians
|
|
275
|
+
start = to_radians(start)
|
|
276
|
+
|
|
277
|
+
lat = start[0]
|
|
278
|
+
lon = start[1]
|
|
279
|
+
heading = to_radians(heading)
|
|
280
|
+
distance = distance.to_f
|
|
281
|
+
|
|
282
|
+
end_lat = Math.asin(Math.sin(lat)*Math.cos(distance/radius) +
|
|
283
|
+
Math.cos(lat)*Math.sin(distance/radius)*Math.cos(heading))
|
|
284
|
+
|
|
285
|
+
end_lon = lon+Math.atan2(Math.sin(heading)*Math.sin(distance/radius)*Math.cos(lat),
|
|
286
|
+
Math.cos(distance/radius)-Math.sin(lat)*Math.sin(end_lat))
|
|
287
|
+
|
|
288
|
+
to_degrees [end_lat, end_lon]
|
|
289
|
+
end
|
|
290
|
+
|
|
257
291
|
##
|
|
258
292
|
# Convert degrees to radians.
|
|
259
293
|
# If an array (or multiple arguments) is passed,
|
|
@@ -283,12 +317,10 @@ module Geocoder
|
|
|
283
317
|
end
|
|
284
318
|
|
|
285
319
|
def distance_to_radians(distance, units = nil)
|
|
286
|
-
units ||= Geocoder.config.units
|
|
287
320
|
distance.to_f / earth_radius(units)
|
|
288
321
|
end
|
|
289
322
|
|
|
290
323
|
def radians_to_distance(radians, units = nil)
|
|
291
|
-
units ||= Geocoder.config.units
|
|
292
324
|
radians * earth_radius(units)
|
|
293
325
|
end
|
|
294
326
|
|
|
@@ -296,6 +328,7 @@ module Geocoder
|
|
|
296
328
|
# Convert miles to kilometers.
|
|
297
329
|
#
|
|
298
330
|
def to_kilometers(mi)
|
|
331
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.to_kilometers is deprecated and will be removed in Geocoder 1.5.0. Please multiply by MI_IN_KM instead.")
|
|
299
332
|
mi * mi_in_km
|
|
300
333
|
end
|
|
301
334
|
|
|
@@ -303,14 +336,16 @@ module Geocoder
|
|
|
303
336
|
# Convert kilometers to miles.
|
|
304
337
|
#
|
|
305
338
|
def to_miles(km)
|
|
306
|
-
|
|
339
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.to_miles is deprecated and will be removed in Geocoder 1.5.0. Please multiply by KM_IN_MI instead.")
|
|
340
|
+
km * KM_IN_MI
|
|
307
341
|
end
|
|
308
342
|
|
|
309
343
|
##
|
|
310
344
|
# Convert kilometers to nautical miles.
|
|
311
345
|
#
|
|
312
346
|
def to_nautical_miles(km)
|
|
313
|
-
|
|
347
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.to_nautical_miles is deprecated and will be removed in Geocoder 1.5.0. Please multiply by KM_IN_NM instead.")
|
|
348
|
+
km * KM_IN_NM
|
|
314
349
|
end
|
|
315
350
|
|
|
316
351
|
##
|
|
@@ -318,18 +353,14 @@ module Geocoder
|
|
|
318
353
|
# Use Geocoder.configure(:units => ...) to configure default units.
|
|
319
354
|
#
|
|
320
355
|
def earth_radius(units = nil)
|
|
321
|
-
units
|
|
322
|
-
case units
|
|
323
|
-
when :km; EARTH_RADIUS
|
|
324
|
-
when :mi; to_miles(EARTH_RADIUS)
|
|
325
|
-
when :nm; to_nautical_miles(EARTH_RADIUS)
|
|
326
|
-
end
|
|
356
|
+
EARTH_RADII[units || Geocoder.config.units]
|
|
327
357
|
end
|
|
328
358
|
|
|
329
359
|
##
|
|
330
360
|
# Conversion factor: km to mi.
|
|
331
361
|
#
|
|
332
362
|
def km_in_mi
|
|
363
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.km_in_mi is deprecated and will be removed in Geocoder 1.5.0. Please use the constant KM_IN_MI instead.")
|
|
333
364
|
KM_IN_MI
|
|
334
365
|
end
|
|
335
366
|
|
|
@@ -337,15 +368,15 @@ module Geocoder
|
|
|
337
368
|
# Conversion factor: km to nm.
|
|
338
369
|
#
|
|
339
370
|
def km_in_nm
|
|
371
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.km_in_nm is deprecated and will be removed in Geocoder 1.5.0. Please use the constant KM_IN_NM instead.")
|
|
340
372
|
KM_IN_NM
|
|
341
373
|
end
|
|
342
374
|
|
|
343
|
-
|
|
344
|
-
|
|
345
375
|
##
|
|
346
376
|
# Conversion factor: mi to km.
|
|
347
377
|
#
|
|
348
378
|
def mi_in_km
|
|
379
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.mi_in_km is deprecated and will be removed in Geocoder 1.5.0. Please use 1.0 / KM_IN_MI instead.")
|
|
349
380
|
1.0 / KM_IN_MI
|
|
350
381
|
end
|
|
351
382
|
|
|
@@ -353,6 +384,7 @@ module Geocoder
|
|
|
353
384
|
# Conversion factor: nm to km.
|
|
354
385
|
#
|
|
355
386
|
def nm_in_km
|
|
387
|
+
Geocoder.log(:warn, "DEPRECATION WARNING: Geocoder::Calculations.nm_in_km is deprecated and will be removed in Geocoder 1.5.0. Please use 1.0 / KM_IN_NM instead.")
|
|
356
388
|
1.0 / KM_IN_NM
|
|
357
389
|
end
|
|
358
390
|
|
|
@@ -386,4 +418,3 @@ module Geocoder
|
|
|
386
418
|
end
|
|
387
419
|
end
|
|
388
420
|
end
|
|
389
|
-
|
data/lib/geocoder/cli.rb
CHANGED
|
@@ -97,7 +97,7 @@ module Geocoder
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
if (result = Geocoder.search(query).first)
|
|
100
|
-
|
|
100
|
+
nominatim = Geocoder::Lookup.get(:nominatim)
|
|
101
101
|
lines = [
|
|
102
102
|
["Latitude", result.latitude],
|
|
103
103
|
["Longitude", result.longitude],
|
|
@@ -106,7 +106,7 @@ module Geocoder
|
|
|
106
106
|
["State/province", result.state],
|
|
107
107
|
["Postal code", result.postal_code],
|
|
108
108
|
["Country", result.country],
|
|
109
|
-
["
|
|
109
|
+
["Map", nominatim.map_link_url(result.coordinates)],
|
|
110
110
|
]
|
|
111
111
|
lines.each do |line|
|
|
112
112
|
out << (line[0] + ": ").ljust(18) + line[1].to_s + "\n"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'singleton'
|
|
2
2
|
require 'geocoder/configuration_hash'
|
|
3
|
+
require 'geocoder/util'
|
|
3
4
|
|
|
4
5
|
module Geocoder
|
|
5
6
|
|
|
@@ -14,14 +15,8 @@ module Geocoder
|
|
|
14
15
|
# )
|
|
15
16
|
#
|
|
16
17
|
def self.configure(options = nil, &block)
|
|
17
|
-
if
|
|
18
|
-
warn "WARNING: Passing a block to Geocoder.configure is DEPRECATED. Please pass a hash instead (eg: Geocoder.configure(:units => ..., :api_key => ...))."
|
|
19
|
-
block.call(Configuration.instance)
|
|
20
|
-
elsif !options.nil?
|
|
18
|
+
if !options.nil?
|
|
21
19
|
Configuration.instance.configure(options)
|
|
22
|
-
else
|
|
23
|
-
warn "WARNING: Use of Geocoder.configure to read or write single config options is DEPRECATED. To write to the config please pass a hash (eg: Geocoder.configure(:units => ...)). To read config options please use the Geocoder.config object (eg: Geocoder.config.units)."
|
|
24
|
-
Configuration.instance
|
|
25
20
|
end
|
|
26
21
|
end
|
|
27
22
|
|
|
@@ -44,6 +39,14 @@ module Geocoder
|
|
|
44
39
|
data
|
|
45
40
|
end
|
|
46
41
|
|
|
42
|
+
##
|
|
43
|
+
# Merge the given hash into a lookup's existing configuration.
|
|
44
|
+
#
|
|
45
|
+
def self.merge_into_lookup_config(lookup_name, options)
|
|
46
|
+
base = Geocoder.config[lookup_name]
|
|
47
|
+
Geocoder.configure(lookup_name => base.merge(options))
|
|
48
|
+
end
|
|
49
|
+
|
|
47
50
|
class Configuration
|
|
48
51
|
include Singleton
|
|
49
52
|
|
|
@@ -52,16 +55,20 @@ module Geocoder
|
|
|
52
55
|
:lookup,
|
|
53
56
|
:ip_lookup,
|
|
54
57
|
:language,
|
|
58
|
+
:host,
|
|
55
59
|
:http_headers,
|
|
56
60
|
:use_https,
|
|
57
61
|
:http_proxy,
|
|
58
62
|
:https_proxy,
|
|
59
63
|
:api_key,
|
|
60
64
|
:cache,
|
|
61
|
-
:cache_prefix,
|
|
62
65
|
:always_raise,
|
|
63
66
|
:units,
|
|
64
|
-
:distances
|
|
67
|
+
:distances,
|
|
68
|
+
:basic_auth,
|
|
69
|
+
:logger,
|
|
70
|
+
:kernel_logger_level,
|
|
71
|
+
:cache_options
|
|
65
72
|
]
|
|
66
73
|
|
|
67
74
|
attr_accessor :data
|
|
@@ -80,7 +87,7 @@ module Geocoder
|
|
|
80
87
|
end
|
|
81
88
|
|
|
82
89
|
def configure(options)
|
|
83
|
-
@data
|
|
90
|
+
Util.recursive_hash_merge(@data, options)
|
|
84
91
|
end
|
|
85
92
|
|
|
86
93
|
def initialize # :nodoc
|
|
@@ -92,25 +99,36 @@ module Geocoder
|
|
|
92
99
|
|
|
93
100
|
# geocoding options
|
|
94
101
|
@data[:timeout] = 3 # geocoding service timeout (secs)
|
|
95
|
-
@data[:lookup] = :
|
|
96
|
-
@data[:ip_lookup] = :
|
|
102
|
+
@data[:lookup] = :nominatim # name of street address geocoding service (symbol)
|
|
103
|
+
@data[:ip_lookup] = :ipinfo_io # name of IP address geocoding service (symbol)
|
|
97
104
|
@data[:language] = :en # ISO-639 language code
|
|
98
105
|
@data[:http_headers] = {} # HTTP headers for lookup
|
|
99
106
|
@data[:use_https] = false # use HTTPS for lookup requests? (if supported)
|
|
100
107
|
@data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
|
|
101
108
|
@data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
|
|
102
109
|
@data[:api_key] = nil # API key for geocoding service
|
|
103
|
-
@data[:
|
|
104
|
-
@data[:
|
|
110
|
+
@data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
|
|
111
|
+
@data[:logger] = :kernel # :kernel or Logger instance
|
|
112
|
+
@data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
|
|
105
113
|
|
|
106
114
|
# exceptions that should not be rescued by default
|
|
107
115
|
# (if you want to implement custom error handling);
|
|
108
|
-
# supports SocketError and
|
|
116
|
+
# supports SocketError and Timeout::Error
|
|
109
117
|
@data[:always_raise] = []
|
|
110
118
|
|
|
111
119
|
# calculation options
|
|
112
120
|
@data[:units] = :mi # :mi or :km
|
|
113
121
|
@data[:distances] = :linear # :linear or :spherical
|
|
122
|
+
|
|
123
|
+
# Set the default values for the caching mechanism
|
|
124
|
+
# By default, the cache keys will not expire as IP addresses and phyiscal
|
|
125
|
+
# addresses will rarely change.
|
|
126
|
+
@data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
|
|
127
|
+
@data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
|
|
128
|
+
@data[:cache_options] = {
|
|
129
|
+
prefix: 'geocoder:',
|
|
130
|
+
expiration: nil
|
|
131
|
+
}
|
|
114
132
|
end
|
|
115
133
|
|
|
116
134
|
instance_eval(OPTIONS.map do |option|
|
|
@@ -125,6 +143,5 @@ module Geocoder
|
|
|
125
143
|
end
|
|
126
144
|
EOS
|
|
127
145
|
end.join("\n\n"))
|
|
128
|
-
|
|
129
146
|
end
|
|
130
147
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
require 'hash_recursive_merge'
|
|
2
|
-
|
|
3
1
|
module Geocoder
|
|
4
2
|
class ConfigurationHash < Hash
|
|
5
|
-
include HashRecursiveMerge
|
|
6
|
-
|
|
7
3
|
def method_missing(meth, *args, &block)
|
|
8
4
|
has_key?(meth) ? self[meth] : super
|
|
9
5
|
end
|
|
6
|
+
|
|
7
|
+
def respond_to_missing?(meth, include_private = false)
|
|
8
|
+
has_key?(meth) || super
|
|
9
|
+
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class EsriToken
|
|
3
|
+
attr_accessor :value, :expires_at
|
|
4
|
+
|
|
5
|
+
def initialize(value, expires_at)
|
|
6
|
+
@value = value
|
|
7
|
+
@expires_at = expires_at
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_s
|
|
11
|
+
@value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def active?
|
|
15
|
+
@expires_at > Time.now
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.generate_token(client_id, client_secret, expires=1440)
|
|
19
|
+
# creates a new token that will expire in 1 day by default
|
|
20
|
+
getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
|
|
21
|
+
f: 'json',
|
|
22
|
+
client_id: client_id,
|
|
23
|
+
client_secret: client_secret,
|
|
24
|
+
grant_type: 'client_credentials',
|
|
25
|
+
expiration: expires # (minutes) max: 20160, default: 1 day
|
|
26
|
+
|
|
27
|
+
response = JSON.parse(getToken.body)
|
|
28
|
+
|
|
29
|
+
if response['error']
|
|
30
|
+
Geocoder.log(:warn, response['error'])
|
|
31
|
+
else
|
|
32
|
+
token_value = response['access_token']
|
|
33
|
+
expires_at = Time.now + (expires * 60)
|
|
34
|
+
new(token_value, expires_at)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/geocoder/exceptions.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
|
|
1
3
|
module Geocoder
|
|
2
4
|
|
|
3
5
|
class Error < StandardError
|
|
@@ -9,6 +11,14 @@ module Geocoder
|
|
|
9
11
|
class OverQueryLimitError < Error
|
|
10
12
|
end
|
|
11
13
|
|
|
14
|
+
class ResponseParseError < Error
|
|
15
|
+
attr_reader :response
|
|
16
|
+
|
|
17
|
+
def initialize(response)
|
|
18
|
+
@response = response
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
12
22
|
class RequestDenied < Error
|
|
13
23
|
end
|
|
14
24
|
|
|
@@ -18,4 +28,13 @@ module Geocoder
|
|
|
18
28
|
class InvalidApiKey < Error
|
|
19
29
|
end
|
|
20
30
|
|
|
31
|
+
class ServiceUnavailable < Error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class LookupTimeout < ::Timeout::Error
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class NetworkError < Error
|
|
38
|
+
end
|
|
39
|
+
|
|
21
40
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'resolv'
|
|
2
|
+
module Geocoder
|
|
3
|
+
class IpAddress < String
|
|
4
|
+
PRIVATE_IPS = [
|
|
5
|
+
'10.0.0.0/8',
|
|
6
|
+
'172.16.0.0/12',
|
|
7
|
+
'192.168.0.0/16',
|
|
8
|
+
].map { |ip| IPAddr.new(ip) }.freeze
|
|
9
|
+
|
|
10
|
+
def initialize(ip)
|
|
11
|
+
ip = ip.to_string if ip.is_a?(IPAddr)
|
|
12
|
+
|
|
13
|
+
super(ip)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def internal?
|
|
17
|
+
loopback? || private?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def loopback?
|
|
21
|
+
valid? and !!(self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def private?
|
|
25
|
+
valid? && PRIVATE_IPS.any? { |ip| ip.include?(self) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def valid?
|
|
29
|
+
ip = self[/(?<=\[)(.*?)(?=\])/] || self
|
|
30
|
+
!!((ip =~ Resolv::IPv4::Regex) || (ip =~ Resolv::IPv6::Regex))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class KernelLogger
|
|
3
|
+
include Singleton
|
|
4
|
+
|
|
5
|
+
def add(level, message)
|
|
6
|
+
return unless log_message_at_level?(level)
|
|
7
|
+
case level
|
|
8
|
+
when ::Logger::DEBUG, ::Logger::INFO
|
|
9
|
+
puts message
|
|
10
|
+
when ::Logger::WARN
|
|
11
|
+
warn message
|
|
12
|
+
when ::Logger::ERROR
|
|
13
|
+
raise message
|
|
14
|
+
when ::Logger::FATAL
|
|
15
|
+
fail message
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def log_message_at_level?(level)
|
|
22
|
+
level >= Geocoder.config.kernel_logger_level
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
|
|
5
|
+
def self.log(level, message)
|
|
6
|
+
Logger.instance.log(level, message)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Logger
|
|
10
|
+
include Singleton
|
|
11
|
+
|
|
12
|
+
SEVERITY = {
|
|
13
|
+
debug: ::Logger::DEBUG,
|
|
14
|
+
info: ::Logger::INFO,
|
|
15
|
+
warn: ::Logger::WARN,
|
|
16
|
+
error: ::Logger::ERROR,
|
|
17
|
+
fatal: ::Logger::FATAL
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def log(level, message)
|
|
21
|
+
unless valid_level?(level)
|
|
22
|
+
raise StandardError, "Geocoder tried to log a message with an invalid log level."
|
|
23
|
+
end
|
|
24
|
+
if current_logger.respond_to? :add
|
|
25
|
+
current_logger.add(SEVERITY[level], message)
|
|
26
|
+
else
|
|
27
|
+
raise Geocoder::ConfigurationError, "Please specify valid logger for Geocoder. " +
|
|
28
|
+
"Logger specified must be :kernel or must respond to `add(level, message)`."
|
|
29
|
+
end
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private # ----------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
def current_logger
|
|
36
|
+
logger = Geocoder.config[:logger]
|
|
37
|
+
if logger == :kernel
|
|
38
|
+
logger = Geocoder::KernelLogger.instance
|
|
39
|
+
end
|
|
40
|
+
logger
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def valid_level?(level)
|
|
44
|
+
SEVERITY.keys.include?(level)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/geocoder/lookup.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "geocoder/lookups/test"
|
|
2
|
+
|
|
1
3
|
module Geocoder
|
|
2
4
|
module Lookup
|
|
3
5
|
extend self
|
|
@@ -16,25 +18,55 @@ module Geocoder
|
|
|
16
18
|
all_services - [:test]
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
##
|
|
22
|
+
# Array of valid Lookup service names, excluding any that do not build their own HTTP requests.
|
|
23
|
+
# For example, Amazon Location Service uses the AWS gem, not HTTP REST requests, to fetch data.
|
|
24
|
+
#
|
|
25
|
+
def all_services_with_http_requests
|
|
26
|
+
all_services_except_test - [:amazon_location_service]
|
|
27
|
+
end
|
|
28
|
+
|
|
19
29
|
##
|
|
20
30
|
# All street address lookup services, default first.
|
|
21
31
|
#
|
|
22
32
|
def street_services
|
|
23
|
-
[
|
|
33
|
+
@street_services ||= [
|
|
34
|
+
:location_iq,
|
|
24
35
|
:dstk,
|
|
25
36
|
:esri,
|
|
26
37
|
:google,
|
|
27
38
|
:google_premier,
|
|
28
|
-
:
|
|
39
|
+
:google_places_details,
|
|
40
|
+
:google_places_search,
|
|
29
41
|
:bing,
|
|
30
42
|
:geocoder_ca,
|
|
31
|
-
:geocoder_us,
|
|
32
43
|
:yandex,
|
|
44
|
+
:nationaal_georegister_nl,
|
|
33
45
|
:nominatim,
|
|
46
|
+
:mapbox,
|
|
34
47
|
:mapquest,
|
|
35
|
-
:
|
|
48
|
+
:uk_ordnance_survey_names,
|
|
49
|
+
:opencagedata,
|
|
50
|
+
:pelias,
|
|
51
|
+
:pickpoint,
|
|
52
|
+
:here,
|
|
36
53
|
:baidu,
|
|
37
|
-
:
|
|
54
|
+
:tencent,
|
|
55
|
+
:geocodio,
|
|
56
|
+
:smarty_streets,
|
|
57
|
+
:postcode_anywhere_uk,
|
|
58
|
+
:postcodes_io,
|
|
59
|
+
:geoportail_lu,
|
|
60
|
+
:ban_data_gouv_fr,
|
|
61
|
+
:test,
|
|
62
|
+
:latlon,
|
|
63
|
+
:amap,
|
|
64
|
+
:osmnames,
|
|
65
|
+
:melissa_street,
|
|
66
|
+
:amazon_location_service,
|
|
67
|
+
:geoapify,
|
|
68
|
+
:photon,
|
|
69
|
+
:twogis
|
|
38
70
|
]
|
|
39
71
|
end
|
|
40
72
|
|
|
@@ -42,9 +74,30 @@ module Geocoder
|
|
|
42
74
|
# All IP address lookup services, default first.
|
|
43
75
|
#
|
|
44
76
|
def ip_services
|
|
45
|
-
[
|
|
77
|
+
@ip_services ||= [
|
|
78
|
+
:baidu_ip,
|
|
79
|
+
:abstract_api,
|
|
80
|
+
:freegeoip,
|
|
81
|
+
:geoip2,
|
|
82
|
+
:maxmind,
|
|
83
|
+
:maxmind_local,
|
|
84
|
+
:telize,
|
|
85
|
+
:pointpin,
|
|
86
|
+
:maxmind_geoip2,
|
|
87
|
+
:ipinfo_io,
|
|
88
|
+
:ipregistry,
|
|
89
|
+
:ipapi_com,
|
|
90
|
+
:ipdata_co,
|
|
91
|
+
:db_ip_com,
|
|
92
|
+
:ipstack,
|
|
93
|
+
:ip2location,
|
|
94
|
+
:ipgeolocation,
|
|
95
|
+
:ipqualityscore
|
|
96
|
+
]
|
|
46
97
|
end
|
|
47
98
|
|
|
99
|
+
attr_writer :street_services, :ip_services
|
|
100
|
+
|
|
48
101
|
##
|
|
49
102
|
# Retrieve a Lookup object from the store.
|
|
50
103
|
# Use this instead of Geocoder::Lookup::X.new to get an
|
|
@@ -64,7 +117,8 @@ module Geocoder
|
|
|
64
117
|
#
|
|
65
118
|
def spawn(name)
|
|
66
119
|
if all_services.include?(name)
|
|
67
|
-
|
|
120
|
+
name = name.to_s
|
|
121
|
+
instantiate_lookup(name)
|
|
68
122
|
else
|
|
69
123
|
valids = all_services.map(&:inspect).join(", ")
|
|
70
124
|
raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
|
|
@@ -78,9 +132,18 @@ module Geocoder
|
|
|
78
132
|
def classify_name(filename)
|
|
79
133
|
filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
|
|
80
134
|
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
135
|
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
##
|
|
137
|
+
# Safely instantiate Lookup
|
|
138
|
+
#
|
|
139
|
+
def instantiate_lookup(name)
|
|
140
|
+
class_name = "Geocoder::Lookup::#{classify_name(name)}"
|
|
141
|
+
begin
|
|
142
|
+
Geocoder::Lookup.const_get(class_name)
|
|
143
|
+
rescue NameError
|
|
144
|
+
require "geocoder/lookups/#{name}"
|
|
145
|
+
end
|
|
146
|
+
Geocoder::Lookup.const_get(class_name).new
|
|
147
|
+
end
|
|
148
|
+
end
|
|
86
149
|
end
|