ultra-fast-mod 0.0.1
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 +7 -0
- data/geocoder-1.8.6/CHANGELOG.md +669 -0
- data/geocoder-1.8.6/LICENSE +20 -0
- data/geocoder-1.8.6/README.md +827 -0
- data/geocoder-1.8.6/bin/console +13 -0
- data/geocoder-1.8.6/bin/geocode +5 -0
- data/geocoder-1.8.6/examples/app_defined_lookup_services.rb +22 -0
- data/geocoder-1.8.6/examples/cache_bypass.rb +48 -0
- data/geocoder-1.8.6/examples/reverse_geocode_job.rb +40 -0
- data/geocoder-1.8.6/lib/easting_northing.rb +171 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/config_generator.rb +14 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/templates/initializer.rb +27 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/geocoder-1.8.6/lib/generators/geocoder/migration_version.rb +15 -0
- data/geocoder-1.8.6/lib/geocoder/cache.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/base.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/generic.rb +35 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/redis.rb +34 -0
- data/geocoder-1.8.6/lib/geocoder/calculations.rb +420 -0
- data/geocoder-1.8.6/lib/geocoder/cli.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/configuration.rb +151 -0
- data/geocoder-1.8.6/lib/geocoder/configuration_hash.rb +11 -0
- data/geocoder-1.8.6/lib/geocoder/esri_token.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/exceptions.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/ip_address.rb +36 -0
- data/geocoder-1.8.6/lib/geocoder/kernel_logger.rb +25 -0
- data/geocoder-1.8.6/lib/geocoder/logger.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/lookup.rb +155 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amap.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amazon_location_service.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/azure.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/base.rb +351 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/bing.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/esri.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/freegeoip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoapify.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocodio.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoip2.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_details.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_search.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_premier.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/here.rb +73 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_io.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_lite.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipbase.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io_lite.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipstack.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/latlon.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/location_iq.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapbox.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapquest.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind.rb +90 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_local.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nominatim.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/osmnames.rb +57 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pc_miler.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pdok_nl.rb +43 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pelias.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/photon.rb +89 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pointpin.rb +69 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/smarty_streets.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/telize.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/tencent.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/test.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/twogis.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/yandex.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/models/active_record.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/models/base.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_base.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_mapper.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongoid.rb +32 -0
- data/geocoder-1.8.6/lib/geocoder/query.rb +125 -0
- data/geocoder-1.8.6/lib/geocoder/railtie.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/request.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/results/abstract_api.rb +146 -0
- data/geocoder-1.8.6/lib/geocoder/results/amap.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/results/amazon_location_service.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/azure.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu_ip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/geocoder-1.8.6/lib/geocoder/results/base.rb +79 -0
- data/geocoder-1.8.6/lib/geocoder/results/bing.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/db_ip_com.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/esri.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/freegeoip.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoapify.rb +179 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocoder_ca.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocodio.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoip2.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/google.rb +150 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_details.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_search.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_premier.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/here.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location.rb +22 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_io.rb +21 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_lite.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipapi_com.rb +45 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipbase.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipdata_co.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io_lite.rb +16 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipregistry.rb +304 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipstack.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/latlon.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/location_iq.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapbox.rb +80 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapquest.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind.rb +130 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_local.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/results/melissa_street.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/nominatim.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/results/opencagedata.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/results/osmnames.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/results/pc_miler.rb +98 -0
- data/geocoder-1.8.6/lib/geocoder/results/pdok_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/pelias.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/photon.rb +119 -0
- data/geocoder-1.8.6/lib/geocoder/results/pickpoint.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/pointpin.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcodes_io.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/smarty_streets.rb +142 -0
- data/geocoder-1.8.6/lib/geocoder/results/telize.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/tencent.rb +72 -0
- data/geocoder-1.8.6/lib/geocoder/results/test.rb +33 -0
- data/geocoder-1.8.6/lib/geocoder/results/twogis.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/yandex.rb +292 -0
- data/geocoder-1.8.6/lib/geocoder/sql.rb +110 -0
- data/geocoder-1.8.6/lib/geocoder/stores/active_record.rb +329 -0
- data/geocoder-1.8.6/lib/geocoder/stores/base.rb +115 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_base.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_mapper.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongoid.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/util.rb +29 -0
- data/geocoder-1.8.6/lib/geocoder/version.rb +3 -0
- data/geocoder-1.8.6/lib/geocoder.rb +48 -0
- data/geocoder-1.8.6/lib/maxmind_database.rb +109 -0
- data/geocoder-1.8.6/lib/tasks/geocoder.rake +54 -0
- data/geocoder-1.8.6/lib/tasks/maxmind.rake +73 -0
- data/ultra-fast-mod.gemspec +12 -0
- metadata +214 -0
|
@@ -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,48 @@
|
|
|
1
|
+
# This class allows you to configure how Geocoder should treat errors that occur when
|
|
2
|
+
# the cache is not available.
|
|
3
|
+
# Configure it like this
|
|
4
|
+
# config/initializers/geocoder.rb
|
|
5
|
+
# Geocoder.configure(
|
|
6
|
+
# :cache => Geocoder::CacheBypass.new(Redis.new)
|
|
7
|
+
# )
|
|
8
|
+
#
|
|
9
|
+
# Depending on the value of @bypass this will either
|
|
10
|
+
# raise the exception (true) or swallow it and pretend the cache did not return a hit (false)
|
|
11
|
+
#
|
|
12
|
+
class Geocoder::CacheBypass
|
|
13
|
+
def initialize(target, bypass = true)
|
|
14
|
+
@target = target
|
|
15
|
+
@bypass = bypass
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def [](key)
|
|
20
|
+
with_bypass { @target[key] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def []=(key, value)
|
|
24
|
+
with_bypass(value) { @target[key] = value }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def keys
|
|
28
|
+
with_bypass([]) { @target.keys }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def del(key)
|
|
32
|
+
with_bypass { @target.del(key) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def with_bypass(return_value_if_exception = nil, &block)
|
|
38
|
+
begin
|
|
39
|
+
yield
|
|
40
|
+
rescue
|
|
41
|
+
if @bypass
|
|
42
|
+
return_value_if_exception
|
|
43
|
+
else
|
|
44
|
+
raise # reraise original exception
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
class ConfigGenerator < Rails::Generators::Base
|
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
6
|
+
|
|
7
|
+
desc "This generator creates an initializer file at config/initializers, " +
|
|
8
|
+
"with the default configuration options for Geocoder."
|
|
9
|
+
def add_initializer
|
|
10
|
+
template "initializer.rb", "config/initializers/geocoder.rb"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Geocoder.configure(
|
|
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
|
+
|
|
13
|
+
# Exceptions that should not be rescued by default
|
|
14
|
+
# (if you want to implement custom error handling);
|
|
15
|
+
# supports SocketError and Timeout::Error
|
|
16
|
+
# always_raise: [],
|
|
17
|
+
|
|
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
|
+
# }
|
|
27
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Generators
|
|
6
|
+
module Maxmind
|
|
7
|
+
class GeoliteCityGenerator < Rails::Generators::Base
|
|
8
|
+
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
10
|
+
|
|
11
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
12
|
+
|
|
13
|
+
def copy_migration_files
|
|
14
|
+
migration_template "migration/geolite_city.rb", "db/migrate/geocoder_maxmind_geolite_city.rb"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Define the next_migration_number method (necessary for the
|
|
18
|
+
# migration_template method to work)
|
|
19
|
+
def self.next_migration_number(dirname)
|
|
20
|
+
if ActiveRecord::Base.timestamped_migrations
|
|
21
|
+
sleep 1 # make sure each time we get a different timestamp
|
|
22
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
23
|
+
else
|
|
24
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rails/generators/migration'
|
|
2
|
+
require 'generators/geocoder/migration_version'
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Generators
|
|
6
|
+
module Maxmind
|
|
7
|
+
class GeoliteCountryGenerator < Rails::Generators::Base
|
|
8
|
+
include Rails::Generators::Migration
|
|
9
|
+
include Generators::MigrationVersion
|
|
10
|
+
|
|
11
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
12
|
+
|
|
13
|
+
def copy_migration_files
|
|
14
|
+
migration_template "migration/geolite_country.rb", "db/migrate/geocoder_maxmind_geolite_country.rb"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Define the next_migration_number method (necessary for the
|
|
18
|
+
# migration_template method to work)
|
|
19
|
+
def self.next_migration_number(dirname)
|
|
20
|
+
if ActiveRecord::Base.timestamped_migrations
|
|
21
|
+
sleep 1 # make sure each time we get a different timestamp
|
|
22
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
23
|
+
else
|
|
24
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class GeocoderMaxmindGeoliteCity < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :maxmind_geolite_city_blocks, id: false do |t|
|
|
4
|
+
t.column :start_ip_num, :bigint, null: false
|
|
5
|
+
t.column :end_ip_num, :bigint, null: false
|
|
6
|
+
t.column :loc_id, :bigint, null: false
|
|
7
|
+
end
|
|
8
|
+
add_index :maxmind_geolite_city_blocks, :loc_id
|
|
9
|
+
add_index :maxmind_geolite_city_blocks, :start_ip_num, unique: true
|
|
10
|
+
add_index :maxmind_geolite_city_blocks, [:end_ip_num, :start_ip_num], unique: true, name: 'index_maxmind_geolite_city_blocks_on_end_ip_num_range'
|
|
11
|
+
|
|
12
|
+
create_table :maxmind_geolite_city_location, id: false do |t|
|
|
13
|
+
t.column :loc_id, :bigint, null: false
|
|
14
|
+
t.string :country, null: false
|
|
15
|
+
t.string :region, null: false
|
|
16
|
+
t.string :city
|
|
17
|
+
t.string :postal_code, null: false
|
|
18
|
+
t.float :latitude
|
|
19
|
+
t.float :longitude
|
|
20
|
+
t.integer :metro_code
|
|
21
|
+
t.integer :area_code
|
|
22
|
+
end
|
|
23
|
+
add_index :maxmind_geolite_city_location, :loc_id, unique: true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.down
|
|
27
|
+
drop_table :maxmind_geolite_city_location
|
|
28
|
+
drop_table :maxmind_geolite_city_blocks
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class GeocoderMaxmindGeoliteCountry < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :maxmind_geolite_country, id: false do |t|
|
|
4
|
+
t.column :start_ip, :string
|
|
5
|
+
t.column :end_ip, :string
|
|
6
|
+
t.column :start_ip_num, :bigint, null: false
|
|
7
|
+
t.column :end_ip_num, :bigint, null: false
|
|
8
|
+
t.column :country_code, :string, null: false
|
|
9
|
+
t.column :country, :string, null: false
|
|
10
|
+
end
|
|
11
|
+
add_index :maxmind_geolite_country, :start_ip_num, unique: true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.down
|
|
15
|
+
drop_table :maxmind_geolite_country
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Dir["#{__dir__}/cache_stores/*.rb"].each {|file| require file }
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
class Cache
|
|
5
|
+
|
|
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)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Read from the Cache.
|
|
13
|
+
#
|
|
14
|
+
def [](url)
|
|
15
|
+
interpret store_service.read(url)
|
|
16
|
+
rescue => e
|
|
17
|
+
Geocoder.log(:warn, "Geocoder cache read error: #{e}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Write to the Cache.
|
|
22
|
+
#
|
|
23
|
+
def []=(url, value)
|
|
24
|
+
store_service.write(url, value)
|
|
25
|
+
rescue => e
|
|
26
|
+
Geocoder.log(:warn, "Geocoder cache write error: #{e}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Delete cache entry for given URL,
|
|
31
|
+
# or pass <tt>:all</tt> to clear all URLs.
|
|
32
|
+
#
|
|
33
|
+
def expire(url)
|
|
34
|
+
if url == :all
|
|
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
|
|
40
|
+
else
|
|
41
|
+
expire_single_url(url)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
private # ----------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
def store_service; @store_service; end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Array of keys with the currently configured prefix
|
|
52
|
+
# that have non-nil values.
|
|
53
|
+
#
|
|
54
|
+
def keys
|
|
55
|
+
store_service.keys
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Array of cached URLs.
|
|
60
|
+
#
|
|
61
|
+
def urls
|
|
62
|
+
store_service.urls
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Clean up value before returning. Namely, convert empty string to nil.
|
|
67
|
+
# (Some key/value stores return empty string instead of nil.)
|
|
68
|
+
#
|
|
69
|
+
def interpret(value)
|
|
70
|
+
value == "" ? nil : value
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def expire_single_url(url)
|
|
74
|
+
store_service.remove(url)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
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
|