geocoder 1.2.6 → 1.8.2
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 +266 -1
- data/LICENSE +1 -1
- data/README.md +530 -804
- 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 +2 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +1 -1
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +1 -1
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +20 -33
- 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 +30 -38
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +36 -9
- 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 +26 -11
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +63 -13
- 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 +55 -0
- data/lib/geocoder/lookups/baidu.rb +17 -9
- data/lib/geocoder/lookups/baidu_ip.rb +7 -31
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/lib/geocoder/lookups/base.rb +75 -26
- data/lib/geocoder/lookups/bing.rb +38 -15
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +78 -12
- data/lib/geocoder/lookups/freegeoip.rb +22 -7
- data/lib/geocoder/lookups/geoapify.rb +78 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +8 -8
- data/lib/geocoder/lookups/geoip2.rb +13 -4
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +44 -11
- data/lib/geocoder/lookups/google_places_details.rb +31 -17
- data/lib/geocoder/lookups/google_places_search.rb +76 -0
- data/lib/geocoder/lookups/google_premier.rb +15 -1
- data/lib/geocoder/lookups/here.rb +38 -27
- data/lib/geocoder/lookups/ip2location.rb +71 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipbase.rb +49 -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 +7 -9
- data/lib/geocoder/lookups/maxmind.rb +7 -7
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +16 -3
- 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 +18 -6
- data/lib/geocoder/lookups/opencagedata.rb +16 -9
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pc_miler.rb +85 -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 +14 -13
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +7 -8
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +29 -6
- data/lib/geocoder/lookups/telize.rb +42 -7
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +5 -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 +20 -13
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/models/mongo_base.rb +0 -2
- data/lib/geocoder/query.rb +15 -1
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/request.rb +103 -14
- 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/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 +15 -3
- data/lib/geocoder/results/geoip2.rb +37 -25
- 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 +4 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/here.rb +30 -15
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipbase.rb +40 -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 +0 -5
- 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 +20 -2
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pc_miler.rb +98 -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 +0 -4
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +55 -19
- data/lib/geocoder/results/telize.rb +0 -5
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +1 -1
- 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 +240 -32
- data/lib/geocoder/sql.rb +9 -6
- data/lib/geocoder/stores/active_record.rb +49 -10
- data/lib/geocoder/stores/base.rb +2 -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 +2 -1
- data/lib/maxmind_database.rb +9 -9
- data/lib/tasks/geocoder.rake +29 -4
- data/lib/tasks/maxmind.rake +1 -1
- metadata +91 -169
- data/.gitignore +0 -6
- data/.travis.yml +0 -31
- 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 -16
- data/lib/geocoder/lookups/geocoder_us.rb +0 -39
- data/lib/geocoder/lookups/okf.rb +0 -43
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/lookups/yahoo.rb +0 -88
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/okf.rb +0 -106
- 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/fixtures/baidu_invalid_key +0 -1
- data/test/fixtures/baidu_ip_202_198_16_3 +0 -19
- data/test/fixtures/baidu_ip_invalid_key +0 -1
- data/test/fixtures/baidu_ip_no_results +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/cloudmade_invalid_key +0 -1
- data/test/fixtures/cloudmade_madison_square_garden +0 -1
- data/test/fixtures/cloudmade_no_results +0 -1
- 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/geocodio_1101_pennsylvania_ave +0 -1
- data/test/fixtures/geocodio_bad_api_key +0 -3
- data/test/fixtures/geocodio_invalid +0 -4
- data/test/fixtures/geocodio_no_results +0 -1
- data/test/fixtures/geocodio_over_query_limit +0 -4
- 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/google_places_details_invalid_request +0 -4
- data/test/fixtures/google_places_details_madison_square_garden +0 -120
- data/test/fixtures/google_places_details_no_results +0 -4
- data/test/fixtures/google_places_details_no_reviews +0 -60
- data/test/fixtures/google_places_details_no_types +0 -66
- data/test/fixtures/here_madison_square_garden +0 -72
- data/test/fixtures/here_no_results +0 -8
- 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/nominatim_over_limit +0 -1
- data/test/fixtures/okf_kirstinmaki +0 -67
- data/test/fixtures/okf_no_results +0 -4
- data/test/fixtures/opencagedata_invalid_api_key +0 -25
- data/test/fixtures/opencagedata_invalid_request +0 -26
- data/test/fixtures/opencagedata_madison_square_garden +0 -73
- data/test/fixtures/opencagedata_no_results +0 -29
- data/test/fixtures/opencagedata_over_limit +0 -31
- data/test/fixtures/ovi_madison_square_garden +0 -72
- data/test/fixtures/ovi_no_results +0 -8
- data/test/fixtures/pointpin_10_10_10_10 +0 -1
- data/test/fixtures/pointpin_555_555_555_555 +0 -1
- data/test/fixtures/pointpin_80_111_555_555 +0 -1
- data/test/fixtures/pointpin_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +0 -1
- data/test/fixtures/smarty_streets_11211 +0 -1
- data/test/fixtures/smarty_streets_madison_square_garden +0 -47
- data/test/fixtures/smarty_streets_no_results +0 -1
- data/test/fixtures/telize_10_10_10_10 +0 -1
- data/test/fixtures/telize_555_555_555_555 +0 -4
- data/test/fixtures/telize_74_200_247_59 +0 -1
- data/test/fixtures/telize_no_results +0 -1
- 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_canada_rue_dupuis_14 +0 -446
- data/test/fixtures/yandex_invalid_key +0 -1
- data/test/fixtures/yandex_kremlin +0 -48
- data/test/fixtures/yandex_new_york +0 -1
- data/test/fixtures/yandex_no_city_and_town +0 -112
- data/test/fixtures/yandex_no_results +0 -16
- data/test/integration/http_client_test.rb +0 -31
- data/test/mongoid_test_helper.rb +0 -43
- data/test/test_helper.rb +0 -416
- data/test/unit/active_record_test.rb +0 -16
- data/test/unit/cache_test.rb +0 -37
- data/test/unit/calculations_test.rb +0 -220
- data/test/unit/configuration_test.rb +0 -55
- data/test/unit/error_handling_test.rb +0 -56
- data/test/unit/geocoder_test.rb +0 -78
- data/test/unit/https_test.rb +0 -17
- data/test/unit/ip_address_test.rb +0 -27
- data/test/unit/lookup_test.rb +0 -153
- data/test/unit/lookups/bing_test.rb +0 -68
- data/test/unit/lookups/dstk_test.rb +0 -26
- data/test/unit/lookups/esri_test.rb +0 -48
- data/test/unit/lookups/freegeoip_test.rb +0 -27
- data/test/unit/lookups/geocoder_ca_test.rb +0 -17
- data/test/unit/lookups/geocodio_test.rb +0 -55
- data/test/unit/lookups/geoip2_test.rb +0 -27
- data/test/unit/lookups/google_places_details_test.rb +0 -122
- data/test/unit/lookups/google_premier_test.rb +0 -22
- data/test/unit/lookups/google_test.rb +0 -84
- data/test/unit/lookups/mapquest_test.rb +0 -60
- data/test/unit/lookups/maxmind_local_test.rb +0 -28
- data/test/unit/lookups/maxmind_test.rb +0 -63
- data/test/unit/lookups/nominatim_test.rb +0 -31
- data/test/unit/lookups/okf_test.rb +0 -38
- data/test/unit/lookups/opencagedata_test.rb +0 -64
- data/test/unit/lookups/pointpin_test.rb +0 -30
- data/test/unit/lookups/postcode_anywhere_uk_test.rb +0 -70
- data/test/unit/lookups/smarty_streets_test.rb +0 -71
- data/test/unit/lookups/telize_test.rb +0 -36
- data/test/unit/lookups/yahoo_test.rb +0 -35
- data/test/unit/method_aliases_test.rb +0 -26
- data/test/unit/model_test.rb +0 -38
- data/test/unit/mongoid_test.rb +0 -47
- data/test/unit/near_test.rb +0 -87
- data/test/unit/oauth_util_test.rb +0 -31
- data/test/unit/proxy_test.rb +0 -37
- data/test/unit/query_test.rb +0 -52
- data/test/unit/rake_task_test.rb +0 -21
- data/test/unit/request_test.rb +0 -35
- data/test/unit/result_test.rb +0 -72
- data/test/unit/test_mode_test.rb +0 -70
|
@@ -28,6 +28,11 @@ module Geocoder::Store
|
|
|
28
28
|
"OR #{table_name}.#{geocoder_options[:longitude]} IS NULL")
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
# scope: not-reverse geocoded objects
|
|
32
|
+
scope :not_reverse_geocoded, lambda {
|
|
33
|
+
where("#{table_name}.#{geocoder_options[:fetched_address]} IS NULL")
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
##
|
|
32
37
|
# Find all objects within a radius of the given location.
|
|
33
38
|
# Location may be either a string to geocode or an array of
|
|
@@ -55,7 +60,7 @@ module Geocoder::Store
|
|
|
55
60
|
# corner followed by the northeast corner of the box
|
|
56
61
|
# (<tt>[[sw_lat, sw_lon], [ne_lat, ne_lon]]</tt>).
|
|
57
62
|
#
|
|
58
|
-
scope :within_bounding_box, lambda{
|
|
63
|
+
scope :within_bounding_box, lambda{ |*bounds|
|
|
59
64
|
sw_lat, sw_lng, ne_lat, ne_lng = bounds.flatten if bounds
|
|
60
65
|
if sw_lat && sw_lng && ne_lat && ne_lng
|
|
61
66
|
where(Geocoder::Sql.within_bounding_box(
|
|
@@ -82,8 +87,6 @@ module Geocoder::Store
|
|
|
82
87
|
end
|
|
83
88
|
end
|
|
84
89
|
|
|
85
|
-
private # ----------------------------------------------------------------
|
|
86
|
-
|
|
87
90
|
##
|
|
88
91
|
# Get options hash suitable for passing to ActiveRecord.find to get
|
|
89
92
|
# records within a radius (in kilometers) of the given point.
|
|
@@ -126,18 +129,31 @@ module Geocoder::Store
|
|
|
126
129
|
distance_column = options.fetch(:distance_column) { 'distance' }
|
|
127
130
|
bearing_column = options.fetch(:bearing_column) { 'bearing' }
|
|
128
131
|
|
|
129
|
-
|
|
132
|
+
# If radius is a DB column name, bounding box should include
|
|
133
|
+
# all rows within the maximum radius appearing in that column.
|
|
134
|
+
# Note: performance is dependent on variability of radii.
|
|
135
|
+
bb_radius = radius.is_a?(Symbol) ? maximum(radius) : radius
|
|
136
|
+
b = Geocoder::Calculations.bounding_box([latitude, longitude], bb_radius, options)
|
|
130
137
|
args = b + [
|
|
131
138
|
full_column_name(latitude_attribute),
|
|
132
139
|
full_column_name(longitude_attribute)
|
|
133
140
|
]
|
|
134
141
|
bounding_box_conditions = Geocoder::Sql.within_bounding_box(*args)
|
|
135
142
|
|
|
136
|
-
if
|
|
143
|
+
if using_unextended_sqlite?
|
|
137
144
|
conditions = bounding_box_conditions
|
|
138
145
|
else
|
|
139
146
|
min_radius = options.fetch(:min_radius, 0).to_f
|
|
140
|
-
|
|
147
|
+
# if radius is a DB column name,
|
|
148
|
+
# find rows between min_radius and value in column
|
|
149
|
+
if radius.is_a?(Symbol)
|
|
150
|
+
c = "BETWEEN ? AND #{radius}"
|
|
151
|
+
a = [min_radius]
|
|
152
|
+
else
|
|
153
|
+
c = "BETWEEN ? AND ?"
|
|
154
|
+
a = [min_radius, radius]
|
|
155
|
+
end
|
|
156
|
+
conditions = [bounding_box_conditions + " AND (#{distance}) " + c] + a
|
|
141
157
|
end
|
|
142
158
|
{
|
|
143
159
|
:select => select_clause(options[:select],
|
|
@@ -155,7 +171,7 @@ module Geocoder::Store
|
|
|
155
171
|
# capabilities (trig functions?).
|
|
156
172
|
#
|
|
157
173
|
def distance_sql(latitude, longitude, options = {})
|
|
158
|
-
method_prefix =
|
|
174
|
+
method_prefix = using_unextended_sqlite? ? "approx" : "full"
|
|
159
175
|
Geocoder::Sql.send(
|
|
160
176
|
method_prefix + "_distance",
|
|
161
177
|
latitude, longitude,
|
|
@@ -174,7 +190,7 @@ module Geocoder::Store
|
|
|
174
190
|
options[:bearing] = Geocoder.config.distances
|
|
175
191
|
end
|
|
176
192
|
if options[:bearing]
|
|
177
|
-
method_prefix =
|
|
193
|
+
method_prefix = using_unextended_sqlite? ? "approx" : "full"
|
|
178
194
|
Geocoder::Sql.send(
|
|
179
195
|
method_prefix + "_bearing",
|
|
180
196
|
latitude, longitude,
|
|
@@ -220,8 +236,20 @@ module Geocoder::Store
|
|
|
220
236
|
conditions
|
|
221
237
|
end
|
|
222
238
|
|
|
239
|
+
def using_unextended_sqlite?
|
|
240
|
+
using_sqlite? && !using_sqlite_with_extensions?
|
|
241
|
+
end
|
|
242
|
+
|
|
223
243
|
def using_sqlite?
|
|
224
|
-
connection.adapter_name.match(/sqlite/i)
|
|
244
|
+
!!connection.adapter_name.match(/sqlite/i)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def using_sqlite_with_extensions?
|
|
248
|
+
connection.adapter_name.match(/sqlite/i) &&
|
|
249
|
+
defined?(::SqliteExt) &&
|
|
250
|
+
%W(MOD POWER SQRT PI SIN COS ASIN ATAN2).all?{ |fn_name|
|
|
251
|
+
connection.raw_connection.function_created?(fn_name)
|
|
252
|
+
}
|
|
225
253
|
end
|
|
226
254
|
|
|
227
255
|
def using_postgres?
|
|
@@ -239,7 +267,7 @@ module Geocoder::Store
|
|
|
239
267
|
# Value which can be passed to where() to produce no results.
|
|
240
268
|
#
|
|
241
269
|
def false_condition
|
|
242
|
-
|
|
270
|
+
using_unextended_sqlite? ? 0 : "false"
|
|
243
271
|
end
|
|
244
272
|
|
|
245
273
|
##
|
|
@@ -251,6 +279,17 @@ module Geocoder::Store
|
|
|
251
279
|
end
|
|
252
280
|
end
|
|
253
281
|
|
|
282
|
+
##
|
|
283
|
+
# Get nearby geocoded objects.
|
|
284
|
+
# Takes the same options hash as the near class method (scope).
|
|
285
|
+
# Returns nil if the object is not geocoded.
|
|
286
|
+
#
|
|
287
|
+
def nearbys(radius = 20, options = {})
|
|
288
|
+
return nil unless geocoded?
|
|
289
|
+
options.merge!(:exclude => self) unless send(self.class.primary_key).nil?
|
|
290
|
+
self.class.near(self, radius, options)
|
|
291
|
+
end
|
|
292
|
+
|
|
254
293
|
##
|
|
255
294
|
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
|
|
256
295
|
# (or other as specified in +geocoded_by+). Returns coordinates (array).
|
data/lib/geocoder/stores/base.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Geocoder
|
|
|
6
6
|
# Is this object geocoded? (Does it have latitude and longitude?)
|
|
7
7
|
#
|
|
8
8
|
def geocoded?
|
|
9
|
-
to_coordinates.compact.size
|
|
9
|
+
to_coordinates.compact.size == 2
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
##
|
|
@@ -55,17 +55,6 @@ module Geocoder
|
|
|
55
55
|
point, to_coordinates, options)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
##
|
|
59
|
-
# Get nearby geocoded objects.
|
|
60
|
-
# Takes the same options hash as the near class method (scope).
|
|
61
|
-
# Returns nil if the object is not geocoded.
|
|
62
|
-
#
|
|
63
|
-
def nearbys(radius = 20, options = {})
|
|
64
|
-
return nil unless geocoded?
|
|
65
|
-
options.merge!(:exclude => self) unless send(self.class.primary_key).nil?
|
|
66
|
-
self.class.near(self, radius, options)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
58
|
##
|
|
70
59
|
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
|
|
71
60
|
# (or other as specified in +geocoded_by+). Returns coordinates (array).
|
|
@@ -101,7 +90,7 @@ module Geocoder
|
|
|
101
90
|
return
|
|
102
91
|
end
|
|
103
92
|
|
|
104
|
-
query_options = [:lookup, :ip_lookup, :language].inject({}) do |hash, key|
|
|
93
|
+
query_options = [:lookup, :ip_lookup, :language, :params].inject({}) do |hash, key|
|
|
105
94
|
if options.has_key?(key)
|
|
106
95
|
val = options[key]
|
|
107
96
|
hash[key] = val.respond_to?(:call) ? val.call(self) : val
|
|
@@ -124,4 +113,3 @@ module Geocoder
|
|
|
124
113
|
end
|
|
125
114
|
end
|
|
126
115
|
end
|
|
127
|
-
|
|
@@ -11,37 +11,6 @@ module Geocoder::Store
|
|
|
11
11
|
scope :not_geocoded, lambda {
|
|
12
12
|
where(geocoder_options[:coordinates] => nil)
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
scope :near, lambda{ |location, *args|
|
|
16
|
-
coords = Geocoder::Calculations.extract_coordinates(location)
|
|
17
|
-
|
|
18
|
-
# no results if no lat/lon given
|
|
19
|
-
return where(:id => false) unless coords.is_a?(Array)
|
|
20
|
-
|
|
21
|
-
radius = args.size > 0 ? args.shift : 20
|
|
22
|
-
options = args.size > 0 ? args.shift : {}
|
|
23
|
-
options[:units] ||= geocoder_options[:units]
|
|
24
|
-
|
|
25
|
-
# Use BSON::OrderedHash if Ruby's hashes are unordered.
|
|
26
|
-
# Conditions must be in order required by indexes (see mongo gem).
|
|
27
|
-
version = RUBY_VERSION.split('.').map { |i| i.to_i }
|
|
28
|
-
empty = version[0] < 2 && version[1] < 9 ? BSON::OrderedHash.new : {}
|
|
29
|
-
|
|
30
|
-
conds = empty.clone
|
|
31
|
-
field = geocoder_options[:coordinates]
|
|
32
|
-
conds[field] = empty.clone
|
|
33
|
-
conds[field]["$nearSphere"] = coords.reverse
|
|
34
|
-
|
|
35
|
-
if radius
|
|
36
|
-
conds[field]["$maxDistance"] = \
|
|
37
|
-
Geocoder::Calculations.distance_to_radians(radius, options[:units])
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
if obj = options[:exclude]
|
|
41
|
-
conds[:_id.ne] = obj.id
|
|
42
|
-
end
|
|
43
|
-
where(conds)
|
|
44
|
-
}
|
|
45
14
|
end
|
|
46
15
|
end
|
|
47
16
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
module Util
|
|
5
|
+
#
|
|
6
|
+
# Recursive version of Hash#merge!
|
|
7
|
+
#
|
|
8
|
+
# Adds the contents of +h2+ to +h1+,
|
|
9
|
+
# merging entries in +h1+ with duplicate keys with those from +h2+.
|
|
10
|
+
#
|
|
11
|
+
# Compared with Hash#merge!, this method supports nested hashes.
|
|
12
|
+
# When both +h1+ and +h2+ contains an entry with the same key,
|
|
13
|
+
# it merges and returns the values from both hashes.
|
|
14
|
+
#
|
|
15
|
+
# h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
|
|
16
|
+
# h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
|
|
17
|
+
# recursive_hash_merge(h1, h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
|
|
18
|
+
#
|
|
19
|
+
# Simply using Hash#merge! would return
|
|
20
|
+
#
|
|
21
|
+
# h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
|
|
22
|
+
#
|
|
23
|
+
def self.recursive_hash_merge(h1, h2)
|
|
24
|
+
h1.merge!(h2) do |_key, oldval, newval|
|
|
25
|
+
oldval.class == h1.class ? self.recursive_hash_merge(oldval, newval) : newval
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/geocoder/version.rb
CHANGED
data/lib/geocoder.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require "geocoder/configuration"
|
|
2
|
+
require "geocoder/logger"
|
|
3
|
+
require "geocoder/kernel_logger"
|
|
2
4
|
require "geocoder/query"
|
|
3
5
|
require "geocoder/calculations"
|
|
4
6
|
require "geocoder/exceptions"
|
|
@@ -43,5 +45,4 @@ end
|
|
|
43
45
|
# load Railtie if Rails exists
|
|
44
46
|
if defined?(Rails)
|
|
45
47
|
require "geocoder/railtie"
|
|
46
|
-
Geocoder::Railtie.insert
|
|
47
48
|
end
|
data/lib/maxmind_database.rb
CHANGED
|
@@ -6,9 +6,9 @@ module Geocoder
|
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
8
|
def download(package, dir = "tmp")
|
|
9
|
-
filepath = File.expand_path(File.join(dir,
|
|
9
|
+
filepath = File.expand_path(File.join(dir, "#{archive_edition(package)}.zip"))
|
|
10
10
|
open(filepath, 'wb') do |file|
|
|
11
|
-
uri = URI.parse(
|
|
11
|
+
uri = URI.parse(base_url(package))
|
|
12
12
|
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
13
13
|
http.request_get(uri.path) do |resp|
|
|
14
14
|
# TODO: show progress
|
|
@@ -21,7 +21,7 @@ module Geocoder
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def insert(package, dir = "tmp")
|
|
24
|
-
data_files(package).each do |filepath,table|
|
|
24
|
+
data_files(package, dir).each do |filepath,table|
|
|
25
25
|
print "Resetting table #{table}..."
|
|
26
26
|
ActiveRecord::Base.connection.execute("DELETE FROM #{table}")
|
|
27
27
|
puts "done"
|
|
@@ -94,16 +94,16 @@ module Geocoder
|
|
|
94
94
|
base_url + archive_url_path(package)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
def
|
|
97
|
+
def archive_edition(package)
|
|
98
98
|
{
|
|
99
|
-
geolite_country_csv: "
|
|
100
|
-
geolite_city_csv: "
|
|
101
|
-
geolite_asn_csv: "
|
|
99
|
+
geolite_country_csv: "GeoLite2-Country-CSV",
|
|
100
|
+
geolite_city_csv: "GeoLite2-City-CSV",
|
|
101
|
+
geolite_asn_csv: "GeoLite2-ASN-CSV"
|
|
102
102
|
}[package]
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
def base_url
|
|
106
|
-
"
|
|
105
|
+
def base_url(edition)
|
|
106
|
+
"https://download.maxmind.com/app/geoip_download?edition_id=#{edition}&license_key=#{ENV['LICENSE_KEY']}&suffix=zip"
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
end
|
data/lib/tasks/geocoder.rake
CHANGED
|
@@ -1,20 +1,45 @@
|
|
|
1
|
+
require "geocoder/models/mongoid"
|
|
2
|
+
|
|
1
3
|
namespace :geocode do
|
|
2
4
|
desc "Geocode all objects without coordinates."
|
|
3
5
|
task :all => :environment do
|
|
4
6
|
class_name = ENV['CLASS'] || ENV['class']
|
|
5
7
|
sleep_timer = ENV['SLEEP'] || ENV['sleep']
|
|
6
8
|
batch = ENV['BATCH'] || ENV['batch']
|
|
9
|
+
reverse = ENV['REVERSE'] || ENV['reverse']
|
|
10
|
+
limit = ENV['LIMIT'] || ENV['limit']
|
|
7
11
|
raise "Please specify a CLASS (model)" unless class_name
|
|
8
12
|
klass = class_from_string(class_name)
|
|
9
|
-
batch = batch.to_i unless batch.nil?
|
|
13
|
+
batch = (batch.to_i unless batch.nil?) || 1000
|
|
14
|
+
orm = (klass < Geocoder::Model::Mongoid) ? 'mongoid' : 'active_record'
|
|
15
|
+
reverse = false unless reverse.to_s.downcase == 'true'
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
obj.
|
|
17
|
+
geocode_record = lambda { |obj|
|
|
18
|
+
reverse ? obj.reverse_geocode : obj.geocode
|
|
19
|
+
obj.save
|
|
13
20
|
sleep(sleep_timer.to_f) unless sleep_timer.nil?
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
scope = reverse ? klass.not_reverse_geocoded : klass.not_geocoded
|
|
24
|
+
scope = scope.limit(limit) if limit
|
|
25
|
+
if orm == 'mongoid'
|
|
26
|
+
scope.each do |obj|
|
|
27
|
+
geocode_record.call(obj)
|
|
28
|
+
end
|
|
29
|
+
elsif orm == 'active_record'
|
|
30
|
+
if limit
|
|
31
|
+
scope.each do |obj|
|
|
32
|
+
geocode_record.call(obj)
|
|
33
|
+
end
|
|
34
|
+
else
|
|
35
|
+
scope.find_each(batch_size: batch) do |obj|
|
|
36
|
+
geocode_record.call(obj)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
14
39
|
end
|
|
40
|
+
|
|
15
41
|
end
|
|
16
42
|
end
|
|
17
|
-
|
|
18
43
|
##
|
|
19
44
|
# Get a class object from the string given in the shell environment.
|
|
20
45
|
# Similar to ActiveSupport's +constantize+ method.
|
data/lib/tasks/maxmind.rake
CHANGED
|
@@ -54,7 +54,7 @@ module MaxmindTask
|
|
|
54
54
|
end
|
|
55
55
|
require 'fileutils'
|
|
56
56
|
p = "geolite_#{package}_csv".intern
|
|
57
|
-
archive_filename = Geocoder::MaxmindDatabase.
|
|
57
|
+
archive_filename = "#{Geocoder::MaxmindDatabase.archive_edition(p)}.zip"
|
|
58
58
|
Zip::File.open(File.join(options[:dir], archive_filename)).each do |entry|
|
|
59
59
|
filepath = File.join(options[:dir], entry.name)
|
|
60
60
|
if File.exist? filepath
|