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
data/bin/console
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'geocoder'
|
|
5
|
+
|
|
6
|
+
if File.exist?("api_keys.yml")
|
|
7
|
+
require 'yaml'
|
|
8
|
+
@api_keys = YAML.load(File.read("api_keys.yml"), symbolize_names: true)
|
|
9
|
+
Geocoder.configure(@api_keys)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'irb'
|
|
13
|
+
IRB.start
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# To extend the Geocoder with additional lookups that come from the application,
|
|
2
|
+
# not shipped with the gem, define a "child" lookup in your application, based on existing one.
|
|
3
|
+
# This is required because the Geocoder::Configuration is a Singleton and stores one api key per lookup.
|
|
4
|
+
|
|
5
|
+
# in app/libs/geocoder/lookup/my_preciousss.rb
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class MyPreciousss < Google
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Update Geocoder's street_services on initialize:
|
|
12
|
+
# config/initializers/geocoder.rb
|
|
13
|
+
Geocoder::Lookup.street_services << :my_preciousss
|
|
14
|
+
|
|
15
|
+
# Override the configuration when necessary (e.g. provide separate Google API key for the account):
|
|
16
|
+
Geocoder.configure(my_preciousss: { api_key: 'abcdef' })
|
|
17
|
+
|
|
18
|
+
# Lastly, search using your custom lookup service/api keys
|
|
19
|
+
Geocoder.search("Paris", lookup: :my_preciousss)
|
|
20
|
+
|
|
21
|
+
# This is useful when we have groups of users in the application who use Google paid services
|
|
22
|
+
# and we want to properly separate them and allow using individual API KEYS or timeouts.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# This class implements an ActiveJob job for performing reverse-geocoding
|
|
2
|
+
# asynchronously. Example usage:
|
|
3
|
+
|
|
4
|
+
# if @location.save && @location.address.blank?
|
|
5
|
+
# ReverseGeocodeJob.perform_later(@location)
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
# Be sure to configure the queue adapter in config/application.rb:
|
|
9
|
+
# config.active_job.queue_adapter = :sidekiq
|
|
10
|
+
|
|
11
|
+
# You can read the Rails docs for more information on configuring ActiveJob:
|
|
12
|
+
# http://edgeguides.rubyonrails.org/active_job_basics.html
|
|
13
|
+
|
|
14
|
+
class ReverseGeocodeJob < ActiveJob::Base
|
|
15
|
+
queue_as :high
|
|
16
|
+
|
|
17
|
+
def perform(location)
|
|
18
|
+
address = address(location)
|
|
19
|
+
|
|
20
|
+
if address.present?
|
|
21
|
+
location.update(address: address)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def address(location)
|
|
28
|
+
Geocoder.address(location.coordinates)
|
|
29
|
+
rescue => exception
|
|
30
|
+
MonitoringService.notify(exception, location: { id: location.id })
|
|
31
|
+
|
|
32
|
+
if retryable?(exception)
|
|
33
|
+
raise exception
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def retryable?(exception)
|
|
38
|
+
exception.is_a?(Timeout::Error) || exception.is_a?(SocketError)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class EastingNorthing
|
|
3
|
+
attr_reader :easting, :northing, :lat_lng
|
|
4
|
+
|
|
5
|
+
def initialize(opts)
|
|
6
|
+
@easting = opts[:easting]
|
|
7
|
+
@northing = opts[:northing]
|
|
8
|
+
|
|
9
|
+
@lat_lng = to_WGS84(to_osgb_36)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def to_osgb_36
|
|
15
|
+
osgb_fo = 0.9996012717
|
|
16
|
+
northing0 = -100_000.0
|
|
17
|
+
easting0 = 400_000.0
|
|
18
|
+
phi0 = deg_to_rad(49.0)
|
|
19
|
+
lambda0 = deg_to_rad(-2.0)
|
|
20
|
+
a = 6_377_563.396
|
|
21
|
+
b = 6_356_256.909
|
|
22
|
+
eSquared = ((a * a) - (b * b)) / (a * a)
|
|
23
|
+
phi = 0.0
|
|
24
|
+
lambda = 0.0
|
|
25
|
+
n = (a - b) / (a + b)
|
|
26
|
+
m = 0.0
|
|
27
|
+
phiPrime = ((northing - northing0) / (a * osgb_fo)) + phi0
|
|
28
|
+
|
|
29
|
+
while (northing - northing0 - m) >= 0.001
|
|
30
|
+
m =
|
|
31
|
+
(b * osgb_fo)\
|
|
32
|
+
* (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))\
|
|
33
|
+
* (phiPrime - phi0))\
|
|
34
|
+
- (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))\
|
|
35
|
+
* Math.sin(phiPrime - phi0)\
|
|
36
|
+
* Math.cos(phiPrime + phi0))\
|
|
37
|
+
+ ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))\
|
|
38
|
+
* Math.sin(2.0 * (phiPrime - phi0))\
|
|
39
|
+
* Math.cos(2.0 * (phiPrime + phi0)))\
|
|
40
|
+
- (((35.0 / 24.0) * n * n * n)\
|
|
41
|
+
* Math.sin(3.0 * (phiPrime - phi0))\
|
|
42
|
+
* Math.cos(3.0 * (phiPrime + phi0))))
|
|
43
|
+
|
|
44
|
+
phiPrime += (northing - northing0 - m) / (a * osgb_fo)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
v = a * osgb_fo * ((1.0 - eSquared * sin_pow_2(phiPrime))**-0.5)
|
|
48
|
+
rho =
|
|
49
|
+
a\
|
|
50
|
+
* osgb_fo\
|
|
51
|
+
* (1.0 - eSquared)\
|
|
52
|
+
* ((1.0 - eSquared * sin_pow_2(phiPrime))**-1.5)
|
|
53
|
+
etaSquared = (v / rho) - 1.0
|
|
54
|
+
vii = Math.tan(phiPrime) / (2 * rho * v)
|
|
55
|
+
viii =
|
|
56
|
+
(Math.tan(phiPrime) / (24.0 * rho * (v**3.0)))\
|
|
57
|
+
* (5.0\
|
|
58
|
+
+ (3.0 * tan_pow_2(phiPrime))\
|
|
59
|
+
+ etaSquared\
|
|
60
|
+
- (9.0 * tan_pow_2(phiPrime) * etaSquared))
|
|
61
|
+
ix =
|
|
62
|
+
(Math.tan(phiPrime) / (720.0 * rho * (v**5.0)))\
|
|
63
|
+
* (61.0\
|
|
64
|
+
+ (90.0 * tan_pow_2(phiPrime))\
|
|
65
|
+
+ (45.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime)))
|
|
66
|
+
x = sec(phiPrime) / v
|
|
67
|
+
xi =
|
|
68
|
+
(sec(phiPrime) / (6.0 * v * v * v))\
|
|
69
|
+
* ((v / rho) + (2 * tan_pow_2(phiPrime)))
|
|
70
|
+
xiii =
|
|
71
|
+
(sec(phiPrime) / (120.0 * (v**5.0)))\
|
|
72
|
+
* (5.0\
|
|
73
|
+
+ (28.0 * tan_pow_2(phiPrime))\
|
|
74
|
+
+ (24.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime)))
|
|
75
|
+
xiia =
|
|
76
|
+
(sec(phiPrime) / (5040.0 * (v**7.0)))\
|
|
77
|
+
* (61.0\
|
|
78
|
+
+ (662.0 * tan_pow_2(phiPrime))\
|
|
79
|
+
+ (1320.0 * tan_pow_2(phiPrime) * tan_pow_2(phiPrime))\
|
|
80
|
+
+ (720.0\
|
|
81
|
+
* tan_pow_2(phiPrime)\
|
|
82
|
+
* tan_pow_2(phiPrime)\
|
|
83
|
+
* tan_pow_2(phiPrime)))
|
|
84
|
+
phi =
|
|
85
|
+
phiPrime\
|
|
86
|
+
- (vii * ((easting - easting0)**2.0))\
|
|
87
|
+
+ (viii * ((easting - easting0)**4.0))\
|
|
88
|
+
- (ix * ((easting - easting0)**6.0))
|
|
89
|
+
lambda =
|
|
90
|
+
lambda0\
|
|
91
|
+
+ (x * (easting - easting0))\
|
|
92
|
+
- (xi * ((easting - easting0)**3.0))\
|
|
93
|
+
+ (xiii * ((easting - easting0)**5.0))\
|
|
94
|
+
- (xiia * ((easting - easting0)**7.0))
|
|
95
|
+
|
|
96
|
+
[rad_to_deg(phi), rad_to_deg(lambda)]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def to_WGS84(latlng)
|
|
100
|
+
latitude = latlng[0]
|
|
101
|
+
longitude = latlng[1]
|
|
102
|
+
|
|
103
|
+
a = 6_377_563.396
|
|
104
|
+
b = 6_356_256.909
|
|
105
|
+
eSquared = ((a * a) - (b * b)) / (a * a)
|
|
106
|
+
|
|
107
|
+
phi = deg_to_rad(latitude)
|
|
108
|
+
lambda = deg_to_rad(longitude)
|
|
109
|
+
v = a / Math.sqrt(1 - eSquared * sin_pow_2(phi))
|
|
110
|
+
h = 0
|
|
111
|
+
x = (v + h) * Math.cos(phi) * Math.cos(lambda)
|
|
112
|
+
y = (v + h) * Math.cos(phi) * Math.sin(lambda)
|
|
113
|
+
z = ((1 - eSquared) * v + h) * Math.sin(phi)
|
|
114
|
+
|
|
115
|
+
tx = 446.448
|
|
116
|
+
ty = -124.157
|
|
117
|
+
tz = 542.060
|
|
118
|
+
|
|
119
|
+
s = -0.0000204894
|
|
120
|
+
rx = deg_to_rad(0.00004172222)
|
|
121
|
+
ry = deg_to_rad(0.00006861111)
|
|
122
|
+
rz = deg_to_rad(0.00023391666)
|
|
123
|
+
|
|
124
|
+
xB = tx + (x * (1 + s)) + (-rx * y) + (ry * z)
|
|
125
|
+
yB = ty + (rz * x) + (y * (1 + s)) + (-rx * z)
|
|
126
|
+
zB = tz + (-ry * x) + (rx * y) + (z * (1 + s))
|
|
127
|
+
|
|
128
|
+
a = 6_378_137.000
|
|
129
|
+
b = 6_356_752.3141
|
|
130
|
+
eSquared = ((a * a) - (b * b)) / (a * a)
|
|
131
|
+
|
|
132
|
+
lambdaB = rad_to_deg(Math.atan(yB / xB))
|
|
133
|
+
p = Math.sqrt((xB * xB) + (yB * yB))
|
|
134
|
+
phiN = Math.atan(zB / (p * (1 - eSquared)))
|
|
135
|
+
|
|
136
|
+
(1..10).each do |_i|
|
|
137
|
+
v = a / Math.sqrt(1 - eSquared * sin_pow_2(phiN))
|
|
138
|
+
phiN1 = Math.atan((zB + (eSquared * v * Math.sin(phiN))) / p)
|
|
139
|
+
phiN = phiN1
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
phiB = rad_to_deg(phiN)
|
|
143
|
+
|
|
144
|
+
[phiB, lambdaB]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def deg_to_rad(degrees)
|
|
148
|
+
degrees / 180.0 * Math::PI
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def rad_to_deg(r)
|
|
152
|
+
(r / Math::PI) * 180
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def sin_pow_2(x)
|
|
156
|
+
Math.sin(x) * Math.sin(x)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def cos_pow_2(x)
|
|
160
|
+
Math.cos(x) * Math.cos(x)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def tan_pow_2(x)
|
|
164
|
+
Math.tan(x) * Math.tan(x)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def sec(x)
|
|
168
|
+
1.0 / Math.cos(x)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
Geocoder.configure(
|
|
2
|
-
#
|
|
3
|
-
# :
|
|
4
|
-
# :
|
|
5
|
-
# :
|
|
6
|
-
# :
|
|
7
|
-
# :
|
|
8
|
-
# :
|
|
9
|
-
# :
|
|
10
|
-
# :
|
|
11
|
-
# :
|
|
2
|
+
# Geocoding options
|
|
3
|
+
# timeout: 3, # geocoding service timeout (secs)
|
|
4
|
+
# lookup: :nominatim, # name of geocoding service (symbol)
|
|
5
|
+
# ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol)
|
|
6
|
+
# language: :en, # ISO-639 language code
|
|
7
|
+
# use_https: false, # use HTTPS for lookup requests? (if supported)
|
|
8
|
+
# http_proxy: nil, # HTTP proxy server (user:pass@host:port)
|
|
9
|
+
# https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
|
|
10
|
+
# api_key: nil, # API key for geocoding service
|
|
11
|
+
# cache: nil, # cache object (must respond to #[], #[]=, and #del)
|
|
12
12
|
|
|
13
|
-
#
|
|
13
|
+
# Exceptions that should not be rescued by default
|
|
14
14
|
# (if you want to implement custom error handling);
|
|
15
|
-
# supports SocketError and
|
|
16
|
-
# :
|
|
15
|
+
# supports SocketError and Timeout::Error
|
|
16
|
+
# always_raise: [],
|
|
17
17
|
|
|
18
|
-
#
|
|
19
|
-
# :
|
|
20
|
-
# :
|
|
18
|
+
# Calculation options
|
|
19
|
+
# units: :mi, # :km for kilometers or :mi for miles
|
|
20
|
+
# distances: :linear # :spherical or :linear
|
|
21
|
+
|
|
22
|
+
# Cache configuration
|
|
23
|
+
# cache_options: {
|
|
24
|
+
# expiration: 2.days,
|
|
25
|
+
# prefix: 'geocoder:'
|
|
26
|
+
# }
|
|
21
27
|
)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
2
3
|
|
|
3
4
|
module Geocoder
|
|
4
5
|
module Generators
|
|
5
6
|
module Maxmind
|
|
6
7
|
class GeoliteCityGenerator < Rails::Generators::Base
|
|
7
8
|
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
8
10
|
|
|
9
11
|
source_root File.expand_path('../templates', __FILE__)
|
|
10
12
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
2
3
|
|
|
3
4
|
module Geocoder
|
|
4
5
|
module Generators
|
|
5
6
|
module Maxmind
|
|
6
7
|
class GeoliteCountryGenerator < Rails::Generators::Base
|
|
7
8
|
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
8
10
|
|
|
9
11
|
source_root File.expand_path('../templates', __FILE__)
|
|
10
12
|
|
data/lib/geocoder/cache.rb
CHANGED
|
@@ -1,37 +1,29 @@
|
|
|
1
|
+
Dir["#{__dir__}/cache_stores/*.rb"].each {|file| require file }
|
|
2
|
+
|
|
1
3
|
module Geocoder
|
|
2
4
|
class Cache
|
|
3
5
|
|
|
4
|
-
def initialize(store,
|
|
5
|
-
@
|
|
6
|
-
@
|
|
6
|
+
def initialize(store, config)
|
|
7
|
+
@class = (Geocoder::CacheStore.const_get("#{store.class}", false) rescue Geocoder::CacheStore::Generic)
|
|
8
|
+
@store_service = @class.new(store, config)
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
##
|
|
10
12
|
# Read from the Cache.
|
|
11
13
|
#
|
|
12
14
|
def [](url)
|
|
13
|
-
interpret
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
when store.respond_to?(:get)
|
|
17
|
-
store.get key_for(url)
|
|
18
|
-
when store.respond_to?(:read)
|
|
19
|
-
store.read key_for(url)
|
|
20
|
-
end
|
|
15
|
+
interpret store_service.read(url)
|
|
16
|
+
rescue => e
|
|
17
|
+
Geocoder.log(:warn, "Geocoder cache read error: #{e}")
|
|
21
18
|
end
|
|
22
19
|
|
|
23
20
|
##
|
|
24
21
|
# Write to the Cache.
|
|
25
22
|
#
|
|
26
23
|
def []=(url, value)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
when store.respond_to?(:set)
|
|
31
|
-
store.set key_for(url), value
|
|
32
|
-
when store.respond_to?(:write)
|
|
33
|
-
store.write key_for(url), value
|
|
34
|
-
end
|
|
24
|
+
store_service.write(url, value)
|
|
25
|
+
rescue => e
|
|
26
|
+
Geocoder.log(:warn, "Geocoder cache write error: #{e}")
|
|
35
27
|
end
|
|
36
28
|
|
|
37
29
|
##
|
|
@@ -40,7 +32,11 @@ module Geocoder
|
|
|
40
32
|
#
|
|
41
33
|
def expire(url)
|
|
42
34
|
if url == :all
|
|
43
|
-
|
|
35
|
+
if store_service.respond_to?(:keys)
|
|
36
|
+
urls.each{ |u| expire(u) }
|
|
37
|
+
else
|
|
38
|
+
raise(NoMethodError, "The Geocoder cache store must implement `#keys` for `expire(:all)` to work")
|
|
39
|
+
end
|
|
44
40
|
else
|
|
45
41
|
expire_single_url(url)
|
|
46
42
|
end
|
|
@@ -49,29 +45,21 @@ module Geocoder
|
|
|
49
45
|
|
|
50
46
|
private # ----------------------------------------------------------------
|
|
51
47
|
|
|
52
|
-
def
|
|
53
|
-
def store; @store; end
|
|
54
|
-
|
|
55
|
-
##
|
|
56
|
-
# Cache key for a given URL.
|
|
57
|
-
#
|
|
58
|
-
def key_for(url)
|
|
59
|
-
[prefix, url].join
|
|
60
|
-
end
|
|
48
|
+
def store_service; @store_service; end
|
|
61
49
|
|
|
62
50
|
##
|
|
63
51
|
# Array of keys with the currently configured prefix
|
|
64
52
|
# that have non-nil values.
|
|
65
53
|
#
|
|
66
54
|
def keys
|
|
67
|
-
|
|
55
|
+
store_service.keys
|
|
68
56
|
end
|
|
69
57
|
|
|
70
58
|
##
|
|
71
59
|
# Array of cached URLs.
|
|
72
60
|
#
|
|
73
61
|
def urls
|
|
74
|
-
|
|
62
|
+
store_service.urls
|
|
75
63
|
end
|
|
76
64
|
|
|
77
65
|
##
|
|
@@ -83,8 +71,7 @@ module Geocoder
|
|
|
83
71
|
end
|
|
84
72
|
|
|
85
73
|
def expire_single_url(url)
|
|
86
|
-
|
|
87
|
-
store.respond_to?(:del) ? store.del(key) : store.delete(key)
|
|
74
|
+
store_service.remove(url)
|
|
88
75
|
end
|
|
89
76
|
end
|
|
90
77
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Geocoder::CacheStore
|
|
2
|
+
class Base
|
|
3
|
+
def initialize(store, options)
|
|
4
|
+
@store = store
|
|
5
|
+
@config = options
|
|
6
|
+
@prefix = config[:prefix]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Array of keys with the currently configured prefix
|
|
11
|
+
# that have non-nil values.
|
|
12
|
+
def keys
|
|
13
|
+
store.keys.select { |k| k.match(/^#{prefix}/) and self[k] }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Array of cached URLs.
|
|
18
|
+
#
|
|
19
|
+
def urls
|
|
20
|
+
keys
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected # ----------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
def prefix; @prefix; end
|
|
26
|
+
def store; @store; end
|
|
27
|
+
def config; @config; end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Cache key for a given URL.
|
|
31
|
+
#
|
|
32
|
+
def key_for(url)
|
|
33
|
+
if url.match(/^#{prefix}/)
|
|
34
|
+
url
|
|
35
|
+
else
|
|
36
|
+
[prefix, url].join
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'geocoder/cache_stores/base'
|
|
2
|
+
|
|
3
|
+
module Geocoder::CacheStore
|
|
4
|
+
class Generic < Base
|
|
5
|
+
def write(url, value)
|
|
6
|
+
case
|
|
7
|
+
when store.respond_to?(:[]=)
|
|
8
|
+
store[key_for(url)] = value
|
|
9
|
+
when store.respond_to?(:set)
|
|
10
|
+
store.set key_for(url), value
|
|
11
|
+
when store.respond_to?(:write)
|
|
12
|
+
store.write key_for(url), value
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def read(url)
|
|
17
|
+
case
|
|
18
|
+
when store.respond_to?(:[])
|
|
19
|
+
store[key_for(url)]
|
|
20
|
+
when store.respond_to?(:get)
|
|
21
|
+
store.get key_for(url)
|
|
22
|
+
when store.respond_to?(:read)
|
|
23
|
+
store.read key_for(url)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def keys
|
|
28
|
+
store.keys
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def remove(key)
|
|
32
|
+
store.delete(key)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'geocoder/cache_stores/base'
|
|
2
|
+
|
|
3
|
+
module Geocoder::CacheStore
|
|
4
|
+
class Redis < Base
|
|
5
|
+
def initialize(store, options)
|
|
6
|
+
super
|
|
7
|
+
@expiration = options[:expiration]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def write(url, value, expire = @expiration)
|
|
11
|
+
if expire.present?
|
|
12
|
+
store.set key_for(url), value, ex: expire
|
|
13
|
+
else
|
|
14
|
+
store.set key_for(url), value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def read(url)
|
|
19
|
+
store.get key_for(url)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def keys
|
|
23
|
+
store.keys("#{prefix}*")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def remove(key)
|
|
27
|
+
store.del(key)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private # ----------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
def expire; @expiration; end
|
|
33
|
+
end
|
|
34
|
+
end
|